From 1df81c373c6514ec79a8720fca0a2e1b8b38ec22 Mon Sep 17 00:00:00 2001 From: Samuliak Date: Tue, 2 Jul 2024 20:31:59 +0200 Subject: [PATCH] handle screen rotation correctly & fix: srgb --- include/renderer_mtl/renderer_mtl.hpp | 1 + src/core/renderer_mtl/renderer_mtl.cpp | 23 +++++++++++++--- src/host_shaders/metal_shaders.metal | 38 +++++++++++++++++++++----- 3 files changed, 51 insertions(+), 11 deletions(-) diff --git a/include/renderer_mtl/renderer_mtl.hpp b/include/renderer_mtl/renderer_mtl.hpp index ec8ec603..e73d2dc9 100644 --- a/include/renderer_mtl/renderer_mtl.hpp +++ b/include/renderer_mtl/renderer_mtl.hpp @@ -44,6 +44,7 @@ class RendererMTL final : public Renderer { // Pipelines MTL::RenderPipelineState* displayPipeline; + MTL::RenderPipelineState* blitPipeline; MTL::RenderPipelineState* drawPipeline; // Active state diff --git a/src/core/renderer_mtl/renderer_mtl.cpp b/src/core/renderer_mtl/renderer_mtl.cpp index 3a090d8a..e363322c 100644 --- a/src/core/renderer_mtl/renderer_mtl.cpp +++ b/src/core/renderer_mtl/renderer_mtl.cpp @@ -118,9 +118,8 @@ void RendererMTL::initGraphicsContext(SDL_Window* window) { MTL::RenderPipelineDescriptor* displayPipelineDescriptor = MTL::RenderPipelineDescriptor::alloc()->init(); displayPipelineDescriptor->setVertexFunction(vertexDisplayFunction); displayPipelineDescriptor->setFragmentFunction(fragmentDisplayFunction); - // HACK auto* displayColorAttachment = displayPipelineDescriptor->colorAttachments()->object(0); - displayColorAttachment->setPixelFormat(MTL::PixelFormat::PixelFormatBGRA8Unorm_sRGB); + displayColorAttachment->setPixelFormat(MTL::PixelFormat::PixelFormatBGRA8Unorm); error = nullptr; displayPipeline = device->newRenderPipelineState(displayPipelineDescriptor, &error); @@ -128,6 +127,22 @@ void RendererMTL::initGraphicsContext(SDL_Window* window) { Helpers::panic("Error creating display pipeline state: %s", error->description()->cString(NS::ASCIIStringEncoding)); } + // Blit + MTL::Function* vertexBlitFunction = library->newFunction(NS::String::string("vertexBlit", NS::ASCIIStringEncoding)); + MTL::Function* fragmentBlitFunction = library->newFunction(NS::String::string("fragmentBlit", NS::ASCIIStringEncoding)); + + MTL::RenderPipelineDescriptor* blitPipelineDescriptor = MTL::RenderPipelineDescriptor::alloc()->init(); + blitPipelineDescriptor->setVertexFunction(vertexBlitFunction); + blitPipelineDescriptor->setFragmentFunction(fragmentBlitFunction); + auto* blitColorAttachment = blitPipelineDescriptor->colorAttachments()->object(0); + blitColorAttachment->setPixelFormat(MTL::PixelFormat::PixelFormatBGRA8Unorm); + + error = nullptr; + blitPipeline = device->newRenderPipelineState(blitPipelineDescriptor, &error); + if (error) { + Helpers::panic("Error creating blit pipeline state: %s", error->description()->cString(NS::ASCIIStringEncoding)); + } + // Draw MTL::Function* vertexDrawFunction = library->newFunction(NS::String::string("vertexDraw", NS::ASCIIStringEncoding)); MTL::Function* fragmentDrawFunction = library->newFunction(NS::String::string("fragmentDraw", NS::ASCIIStringEncoding)); @@ -135,7 +150,7 @@ void RendererMTL::initGraphicsContext(SDL_Window* window) { MTL::RenderPipelineDescriptor* drawPipelineDescriptor = MTL::RenderPipelineDescriptor::alloc()->init(); drawPipelineDescriptor->setVertexFunction(vertexDrawFunction); drawPipelineDescriptor->setFragmentFunction(fragmentDrawFunction); - // HACK + auto* drawColorAttachment = drawPipelineDescriptor->colorAttachments()->object(0); drawColorAttachment->setPixelFormat(MTL::PixelFormatRGBA8Unorm); drawColorAttachment->setBlendingEnabled(true); @@ -281,7 +296,7 @@ void RendererMTL::displayTransfer(u32 inputAddr, u32 outputAddr, u32 inputSize, colorAttachment->setStoreAction(MTL::StoreActionStore); MTL::RenderCommandEncoder* renderCommandEncoder = commandBuffer->renderCommandEncoder(renderPassDescriptor); - renderCommandEncoder->setRenderPipelineState(displayPipeline); + renderCommandEncoder->setRenderPipelineState(blitPipeline); renderCommandEncoder->setFragmentTexture(srcFramebuffer->texture, 0); renderCommandEncoder->setFragmentSamplerState(basicSampler, 0); diff --git a/src/host_shaders/metal_shaders.metal b/src/host_shaders/metal_shaders.metal index 37f7892d..95219082 100644 --- a/src/host_shaders/metal_shaders.metal +++ b/src/host_shaders/metal_shaders.metal @@ -1,21 +1,47 @@ #include using namespace metal; -struct DisplayVertexOut { +struct BasicVertexOut { float4 position [[position]]; float2 uv; }; -vertex DisplayVertexOut vertexDisplay(uint vid [[vertex_id]]) { - DisplayVertexOut out; +constant float4 displayPositions[4] = { + float4(-1.0, -1.0, 0.0, 1.0), + float4( 1.0, -1.0, 0.0, 1.0), + float4(-1.0, 1.0, 0.0, 1.0), + float4( 1.0, 1.0, 0.0, 1.0) +}; + +constant float2 displayTexCoord[4] = { + float2(0.0, 1.0), + float2(0.0, 0.0), + float2(1.0, 1.0), + float2(1.0, 0.0) +}; + +vertex BasicVertexOut vertexDisplay(uint vid [[vertex_id]]) { + BasicVertexOut out; + out.position = displayPositions[vid]; + out.uv = displayTexCoord[vid]; + + return out; +} + +fragment float4 fragmentDisplay(BasicVertexOut in [[stage_in]], texture2d tex [[texture(0)]], sampler samplr [[sampler(0)]]) { + return tex.sample(samplr, in.uv); +} + +vertex BasicVertexOut vertexBlit(uint vid [[vertex_id]]) { + BasicVertexOut out; out.uv = float2((vid << 1) & 2, vid & 2); - out.position = float4(out.uv * 2.0f + -1.0f, 0.0f, 1.0f); + out.position = float4(out.uv * 2.0 - 1.0, 0.0, 1.0); out.position.y = -out.position.y; return out; } -fragment float4 fragmentDisplay(DisplayVertexOut in [[stage_in]], texture2d tex [[texture(0)]], sampler samplr [[sampler(0)]]) { +fragment float4 fragmentBlit(BasicVertexOut in [[stage_in]], texture2d tex [[texture(0)]], sampler samplr [[sampler(0)]]) { return tex.sample(samplr, in.uv); } @@ -85,8 +111,6 @@ vertex DrawVertexOut vertexDraw(DrawVertexIn in [[stage_in]], constant PicaRegs& // Position out.position = in.position; - // HACK: rotate the position - out.position.xy = -out.position.yx; // Flip the y position out.position.y = -out.position.y; // in.position.z is in range of [-1 ... 1], convert it to [0 ... 1]