diff --git a/src/Cafe/HW/Latte/Renderer/Metal/MetalMemoryManager.cpp b/src/Cafe/HW/Latte/Renderer/Metal/MetalMemoryManager.cpp index 09e07cd9..aef458a7 100644 --- a/src/Cafe/HW/Latte/Renderer/Metal/MetalMemoryManager.cpp +++ b/src/Cafe/HW/Latte/Renderer/Metal/MetalMemoryManager.cpp @@ -96,6 +96,7 @@ MetalRestridedBufferRange MetalVertexBufferCache::RestrideBufferIfNeeded(MTL::Bu // TODO: use compute/void vertex function instead size_t newStride = Align(stride, 4); size_t newSize = vertexBufferRange.size / stride * newStride; + // TODO: use one big buffer for all restrided buffers restrideInfo.buffer = m_mtlr->GetDevice()->newBuffer(newSize, MTL::StorageModeShared); uint8* oldPtr = (uint8*)bufferCache->contents() + vertexBufferRange.offset; diff --git a/src/Cafe/HW/Latte/Renderer/Metal/MetalRenderer.cpp b/src/Cafe/HW/Latte/Renderer/Metal/MetalRenderer.cpp index f3e3fdb1..7afbefd6 100644 --- a/src/Cafe/HW/Latte/Renderer/Metal/MetalRenderer.cpp +++ b/src/Cafe/HW/Latte/Renderer/Metal/MetalRenderer.cpp @@ -60,14 +60,12 @@ MetalRenderer::MetalRenderer() } // Hybrid pipelines - m_copyDepthToColorPipeline = new MetalHybridComputePipeline(this, m_utilityLibrary, "vertexCopyDepthToColor", "kernelCopyDepthToColor"); - m_copyColorToDepthPipeline = new MetalHybridComputePipeline(this, m_utilityLibrary, "vertexCopyColorToDepth", "kernelCopyColorToDepth"); + m_copyTextureToTexturePipeline = new MetalHybridComputePipeline(this, m_utilityLibrary, "vertexCopyTextureToTexture", "kernelCopyTextureToTexture"); } MetalRenderer::~MetalRenderer() { - delete m_copyDepthToColorPipeline; - delete m_copyColorToDepthPipeline; + delete m_copyTextureToTexturePipeline; m_presentPipeline->release(); @@ -476,26 +474,28 @@ void MetalRenderer::surfaceCopy_copySurfaceWithFormatConversion(LatteTexture* so return; } - MetalHybridComputePipeline* copyPipeline; - if (srcTextureMtl->IsDepth()) - copyPipeline = m_copyDepthToColorPipeline; - else - copyPipeline = m_copyColorToDepthPipeline; - MTL::Texture* textures[] = {srcTextureMtl->GetTexture(), dstTextureMtl->GetTexture()}; + struct CopyParams + { + uint32 width; + uint32 srcMip; + uint32 srcSlice; + uint32 dstMip; + uint32 dstSlice; + } params{(uint32)effectiveCopyWidth, (uint32)texSrcMip, (uint32)texSrcSlice, (uint32)texDstMip, (uint32)texDstSlice}; + if (m_encoderType == MetalEncoderType::Render) { auto renderCommandEncoder = static_cast(m_commandEncoder); - renderCommandEncoder->setRenderPipelineState(copyPipeline->GetRenderPipelineState()); + renderCommandEncoder->setRenderPipelineState(m_copyTextureToTexturePipeline->GetRenderPipelineState()); renderCommandEncoder->setViewport(MTL::Viewport{0.0, 0.0, (double)effectiveCopyWidth, (double)effectiveCopyHeight, 0.0, 1.0}); renderCommandEncoder->setScissorRect(MTL::ScissorRect{0, 0, (uint32)effectiveCopyWidth, (uint32)effectiveCopyHeight}); renderCommandEncoder->setVertexTextures(textures, NS::Range(0, 2)); - renderCommandEncoder->setVertexBytes(&effectiveCopyWidth, sizeof(uint32), 0); - // TODO: set slices and mips + renderCommandEncoder->setVertexBytes(¶ms, sizeof(params), 0); renderCommandEncoder->drawPrimitives(MTL::PrimitiveTypeTriangle, NS::UInteger(0), NS::UInteger(3)); } diff --git a/src/Cafe/HW/Latte/Renderer/Metal/MetalRenderer.h b/src/Cafe/HW/Latte/Renderer/Metal/MetalRenderer.h index efff0264..0b2208ec 100644 --- a/src/Cafe/HW/Latte/Renderer/Metal/MetalRenderer.h +++ b/src/Cafe/HW/Latte/Renderer/Metal/MetalRenderer.h @@ -261,8 +261,7 @@ private: MTL::RenderPipelineState* m_presentPipeline; // Hybrid pipelines - class MetalHybridComputePipeline* m_copyDepthToColorPipeline; - class MetalHybridComputePipeline* m_copyColorToDepthPipeline; + class MetalHybridComputePipeline* m_copyTextureToTexturePipeline; // Basic MTL::SamplerState* m_nearestSampler; diff --git a/src/Cafe/HW/Latte/Renderer/Metal/UtilityShaderSource.h b/src/Cafe/HW/Latte/Renderer/Metal/UtilityShaderSource.h index edfee9ba..2e49fa95 100644 --- a/src/Cafe/HW/Latte/Renderer/Metal/UtilityShaderSource.h +++ b/src/Cafe/HW/Latte/Renderer/Metal/UtilityShaderSource.h @@ -22,13 +22,16 @@ inline const char* utilityShaderSource = \ " return tex.sample(samplr, in.texCoord);\n" \ "}\n" \ "\n" \ -"vertex void vertexCopyDepthToColor(uint vid [[vertex_id]], depth2d src [[texture(0)]], texture2d dst [[texture(1)]], constant uint& copyWidth) {\n" \ -" uint2 coord = uint2(vid % copyWidth, vid / copyWidth);\n" \ -" return dst.write(float4(src.read(coord), 0.0, 0.0, 0.0), coord);\n" \ -"}\n" \ +"struct CopyParams {\n" \ +" uint width;\n" \ +" uint srcMip;\n" \ +" uint srcSlice;\n" \ +" uint dstMip;\n" \ +" uint dstSlice;\n" \ +"};\n" \ "\n" \ -"vertex void vertexCopyColorToDepth(uint vid [[vertex_id]], texture2d src [[texture(0)]], texture2d dst [[texture(1)]], constant uint& copyWidth) {\n" \ -" uint2 coord = uint2(vid % copyWidth, vid / copyWidth);\n" \ -" return dst.write(float4(src.read(coord).r), coord);\n" \ +"vertex void vertexCopyTextureToTexture(uint vid [[vertex_id]], texture2d_array src [[texture(0)]], texture2d_array dst [[texture(1)]], constant CopyParams& params) {\n" \ +" uint2 coord = uint2(vid % params.width, vid / params.width);\n" \ +" return dst.write(float4(src.read(coord, params.srcSlice, params.srcMip).r, 0.0, 0.0, 0.0), coord, params.dstSlice, params.dstMip);\n" \ "}\n" \ "\n";