diff --git a/include/renderer_mtl/renderer_mtl.hpp b/include/renderer_mtl/renderer_mtl.hpp index c3c2ad51..e21582bb 100644 --- a/include/renderer_mtl/renderer_mtl.hpp +++ b/include/renderer_mtl/renderer_mtl.hpp @@ -54,6 +54,7 @@ class RendererMTL final : public Renderer { // Pipelines MTL::RenderPipelineState* displayPipeline; + MTL::RenderPipelineState* copyToLutTexturePipeline; // Active state MTL::CommandBuffer* commandBuffer = nullptr; diff --git a/src/core/renderer_mtl/renderer_mtl.cpp b/src/core/renderer_mtl/renderer_mtl.cpp index e2384a79..4c1a7ef6 100644 --- a/src/core/renderer_mtl/renderer_mtl.cpp +++ b/src/core/renderer_mtl/renderer_mtl.cpp @@ -22,6 +22,18 @@ PICA::ColorFmt ToColorFormat(u32 format) { } } +MTL::Library* loadLibrary(MTL::Device* device, const cmrc::file& shaderSource) { + //MTL::CompileOptions* compileOptions = MTL::CompileOptions::alloc()->init(); + NS::Error* error = nullptr; + MTL::Library* library = device->newLibrary(Metal::createDispatchData(shaderSource.begin(), shaderSource.size()), &error); + //MTL::Library* library = device->newLibrary(NS::String::string(source.c_str(), NS::ASCIIStringEncoding), compileOptions, &error); + if (error) { + Helpers::panic("Error loading shaders: %s", error->description()->cString(NS::ASCIIStringEncoding)); + } + + return library; +} + RendererMTL::RendererMTL(GPU& gpu, const std::array& internalRegs, const std::array& externalRegs) : Renderer(gpu, internalRegs, externalRegs) {} RendererMTL::~RendererMTL() {} @@ -125,14 +137,8 @@ void RendererMTL::initGraphicsContext(SDL_Window* window) { // Load shaders auto mtlResources = cmrc::RendererMTL::get_filesystem(); - auto shaderSource = mtlResources.open("metal_shaders.metallib"); - //MTL::CompileOptions* compileOptions = MTL::CompileOptions::alloc()->init(); - NS::Error* error = nullptr; - MTL::Library* library = device->newLibrary(Metal::createDispatchData(shaderSource.begin(), shaderSource.size()), &error); - //MTL::Library* library = device->newLibrary(NS::String::string(source.c_str(), NS::ASCIIStringEncoding), compileOptions, &error); - if (error) { - Helpers::panic("Error loading shaders: %s", error->description()->cString(NS::ASCIIStringEncoding)); - } + MTL::Library* library = loadLibrary(device, mtlResources.open("metal_shaders.metallib")); + MTL::Library* copyToLutTextureLibrary = loadLibrary(device, mtlResources.open("metal_copy_to_lut_texture.metallib")); // Display MTL::Function* vertexDisplayFunction = library->newFunction(NS::String::string("vertexDisplay", NS::ASCIIStringEncoding)); @@ -144,7 +150,7 @@ void RendererMTL::initGraphicsContext(SDL_Window* window) { auto* displayColorAttachment = displayPipelineDescriptor->colorAttachments()->object(0); displayColorAttachment->setPixelFormat(MTL::PixelFormat::PixelFormatBGRA8Unorm); - error = nullptr; + NS::Error* error = nullptr; displayPipeline = device->newRenderPipelineState(displayPipelineDescriptor, &error); if (error) { Helpers::panic("Error creating display pipeline state: %s", error->description()->cString(NS::ASCIIStringEncoding)); @@ -217,6 +223,20 @@ void RendererMTL::initGraphicsContext(SDL_Window* window) { drawPipelineCache.set(device, library, vertexDrawFunction, vertexDescriptor); + // Copy to LUT texture + MTL::Function* vertexCopyToLutTextureFunction = copyToLutTextureLibrary->newFunction(NS::String::string("vertexCopyToLutTexture", NS::ASCIIStringEncoding)); + + MTL::RenderPipelineDescriptor* copyToLutTexturePipelineDescriptor = MTL::RenderPipelineDescriptor::alloc()->init(); + copyToLutTexturePipelineDescriptor->setVertexFunction(vertexDisplayFunction); + auto* copyToLutTextureColorAttachment = copyToLutTexturePipelineDescriptor->colorAttachments()->object(0); + copyToLutTextureColorAttachment->setPixelFormat(MTL::PixelFormat::PixelFormatBGRA8Unorm); + + error = nullptr; + copyToLutTexturePipeline = device->newRenderPipelineState(copyToLutTexturePipelineDescriptor, &error); + if (error) { + Helpers::panic("Error creating copy_to_lut_texture pipeline state: %s", error->description()->cString(NS::ASCIIStringEncoding)); + } + // Depth stencil cache depthStencilCache.set(device); diff --git a/src/host_shaders/metal_copy_to_lut_texture.metal b/src/host_shaders/metal_copy_to_lut_texture.metal index 087e9acb..b069f6c5 100644 --- a/src/host_shaders/metal_copy_to_lut_texture.metal +++ b/src/host_shaders/metal_copy_to_lut_texture.metal @@ -3,6 +3,6 @@ using namespace metal; constant ushort lutTextureWidth [[function_constant(0)]]; -vertex void vertexCopyToLUTTexture(uint vid [[vertex_id]], constant ushort* data [[buffer(0)]], texture1d_array out [[texture(0)]]) { +vertex void vertexCopyToLutTexture(uint vid [[vertex_id]], constant ushort* data [[buffer(0)]], texture1d_array out [[texture(0)]]) { out.write(data[vid], vid % lutTextureWidth, vid / lutTextureWidth); }