This commit is contained in:
elwrcl committed 2026-06-06 13:25:15 +03:00
1 parent 04d4dc8b09
commit 818cab85dc
12511 files changed
+6156641

No files matched your search

+63
View File
@@ -0,0 +1,63 @@
# Copyright 2025 LunarG, Inc.
# Copyright 2025 Google LLC
# SPDX-License-Identifier: MIT
mtl_bridge_files = files(
'vk_to_mtl_map.h',
'vk_to_mtl_map.c',
'mtl_format.h',
)
if host_machine.system() == 'darwin'
mtl_bridge_files += files(
'mtl_bridge.m',
'mtl_buffer.m',
'mtl_command_buffer.m',
'mtl_command_queue.m',
'mtl_compute_state.m',
'mtl_device.m',
'mtl_encoder.m',
'mtl_heap.m',
'mtl_library.m',
'mtl_render_state.m',
'mtl_residency_set.m',
'mtl_sampler.m',
'mtl_sync.m',
'mtl_texture.m',
)
else
mtl_bridge_files += files(
'stubs/mtl_bridge.c',
'stubs/mtl_buffer.c',
'stubs/mtl_command_buffer.c',
'stubs/mtl_command_queue.c',
'stubs/mtl_compute_state.c',
'stubs/mtl_device.c',
'stubs/mtl_encoder.c',
'stubs/mtl_heap.c',
'stubs/mtl_library.c',
'stubs/mtl_render_state.c',
'stubs/mtl_residency_set.c',
'stubs/mtl_sampler.c',
'stubs/mtl_sync.c',
'stubs/mtl_texture.c',
)
endif
mtl_bridge_dependencies = [
idep_vulkan_lite_runtime_headers,
idep_vulkan_util
]
libmtl_bridge = static_library(
'mtl_bridge',
[mtl_bridge_files],
include_directories : [include_directories('../vulkan/'), inc_include, inc_src],
dependencies : mtl_bridge_dependencies,
gnu_symbol_visibility: 'hidden',
build_by_default: false,
)
idep_mtl_bridge = declare_dependency(
link_with : libmtl_bridge,
)
+44
View File
@@ -0,0 +1,44 @@
/*
* Copyright 2025 LunarG, Inc.
* Copyright 2025 Google LLC
* SPDX-License-Identifier: MIT
*/
#ifndef KK_BRIDGE_H
#define KK_BRIDGE_H 1
/* C wrappers for Metal. May not be complete. If you find something you need
* feel free to add them where they belong. As a rule of thumb, member functions
* go in the objects' .h/.m/.c Naming convention for wrappers is:
* object_type* mtl_new_object_type(params...);
* void mtl_member_function(object_type* ptr, params...);
* void mtl_object_set_member(object_type* ptr, member_type value);
* member_type mtl_object_get_member(object_type* ptr);
*
* Functions that have new in the name require to release the returned object
* via mtl_release(object);
* */
#include "mtl_types.h"
#include "mtl_buffer.h"
#include "mtl_command_buffer.h"
#include "mtl_command_queue.h"
#include "mtl_compute_state.h"
#include "mtl_device.h"
#include "mtl_encoder.h"
#include "mtl_format.h"
#include "mtl_heap.h"
#include "mtl_library.h"
#include "mtl_render_state.h"
#include "mtl_residency_set.h"
#include "mtl_sampler.h"
#include "mtl_sync.h"
#include "mtl_texture.h"
mtl_texture *mtl_drawable_get_texture(void *drawable_ptr);
void *mtl_retain(void *handle);
void mtl_release(void *handle);
#endif /* KK_BRIDGE_H */
+50
View File
@@ -0,0 +1,50 @@
/*
* Copyright 2025 LunarG, Inc.
* Copyright 2025 Google LLC
* SPDX-License-Identifier: MIT
*/
#include "mtl_bridge.h"
// kk_image_layout.h should also includes "vulkan/vulkan.h", but just to be safe
#include "vulkan/vulkan.h"
#include "kk_image_layout.h"
#include "util/macros.h"
#include <Metal/MTLCommandBuffer.h>
#include <Metal/MTLCommandQueue.h>
#include <Metal/MTLDevice.h>
#include <Metal/MTLHeap.h>
#include <Metal/MTLEvent.h>
#include <QuartzCore/CAMetalLayer.h>
static_assert(sizeof(MTLResourceID) == sizeof(uint64_t), "Must match, otherwise descriptors are broken");
mtl_texture *
mtl_drawable_get_texture(void *drawable_ptr)
{
@autoreleasepool {
id<CAMetalDrawable> drawable = (id<CAMetalDrawable>)drawable_ptr;
return drawable.texture;
}
}
void *
mtl_retain(void *handle)
{
@autoreleasepool {
NSObject *obj = (NSObject *)handle;
return [obj retain];
}
}
void
mtl_release(void *handle)
{
@autoreleasepool {
NSObject *obj = (NSObject *)handle;
[obj release];
}
}
+26
View File
@@ -0,0 +1,26 @@
/*
* Copyright 2025 LunarG, Inc.
* Copyright 2025 Google LLC
* SPDX-License-Identifier: MIT
*/
#ifndef MTL_BUFFER_H
#define MTL_BUFFER_H 1
#include "mtl_types.h"
#include <inttypes.h>
struct kk_image_layout;
/* Utils */
uint64_t mtl_buffer_get_length(mtl_buffer *buffer);
uint64_t mtl_buffer_get_gpu_address(mtl_buffer *buffer);
/* Gets CPU address */
void *mtl_get_contents(mtl_buffer *buffer);
/* Allocation from buffer */
mtl_texture *mtl_new_texture_with_descriptor_linear(
mtl_buffer *buffer, const struct kk_image_layout *layout, uint64_t offset);
#endif /* MTL_BUFFER_H */
+78
View File
@@ -0,0 +1,78 @@
/*
* Copyright 2025 LunarG, Inc.
* Copyright 2025 Google LLC
* SPDX-License-Identifier: MIT
*/
#include "mtl_buffer.h"
/* TODO_KOSMICKRISP Remove */
#include "kk_image_layout.h"
#include <Metal/MTLBuffer.h>
#include <Metal/MTLTexture.h>
uint64_t
mtl_buffer_get_length(mtl_buffer *buffer)
{
@autoreleasepool {
id<MTLBuffer> buf = (id<MTLBuffer>)buffer;
return buf.length;
}
}
uint64_t
mtl_buffer_get_gpu_address(mtl_buffer *buffer)
{
@autoreleasepool {
id<MTLBuffer> buf = (id<MTLBuffer>)buffer;
return [buf gpuAddress];
}
}
void *
mtl_get_contents(mtl_buffer *buffer)
{
@autoreleasepool {
id<MTLBuffer> buf = (id<MTLBuffer>)buffer;
return [buf contents];
}
}
/* TODO_KOSMICKRISP This is a duplicate, but both should be removed once we move kk_image_layout to the bridge. */
static MTLTextureDescriptor *
mtl_new_texture_descriptor(const struct kk_image_layout *layout)
{
@autoreleasepool {
MTLTextureDescriptor *descriptor = [MTLTextureDescriptor new];
descriptor.textureType = (MTLTextureType)layout->type;
descriptor.pixelFormat = layout->format.mtl;
descriptor.width = layout->width_px;
descriptor.height = layout->height_px;
descriptor.depth = layout->depth_px;
descriptor.mipmapLevelCount = layout->levels;
descriptor.sampleCount = layout->sample_count_sa;
descriptor.arrayLength = layout->layers;
descriptor.allowGPUOptimizedContents = layout->optimized_layout;
descriptor.usage = (MTLTextureUsage)layout->usage;
/* We don't set the swizzle because Metal complains when the usage has store or render target with swizzle... */
return descriptor;
}
}
mtl_texture *
mtl_new_texture_with_descriptor_linear(mtl_buffer *buffer,
const struct kk_image_layout *layout,
uint64_t offset)
{
@autoreleasepool {
id<MTLBuffer> buf = (id<MTLBuffer>)buffer;
MTLTextureDescriptor *descriptor = [mtl_new_texture_descriptor(layout) autorelease];
descriptor.resourceOptions = buf.resourceOptions;
id<MTLTexture> texture = [buf newTextureWithDescriptor:descriptor offset:offset bytesPerRow:layout->linear_stride_B];
return texture;
}
}
@@ -0,0 +1,27 @@
/*
* Copyright 2025 LunarG, Inc.
* Copyright 2025 Google LLC
* SPDX-License-Identifier: MIT
*/
#ifndef MTL_COMMAND_BUFFER_H
#define MTL_COMMAND_BUFFER_H 1
#include "mtl_types.h"
#include <stdint.h>
void mtl_encode_signal_event(mtl_command_buffer *cmd_buf_handle,
mtl_event *event_handle, uint64_t value);
void mtl_encode_wait_for_event(mtl_command_buffer *cmd_buf_handle,
mtl_event *event_handle, uint64_t value);
void mtl_add_completed_handler(mtl_command_buffer *cmd,
void (*callback)(void *data), void *data);
void mtl_command_buffer_commit(mtl_command_buffer *cmd_buf);
void mtl_present_drawable(mtl_command_buffer *cmd_buf, void *drawable);
#endif /* MTL_COMMAND_BUFFER_H */
@@ -0,0 +1,66 @@
/*
* Copyright 2025 LunarG, Inc.
* Copyright 2025 Google LLC
* SPDX-License-Identifier: MIT
*/
#include "mtl_command_buffer.h"
#include <Metal/MTLCommandBuffer.h>
#include <QuartzCore/CAMetalLayer.h>
void
mtl_encode_signal_event(mtl_command_buffer *cmd_buf_handle,
mtl_event *event_handle, uint64_t value)
{
@autoreleasepool {
id<MTLCommandBuffer> cmd_buf = (id<MTLCommandBuffer>)cmd_buf_handle;
id<MTLEvent> event = (id<MTLEvent>)event_handle;
[cmd_buf encodeSignalEvent:event value:value];
}
}
void
mtl_encode_wait_for_event(mtl_command_buffer *cmd_buf_handle,
mtl_event *event_handle, uint64_t value)
{
@autoreleasepool {
id<MTLCommandBuffer> cmd_buf = (id<MTLCommandBuffer>)cmd_buf_handle;
id<MTLEvent> event = (id<MTLEvent>)event_handle;
[cmd_buf encodeWaitForEvent:event value:value];
}
}
void
mtl_add_completed_handler(mtl_command_buffer *cmd, void (*callback)(void *data),
void *data)
{
@autoreleasepool {
id<MTLCommandBuffer> mtl_cmd = (id<MTLCommandBuffer>)cmd;
[mtl_cmd addCompletedHandler:^(id<MTLCommandBuffer> _Nonnull cmd_buf) {
@autoreleasepool {
if (callback)
callback(data);
}
}];
}
}
void
mtl_command_buffer_commit(mtl_command_buffer *cmd_buffer)
{
@autoreleasepool {
id<MTLCommandBuffer> cmd_buf = (id<MTLCommandBuffer>)cmd_buffer;
[cmd_buf commit];
}
}
void
mtl_present_drawable(mtl_command_buffer *cmd_buf, void *drawable_ptr)
{
@autoreleasepool {
id<MTLCommandBuffer> cmd = (id<MTLCommandBuffer>)cmd_buf;
id<CAMetalDrawable> drawable = [(id<CAMetalDrawable>)drawable_ptr autorelease];
[cmd presentDrawable:drawable];
}
}
@@ -0,0 +1,25 @@
/*
* Copyright 2025 LunarG, Inc.
* Copyright 2025 Google LLC
* SPDX-License-Identifier: MIT
*/
#ifndef MTL_COMMAND_QUEUE_H
#define MTL_COMMAND_QUEUE_H 1
#include "mtl_types.h"
#include <stdint.h>
mtl_command_queue *mtl_new_command_queue(mtl_device *device,
uint32_t cmd_buffer_count);
mtl_command_buffer *mtl_new_command_buffer(mtl_command_queue *cmd_queue);
void mtl_command_queue_add_residency_set(mtl_command_queue *cmd_queue,
mtl_residency_set *set);
void mtl_command_queue_remove_residency_set(mtl_command_queue *cmd_queue,
mtl_residency_set *set);
#endif /* MTL_COMMAND_QUEUE_H */
@@ -0,0 +1,50 @@
/*
* Copyright 2025 LunarG, Inc.
* Copyright 2025 Google LLC
* SPDX-License-Identifier: MIT
*/
#include "mtl_command_queue.h"
#include <Metal/MTLDevice.h>
#include <Metal/MTLCommandQueue.h>
mtl_command_queue *
mtl_new_command_queue(mtl_device *device, uint32_t cmd_buffer_count)
{
@autoreleasepool {
id<MTLDevice> dev = (id<MTLDevice>)device;
return [dev newCommandQueueWithMaxCommandBufferCount:cmd_buffer_count];
}
}
mtl_command_buffer *
mtl_new_command_buffer(mtl_command_queue *cmd_queue)
{
@autoreleasepool {
id<MTLCommandQueue> queue = (id<MTLCommandQueue>)cmd_queue;
return [[queue commandBuffer] retain];
}
}
void
mtl_command_queue_add_residency_set(mtl_command_queue *cmd_queue,
mtl_residency_set *set)
{
@autoreleasepool {
id<MTLCommandQueue> queue = (id<MTLCommandQueue>)cmd_queue;
id<MTLResidencySet> s = (id<MTLResidencySet>)set;
return [queue addResidencySet:s];
}
}
void
mtl_command_queue_remove_residency_set(mtl_command_queue *cmd_queue,
mtl_residency_set *set)
{
@autoreleasepool {
id<MTLCommandQueue> queue = (id<MTLCommandQueue>)cmd_queue;
id<MTLResidencySet> s = (id<MTLResidencySet>)set;
return [queue removeResidencySet:s];
}
}
@@ -0,0 +1,13 @@
/*
* Copyright 2025 LunarG, Inc.
* Copyright 2025 Google LLC
* SPDX-License-Identifier: MIT
*/
#include "mtl_types.h"
#include <stdint.h>
mtl_compute_pipeline_state *
mtl_new_compute_pipeline_state(mtl_device *device, mtl_function *function,
uint64_t max_total_threads_per_threadgroup);
@@ -0,0 +1,29 @@
/*
* Copyright 2025 LunarG, Inc.
* Copyright 2025 Google LLC
* SPDX-License-Identifier: MIT
*/
#include "mtl_compute_state.h"
#include <Metal/MTLComputePipeline.h>
mtl_compute_pipeline_state *
mtl_new_compute_pipeline_state(mtl_device *device, mtl_function *function,
uint64_t max_total_threads_per_threadgroup)
{
@autoreleasepool {
id<MTLDevice> dev = (id<MTLDevice>)device;
id<MTLComputePipelineState> pipeline = NULL;
MTLComputePipelineDescriptor *comp_desc = [[[MTLComputePipelineDescriptor alloc] init] autorelease];
NSError *error;
comp_desc.computeFunction = (id<MTLFunction>)function;
comp_desc.maxTotalThreadsPerThreadgroup = max_total_threads_per_threadgroup;
pipeline = [dev newComputePipelineStateWithDescriptor:comp_desc options:0 reflection:nil error:&error];
/* TODO_KOSMICKRISP Error checking */
return pipeline;
}
}
+63
View File
@@ -0,0 +1,63 @@
/*
* Copyright 2025 LunarG, Inc.
* Copyright 2025 Google LLC
* SPDX-License-Identifier: MIT
*/
#ifndef MTL_DEVICE_H
#define MTL_DEVICE_H 1
#include "mtl_format.h"
#include "mtl_types.h"
#include <stdbool.h>
#include <stdint.h>
/* TODO_KOSMICKRISP Remove */
struct kk_image_layout;
/* Device creation */
mtl_device *mtl_device_create(void);
/* Device operations */
void mtl_start_gpu_capture(mtl_device *mtl_dev_handle, const char *directory);
void mtl_stop_gpu_capture(void);
/* Device feature query */
void mtl_device_get_name(mtl_device *dev, char buffer[256]);
void mtl_device_get_architecture_name(mtl_device *dev, char buffer[256]);
uint64_t mtl_device_get_peer_group_id(mtl_device *dev);
uint32_t mtl_device_get_peer_index(mtl_device *dev);
uint64_t mtl_device_get_registry_id(mtl_device *dev);
bool mtl_device_supports_sample_count(mtl_device *dev, uint32_t sample_count);
struct mtl_size mtl_device_max_threads_per_threadgroup(mtl_device *dev);
uint32_t mtl_device_max_threadgroup_memory_length(mtl_device *dev);
uint64_t mtl_device_max_buffer_length(mtl_device *dev);
uint64_t mtl_device_recommended_max_working_set_size(mtl_device *dev);
uint64_t mtl_device_current_allocated_size(mtl_device *dev);
/* Timestamp query */
uint64_t mtl_device_get_gpu_timestamp(mtl_device *dev);
/* Resource queries */
void mtl_heap_buffer_size_and_align_with_length(mtl_device *device,
uint64_t *size_B,
uint64_t *align_B);
uint64_t mtl_minimum_linear_texture_alignment_for_pixel_format(
mtl_device *device, enum mtl_pixel_format format);
void mtl_heap_texture_size_and_align_with_descriptor(
mtl_device *device, struct kk_image_layout *layout, uint64_t *size_B,
uint64_t *align_B);
uint32_t mtl_sparse_tile_size_in_bytes(mtl_device *device);
struct mtl_size mtl_sparse_tile_size(mtl_device *device,
struct kk_image_layout *layout);
struct mtl_size mtl_sparse_tile_count(mtl_device *device,
struct kk_image_layout *layout,
struct mtl_size tile_size);
/* Resource creation */
mtl_buffer *mtl_new_buffer_with_bytes_no_copy(mtl_device *device, void *ptr,
uint64_t size_B);
#endif /* MTL_DEVICE_H */
+303
View File
@@ -0,0 +1,303 @@
/*
* Copyright 2025 LunarG, Inc.
* Copyright 2025 Google LLC
* SPDX-License-Identifier: MIT
*/
#include "mtl_device.h"
/* TODO_KOSMICKRISP Remove */
#include "kk_image_layout.h"
#include "kk_private.h"
#include <Metal/MTLDevice.h>
#include <Metal/MTLCaptureManager.h>
/* Device creation */
mtl_device *
mtl_device_create()
{
mtl_device *device = 0u;
@autoreleasepool {
NSArray<id<MTLDevice>> *devs = [MTLCopyAllDevices() autorelease];
uint32_t device_count = [devs count];
for (uint32_t i = 0u; i < device_count; ++i) {
if (@available(macOS 10.15, *)) {
if (!device && [devs[i] supportsFamily:MTLGPUFamilyMetal3]) {
device = (mtl_device *)[devs[i] retain];
break;
}
}
}
}
return device;
}
/* Device operations */
void
mtl_start_gpu_capture(mtl_device *mtl_dev_handle, const char *directory)
{
@autoreleasepool {
id<MTLDevice> mtl_dev = (id<MTLDevice>)mtl_dev_handle;
MTLCaptureManager *captureMgr = [MTLCaptureManager sharedCaptureManager];
MTLCaptureDescriptor *captureDesc = [[MTLCaptureDescriptor new] autorelease];
captureDesc.captureObject = mtl_dev;
captureDesc.destination = MTLCaptureDestinationDeveloperTools;
if (directory && [captureMgr supportsDestination: MTLCaptureDestinationGPUTraceDocument]) {
NSString *dir = [NSString stringWithUTF8String:directory];
NSString *pname = [[NSProcessInfo processInfo] processName];
NSString *capture_path = [NSString stringWithFormat:@"%@/%@.gputrace", dir, pname];
captureDesc.destination = MTLCaptureDestinationGPUTraceDocument;
captureDesc.outputURL = [NSURL fileURLWithPath: capture_path];
}
NSError *err = nil;
if (![captureMgr startCaptureWithDescriptor:captureDesc error:&err]) {
fprintf(stderr, "Failed to automatically start GPU capture session (Error code %li) using startCaptureWithDescriptor: %s\n",
(long)err.code, err.localizedDescription.UTF8String);
}
}
}
void
mtl_stop_gpu_capture()
{
@autoreleasepool {
[[MTLCaptureManager sharedCaptureManager] stopCapture];
}
}
/* Device feature query */
void
mtl_device_get_name(mtl_device *dev, char buffer[256])
{
@autoreleasepool {
id<MTLDevice> device = (id<MTLDevice>)dev;
[device.name getCString:buffer maxLength:(sizeof(char) * 256) encoding:NSUTF8StringEncoding];
}
}
void
mtl_device_get_architecture_name(mtl_device *dev, char buffer[256])
{
@autoreleasepool {
id<MTLDevice> device = (id<MTLDevice>)dev;
[device.architecture.name getCString:buffer maxLength:(sizeof(char) * 256) encoding:NSUTF8StringEncoding];
}
}
uint64_t
mtl_device_get_peer_group_id(mtl_device *dev)
{
@autoreleasepool {
id<MTLDevice> device = (id<MTLDevice>)dev;
return device.peerGroupID;
}
}
uint32_t
mtl_device_get_peer_index(mtl_device *dev)
{
@autoreleasepool {
id<MTLDevice> device = (id<MTLDevice>)dev;
return device.peerIndex;
}
}
uint64_t
mtl_device_get_registry_id(mtl_device *dev)
{
@autoreleasepool {
id<MTLDevice> device = (id<MTLDevice>)dev;
return device.registryID;
}
}
bool
mtl_device_supports_sample_count(mtl_device *dev, uint32_t sample_count)
{
@autoreleasepool {
id<MTLDevice> device = (id<MTLDevice>)dev;
return [device supportsTextureSampleCount:sample_count];
}
}
struct mtl_size
mtl_device_max_threads_per_threadgroup(mtl_device *dev)
{
@autoreleasepool {
id<MTLDevice> device = (id<MTLDevice>)dev;
return (struct mtl_size){.x = device.maxThreadsPerThreadgroup.width,
.y = device.maxThreadsPerThreadgroup.height,
.z = device.maxThreadsPerThreadgroup.depth};
}
}
uint32_t
mtl_device_max_threadgroup_memory_length(mtl_device *dev)
{
@autoreleasepool {
id<MTLDevice> device = (id<MTLDevice>)dev;
return device.maxThreadgroupMemoryLength;
}
}
uint64_t
mtl_device_max_buffer_length(mtl_device *dev)
{
@autoreleasepool {
id<MTLDevice> device = (id<MTLDevice>)dev;
return device.maxBufferLength;
}
}
uint64_t
mtl_device_recommended_max_working_set_size(mtl_device *dev)
{
@autoreleasepool {
id<MTLDevice> device = (id<MTLDevice>)dev;
return device.recommendedMaxWorkingSetSize;
}
}
uint64_t
mtl_device_current_allocated_size(mtl_device *dev)
{
@autoreleasepool {
id<MTLDevice> device = (id<MTLDevice>)dev;
return device.currentAllocatedSize;
}
}
/* Timestamp query */
uint64_t
mtl_device_get_gpu_timestamp(mtl_device *dev)
{
@autoreleasepool {
id<MTLDevice> device = (id<MTLDevice>)dev;
MTLTimestamp cpu_ts, gpu_ts;
[device sampleTimestamps:&cpu_ts gpuTimestamp:&gpu_ts];
return (uint64_t)gpu_ts;
}
}
/* Resource queries */
/* TODO_KOSMICKRISP Return a struct */
void
mtl_heap_buffer_size_and_align_with_length(mtl_device *device, uint64_t *size_B,
uint64_t *align_B)
{
@autoreleasepool {
id<MTLDevice> dev = (id<MTLDevice>)device;
MTLSizeAndAlign size_align = [dev heapBufferSizeAndAlignWithLength:*size_B options:KK_MTL_RESOURCE_OPTIONS];
*size_B = size_align.size;
*align_B = size_align.align;
}
}
/* TODO_KOSMICKRISP Remove */
static MTLTextureDescriptor *
mtl_new_texture_descriptor(const struct kk_image_layout *layout)
{
@autoreleasepool {
MTLTextureDescriptor *descriptor = [MTLTextureDescriptor new];
descriptor.textureType = (MTLTextureType)layout->type;
descriptor.pixelFormat = layout->format.mtl;
descriptor.width = layout->width_px;
descriptor.height = layout->height_px;
descriptor.depth = layout->depth_px;
descriptor.mipmapLevelCount = layout->levels;
descriptor.sampleCount = layout->sample_count_sa;
descriptor.arrayLength = layout->layers;
descriptor.allowGPUOptimizedContents = layout->optimized_layout;
descriptor.usage = (MTLTextureUsage)layout->usage;
/* We don't set the swizzle because Metal complains when the usage has store or render target with swizzle... */
return descriptor;
}
}
uint64_t
mtl_minimum_linear_texture_alignment_for_pixel_format(
mtl_device *device, enum mtl_pixel_format format)
{
@autoreleasepool {
id<MTLDevice> dev = (id<MTLDevice>)device;
return [dev minimumLinearTextureAlignmentForPixelFormat:(MTLPixelFormat)format];
}
}
void
mtl_heap_texture_size_and_align_with_descriptor(mtl_device *device,
struct kk_image_layout *layout,
uint64_t *size_B,
uint64_t *align_B)
{
@autoreleasepool {
id<MTLDevice> dev = (id<MTLDevice>)device;
MTLTextureDescriptor *descriptor = [mtl_new_texture_descriptor(layout) autorelease];
descriptor.resourceOptions = KK_MTL_RESOURCE_OPTIONS;
MTLSizeAndAlign size_align = [dev heapTextureSizeAndAlignWithDescriptor:descriptor];
if (size_B)
*size_B = size_align.size;
if (align_B)
*align_B = size_align.align;
}
}
uint32_t
mtl_sparse_tile_size_in_bytes(mtl_device *device) {
@autoreleasepool {
id<MTLDevice> dev = (id<MTLDevice>)device;
return [dev sparseTileSizeInBytes];
}
}
struct mtl_size
mtl_sparse_tile_size(mtl_device *device, struct kk_image_layout *layout) {
@autoreleasepool {
id<MTLDevice> dev = (id<MTLDevice>)device;
MTLSize tile_size = [dev sparseTileSizeWithTextureType:(MTLTextureType)layout->type
pixelFormat:layout->format.mtl
sampleCount:layout->sample_count_sa];
return (struct mtl_size){tile_size.width, tile_size.height, tile_size.depth};
}
}
struct mtl_size
mtl_sparse_tile_count(mtl_device *device, struct kk_image_layout *layout,
struct mtl_size tile_size) {
@autoreleasepool {
id<MTLDevice> dev = (id<MTLDevice>)device;
MTLRegion pixel_region = MTLRegionMake3D(
0, 0, 0, layout->width_px, layout->height_px, layout->depth_px);
MTLRegion tile_region;
[dev convertSparsePixelRegions:&pixel_region
toTileRegions:&tile_region
withTileSize:MTLSizeMake(tile_size.x, tile_size.y, tile_size.z)
alignmentMode:MTLSparseTextureRegionAlignmentModeOutward
numRegions:1];
return (struct mtl_size){tile_region.size.width, tile_region.size.height,
tile_region.size.depth};
}
}
/* Resource creation */
mtl_buffer *
mtl_new_buffer_with_bytes_no_copy(mtl_device *device, void* ptr,
uint64_t size_B)
{
@autoreleasepool {
id<MTLDevice> dev = (id<MTLDevice>)device;
return [dev newBufferWithBytesNoCopy:ptr length:size_B options:KK_MTL_RESOURCE_OPTIONS deallocator:nil];
}
}
+154
View File
@@ -0,0 +1,154 @@
/*
* Copyright 2025 LunarG, Inc.
* Copyright 2025 Google LLC
* SPDX-License-Identifier: MIT
*/
#ifndef MTL_ENCODER_H
#define MTL_ENCODER_H 1
#include "mtl_types.h"
#include <stdint.h>
/* Common encoder utils */
void mtl_end_encoding(void *encoder);
/* MTLBlitEncoder */
mtl_blit_encoder *mtl_new_blit_command_encoder(mtl_command_buffer *cmd_buffer);
void mtl_blit_update_fence(mtl_blit_encoder *encoder, mtl_fence *fence);
void mtl_blit_wait_for_fence(mtl_blit_encoder *encoder, mtl_fence *fence);
void mtl_copy_from_buffer_to_buffer(mtl_blit_encoder *blit_enc_handle,
mtl_buffer *src_buf, size_t src_offset,
mtl_buffer *dst_buf, size_t dst_offset,
size_t size);
void mtl_copy_from_buffer_to_texture(mtl_blit_encoder *blit_enc_handle,
struct mtl_buffer_image_copy *data);
void mtl_copy_from_texture_to_buffer(mtl_blit_encoder *blit_enc_handle,
struct mtl_buffer_image_copy *data);
void mtl_copy_from_texture_to_texture(
mtl_blit_encoder *blit_enc_handle, mtl_texture *src_tex_handle,
size_t src_slice, size_t src_level, struct mtl_origin src_origin,
struct mtl_size src_size, mtl_texture *dst_tex_handle, size_t dst_slice,
size_t dst_level, struct mtl_origin dst_origin);
/* MTLComputeEncoder */
mtl_compute_encoder *
mtl_new_compute_command_encoder(mtl_command_buffer *cmd_buffer);
void mtl_compute_update_fence(mtl_compute_encoder *encoder, mtl_fence *fence);
void mtl_compute_wait_for_fence(mtl_compute_encoder *encoder, mtl_fence *fence);
void mtl_compute_set_pipeline_state(mtl_compute_encoder *encoder,
mtl_compute_pipeline_state *state_handle);
void mtl_compute_set_buffer(mtl_compute_encoder *encoder, mtl_buffer *buffer,
size_t offset, size_t index);
void mtl_compute_use_heaps(mtl_compute_encoder *encoder, mtl_heap **heaps,
uint32_t count);
void mtl_dispatch_threads(mtl_compute_encoder *encoder,
struct mtl_size grid_size,
struct mtl_size local_size);
void mtl_dispatch_threadgroups_with_indirect_buffer(
mtl_compute_encoder *encoder, mtl_buffer *buffer, uint32_t offset,
struct mtl_size local_size);
void mtl_memory_barrier_with_scope(mtl_compute_encoder *encoder,
enum mtl_barrier_scope scope);
/* MTLRenderEncoder */
mtl_render_encoder *mtl_new_render_command_encoder_with_descriptor(
mtl_command_buffer *command_buffer, mtl_render_pass_descriptor *descriptor);
void mtl_render_update_fence(mtl_render_encoder *encoder, mtl_fence *fence);
void mtl_render_wait_for_fence(mtl_render_encoder *encoder, mtl_fence *fence);
void mtl_set_viewports(mtl_render_encoder *encoder,
struct mtl_viewport *viewports, uint32_t count);
void mtl_set_scissor_rects(mtl_render_encoder *encoder,
struct mtl_scissor_rect *scissor_rects,
uint32_t count);
void mtl_render_set_pipeline_state(mtl_render_encoder *encoder,
mtl_render_pipeline_state *pipeline);
void mtl_set_depth_stencil_state(mtl_render_encoder *encoder,
mtl_depth_stencil_state *state);
void mtl_set_stencil_references(mtl_render_encoder *encoder, uint32_t front,
uint32_t back);
void mtl_set_front_face_winding(mtl_render_encoder *encoder,
enum mtl_winding winding);
void mtl_set_cull_mode(mtl_render_encoder *encoder, enum mtl_cull_mode mode);
void mtl_set_visibility_result_mode(mtl_render_encoder *encoder,
enum mtl_visibility_result_mode mode,
size_t offset);
void mtl_set_depth_bias(mtl_render_encoder *encoder, float depth_bias,
float slope_scale, float clamp);
void mtl_set_depth_clip_mode(mtl_render_encoder *encoder,
enum mtl_depth_clip_mode mode);
void mtl_set_vertex_amplification_count(mtl_render_encoder *encoder,
uint32_t *layer_ids, uint32_t id_count);
void mtl_set_vertex_buffer(mtl_render_encoder *encoder, mtl_buffer *buffer,
uint32_t offset, uint32_t index);
void mtl_set_vertex_bytes(mtl_render_encoder *encoder, const void *bytes,
uint32_t length, uint32_t index);
void mtl_set_fragment_buffer(mtl_render_encoder *encoder, mtl_buffer *buffer,
uint32_t offset, uint32_t index);
void mtl_set_fragment_bytes(mtl_render_encoder *encoder, const void *bytes,
uint32_t length, uint32_t index);
void mtl_draw_primitives(mtl_render_encoder *encoder,
enum mtl_primitive_type primitve_type,
uint32_t vertexStart, uint32_t vertexCount,
uint32_t instanceCount, uint32_t baseInstance);
void mtl_draw_indexed_primitives(
mtl_render_encoder *encoder, enum mtl_primitive_type primitve_type,
uint32_t index_count, enum mtl_index_type index_type,
mtl_buffer *index_buffer, uint32_t index_buffer_offset,
uint32_t instance_count, int32_t base_vertex, uint32_t base_instance);
void mtl_draw_primitives_indirect(mtl_render_encoder *encoder,
enum mtl_primitive_type primitve_type,
mtl_buffer *indirect_buffer,
uint64_t indirect_buffer_offset);
void mtl_draw_indexed_primitives_indirect(mtl_render_encoder *encoder,
enum mtl_primitive_type primitve_type,
enum mtl_index_type index_type,
mtl_buffer *index_buffer,
uint32_t index_buffer_offset,
mtl_buffer *indirect_buffer,
uint64_t indirect_buffer_offset);
void mtl_render_use_resource(mtl_compute_encoder *encoder,
mtl_resource *res_handle, uint32_t usage);
void mtl_render_use_resources(mtl_render_encoder *encoder,
mtl_resource **resource_handles, uint32_t count,
enum mtl_resource_usage usage);
void mtl_render_use_heaps(mtl_render_encoder *encoder, mtl_heap **heaps,
uint32_t count);
#endif /* MTL_ENCODER_H */
+541
View File
@@ -0,0 +1,541 @@
/*
* Copyright 2025 LunarG, Inc.
* Copyright 2025 Google LLC
* SPDX-License-Identifier: MIT
*/
#include "mtl_encoder.h"
#include <Metal/MTLBlitCommandEncoder.h>
#include <Metal/MTLComputeCommandEncoder.h>
#include <Metal/MTLRenderCommandEncoder.h>
/* Common encoder utils */
void
mtl_end_encoding(void *encoder)
{
@autoreleasepool {
id<MTLCommandEncoder> enc = (id<MTLComputeCommandEncoder>)encoder;
[enc endEncoding];
}
}
/* MTLBlitEncoder */
mtl_blit_encoder *
mtl_new_blit_command_encoder(mtl_command_buffer *cmd_buffer)
{
@autoreleasepool {
id<MTLCommandBuffer> cmd_buf = (id<MTLCommandBuffer>)cmd_buffer;
return [[cmd_buf blitCommandEncoder] retain];
}
}
void
mtl_blit_update_fence(mtl_blit_encoder *encoder,
mtl_fence *fence)
{
@autoreleasepool {
id<MTLBlitCommandEncoder> enc = (id<MTLBlitCommandEncoder>)encoder;
id<MTLFence> f = (id<MTLFence>)fence;
[enc updateFence:f];
}
}
void
mtl_blit_wait_for_fence(mtl_blit_encoder *encoder,
mtl_fence *fence)
{
@autoreleasepool {
id<MTLBlitCommandEncoder> enc = (id<MTLBlitCommandEncoder>)encoder;
id<MTLFence> f = (id<MTLFence>)fence;
[enc waitForFence:f];
}
}
void
mtl_copy_from_buffer_to_buffer(mtl_blit_encoder *blit_enc_handle,
mtl_buffer *src_buf, size_t src_offset,
mtl_buffer *dst_buf, size_t dst_offset,
size_t size)
{
@autoreleasepool {
id<MTLBlitCommandEncoder> blit = (id<MTLBlitCommandEncoder>)blit_enc_handle;
id<MTLBuffer> mtl_src_buffer = (id<MTLBuffer>)src_buf;
id<MTLBuffer> mtl_dst_buffer = (id<MTLBuffer>)dst_buf;
[blit copyFromBuffer:mtl_src_buffer sourceOffset:src_offset toBuffer:mtl_dst_buffer destinationOffset:dst_offset size:size];
}
}
void
mtl_copy_from_buffer_to_texture(mtl_blit_encoder *blit_enc_handle,
struct mtl_buffer_image_copy *data)
{
@autoreleasepool {
const MTLSize size = MTLSizeMake(data->image_size.x, data->image_size.y, data->image_size.z);
const MTLOrigin origin = MTLOriginMake(data->image_origin.x, data->image_origin.y, data->image_origin.z);
id<MTLBlitCommandEncoder> blit = (id<MTLBlitCommandEncoder>)blit_enc_handle;
id<MTLBuffer> buffer = (id<MTLBuffer>)data->buffer;
id<MTLTexture> image = (id<MTLTexture>)data->image;
[blit copyFromBuffer:buffer
sourceOffset:data->buffer_offset_B
sourceBytesPerRow:data->buffer_stride_B
sourceBytesPerImage:data->buffer_2d_image_size_B
sourceSize:size
toTexture:image
destinationSlice:data->image_slice
destinationLevel:data->image_level
destinationOrigin:origin
options:(MTLBlitOption)data->options];
}
}
void
mtl_copy_from_texture_to_buffer(mtl_blit_encoder *blit_enc_handle,
struct mtl_buffer_image_copy *data)
{
@autoreleasepool {
const MTLSize size = MTLSizeMake(data->image_size.x, data->image_size.y, data->image_size.z);
const MTLOrigin origin = MTLOriginMake(data->image_origin.x, data->image_origin.y, data->image_origin.z);
id<MTLBlitCommandEncoder> blit = (id<MTLBlitCommandEncoder>)blit_enc_handle;
id<MTLBuffer> buffer = (id<MTLBuffer>)data->buffer;
id<MTLTexture> image = (id<MTLTexture>)data->image;
[blit copyFromTexture:image
sourceSlice:data->image_slice
sourceLevel:data->image_level
sourceOrigin:origin
sourceSize:size
toBuffer:buffer
destinationOffset:data->buffer_offset_B
destinationBytesPerRow:data->buffer_stride_B
destinationBytesPerImage:data->buffer_2d_image_size_B
options:(MTLBlitOption)data->options];
}
}
void
mtl_copy_from_texture_to_texture(mtl_blit_encoder *blit_enc_handle,
mtl_texture *src_tex_handle, size_t src_slice,
size_t src_level, struct mtl_origin src_origin,
struct mtl_size src_size,
mtl_texture *dst_tex_handle, size_t dst_slice,
size_t dst_level, struct mtl_origin dst_origin)
{
@autoreleasepool {
MTLOrigin mtl_src_origin = MTLOriginMake(src_origin.x, src_origin.y, src_origin.z);
MTLSize mtl_src_size = MTLSizeMake(src_size.x, src_size.y, src_size.z);
MTLOrigin mtl_dst_origin = MTLOriginMake(dst_origin.x, dst_origin.y, dst_origin.z);
id<MTLTexture> mtl_dst_tex = (id<MTLTexture>)dst_tex_handle;
id<MTLBlitCommandEncoder> blit = (id<MTLBlitCommandEncoder>)blit_enc_handle;
id<MTLTexture> mtl_src_tex = (id<MTLTexture>)src_tex_handle;
[blit copyFromTexture:mtl_src_tex
sourceSlice:src_slice
sourceLevel:src_level
sourceOrigin:mtl_src_origin
sourceSize:mtl_src_size
toTexture:mtl_dst_tex
destinationSlice:dst_slice
destinationLevel:dst_level
destinationOrigin:mtl_dst_origin];
}
}
/* MTLComputeEncoder */
mtl_compute_encoder *
mtl_new_compute_command_encoder(mtl_command_buffer *cmd_buffer)
{
@autoreleasepool {
id<MTLCommandBuffer> cmd_buf = (id<MTLCommandBuffer>)cmd_buffer;
return [[cmd_buf computeCommandEncoder] retain];
}
}
void
mtl_compute_update_fence(mtl_compute_encoder *encoder, mtl_fence *fence)
{
@autoreleasepool {
id<MTLComputeCommandEncoder> enc = (id<MTLComputeCommandEncoder>)encoder;
id<MTLFence> f = (id<MTLFence>)fence;
[enc updateFence:f];
}
}
void
mtl_compute_wait_for_fence(mtl_compute_encoder *encoder, mtl_fence *fence)
{
@autoreleasepool {
id<MTLComputeCommandEncoder> enc = (id<MTLComputeCommandEncoder>)encoder;
id<MTLFence> f = (id<MTLFence>)fence;
[enc waitForFence:f];
}
}
void
mtl_compute_set_pipeline_state(mtl_compute_encoder *encoder,
mtl_compute_pipeline_state *state_handle)
{
@autoreleasepool {
id<MTLComputeCommandEncoder> enc = (id<MTLComputeCommandEncoder>)encoder;
id<MTLComputePipelineState> state = (id<MTLComputePipelineState>)state_handle;
[enc setComputePipelineState:state];
}
}
void
mtl_compute_set_buffer(mtl_compute_encoder *encoder,
mtl_buffer *buffer, size_t offset, size_t index)
{
@autoreleasepool {
id<MTLComputeCommandEncoder> enc = (id<MTLComputeCommandEncoder>)encoder;
id<MTLBuffer> buf = (id<MTLBuffer>)buffer;
[enc setBuffer:buf offset:offset atIndex:index];
}
}
void
mtl_compute_use_heaps(mtl_compute_encoder *encoder, mtl_heap **heaps,
uint32_t count)
{
@autoreleasepool {
id<MTLComputeCommandEncoder> enc = (id<MTLComputeCommandEncoder>)encoder;
id<MTLHeap> *handles = (id<MTLHeap>*)heaps;
[enc useHeaps:handles count:count];
}
}
void
mtl_dispatch_threads(mtl_compute_encoder *encoder,
struct mtl_size grid_size, struct mtl_size local_size)
{
@autoreleasepool {
id<MTLComputeCommandEncoder> enc = (id<MTLComputeCommandEncoder>)encoder;
MTLSize thread_count = MTLSizeMake(grid_size.x, grid_size.y, grid_size.z);
MTLSize threads_per_threadgroup = MTLSizeMake(local_size.x, local_size.y,
local_size.z);
// TODO_KOSMICKRISP can we rely on nonuniform threadgroup size support?
[enc dispatchThreads:thread_count threadsPerThreadgroup:threads_per_threadgroup];
}
}
void
mtl_dispatch_threadgroups_with_indirect_buffer(mtl_compute_encoder *encoder,
mtl_buffer *buffer,
uint32_t offset,
struct mtl_size local_size)
{
@autoreleasepool {
id<MTLComputeCommandEncoder> enc = (id<MTLComputeCommandEncoder>)encoder;
id<MTLBuffer> buf = (id<MTLBuffer>)buffer;
MTLSize threads_per_threadgroup = MTLSizeMake(local_size.x,
local_size.y,
local_size.z);
[enc dispatchThreadgroupsWithIndirectBuffer:buf indirectBufferOffset:offset threadsPerThreadgroup:threads_per_threadgroup];
}
}
void
mtl_memory_barrier_with_scope(mtl_compute_encoder *encoder,
enum mtl_barrier_scope scope)
{
@autoreleasepool {
id<MTLComputeCommandEncoder> enc = (id<MTLComputeCommandEncoder>)encoder;
[enc memoryBarrierWithScope:(MTLBarrierScope)scope];
}
}
/* MTLRenderEncoder */
/* Encoder commands */
mtl_render_encoder *
mtl_new_render_command_encoder_with_descriptor(
mtl_command_buffer *command_buffer, mtl_render_pass_descriptor *descriptor)
{
@autoreleasepool {
id<MTLCommandBuffer> cmd = (id<MTLCommandBuffer>)command_buffer;
MTLRenderPassDescriptor *desc = (MTLRenderPassDescriptor *)descriptor;
return [[cmd renderCommandEncoderWithDescriptor:desc] retain];
}
}
void
mtl_render_update_fence(mtl_render_encoder *encoder, mtl_fence *fence)
{
@autoreleasepool {
id<MTLRenderCommandEncoder> enc = (id<MTLRenderCommandEncoder>)encoder;
id<MTLFence> f = (id<MTLFence>)fence;
[enc updateFence:f afterStages:MTLRenderStageFragment];
}
}
void
mtl_render_wait_for_fence(mtl_render_encoder *encoder, mtl_fence *fence)
{
@autoreleasepool {
id<MTLRenderCommandEncoder> enc = (id<MTLRenderCommandEncoder>)encoder;
id<MTLFence> f = (id<MTLFence>)fence;
[enc waitForFence:f beforeStages:MTLRenderStageVertex];
}
}
void
mtl_set_viewports(mtl_render_encoder *encoder, struct mtl_viewport *viewports,
uint32_t count)
{
@autoreleasepool {
id<MTLRenderCommandEncoder> enc = (id<MTLRenderCommandEncoder>)encoder;
MTLViewport *vps = (MTLViewport *)viewports;
[enc setViewports:vps count:count];
}
}
void
mtl_set_scissor_rects(mtl_render_encoder *encoder,
struct mtl_scissor_rect *scissor_rects, uint32_t count)
{
@autoreleasepool {
id<MTLRenderCommandEncoder> enc = (id<MTLRenderCommandEncoder>)encoder;
MTLScissorRect *rects = (MTLScissorRect *)scissor_rects;
[enc setScissorRects:rects count:count];
}
}
void
mtl_render_set_pipeline_state(mtl_render_encoder *encoder,
mtl_render_pipeline_state *pipeline)
{
@autoreleasepool {
id<MTLRenderCommandEncoder> enc = (id<MTLRenderCommandEncoder>)encoder;
id<MTLRenderPipelineState> pipe = (id<MTLRenderPipelineState>)pipeline;
[enc setRenderPipelineState:pipe];
}
}
void
mtl_set_depth_stencil_state(mtl_render_encoder *encoder,
mtl_depth_stencil_state *state)
{
@autoreleasepool {
id<MTLRenderCommandEncoder> enc = (id<MTLRenderCommandEncoder>)encoder;
id<MTLDepthStencilState> s = (id<MTLDepthStencilState>)state;
[enc setDepthStencilState:s];
}
}
void
mtl_set_stencil_references(mtl_render_encoder *encoder, uint32_t front,
uint32_t back)
{
@autoreleasepool {
id<MTLRenderCommandEncoder> enc = (id<MTLRenderCommandEncoder>)encoder;
[enc setStencilFrontReferenceValue:front backReferenceValue:back];
}
}
void
mtl_set_front_face_winding(mtl_render_encoder *encoder,
enum mtl_winding winding)
{
@autoreleasepool {
id<MTLRenderCommandEncoder> enc = (id<MTLRenderCommandEncoder>)encoder;
[enc setFrontFacingWinding:(MTLWinding)winding];
}
}
void
mtl_set_cull_mode(mtl_render_encoder *encoder, enum mtl_cull_mode mode)
{
@autoreleasepool {
id<MTLRenderCommandEncoder> enc = (id<MTLRenderCommandEncoder>)encoder;
[enc setCullMode:(MTLCullMode)mode];
}
}
void
mtl_set_visibility_result_mode(mtl_render_encoder *encoder,
enum mtl_visibility_result_mode mode,
size_t offset)
{
@autoreleasepool {
id<MTLRenderCommandEncoder> enc = (id<MTLRenderCommandEncoder>)encoder;
[enc setVisibilityResultMode:(MTLVisibilityResultMode)mode offset:offset];
}
}
void
mtl_set_depth_bias(mtl_render_encoder *encoder, float depth_bias,
float slope_scale, float clamp)
{
@autoreleasepool {
id<MTLRenderCommandEncoder> enc = (id<MTLRenderCommandEncoder>)encoder;
[enc setDepthBias:depth_bias slopeScale:slope_scale clamp:clamp];
}
}
void
mtl_set_depth_clip_mode(mtl_render_encoder *encoder,
enum mtl_depth_clip_mode mode)
{
@autoreleasepool {
id<MTLRenderCommandEncoder> enc = (id<MTLRenderCommandEncoder>)encoder;
[enc setDepthClipMode:(MTLDepthClipMode)mode];
}
}
void
mtl_set_vertex_amplification_count(mtl_render_encoder *encoder,
uint32_t *layer_ids, uint32_t id_count)
{
@autoreleasepool {
id<MTLRenderCommandEncoder> enc = (id<MTLRenderCommandEncoder>)encoder;
MTLVertexAmplificationViewMapping mappings[32];
for (uint32_t i = 0u; i < id_count; ++i) {
mappings[i].renderTargetArrayIndexOffset = layer_ids[i];
mappings[i].viewportArrayIndexOffset = 0u;
}
[enc setVertexAmplificationCount:id_count viewMappings:mappings];
}
}
void
mtl_set_vertex_buffer(mtl_render_encoder *encoder, mtl_buffer *buffer,
uint32_t offset, uint32_t index)
{
@autoreleasepool {
id<MTLRenderCommandEncoder> enc = (id<MTLRenderCommandEncoder>)encoder;
id<MTLBuffer> buf = (id<MTLBuffer>)buffer;
[enc setVertexBuffer:buf offset:offset atIndex:index];
}
}
void
mtl_set_vertex_bytes(mtl_render_encoder *encoder, const void *bytes,
uint32_t length, uint32_t index)
{
@autoreleasepool {
id<MTLRenderCommandEncoder> enc = (id<MTLRenderCommandEncoder>)encoder;
[enc setVertexBytes:bytes length:length atIndex:index];
}
}
void
mtl_set_fragment_buffer(mtl_render_encoder *encoder, mtl_buffer *buffer,
uint32_t offset, uint32_t index)
{
@autoreleasepool {
id<MTLRenderCommandEncoder> enc = (id<MTLRenderCommandEncoder>)encoder;
id<MTLBuffer> buf = (id<MTLBuffer>)buffer;
[enc setFragmentBuffer:buf offset:offset atIndex:index];
}
}
void
mtl_set_fragment_bytes(mtl_render_encoder *encoder, const void *bytes,
uint32_t length, uint32_t index)
{
@autoreleasepool {
id<MTLRenderCommandEncoder> enc = (id<MTLRenderCommandEncoder>)encoder;
[enc setFragmentBytes:bytes length:length atIndex:index];
}
}
void
mtl_draw_primitives(mtl_render_encoder *encoder,
enum mtl_primitive_type primitve_type, uint32_t vertexStart,
uint32_t vertexCount, uint32_t instanceCount,
uint32_t baseInstance)
{
@autoreleasepool {
id<MTLRenderCommandEncoder> enc = (id<MTLRenderCommandEncoder>)encoder;
MTLPrimitiveType type = (MTLPrimitiveType)primitve_type;
[enc drawPrimitives:type vertexStart:vertexStart vertexCount:vertexCount instanceCount:instanceCount baseInstance:baseInstance];
}
}
void
mtl_draw_indexed_primitives(
mtl_render_encoder *encoder, enum mtl_primitive_type primitve_type,
uint32_t index_count, enum mtl_index_type index_type,
mtl_buffer *index_buffer, uint32_t index_buffer_offset,
uint32_t instance_count, int32_t base_vertex, uint32_t base_instance)
{
@autoreleasepool {
id<MTLRenderCommandEncoder> enc = (id<MTLRenderCommandEncoder>)encoder;
id<MTLBuffer> buf = (id<MTLBuffer>)index_buffer;
MTLIndexType ndx_type = (MTLIndexType)index_type;
MTLPrimitiveType primitive = (MTLPrimitiveType)primitve_type;
[enc drawIndexedPrimitives:primitive indexCount:index_count indexType:ndx_type indexBuffer:buf indexBufferOffset:index_buffer_offset instanceCount:instance_count baseVertex:base_vertex baseInstance:base_instance];
}
}
void
mtl_draw_primitives_indirect(mtl_render_encoder *encoder,
enum mtl_primitive_type primitve_type,
mtl_buffer *indirect_buffer,
uint64_t indirect_buffer_offset)
{
@autoreleasepool {
id<MTLRenderCommandEncoder> enc = (id<MTLRenderCommandEncoder>)encoder;
id<MTLBuffer> buf = (id<MTLBuffer>)indirect_buffer;
MTLPrimitiveType type = (MTLPrimitiveType)primitve_type;
[enc drawPrimitives:type indirectBuffer:buf indirectBufferOffset:indirect_buffer_offset];
}
}
void
mtl_draw_indexed_primitives_indirect(mtl_render_encoder *encoder,
enum mtl_primitive_type primitve_type,
enum mtl_index_type index_type,
mtl_buffer *index_buffer,
uint32_t index_buffer_offset,
mtl_buffer *indirect_buffer,
uint64_t indirect_buffer_offset)
{
@autoreleasepool {
id<MTLRenderCommandEncoder> enc = (id<MTLRenderCommandEncoder>)encoder;
id<MTLBuffer> buf = (id<MTLBuffer>)indirect_buffer;
id<MTLBuffer> ndx_buf = (id<MTLBuffer>)index_buffer;
MTLPrimitiveType type = (MTLPrimitiveType)primitve_type;
MTLIndexType ndx_type = (MTLIndexType)index_type;
[enc drawIndexedPrimitives:type indexType:ndx_type indexBuffer:ndx_buf indexBufferOffset:index_buffer_offset indirectBuffer:buf indirectBufferOffset:indirect_buffer_offset];
}
}
void
mtl_render_use_resource(mtl_compute_encoder *encoder, mtl_resource *res_handle,
uint32_t usage)
{
@autoreleasepool {
id<MTLRenderCommandEncoder> enc = (id<MTLRenderCommandEncoder>)encoder;
id<MTLResource> res = (id<MTLResource>)res_handle;
[enc useResource:res usage:(MTLResourceUsage)usage stages:MTLRenderStageVertex|MTLRenderStageFragment];
}
}
void
mtl_render_use_resources(mtl_render_encoder *encoder,
mtl_resource **resource_handles, uint32_t count,
enum mtl_resource_usage usage)
{
@autoreleasepool {
// id<MTLRenderCommandEncoder> enc = (id<MTLRenderCommandEncoder>)encoder;
id<MTLResource> *handles = (id<MTLResource>*)resource_handles;
for (uint32_t i = 0u; i < count; ++i) {
if (handles[i] != NULL)
mtl_render_use_resource(encoder, handles[i], usage);
}
/* TODO_KOSMICKRISP No null values in the array or Metal complains */
// [enc useResources:handles count:count usage:(MTLResourceUsage)usage];
}
}
void
mtl_render_use_heaps(mtl_render_encoder *encoder, mtl_heap **heaps,
uint32_t count)
{
@autoreleasepool {
id<MTLRenderCommandEncoder> enc = (id<MTLRenderCommandEncoder>)encoder;
id<MTLHeap> *handles = (id<MTLHeap>*)heaps;
[enc useHeaps:handles count:count stages:MTLRenderStageVertex|MTLRenderStageFragment];
}
}
+205
View File
@@ -0,0 +1,205 @@
/*
* Copyright 2025 LunarG, Inc.
* Copyright 2025 Google LLC
* SPDX-License-Identifier: MIT
*/
#ifndef MTL_FORMAT_H
#define MTL_FORMAT_H 1
/* TODO_KOSMICKRISP Haven't modified all
* Slightly modified naming so they match to enum pipe_format for convenience
*/
enum mtl_pixel_format {
MTL_PIXEL_FORMAT_INVALID = 0,
/* Normal 8 bit formats */
MTL_PIXEL_FORMAT_A8_UNORM = 1,
MTL_PIXEL_FORMAT_R8_UNORM = 10,
MTL_PIXEL_FORMAT_R8_SRGB = 11,
MTL_PIXEL_FORMAT_R8_SNORM = 12,
MTL_PIXEL_FORMAT_R8_UINT = 13,
MTL_PIXEL_FORMAT_R8_SINT = 14,
/* Normal 16 bit formats */
MTL_PIXEL_FORMAT_R16_UNORM = 20,
MTL_PIXEL_FORMAT_R16_SNORM = 22,
MTL_PIXEL_FORMAT_R16_UINT = 23,
MTL_PIXEL_FORMAT_R16_SINT = 24,
MTL_PIXEL_FORMAT_R16_FLOAT = 25,
MTL_PIXEL_FORMAT_R8G8_UNORM = 30,
MTL_PIXEL_FORMAT_R8G8_SRGB = 31,
MTL_PIXEL_FORMAT_R8G8_SNORM = 32,
MTL_PIXEL_FORMAT_R8G8_UINT = 33,
MTL_PIXEL_FORMAT_R8G8_SINT = 34,
/* Packed 16 bit formats */
MTL_PIXEL_FORMAT_B5G6R5_UNORM = 40,
MTL_PIXEL_FORMAT_A1B5G5R5_UNORM = 41,
MTL_PIXEL_FORMAT_A4B4G4R4_UNORM = 42,
MTL_PIXEL_FORMAT_B5G5R5A1_UNORM = 43,
/* Normal 32 bit formats */
MTL_PIXEL_FORMAT_R32_UINT = 53,
MTL_PIXEL_FORMAT_R32_SINT = 54,
MTL_PIXEL_FORMAT_R32_FLOAT = 55,
MTL_PIXEL_FORMAT_R16G16_UNORM = 60,
MTL_PIXEL_FORMAT_R16G16_SNORM = 62,
MTL_PIXEL_FORMAT_R16G16_UINT = 63,
MTL_PIXEL_FORMAT_R16G16_SINT = 64,
MTL_PIXEL_FORMAT_R16G16_FLOAT = 65,
MTL_PIXEL_FORMAT_R8G8B8A8_UNORM = 70,
MTL_PIXEL_FORMAT_R8G8B8A8_SRGB = 71,
MTL_PIXEL_FORMAT_R8G8B8A8_SNORM = 72,
MTL_PIXEL_FORMAT_R8G8B8A8_UINT = 73,
MTL_PIXEL_FORMAT_R8G8B8A8_SINT = 74,
MTL_PIXEL_FORMAT_B8G8R8A8_UNORM = 80,
MTL_PIXEL_FORMAT_B8G8R8A8_SRGB = 81,
/* Packed 32 bit formats */
MTL_PIXEL_FORMAT_R10G10B10A2_UNORM = 90,
MTL_PIXEL_FORMAT_R10G10B10A2_UINT = 91,
MTL_PIXEL_FORMAT_R11G11B10_FLOAT = 92,
MTL_PIXEL_FORMAT_R9G9B9E5_FLOAT = 93,
MTL_PIXEL_FORMAT_B10G10R10A2_UNORM = 94,
MTL_PIXEL_FORMAT_BGR10_XR = 554,
MTL_PIXEL_FORMAT_BGR10_XR_SRGB = 555,
/* Normal 64 bit formats */
MTL_PIXEL_FORMAT_R32G32_UINT = 103,
MTL_PIXEL_FORMAT_R32G32_SINT = 104,
MTL_PIXEL_FORMAT_R32G32_FLOAT = 105,
MTL_PIXEL_FORMAT_R16G16B16A16_UNORM = 110,
MTL_PIXEL_FORMAT_R16G16B16A16_SNORM = 112,
MTL_PIXEL_FORMAT_R16G16B16A16_UINT = 113,
MTL_PIXEL_FORMAT_R16G16B16A16_SINT = 114,
MTL_PIXEL_FORMAT_R16G16B16A16_FLOAT = 115,
MTL_PIXEL_FORMAT_BGRA10_XR = 552,
MTL_PIXEL_FORMAT_BGRA10_XR_SRGB = 553,
/* Normal 128 bit formats */
MTL_PIXEL_FORMAT_R32G32B32A32_UINT = 123,
MTL_PIXEL_FORMAT_R32G32B32A32_SINT = 124,
MTL_PIXEL_FORMAT_R32G32B32A32_FLOAT = 125,
/* Compressed formats. */
/* S3TC/DXT */
MTL_PIXEL_FORMAT_DXT1_RGBA = 130,
MTL_PIXEL_FORMAT_DXT1_SRGBA = 131,
MTL_PIXEL_FORMAT_DXT3_RGBA = 132,
MTL_PIXEL_FORMAT_DXT3_SRGBA = 133,
MTL_PIXEL_FORMAT_DXT5_RGBA = 134,
MTL_PIXEL_FORMAT_DXT5_SRGBA = 135,
/* RGTC */
MTL_PIXEL_FORMAT_RGTC1_UNORM = 140,
MTL_PIXEL_FORMAT_RGTC1_SNORM = 141,
MTL_PIXEL_FORMAT_RGTC2_UNORM = 142,
MTL_PIXEL_FORMAT_RGTC2_SNORM = 143,
/* BPTC */
MTL_PIXEL_FORMAT_BPTC_RGB_FLOAT = 150,
MTL_PIXEL_FORMAT_BPTC_RGB_UFLOAT = 151,
MTL_PIXEL_FORMAT_BPTC_RGBA_UNORM = 152,
MTL_PIXEL_FORMAT_BPTC_SRGBA = 153,
/* PVRTC */
MTL_PIXEL_FORMAT_PVRTC_RGB_2BPP = 160,
MTL_PIXEL_FORMAT_PVRTC_RGB_2BPP_SRGB = 161,
MTL_PIXEL_FORMAT_PVRTC_RGB_4BPP = 162,
MTL_PIXEL_FORMAT_PVRTC_RGB_4BPP_SRGB = 163,
MTL_PIXEL_FORMAT_PVRTC_RGBA_2BPP = 164,
MTL_PIXEL_FORMAT_PVRTC_RGBA_2BPP_SRGB = 165,
MTL_PIXEL_FORMAT_PVRTC_RGBA_4BPP = 166,
MTL_PIXEL_FORMAT_PVRTC_RGBA_4BPP_SRGB = 167,
/* ETC2 */
MTL_PIXEL_FORMAT_ETC2_R11_UNORM = 170,
MTL_PIXEL_FORMAT_ETC2_R11_SNORM = 172,
MTL_PIXEL_FORMAT_ETC2_RG11_UNORM = 174,
MTL_PIXEL_FORMAT_ETC2_RG11_SNORM = 176,
MTL_PIXEL_FORMAT_ETC2_RGBA8 = 178,
MTL_PIXEL_FORMAT_ETC2_SRGBA8 = 179,
MTL_PIXEL_FORMAT_ETC2_RGB8 = 180,
MTL_PIXEL_FORMAT_ETC2_SRGB8 = 181,
MTL_PIXEL_FORMAT_ETC2_RGB8A1 = 182,
MTL_PIXEL_FORMAT_ETC2_SRGB8A1 = 183,
/* ASTC */
MTL_PIXEL_FORMAT_ASTC_4x4_SRGB = 186,
MTL_PIXEL_FORMAT_ASTC_5x4_SRGB = 187,
MTL_PIXEL_FORMAT_ASTC_5x5_SRGB = 188,
MTL_PIXEL_FORMAT_ASTC_6x5_SRGB = 189,
MTL_PIXEL_FORMAT_ASTC_6x6_SRGB = 190,
MTL_PIXEL_FORMAT_ASTC_8x5_SRGB = 192,
MTL_PIXEL_FORMAT_ASTC_8x6_SRGB = 193,
MTL_PIXEL_FORMAT_ASTC_8x8_SRGB = 194,
MTL_PIXEL_FORMAT_ASTC_10x5_SRGB = 195,
MTL_PIXEL_FORMAT_ASTC_10x6_SRGB = 196,
MTL_PIXEL_FORMAT_ASTC_10x8_SRGB = 197,
MTL_PIXEL_FORMAT_ASTC_10x10_SRGB = 198,
MTL_PIXEL_FORMAT_ASTC_12x10_SRGB = 199,
MTL_PIXEL_FORMAT_ASTC_12x12_SRGB = 200,
MTL_PIXEL_FORMAT_ASTC_4x4 = 204,
MTL_PIXEL_FORMAT_ASTC_5x4 = 205,
MTL_PIXEL_FORMAT_ASTC_5x5 = 206,
MTL_PIXEL_FORMAT_ASTC_6x5 = 207,
MTL_PIXEL_FORMAT_ASTC_6x6 = 208,
MTL_PIXEL_FORMAT_ASTC_8x5 = 210,
MTL_PIXEL_FORMAT_ASTC_8x6 = 211,
MTL_PIXEL_FORMAT_ASTC_8x8 = 212,
MTL_PIXEL_FORMAT_ASTC_10x5 = 213,
MTL_PIXEL_FORMAT_ASTC_10x6 = 214,
MTL_PIXEL_FORMAT_ASTC_10x8 = 215,
MTL_PIXEL_FORMAT_ASTC_10x10 = 216,
MTL_PIXEL_FORMAT_ASTC_12x10 = 217,
MTL_PIXEL_FORMAT_ASTC_12x12 = 218,
/* ASTC HDR (High Dynamic Range) */
MTL_PIXEL_FORMAT_ASTC_4x4_FLOAT = 222,
MTL_PIXEL_FORMAT_ASTC_5x4_FLOAT = 223,
MTL_PIXEL_FORMAT_ASTC_5x5_FLOAT = 224,
MTL_PIXEL_FORMAT_ASTC_6x5_FLOAT = 225,
MTL_PIXEL_FORMAT_ASTC_6x6_FLOAT = 226,
MTL_PIXEL_FORMAT_ASTC_8x5_FLOAT = 228,
MTL_PIXEL_FORMAT_ASTC_8x6_FLOAT = 229,
MTL_PIXEL_FORMAT_ASTC_8x8_FLOAT = 230,
MTL_PIXEL_FORMAT_ASTC_10x5_FLOAT = 231,
MTL_PIXEL_FORMAT_ASTC_10x6_FLOAT = 232,
MTL_PIXEL_FORMAT_ASTC_10x8_FLOAT = 233,
MTL_PIXEL_FORMAT_ASTC_10x10_FLOAT = 234,
MTL_PIXEL_FORMAT_ASTC_12x10_FLOAT = 235,
MTL_PIXEL_FORMAT_ASTC_12x12_FLOAT = 236,
/* YUV */
MTL_PIXEL_FORMAT_GBGR422 = 240,
MTL_PIXEL_FORMAT_BGRG422 = 241,
/* DEPTH */
MTL_PIXEL_FORMAT_Z16_UNORM = 250,
MTL_PIXEL_FORMAT_Z32_FLOAT = 252,
/* STENCIL */
MTL_PIXEL_FORMAT_S8_UINT = 253,
/* DEPTH STENCIL */
MTL_PIXEL_FORMAT_Z24_UNORM_S8_UINT = 255,
MTL_PIXEL_FORMAT_Z32_FLOAT_S8X24_UINT = 260,
MTL_PIXEL_FORMAT_X32_S8X24_UINT = 261,
MTL_PIXEL_FORMAT_X24_S8_UINT = 262,
};
#endif /* MTL_FORMAT_H */
+30
View File
@@ -0,0 +1,30 @@
/*
* Copyright 2025 LunarG, Inc.
* Copyright 2025 Google LLC
* SPDX-License-Identifier: MIT
*/
#ifndef MTL_HEAP_H
#define MTL_HEAP_H 1
#include "mtl_types.h"
#include <inttypes.h>
/* TODO_KOSMICKRISP We should move this struct to the bridge side. */
struct kk_image_layout;
/* Creation */
mtl_heap *mtl_new_heap(mtl_device *device, uint64_t size,
enum mtl_resource_options resource_options);
/* Utils */
uint64_t mtl_heap_get_size(mtl_heap *heap);
/* Allocation from heap */
mtl_buffer *mtl_new_buffer_with_length(mtl_heap *heap, uint64_t size_B,
uint64_t offset_B);
mtl_texture *mtl_new_texture_with_descriptor(
mtl_heap *heap, const struct kk_image_layout *layout, uint64_t offset);
#endif /* MTL_HEAP_H */
+83
View File
@@ -0,0 +1,83 @@
/*
* Copyright 2025 LunarG, Inc.
* Copyright 2025 Google LLC
* SPDX-License-Identifier: MIT
*/
#include "mtl_heap.h"
/* TODO_KOSMICKRISP Remove */
#include "kk_private.h"
#include "kk_image_layout.h"
#include <Metal/MTLHeap.h>
/* Creation */
mtl_heap *
mtl_new_heap(mtl_device *device, uint64_t size,
enum mtl_resource_options resource_options)
{
@autoreleasepool {
id<MTLDevice> dev = (id<MTLDevice>)device;
MTLHeapDescriptor *descriptor = [[MTLHeapDescriptor new] autorelease];
descriptor.type = MTLHeapTypePlacement;
descriptor.resourceOptions = (MTLResourceOptions)resource_options;
descriptor.size = size;
descriptor.sparsePageSize = MTLSparsePageSize16;
return [dev newHeapWithDescriptor:descriptor];
}
}
/* Utils */
uint64_t
mtl_heap_get_size(mtl_heap *heap)
{
@autoreleasepool {
id<MTLHeap> hp = (id<MTLHeap>)heap;
return hp.size;
}
}
static MTLTextureDescriptor *
mtl_new_texture_descriptor(const struct kk_image_layout *layout)
{
@autoreleasepool {
MTLTextureDescriptor *descriptor = [MTLTextureDescriptor new];
descriptor.textureType = (MTLTextureType)layout->type;
descriptor.pixelFormat = layout->format.mtl;
descriptor.width = layout->width_px;
descriptor.height = layout->height_px;
descriptor.depth = layout->depth_px;
descriptor.mipmapLevelCount = layout->levels;
descriptor.sampleCount = layout->sample_count_sa;
descriptor.arrayLength = layout->layers;
descriptor.allowGPUOptimizedContents = layout->optimized_layout;
descriptor.usage = (MTLTextureUsage)layout->usage;
/* We don't set the swizzle because Metal complains when the usage has store or render target with swizzle... */
return descriptor;
}
}
/* Allocation from heap */
mtl_buffer *
mtl_new_buffer_with_length(mtl_heap *heap, uint64_t size_B, uint64_t offset_B)
{
@autoreleasepool {
id<MTLHeap> hp = (id<MTLHeap>)heap;
return (mtl_buffer *)[hp newBufferWithLength:size_B options:KK_MTL_RESOURCE_OPTIONS offset:offset_B];
}
}
mtl_texture *
mtl_new_texture_with_descriptor(mtl_heap *heap,
const struct kk_image_layout *layout,
uint64_t offset)
{
@autoreleasepool {
id<MTLHeap> hp = (id<MTLHeap>)heap;
MTLTextureDescriptor *descriptor = [mtl_new_texture_descriptor(layout) autorelease];
descriptor.resourceOptions = hp.resourceOptions;
return [hp newTextureWithDescriptor:descriptor offset:offset];
}
}
+16
View File
@@ -0,0 +1,16 @@
/*
* Copyright 2025 LunarG, Inc.
* Copyright 2025 Google LLC
* SPDX-License-Identifier: MIT
*/
#ifndef MTL_LIBRARY_H
#define MTL_LIBRARY_H 1
#include "mtl_types.h"
mtl_library *mtl_new_library(mtl_device *device, const char *src);
mtl_function *mtl_new_function_with_name(mtl_library *lib,
const char *entry_point);
#endif /* MTL_LIBRARY_H */
+43
View File
@@ -0,0 +1,43 @@
/*
* Copyright 2025 LunarG, Inc.
* Copyright 2025 Google LLC
* SPDX-License-Identifier: MIT
*/
#include "mtl_library.h"
#include <Metal/MTLDevice.h>
mtl_library *
mtl_new_library(mtl_device *device, const char *src)
{
@autoreleasepool {
id<MTLDevice> dev = (id<MTLDevice>)device;
id<MTLLibrary> lib = NULL;
NSString *nsstr = [NSString stringWithCString:src encoding:NSASCIIStringEncoding];
NSError *error;
MTLCompileOptions *comp_opts = [MTLCompileOptions new];
comp_opts.languageVersion = MTLLanguageVersion3_2;
comp_opts.mathMode = MTLMathModeSafe;
comp_opts.mathFloatingPointFunctions = MTLMathFloatingPointFunctionsPrecise;
lib = [dev newLibraryWithSource:nsstr options:comp_opts error:&error];
if (error != nil) {
fprintf(stderr, "Failed to create MTLLibrary: %s\n", [error.localizedDescription UTF8String]);
}
[comp_opts release];
return lib;
}
}
mtl_function *
mtl_new_function_with_name(mtl_library *lib, const char *entry_point)
{
@autoreleasepool {
id<MTLLibrary> mtl_lib = (id<MTLLibrary>)lib;
NSString *ns_entry_point = [NSString stringWithCString:entry_point encoding:NSASCIIStringEncoding];
return [mtl_lib newFunctionWithName:ns_entry_point];
}
}
+169
View File
@@ -0,0 +1,169 @@
/*
* Copyright 2025 LunarG, Inc.
* Copyright 2025 Google LLC
* SPDX-License-Identifier: MIT
*/
#ifndef MTL_RENDER_STATE_H
#define MTL_RENDER_STATE_H 1
#include "mtl_types.h"
#include <inttypes.h>
#include <stdbool.h>
/* Bridge enums */
enum mtl_pixel_format;
/* TODO_KOSMICKRISP Remove */
enum VkCompareOp;
enum VkStencilOp;
/* Render pass descriptor */
mtl_render_pass_descriptor *mtl_new_render_pass_descriptor(void);
mtl_render_pass_attachment_descriptor *
mtl_render_pass_descriptor_get_color_attachment(
mtl_render_pass_descriptor *descriptor, uint32_t index);
mtl_render_pass_attachment_descriptor *
mtl_render_pass_descriptor_get_depth_attachment(
mtl_render_pass_descriptor *descriptor);
mtl_render_pass_attachment_descriptor *
mtl_render_pass_descriptor_get_stencil_attachment(
mtl_render_pass_descriptor *descriptor);
void mtl_render_pass_attachment_descriptor_set_texture(
mtl_render_pass_attachment_descriptor *descriptor, mtl_texture *texture);
void mtl_render_pass_attachment_descriptor_set_level(
mtl_render_pass_attachment_descriptor *descriptor, uint32_t level);
void mtl_render_pass_attachment_descriptor_set_slice(
mtl_render_pass_attachment_descriptor *descriptor, uint32_t slice);
void mtl_render_pass_attachment_descriptor_set_load_action(
mtl_render_pass_attachment_descriptor *descriptor,
enum mtl_load_action action);
void mtl_render_pass_attachment_descriptor_set_store_action(
mtl_render_pass_attachment_descriptor *descriptor,
enum mtl_store_action action);
void mtl_render_pass_attachment_descriptor_set_clear_color(
mtl_render_pass_attachment_descriptor *descriptor,
struct mtl_clear_color clear_color);
void mtl_render_pass_attachment_descriptor_set_clear_depth(
mtl_render_pass_attachment_descriptor *descriptor, double depth);
void mtl_render_pass_attachment_descriptor_set_clear_stencil(
mtl_render_pass_attachment_descriptor *descriptor, uint32_t stencil);
void mtl_render_pass_descriptor_set_render_target_array_length(
mtl_render_pass_descriptor *descriptor, uint32_t length);
void mtl_render_pass_descriptor_set_render_target_width(
mtl_render_pass_descriptor *descriptor, uint32_t width);
void mtl_render_pass_descriptor_set_render_target_height(
mtl_render_pass_descriptor *descriptor, uint32_t height);
void mtl_render_pass_descriptor_set_default_raster_sample_count(
mtl_render_pass_descriptor *descriptor, uint32_t sample_count);
void mtl_render_pass_descriptor_set_sample_positions(
mtl_render_pass_descriptor *descriptor,
const struct mtl_sample_position *positions, uint32_t count);
void mtl_render_pass_descriptor_set_visibility_buffer(
mtl_render_pass_descriptor *descriptor, mtl_buffer *visibility_buffer);
/* Render pipeline descriptor */
mtl_render_pipeline_descriptor *mtl_new_render_pipeline_descriptor(void);
void mtl_render_pipeline_descriptor_set_vertex_shader(
mtl_render_pass_descriptor *descriptor, mtl_function *shader);
void mtl_render_pipeline_descriptor_set_fragment_shader(
mtl_render_pass_descriptor *descriptor, mtl_function *shader);
void mtl_render_pipeline_descriptor_set_input_primitive_topology(
mtl_render_pass_descriptor *descriptor,
enum mtl_primitive_topology_class topology_class);
void mtl_render_pipeline_descriptor_set_color_attachment_format(
mtl_render_pass_descriptor *descriptor, uint8_t index,
enum mtl_pixel_format format);
void mtl_render_pipeline_descriptor_set_depth_attachment_format(
mtl_render_pass_descriptor *descriptor, enum mtl_pixel_format format);
void mtl_render_pipeline_descriptor_set_stencil_attachment_format(
mtl_render_pass_descriptor *descriptor, enum mtl_pixel_format format);
void mtl_render_pipeline_descriptor_set_raster_sample_count(
mtl_render_pass_descriptor *descriptor, uint32_t sample_count);
void mtl_render_pipeline_descriptor_set_alpha_to_coverage(
mtl_render_pass_descriptor *descriptor, bool enabled);
void mtl_render_pipeline_descriptor_set_alpha_to_one(
mtl_render_pass_descriptor *descriptor, bool enabled);
void mtl_render_pipeline_descriptor_set_rasterization_enabled(
mtl_render_pass_descriptor *descriptor, bool enabled);
void mtl_render_pipeline_descriptor_set_max_vertex_amplification_count(
mtl_render_pass_descriptor *descriptor, uint32_t count);
/* Render pipeline */
mtl_render_pipeline_state *
mtl_new_render_pipeline(mtl_device *device,
mtl_render_pass_descriptor *descriptor);
/* Stencil descriptor */
mtl_stencil_descriptor *mtl_new_stencil_descriptor(void);
void mtl_stencil_descriptor_set_stencil_failure_operation(
mtl_stencil_descriptor *descriptor, enum VkStencilOp op);
void mtl_stencil_descriptor_set_depth_failure_operation(
mtl_stencil_descriptor *descriptor, enum VkStencilOp op);
void mtl_stencil_descriptor_set_depth_stencil_pass_operation(
mtl_stencil_descriptor *descriptor, enum VkStencilOp op);
void mtl_stencil_descriptor_set_stencil_compare_function(
mtl_stencil_descriptor *descriptor, enum VkCompareOp op);
void mtl_stencil_descriptor_set_read_mask(mtl_stencil_descriptor *descriptor,
uint32_t mask);
void mtl_stencil_descriptor_set_write_mask(mtl_stencil_descriptor *descriptor,
uint32_t mask);
/* Depth stencil descriptor */
mtl_depth_stencil_descriptor *mtl_new_depth_stencil_descriptor(void);
void mtl_depth_stencil_descriptor_set_depth_compare_function(
mtl_depth_stencil_descriptor *descriptor, enum VkCompareOp op);
void mtl_depth_stencil_descriptor_set_depth_write_enabled(
mtl_depth_stencil_descriptor *descriptor, bool enable_write);
void mtl_depth_stencil_descriptor_set_back_face_stencil(
mtl_depth_stencil_descriptor *descriptor,
mtl_stencil_descriptor *stencil_descriptor);
void mtl_depth_stencil_descriptor_set_front_face_stencil(
mtl_depth_stencil_descriptor *descriptor,
mtl_stencil_descriptor *stencil_descriptor);
/* Depth stencil state */
mtl_depth_stencil_state *
mtl_new_depth_stencil_state(mtl_device *device,
mtl_depth_stencil_descriptor *descriptor);
#endif /* MTL_RENDER_STATE_H */
+495
View File
@@ -0,0 +1,495 @@
/*
* Copyright 2025 LunarG, Inc.
* Copyright 2025 Google LLC
* SPDX-License-Identifier: MIT
*/
#include "mtl_render_state.h"
#include "mtl_format.h"
/* TODO_KOSMICKRISP Remove */
#include "vk_to_mtl_map.h"
/* TODO_KOSMICKRISP Remove */
#include "vulkan/vulkan.h"
#include <Metal/MTLRenderPass.h>
#include <Metal/MTLRenderPipeline.h>
#include <Metal/MTLDepthStencil.h>
/* Render pass descriptor */
mtl_render_pass_descriptor *
mtl_new_render_pass_descriptor(void)
{
@autoreleasepool {
return [[MTLRenderPassDescriptor renderPassDescriptor] retain];
}
}
mtl_render_pass_attachment_descriptor *
mtl_render_pass_descriptor_get_color_attachment(
mtl_render_pass_descriptor *descriptor, uint32_t index)
{
@autoreleasepool {
MTLRenderPassDescriptor *desc = (MTLRenderPassDescriptor *)descriptor;
return desc.colorAttachments[index];
}
}
mtl_render_pass_attachment_descriptor *
mtl_render_pass_descriptor_get_depth_attachment(
mtl_render_pass_descriptor *descriptor)
{
@autoreleasepool {
MTLRenderPassDescriptor *desc = (MTLRenderPassDescriptor *)descriptor;
return desc.depthAttachment;
}
}
mtl_render_pass_attachment_descriptor *
mtl_render_pass_descriptor_get_stencil_attachment(
mtl_render_pass_descriptor *descriptor)
{
@autoreleasepool {
MTLRenderPassDescriptor *desc = (MTLRenderPassDescriptor *)descriptor;
return desc.stencilAttachment;
}
}
void
mtl_render_pass_attachment_descriptor_set_texture(
mtl_render_pass_attachment_descriptor *descriptor, mtl_texture *texture)
{
@autoreleasepool {
MTLRenderPassAttachmentDescriptor *desc = (MTLRenderPassAttachmentDescriptor *)descriptor;
desc.texture = (id<MTLTexture>)texture;
}
}
void
mtl_render_pass_attachment_descriptor_set_level(
mtl_render_pass_attachment_descriptor *descriptor, uint32_t level)
{
@autoreleasepool {
MTLRenderPassAttachmentDescriptor *desc = (MTLRenderPassAttachmentDescriptor *)descriptor;
desc.level = level;
}
}
void
mtl_render_pass_attachment_descriptor_set_slice(
mtl_render_pass_attachment_descriptor *descriptor, uint32_t slice)
{
@autoreleasepool {
MTLRenderPassAttachmentDescriptor *desc = (MTLRenderPassAttachmentDescriptor *)descriptor;
desc.slice = slice;
}
}
void
mtl_render_pass_attachment_descriptor_set_load_action(
mtl_render_pass_attachment_descriptor *descriptor,
enum mtl_load_action action)
{
@autoreleasepool {
MTLRenderPassAttachmentDescriptor *desc = (MTLRenderPassAttachmentDescriptor *)descriptor;
desc.loadAction = (MTLLoadAction)action;
}
}
void
mtl_render_pass_attachment_descriptor_set_store_action(
mtl_render_pass_attachment_descriptor *descriptor,
enum mtl_store_action action)
{
@autoreleasepool {
MTLRenderPassAttachmentDescriptor *desc = (MTLRenderPassAttachmentDescriptor *)descriptor;
desc.storeAction = (MTLStoreAction)action;
desc.storeActionOptions = MTLStoreActionOptionNone; /* TODO_KOSMICKRISP Maybe expose this? */
}
}
void
mtl_render_pass_attachment_descriptor_set_clear_color(
mtl_render_pass_attachment_descriptor *descriptor,
struct mtl_clear_color clear_color)
{
@autoreleasepool {
MTLRenderPassColorAttachmentDescriptor *desc = (MTLRenderPassColorAttachmentDescriptor *)descriptor;
desc.clearColor = MTLClearColorMake(clear_color.red, clear_color.green, clear_color.blue, clear_color.alpha);
}
}
void
mtl_render_pass_attachment_descriptor_set_clear_depth(
mtl_render_pass_attachment_descriptor *descriptor, double depth)
{
@autoreleasepool {
MTLRenderPassDepthAttachmentDescriptor *desc = (MTLRenderPassDepthAttachmentDescriptor *)descriptor;
desc.clearDepth = depth;
}
}
void
mtl_render_pass_attachment_descriptor_set_clear_stencil(mtl_render_pass_attachment_descriptor *descriptor,
uint32_t stencil)
{
@autoreleasepool {
MTLRenderPassStencilAttachmentDescriptor *desc = (MTLRenderPassStencilAttachmentDescriptor *)descriptor;
desc.clearStencil = stencil;
}
}
void
mtl_render_pass_descriptor_set_render_target_array_length(mtl_render_pass_descriptor *descriptor,
uint32_t length)
{
@autoreleasepool {
MTLRenderPassDescriptor *desc = (MTLRenderPassDescriptor *)descriptor;
desc.renderTargetArrayLength = length;
}
}
void
mtl_render_pass_descriptor_set_render_target_width(mtl_render_pass_descriptor *descriptor,
uint32_t width)
{
@autoreleasepool {
MTLRenderPassDescriptor *desc = (MTLRenderPassDescriptor *)descriptor;
desc.renderTargetWidth = width;
}
}
void
mtl_render_pass_descriptor_set_render_target_height(mtl_render_pass_descriptor *descriptor,
uint32_t height)
{
@autoreleasepool {
MTLRenderPassDescriptor *desc = (MTLRenderPassDescriptor *)descriptor;
desc.renderTargetHeight = height;
}
}
void
mtl_render_pass_descriptor_set_default_raster_sample_count(mtl_render_pass_descriptor *descriptor,
uint32_t sample_count)
{
@autoreleasepool {
MTLRenderPassDescriptor *desc = (MTLRenderPassDescriptor *)descriptor;
desc.defaultRasterSampleCount = sample_count;
}
}
void
mtl_render_pass_descriptor_set_sample_positions(
mtl_render_pass_descriptor *descriptor,
const struct mtl_sample_position *positions,
uint32_t count)
{
@autoreleasepool {
MTLRenderPassDescriptor *desc = (MTLRenderPassDescriptor *)descriptor;
if (count > 0) {
MTLSamplePosition pos[count];
for (uint32_t i = 0; i < count; i++) {
pos[i] = MTLSamplePositionMake(positions[i].x, positions[i].y);
}
[desc setSamplePositions:pos count:count];
} else {
[desc setSamplePositions:NULL count:count];
}
}
}
void
mtl_render_pass_descriptor_set_visibility_buffer(mtl_render_pass_descriptor *descriptor,
mtl_buffer *visibility_buffer)
{
@autoreleasepool {
MTLRenderPassDescriptor *desc = (MTLRenderPassDescriptor *)descriptor;
id<MTLBuffer> buffer = (id<MTLBuffer>)visibility_buffer;
desc.visibilityResultBuffer = buffer;
}
}
/* Render pipeline descriptor */
mtl_render_pipeline_descriptor *
mtl_new_render_pipeline_descriptor()
{
@autoreleasepool {
return [[MTLRenderPipelineDescriptor alloc] init];
}
}
void
mtl_render_pipeline_descriptor_set_vertex_shader(mtl_render_pass_descriptor *descriptor,
mtl_function *shader)
{
@autoreleasepool {
MTLRenderPipelineDescriptor *desc = (MTLRenderPipelineDescriptor *)descriptor;
desc.vertexFunction = (id<MTLFunction>)shader;
}
}
void
mtl_render_pipeline_descriptor_set_fragment_shader(mtl_render_pass_descriptor *descriptor,
mtl_function *shader)
{
@autoreleasepool {
MTLRenderPipelineDescriptor *desc = (MTLRenderPipelineDescriptor *)descriptor;
desc.fragmentFunction = (id<MTLFunction>)shader;
}
}
void
mtl_render_pipeline_descriptor_set_input_primitive_topology(mtl_render_pass_descriptor *descriptor,
enum mtl_primitive_topology_class class)
{
@autoreleasepool {
MTLRenderPipelineDescriptor *desc = (MTLRenderPipelineDescriptor *)descriptor;
desc.inputPrimitiveTopology = (MTLPrimitiveTopologyClass)class;
}
}
void
mtl_render_pipeline_descriptor_set_color_attachment_format(mtl_render_pass_descriptor *descriptor,
uint8_t index,
enum mtl_pixel_format format)
{
@autoreleasepool {
MTLRenderPipelineDescriptor *desc = (MTLRenderPipelineDescriptor *)descriptor;
desc.colorAttachments[index].pixelFormat = (MTLPixelFormat)format;
}
}
void
mtl_render_pipeline_descriptor_set_depth_attachment_format(mtl_render_pass_descriptor *descriptor,
enum mtl_pixel_format format)
{
@autoreleasepool {
MTLRenderPipelineDescriptor *desc = (MTLRenderPipelineDescriptor *)descriptor;
desc.depthAttachmentPixelFormat = (MTLPixelFormat)format;
}
}
void
mtl_render_pipeline_descriptor_set_stencil_attachment_format(mtl_render_pass_descriptor *descriptor,
enum mtl_pixel_format format)
{
@autoreleasepool {
MTLRenderPipelineDescriptor *desc = (MTLRenderPipelineDescriptor *)descriptor;
desc.stencilAttachmentPixelFormat = (MTLPixelFormat)format;
}
}
void
mtl_render_pipeline_descriptor_set_raster_sample_count(mtl_render_pass_descriptor *descriptor,
uint32_t sample_count)
{
@autoreleasepool {
MTLRenderPipelineDescriptor *desc = (MTLRenderPipelineDescriptor *)descriptor;
desc.rasterSampleCount = sample_count;
}
}
void
mtl_render_pipeline_descriptor_set_alpha_to_coverage(mtl_render_pass_descriptor *descriptor,
bool enabled)
{
@autoreleasepool {
MTLRenderPipelineDescriptor *desc = (MTLRenderPipelineDescriptor *)descriptor;
desc.alphaToCoverageEnabled = enabled;
}
}
void
mtl_render_pipeline_descriptor_set_alpha_to_one(mtl_render_pass_descriptor *descriptor,
bool enabled)
{
@autoreleasepool {
MTLRenderPipelineDescriptor *desc = (MTLRenderPipelineDescriptor *)descriptor;
desc.alphaToOneEnabled = enabled;
}
}
void
mtl_render_pipeline_descriptor_set_rasterization_enabled(mtl_render_pass_descriptor *descriptor,
bool enabled)
{
@autoreleasepool {
MTLRenderPipelineDescriptor *desc = (MTLRenderPipelineDescriptor *)descriptor;
desc.rasterizationEnabled = enabled;
}
}
void
mtl_render_pipeline_descriptor_set_max_vertex_amplification_count( mtl_render_pass_descriptor *descriptor,
uint32_t count)
{
@autoreleasepool {
MTLRenderPipelineDescriptor *desc = (MTLRenderPipelineDescriptor *)descriptor;
desc.maxVertexAmplificationCount = count;
}
}
/* Render pipeline */
mtl_render_pipeline_state *
mtl_new_render_pipeline(mtl_device *device, mtl_render_pass_descriptor *descriptor)
{
@autoreleasepool {
MTLRenderPipelineDescriptor *desc = (MTLRenderPipelineDescriptor *)descriptor;
id<MTLDevice> dev = (id<MTLDevice>)device;
NSError *error = nil;
mtl_render_pipeline_state *pipeline = [dev newRenderPipelineStateWithDescriptor:desc error:&error];
if (error != nil) {
fprintf(stderr, "Failed to create MTLLibrary: %s\n", [error.localizedDescription UTF8String]);
}
return pipeline;
}
}
/* Stencil descriptor */
mtl_stencil_descriptor *
mtl_new_stencil_descriptor()
{
@autoreleasepool {
return [[MTLStencilDescriptor new] init];
}
}
/* TODO_KOSMICKRISP Move this to map */
static MTLStencilOperation
map_vk_stencil_op_to_mtl_stencil_operation(VkStencilOp op)
{
switch (op) {
case VK_STENCIL_OP_KEEP:
return MTLStencilOperationKeep;
case VK_STENCIL_OP_ZERO:
return MTLStencilOperationZero;
case VK_STENCIL_OP_REPLACE:
return MTLStencilOperationReplace;
case VK_STENCIL_OP_INCREMENT_AND_CLAMP:
return MTLStencilOperationIncrementClamp;
case VK_STENCIL_OP_DECREMENT_AND_CLAMP:
return MTLStencilOperationDecrementClamp;
case VK_STENCIL_OP_INVERT:
return MTLStencilOperationInvert;
case VK_STENCIL_OP_INCREMENT_AND_WRAP:
return MTLStencilOperationIncrementWrap;
case VK_STENCIL_OP_DECREMENT_AND_WRAP:
return MTLStencilOperationDecrementWrap;
default:
assert(false && "Unsupported VkStencilOp");
return MTLStencilOperationZero;
};
}
void
mtl_stencil_descriptor_set_stencil_failure_operation(mtl_stencil_descriptor *descriptor, VkStencilOp op)
{
@autoreleasepool {
MTLStencilDescriptor *desc = (MTLStencilDescriptor *)descriptor;
desc.stencilFailureOperation = map_vk_stencil_op_to_mtl_stencil_operation(op);
}
}
void
mtl_stencil_descriptor_set_depth_failure_operation(mtl_stencil_descriptor *descriptor, VkStencilOp op)
{
@autoreleasepool {
MTLStencilDescriptor *desc = (MTLStencilDescriptor *)descriptor;
desc.depthFailureOperation = map_vk_stencil_op_to_mtl_stencil_operation(op);
}
}
void
mtl_stencil_descriptor_set_depth_stencil_pass_operation(mtl_stencil_descriptor *descriptor, VkStencilOp op)
{
@autoreleasepool {
MTLStencilDescriptor *desc = (MTLStencilDescriptor *)descriptor;
desc.depthStencilPassOperation = map_vk_stencil_op_to_mtl_stencil_operation(op);
}
}
void
mtl_stencil_descriptor_set_stencil_compare_function(mtl_stencil_descriptor *descriptor, VkCompareOp op)
{
@autoreleasepool {
MTLStencilDescriptor *desc = (MTLStencilDescriptor *)descriptor;
desc.stencilCompareFunction = (MTLCompareFunction)vk_compare_op_to_mtl_compare_function(op);
}
}
void
mtl_stencil_descriptor_set_read_mask(mtl_stencil_descriptor *descriptor, uint32_t mask)
{
@autoreleasepool {
MTLStencilDescriptor *desc = (MTLStencilDescriptor *)descriptor;
desc.readMask = mask;
}
}
void
mtl_stencil_descriptor_set_write_mask(mtl_stencil_descriptor *descriptor, uint32_t mask)
{
@autoreleasepool {
MTLStencilDescriptor *desc = (MTLStencilDescriptor *)descriptor;
desc.writeMask = mask;
}
}
/* Depth stencil descriptor */
mtl_depth_stencil_descriptor *
mtl_new_depth_stencil_descriptor()
{
@autoreleasepool {
return [[MTLDepthStencilDescriptor new] init];
}
}
void
mtl_depth_stencil_descriptor_set_depth_compare_function(mtl_depth_stencil_descriptor *descriptor, VkCompareOp op)
{
@autoreleasepool {
MTLDepthStencilDescriptor *desc = (MTLDepthStencilDescriptor *)descriptor;
desc.depthCompareFunction = (MTLCompareFunction)vk_compare_op_to_mtl_compare_function(op);
}
}
void
mtl_depth_stencil_descriptor_set_depth_write_enabled(mtl_depth_stencil_descriptor *descriptor, bool enable_write)
{
@autoreleasepool {
MTLDepthStencilDescriptor *desc = (MTLDepthStencilDescriptor *)descriptor;
desc.depthWriteEnabled = enable_write;
}
}
void
mtl_depth_stencil_descriptor_set_back_face_stencil(mtl_depth_stencil_descriptor *descriptor, mtl_stencil_descriptor *stencil_descriptor)
{
@autoreleasepool {
MTLDepthStencilDescriptor *desc = (MTLDepthStencilDescriptor *)descriptor;
desc.backFaceStencil = (MTLStencilDescriptor *)stencil_descriptor;
}
}
void
mtl_depth_stencil_descriptor_set_front_face_stencil(mtl_depth_stencil_descriptor *descriptor, mtl_stencil_descriptor *stencil_descriptor)
{
@autoreleasepool {
MTLDepthStencilDescriptor *desc = (MTLDepthStencilDescriptor *)descriptor;
desc.frontFaceStencil = (MTLStencilDescriptor *)stencil_descriptor;
}
}
mtl_depth_stencil_state *
mtl_new_depth_stencil_state(mtl_device *device, mtl_depth_stencil_descriptor *descriptor)
{
@autoreleasepool {
id<MTLDevice> dev = (id<MTLDevice>)device;
MTLDepthStencilDescriptor *desc = (MTLDepthStencilDescriptor *)descriptor;
return [dev newDepthStencilStateWithDescriptor:desc];
}
}
@@ -0,0 +1,21 @@
/*
* Copyright 2025 LunarG, Inc.
* Copyright 2025 Google LLC
* SPDX-License-Identifier: MIT
*/
#ifndef MTL_RESIDENCY_SET_H
#define MTL_RESIDENCY_SET_H 1
#include "mtl_types.h"
mtl_residency_set *mtl_new_residency_set(mtl_device *device);
void mtl_residency_set_add_allocation(mtl_residency_set *residency_set,
mtl_allocation *allocation);
void mtl_residency_set_remove_allocation(mtl_residency_set *residency_set,
mtl_allocation *allocation);
void mtl_residency_set_commit(mtl_residency_set *residency_set);
void mtl_residency_set_request_residency(mtl_residency_set *residency_set);
void mtl_residency_set_end_residency(mtl_residency_set *residency_set);
#endif /* MTL_RESIDENCY_SET_H */
@@ -0,0 +1,78 @@
/*
* Copyright 2025 LunarG, Inc.
* Copyright 2025 Google LLC
* SPDX-License-Identifier: MIT
*/
#include "mtl_residency_set.h"
#include <Metal/MTLDevice.h>
#include <Metal/MTLResidencySet.h>
mtl_residency_set *
mtl_new_residency_set(mtl_device *device)
{
@autoreleasepool {
id<MTLDevice> dev = (id<MTLDevice>)device;
MTLResidencySetDescriptor *setDescriptor = [[[MTLResidencySetDescriptor alloc] init] autorelease];
setDescriptor.initialCapacity = 100;
NSError *error;
id<MTLResidencySet> set = [dev newResidencySetWithDescriptor:setDescriptor
error:&error];
if (error != nil) {
fprintf(stderr, "Failed to create MTLResidencySet: %s\n", [error.localizedDescription UTF8String]);
}
return set;
}
}
void
mtl_residency_set_add_allocation(mtl_residency_set *residency_set,
mtl_allocation *allocation)
{
@autoreleasepool {
id<MTLResidencySet> set = (id<MTLResidencySet>)residency_set;
id<MTLAllocation> alloc = (id<MTLAllocation>)allocation;
[set addAllocation:alloc];
}
}
void
mtl_residency_set_remove_allocation(mtl_residency_set *residency_set,
mtl_allocation *allocation)
{
@autoreleasepool {
id<MTLResidencySet> set = (id<MTLResidencySet>)residency_set;
id<MTLAllocation> alloc = (id<MTLAllocation>)allocation;
[set removeAllocation:alloc];
}
}
void
mtl_residency_set_commit(mtl_residency_set *residency_set)
{
@autoreleasepool {
id<MTLResidencySet> set = (id<MTLResidencySet>)residency_set;
[set commit];
}
}
void
mtl_residency_set_request_residency(mtl_residency_set *residency_set)
{
@autoreleasepool {
id<MTLResidencySet> set = (id<MTLResidencySet>)residency_set;
[set requestResidency];
}
}
void
mtl_residency_set_end_residency(mtl_residency_set *residency_set)
{
@autoreleasepool {
id<MTLResidencySet> set = (id<MTLResidencySet>)residency_set;
[set endResidency];
}
}
+50
View File
@@ -0,0 +1,50 @@
/*
* Copyright 2025 LunarG, Inc.
* Copyright 2025 Google LLC
* SPDX-License-Identifier: MIT
*/
#ifndef MTL_SAMPLER_H
#define MTL_SAMPLER_H 1
#include "mtl_types.h"
#include <inttypes.h>
#include <stdbool.h>
/* Sampler descriptor */
mtl_sampler_descriptor *mtl_new_sampler_descriptor(void);
/* Sampler descriptor utils */
void mtl_sampler_descriptor_set_normalized_coordinates(
mtl_sampler_descriptor *descriptor, bool normalized_coordinates);
void mtl_sampler_descriptor_set_address_mode(
mtl_sampler_descriptor *descriptor,
enum mtl_sampler_address_mode address_mode_u,
enum mtl_sampler_address_mode address_mode_v,
enum mtl_sampler_address_mode address_mode_w);
void
mtl_sampler_descriptor_set_border_color(mtl_sampler_descriptor *descriptor,
enum mtl_sampler_border_color color);
void
mtl_sampler_descriptor_set_filters(mtl_sampler_descriptor *descriptor,
enum mtl_sampler_min_mag_filter min_filter,
enum mtl_sampler_min_mag_filter mag_filter,
enum mtl_sampler_mip_filter mip_filter);
void mtl_sampler_descriptor_set_lod_clamp(mtl_sampler_descriptor *descriptor,
float min, float max);
void
mtl_sampler_descriptor_set_max_anisotropy(mtl_sampler_descriptor *descriptor,
uint64_t max);
void
mtl_sampler_descriptor_set_compare_function(mtl_sampler_descriptor *descriptor,
enum mtl_compare_function function);
/* Sampler */
mtl_sampler *mtl_new_sampler(mtl_device *device,
mtl_sampler_descriptor *descriptor);
/* Sampler utils */
uint64_t mtl_sampler_get_gpu_resource_id(mtl_sampler *sampler);
#endif /* MTL_SAMPLER_H */
+118
View File
@@ -0,0 +1,118 @@
/*
* Copyright 2025 LunarG, Inc.
* Copyright 2025 Google LLC
* SPDX-License-Identifier: MIT
*/
#include "mtl_sampler.h"
#include <Metal/MTLSampler.h>
mtl_sampler_descriptor *
mtl_new_sampler_descriptor()
{
@autoreleasepool {
MTLSamplerDescriptor *descriptor = [MTLSamplerDescriptor new];
/* Set common variables we don't expose */
descriptor.lodAverage = false;
descriptor.supportArgumentBuffers = true;
return descriptor;
}
}
void
mtl_sampler_descriptor_set_normalized_coordinates(mtl_sampler_descriptor *descriptor, bool normalized_coordinates)
{
@autoreleasepool {
MTLSamplerDescriptor *desc = (MTLSamplerDescriptor *)descriptor;
desc.normalizedCoordinates = normalized_coordinates;
}
}
void
mtl_sampler_descriptor_set_address_mode(mtl_sampler_descriptor *descriptor,
enum mtl_sampler_address_mode address_mode_u,
enum mtl_sampler_address_mode address_mode_v,
enum mtl_sampler_address_mode address_mode_w)
{
@autoreleasepool {
MTLSamplerDescriptor *desc = (MTLSamplerDescriptor *)descriptor;
desc.sAddressMode = (MTLSamplerAddressMode)address_mode_u;
desc.tAddressMode = (MTLSamplerAddressMode)address_mode_v;
desc.rAddressMode = (MTLSamplerAddressMode)address_mode_w;
}
}
void
mtl_sampler_descriptor_set_border_color(mtl_sampler_descriptor *descriptor, enum mtl_sampler_border_color color)
{
@autoreleasepool {
MTLSamplerDescriptor *desc = (MTLSamplerDescriptor *)descriptor;
desc.borderColor = (MTLSamplerBorderColor)color;
}
}
void
mtl_sampler_descriptor_set_filters(mtl_sampler_descriptor *descriptor,
enum mtl_sampler_min_mag_filter min_filter,
enum mtl_sampler_min_mag_filter mag_filter,
enum mtl_sampler_mip_filter mip_filter)
{
@autoreleasepool {
MTLSamplerDescriptor *desc = (MTLSamplerDescriptor *)descriptor;
desc.minFilter = (MTLSamplerMinMagFilter)min_filter;
desc.magFilter = (MTLSamplerMinMagFilter)mag_filter;
desc.mipFilter = (MTLSamplerMipFilter)mip_filter;
}
}
void
mtl_sampler_descriptor_set_lod_clamp(mtl_sampler_descriptor *descriptor,
float min,
float max)
{
@autoreleasepool {
MTLSamplerDescriptor *desc = (MTLSamplerDescriptor *)descriptor;
desc.lodMinClamp = min;
desc.lodMaxClamp = max;
}
}
void
mtl_sampler_descriptor_set_max_anisotropy(mtl_sampler_descriptor *descriptor,
uint64_t max)
{
@autoreleasepool {
MTLSamplerDescriptor *desc = (MTLSamplerDescriptor *)descriptor;
desc.maxAnisotropy = max ? max : 1u; /* Metal requires a non-zero value */
}
}
void
mtl_sampler_descriptor_set_compare_function(mtl_sampler_descriptor *descriptor,
enum mtl_compare_function function)
{
@autoreleasepool {
MTLSamplerDescriptor *desc = (MTLSamplerDescriptor *)descriptor;
desc.compareFunction = (MTLCompareFunction)function;
}
}
mtl_sampler *
mtl_new_sampler(mtl_device *device, mtl_sampler_descriptor *descriptor)
{
@autoreleasepool {
id<MTLDevice> dev = (id<MTLDevice>)device;
MTLSamplerDescriptor *desc = (MTLSamplerDescriptor *)descriptor;
return [dev newSamplerStateWithDescriptor:desc];
}
}
uint64_t
mtl_sampler_get_gpu_resource_id(mtl_sampler *sampler)
{
@autoreleasepool {
id<MTLSamplerState> samp = (id<MTLSamplerState>)sampler;
return [samp gpuResourceID]._impl;
}
}
+29
View File
@@ -0,0 +1,29 @@
/*
* Copyright 2025 LunarG, Inc.
* Copyright 2025 Google LLC
* SPDX-License-Identifier: MIT
*/
#ifndef MTL_SYNC_H
#define MTL_SYNC_H 1
#include "mtl_types.h"
#include <inttypes.h>
/* MTLFence */
mtl_fence *mtl_new_fence(mtl_device *device);
/* MTLEvent */
mtl_event *mtl_new_event(mtl_device *device);
/* MTLSharedEvent */
mtl_shared_event *mtl_new_shared_event(mtl_device *device);
int mtl_shared_event_wait_until_signaled_value(mtl_shared_event *event_handle,
uint64_t value,
uint64_t timeout_ms);
uint64_t mtl_shared_event_get_signaled_value(mtl_shared_event *event_handle);
void mtl_shared_event_set_signaled_value(mtl_shared_event *event_handle,
uint64_t value);
#endif /* MTL_SYNC_H */
+66
View File
@@ -0,0 +1,66 @@
/*
* Copyright 2025 LunarG, Inc.
* Copyright 2025 Google LLC
* SPDX-License-Identifier: MIT
*/
#include "mtl_sync.h"
#include <Metal/MTLEvent.h>
/* MTLFence */
mtl_fence *
mtl_new_fence(mtl_device *device)
{
@autoreleasepool {
id<MTLDevice> dev = (id<MTLDevice>)device;
return (mtl_fence *)[dev newFence];
}
}
/* MTLEvent */
mtl_event *
mtl_new_event(mtl_device *device)
{
@autoreleasepool {
id<MTLDevice> dev = (id<MTLDevice>)device;
return [dev newEvent];
}
}
/* MTLSharedEvent */
mtl_shared_event *
mtl_new_shared_event(mtl_device *device)
{
@autoreleasepool {
id<MTLDevice> dev = (id<MTLDevice>)device;
return [dev newSharedEvent];
}
}
int
mtl_shared_event_wait_until_signaled_value(mtl_shared_event *event_handle, uint64_t value, uint64_t timeout_ms)
{
@autoreleasepool {
id<MTLSharedEvent> event = (id<MTLSharedEvent>)event_handle;
return (int)[event waitUntilSignaledValue:value timeoutMS:timeout_ms];
}
}
void
mtl_shared_event_set_signaled_value(mtl_shared_event *event_handle, uint64_t value)
{
@autoreleasepool {
id<MTLSharedEvent> event = (id<MTLSharedEvent>)event_handle;
event.signaledValue = value;
}
}
uint64_t
mtl_shared_event_get_signaled_value(mtl_shared_event *event_handle)
{
@autoreleasepool {
id<MTLSharedEvent> event = (id<MTLSharedEvent>)event_handle;
return event.signaledValue;
}
}
+33
View File
@@ -0,0 +1,33 @@
/*
* Copyright 2025 LunarG, Inc.
* Copyright 2025 Google LLC
* SPDX-License-Identifier: MIT
*/
#ifndef MTL_TEXTURE_H
#define MTL_TEXTURE_H 1
#include "mtl_types.h"
#include <inttypes.h>
/* TODO_KOSMICKRISP Move this to bridge. */
struct kk_view_layout;
/* Utils*/
uint64_t mtl_texture_get_gpu_resource_id(mtl_texture *texture);
/* Texture view creation */
mtl_texture *mtl_new_texture_view_with(mtl_texture *texture,
const struct kk_view_layout *layout);
mtl_texture *
mtl_new_texture_view_with_no_swizzle(mtl_texture *texture,
const struct kk_view_layout *layout);
void mtl_texture_get_bytes(mtl_texture *texture, void *host_ptr,
struct mtl_texture_memory_copy *data);
void mtl_texture_replace_region(mtl_texture *texture, const void *host_ptr,
struct mtl_texture_memory_copy *data);
#endif /* MTL_TEXTURE_H */
+127
View File
@@ -0,0 +1,127 @@
/*
* Copyright 2025 LunarG, Inc.
* Copyright 2025 Google LLC
* SPDX-License-Identifier: MIT
*/
#include "mtl_texture.h"
/* TODO_LUNARG Remove */
#include "kk_image_layout.h"
/* TODO_LUNARG Remove */
#include "vulkan/vulkan.h"
#include <Metal/MTLTexture.h>
uint64_t
mtl_texture_get_gpu_resource_id(mtl_texture *texture)
{
@autoreleasepool {
id<MTLTexture> tex = (id<MTLTexture>)texture;
return (uint64_t)[tex gpuResourceID]._impl;
}
}
/* TODO_KOSMICKRISP This should be part of the mapping */
static uint32_t
mtl_texture_view_type(uint32_t type, uint8_t sample_count)
{
switch (type) {
case VK_IMAGE_VIEW_TYPE_1D:
return MTLTextureType1D;
case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
return MTLTextureType1DArray;
case VK_IMAGE_VIEW_TYPE_2D:
return sample_count > 1u ? MTLTextureType2DMultisample : MTLTextureType2D;;
case VK_IMAGE_VIEW_TYPE_CUBE:
return MTLTextureTypeCube;
case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
return MTLTextureTypeCubeArray;
case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
return sample_count > 1u ? MTLTextureType2DMultisampleArray : MTLTextureType2DArray;
case VK_IMAGE_VIEW_TYPE_3D:
return MTLTextureType3D;
default:
assert(false && "Unsupported VkViewType");
return MTLTextureType1D;
}
}
static MTLTextureSwizzle
mtl_texture_swizzle(enum pipe_swizzle swizzle)
{
const MTLTextureSwizzle map[] =
{
[PIPE_SWIZZLE_X] = MTLTextureSwizzleRed,
[PIPE_SWIZZLE_Y] = MTLTextureSwizzleGreen,
[PIPE_SWIZZLE_Z] = MTLTextureSwizzleBlue,
[PIPE_SWIZZLE_W] = MTLTextureSwizzleAlpha,
[PIPE_SWIZZLE_0] = MTLTextureSwizzleZero,
[PIPE_SWIZZLE_1] = MTLTextureSwizzleOne,
};
return map[swizzle];
}
mtl_texture *
mtl_new_texture_view_with(mtl_texture *texture, const struct kk_view_layout *layout)
{
@autoreleasepool {
id<MTLTexture> tex = (id<MTLTexture>)texture;
MTLTextureType type = mtl_texture_view_type(layout->view_type, layout->sample_count_sa);
NSRange levels = NSMakeRange(layout->base_level, layout->num_levels);
NSRange slices = NSMakeRange(layout->base_array_layer, layout->array_len);
MTLTextureSwizzleChannels swizzle = MTLTextureSwizzleChannelsMake(mtl_texture_swizzle(layout->swizzle.red),
mtl_texture_swizzle(layout->swizzle.green),
mtl_texture_swizzle(layout->swizzle.blue),
mtl_texture_swizzle(layout->swizzle.alpha));
return [tex newTextureViewWithPixelFormat:layout->format.mtl textureType:type levels:levels slices:slices swizzle:swizzle];
}
}
mtl_texture *
mtl_new_texture_view_with_no_swizzle(mtl_texture *texture, const struct kk_view_layout *layout)
{
@autoreleasepool {
id<MTLTexture> tex = (id<MTLTexture>)texture;
MTLTextureType type = mtl_texture_view_type(layout->view_type, layout->sample_count_sa);
NSRange levels = NSMakeRange(layout->base_level, layout->num_levels);
NSRange slices = NSMakeRange(layout->base_array_layer, layout->array_len);
return [tex newTextureViewWithPixelFormat:layout->format.mtl textureType:type levels:levels slices:slices];
}
}
void
mtl_texture_get_bytes(mtl_texture *texture, void *host_ptr,
struct mtl_texture_memory_copy *data)
{
@autoreleasepool {
id<MTLTexture> tex = (id<MTLTexture>)texture;
MTLRegion region = MTLRegionMake3D(data->image_origin.x, data->image_origin.y, data->image_origin.z,
data->image_size.x, data->image_size.y, data->image_size.z);
return [tex getBytes:host_ptr
bytesPerRow:data->buffer_stride_B
bytesPerImage:data->buffer_2d_image_size_B
fromRegion:region
mipmapLevel:data->image_level
slice:data->image_slice];
}
}
void
mtl_texture_replace_region(mtl_texture *texture, const void *host_ptr,
struct mtl_texture_memory_copy *data)
{
@autoreleasepool {
id<MTLTexture> tex = (id<MTLTexture>)texture;
MTLRegion region = MTLRegionMake3D(data->image_origin.x, data->image_origin.y, data->image_origin.z,
data->image_size.x, data->image_size.y, data->image_size.z);
return [tex replaceRegion:region
mipmapLevel:data->image_level
slice:data->image_slice
withBytes:host_ptr
bytesPerRow:data->buffer_stride_B
bytesPerImage:data->buffer_2d_image_size_B];
}
}
+293
View File
@@ -0,0 +1,293 @@
/*
* Copyright 2025 LunarG, Inc.
* Copyright 2025 Google LLC
* SPDX-License-Identifier: MIT
*
* Structures and enums found in this file are a 1-1 mapping of Metal's
* equivalents
*/
#ifndef KK_MTL_TYPES_H
#define KK_MTL_TYPES_H 1
#include <stddef.h> /* For size_t definition */
/** HANDLES */
typedef void mtl_device;
typedef void mtl_heap;
typedef void mtl_buffer;
typedef void mtl_texture;
typedef void mtl_command_queue;
typedef void mtl_command_buffer;
typedef void mtl_command_encoder;
typedef void mtl_blit_encoder;
typedef void mtl_compute_encoder;
typedef void mtl_render_encoder;
typedef void mtl_event;
typedef void mtl_shared_event;
typedef void mtl_sampler_descriptor;
typedef void mtl_sampler;
typedef void mtl_compute_pipeline_state;
typedef void mtl_library;
typedef void mtl_render_pipeline_state;
typedef void mtl_function;
typedef void mtl_resource;
typedef void mtl_render_pass_descriptor;
typedef void mtl_render_pipeline_descriptor;
typedef void mtl_fence;
typedef void mtl_stencil_descriptor;
typedef void mtl_depth_stencil_descriptor;
typedef void mtl_depth_stencil_state;
typedef void mtl_render_pass_attachment_descriptor;
typedef void mtl_residency_set;
typedef void mtl_allocation;
/** ENUMS */
enum mtl_cpu_cache_mode {
MTL_CPU_CACHE_MODE_DEFAULT_CACHE = 0,
MTL_CPU_CACHE_MODE_WRITE_COMBINED = 1,
};
enum mtl_storage_mode {
MTL_STORAGE_MODE_SHARED = 0,
MTL_STORAGE_MODE_MANAGED = 1,
MTL_STORAGE_MODE_PRIVATE = 2,
MTL_STORAGE_MODE_MEMORYLESS = 3,
};
enum mtl_hazard_tracking_mode {
MTL_HAZARD_TRACKING_MODE_DFEAULT = 0,
MTL_HAZARD_TRACKING_MODE_UNTRACKED = 1,
MTL_HAZARD_TRACKING_MODE_TRACKED = 2,
};
#define MTL_RESOURCE_CPU_CACHE_MODE_SHIFT 0
#define MTL_RESOURCE_STORAGE_MODE_SHIFT 4
#define MTL_RESOURCE_HAZARD_TRACKING_MODE_SHIFT 8
enum mtl_resource_options {
MTL_RESOURCE_CPU_CACHE_MODE_DEFAULT_CACHE =
MTL_CPU_CACHE_MODE_DEFAULT_CACHE << MTL_RESOURCE_CPU_CACHE_MODE_SHIFT,
MTL_RESOURCE_CPU_CACHE_MODE_WRITE_COMBINED =
MTL_CPU_CACHE_MODE_WRITE_COMBINED << MTL_RESOURCE_CPU_CACHE_MODE_SHIFT,
MTL_RESOURCE_STORAGE_MODE_SHARED = MTL_STORAGE_MODE_SHARED
<< MTL_RESOURCE_STORAGE_MODE_SHIFT,
MTL_RESOURCE_STORAGE_MODE_PRIVATE = MTL_STORAGE_MODE_PRIVATE
<< MTL_RESOURCE_STORAGE_MODE_SHIFT,
MTL_RESOURCE_TRACKING_MODE_DEFAULT =
MTL_HAZARD_TRACKING_MODE_DFEAULT
<< MTL_RESOURCE_HAZARD_TRACKING_MODE_SHIFT,
MTL_RESOURCE_TRACKING_MODE_UNTRACKED =
MTL_HAZARD_TRACKING_MODE_UNTRACKED
<< MTL_RESOURCE_HAZARD_TRACKING_MODE_SHIFT,
MTL_RESOURCE_TRACKING_MODE_TRACKED =
MTL_HAZARD_TRACKING_MODE_TRACKED
<< MTL_RESOURCE_HAZARD_TRACKING_MODE_SHIFT,
};
enum mtl_blit_options {
MTL_BLIT_OPTION_NONE = 0,
MTL_BLIT_OPTION_DEPTH_FROM_DEPTH_STENCIL = 1 << 0,
MTL_BLIT_OPTION_STENCIL_FROM_DEPTH_STENCIL = 1 << 1,
};
enum mtl_resource_usage {
MTL_RESOURCE_USAGE_READ = 1 << 0,
MTL_RESOURCE_USAGE_WRITE = 1 << 1,
};
enum mtl_primitive_type {
MTL_PRIMITIVE_TYPE_POINT = 0,
MTL_PRIMITIVE_TYPE_LINE = 1,
MTL_PRIMITIVE_TYPE_LINE_STRIP = 2,
MTL_PRIMITIVE_TYPE_TRIANGLE = 3,
MTL_PRIMITIVE_TYPE_TRIANGLE_STRIP = 4,
};
enum mtl_primitive_topology_class {
MTL_PRIMITIVE_TOPOLOGY_CLASS_UNSPECIFIED = 0,
MTL_PRIMITIVE_TOPOLOGY_CLASS_POINT = 1,
MTL_PRIMITIVE_TOPOLOGY_CLASS_LINE = 2,
MTL_PRIMITIVE_TOPOLOGY_CLASS_TRIANGLE = 3,
};
enum mtl_texture_type {
MTL_TEXTURE_TYPE_1D = 0u,
MTL_TEXTURE_TYPE_1D_ARRAY = 1u,
MTL_TEXTURE_TYPE_2D = 2u,
MTL_TEXTURE_TYPE_2D_ARRAY = 3u,
MTL_TEXTURE_TYPE_2D_MULTISAMPLE = 4u,
MTL_TEXTURE_TYPE_CUBE = 5u,
MTL_TEXTURE_TYPE_CUBE_ARRAY = 6u,
MTL_TEXTURE_TYPE_3D = 7u,
MTL_TEXTURE_TYPE_2D_ARRAY_MULTISAMPLE = 8u,
MTL_TEXTURE_TYPE_TEXTURE_BUFFER = 9u,
};
enum mtl_texture_usage {
MTL_TEXTURE_USAGE_UNKNOWN = 0x0000,
MTL_TEXTURE_USAGE_SHADER_READ = 0x0001,
MTL_TEXTURE_USAGE_SHADER_WRITE = 0X0002,
MTL_TEXTURE_USAGE_RENDER_TARGET = 0X0004,
MTL_TEXTURE_USAGE_PIXEL_FORMAT_VIEW = 0X0010,
MTL_TEXTURE_USAGE_SHADER_ATOMIC = 0X0020,
};
enum mtl_load_action {
MTL_LOAD_ACTION_DONT_CARE = 0u,
MTL_LOAD_ACTION_LOAD = 1u,
MTL_LOAD_ACTION_CLEAR = 2u,
};
enum mtl_store_action {
MTL_STORE_ACTION_DONT_CARE = 0u,
MTL_STORE_ACTION_STORE = 1u,
MTL_STORE_ACTION_MULTISAMPLE_RESOLVE = 2u,
MTL_STORE_ACTION_STORE_AND_MULTISAMPLE_RESOLVE = 3u,
MTL_STORE_ACTION_UNKNOWN = 4u,
MTL_STORE_ACTION_CUSTOM_SAMPLE_DEPTH_STORE = 5u,
};
enum mtl_texture_swizzle {
MTL_TEXTURE_SWIZZLE_ZERO = 0,
MTL_TEXTURE_SWIZZLE_ONE = 1,
MTL_TEXTURE_SWIZZLE_RED = 2,
MTL_TEXTURE_SWIZZLE_GREEN = 3,
MTL_TEXTURE_SWIZZLE_BLUE = 4,
MTL_TEXTURE_SWIZZLE_ALPHA = 5,
};
enum mtl_index_type {
MTL_INDEX_TYPE_UINT16 = 0,
MTL_INDEX_TYPE_UINT32 = 1,
};
enum mtl_sampler_address_mode {
MTL_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE = 0,
MTL_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE = 1,
MTL_SAMPLER_ADDRESS_MODE_REPEAT = 2,
MTL_SAMPLER_ADDRESS_MODE_MIRROR_REPEAT = 3,
MTL_SAMPLER_ADDRESS_MODE_CLAMP_TO_ZERO = 4,
MTL_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER_COLOR = 5,
};
enum mtl_sampler_border_color {
MTL_SAMPLER_BORDER_COLOR_TRANSPARENT_BLACK = 0,
MTL_SAMPLER_BORDER_COLOR_OPAQUE_BLACK = 1,
MTL_SAMPLER_BORDER_COLOR_OPAQUE_WHITE = 2,
};
enum mtl_sampler_min_mag_filter {
MTL_SAMPLER_MIN_MAG_FILTER_NEAREST = 0,
MTL_SAMPLER_MIN_MAG_FILTER_LINEAR = 1,
};
enum mtl_sampler_mip_filter {
MTL_SAMPLER_MIP_FILTER_NOT_MIP_MAPPED = 0,
MTL_SAMPLER_MIP_FILTER_NEAREST = 1,
MTL_SAMPLER_MIP_FILTER_LINEAR = 2,
};
enum mtl_compare_function {
MTL_COMPARE_FUNCTION_NEVER = 0,
MTL_COMPARE_FUNCTION_LESS = 1,
MTL_COMPARE_FUNCTION_EQUAL = 2,
MTL_COMPARE_FUNCTION_LESS_EQUAL = 3,
MTL_COMPARE_FUNCTION_GREATER = 4,
MTL_COMPARE_FUNCTION_NOT_EQUAL = 5,
MTL_COMPARE_FUNCTION_GREATER_EQUAL = 6,
MTL_COMPARE_FUNCTION_ALWAYS = 7,
};
enum mtl_winding {
MTL_WINDING_CLOCKWISE = 0,
MTL_WINDING_COUNTER_CLOCKWISE = 1,
};
enum mtl_cull_mode {
MTL_CULL_MODE_NONE = 0,
MTL_CULL_MODE_FRONT = 1,
MTL_CULL_MODE_BACK = 2,
};
enum mtl_visibility_result_mode {
MTL_VISIBILITY_RESULT_MODE_DISABLED = 0,
MTL_VISIBILITY_RESULT_MODE_BOOLEAN = 1,
MTL_VISIBILITY_RESULT_MODE_COUNTING = 2,
};
enum mtl_depth_clip_mode {
MTL_DEPTH_CLIP_MODE_CLIP = 0,
MTL_DEPTH_CLIP_MODE_CLAMP = 1,
};
enum mtl_barrier_scope {
MTL_BARRIER_SCOPE_BUFFERS = 1 << 0,
MTL_BARRIER_SCOPE_TEXTURES = 1 << 1,
MTL_BARRIER_SCOPE_RENDER_TARGETS = 1 << 2,
};
/** STRUCTURES */
struct mtl_range {
size_t offset;
size_t length;
};
struct mtl_origin {
size_t x, y, z;
};
struct mtl_size {
size_t x, y, z;
};
struct mtl_sample_position {
float x, y;
};
struct mtl_viewport {
double originX, originY, width, height, znear, zfar;
};
struct mtl_clear_color {
union {
struct {
double red, green, blue, alpha;
};
double channel[4];
};
};
struct mtl_scissor_rect {
size_t x, y, width, height;
};
struct mtl_texture_swizzle_channels {
enum mtl_texture_swizzle red;
enum mtl_texture_swizzle green;
enum mtl_texture_swizzle blue;
enum mtl_texture_swizzle alpha;
};
struct mtl_buffer_image_copy {
struct mtl_size image_size;
struct mtl_origin image_origin;
mtl_buffer *buffer;
mtl_texture *image;
size_t buffer_offset_B;
size_t buffer_stride_B;
size_t buffer_2d_image_size_B;
size_t image_slice;
size_t image_level;
enum mtl_blit_options options;
};
struct mtl_texture_memory_copy {
struct mtl_size image_size;
struct mtl_origin image_origin;
size_t buffer_stride_B;
size_t buffer_2d_image_size_B;
size_t image_slice;
size_t image_level;
};
#endif /* KK_MTL_TYPES_H */
+24
View File
@@ -0,0 +1,24 @@
/*
* Copyright 2025 LunarG, Inc.
* Copyright 2025 Google LLC
* SPDX-License-Identifier: MIT
*/
#include "mtl_bridge.h"
mtl_texture *
mtl_drawable_get_texture(void *drawable_ptr)
{
return NULL;
}
void *
mtl_retain(void *handle)
{
return NULL;
}
void
mtl_release(void *handle)
{
}
+33
View File
@@ -0,0 +1,33 @@
/*
* Copyright 2025 LunarG, Inc.
* Copyright 2025 Google LLC
* SPDX-License-Identifier: MIT
*/
#include "mtl_buffer.h"
uint64_t
mtl_buffer_get_length(mtl_buffer *buffer)
{
return 0u;
}
uint64_t
mtl_buffer_get_gpu_address(mtl_buffer *buffer)
{
return 0u;
}
void *
mtl_get_contents(mtl_buffer *buffer)
{
return NULL;
}
mtl_texture *
mtl_new_texture_with_descriptor_linear(mtl_buffer *buffer,
const struct kk_image_layout *layout,
uint64_t offset)
{
return NULL;
}
@@ -0,0 +1,35 @@
/*
* Copyright 2025 LunarG, Inc.
* Copyright 2025 Google LLC
* SPDX-License-Identifier: MIT
*/
#include "mtl_command_buffer.h"
void
mtl_encode_signal_event(mtl_command_buffer *cmd_buf_handle,
mtl_event *event_handle, uint64_t value)
{
}
void
mtl_encode_wait_for_event(mtl_command_buffer *cmd_buf_handle,
mtl_event *event_handle, uint64_t value)
{
}
void
mtl_add_completed_handler(mtl_command_buffer *cmd, void (*callback)(void *data),
void *data)
{
}
void
mtl_command_buffer_commit(mtl_command_buffer *cmd_buf)
{
}
void
mtl_present_drawable(mtl_command_buffer *cmd_buf, void *drawable)
{
}
@@ -0,0 +1,31 @@
/*
* Copyright 2025 LunarG, Inc.
* Copyright 2025 Google LLC
* SPDX-License-Identifier: MIT
*/
#include "mtl_command_queue.h"
mtl_command_queue *
mtl_new_command_queue(mtl_device *device, uint32_t cmd_buffer_count)
{
return NULL;
}
mtl_command_buffer *
mtl_new_command_buffer(mtl_command_queue *cmd_queue)
{
return NULL;
}
void
mtl_command_queue_add_residency_set(mtl_command_queue *cmd_queue,
mtl_residency_set *set)
{
}
void
mtl_command_queue_remove_residency_set(mtl_command_queue *cmd_queue,
mtl_residency_set *set)
{
}
@@ -0,0 +1,14 @@
/*
* Copyright 2025 LunarG, Inc.
* Copyright 2025 Google LLC
* SPDX-License-Identifier: MIT
*/
#include "mtl_compute_state.h"
mtl_compute_pipeline_state *
mtl_new_compute_pipeline_state(mtl_device *device, mtl_function *function,
uint64_t max_total_threads_per_threadgroup)
{
return NULL;
}
+146
View File
@@ -0,0 +1,146 @@
/*
* Copyright 2025 LunarG, Inc.
* Copyright 2025 Google LLC
* SPDX-License-Identifier: MIT
*/
#include "mtl_device.h"
/* Device creation */
mtl_device *
mtl_device_create(void)
{
return NULL;
}
/* Device operations */
void
mtl_start_gpu_capture(mtl_device *mtl_dev_handle, const char *directory)
{
}
void
mtl_stop_gpu_capture(void)
{
}
/* Device feature query */
void
mtl_device_get_name(mtl_device *dev, char buffer[256])
{
}
void
mtl_device_get_architecture_name(mtl_device *dev, char buffer[256])
{
}
uint64_t
mtl_device_get_peer_group_id(mtl_device *dev)
{
return 0u;
}
uint32_t
mtl_device_get_peer_index(mtl_device *dev)
{
return 0u;
}
uint64_t
mtl_device_get_registry_id(mtl_device *dev)
{
return 0u;
}
bool
mtl_device_supports_sample_count(mtl_device *dev, uint32_t sample_count)
{
return false;
}
struct mtl_size
mtl_device_max_threads_per_threadgroup(mtl_device *dev)
{
return (struct mtl_size){};
}
uint32_t
mtl_device_max_threadgroup_memory_length(mtl_device *dev)
{
return 0u;
}
uint64_t
mtl_device_max_buffer_length(mtl_device *dev)
{
return 0u;
}
uint64_t
mtl_device_recommended_max_working_set_size(mtl_device *dev)
{
return 0u;
}
uint64_t
mtl_device_current_allocated_size(mtl_device *dev)
{
return 0u;
}
/* Timestamp query */
uint64_t
mtl_device_get_gpu_timestamp(mtl_device *dev)
{
return 0u;
}
/* Resource queries */
void
mtl_heap_buffer_size_and_align_with_length(mtl_device *device, uint64_t *size_B,
uint64_t *align_B)
{
}
uint64_t
mtl_minimum_linear_texture_alignment_for_pixel_format(
mtl_device *device, enum mtl_pixel_format format)
{
return 0u;
}
void
mtl_heap_texture_size_and_align_with_descriptor(mtl_device *device,
struct kk_image_layout *layout,
uint64_t *size_B,
uint64_t *align_B)
{
}
uint32_t
mtl_sparse_tile_size_in_bytes(mtl_device *device)
{
return 0u;
}
struct mtl_size
mtl_sparse_tile_size(mtl_device *device, struct kk_image_layout *layout)
{
return (struct mtl_size){};
}
struct mtl_size
mtl_sparse_tile_count(mtl_device *device, struct kk_image_layout *layout,
struct mtl_size tile_size)
{
return (struct mtl_size){};
}
/* Resource creation */
mtl_buffer *
mtl_new_buffer_with_bytes_no_copy(mtl_device *device, void *ptr,
uint64_t size_B)
{
return NULL;
}
+278
View File
@@ -0,0 +1,278 @@
/*
* Copyright 2025 LunarG, Inc.
* Copyright 2025 Google LLC
* SPDX-License-Identifier: MIT
*/
#include "mtl_encoder.h"
/* Common encoder utils */
void
mtl_end_encoding(void *encoder)
{
}
/* MTLBlitEncoder */
mtl_blit_encoder *
mtl_new_blit_command_encoder(mtl_command_buffer *cmd_buffer)
{
return NULL;
}
void
mtl_blit_update_fence(mtl_blit_encoder *encoder, mtl_fence *fence)
{
}
void
mtl_blit_wait_for_fence(mtl_blit_encoder *encoder, mtl_fence *fence)
{
}
void
mtl_copy_from_buffer_to_buffer(mtl_blit_encoder *blit_enc_handle,
mtl_buffer *src_buf, size_t src_offset,
mtl_buffer *dst_buf, size_t dst_offset,
size_t size)
{
}
void
mtl_copy_from_buffer_to_texture(mtl_blit_encoder *blit_enc_handle,
struct mtl_buffer_image_copy *data)
{
}
void
mtl_copy_from_texture_to_buffer(mtl_blit_encoder *blit_enc_handle,
struct mtl_buffer_image_copy *data)
{
}
void
mtl_copy_from_texture_to_texture(mtl_blit_encoder *blit_enc_handle,
mtl_texture *src_tex_handle, size_t src_slice,
size_t src_level, struct mtl_origin src_origin,
struct mtl_size src_size,
mtl_texture *dst_tex_handle, size_t dst_slice,
size_t dst_level, struct mtl_origin dst_origin)
{
}
void
mtl_memory_barrier_with_scope(mtl_compute_encoder *encoder,
enum mtl_barrier_scope scope)
{
}
/* MTLComputeEncoder */
mtl_compute_encoder *
mtl_new_compute_command_encoder(mtl_command_buffer *cmd_buffer)
{
return NULL;
}
void
mtl_compute_update_fence(mtl_compute_encoder *encoder, mtl_fence *fence)
{
}
void
mtl_compute_wait_for_fence(mtl_compute_encoder *encoder, mtl_fence *fence)
{
}
void
mtl_compute_set_pipeline_state(mtl_compute_encoder *encoder,
mtl_compute_pipeline_state *state_handle)
{
}
void
mtl_compute_set_buffer(mtl_compute_encoder *encoder, mtl_buffer *buffer,
size_t offset, size_t index)
{
}
void
mtl_compute_use_heaps(mtl_compute_encoder *encoder, mtl_heap **heaps,
uint32_t count)
{
}
void
mtl_dispatch_threads(mtl_compute_encoder *encoder, struct mtl_size grid_size,
struct mtl_size local_size)
{
}
void
mtl_dispatch_threadgroups_with_indirect_buffer(mtl_compute_encoder *encoder,
mtl_buffer *buffer,
uint32_t offset,
struct mtl_size local_size)
{
}
/* MTLRenderEncoder */
mtl_render_encoder *
mtl_new_render_command_encoder_with_descriptor(
mtl_command_buffer *command_buffer, mtl_render_pass_descriptor *descriptor)
{
return NULL;
}
void
mtl_render_update_fence(mtl_render_encoder *encoder, mtl_fence *fence)
{
}
void
mtl_render_wait_for_fence(mtl_render_encoder *encoder, mtl_fence *fence)
{
}
void
mtl_set_viewports(mtl_render_encoder *encoder, struct mtl_viewport *viewports,
uint32_t count)
{
}
void
mtl_set_scissor_rects(mtl_render_encoder *encoder,
struct mtl_scissor_rect *scissor_rects, uint32_t count)
{
}
void
mtl_render_set_pipeline_state(mtl_render_encoder *encoder,
mtl_render_pipeline_state *pipeline)
{
}
void
mtl_set_depth_stencil_state(mtl_render_encoder *encoder,
mtl_depth_stencil_state *state)
{
}
void
mtl_set_stencil_references(mtl_render_encoder *encoder, uint32_t front,
uint32_t back)
{
}
void
mtl_set_front_face_winding(mtl_render_encoder *encoder,
enum mtl_winding winding)
{
}
void
mtl_set_cull_mode(mtl_render_encoder *encoder, enum mtl_cull_mode mode)
{
}
void
mtl_set_visibility_result_mode(mtl_render_encoder *encoder,
enum mtl_visibility_result_mode mode,
size_t offset)
{
}
void
mtl_set_depth_bias(mtl_render_encoder *encoder, float depth_bias,
float slope_scale, float clamp)
{
}
void
mtl_set_depth_clip_mode(mtl_render_encoder *encoder,
enum mtl_depth_clip_mode mode)
{
}
void
mtl_set_vertex_amplification_count(mtl_render_encoder *encoder,
uint32_t *layer_ids, uint32_t id_count)
{
}
void
mtl_set_vertex_buffer(mtl_render_encoder *encoder, mtl_buffer *buffer,
uint32_t offset, uint32_t index)
{
}
void
mtl_set_vertex_bytes(mtl_render_encoder *encoder, const void *bytes,
uint32_t length, uint32_t index)
{
}
void
mtl_set_fragment_buffer(mtl_render_encoder *encoder, mtl_buffer *buffer,
uint32_t offset, uint32_t index)
{
}
void
mtl_set_fragment_bytes(mtl_render_encoder *encoder, const void *bytes,
uint32_t length, uint32_t index)
{
}
void
mtl_draw_primitives(mtl_render_encoder *encoder,
enum mtl_primitive_type primitve_type, uint32_t vertexStart,
uint32_t vertexCount, uint32_t instanceCount,
uint32_t baseInstance)
{
}
void
mtl_draw_indexed_primitives(
mtl_render_encoder *encoder, enum mtl_primitive_type primitve_type,
uint32_t index_count, enum mtl_index_type index_type,
mtl_buffer *index_buffer, uint32_t index_buffer_offset,
uint32_t instance_count, int32_t base_vertex, uint32_t base_instance)
{
}
void
mtl_draw_primitives_indirect(mtl_render_encoder *encoder,
enum mtl_primitive_type primitve_type,
mtl_buffer *indirect_buffer,
uint64_t indirect_buffer_offset)
{
}
void
mtl_draw_indexed_primitives_indirect(mtl_render_encoder *encoder,
enum mtl_primitive_type primitve_type,
enum mtl_index_type index_type,
mtl_buffer *index_buffer,
uint32_t index_buffer_offset,
mtl_buffer *indirect_buffer,
uint64_t indirect_buffer_offset)
{
}
void
mtl_render_use_resource(mtl_compute_encoder *encoder, mtl_resource *res_handle,
uint32_t usage)
{
}
void
mtl_render_use_resources(mtl_render_encoder *encoder,
mtl_resource **resource_handles, uint32_t count,
enum mtl_resource_usage usage)
{
}
void
mtl_render_use_heaps(mtl_render_encoder *encoder, mtl_heap **heaps,
uint32_t count)
{
}
+37
View File
@@ -0,0 +1,37 @@
/*
* Copyright 2025 LunarG, Inc.
* Copyright 2025 Google LLC
* SPDX-License-Identifier: MIT
*/
#include "mtl_heap.h"
/* Creation */
mtl_heap *
mtl_new_heap(mtl_device *device, uint64_t size,
enum mtl_resource_options resource_options)
{
return NULL;
}
/* Utils */
uint64_t
mtl_heap_get_size(mtl_heap *heap)
{
return 0u;
}
/* Allocation from heap */
mtl_buffer *
mtl_new_buffer_with_length(mtl_heap *heap, uint64_t size_B, uint64_t offset_B)
{
return NULL;
}
mtl_texture *
mtl_new_texture_with_descriptor(mtl_heap *heap,
const struct kk_image_layout *layout,
uint64_t offset)
{
return NULL;
}
@@ -0,0 +1,19 @@
/*
* Copyright 2025 LunarG, Inc.
* Copyright 2025 Google LLC
* SPDX-License-Identifier: MIT
*/
#include "mtl_library.h"
mtl_library *
mtl_new_library(mtl_device *device, const char *src)
{
return NULL;
}
mtl_function *
mtl_new_function_with_name(mtl_library *lib, const char *entry_point)
{
return NULL;
}
@@ -0,0 +1,295 @@
/*
* Copyright 2025 LunarG, Inc.
* Copyright 2025 Google LLC
* SPDX-License-Identifier: MIT
*/
#include "mtl_render_state.h"
#include "mtl_format.h"
/* TODO_KOSMICKRISP Remove */
#include "vulkan/vulkan.h"
/* Render pass descriptor */
mtl_render_pass_descriptor *
mtl_new_render_pass_descriptor(void)
{
return NULL;
}
mtl_render_pass_attachment_descriptor *
mtl_render_pass_descriptor_get_color_attachment(
mtl_render_pass_descriptor *descriptor, uint32_t index)
{
return NULL;
}
mtl_render_pass_attachment_descriptor *
mtl_render_pass_descriptor_get_depth_attachment(
mtl_render_pass_descriptor *descriptor)
{
return NULL;
}
mtl_render_pass_attachment_descriptor *
mtl_render_pass_descriptor_get_stencil_attachment(
mtl_render_pass_descriptor *descriptor)
{
return NULL;
}
void
mtl_render_pass_attachment_descriptor_set_texture(
mtl_render_pass_attachment_descriptor *descriptor, mtl_texture *texture)
{
}
void
mtl_render_pass_attachment_descriptor_set_level(
mtl_render_pass_attachment_descriptor *descriptor, uint32_t level)
{
}
void
mtl_render_pass_attachment_descriptor_set_slice(
mtl_render_pass_attachment_descriptor *descriptor, uint32_t slice)
{
}
void
mtl_render_pass_attachment_descriptor_set_load_action(
mtl_render_pass_attachment_descriptor *descriptor,
enum mtl_load_action action)
{
}
void
mtl_render_pass_attachment_descriptor_set_store_action(
mtl_render_pass_attachment_descriptor *descriptor,
enum mtl_store_action action)
{
}
void
mtl_render_pass_attachment_descriptor_set_clear_color(
mtl_render_pass_attachment_descriptor *descriptor,
struct mtl_clear_color clear_color)
{
}
void
mtl_render_pass_attachment_descriptor_set_clear_depth(
mtl_render_pass_attachment_descriptor *descriptor, double depth)
{
}
void
mtl_render_pass_attachment_descriptor_set_clear_stencil(
mtl_render_pass_attachment_descriptor *descriptor, uint32_t stencil)
{
}
void
mtl_render_pass_descriptor_set_render_target_array_length(
mtl_render_pass_descriptor *descriptor, uint32_t length)
{
}
void
mtl_render_pass_descriptor_set_render_target_width(
mtl_render_pass_descriptor *descriptor, uint32_t width)
{
}
void
mtl_render_pass_descriptor_set_render_target_height(
mtl_render_pass_descriptor *descriptor, uint32_t height)
{
}
void
mtl_render_pass_descriptor_set_default_raster_sample_count(
mtl_render_pass_descriptor *descriptor, uint32_t sample_count)
{
}
void
mtl_render_pass_descriptor_set_sample_positions(
mtl_render_pass_descriptor *descriptor,
const struct mtl_sample_position *positions, uint32_t count)
{
}
void
mtl_render_pass_descriptor_set_visibility_buffer(
mtl_render_pass_descriptor *descriptor, mtl_buffer *visibility_buffer)
{
}
/* Render pipeline descriptor */
mtl_render_pipeline_descriptor *
mtl_new_render_pipeline_descriptor(void)
{
return NULL;
}
void
mtl_render_pipeline_descriptor_set_vertex_shader(
mtl_render_pass_descriptor *descriptor, mtl_function *shader)
{
}
void
mtl_render_pipeline_descriptor_set_fragment_shader(
mtl_render_pass_descriptor *descriptor, mtl_function *shader)
{
}
void
mtl_render_pipeline_descriptor_set_input_primitive_topology(
mtl_render_pass_descriptor *descriptor,
enum mtl_primitive_topology_class topology_class)
{
}
void
mtl_render_pipeline_descriptor_set_color_attachment_format(
mtl_render_pass_descriptor *descriptor, uint8_t index,
enum mtl_pixel_format format)
{
}
void
mtl_render_pipeline_descriptor_set_depth_attachment_format(
mtl_render_pass_descriptor *descriptor, enum mtl_pixel_format format)
{
}
void
mtl_render_pipeline_descriptor_set_stencil_attachment_format(
mtl_render_pass_descriptor *descriptor, enum mtl_pixel_format format)
{
}
void
mtl_render_pipeline_descriptor_set_raster_sample_count(
mtl_render_pass_descriptor *descriptor, uint32_t sample_count)
{
}
void
mtl_render_pipeline_descriptor_set_alpha_to_coverage(
mtl_render_pass_descriptor *descriptor, bool enabled)
{
}
void
mtl_render_pipeline_descriptor_set_alpha_to_one(
mtl_render_pass_descriptor *descriptor, bool enabled)
{
}
void
mtl_render_pipeline_descriptor_set_rasterization_enabled(
mtl_render_pass_descriptor *descriptor, bool enabled)
{
}
void
mtl_render_pipeline_descriptor_set_max_vertex_amplification_count(
mtl_render_pass_descriptor *descriptor, uint32_t count)
{
}
/* Render pipeline */
mtl_render_pipeline_state *
mtl_new_render_pipeline(mtl_device *device,
mtl_render_pass_descriptor *descriptor)
{
return NULL;
}
/* Stencil descriptor */
mtl_stencil_descriptor *
mtl_new_stencil_descriptor(void)
{
return NULL;
}
void
mtl_stencil_descriptor_set_stencil_failure_operation(
mtl_stencil_descriptor *descriptor, enum VkStencilOp op)
{
}
void
mtl_stencil_descriptor_set_depth_failure_operation(
mtl_stencil_descriptor *descriptor, enum VkStencilOp op)
{
}
void
mtl_stencil_descriptor_set_depth_stencil_pass_operation(
mtl_stencil_descriptor *descriptor, enum VkStencilOp op)
{
}
void
mtl_stencil_descriptor_set_stencil_compare_function(
mtl_stencil_descriptor *descriptor, enum VkCompareOp op)
{
}
void
mtl_stencil_descriptor_set_read_mask(mtl_stencil_descriptor *descriptor,
uint32_t mask)
{
}
void
mtl_stencil_descriptor_set_write_mask(mtl_stencil_descriptor *descriptor,
uint32_t mask)
{
}
/* Depth stencil descriptor */
mtl_depth_stencil_descriptor *
mtl_new_depth_stencil_descriptor(void)
{
return NULL;
}
void
mtl_depth_stencil_descriptor_set_depth_compare_function(
mtl_depth_stencil_descriptor *descriptor, enum VkCompareOp op)
{
}
void
mtl_depth_stencil_descriptor_set_depth_write_enabled(
mtl_depth_stencil_descriptor *descriptor, bool enable_write)
{
}
void
mtl_depth_stencil_descriptor_set_back_face_stencil(
mtl_depth_stencil_descriptor *descriptor,
mtl_stencil_descriptor *stencil_descriptor)
{
}
void
mtl_depth_stencil_descriptor_set_front_face_stencil(
mtl_depth_stencil_descriptor *descriptor,
mtl_stencil_descriptor *stencil_descriptor)
{
}
/* Depth stencil state */
mtl_depth_stencil_state *
mtl_new_depth_stencil_state(mtl_device *device,
mtl_depth_stencil_descriptor *descriptor)
{
return NULL;
}
@@ -0,0 +1,40 @@
/*
* Copyright 2025 LunarG, Inc.
* Copyright 2025 Google LLC
* SPDX-License-Identifier: MIT
*/
#include "mtl_residency_set.h"
mtl_residency_set *
mtl_new_residency_set(mtl_device *device)
{
return NULL;
}
void
mtl_residency_set_add_allocation(mtl_residency_set *residency_set,
mtl_allocation *allocation)
{
}
void
mtl_residency_set_remove_allocation(mtl_residency_set *residency_set,
mtl_allocation *allocation)
{
}
void
mtl_residency_set_commit(mtl_residency_set *residency_set)
{
}
void
mtl_residency_set_request_residency(mtl_residency_set *residency_set)
{
}
void
mtl_residency_set_end_residency(mtl_residency_set *residency_set)
{
}
@@ -0,0 +1,74 @@
/*
* Copyright 2025 LunarG, Inc.
* Copyright 2025 Google LLC
* SPDX-License-Identifier: MIT
*/
#include "mtl_sampler.h"
/* Sampler descriptor */
mtl_sampler_descriptor *
mtl_new_sampler_descriptor(void)
{
return NULL;
}
/* Sampler descriptor utils */
void
mtl_sampler_descriptor_set_normalized_coordinates(
mtl_sampler_descriptor *descriptor, bool normalized_coordinates)
{
}
void
mtl_sampler_descriptor_set_address_mode(
mtl_sampler_descriptor *descriptor,
enum mtl_sampler_address_mode address_mode_u,
enum mtl_sampler_address_mode address_mode_v,
enum mtl_sampler_address_mode address_mode_w)
{
}
void
mtl_sampler_descriptor_set_border_color(mtl_sampler_descriptor *descriptor,
enum mtl_sampler_border_color color)
{
}
void
mtl_sampler_descriptor_set_filters(mtl_sampler_descriptor *descriptor,
enum mtl_sampler_min_mag_filter min_filter,
enum mtl_sampler_min_mag_filter mag_filter,
enum mtl_sampler_mip_filter mip_filter)
{
}
void
mtl_sampler_descriptor_set_lod_clamp(mtl_sampler_descriptor *descriptor,
float min, float max)
{
}
void
mtl_sampler_descriptor_set_max_anisotropy(mtl_sampler_descriptor *descriptor,
uint64_t max)
{
}
void
mtl_sampler_descriptor_set_compare_function(mtl_sampler_descriptor *descriptor,
enum mtl_compare_function function)
{
}
/* Sampler */
mtl_sampler *
mtl_new_sampler(mtl_device *device, mtl_sampler_descriptor *descriptor)
{
return NULL;
}
/* Sampler utils */
uint64_t
mtl_sampler_get_gpu_resource_id(mtl_sampler *sampler)
{
return 0u;
}
+47
View File
@@ -0,0 +1,47 @@
/*
* Copyright 2025 LunarG, Inc.
* Copyright 2025 Google LLC
* SPDX-License-Identifier: MIT
*/
#include "mtl_sync.h"
/* MTLFence */
mtl_fence *
mtl_new_fence(mtl_device *device)
{
return NULL;
}
/* MTLEvent */
mtl_event *
mtl_new_event(mtl_device *device)
{
return NULL;
}
/* MTLSharedEvent */
mtl_shared_event *
mtl_new_shared_event(mtl_device *device)
{
return NULL;
}
int
mtl_shared_event_wait_until_signaled_value(mtl_shared_event *event_handle,
uint64_t value, uint64_t timeout_ms)
{
return 0;
}
uint64_t
mtl_shared_event_get_signaled_value(mtl_shared_event *event_handle)
{
return 0u;
}
void
mtl_shared_event_set_signaled_value(mtl_shared_event *event_handle,
uint64_t value)
{
}
@@ -0,0 +1,41 @@
/*
* Copyright 2025 LunarG, Inc.
* Copyright 2025 Google LLC
* SPDX-License-Identifier: MIT
*/
#include "mtl_texture.h"
/* Utils*/
uint64_t
mtl_texture_get_gpu_resource_id(mtl_texture *texture)
{
return 0u;
}
/* Texture view creation */
mtl_texture *
mtl_new_texture_view_with(mtl_texture *texture,
const struct kk_view_layout *layout)
{
return NULL;
}
mtl_texture *
mtl_new_texture_view_with_no_swizzle(mtl_texture *texture,
const struct kk_view_layout *layout)
{
return NULL;
}
void
mtl_texture_get_bytes(mtl_texture *texture, void *host_ptr,
struct mtl_texture_memory_copy *data)
{
}
void
mtl_texture_replace_region(mtl_texture *texture, const void *host_ptr,
struct mtl_texture_memory_copy *data)
{
}
+265
View File
@@ -0,0 +1,265 @@
/*
* Copyright 2025 LunarG, Inc.
* Copyright 2025 Google LLC
* SPDX-License-Identifier: MIT
*/
#include "vk_to_mtl_map.h"
#include "kosmickrisp/bridge/mtl_types.h"
#include "util/format/u_format.h"
#include "vulkan/vulkan.h"
#include "vk_meta.h"
struct mtl_origin
vk_offset_3d_to_mtl_origin(const struct VkOffset3D *offset)
{
struct mtl_origin ret = {
.x = offset->x,
.y = offset->y,
.z = offset->z,
};
return ret;
}
struct mtl_size
vk_extent_3d_to_mtl_size(const struct VkExtent3D *extent)
{
struct mtl_size ret = {
.x = extent->width,
.y = extent->height,
.z = extent->depth,
};
return ret;
}
enum mtl_primitive_type
vk_primitive_topology_to_mtl_primitive_type(enum VkPrimitiveTopology topology)
{
switch (topology) {
case VK_PRIMITIVE_TOPOLOGY_POINT_LIST:
return MTL_PRIMITIVE_TYPE_POINT;
case VK_PRIMITIVE_TOPOLOGY_LINE_LIST:
return MTL_PRIMITIVE_TYPE_LINE;
case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP:
return MTL_PRIMITIVE_TYPE_LINE_STRIP;
case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST:
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wswitch"
case VK_PRIMITIVE_TOPOLOGY_META_RECT_LIST_MESA:
#pragma GCC diagnostic pop
/* Triangle fans are emulated meaning we'll translate the index buffer to
* triangle list or generate a index buffer if there's none */
case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN:
return MTL_PRIMITIVE_TYPE_TRIANGLE;
case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP:
return MTL_PRIMITIVE_TYPE_TRIANGLE_STRIP;
default:
assert(0 && "Primitive topology not supported!");
return 0;
}
}
enum mtl_primitive_topology_class
vk_primitive_topology_to_mtl_primitive_topology_class(
enum VkPrimitiveTopology topology)
{
switch (topology) {
case VK_PRIMITIVE_TOPOLOGY_POINT_LIST:
return MTL_PRIMITIVE_TOPOLOGY_CLASS_POINT;
case VK_PRIMITIVE_TOPOLOGY_LINE_LIST:
case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP:
return MTL_PRIMITIVE_TOPOLOGY_CLASS_LINE;
case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST:
case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP:
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wswitch"
case VK_PRIMITIVE_TOPOLOGY_META_RECT_LIST_MESA:
#pragma GCC diagnostic pop
return MTL_PRIMITIVE_TOPOLOGY_CLASS_TRIANGLE;
default:
return MTL_PRIMITIVE_TOPOLOGY_CLASS_UNSPECIFIED;
}
}
enum mtl_load_action
vk_attachment_load_op_to_mtl_load_action(enum VkAttachmentLoadOp op)
{
switch (op) {
case VK_ATTACHMENT_LOAD_OP_LOAD:
return MTL_LOAD_ACTION_LOAD;
case VK_ATTACHMENT_LOAD_OP_CLEAR:
return MTL_LOAD_ACTION_CLEAR;
case VK_ATTACHMENT_LOAD_OP_DONT_CARE:
return MTL_LOAD_ACTION_DONT_CARE;
default:
assert(false && "Unsupported VkAttachmentLoadOp");
return MTL_LOAD_ACTION_DONT_CARE;
};
}
enum mtl_store_action
vk_attachment_store_op_to_mtl_store_action(enum VkAttachmentStoreOp op)
{
switch (op) {
case VK_ATTACHMENT_STORE_OP_STORE:
return MTL_STORE_ACTION_STORE;
case VK_ATTACHMENT_STORE_OP_DONT_CARE:
return MTL_STORE_ACTION_DONT_CARE;
case VK_ATTACHMENT_STORE_OP_NONE:
return MTL_STORE_ACTION_UNKNOWN;
default:
assert(false && "Unsupported VkAttachmentStoreOp");
return MTL_STORE_ACTION_UNKNOWN;
};
}
enum mtl_sampler_address_mode
vk_sampler_address_mode_to_mtl_sampler_address_mode(
enum VkSamplerAddressMode mode)
{
switch (mode) {
case VK_SAMPLER_ADDRESS_MODE_REPEAT:
return MTL_SAMPLER_ADDRESS_MODE_REPEAT;
case VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT:
return MTL_SAMPLER_ADDRESS_MODE_MIRROR_REPEAT;
case VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE:
return MTL_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
case VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER:
return MTL_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER_COLOR;
case VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE:
return MTL_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE;
default:
UNREACHABLE("Unsupported address mode");
}
}
enum mtl_sampler_border_color
vk_border_color_to_mtl_sampler_border_color(enum VkBorderColor color)
{
switch (color) {
case VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK:
case VK_BORDER_COLOR_INT_TRANSPARENT_BLACK:
return MTL_SAMPLER_BORDER_COLOR_TRANSPARENT_BLACK;
case VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK:
case VK_BORDER_COLOR_INT_OPAQUE_BLACK:
return MTL_SAMPLER_BORDER_COLOR_OPAQUE_BLACK;
case VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE:
case VK_BORDER_COLOR_INT_OPAQUE_WHITE:
return MTL_SAMPLER_BORDER_COLOR_OPAQUE_WHITE;
case VK_BORDER_COLOR_FLOAT_CUSTOM_EXT:
case VK_BORDER_COLOR_INT_CUSTOM_EXT:
return MTL_SAMPLER_BORDER_COLOR_OPAQUE_WHITE;
default:
UNREACHABLE("Unsupported address mode");
}
}
enum mtl_sampler_min_mag_filter
vk_filter_to_mtl_sampler_min_mag_filter(enum VkFilter filter)
{
switch (filter) {
case VK_FILTER_NEAREST:
return MTL_SAMPLER_MIN_MAG_FILTER_NEAREST;
case VK_FILTER_LINEAR:
return MTL_SAMPLER_MIN_MAG_FILTER_LINEAR;
default:
UNREACHABLE("Unsupported address mode");
}
}
enum mtl_sampler_mip_filter
vk_sampler_mipmap_mode_to_mtl_sampler_mip_filter(enum VkSamplerMipmapMode mode)
{
switch (mode) {
case VK_SAMPLER_MIPMAP_MODE_NEAREST:
return MTL_SAMPLER_MIP_FILTER_NEAREST;
case VK_SAMPLER_MIPMAP_MODE_LINEAR:
return MTL_SAMPLER_MIP_FILTER_LINEAR;
default:
UNREACHABLE("Unsupported address mode");
}
}
enum mtl_compare_function
vk_compare_op_to_mtl_compare_function(enum VkCompareOp op)
{
switch (op) {
case VK_COMPARE_OP_NEVER:
return MTL_COMPARE_FUNCTION_NEVER;
case VK_COMPARE_OP_LESS:
return MTL_COMPARE_FUNCTION_LESS;
case VK_COMPARE_OP_EQUAL:
return MTL_COMPARE_FUNCTION_EQUAL;
case VK_COMPARE_OP_LESS_OR_EQUAL:
return MTL_COMPARE_FUNCTION_LESS_EQUAL;
case VK_COMPARE_OP_GREATER:
return MTL_COMPARE_FUNCTION_GREATER;
case VK_COMPARE_OP_NOT_EQUAL:
return MTL_COMPARE_FUNCTION_NOT_EQUAL;
case VK_COMPARE_OP_GREATER_OR_EQUAL:
return MTL_COMPARE_FUNCTION_GREATER_EQUAL;
case VK_COMPARE_OP_ALWAYS:
return MTL_COMPARE_FUNCTION_ALWAYS;
default:
UNREACHABLE("Unsupported address mode");
}
}
enum mtl_winding
vk_front_face_to_mtl_winding(enum VkFrontFace face)
{
switch (face) {
case VK_FRONT_FACE_CLOCKWISE:
return MTL_WINDING_CLOCKWISE;
case VK_FRONT_FACE_COUNTER_CLOCKWISE:
return MTL_WINDING_COUNTER_CLOCKWISE;
default:
assert(false && "Unsupported VkFrontFace");
return MTL_WINDING_CLOCKWISE;
}
}
enum mtl_cull_mode
vk_front_face_to_mtl_cull_mode(enum VkCullModeFlagBits mode)
{
switch (mode) {
case VK_CULL_MODE_NONE:
case VK_CULL_MODE_FRONT_AND_BACK: // Emulated with scissor
return MTL_CULL_MODE_NONE;
case VK_CULL_MODE_FRONT_BIT:
return MTL_CULL_MODE_FRONT;
case VK_CULL_MODE_BACK_BIT:
return MTL_CULL_MODE_BACK;
default:
UNREACHABLE("Unsupported VkCullModeFlags");
}
}
enum mtl_index_type
index_size_in_bytes_to_mtl_index_type(unsigned bytes)
{
switch (bytes) {
case 2u:
return MTL_INDEX_TYPE_UINT16;
case 4u:
return MTL_INDEX_TYPE_UINT32;
default:
UNREACHABLE("Unsupported byte size for index");
}
}
unsigned
mtl_index_type_to_size_B(enum mtl_index_type type)
{
switch (type) {
case MTL_INDEX_TYPE_UINT16:
return 2u;
case MTL_INDEX_TYPE_UINT32:
return 4u;
default:
UNREACHABLE("Unhandled index type");
}
}
+81
View File
@@ -0,0 +1,81 @@
/*
* Copyright 2025 LunarG, Inc.
* Copyright 2025 Google LLC
* SPDX-License-Identifier: MIT
*/
#ifndef KK_MTL_TO_VK_MAP_H
#define KK_MTL_TO_VK_MAP_H 1
struct mtl_origin;
struct mtl_size;
enum mtl_primitive_type;
enum mtl_primitive_topology_class;
enum mtl_load_action;
enum mtl_store_action;
enum mtl_sampler_address_mode;
enum mtl_sampler_border_color;
enum mtl_sampler_min_mag_filter;
enum mtl_sampler_mip_filter;
enum mtl_compare_function;
enum mtl_winding;
enum mtl_cull_mode;
enum mtl_index_type;
struct VkOffset3D;
struct VkExtent3D;
union VkClearColorValue;
enum VkPrimitiveTopology;
enum VkAttachmentLoadOp;
enum VkAttachmentStoreOp;
enum VkSamplerAddressMode;
enum VkBorderColor;
enum VkFilter;
enum VkSamplerMipmapMode;
enum VkCompareOp;
enum VkFrontFace;
enum VkCullModeFlagBits;
/* STRUCTS */
struct mtl_origin vk_offset_3d_to_mtl_origin(const struct VkOffset3D *offset);
struct mtl_size vk_extent_3d_to_mtl_size(const struct VkExtent3D *extent);
/* ENUMS */
enum mtl_primitive_type
vk_primitive_topology_to_mtl_primitive_type(enum VkPrimitiveTopology topology);
enum mtl_primitive_topology_class
vk_primitive_topology_to_mtl_primitive_topology_class(
enum VkPrimitiveTopology topology);
enum mtl_load_action
vk_attachment_load_op_to_mtl_load_action(enum VkAttachmentLoadOp op);
enum mtl_store_action
vk_attachment_store_op_to_mtl_store_action(enum VkAttachmentStoreOp op);
enum mtl_sampler_address_mode
vk_sampler_address_mode_to_mtl_sampler_address_mode(
enum VkSamplerAddressMode mode);
enum mtl_sampler_border_color
vk_border_color_to_mtl_sampler_border_color(enum VkBorderColor color);
enum mtl_sampler_min_mag_filter
vk_filter_to_mtl_sampler_min_mag_filter(enum VkFilter filter);
enum mtl_sampler_mip_filter
vk_sampler_mipmap_mode_to_mtl_sampler_mip_filter(enum VkSamplerMipmapMode mode);
enum mtl_compare_function
vk_compare_op_to_mtl_compare_function(enum VkCompareOp op);
enum mtl_winding vk_front_face_to_mtl_winding(enum VkFrontFace face);
enum mtl_cull_mode vk_front_face_to_mtl_cull_mode(enum VkCullModeFlagBits mode);
enum mtl_index_type index_size_in_bytes_to_mtl_index_type(unsigned bytes);
unsigned mtl_index_type_to_size_B(enum mtl_index_type type);
#endif /* KK_MTL_TO_VK_MAP_H */