diff --git a/src/core/renderer_mtl/renderer_mtl.cpp b/src/core/renderer_mtl/renderer_mtl.cpp index 649a5654..cedc0d16 100644 --- a/src/core/renderer_mtl/renderer_mtl.cpp +++ b/src/core/renderer_mtl/renderer_mtl.cpp @@ -219,7 +219,36 @@ void RendererMTL::clearBuffer(u32 startAddress, u32 endAddress, u32 value, u32 c return; } - // TODO: Implement depth and stencil buffers + const auto depth = depthStencilRenderTargetCache.findFromAddress(startAddress); + if (depth) { + float depthVal; + const auto format = depth->get().format; + if (format == DepthFmt::Depth16) { + depthVal = (value & 0xffff) / 65535.0f; + } else { + depthVal = (value & 0xffffff) / 16777215.0f; + } + + if (false/*format == DepthFmt::Depth24Stencil8*/) { + // TODO: clear stencil + //const u8 stencil = (value >> 24); + //gl.setStencilMask(0xff); + //OpenGL::setClearStencil(stencil); + //OpenGL::clearDepthAndStencil(); + } else { + MTL::RenderPassDescriptor* passDescriptor = MTL::RenderPassDescriptor::alloc()->init(); + MTL::RenderPassDepthAttachmentDescriptor* depthAttachment = passDescriptor->depthAttachment(); + depthAttachment->setTexture(depth->get().texture); + depthAttachment->setClearDepth(depthVal); + depthAttachment->setLoadAction(MTL::LoadActionClear); + depthAttachment->setStoreAction(MTL::StoreActionStore); + + MTL::RenderCommandEncoder* renderEncoder = commandBuffer->renderCommandEncoder(passDescriptor); + renderEncoder->endEncoding(); + } + + return; + } Helpers::warn("[RendererGL::ClearBuffer] No buffer found!\n"); } @@ -336,14 +365,18 @@ void RendererMTL::drawVertices(PICA::PrimType primType, std::span<const PICA::Ve } // Pipeline - Metal::PipelineHash hash{colorRenderTarget->format, DepthFmt::Unknown1}; + Metal::PipelineHash pipelineHash{colorRenderTarget->format, DepthFmt::Unknown1}; if (depthStencilRenderTarget) { - hash.depthFmt = depthStencilRenderTarget->format; + pipelineHash.depthFmt = depthStencilRenderTarget->format; } - MTL::RenderPipelineState* pipeline = drawPipelineCache.get(hash); + MTL::RenderPipelineState* pipeline = drawPipelineCache.get(pipelineHash); + + // Depth stencil state + MTL::DepthStencilState* depthStencilState = depthStencilCache.get(depthStencilHash); MTL::RenderCommandEncoder* renderCommandEncoder = commandBuffer->renderCommandEncoder(renderPassDescriptor); renderCommandEncoder->setRenderPipelineState(pipeline); + renderCommandEncoder->setDepthStencilState(depthStencilState); // If size is < 4KB, use inline vertex data, otherwise use a buffer if (vertices.size_bytes() < 4 * 1024) { renderCommandEncoder->setVertexBytes(vertices.data(), vertices.size_bytes(), VERTEX_BUFFER_BINDING_INDEX); diff --git a/src/host_shaders/metal_shaders.metal b/src/host_shaders/metal_shaders.metal index 95219082..6d667329 100644 --- a/src/host_shaders/metal_shaders.metal +++ b/src/host_shaders/metal_shaders.metal @@ -116,7 +116,7 @@ vertex DrawVertexOut vertexDraw(DrawVertexIn in [[stage_in]], constant PicaRegs& // in.position.z is in range of [-1 ... 1], convert it to [0 ... 1] out.position.xyz /= out.position.w; out.position.w = 1.0; - out.position.z = (out.position.z + 1.0) * 0.5; + out.position.z = (-out.position.z + 1.0) * 0.5; // Color out.color = in.color;