redo metal presentation

This commit is contained in:
Gregory Wells
2025-08-04 09:24:12 -04:00
parent 80fbb3e691
commit 14b1dc0fdf
5 changed files with 111 additions and 22 deletions

View File

@@ -4,12 +4,60 @@
#include "instance/metal_instance.h"
#include "instance/gryphn_instance.h"
#include "metal_shader.msl"
gnReturnCode createMetalOutputDevice(gnInstanceHandle instance, gnOutputDeviceHandle outputDevice, gnOutputDeviceInfo deviceInfo) {
if (instance == GN_NULL_HANDLE) return GN_INVALID_HANDLE;
outputDevice->outputDevice = malloc(sizeof(gnPlatformOutputDevice));
outputDevice->outputDevice->device = deviceInfo.physicalDevice->physicalDevice->device.retain;
outputDevice->outputDevice->transferQueue = outputDevice->outputDevice->device.newCommandQueue;
// create full screen quad
float verticies[] = {
-1.0f, -1.0f, 0.0f, 1.0f,
1.0f, -1.0f, 1.0f, 1.0f,
-1.0f, 1.0f, 0.0f, 0.0f,
1.0f, 1.0f, 1.0f, 0.0f,
};
outputDevice->outputDevice->fullScreenQuadBuffer =
[outputDevice->outputDevice->device
newBufferWithBytes:verticies
length:sizeof(verticies)
options:MTLResourceStorageModeShared
];
NSError *error = nil;
outputDevice->outputDevice->fullScreenShader = [outputDevice->outputDevice->device
newLibraryWithSource:@(shader_source)
options:nil
error:&error
];
if (!outputDevice->outputDevice->fullScreenShader) {
gnDebuggerSetErrorMessage(instance->debugger, (gnMessageData){
.message = gnCombineStrings(gnCreateString("Failed to create shader for output device: \n"), error.localizedDescription.UTF8String)
});
return GN_DEVICE_LOST;
}
outputDevice->outputDevice->fullScreenVertex = [outputDevice->outputDevice->fullScreenShader newFunctionWithName:@"fullscreen_vertex"];
outputDevice->outputDevice->fullScreenFragment = [outputDevice->outputDevice->fullScreenShader newFunctionWithName:@"fullscreen_fragment"];
MTLRenderPipelineDescriptor *pipelineDesc = [[MTLRenderPipelineDescriptor alloc] init];
pipelineDesc.vertexFunction = outputDevice->outputDevice->fullScreenVertex;
pipelineDesc.fragmentFunction = outputDevice->outputDevice->fullScreenFragment;
pipelineDesc.colorAttachments[0].pixelFormat = MTLPixelFormatBGRA8Unorm_sRGB;
pipelineDesc.depthAttachmentPixelFormat = MTLPixelFormatInvalid;
pipelineDesc.stencilAttachmentPixelFormat = MTLPixelFormatInvalid;
outputDevice->outputDevice->fullScreenPipeline = [outputDevice->outputDevice->device newRenderPipelineStateWithDescriptor:pipelineDesc error:&error];
if (!outputDevice->outputDevice->fullScreenPipeline) {
gnDebuggerSetErrorMessage(instance->debugger, (gnMessageData){
.message = gnCombineStrings(gnCreateString("Failed to create graphics pipeline for output device: \n"), error.localizedDescription.UTF8String)
});
return GN_DEVICE_LOST;
}
return GN_SUCCESS;
}
@@ -20,6 +68,13 @@ void waitForMetalDevice(gnOutputDeviceHandle device) {
void destroyMetalOutputDevice(gnOutputDeviceHandle device) {
[device->outputDevice->transferQueue release];
[device->outputDevice->device release];
[device->outputDevice->fullScreenQuadBuffer release];
[device->outputDevice->fullScreenShader release];
[device->outputDevice->fullScreenVertex release];
[device->outputDevice->fullScreenFragment release];
[device->outputDevice->fullScreenPipeline release];
free(device->outputDevice);
}

View File

@@ -14,6 +14,11 @@ struct gnPlatformOutputDevice_t {
id<MTLCommandBuffer> executingCommandBuffer;
id<MTLCommandQueue> transferQueue;
id<MTLBuffer> fullScreenQuadBuffer;
id<MTLLibrary> fullScreenShader;
id<MTLFunction> fullScreenVertex, fullScreenFragment;
id<MTLRenderPipelineState> fullScreenPipeline;
} gnPlatformOutputDevice;
gnPhysicalDevice* getMetalDevices(gnInstanceHandle instance, uint32_t* deviceCount);

View File

@@ -0,0 +1,26 @@
const char* shader_source =
"using namespace metal;"
""
"struct Vertex {"
" float2 position;"
" float2 texcoord;"
"};"
""
"struct VertexOut {"
" float4 position [[position]];"
" float2 texcoord;"
"};"
""
"vertex VertexOut fullscreen_vertex(const device Vertex* vertices [[buffer(0)]],"
" uint vid [[vertex_id]]) {"
" VertexOut out;"
" out.position = float4(vertices[vid].position, 0.0, 1.0);"
" out.texcoord = vertices[vid].texcoord;"
" return out;"
"}"
""
"fragment float4 fullscreen_fragment(VertexOut in [[stage_in]],"
" texture2d<float> tex [[texture(0)]]) {"
" constexpr sampler s(address::clamp_to_edge, filter::linear);"
" return tex.sample(s, in.texcoord);"
"}";