From cb4cefb6114d460c8ea5a3a3c2cb41da4bb20061 Mon Sep 17 00:00:00 2001 From: assiduous Date: Wed, 18 Nov 2020 14:28:46 -0800 Subject: Updated Metal reference implementations --- .../src/Metal/ClearRenderTargetReferenceMtl.mm | 31 ++-- .../src/Metal/ComputeShaderReferenceMtl.mm | 58 +++--- .../src/Metal/DrawCommandReferenceMtl.mm | 197 +++++++++++++-------- .../src/Metal/TestingSwapChainMtl.mm | 38 ++-- 4 files changed, 196 insertions(+), 128 deletions(-) diff --git a/Tests/DiligentCoreAPITest/src/Metal/ClearRenderTargetReferenceMtl.mm b/Tests/DiligentCoreAPITest/src/Metal/ClearRenderTargetReferenceMtl.mm index 977b039d..c67ea4e6 100644 --- a/Tests/DiligentCoreAPITest/src/Metal/ClearRenderTargetReferenceMtl.mm +++ b/Tests/DiligentCoreAPITest/src/Metal/ClearRenderTargetReferenceMtl.mm @@ -47,19 +47,26 @@ void ClearRenderTargetReferenceMtl(ISwapChain* pSwapChain, const float ClearColo auto* pRTV = pTestingSwapChainMtl->GetCurrentBackBufferRTV(); auto* mtlTexture = ValidatedCast(pRTV)->GetMtlTexture(); - id mtlCommandBuffer = [mtlCommandQueue commandBuffer]; + @autoreleasepool + { + // Autoreleased + id mtlCommandBuffer = [mtlCommandQueue commandBuffer]; - MTLRenderPassDescriptor* renderPassDesc = - [MTLRenderPassDescriptor renderPassDescriptor]; - renderPassDesc.colorAttachments[0].texture = mtlTexture; - renderPassDesc.colorAttachments[0].loadAction = MTLLoadActionClear; - renderPassDesc.colorAttachments[0].clearColor = - MTLClearColorMake(ClearColor[0], ClearColor[1], ClearColor[2], ClearColor[3]); - renderPassDesc.colorAttachments[0].storeAction = MTLStoreActionStore; - id renderEncoder = - [mtlCommandBuffer renderCommandEncoderWithDescriptor:renderPassDesc]; - [renderEncoder endEncoding]; - [mtlCommandBuffer commit]; + // Autoreleased + MTLRenderPassDescriptor* renderPassDesc = + [MTLRenderPassDescriptor renderPassDescriptor]; + renderPassDesc.colorAttachments[0].texture = mtlTexture; + renderPassDesc.colorAttachments[0].loadAction = MTLLoadActionClear; + renderPassDesc.colorAttachments[0].clearColor = + MTLClearColorMake(ClearColor[0], ClearColor[1], ClearColor[2], ClearColor[3]); + renderPassDesc.colorAttachments[0].storeAction = MTLStoreActionStore; + + // Autoreleased + id renderEncoder = + [mtlCommandBuffer renderCommandEncoderWithDescriptor:renderPassDesc]; + [renderEncoder endEncoding]; + [mtlCommandBuffer commit]; + } } } // namespace Testing diff --git a/Tests/DiligentCoreAPITest/src/Metal/ComputeShaderReferenceMtl.mm b/Tests/DiligentCoreAPITest/src/Metal/ComputeShaderReferenceMtl.mm index 489f36f2..9957a097 100644 --- a/Tests/DiligentCoreAPITest/src/Metal/ComputeShaderReferenceMtl.mm +++ b/Tests/DiligentCoreAPITest/src/Metal/ComputeShaderReferenceMtl.mm @@ -44,34 +44,44 @@ void ComputeShaderReferenceMtl(ISwapChain* pSwapChain) auto* const pEnv = TestingEnvironmentMtl::GetInstance(); auto const mtlDevice = pEnv->GetMtlDevice(); - auto* progSrc = [NSString stringWithUTF8String:MSL::FillTextureCS.c_str()]; - NSError *errors = nil; - id library = [mtlDevice newLibraryWithSource:progSrc - options:nil - error:&errors]; - ASSERT_TRUE(library != nil); - id computeFunc = [library newFunctionWithName:@"CSMain"]; - ASSERT_TRUE(computeFunc != nil); - auto* computePipeline = [mtlDevice newComputePipelineStateWithFunction:computeFunc error:&errors]; - ASSERT_TRUE(computePipeline != nil); + @autoreleasepool + { + // Autoreleased + auto* progSrc = [NSString stringWithUTF8String:MSL::FillTextureCS.c_str()]; + NSError *errors = nil; // Autoreleased + id library = [mtlDevice newLibraryWithSource:progSrc + options:nil + error:&errors]; + ASSERT_TRUE(library != nil); + id computeFunc = [library newFunctionWithName:@"CSMain"]; + ASSERT_TRUE(computeFunc != nil); + [library release]; - auto* pTestingSwapChainMtl = ValidatedCast(pSwapChain); - auto* pUAV = pTestingSwapChainMtl->GetCurrentBackBufferUAV(); - auto* mtlTexture = ValidatedCast(pUAV)->GetMtlTexture(); - const auto& SCDesc = pTestingSwapChainMtl->GetDesc(); + auto* computePipeline = [mtlDevice newComputePipelineStateWithFunction:computeFunc error:&errors]; + ASSERT_TRUE(computePipeline != nil); + [computeFunc release]; - auto* mtlCommandQueue = pEnv->GetMtlCommandQueue(); - id mtlCommandBuffer = [mtlCommandQueue commandBuffer]; - auto* cmdEncoder = [mtlCommandBuffer computeCommandEncoder]; - ASSERT_TRUE(cmdEncoder != nil); + auto* pTestingSwapChainMtl = ValidatedCast(pSwapChain); + auto* pUAV = pTestingSwapChainMtl->GetCurrentBackBufferUAV(); + auto* mtlTexture = ValidatedCast(pUAV)->GetMtlTexture(); + const auto& SCDesc = pTestingSwapChainMtl->GetDesc(); - [cmdEncoder setComputePipelineState:computePipeline]; - [cmdEncoder setTexture:mtlTexture atIndex:0]; - [cmdEncoder dispatchThreadgroups:MTLSizeMake((SCDesc.Width + 15) / 16, (SCDesc.Height + 15) / 16, 1) - threadsPerThreadgroup:MTLSizeMake(16, 16, 1)]; + auto* mtlCommandQueue = pEnv->GetMtlCommandQueue(); - [cmdEncoder endEncoding]; - [mtlCommandBuffer commit]; + // Command buffer is autoreleased + id mtlCommandBuffer = [mtlCommandQueue commandBuffer]; + // Command encoder is autoreleased + auto* cmdEncoder = [mtlCommandBuffer computeCommandEncoder]; + ASSERT_TRUE(cmdEncoder != nil); + + [cmdEncoder setComputePipelineState:computePipeline]; + [cmdEncoder setTexture:mtlTexture atIndex:0]; + [cmdEncoder dispatchThreadgroups:MTLSizeMake((SCDesc.Width + 15) / 16, (SCDesc.Height + 15) / 16, 1) + threadsPerThreadgroup:MTLSizeMake(16, 16, 1)]; + + [cmdEncoder endEncoding]; + [mtlCommandBuffer commit]; + } } } // namespace Testing diff --git a/Tests/DiligentCoreAPITest/src/Metal/DrawCommandReferenceMtl.mm b/Tests/DiligentCoreAPITest/src/Metal/DrawCommandReferenceMtl.mm index f5a3d4fb..f070c289 100644 --- a/Tests/DiligentCoreAPITest/src/Metal/DrawCommandReferenceMtl.mm +++ b/Tests/DiligentCoreAPITest/src/Metal/DrawCommandReferenceMtl.mm @@ -47,45 +47,57 @@ class TriangleRenderer { public: - TriangleRenderer(NSString* fragEntry, Uint32 SampleCount = 1) + TriangleRenderer(NSString* fragEntry, MTLPixelFormat mtlRTFormat, Uint32 SampleCount = 1) { auto* const pEnv = TestingEnvironmentMtl::GetInstance(); auto* const mtlDevice = pEnv->GetMtlDevice(); + id vertFunc = nil; + id fragFunc = nil; + + // Autoreleased auto* progSrc = [NSString stringWithUTF8String:MSL::DrawTestFunctions.c_str()]; - NSError *errors = nil; - id library = [mtlDevice newLibraryWithSource:progSrc - options:nil - error:&errors]; + NSError* errors = nil; // Autoreleased + id library = + [mtlDevice newLibraryWithSource:progSrc + options:nil + error:&errors]; if (library == nil) { LOG_ERROR_AND_THROW("Failed to create Metal library: ", [errors.localizedDescription cStringUsingEncoding:NSUTF8StringEncoding]); } - id vertFunc = [library newFunctionWithName:@"TrisVS"]; - id fragFunc = [library newFunctionWithName:fragEntry]; + + vertFunc = [library newFunctionWithName:@"TrisVS"]; + fragFunc = [library newFunctionWithName:fragEntry]; + [library release]; + if (vertFunc == nil) + LOG_ERROR_AND_THROW("Unable to find vertex function"); + if (fragFunc == nil) + LOG_ERROR_AND_THROW("Unable to find fragment function"); + MTLRenderPipelineDescriptor* renderPipelineDesc = [[MTLRenderPipelineDescriptor alloc] init]; renderPipelineDesc.vertexFunction = vertFunc; renderPipelineDesc.fragmentFunction = fragFunc; - const auto& SCDesc = pEnv->GetSwapChain()->GetDesc(); - MTLPixelFormat pixelFormat = MTLPixelFormatInvalid; - switch (SCDesc.ColorBufferFormat) - { - case TEX_FORMAT_RGBA8_UNORM: - pixelFormat = MTLPixelFormatRGBA8Unorm; - break; + [vertFunc release]; + [fragFunc release]; - default: - UNSUPPORTED("Unexpected swap chain color format"); - } renderPipelineDesc.sampleCount = SampleCount; - renderPipelineDesc.colorAttachments[0].pixelFormat = pixelFormat; + renderPipelineDesc.colorAttachments[0].pixelFormat = mtlRTFormat; + m_MtlPipeline = [mtlDevice newRenderPipelineStateWithDescriptor:renderPipelineDesc error:&errors]; + [renderPipelineDesc release]; + + if (m_MtlPipeline == nil) + { + LOG_ERROR_AND_THROW("Failed to create Metal pipeline: ", [errors.localizedDescription cStringUsingEncoding:NSUTF8StringEncoding]); + } } ~TriangleRenderer() { + [m_MtlPipeline release]; } void Draw(id renderEncoder) @@ -97,7 +109,7 @@ public: } private: - id m_MtlPipeline; + id m_MtlPipeline = nil; }; } // namespace @@ -113,26 +125,35 @@ void RenderDrawCommandReferenceMtl(ISwapChain* pSwapChain, const float* pClearCo auto* pRTV = pTestingSwapChainMtl->GetCurrentBackBufferRTV(); auto* mtlBackBuffer = ValidatedCast(pRTV)->GetMtlTexture(); - id mtlCommandBuffer = [mtlCommandQueue commandBuffer]; - constexpr float Zero[4] = {}; if (pClearColor == nullptr) pClearColor = Zero; - MTLRenderPassDescriptor* renderPassDesc = - [MTLRenderPassDescriptor renderPassDescriptor]; - renderPassDesc.colorAttachments[0].texture = mtlBackBuffer; - renderPassDesc.colorAttachments[0].loadAction = MTLLoadActionClear; - renderPassDesc.colorAttachments[0].clearColor = MTLClearColorMake(pClearColor[0], pClearColor[1], pClearColor[2], pClearColor[3]); - renderPassDesc.colorAttachments[0].storeAction = MTLStoreActionStore; - id renderEncoder = - [mtlCommandBuffer renderCommandEncoderWithDescriptor:renderPassDesc]; - [renderEncoder setViewport:MTLViewport{0, 0, (double) SCDesc.Width, (double) SCDesc.Height, 0, 1}]; + @autoreleasepool + { + TriangleRenderer TriRenderer{@"TrisFS", mtlBackBuffer.pixelFormat}; + + // Command buffer is autoreleased + id mtlCommandBuffer = [mtlCommandQueue commandBuffer]; + + // Render pass descriptor is autoreleased + MTLRenderPassDescriptor* renderPassDesc = + [MTLRenderPassDescriptor renderPassDescriptor]; + renderPassDesc.colorAttachments[0].texture = mtlBackBuffer; + renderPassDesc.colorAttachments[0].loadAction = MTLLoadActionClear; + renderPassDesc.colorAttachments[0].clearColor = MTLClearColorMake(pClearColor[0], pClearColor[1], pClearColor[2], pClearColor[3]); + renderPassDesc.colorAttachments[0].storeAction = MTLStoreActionStore; + + // Render encoder is autoreleased + id renderEncoder = + [mtlCommandBuffer renderCommandEncoderWithDescriptor:renderPassDesc]; + + [renderEncoder setViewport:MTLViewport{0, 0, (double) SCDesc.Width, (double) SCDesc.Height, 0, 1}]; - TriangleRenderer TriRenderer{@"TrisFS"}; - TriRenderer.Draw(renderEncoder); + TriRenderer.Draw(renderEncoder); - [mtlCommandBuffer commit]; + [mtlCommandBuffer commit]; + } } void RenderPassMSResolveReferenceMtl(ISwapChain* pSwapChain, const float* pClearColor) @@ -162,24 +183,35 @@ void RenderPassMSResolveReferenceMtl(ISwapChain* pSwapChain, const float* pClear msTextureDescriptor.usage = MTLTextureUsageRenderTarget; auto mtlMSTexture = [mtlDevice newTextureWithDescriptor:msTextureDescriptor]; ASSERT_TRUE(mtlMSTexture != nil); + [msTextureDescriptor release]; + + @autoreleasepool + { + TriangleRenderer TriRenderer{@"TrisFS", mtlBackBuffer.pixelFormat, SampleCount}; - id mtlCommandBuffer = [mtlCommandQueue commandBuffer]; + // Command buffer is autoreleased + id mtlCommandBuffer = [mtlCommandQueue commandBuffer]; - MTLRenderPassDescriptor* renderPassDesc = - [MTLRenderPassDescriptor renderPassDescriptor]; - renderPassDesc.colorAttachments[0].texture = mtlMSTexture; - renderPassDesc.colorAttachments[0].loadAction = MTLLoadActionClear; - renderPassDesc.colorAttachments[0].clearColor = MTLClearColorMake(pClearColor[0], pClearColor[1], pClearColor[2], pClearColor[3]); - renderPassDesc.colorAttachments[0].storeAction = MTLStoreActionMultisampleResolve; - renderPassDesc.colorAttachments[0].resolveTexture = mtlBackBuffer; - id renderEncoder = - [mtlCommandBuffer renderCommandEncoderWithDescriptor:renderPassDesc]; - [renderEncoder setViewport:MTLViewport{0, 0, (double) SCDesc.Width, (double) SCDesc.Height, 0, 1}]; + // Render pass descriptor is autoreleased + MTLRenderPassDescriptor* renderPassDesc = + [MTLRenderPassDescriptor renderPassDescriptor]; + renderPassDesc.colorAttachments[0].texture = mtlMSTexture; + renderPassDesc.colorAttachments[0].loadAction = MTLLoadActionClear; + renderPassDesc.colorAttachments[0].clearColor = MTLClearColorMake(pClearColor[0], pClearColor[1], pClearColor[2], pClearColor[3]); + renderPassDesc.colorAttachments[0].storeAction = MTLStoreActionMultisampleResolve; + renderPassDesc.colorAttachments[0].resolveTexture = mtlBackBuffer; - TriangleRenderer TriRenderer{@"TrisFS", SampleCount}; - TriRenderer.Draw(renderEncoder); + // Render encoder is autoreleased + id renderEncoder = + [mtlCommandBuffer renderCommandEncoderWithDescriptor:renderPassDesc]; - [mtlCommandBuffer commit]; + [renderEncoder setViewport:MTLViewport{0, 0, (double) SCDesc.Width, (double) SCDesc.Height, 0, 1}]; + + TriRenderer.Draw(renderEncoder); + + [mtlCommandBuffer commit]; + } + [mtlMSTexture release]; } void RenderPassInputAttachmentReferenceMtl(ISwapChain* pSwapChain, const float* pClearColor) @@ -206,36 +238,49 @@ void RenderPassInputAttachmentReferenceMtl(ISwapChain* pSwapChain, const float* inptAttTextureDescriptor.usage = MTLTextureUsageRenderTarget | MTLTextureUsageShaderRead; auto mtlInputAttachment = [mtlDevice newTextureWithDescriptor:inptAttTextureDescriptor]; ASSERT_TRUE(mtlInputAttachment != nil); + [inptAttTextureDescriptor release]; - id mtlCommandBuffer = [mtlCommandQueue commandBuffer]; - - MTLRenderPassDescriptor* subpass0Desc = - [MTLRenderPassDescriptor renderPassDescriptor]; - subpass0Desc.colorAttachments[0].texture = mtlInputAttachment; - subpass0Desc.colorAttachments[0].loadAction = MTLLoadActionClear; - subpass0Desc.colorAttachments[0].clearColor = MTLClearColorMake(0, 0, 0, 0); - subpass0Desc.colorAttachments[0].storeAction = MTLStoreActionStore; - id renderEncoder = - [mtlCommandBuffer renderCommandEncoderWithDescriptor:subpass0Desc]; - [renderEncoder setViewport:MTLViewport{0, 0, (double) SCDesc.Width, (double) SCDesc.Height, 0, 1}]; - - TriangleRenderer TriRenderer{@"TrisFS"}; - TriRenderer.Draw(renderEncoder); - - MTLRenderPassDescriptor* subpass1Desc = - [MTLRenderPassDescriptor renderPassDescriptor]; - subpass1Desc.colorAttachments[0].texture = mtlBackBuffer; - subpass1Desc.colorAttachments[0].loadAction = MTLLoadActionClear; - subpass1Desc.colorAttachments[0].clearColor = MTLClearColorMake(pClearColor[0], pClearColor[1], pClearColor[2], pClearColor[3]); - subpass1Desc.colorAttachments[0].storeAction = MTLStoreActionStore; - renderEncoder = [mtlCommandBuffer renderCommandEncoderWithDescriptor:subpass1Desc]; - [renderEncoder setViewport:MTLViewport{0, 0, (double) SCDesc.Width, (double) SCDesc.Height, 0, 1}]; - - TriangleRenderer TriRendererInptAtt{@"InptAttFS"}; - [renderEncoder setFragmentTexture:mtlInputAttachment atIndex:0]; - TriRendererInptAtt.Draw(renderEncoder); - - [mtlCommandBuffer commit]; + @autoreleasepool + { + TriangleRenderer TriRenderer{@"TrisFS", mtlBackBuffer.pixelFormat}; + TriangleRenderer TriRendererInptAtt{@"InptAttFS", mtlBackBuffer.pixelFormat}; + + // Command buffer is autoreleased + id mtlCommandBuffer = [mtlCommandQueue commandBuffer]; + + // Render pass descritor is autoreleased + MTLRenderPassDescriptor* subpass0Desc = + [MTLRenderPassDescriptor renderPassDescriptor]; + subpass0Desc.colorAttachments[0].texture = mtlInputAttachment; + subpass0Desc.colorAttachments[0].loadAction = MTLLoadActionClear; + subpass0Desc.colorAttachments[0].clearColor = MTLClearColorMake(0, 0, 0, 0); + subpass0Desc.colorAttachments[0].storeAction = MTLStoreActionStore; + + // Render encoder is autoreleased + id renderEncoder = + [mtlCommandBuffer renderCommandEncoderWithDescriptor:subpass0Desc]; + + [renderEncoder setViewport:MTLViewport{0, 0, (double) SCDesc.Width, (double) SCDesc.Height, 0, 1}]; + + TriRenderer.Draw(renderEncoder); + + // Autoreleased + MTLRenderPassDescriptor* subpass1Desc = + [MTLRenderPassDescriptor renderPassDescriptor]; + subpass1Desc.colorAttachments[0].texture = mtlBackBuffer; + subpass1Desc.colorAttachments[0].loadAction = MTLLoadActionClear; + subpass1Desc.colorAttachments[0].clearColor = MTLClearColorMake(pClearColor[0], pClearColor[1], pClearColor[2], pClearColor[3]); + subpass1Desc.colorAttachments[0].storeAction = MTLStoreActionStore; + // Autoreleased + renderEncoder = [mtlCommandBuffer renderCommandEncoderWithDescriptor:subpass1Desc]; + [renderEncoder setViewport:MTLViewport{0, 0, (double) SCDesc.Width, (double) SCDesc.Height, 0, 1}]; + + [renderEncoder setFragmentTexture:mtlInputAttachment atIndex:0]; + TriRendererInptAtt.Draw(renderEncoder); + + [mtlCommandBuffer commit]; + } + [mtlInputAttachment release]; } } // namespace Testing diff --git a/Tests/DiligentCoreAPITest/src/Metal/TestingSwapChainMtl.mm b/Tests/DiligentCoreAPITest/src/Metal/TestingSwapChainMtl.mm index c6f93759..81dd01ed 100644 --- a/Tests/DiligentCoreAPITest/src/Metal/TestingSwapChainMtl.mm +++ b/Tests/DiligentCoreAPITest/src/Metal/TestingSwapChainMtl.mm @@ -59,6 +59,7 @@ TestingSwapChainMtl::TestingSwapChainMtl(IReferenceCounters* pRefCounters, TestingSwapChainMtl::~TestingSwapChainMtl() { + [m_MtlStagingBuffer release]; } void TestingSwapChainMtl::TakeSnapshot() @@ -72,22 +73,27 @@ void TestingSwapChainMtl::TakeSnapshot() m_ReferenceDataPitch = m_SwapChainDesc.Height * 4; m_ReferenceData.resize(m_SwapChainDesc.Width * m_ReferenceDataPitch); - auto commandBuffer = [mtlCommandQueue commandBuffer]; - auto blitEncoder = [commandBuffer blitCommandEncoder]; - [blitEncoder copyFromTexture:mtlTexture - sourceSlice:0 - sourceLevel:0 - sourceOrigin:MTLOrigin{0,0,0} - sourceSize:MTLSize{m_SwapChainDesc.Width, m_SwapChainDesc.Height, 1} - toBuffer:m_MtlStagingBuffer - destinationOffset:0 - destinationBytesPerRow:m_ReferenceDataPitch - destinationBytesPerImage:0]; - [blitEncoder synchronizeResource:m_MtlStagingBuffer]; - [blitEncoder endEncoding]; - [commandBuffer commit]; - [commandBuffer waitUntilCompleted]; - memcpy(m_ReferenceData.data(), [m_MtlStagingBuffer contents], m_ReferenceData.size()); + @autoreleasepool + { + // Command buffer is autoreleased + auto commandBuffer = [mtlCommandQueue commandBuffer]; + // Command encoder is autoreleased + auto blitEncoder = [commandBuffer blitCommandEncoder]; + [blitEncoder copyFromTexture:mtlTexture + sourceSlice:0 + sourceLevel:0 + sourceOrigin:MTLOrigin{0,0,0} + sourceSize:MTLSize{m_SwapChainDesc.Width, m_SwapChainDesc.Height, 1} + toBuffer:m_MtlStagingBuffer + destinationOffset:0 + destinationBytesPerRow:m_ReferenceDataPitch + destinationBytesPerImage:0]; + [blitEncoder synchronizeResource:m_MtlStagingBuffer]; + [blitEncoder endEncoding]; + [commandBuffer commit]; + [commandBuffer waitUntilCompleted]; + memcpy(m_ReferenceData.data(), [m_MtlStagingBuffer contents], m_ReferenceData.size()); + } } void CreateTestingSwapChainMtl(TestingEnvironmentMtl* pEnv, -- cgit v1.2.3