From 4de31406047a3784361995ad244b2b7720eba067 Mon Sep 17 00:00:00 2001 From: Simon Kallweit Date: Fri, 6 Sep 2024 15:04:38 +0200 Subject: [PATCH 1/8] wip --- include/slang-rhi.h | 112 +++++++---------- src/command-writer.h | 33 +++-- src/cuda/cuda-command-buffer.cpp | 10 +- src/cuda/cuda-command-buffer.h | 7 +- src/cuda/cuda-device.cpp | 16 --- src/cuda/cuda-device.h | 6 - src/d3d11/d3d11-base.h | 1 - src/d3d11/d3d11-device.cpp | 104 ++++++++-------- src/d3d11/d3d11-device.h | 15 ++- src/d3d11/d3d11-framebuffer.h | 9 -- src/d3d11/d3d11-swap-chain.cpp | 1 - src/d3d12/d3d12-base.h | 3 - src/d3d12/d3d12-command-buffer.cpp | 14 +-- src/d3d12/d3d12-command-buffer.h | 7 +- src/d3d12/d3d12-command-encoder.cpp | 106 ++++++++-------- src/d3d12/d3d12-command-encoder.h | 12 +- src/d3d12/d3d12-device.cpp | 58 --------- src/d3d12/d3d12-device.h | 6 - src/d3d12/d3d12-framebuffer.h | 15 --- src/d3d12/d3d12-render-pass.cpp | 12 -- src/d3d12/d3d12-render-pass.h | 15 --- src/debug-layer/debug-base.h | 1 - src/debug-layer/debug-command-buffer.cpp | 22 ++-- src/debug-layer/debug-command-buffer.h | 7 +- src/debug-layer/debug-device.cpp | 38 ------ src/debug-layer/debug-device.h | 4 - src/debug-layer/debug-framebuffer.h | 9 -- src/debug-layer/debug-helper-functions.cpp | 2 - src/debug-layer/debug-helper-functions.h | 3 - src/debug-layer/debug-render-pass.h | 16 --- src/immediate-renderer-base.cpp | 64 ++-------- src/immediate-renderer-base.h | 29 +---- src/metal/metal-base.h | 2 - src/metal/metal-command-buffer.cpp | 8 +- src/metal/metal-command-buffer.h | 2 +- src/metal/metal-device.cpp | 20 --- src/metal/metal-device.h | 4 - src/renderer-shared.cpp | 9 -- src/renderer-shared.h | 8 -- src/simple-render-pass-layout.cpp | 24 ---- src/simple-render-pass-layout.h | 27 ---- src/vulkan/vk-api.h | 14 +++ src/vulkan/vk-base.h | 1 - src/vulkan/vk-command-buffer.cpp | 8 +- src/vulkan/vk-command-buffer.h | 7 +- src/vulkan/vk-command-encoder.cpp | 137 ++++++++++++++++++++- src/vulkan/vk-command-encoder.h | 9 +- src/vulkan/vk-device.cpp | 59 +++++---- src/vulkan/vk-device.h | 6 - src/vulkan/vk-framebuffer.cpp | 4 +- src/vulkan/vk-framebuffer.h | 4 + src/vulkan/vk-helper-functions.cpp | 10 +- src/vulkan/vk-helper-functions.h | 4 +- src/vulkan/vk-pipeline.cpp | 15 ++- src/vulkan/vk-render-pass.cpp | 2 + src/vulkan/vk-render-pass.h | 22 ---- tests/test-buffer-barrier.cpp | 7 +- tests/test-instanced-draw.cpp | 63 ++++++---- tests/test-nested-parameter-block.cpp | 18 +-- tests/test-ray-tracing.cpp | 1 + tests/test-resolve-resource-tests.cpp | 34 ++--- tests/test-sampler-array.slang | 2 +- tests/test-shader-cache.cpp | 35 ++---- tests/test-texture-types.cpp | 43 +++---- tests/testing.cpp | 34 ++++- 65 files changed, 570 insertions(+), 830 deletions(-) delete mode 100644 src/d3d12/d3d12-render-pass.cpp delete mode 100644 src/d3d12/d3d12-render-pass.h delete mode 100644 src/debug-layer/debug-render-pass.h delete mode 100644 src/simple-render-pass-layout.cpp delete mode 100644 src/simple-render-pass-layout.h delete mode 100644 src/vulkan/vk-render-pass.h diff --git a/include/slang-rhi.h b/include/slang-rhi.h index e75c6be8..eb7941e1 100644 --- a/include/slang-rhi.h +++ b/include/slang-rhi.h @@ -1296,20 +1296,6 @@ struct Viewport float maxZ = 1.0f; }; -class IFramebuffer : public ISlangUnknown -{ - SLANG_COM_INTERFACE(0x19ed79f3, 0xcea8, 0x4a3d, {0xae, 0xf5, 0x03, 0xa7, 0xe4, 0xda, 0xc6, 0x11}); - -public: - struct Desc - { - GfxCount renderTargetCount; - IResourceView* const* renderTargetViews; - IResourceView* depthStencilView; - IFramebufferLayout* layout; - }; -}; - struct WindowHandle { enum class Type @@ -1354,38 +1340,47 @@ struct FaceMask }; }; -class IRenderPassLayout : public ISlangUnknown +enum class TargetLoadOp { - SLANG_COM_INTERFACE(0x923d7ba6, 0xee84, 0x434f, {0x91, 0x85, 0x67, 0xda, 0x6f, 0x93, 0x9c, 0x58}); + Load, + Clear, + DontCare +}; -public: - enum class TargetLoadOp - { - Load, - Clear, - DontCare - }; - enum class TargetStoreOp - { - Store, - DontCare - }; - struct TargetAccessDesc - { - TargetLoadOp loadOp; - TargetLoadOp stencilLoadOp; - TargetStoreOp storeOp; - TargetStoreOp stencilStoreOp; - ResourceState initialState; - ResourceState finalState; - }; - struct Desc - { - IFramebufferLayout* framebufferLayout = nullptr; - GfxCount renderTargetCount; - TargetAccessDesc* renderTargetAccess = nullptr; - TargetAccessDesc* depthStencilAccess = nullptr; - }; +enum class TargetStoreOp +{ + Store, + DontCare +}; + +struct RenderAttachmentDesc +{ + float clearValue[4] = {0.0f, 0.0f, 0.0f, 0.0f}; + TargetLoadOp loadOp = TargetLoadOp::DontCare; + TargetStoreOp storeOp = TargetStoreOp::Store; + IResourceView* view = nullptr; + ResourceState initialState; + ResourceState finalState; +}; + +struct DepthStencilAttachmentDesc +{ + float depthClearValue = 1.f; + TargetLoadOp depthLoadOp = TargetLoadOp::DontCare; + TargetStoreOp depthStoreOp = TargetStoreOp::Store; + uint8_t stencilClearValue = 0; + TargetLoadOp stencilLoadOp = TargetLoadOp::DontCare; + TargetStoreOp stencilStoreOp = TargetStoreOp::DontCare; + IResourceView* view = nullptr; + ResourceState initialState; + ResourceState finalState; +}; + +struct RenderPassDesc +{ + RenderAttachmentDesc colorAttachments[kMaxRenderTargetCount]; + GfxCount colorAttachmentCount = 0; + DepthStencilAttachmentDesc depthStencilAttachment; }; enum class QueryType @@ -1754,16 +1749,13 @@ class ICommandBuffer : public ISlangUnknown return encoder; } - virtual SLANG_NO_THROW Result SLANG_MCALL encodeRenderCommands( - IRenderPassLayout* renderPass, - IFramebuffer* framebuffer, - IRenderCommandEncoder** outEncoder - ) = 0; + virtual SLANG_NO_THROW Result SLANG_MCALL + encodeRenderCommands(const RenderPassDesc& desc, IRenderCommandEncoder** outEncoder) = 0; - inline IRenderCommandEncoder* encodeRenderCommands(IRenderPassLayout* renderPass, IFramebuffer* framebuffer) + inline IRenderCommandEncoder* encodeRenderCommands(const RenderPassDesc& desc) { IRenderCommandEncoder* encoder; - SLANG_RETURN_NULL_ON_FAIL(encodeRenderCommands(renderPass, framebuffer, &encoder)); + SLANG_RETURN_NULL_ON_FAIL(encodeRenderCommands(desc, &encoder)); return encoder; } @@ -2259,24 +2251,6 @@ class IDevice : public ISlangUnknown return fb; } - virtual SLANG_NO_THROW Result SLANG_MCALL - createFramebuffer(IFramebuffer::Desc const& desc, IFramebuffer** outFrameBuffer) = 0; - inline ComPtr createFramebuffer(IFramebuffer::Desc const& desc) - { - ComPtr fb; - SLANG_RETURN_NULL_ON_FAIL(createFramebuffer(desc, fb.writeRef())); - return fb; - } - - virtual SLANG_NO_THROW Result SLANG_MCALL - createRenderPassLayout(const IRenderPassLayout::Desc& desc, IRenderPassLayout** outRenderPassLayout) = 0; - inline ComPtr createRenderPassLayout(const IRenderPassLayout::Desc& desc) - { - ComPtr rs; - SLANG_RETURN_NULL_ON_FAIL(createRenderPassLayout(desc, rs.writeRef())); - return rs; - } - virtual SLANG_NO_THROW Result SLANG_MCALL createSwapchain(ISwapchain::Desc const& desc, WindowHandle window, ISwapchain** outSwapchain) = 0; inline ComPtr createSwapchain(ISwapchain::Desc const& desc, WindowHandle window) diff --git a/src/command-writer.h b/src/command-writer.h index f4e3d8b1..ec49128f 100644 --- a/src/command-writer.h +++ b/src/command-writer.h @@ -14,8 +14,8 @@ enum class CommandName { SetPipeline, BindRootShaderObject, - SetFramebuffer, - ClearFrame, + BeginRenderPass, + EndRenderPass, SetViewports, SetScissorRects, SetPrimitiveTopology, @@ -39,6 +39,10 @@ struct Command CommandName name; uint32_t operands[kMaxCommandOperands]; Command() = default; + Command(CommandName inName) + : name(inName) + { + } Command(CommandName inName, uint32_t op) : name(inName) { @@ -162,17 +166,26 @@ class CommandWriter )); } - void setFramebuffer(IFramebuffer* frameBuffer) + void beginRenderPass(const RenderPassDesc& desc) { - auto framebufferOffset = encodeObject(static_cast(frameBuffer)); - m_commands.push_back(Command(CommandName::SetFramebuffer, (uint32_t)framebufferOffset)); + auto dataOffset = encodeData(&desc, sizeof(RenderPassDesc)); + Offset viewsOffset = 0; + for (uint32_t i = 0; i < desc.colorAttachmentCount; i++) + { + auto offset = encodeObject(static_cast(desc.colorAttachments[0].view)); + if (i == 0) + viewsOffset = offset; + } + if (desc.depthStencilAttachment.view) + { + auto offset = encodeObject(static_cast(desc.depthStencilAttachment.view)); + if (desc.colorAttachmentCount == 0) + viewsOffset = offset; + } + m_commands.push_back(Command(CommandName::BeginRenderPass, (uint32_t)dataOffset, (uint32_t)viewsOffset)); } - void clearFrame(uint32_t colorBufferMask, bool clearDepth, bool clearStencil) - { - m_commands.push_back(Command(CommandName::ClearFrame, colorBufferMask, clearDepth ? 1 : 0, clearStencil ? 1 : 0) - ); - } + void endRenderPass() { m_commands.push_back(Command(CommandName::EndRenderPass)); } void setViewports(GfxCount count, const Viewport* viewports) { diff --git a/src/cuda/cuda-command-buffer.cpp b/src/cuda/cuda-command-buffer.cpp index c15c8032..3fe9870c 100644 --- a/src/cuda/cuda-command-buffer.cpp +++ b/src/cuda/cuda-command-buffer.cpp @@ -22,14 +22,10 @@ SLANG_NO_THROW Result SLANG_MCALL CommandBufferImpl::encodeResourceCommands(IRes return SLANG_OK; } -SLANG_NO_THROW Result SLANG_MCALL CommandBufferImpl::encodeRenderCommands( - IRenderPassLayout* renderPass, - IFramebuffer* framebuffer, - IRenderCommandEncoder** outEncoder -) +SLANG_NO_THROW Result SLANG_MCALL +CommandBufferImpl::encodeRenderCommands(const RenderPassDesc& desc, IRenderCommandEncoder** outEncoder) { - SLANG_UNUSED(renderPass); - SLANG_UNUSED(framebuffer); + SLANG_UNUSED(desc); *outEncoder = nullptr; return SLANG_E_NOT_AVAILABLE; } diff --git a/src/cuda/cuda-command-buffer.h b/src/cuda/cuda-command-buffer.h index 7b23fc53..02d125ef 100644 --- a/src/cuda/cuda-command-buffer.h +++ b/src/cuda/cuda-command-buffer.h @@ -20,11 +20,8 @@ class CommandBufferImpl : public ICommandBuffer, public CommandWriter, public Co void init(DeviceImpl* device, TransientResourceHeapBase* transientHeap); virtual SLANG_NO_THROW Result SLANG_MCALL encodeResourceCommands(IResourceCommandEncoder** outEncoder) override; - virtual SLANG_NO_THROW Result SLANG_MCALL encodeRenderCommands( - IRenderPassLayout* renderPass, - IFramebuffer* framebuffer, - IRenderCommandEncoder** outEncoder - ) override; + virtual SLANG_NO_THROW Result SLANG_MCALL + encodeRenderCommands(const RenderPassDesc& desc, IRenderCommandEncoder** outEncoder) override; virtual SLANG_NO_THROW Result SLANG_MCALL encodeComputeCommands(IComputeCommandEncoder** outEncoder) override; virtual SLANG_NO_THROW Result SLANG_MCALL encodeRayTracingCommands(IRayTracingCommandEncoder** outEncoder) override; diff --git a/src/cuda/cuda-device.cpp b/src/cuda/cuda-device.cpp index ef4cc321..608425d9 100644 --- a/src/cuda/cuda-device.cpp +++ b/src/cuda/cuda-device.cpp @@ -1076,22 +1076,6 @@ DeviceImpl::createFramebufferLayout(const FramebufferLayoutDesc& desc, IFramebuf return SLANG_FAIL; } -SLANG_NO_THROW Result SLANG_MCALL -DeviceImpl::createFramebuffer(const IFramebuffer::Desc& desc, IFramebuffer** outFramebuffer) -{ - SLANG_UNUSED(desc); - SLANG_UNUSED(outFramebuffer); - return SLANG_FAIL; -} - -SLANG_NO_THROW Result SLANG_MCALL -DeviceImpl::createRenderPassLayout(const IRenderPassLayout::Desc& desc, IRenderPassLayout** outRenderPassLayout) -{ - SLANG_UNUSED(desc); - SLANG_UNUSED(outRenderPassLayout); - return SLANG_FAIL; -} - SLANG_NO_THROW Result SLANG_MCALL DeviceImpl::createSampler(SamplerDesc const& desc, ISampler** outSampler) { SLANG_UNUSED(desc); diff --git a/src/cuda/cuda-device.h b/src/cuda/cuda-device.h index 90bdad40..eedca35a 100644 --- a/src/cuda/cuda-device.h +++ b/src/cuda/cuda-device.h @@ -99,12 +99,6 @@ class DeviceImpl : public RendererBase virtual SLANG_NO_THROW Result SLANG_MCALL createFramebufferLayout(const FramebufferLayoutDesc& desc, IFramebufferLayout** outLayout) override; - virtual SLANG_NO_THROW Result SLANG_MCALL - createFramebuffer(const IFramebuffer::Desc& desc, IFramebuffer** outFramebuffer) override; - - virtual SLANG_NO_THROW Result SLANG_MCALL - createRenderPassLayout(const IRenderPassLayout::Desc& desc, IRenderPassLayout** outRenderPassLayout) override; - virtual SLANG_NO_THROW Result SLANG_MCALL createSampler(SamplerDesc const& desc, ISampler** outSampler) override; virtual SLANG_NO_THROW Result SLANG_MCALL diff --git a/src/d3d11/d3d11-base.h b/src/d3d11/d3d11-base.h index 129ec26b..d17bac39 100644 --- a/src/d3d11/d3d11-base.h +++ b/src/d3d11/d3d11-base.h @@ -54,7 +54,6 @@ class UnorderedAccessViewImpl; class DepthStencilViewImpl; class RenderTargetViewImpl; class FramebufferLayoutImpl; -class FramebufferImpl; class SwapchainImpl; class InputLayoutImpl; class QueryPoolImpl; diff --git a/src/d3d11/d3d11-device.cpp b/src/d3d11/d3d11-device.cpp index f53c4bf9..dc0579ce 100644 --- a/src/d3d11/d3d11-device.cpp +++ b/src/d3d11/d3d11-device.cpp @@ -329,35 +329,6 @@ Result DeviceImpl::initialize(const Desc& desc) return SLANG_OK; } -void DeviceImpl::clearFrame(uint32_t colorBufferMask, bool clearDepth, bool clearStencil) -{ - uint32_t mask = 1; - for (auto rtv : m_currentFramebuffer->renderTargetViews) - { - if (colorBufferMask & mask) - m_immediateContext->ClearRenderTargetView(rtv->m_rtv, rtv->m_clearValue); - mask <<= 1; - } - - if (m_currentFramebuffer->depthStencilView) - { - UINT clearFlags = 0; - if (clearDepth) - clearFlags = D3D11_CLEAR_DEPTH; - if (clearStencil) - clearFlags |= D3D11_CLEAR_STENCIL; - if (clearFlags) - { - m_immediateContext->ClearDepthStencilView( - m_currentFramebuffer->depthStencilView->m_dsv, - clearFlags, - m_currentFramebuffer->depthStencilView->m_clearValue.depth, - m_currentFramebuffer->depthStencilView->m_clearValue.stencil - ); - } - } -} - Result DeviceImpl::createSwapchain(const ISwapchain::Desc& desc, WindowHandle window, ISwapchain** outSwapchain) { RefPtr swapchain = new SwapchainImpl(); @@ -374,23 +345,7 @@ Result DeviceImpl::createFramebufferLayout(const FramebufferLayoutDesc& desc, IF return SLANG_OK; } -Result DeviceImpl::createFramebuffer(const IFramebuffer::Desc& desc, IFramebuffer** outFramebuffer) -{ - RefPtr framebuffer = new FramebufferImpl(); - framebuffer->renderTargetViews.resize(desc.renderTargetCount); - framebuffer->d3dRenderTargetViews.resize(desc.renderTargetCount); - for (GfxIndex i = 0; i < desc.renderTargetCount; i++) - { - framebuffer->renderTargetViews[i] = static_cast(desc.renderTargetViews[i]); - framebuffer->d3dRenderTargetViews[i] = framebuffer->renderTargetViews[i]->m_rtv; - } - framebuffer->depthStencilView = static_cast(desc.depthStencilView); - framebuffer->d3dDepthStencilView = framebuffer->depthStencilView ? framebuffer->depthStencilView->m_dsv : nullptr; - returnComPtr(outFramebuffer, framebuffer); - return SLANG_OK; -} - -void DeviceImpl::setFramebuffer(IFramebuffer* frameBuffer) +void DeviceImpl::beginRenderPass(const RenderPassDesc& desc) { // Note: the framebuffer state will be flushed to the pipeline as part // of binding the root shader object. @@ -399,7 +354,56 @@ void DeviceImpl::setFramebuffer(IFramebuffer* frameBuffer) // call `OMSetRenderTargetsAndUnorderedAccessViews` later with the option // that preserves the existing RTV/DSV bindings. // - m_currentFramebuffer = static_cast(frameBuffer); + m_d3dRenderTargetViews.resize(desc.colorAttachmentCount); + for (Index i = 0; i < desc.colorAttachmentCount; ++i) + { + m_d3dRenderTargetViews[i] = static_cast(desc.colorAttachments[i].view)->m_rtv; + } + m_d3dDepthStencilView = desc.depthStencilAttachment.view + ? static_cast(desc.depthStencilAttachment.view)->m_dsv + : nullptr; + + // Clear color attachments. + for (Index i = 0; i < desc.colorAttachmentCount; ++i) + { + const auto& attachment = desc.colorAttachments[i]; + if (attachment.loadOp == TargetLoadOp::Clear) + { + m_immediateContext->ClearRenderTargetView( + static_cast(attachment.view)->m_rtv, + attachment.clearValue + ); + } + } + // Clear depth/stencil attachment. + if (desc.depthStencilAttachment.view) + { + const auto& attachment = desc.depthStencilAttachment; + UINT clearFlags = 0; + if (attachment.depthLoadOp == TargetLoadOp::Clear) + { + clearFlags |= D3D11_CLEAR_DEPTH; + } + if (attachment.stencilLoadOp == TargetLoadOp::Clear) + { + clearFlags |= D3D11_CLEAR_STENCIL; + } + if (clearFlags) + { + m_immediateContext->ClearDepthStencilView( + static_cast(attachment.view)->m_dsv, + D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, + attachment.depthClearValue, + attachment.stencilClearValue + ); + } + } +} + +void DeviceImpl::endRenderPass() +{ + m_d3dRenderTargetViews.clear(); + m_d3dDepthStencilView = nullptr; } void DeviceImpl::setStencilReference(uint32_t referenceValue) @@ -1515,7 +1519,7 @@ void DeviceImpl::bindRootShaderObject(IShaderObject* shaderObject) // RTVs are bound as part of the active framebuffer, and then adjust // the UAVs that we bind accordingly. // - auto rtvCount = (UINT)m_currentFramebuffer->renderTargetViews.size(); + auto rtvCount = (UINT)m_d3dRenderTargetViews.size(); // // The `context` we are using will have computed the number of UAV registers // that might need to be bound, as a range from 0 to `context.uavCount`. @@ -1543,8 +1547,8 @@ void DeviceImpl::bindRootShaderObject(IShaderObject* shaderObject) // m_immediateContext->OMSetRenderTargetsAndUnorderedAccessViews( rtvCount, - m_currentFramebuffer->d3dRenderTargetViews.data(), - m_currentFramebuffer->d3dDepthStencilView, + m_d3dRenderTargetViews.data(), + m_d3dDepthStencilView, rtvCount, bindableUAVCount, bindableUAVs, diff --git a/src/d3d11/d3d11-device.h b/src/d3d11/d3d11-device.h index 0e32d06f..a9b61cb9 100644 --- a/src/d3d11/d3d11-device.h +++ b/src/d3d11/d3d11-device.h @@ -2,6 +2,7 @@ #include "d3d11-framebuffer.h" #include "d3d11-pipeline.h" +#include "d3d11-resource-views.h" namespace rhi::d3d11 { @@ -12,14 +13,12 @@ class DeviceImpl : public ImmediateRendererBase // Renderer implementation virtual SLANG_NO_THROW Result SLANG_MCALL initialize(const Desc& desc) override; - virtual void clearFrame(uint32_t colorBufferMask, bool clearDepth, bool clearStencil) override; virtual SLANG_NO_THROW Result SLANG_MCALL createSwapchain(const ISwapchain::Desc& desc, WindowHandle window, ISwapchain** outSwapchain) override; virtual SLANG_NO_THROW Result SLANG_MCALL createFramebufferLayout(const FramebufferLayoutDesc& desc, IFramebufferLayout** outLayout) override; - virtual SLANG_NO_THROW Result SLANG_MCALL - createFramebuffer(const IFramebuffer::Desc& desc, IFramebuffer** outFramebuffer) override; - virtual void setFramebuffer(IFramebuffer* frameBuffer) override; + virtual void beginRenderPass(const RenderPassDesc& desc) override; + virtual void endRenderPass() override; virtual void setStencilReference(uint32_t referenceValue) override; virtual SLANG_NO_THROW Result SLANG_MCALL @@ -116,7 +115,13 @@ class DeviceImpl : public ImmediateRendererBase ComPtr m_immediateContext; ComPtr m_backBufferTexture; ComPtr m_dxgiFactory; - RefPtr m_currentFramebuffer; + + short_vector m_d3dRenderTargetViews; + ID3D11DepthStencilView* m_d3dDepthStencilView; + + RefPtr m_currentColorAttachments[kMaxRenderTargetCount]; + GfxCount m_currentColorAttachmentCount = 0; + RefPtr m_currentDepthStencilAttachment; RefPtr m_currentPipeline; diff --git a/src/d3d11/d3d11-framebuffer.h b/src/d3d11/d3d11-framebuffer.h index d80030e3..360c8d9f 100644 --- a/src/d3d11/d3d11-framebuffer.h +++ b/src/d3d11/d3d11-framebuffer.h @@ -18,13 +18,4 @@ class FramebufferLayoutImpl : public FramebufferLayoutBase FramebufferLayoutDesc m_desc; }; -class FramebufferImpl : public FramebufferBase -{ -public: - short_vector, kMaxRTVs> renderTargetViews; - short_vector d3dRenderTargetViews; - RefPtr depthStencilView; - ID3D11DepthStencilView* d3dDepthStencilView; -}; - } // namespace rhi::d3d11 diff --git a/src/d3d11/d3d11-swap-chain.cpp b/src/d3d11/d3d11-swap-chain.cpp index 3e442b7a..94bb0db3 100644 --- a/src/d3d11/d3d11-swap-chain.cpp +++ b/src/d3d11/d3d11-swap-chain.cpp @@ -40,7 +40,6 @@ void SwapchainImpl::createSwapchainBufferImages() SLANG_NO_THROW Result SLANG_MCALL SwapchainImpl::resize(GfxCount width, GfxCount height) { - m_renderer->m_currentFramebuffer = nullptr; m_renderer->m_immediateContext->ClearState(); return D3DSwapchainBase::resize(width, height); } diff --git a/src/d3d12/d3d12-base.h b/src/d3d12/d3d12-base.h index d83c7e83..e450ee8b 100644 --- a/src/d3d12/d3d12-base.h +++ b/src/d3d12/d3d12-base.h @@ -4,7 +4,6 @@ #include "../d3d/d3d-swapchain.h" #include "../mutable-shader-object.h" #include "../renderer-shared.h" -#include "../simple-render-pass-layout.h" #include "../transient-resource-heap-base.h" #include "d3d12-descriptor-heap.h" #include "d3d12-posix-synchapi.h" @@ -49,11 +48,9 @@ class ComputeCommandEncoderImpl; class CommandQueueImpl; class FenceImpl; class FramebufferLayoutImpl; -class FramebufferImpl; class QueryPoolImpl; class PlainBufferProxyQueryPoolImpl; class PipelineImpl; -class RenderPassLayoutImpl; class ResourceViewInternalImpl; class ResourceViewImpl; class AccelerationStructureImpl; diff --git a/src/d3d12/d3d12-command-buffer.cpp b/src/d3d12/d3d12-command-buffer.cpp index 239b4363..bc00c679 100644 --- a/src/d3d12/d3d12-command-buffer.cpp +++ b/src/d3d12/d3d12-command-buffer.cpp @@ -77,19 +77,9 @@ Result CommandBufferImpl::encodeResourceCommands(IResourceCommandEncoder** outEn return SLANG_OK; } -Result CommandBufferImpl::encodeRenderCommands( - IRenderPassLayout* renderPass, - IFramebuffer* framebuffer, - IRenderCommandEncoder** outEncoder -) +Result CommandBufferImpl::encodeRenderCommands(const RenderPassDesc& desc, IRenderCommandEncoder** outEncoder) { - m_renderCommandEncoder.init( - m_renderer, - m_transientHeap, - this, - static_cast(renderPass), - static_cast(framebuffer) - ); + m_renderCommandEncoder.init(m_renderer, m_transientHeap, this, desc); *outEncoder = &m_renderCommandEncoder; return SLANG_OK; } diff --git a/src/d3d12/d3d12-command-buffer.h b/src/d3d12/d3d12-command-buffer.h index 461f66b7..06791a7b 100644 --- a/src/d3d12/d3d12-command-buffer.h +++ b/src/d3d12/d3d12-command-buffer.h @@ -61,11 +61,8 @@ class CommandBufferImpl : public ICommandBufferD3D12, public ComObject RenderCommandEncoderImpl m_renderCommandEncoder; - virtual SLANG_NO_THROW Result SLANG_MCALL encodeRenderCommands( - IRenderPassLayout* renderPass, - IFramebuffer* framebuffer, - IRenderCommandEncoder** outEncoder - ) override; + virtual SLANG_NO_THROW Result SLANG_MCALL + encodeRenderCommands(const RenderPassDesc& desc, IRenderCommandEncoder** outEncoder) override; ComputeCommandEncoderImpl m_computeCommandEncoder; diff --git a/src/d3d12/d3d12-command-encoder.cpp b/src/d3d12/d3d12-command-encoder.cpp index 763afb79..46976cd1 100644 --- a/src/d3d12/d3d12-command-encoder.cpp +++ b/src/d3d12/d3d12-command-encoder.cpp @@ -787,14 +787,11 @@ void RenderCommandEncoderImpl::init( DeviceImpl* renderer, TransientResourceHeapImpl* transientHeap, CommandBufferImpl* cmdBuffer, - RenderPassLayoutImpl* renderPass, - FramebufferImpl* framebuffer + const RenderPassDesc& desc ) { CommandEncoderImpl::init(cmdBuffer); m_preCmdList = nullptr; - m_renderPass = renderPass; - m_framebuffer = framebuffer; m_transientHeap = transientHeap; m_boundVertexBuffers.clear(); m_boundIndexBuffer = nullptr; @@ -804,95 +801,95 @@ void RenderCommandEncoderImpl::init( m_boundIndexOffset = 0; m_currentPipeline = nullptr; - // Set render target states. - if (!framebuffer) + m_renderTargetViews.resize(desc.colorAttachmentCount); + m_renderTargetFinalStates.resize(desc.colorAttachmentCount); + static_vector renderTargetDescriptors; + for (Index i = 0; i < desc.colorAttachmentCount; i++) { - return; + m_renderTargetViews[i] = static_cast(desc.colorAttachments[i].view); + m_renderTargetFinalStates[i] = desc.colorAttachments[i].finalState; + renderTargetDescriptors.push_back(m_renderTargetViews[i]->m_descriptor.cpuHandle); } + m_depthStencilView = static_cast(desc.depthStencilAttachment.view); + m_depthStencilFinalState = desc.depthStencilAttachment.finalState; + m_d3dCmdList->OMSetRenderTargets( - (UINT)framebuffer->renderTargetViews.size(), - framebuffer->renderTargetDescriptors.data(), + (UINT)m_renderTargetViews.size(), + renderTargetDescriptors.data(), FALSE, - framebuffer->depthStencilView ? &framebuffer->depthStencilDescriptor : nullptr + m_depthStencilView ? &m_depthStencilView->m_descriptor.cpuHandle : nullptr ); // Issue clear commands based on render pass set up. - for (Index i = 0; i < framebuffer->renderTargetViews.size(); i++) + for (Index i = 0; i < m_renderTargetViews.size(); i++) { - if (i >= renderPass->m_renderTargetAccesses.size()) - continue; - - auto& access = renderPass->m_renderTargetAccesses[i]; + const auto& attachment = desc.colorAttachments[i]; // Transit resource states. { D3D12BarrierSubmitter submitter(m_d3dCmdList); - auto resourceViewImpl = framebuffer->renderTargetViews[i].Ptr(); + auto resourceViewImpl = m_renderTargetViews[i].get(); if (resourceViewImpl) { auto texture = static_cast(resourceViewImpl->m_resource.Ptr()); if (texture) { D3D12_RESOURCE_STATES initialState; - if (access.initialState == ResourceState::Undefined) + if (attachment.initialState == ResourceState::Undefined) { initialState = texture->m_defaultState; } else { - initialState = D3DUtil::getResourceState(access.initialState); + initialState = D3DUtil::getResourceState(attachment.initialState); } texture->m_resource.transition(initialState, D3D12_RESOURCE_STATE_RENDER_TARGET, submitter); } } } // Clear. - if (access.loadOp == IRenderPassLayout::TargetLoadOp::Clear) + if (attachment.loadOp == TargetLoadOp::Clear) { - m_d3dCmdList->ClearRenderTargetView( - framebuffer->renderTargetDescriptors[i], - framebuffer->renderTargetClearValues[i].values, - 0, - nullptr - ); + m_d3dCmdList->ClearRenderTargetView(renderTargetDescriptors[i], attachment.clearValue, 0, nullptr); } } - if (renderPass->m_hasDepthStencil) + if (m_depthStencilView) { + const auto& attachment = desc.depthStencilAttachment; + // Transit resource states. { D3D12BarrierSubmitter submitter(m_d3dCmdList); - auto resourceViewImpl = framebuffer->depthStencilView.Ptr(); - auto texture = static_cast(resourceViewImpl->m_resource.Ptr()); + auto texture = static_cast(m_depthStencilView->m_resource.get()); D3D12_RESOURCE_STATES initialState; - if (renderPass->m_depthStencilAccess.initialState == ResourceState::Undefined) + if (attachment.initialState == ResourceState::Undefined) { initialState = texture->m_defaultState; } else { - initialState = D3DUtil::getResourceState(renderPass->m_depthStencilAccess.initialState); + initialState = D3DUtil::getResourceState(attachment.initialState); } texture->m_resource.transition(initialState, D3D12_RESOURCE_STATE_DEPTH_WRITE, submitter); } // Clear. uint32_t clearFlags = 0; - if (renderPass->m_depthStencilAccess.loadOp == IRenderPassLayout::TargetLoadOp::Clear) + if (attachment.depthLoadOp == TargetLoadOp::Clear) { clearFlags |= D3D12_CLEAR_FLAG_DEPTH; } - if (renderPass->m_depthStencilAccess.stencilLoadOp == IRenderPassLayout::TargetLoadOp::Clear) + if (attachment.stencilLoadOp == TargetLoadOp::Clear) { clearFlags |= D3D12_CLEAR_FLAG_STENCIL; } if (clearFlags) { m_d3dCmdList->ClearDepthStencilView( - framebuffer->depthStencilDescriptor, + m_depthStencilView->m_descriptor.cpuHandle, (D3D12_CLEAR_FLAGS)clearFlags, - framebuffer->depthStencilClearValue.depth, - framebuffer->depthStencilClearValue.stencil, + attachment.depthClearValue, + attachment.stencilClearValue, 0, nullptr ); @@ -1056,45 +1053,44 @@ Result RenderCommandEncoderImpl::drawIndexed(GfxCount indexCount, GfxIndex start void RenderCommandEncoderImpl::endEncoding() { - CommandEncoderImpl::endEncodingImpl(); - if (!m_framebuffer) - return; // Issue clear commands based on render pass set up. - for (Index i = 0; i < m_renderPass->m_renderTargetAccesses.size(); i++) + for (Index i = 0; i < m_renderTargetViews.size(); i++) { - auto& access = m_renderPass->m_renderTargetAccesses[i]; - // Transit resource states. + if (m_renderTargetViews[i]) { D3D12BarrierSubmitter submitter(m_d3dCmdList); - auto resourceViewImpl = m_framebuffer->renderTargetViews[i].Ptr(); - if (!resourceViewImpl) - continue; - auto texture = static_cast(resourceViewImpl->m_resource.Ptr()); + auto texture = static_cast(m_renderTargetViews[i]->m_resource.get()); if (texture) { texture->m_resource.transition( D3D12_RESOURCE_STATE_RENDER_TARGET, - D3DUtil::getResourceState(access.finalState), + D3DUtil::getResourceState(m_renderTargetFinalStates[i]), submitter ); } } } - if (m_renderPass->m_hasDepthStencil) + if (m_depthStencilView) { // Transit resource states. D3D12BarrierSubmitter submitter(m_d3dCmdList); - auto resourceViewImpl = m_framebuffer->depthStencilView.Ptr(); - auto texture = static_cast(resourceViewImpl->m_resource.Ptr()); - texture->m_resource.transition( - D3D12_RESOURCE_STATE_DEPTH_WRITE, - D3DUtil::getResourceState(m_renderPass->m_depthStencilAccess.finalState), - submitter - ); + auto texture = static_cast(m_depthStencilView->m_resource.get()); + if (texture) + { + texture->m_resource.transition( + D3D12_RESOURCE_STATE_DEPTH_WRITE, + D3DUtil::getResourceState(m_depthStencilFinalState), + submitter + ); + } } - m_framebuffer = nullptr; + + m_renderTargetViews.clear(); + m_depthStencilView = nullptr; + + CommandEncoderImpl::endEncodingImpl(); } void RenderCommandEncoderImpl::setStencilReference(uint32_t referenceValue) diff --git a/src/d3d12/d3d12-command-encoder.h b/src/d3d12/d3d12-command-encoder.h index 92f34144..ddf99ec2 100644 --- a/src/d3d12/d3d12-command-encoder.h +++ b/src/d3d12/d3d12-command-encoder.h @@ -3,9 +3,10 @@ #include "d3d12-base.h" #include "d3d12-buffer.h" #include "d3d12-framebuffer.h" -#include "d3d12-render-pass.h" #include "d3d12-submitter.h" +#include "core/static_vector.h" + namespace rhi::d3d12 { static const Int kMaxRTVCount = 8; @@ -165,8 +166,10 @@ class RenderCommandEncoderImpl : public IRenderCommandEncoder, public CommandEnc } public: - RefPtr m_renderPass; - RefPtr m_framebuffer; + static_vector, kMaxRenderTargetCount> m_renderTargetViews; + static_vector m_renderTargetFinalStates; + RefPtr m_depthStencilView; + ResourceState m_depthStencilFinalState; std::vector m_boundVertexBuffers; @@ -185,8 +188,7 @@ class RenderCommandEncoderImpl : public IRenderCommandEncoder, public CommandEnc DeviceImpl* renderer, TransientResourceHeapImpl* transientHeap, CommandBufferImpl* cmdBuffer, - RenderPassLayoutImpl* renderPass, - FramebufferImpl* framebuffer + const RenderPassDesc& desc ); virtual SLANG_NO_THROW Result SLANG_MCALL bindPipeline(IPipeline* state, IShaderObject** outRootObject) override; diff --git a/src/d3d12/d3d12-device.cpp b/src/d3d12/d3d12-device.cpp index ed77fca8..2419374a 100644 --- a/src/d3d12/d3d12-device.cpp +++ b/src/d3d12/d3d12-device.cpp @@ -6,7 +6,6 @@ #include "d3d12-helper-functions.h" #include "d3d12-pipeline.h" #include "d3d12-query.h" -#include "d3d12-render-pass.h" #include "d3d12-resource-views.h" #include "d3d12-sampler.h" #include "d3d12-shader-object.h" @@ -1657,55 +1656,6 @@ Result DeviceImpl::createBufferView( return SLANG_OK; } -Result DeviceImpl::createFramebuffer(IFramebuffer::Desc const& desc, IFramebuffer** outFb) -{ - RefPtr framebuffer = new FramebufferImpl(); - framebuffer->renderTargetViews.resize(desc.renderTargetCount); - framebuffer->renderTargetDescriptors.resize(desc.renderTargetCount); - framebuffer->renderTargetClearValues.resize(desc.renderTargetCount); - for (GfxIndex i = 0; i < desc.renderTargetCount; i++) - { - framebuffer->renderTargetViews[i] = static_cast(desc.renderTargetViews[i]); - framebuffer->renderTargetDescriptors[i] = framebuffer->renderTargetViews[i]->m_descriptor.cpuHandle; - if (static_cast(desc.renderTargetViews[i])->m_resource.Ptr()) - { - auto clearValue = - static_cast(static_cast(desc.renderTargetViews[i])->m_resource.Ptr()) - ->getDesc() - ->optimalClearValue; - if (clearValue) - { - memcpy(&framebuffer->renderTargetClearValues[i], &clearValue->color, sizeof(ColorClearValue)); - } - } - else - { - memset(&framebuffer->renderTargetClearValues[i], 0, sizeof(ColorClearValue)); - } - } - framebuffer->depthStencilView = static_cast(desc.depthStencilView); - if (desc.depthStencilView) - { - auto clearValue = - static_cast(static_cast(desc.depthStencilView)->m_resource.Ptr()) - ->getDesc() - ->optimalClearValue; - - if (clearValue) - { - framebuffer->depthStencilClearValue = clearValue->depthStencil; - } - framebuffer->depthStencilDescriptor = - static_cast(desc.depthStencilView)->m_descriptor.cpuHandle; - } - else - { - framebuffer->depthStencilDescriptor.ptr = 0; - } - returnComPtr(outFb, framebuffer); - return SLANG_OK; -} - Result DeviceImpl::createFramebufferLayout(FramebufferLayoutDesc const& desc, IFramebufferLayout** outLayout) { RefPtr layout = new FramebufferLayoutImpl(); @@ -1714,14 +1664,6 @@ Result DeviceImpl::createFramebufferLayout(FramebufferLayoutDesc const& desc, IF return SLANG_OK; } -Result DeviceImpl::createRenderPassLayout(const IRenderPassLayout::Desc& desc, IRenderPassLayout** outRenderPassLayout) -{ - RefPtr result = new RenderPassLayoutImpl(); - result->init(desc); - returnComPtr(outRenderPassLayout, result); - return SLANG_OK; -} - Result DeviceImpl::createInputLayout(InputLayoutDesc const& desc, IInputLayout** outLayout) { RefPtr layout(new InputLayoutImpl); diff --git a/src/d3d12/d3d12-device.h b/src/d3d12/d3d12-device.h index 2f9ce94c..612eddcc 100644 --- a/src/d3d12/d3d12-device.h +++ b/src/d3d12/d3d12-device.h @@ -129,15 +129,9 @@ class DeviceImpl : public RendererBase createBufferView(IBuffer* buffer, IBuffer* counterBuffer, IResourceView::Desc const& desc, IResourceView** outView) override; - virtual SLANG_NO_THROW Result SLANG_MCALL - createFramebuffer(IFramebuffer::Desc const& desc, IFramebuffer** outFrameBuffer) override; - virtual SLANG_NO_THROW Result SLANG_MCALL createFramebufferLayout(FramebufferLayoutDesc const& desc, IFramebufferLayout** outLayout) override; - virtual SLANG_NO_THROW Result SLANG_MCALL - createRenderPassLayout(const IRenderPassLayout::Desc& desc, IRenderPassLayout** outRenderPassLayout) override; - virtual SLANG_NO_THROW Result SLANG_MCALL createInputLayout(InputLayoutDesc const& desc, IInputLayout** outLayout) override; diff --git a/src/d3d12/d3d12-framebuffer.h b/src/d3d12/d3d12-framebuffer.h index 18e5369e..263b21bf 100644 --- a/src/d3d12/d3d12-framebuffer.h +++ b/src/d3d12/d3d12-framebuffer.h @@ -13,19 +13,4 @@ class FramebufferLayoutImpl : public FramebufferLayoutBase FramebufferLayoutDesc m_desc; }; -class FramebufferImpl : public FramebufferBase -{ -public: - short_vector> renderTargetViews; - RefPtr depthStencilView; - short_vector renderTargetDescriptors; - struct Color4f - { - float values[4]; - }; - short_vector renderTargetClearValues; - D3D12_CPU_DESCRIPTOR_HANDLE depthStencilDescriptor; - DepthStencilClearValue depthStencilClearValue; -}; - } // namespace rhi::d3d12 diff --git a/src/d3d12/d3d12-render-pass.cpp b/src/d3d12/d3d12-render-pass.cpp deleted file mode 100644 index 1e361b97..00000000 --- a/src/d3d12/d3d12-render-pass.cpp +++ /dev/null @@ -1,12 +0,0 @@ -#include "d3d12-render-pass.h" - -namespace rhi::d3d12 { - -void RenderPassLayoutImpl::init(const IRenderPassLayout::Desc& desc) -{ - SimpleRenderPassLayout::init(desc); - m_framebufferLayout = static_cast(desc.framebufferLayout); - m_hasDepthStencil = m_framebufferLayout->m_desc.depthStencil.format != Format::Unknown; -} - -} // namespace rhi::d3d12 diff --git a/src/d3d12/d3d12-render-pass.h b/src/d3d12/d3d12-render-pass.h deleted file mode 100644 index 84c964d0..00000000 --- a/src/d3d12/d3d12-render-pass.h +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -#include "d3d12-base.h" -#include "d3d12-framebuffer.h" - -namespace rhi::d3d12 { - -class RenderPassLayoutImpl : public SimpleRenderPassLayout -{ -public: - RefPtr m_framebufferLayout; - void init(const IRenderPassLayout::Desc& desc); -}; - -} // namespace rhi::d3d12 diff --git a/src/debug-layer/debug-base.h b/src/debug-layer/debug-base.h index af50a377..97924586 100644 --- a/src/debug-layer/debug-base.h +++ b/src/debug-layer/debug-base.h @@ -58,7 +58,6 @@ class DebugFramebuffer; class DebugFramebufferLayout; class DebugInputLayout; class DebugPipeline; -class DebugRenderPassLayout; class DebugShaderProgram; class DebugTransientResourceHeap; class DebugSwapchain; diff --git a/src/debug-layer/debug-command-buffer.cpp b/src/debug-layer/debug-command-buffer.cpp index 79692902..c9cacd96 100644 --- a/src/debug-layer/debug-command-buffer.cpp +++ b/src/debug-layer/debug-command-buffer.cpp @@ -1,7 +1,6 @@ #include "debug-command-buffer.h" #include "debug-framebuffer.h" #include "debug-helper-functions.h" -#include "debug-render-pass.h" namespace rhi::debug { @@ -34,21 +33,22 @@ Result DebugCommandBuffer::encodeResourceCommands(IResourceCommandEncoder** outE return SLANG_OK; } -Result DebugCommandBuffer::encodeRenderCommands( - IRenderPassLayout* renderPass, - IFramebuffer* framebuffer, - IRenderCommandEncoder** outEncoder -) +Result DebugCommandBuffer::encodeRenderCommands(const RenderPassDesc& desc, IRenderCommandEncoder** outEncoder) { SLANG_RHI_API_FUNC; checkCommandBufferOpenWhenCreatingEncoder(); checkEncodersClosedBeforeNewEncoder(); - auto innerRenderPass = getInnerObj(renderPass); - auto innerFramebuffer = getInnerObj(framebuffer); + RenderPassDesc innerDesc = desc; + for (Index i = 0; i < innerDesc.colorAttachmentCount; ++i) + { + innerDesc.colorAttachments[i].view = getInnerObj(desc.colorAttachments[i].view); + } + if (innerDesc.depthStencilAttachment.view) + { + innerDesc.depthStencilAttachment.view = getInnerObj(desc.depthStencilAttachment.view); + } m_renderCommandEncoder.isOpen = true; - SLANG_RETURN_ON_FAIL( - baseObject->encodeRenderCommands(innerRenderPass, innerFramebuffer, &m_renderCommandEncoder.baseObject) - ); + SLANG_RETURN_ON_FAIL(baseObject->encodeRenderCommands(innerDesc, &m_renderCommandEncoder.baseObject)); *outEncoder = &m_renderCommandEncoder; return SLANG_OK; } diff --git a/src/debug-layer/debug-command-buffer.h b/src/debug-layer/debug-command-buffer.h index 24bbc421..fed68120 100644 --- a/src/debug-layer/debug-command-buffer.h +++ b/src/debug-layer/debug-command-buffer.h @@ -24,11 +24,8 @@ class DebugCommandBuffer : public DebugObject, ICommandBufferD3D DebugCommandBuffer(); ICommandBuffer* getInterface(const Guid& guid); virtual SLANG_NO_THROW Result SLANG_MCALL encodeResourceCommands(IResourceCommandEncoder** outEncoder) override; - virtual SLANG_NO_THROW Result SLANG_MCALL encodeRenderCommands( - IRenderPassLayout* renderPass, - IFramebuffer* framebuffer, - IRenderCommandEncoder** outEncoder - ) override; + virtual SLANG_NO_THROW Result SLANG_MCALL + encodeRenderCommands(const RenderPassDesc& desc, IRenderCommandEncoder** outEncoder) override; virtual SLANG_NO_THROW Result SLANG_MCALL encodeComputeCommands(IComputeCommandEncoder** outEncoder) override; virtual SLANG_NO_THROW Result SLANG_MCALL encodeRayTracingCommands(IRayTracingCommandEncoder** outEncoder) override; virtual SLANG_NO_THROW void SLANG_MCALL close() override; diff --git a/src/debug-layer/debug-device.cpp b/src/debug-layer/debug-device.cpp index 6d35166f..6fb29324 100644 --- a/src/debug-layer/debug-device.cpp +++ b/src/debug-layer/debug-device.cpp @@ -6,7 +6,6 @@ #include "debug-helper-functions.h" #include "debug-pipeline.h" #include "debug-query.h" -#include "debug-render-pass.h" #include "debug-resource-views.h" #include "debug-sampler.h" #include "debug-shader-object.h" @@ -252,43 +251,6 @@ Result DebugDevice::createFramebufferLayout(FramebufferLayoutDesc const& desc, I return result; } -Result DebugDevice::createFramebuffer(IFramebuffer::Desc const& desc, IFramebuffer** outFrameBuffer) -{ - SLANG_RHI_API_FUNC; - - auto innerDesc = desc; - innerDesc.layout = getInnerObj(desc.layout); - innerDesc.depthStencilView = getInnerObj(desc.depthStencilView); - std::vector innerRenderTargets; - for (GfxIndex i = 0; i < desc.renderTargetCount; i++) - { - auto innerRenderTarget = getInnerObj(desc.renderTargetViews[i]); - innerRenderTargets.push_back(innerRenderTarget); - } - innerDesc.renderTargetViews = innerRenderTargets.data(); - - RefPtr outObject = new DebugFramebuffer(); - auto result = baseObject->createFramebuffer(innerDesc, outObject->baseObject.writeRef()); - if (SLANG_FAILED(result)) - return result; - returnComPtr(outFrameBuffer, outObject); - return result; -} - -Result DebugDevice::createRenderPassLayout(const IRenderPassLayout::Desc& desc, IRenderPassLayout** outRenderPassLayout) -{ - SLANG_RHI_API_FUNC; - - auto innerDesc = desc; - innerDesc.framebufferLayout = getInnerObj(desc.framebufferLayout); - RefPtr outObject = new DebugRenderPassLayout(); - auto result = baseObject->createRenderPassLayout(innerDesc, outObject->baseObject.writeRef()); - if (SLANG_FAILED(result)) - return result; - returnComPtr(outRenderPassLayout, outObject); - return result; -} - Result DebugDevice::createSwapchain(ISwapchain::Desc const& desc, WindowHandle window, ISwapchain** outSwapchain) { SLANG_RHI_API_FUNC; diff --git a/src/debug-layer/debug-device.h b/src/debug-layer/debug-device.h index 2282b16e..ffbb705a 100644 --- a/src/debug-layer/debug-device.h +++ b/src/debug-layer/debug-device.h @@ -57,10 +57,6 @@ class DebugDevice : public DebugObject virtual SLANG_NO_THROW Result SLANG_MCALL createFramebufferLayout(FramebufferLayoutDesc const& desc, IFramebufferLayout** outFrameBuffer) override; virtual SLANG_NO_THROW Result SLANG_MCALL - createFramebuffer(IFramebuffer::Desc const& desc, IFramebuffer** outFrameBuffer) override; - virtual SLANG_NO_THROW Result SLANG_MCALL - createRenderPassLayout(const IRenderPassLayout::Desc& desc, IRenderPassLayout** outRenderPassLayout) override; - virtual SLANG_NO_THROW Result SLANG_MCALL createSwapchain(ISwapchain::Desc const& desc, WindowHandle window, ISwapchain** outSwapchain) override; virtual SLANG_NO_THROW Result SLANG_MCALL createInputLayout(InputLayoutDesc const& desc, IInputLayout** outLayout) override; diff --git a/src/debug-layer/debug-framebuffer.h b/src/debug-layer/debug-framebuffer.h index 242b7deb..5ad4d10f 100644 --- a/src/debug-layer/debug-framebuffer.h +++ b/src/debug-layer/debug-framebuffer.h @@ -4,15 +4,6 @@ namespace rhi::debug { -class DebugFramebuffer : public DebugObject -{ -public: - SLANG_COM_OBJECT_IUNKNOWN_ALL; - -public: - IFramebuffer* getInterface(const Guid& guid); -}; - class DebugFramebufferLayout : public DebugObject { public: diff --git a/src/debug-layer/debug-helper-functions.cpp b/src/debug-layer/debug-helper-functions.cpp index dd581e15..dfdb9b24 100644 --- a/src/debug-layer/debug-helper-functions.cpp +++ b/src/debug-layer/debug-helper-functions.cpp @@ -10,10 +10,8 @@ SLANG_RHI_DEBUG_GET_INTERFACE_IMPL(Device) SLANG_RHI_DEBUG_GET_INTERFACE_IMPL_PARENT(Buffer, Resource) SLANG_RHI_DEBUG_GET_INTERFACE_IMPL_PARENT(Texture, Resource) SLANG_RHI_DEBUG_GET_INTERFACE_IMPL(CommandQueue) -SLANG_RHI_DEBUG_GET_INTERFACE_IMPL(Framebuffer) SLANG_RHI_DEBUG_GET_INTERFACE_IMPL(FramebufferLayout) SLANG_RHI_DEBUG_GET_INTERFACE_IMPL(InputLayout) -SLANG_RHI_DEBUG_GET_INTERFACE_IMPL(RenderPassLayout) SLANG_RHI_DEBUG_GET_INTERFACE_IMPL(Pipeline) SLANG_RHI_DEBUG_GET_INTERFACE_IMPL(ResourceView) SLANG_RHI_DEBUG_GET_INTERFACE_IMPL(Sampler) diff --git a/src/debug-layer/debug-helper-functions.h b/src/debug-layer/debug-helper-functions.h index 365c63a4..31f43f7d 100644 --- a/src/debug-layer/debug-helper-functions.h +++ b/src/debug-layer/debug-helper-functions.h @@ -8,7 +8,6 @@ #include "debug-framebuffer.h" #include "debug-pipeline.h" #include "debug-query.h" -#include "debug-render-pass.h" #include "debug-resource-views.h" #include "debug-sampler.h" #include "debug-shader-object.h" @@ -161,10 +160,8 @@ SLANG_RHI_DEBUG_GET_OBJ_IMPL_UNOWNED(ComputeCommandEncoder) SLANG_RHI_DEBUG_GET_OBJ_IMPL_UNOWNED(RenderCommandEncoder) SLANG_RHI_DEBUG_GET_OBJ_IMPL_UNOWNED(ResourceCommandEncoder) SLANG_RHI_DEBUG_GET_OBJ_IMPL_UNOWNED(RayTracingCommandEncoder) -SLANG_RHI_DEBUG_GET_OBJ_IMPL(Framebuffer) SLANG_RHI_DEBUG_GET_OBJ_IMPL(FramebufferLayout) SLANG_RHI_DEBUG_GET_OBJ_IMPL(InputLayout) -SLANG_RHI_DEBUG_GET_OBJ_IMPL(RenderPassLayout) SLANG_RHI_DEBUG_GET_OBJ_IMPL(Pipeline) SLANG_RHI_DEBUG_GET_OBJ_IMPL(ResourceView) SLANG_RHI_DEBUG_GET_OBJ_IMPL(Sampler) diff --git a/src/debug-layer/debug-render-pass.h b/src/debug-layer/debug-render-pass.h deleted file mode 100644 index cbb688c0..00000000 --- a/src/debug-layer/debug-render-pass.h +++ /dev/null @@ -1,16 +0,0 @@ -#pragma once - -#include "debug-base.h" - -namespace rhi::debug { - -class DebugRenderPassLayout : public DebugObject -{ -public: - SLANG_COM_OBJECT_IUNKNOWN_ALL; - -public: - IRenderPassLayout* getInterface(const Guid& guid); -}; - -} // namespace rhi::debug diff --git a/src/immediate-renderer-base.cpp b/src/immediate-renderer-base.cpp index 75325e05..c897f4fd 100644 --- a/src/immediate-renderer-base.cpp +++ b/src/immediate-renderer-base.cpp @@ -1,7 +1,6 @@ #include "immediate-renderer-base.h" #include "command-encoder-com-forward.h" #include "command-writer.h" -#include "simple-render-pass-layout.h" #include "simple-transient-resource-heap.h" #include "core/common.h" @@ -273,41 +272,14 @@ class CommandBufferImpl : public ICommandBuffer, public ComObject } public: - virtual SLANG_NO_THROW void SLANG_MCALL endEncoding() override {} - - void init(CommandBufferImpl* cmdBuffer, SimpleRenderPassLayout* renderPass, IFramebuffer* framebuffer) + void init(CommandBufferImpl* cmdBuffer, const RenderPassDesc& desc) { CommandEncoderImpl::init(cmdBuffer); - - // Encode clear commands. - m_writer->setFramebuffer(framebuffer); - uint32_t clearMask = 0; - for (Index i = 0; i < renderPass->m_renderTargetAccesses.size(); i++) - { - auto& access = renderPass->m_renderTargetAccesses[i]; - // Clear. - if (access.loadOp == IRenderPassLayout::TargetLoadOp::Clear) - { - clearMask |= (1 << (uint32_t)i); - } - } - bool clearDepth = false; - bool clearStencil = false; - if (renderPass->m_hasDepthStencil) - { - // Clear. - if (renderPass->m_depthStencilAccess.loadOp == IRenderPassLayout::TargetLoadOp::Clear) - { - clearDepth = true; - } - if (renderPass->m_depthStencilAccess.stencilLoadOp == IRenderPassLayout::TargetLoadOp::Clear) - { - clearStencil = true; - } - } - m_writer->clearFrame(clearMask, clearDepth, clearStencil); + m_writer->beginRenderPass(desc); } + virtual SLANG_NO_THROW void SLANG_MCALL endEncoding() override { m_writer->endRenderPass(); } + virtual SLANG_NO_THROW Result SLANG_MCALL bindPipeline(IPipeline* state, IShaderObject** outRootObject) override { m_writer->setPipeline(state); @@ -462,13 +434,10 @@ class CommandBufferImpl : public ICommandBuffer, public ComObject }; RenderCommandEncoderImpl m_renderCommandEncoder; - virtual SLANG_NO_THROW Result SLANG_MCALL encodeRenderCommands( - IRenderPassLayout* renderPass, - IFramebuffer* framebuffer, - IRenderCommandEncoder** outEncoder - ) override + virtual SLANG_NO_THROW Result SLANG_MCALL + encodeRenderCommands(const RenderPassDesc& desc, IRenderCommandEncoder** outEncoder) override { - m_renderCommandEncoder.init(this, static_cast(renderPass), framebuffer); + m_renderCommandEncoder.init(this, desc); *outEncoder = &m_renderCommandEncoder; return SLANG_OK; } @@ -563,11 +532,11 @@ class CommandBufferImpl : public ICommandBuffer, public ComObject case CommandName::BindRootShaderObject: m_renderer->bindRootShaderObject(m_writer.getObject(cmd.operands[0])); break; - case CommandName::SetFramebuffer: - m_renderer->setFramebuffer(m_writer.getObject(cmd.operands[0])); + case CommandName::BeginRenderPass: + m_renderer->beginRenderPass(*m_writer.getData(cmd.operands[0])); break; - case CommandName::ClearFrame: - m_renderer->clearFrame(cmd.operands[0], (cmd.operands[1] != 0), (cmd.operands[2] != 0)); + case CommandName::EndRenderPass: + m_renderer->endRenderPass(); break; case CommandName::SetViewports: m_renderer->setViewports((UInt)cmd.operands[0], m_writer.getData(cmd.operands[1])); @@ -744,17 +713,6 @@ ImmediateRendererBase::createCommandQueue(const ICommandQueue::Desc& desc, IComm return SLANG_OK; } -SLANG_NO_THROW Result SLANG_MCALL ImmediateRendererBase::createRenderPassLayout( - const IRenderPassLayout::Desc& desc, - IRenderPassLayout** outRenderPassLayout -) -{ - RefPtr renderPass = new SimpleRenderPassLayout(); - renderPass->init(desc); - returnComPtr(outRenderPassLayout, renderPass); - return SLANG_OK; -} - void ImmediateRendererBase::uploadBufferData(IBuffer* dst, size_t offset, size_t size, void* data) { auto buffer = map(dst, MapFlavor::WriteDiscard); diff --git a/src/immediate-renderer-base.h b/src/immediate-renderer-base.h index bea30ab4..a4a75653 100644 --- a/src/immediate-renderer-base.h +++ b/src/immediate-renderer-base.h @@ -49,8 +49,8 @@ class ImmediateRendererBase : public RendererBase virtual Result createRootShaderObject(IShaderProgram* program, ShaderObjectBase** outObject) = 0; virtual void bindRootShaderObject(IShaderObject* rootObject) = 0; virtual void setPipeline(IPipeline* state) = 0; - virtual void setFramebuffer(IFramebuffer* frameBuffer) = 0; - virtual void clearFrame(uint32_t colorBufferMask, bool clearDepth, bool clearStencil) = 0; + virtual void beginRenderPass(const RenderPassDesc& desc) = 0; + virtual void endRenderPass() = 0; virtual void setViewports(GfxCount count, const Viewport* viewports) = 0; virtual void setScissorRects(GfxCount count, const ScissorRect* scissors) = 0; virtual void setPrimitiveTopology(PrimitiveTopology topology) = 0; @@ -97,8 +97,6 @@ class ImmediateRendererBase : public RendererBase createCommandQueue(const ICommandQueue::Desc& desc, ICommandQueue** outQueue) override; virtual SLANG_NO_THROW Result SLANG_MCALL createTransientResourceHeap(const ITransientResourceHeap::Desc& desc, ITransientResourceHeap** outHeap) override; - virtual SLANG_NO_THROW Result SLANG_MCALL - createRenderPassLayout(const IRenderPassLayout::Desc& desc, IRenderPassLayout** outRenderPassLayout) override; void uploadBufferData(IBuffer* dst, Offset offset, Size size, void* data); @@ -110,13 +108,8 @@ class ImmediateComputeDeviceBase : public ImmediateRendererBase { public: // Provide empty implementation for devices without graphics support. - virtual void setFramebuffer(IFramebuffer* frameBuffer) override { SLANG_UNUSED(frameBuffer); } - virtual void clearFrame(uint32_t colorBufferMask, bool clearDepth, bool clearStencil) override - { - SLANG_UNUSED(colorBufferMask); - SLANG_UNUSED(clearDepth); - SLANG_UNUSED(clearStencil); - } + virtual void beginRenderPass(const RenderPassDesc& desc) override { SLANG_UNUSED(desc); } + virtual void endRenderPass() override {} virtual void setViewports(GfxCount count, const Viewport* viewports) override { SLANG_UNUSED(count); @@ -201,20 +194,6 @@ class ImmediateComputeDeviceBase : public ImmediateRendererBase SLANG_UNUSED(outLayout); return SLANG_FAIL; } - virtual SLANG_NO_THROW Result SLANG_MCALL - createFramebuffer(const IFramebuffer::Desc& desc, IFramebuffer** outFramebuffer) override - { - SLANG_UNUSED(desc); - SLANG_UNUSED(outFramebuffer); - return SLANG_FAIL; - } - virtual SLANG_NO_THROW Result SLANG_MCALL - createRenderPassLayout(const IRenderPassLayout::Desc& desc, IRenderPassLayout** outRenderPassLayout) override - { - SLANG_UNUSED(desc); - SLANG_UNUSED(outRenderPassLayout); - return SLANG_FAIL; - } virtual SLANG_NO_THROW Result SLANG_MCALL createInputLayout(InputLayoutDesc const& desc, IInputLayout** outLayout) override diff --git a/src/metal/metal-base.h b/src/metal/metal-base.h index bdd5d546..45e5d374 100644 --- a/src/metal/metal-base.h +++ b/src/metal/metal-base.h @@ -23,8 +23,6 @@ class TexelBufferViewImpl; class PlainBufferViewImpl; class AccelerationStructureImpl; class FramebufferLayoutImpl; -class RenderPassLayoutImpl; -class FramebufferImpl; class PipelineImpl; class RayTracingPipelineImpl; class ShaderObjectLayoutImpl; diff --git a/src/metal/metal-command-buffer.cpp b/src/metal/metal-command-buffer.cpp index 733592c4..1b2fda03 100644 --- a/src/metal/metal-command-buffer.cpp +++ b/src/metal/metal-command-buffer.cpp @@ -27,14 +27,10 @@ Result CommandBufferImpl::encodeResourceCommands(IResourceCommandEncoder** outEn return SLANG_OK; } -Result CommandBufferImpl::encodeRenderCommands( - IRenderPassLayout* renderPass, - IFramebuffer* framebuffer, - IRenderCommandEncoder** outEncoder -) +Result CommandBufferImpl::encodeRenderCommands(const RenderPassDesc& desc, IRenderCommandEncoder** outEncoder) { m_renderCommandEncoder.init(this); - m_renderCommandEncoder.beginPass(renderPass, framebuffer); + m_renderCommandEncoder.beginPass(desc); *outEncoder = &m_renderCommandEncoder; return SLANG_OK; } diff --git a/src/metal/metal-command-buffer.h b/src/metal/metal-command-buffer.h index be71cd2d..8d30a761 100644 --- a/src/metal/metal-command-buffer.h +++ b/src/metal/metal-command-buffer.h @@ -44,7 +44,7 @@ class CommandBufferImpl : public ICommandBuffer, public ComObject public: virtual SLANG_NO_THROW Result SLANG_MCALL encodeResourceCommands(IResourceCommandEncoder** outEncoder) override; virtual SLANG_NO_THROW Result SLANG_MCALL encodeRenderCommands( - IRenderPassLayout* renderPass, + const RenderPassDesc& desc, IFramebuffer* framebuffer, IRenderCommandEncoder** outEncoder ) override; diff --git a/src/metal/metal-device.cpp b/src/metal/metal-device.cpp index 49a7e3a0..abd7582b 100644 --- a/src/metal/metal-device.cpp +++ b/src/metal/metal-device.cpp @@ -158,26 +158,6 @@ Result DeviceImpl::createFramebufferLayout(const FramebufferLayoutDesc& desc, IF return SLANG_OK; } -Result DeviceImpl::createRenderPassLayout(const IRenderPassLayout::Desc& desc, IRenderPassLayout** outRenderPassLayout) -{ - AUTORELEASEPOOL - - RefPtr renderPassLayoutImpl = new RenderPassLayoutImpl; - SLANG_RETURN_ON_FAIL(renderPassLayoutImpl->init(this, desc)); - returnComPtr(outRenderPassLayout, renderPassLayoutImpl); - return SLANG_OK; -} - -Result DeviceImpl::createFramebuffer(const IFramebuffer::Desc& desc, IFramebuffer** outFramebuffer) -{ - AUTORELEASEPOOL - - RefPtr framebufferImpl = new FramebufferImpl; - SLANG_RETURN_ON_FAIL(framebufferImpl->init(this, desc)); - returnComPtr(outFramebuffer, framebufferImpl); - return SLANG_OK; -} - Result DeviceImpl::readTexture( ITexture* texture, ResourceState state, diff --git a/src/metal/metal-device.h b/src/metal/metal-device.h index 26e3463a..0d5f8358 100644 --- a/src/metal/metal-device.h +++ b/src/metal/metal-device.h @@ -27,10 +27,6 @@ class DeviceImpl : public RendererBase virtual SLANG_NO_THROW Result SLANG_MCALL createFramebufferLayout(const FramebufferLayoutDesc& desc, IFramebufferLayout** outLayout) override; virtual SLANG_NO_THROW Result SLANG_MCALL - createFramebuffer(const IFramebuffer::Desc& desc, IFramebuffer** outFramebuffer) override; - virtual SLANG_NO_THROW Result SLANG_MCALL - createRenderPassLayout(const IRenderPassLayout::Desc& desc, IRenderPassLayout** outRenderPassLayout) override; - virtual SLANG_NO_THROW Result SLANG_MCALL createTexture(const TextureDesc& desc, const SubresourceData* initData, ITexture** outTexture) override; virtual SLANG_NO_THROW Result SLANG_MCALL createBuffer(const BufferDesc& desc, const void* initData, IBuffer** outBuffer) override; diff --git a/src/renderer-shared.cpp b/src/renderer-shared.cpp index 1381aaf5..80b4b098 100644 --- a/src/renderer-shared.cpp +++ b/src/renderer-shared.cpp @@ -18,7 +18,6 @@ const Guid GUID::IID_IInputLayout = IInputLayout::getTypeGuid(); const Guid GUID::IID_IPipeline = IPipeline::getTypeGuid(); const Guid GUID::IID_ITransientResourceHeap = ITransientResourceHeap::getTypeGuid(); const Guid GUID::IID_IResourceView = IResourceView::getTypeGuid(); -const Guid GUID::IID_IFramebuffer = IFramebuffer::getTypeGuid(); const Guid GUID::IID_IFramebufferLayout = IFramebufferLayout::getTypeGuid(); const Guid GUID::IID_ISwapchain = ISwapchain::getTypeGuid(); @@ -30,7 +29,6 @@ const Guid GUID::IID_IDevice = IDevice::getTypeGuid(); const Guid GUID::IID_IPersistentShaderCache = IPersistentShaderCache::getTypeGuid(); const Guid GUID::IID_IShaderObject = IShaderObject::getTypeGuid(); -const Guid GUID::IID_IRenderPassLayout = IRenderPassLayout::getTypeGuid(); const Guid GUID::IID_ICommandEncoder = ICommandEncoder::getTypeGuid(); const Guid GUID::IID_IResourceCommandEncoder = IResourceCommandEncoder::getTypeGuid(); const Guid GUID::IID_IRenderCommandEncoder = IRenderCommandEncoder::getTypeGuid(); @@ -217,13 +215,6 @@ IFramebufferLayout* FramebufferLayoutBase::getInterface(const Guid& guid) return nullptr; } -IFramebuffer* FramebufferBase::getInterface(const Guid& guid) -{ - if (guid == GUID::IID_ISlangUnknown || guid == GUID::IID_IFramebuffer) - return static_cast(this); - return nullptr; -} - IQueryPool* QueryPoolBase::getInterface(const Guid& guid) { if (guid == GUID::IID_ISlangUnknown || guid == GUID::IID_IQueryPool) diff --git a/src/renderer-shared.h b/src/renderer-shared.h index e995db7e..0b8788e7 100644 --- a/src/renderer-shared.h +++ b/src/renderer-shared.h @@ -36,7 +36,6 @@ struct GUID static const Guid IID_IPersistentShaderCache; static const Guid IID_IShaderObjectLayout; static const Guid IID_IShaderObject; - static const Guid IID_IRenderPassLayout; static const Guid IID_ICommandEncoder; static const Guid IID_IRenderCommandEncoder; static const Guid IID_IComputeCommandEncoder; @@ -826,13 +825,6 @@ class FramebufferLayoutBase : public IFramebufferLayout, public ComObject IFramebufferLayout* getInterface(const Guid& guid); }; -class FramebufferBase : public IFramebuffer, public ComObject -{ -public: - SLANG_COM_OBJECT_IUNKNOWN_ALL - IFramebuffer* getInterface(const Guid& guid); -}; - class QueryPoolBase : public IQueryPool, public ComObject { public: diff --git a/src/simple-render-pass-layout.cpp b/src/simple-render-pass-layout.cpp deleted file mode 100644 index 1d5f1c92..00000000 --- a/src/simple-render-pass-layout.cpp +++ /dev/null @@ -1,24 +0,0 @@ -#include "simple-render-pass-layout.h" - -#include "renderer-shared.h" - -namespace rhi { - -IRenderPassLayout* SimpleRenderPassLayout::getInterface(const Guid& guid) -{ - if (guid == GUID::IID_ISlangUnknown || guid == GUID::IID_IRenderPassLayout) - return static_cast(this); - return nullptr; -} - -void SimpleRenderPassLayout::init(const IRenderPassLayout::Desc& desc) -{ - m_renderTargetAccesses.resize(desc.renderTargetCount); - for (GfxIndex i = 0; i < desc.renderTargetCount; i++) - m_renderTargetAccesses[i] = desc.renderTargetAccess[i]; - m_hasDepthStencil = (desc.depthStencilAccess != nullptr); - if (m_hasDepthStencil) - m_depthStencilAccess = *desc.depthStencilAccess; -} - -} // namespace rhi diff --git a/src/simple-render-pass-layout.h b/src/simple-render-pass-layout.h deleted file mode 100644 index c3b719e6..00000000 --- a/src/simple-render-pass-layout.h +++ /dev/null @@ -1,27 +0,0 @@ -#pragma once - -// Implementation of a dummy render pass layout object that stores and holds its -// desc value. Used by targets that does not expose an API object for the render pass -// concept. - -#include - -#include "core/common.h" -#include "core/short_vector.h" - -namespace rhi { - -class SimpleRenderPassLayout : public IRenderPassLayout, public ComObject -{ -public: - SLANG_COM_OBJECT_IUNKNOWN_ALL - IRenderPassLayout* getInterface(const Guid& guid); - -public: - short_vector m_renderTargetAccesses; - TargetAccessDesc m_depthStencilAccess; - bool m_hasDepthStencil; - void init(const IRenderPassLayout::Desc& desc); -}; - -} // namespace rhi diff --git a/src/vulkan/vk-api.h b/src/vulkan/vk-api.h index 9865288c..32f46880 100644 --- a/src/vulkan/vk-api.h +++ b/src/vulkan/vk-api.h @@ -171,6 +171,8 @@ namespace rhi::vk { x(vkGetSwapchainImagesKHR) \ x(vkDestroySwapchainKHR) \ x(vkAcquireNextImageKHR) \ + x(vkCmdBeginRenderingKHR) \ + x(vkCmdEndRenderingKHR) \ x(vkCreateRayTracingPipelinesKHR) \ x(vkCmdTraceRaysKHR) \ x(vkGetRayTracingShaderGroupHandlesKHR) \ @@ -311,6 +313,18 @@ struct VulkanExtendedFeatureProperties // Vulkan 1.2 features. VkPhysicalDeviceVulkan12Features vulkan12Features = {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES}; + // Vulkan 1.3 features. + VkPhysicalDeviceVulkan13Features vulkan13Features = {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_FEATURES}; + + // Dynamic rendering features + VkPhysicalDeviceDynamicRenderingFeaturesKHR dynamicRenderingFeatures = { + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DYNAMIC_RENDERING_FEATURES_KHR + }; + + VkPhysicalDevice4444FormatsFeaturesEXT formats4444Features = { + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_4444_FORMATS_FEATURES_EXT + }; + // Ray tracing validation features VkPhysicalDeviceRayTracingValidationFeaturesNV rayTracingValidationFeatures = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_VALIDATION_FEATURES_NV diff --git a/src/vulkan/vk-base.h b/src/vulkan/vk-base.h index f9a18cf3..c81900d7 100644 --- a/src/vulkan/vk-base.h +++ b/src/vulkan/vk-base.h @@ -25,7 +25,6 @@ class PlainBufferViewImpl; class AccelerationStructureImpl; class FramebufferLayoutImpl; class RenderPassLayoutImpl; -class FramebufferImpl; class PipelineImpl; class RayTracingPipelineImpl; class ShaderObjectLayoutImpl; diff --git a/src/vulkan/vk-command-buffer.cpp b/src/vulkan/vk-command-buffer.cpp index 21d58bb5..dcca3f89 100644 --- a/src/vulkan/vk-command-buffer.cpp +++ b/src/vulkan/vk-command-buffer.cpp @@ -83,14 +83,10 @@ Result CommandBufferImpl::encodeResourceCommands(IResourceCommandEncoder** outEn return SLANG_OK; } -Result CommandBufferImpl::encodeRenderCommands( - IRenderPassLayout* renderPass, - IFramebuffer* framebuffer, - IRenderCommandEncoder** outEncoder -) +Result CommandBufferImpl::encodeRenderCommands(const RenderPassDesc& desc, IRenderCommandEncoder** outEncoder) { m_renderCommandEncoder.init(this); - m_renderCommandEncoder.beginPass(renderPass, framebuffer); + m_renderCommandEncoder.beginPass(desc); *outEncoder = &m_renderCommandEncoder; return SLANG_OK; } diff --git a/src/vulkan/vk-command-buffer.h b/src/vulkan/vk-command-buffer.h index 2645ea41..7fbe2b43 100644 --- a/src/vulkan/vk-command-buffer.h +++ b/src/vulkan/vk-command-buffer.h @@ -46,11 +46,8 @@ class CommandBufferImpl : public ICommandBuffer, public ComObject public: virtual SLANG_NO_THROW Result SLANG_MCALL encodeResourceCommands(IResourceCommandEncoder** outEncoder) override; - virtual SLANG_NO_THROW Result SLANG_MCALL encodeRenderCommands( - IRenderPassLayout* renderPass, - IFramebuffer* framebuffer, - IRenderCommandEncoder** outEncoder - ) override; + virtual SLANG_NO_THROW Result SLANG_MCALL + encodeRenderCommands(const RenderPassDesc& desc, IRenderCommandEncoder** outEncoder) override; virtual SLANG_NO_THROW Result SLANG_MCALL encodeComputeCommands(IComputeCommandEncoder** outEncoder) override; virtual SLANG_NO_THROW Result SLANG_MCALL encodeRayTracingCommands(IRayTracingCommandEncoder** outEncoder) override; virtual SLANG_NO_THROW void SLANG_MCALL close() override; diff --git a/src/vulkan/vk-command-encoder.cpp b/src/vulkan/vk-command-encoder.cpp index 69d30bb6..4307c226 100644 --- a/src/vulkan/vk-command-encoder.cpp +++ b/src/vulkan/vk-command-encoder.cpp @@ -3,7 +3,6 @@ #include "vk-command-buffer.h" #include "vk-helper-functions.h" #include "vk-query.h" -#include "vk-render-pass.h" #include "vk-resource-views.h" #include "vk-shader-object.h" #include "vk-shader-program.h" @@ -948,8 +947,9 @@ void ResourceCommandEncoderImpl::copyTextureToBuffer( // RenderCommandEncoderImpl -void RenderCommandEncoderImpl::beginPass(IRenderPassLayout* renderPass, IFramebuffer* framebuffer) +void RenderCommandEncoderImpl::beginPass(const RenderPassDesc& desc) { +#if 0 FramebufferImpl* framebufferImpl = static_cast(framebuffer); if (!framebuffer) framebufferImpl = this->m_device->m_emptyFramebuffer; @@ -966,14 +966,143 @@ void RenderCommandEncoderImpl::beginPass(IRenderPassLayout* renderPass, IFramebu beginInfo.renderArea.extent.width = framebufferImpl->m_width; beginInfo.renderArea.extent.height = framebufferImpl->m_height; beginInfo.pClearValues = framebufferImpl->m_clearValues; - auto& api = *m_api; api.vkCmdBeginRenderPass(m_vkCommandBuffer, &beginInfo, VK_SUBPASS_CONTENTS_INLINE); +#endif + auto& api = *m_api; + + m_renderTargetViews.resize(desc.colorAttachmentCount); + m_renderTargetFinalStates.resize(desc.colorAttachmentCount); + for (GfxIndex i = 0; i < desc.colorAttachmentCount; ++i) + { + m_renderTargetViews[i] = static_cast(desc.colorAttachments[i].view); + m_renderTargetFinalStates[i] = desc.colorAttachments[i].finalState; + } + m_depthStencilView = static_cast(desc.depthStencilAttachment.view); + m_depthStencilFinalState = desc.depthStencilAttachment.finalState; + + VkRect2D renderArea; + renderArea.offset = {0, 0}; + renderArea.extent = { + api.m_deviceProperties.limits.maxFramebufferWidth, + api.m_deviceProperties.limits.maxFramebufferHeight + }; + uint32_t layerCount = 1; + + // Transition render targets from their initial state to render target state. + for (GfxIndex i = 0; i < desc.colorAttachmentCount; ++i) + { + const auto& attachment = desc.colorAttachments[i]; + TextureViewImpl* view = static_cast(attachment.view); + if (view) + { + ITexture* texture = view->m_texture; + textureBarrier(1, &texture, attachment.initialState, ResourceState::RenderTarget); + } + const IResourceView::Desc* viewDesc = &view->m_desc; + const TextureDesc* textureDesc = view->m_texture->getDesc(); + uint32_t width = getMipLevelSize(viewDesc->subresourceRange.mipLevel, textureDesc->size.width); + uint32_t height = getMipLevelSize(viewDesc->subresourceRange.mipLevel, textureDesc->size.height); + renderArea.extent.width = std::min(renderArea.extent.width, width); + renderArea.extent.height = std::min(renderArea.extent.height, height); + uint32_t attachmentLayerCount = (textureDesc->type == TextureType::Texture3D) + ? textureDesc->size.depth + : viewDesc->subresourceRange.layerCount; + layerCount = std::max(layerCount, attachmentLayerCount); + } + // Transition depth stencil from its initial state to depth write state. + if (desc.depthStencilAttachment.view) + { + TextureViewImpl* view = static_cast(desc.depthStencilAttachment.view); + ITexture* texture = view->m_texture; + // TODO we could use DepthRead if we are not writing to the depth buffer + textureBarrier(1, &texture, desc.depthStencilAttachment.initialState, ResourceState::DepthWrite); + + const IResourceView::Desc* viewDesc = &view->m_desc; + const TextureDesc* textureDesc = view->m_texture->getDesc(); + uint32_t width = getMipLevelSize(viewDesc->subresourceRange.mipLevel, textureDesc->size.width); + uint32_t height = getMipLevelSize(viewDesc->subresourceRange.mipLevel, textureDesc->size.height); + renderArea.extent.width = std::min(renderArea.extent.width, width); + renderArea.extent.height = std::min(renderArea.extent.height, height); + } + + static_vector colorAttachmentInfos; + for (GfxIndex i = 0; i < desc.colorAttachmentCount; ++i) + { + const auto& attachment = desc.colorAttachments[i]; + if (attachment.view) + { + VkRenderingAttachmentInfoKHR attachmentInfo = {VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR}; + attachmentInfo.imageView = static_cast(attachment.view)->m_view; + attachmentInfo.imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + attachmentInfo.loadOp = translateLoadOp(attachment.loadOp); + attachmentInfo.storeOp = translateStoreOp(attachment.storeOp); + attachmentInfo.clearValue.color.float32[0] = attachment.clearValue[0]; + attachmentInfo.clearValue.color.float32[1] = attachment.clearValue[1]; + attachmentInfo.clearValue.color.float32[2] = attachment.clearValue[2]; + attachmentInfo.clearValue.color.float32[3] = attachment.clearValue[3]; + colorAttachmentInfos.push_back(attachmentInfo); + } + } + VkRenderingAttachmentInfo depthAttachmentInfo = {VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR}; + bool hasDepthAttachment = false; + if (desc.depthStencilAttachment.view) + { + hasDepthAttachment = true; + const auto& attachment = desc.depthStencilAttachment; + depthAttachmentInfo.imageView = static_cast(attachment.view)->m_view; + depthAttachmentInfo.imageLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; + depthAttachmentInfo.loadOp = translateLoadOp(attachment.depthLoadOp); + depthAttachmentInfo.storeOp = translateStoreOp(attachment.depthStoreOp); + depthAttachmentInfo.clearValue.depthStencil.depth = attachment.depthClearValue; + } + VkRenderingAttachmentInfo stencilAttachmentInfo = {VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR}; + bool hasStencilAttachment = false; + // TODO only set if stencil is present + if (desc.depthStencilAttachment.view) + { + hasStencilAttachment = true; + const auto& attachment = desc.depthStencilAttachment; + stencilAttachmentInfo.imageView = static_cast(attachment.view)->m_view; + stencilAttachmentInfo.imageLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; + stencilAttachmentInfo.loadOp = translateLoadOp(attachment.stencilLoadOp); + stencilAttachmentInfo.storeOp = translateStoreOp(attachment.stencilStoreOp); + stencilAttachmentInfo.clearValue.depthStencil.stencil = attachment.stencilClearValue; + } + + VkRenderingInfoKHR renderingInfo = {VK_STRUCTURE_TYPE_RENDERING_INFO_KHR}; + renderingInfo.renderArea = renderArea; + renderingInfo.layerCount = layerCount; + renderingInfo.colorAttachmentCount = colorAttachmentInfos.size(); + renderingInfo.pColorAttachments = colorAttachmentInfos.data(); + renderingInfo.pDepthAttachment = hasDepthAttachment ? &depthAttachmentInfo : nullptr; + renderingInfo.pStencilAttachment = hasStencilAttachment ? &stencilAttachmentInfo : nullptr; + + api.vkCmdBeginRenderingKHR(m_vkCommandBuffer, &renderingInfo); } void RenderCommandEncoderImpl::endEncoding() { auto& api = *m_api; - api.vkCmdEndRenderPass(m_vkCommandBuffer); + api.vkCmdEndRenderingKHR(m_vkCommandBuffer); + + for (Index i = 0; i < m_renderTargetViews.size(); ++i) + { + if (m_renderTargetViews[i]) + { + ITexture* texture = m_renderTargetViews[i]->m_texture; + textureBarrier(1, &texture, ResourceState::RenderTarget, m_renderTargetFinalStates[i]); + } + } + if (m_depthStencilView) + { + ITexture* texture = m_depthStencilView->m_texture; + // TODO we could use DepthRead if we are not writing to the depth buffer + textureBarrier(1, &texture, ResourceState::DepthWrite, m_depthStencilFinalState); + } + + m_renderTargetViews.clear(); + m_depthStencilView = nullptr; + endEncodingImpl(); } diff --git a/src/vulkan/vk-command-encoder.h b/src/vulkan/vk-command-encoder.h index c4542896..38e2bf36 100644 --- a/src/vulkan/vk-command-encoder.h +++ b/src/vulkan/vk-command-encoder.h @@ -3,6 +3,8 @@ #include "vk-base.h" #include "vk-pipeline.h" +#include "core/static_vector.h" + #include namespace rhi::vk { @@ -173,11 +175,16 @@ class RenderCommandEncoderImpl : public IRenderCommandEncoder, public CommandEnc } public: + static_vector, kMaxRenderTargetCount> m_renderTargetViews; + static_vector m_renderTargetFinalStates; + RefPtr m_depthStencilView; + ResourceState m_depthStencilFinalState; + std::vector m_viewports; std::vector m_scissorRects; public: - void beginPass(IRenderPassLayout* renderPass, IFramebuffer* framebuffer); + void beginPass(const RenderPassDesc& desc); virtual SLANG_NO_THROW void SLANG_MCALL endEncoding() override; diff --git a/src/vulkan/vk-device.cpp b/src/vulkan/vk-device.cpp index 512aa277..cb71349e 100644 --- a/src/vulkan/vk-device.cpp +++ b/src/vulkan/vk-device.cpp @@ -4,7 +4,6 @@ #include "vk-fence.h" #include "vk-helper-functions.h" #include "vk-query.h" -#include "vk-render-pass.h" #include "vk-resource-views.h" #include "vk-sampler.h" #include "vk-shader-object-layout.h" @@ -53,8 +52,6 @@ DeviceImpl::~DeviceImpl() descriptorSetAllocator.close(); - m_emptyFramebuffer = nullptr; - if (m_device != VK_NULL_HANDLE) { if (!m_desc.existingDeviceHandles.handles[2]) @@ -521,12 +518,25 @@ Result DeviceImpl::initVulkanInstanceAndDevice(const NativeHandle* handles, bool extendedFeatures.rayTracingValidationFeatures.pNext = deviceFeatures2.pNext; deviceFeatures2.pNext = &extendedFeatures.rayTracingValidationFeatures; + // dynamic rendering features + extendedFeatures.dynamicRenderingFeatures.pNext = deviceFeatures2.pNext; + deviceFeatures2.pNext = &extendedFeatures.dynamicRenderingFeatures; + + extendedFeatures.formats4444Features.pNext = deviceFeatures2.pNext; + deviceFeatures2.pNext = &extendedFeatures.formats4444Features; + if (VK_MAKE_VERSION(majorVersion, minorVersion, 0) >= VK_API_VERSION_1_2) { extendedFeatures.vulkan12Features.pNext = deviceFeatures2.pNext; deviceFeatures2.pNext = &extendedFeatures.vulkan12Features; } + // if (VK_MAKE_VERSION(majorVersion, minorVersion, 0) >= VK_API_VERSION_1_3) + // { + // extendedFeatures.vulkan13Features.pNext = deviceFeatures2.pNext; + // deviceFeatures2.pNext = &extendedFeatures.vulkan13Features; + // } + m_api.vkGetPhysicalDeviceFeatures2(m_api.m_physicalDevice, &deviceFeatures2); if (deviceFeatures2.features.shaderResourceMinLod) @@ -583,6 +593,20 @@ Result DeviceImpl::initVulkanInstanceAndDevice(const NativeHandle* handles, bool } \ while (0) + SIMPLE_EXTENSION_FEATURE( + extendedFeatures.dynamicRenderingFeatures, + dynamicRendering, + VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME, + "dynamic-rendering" + ); + + SIMPLE_EXTENSION_FEATURE( + extendedFeatures.formats4444Features, + formatA4R4G4B4, + VK_EXT_4444_FORMATS_EXTENSION_NAME, + "b4g4r4a4-format" + ); + SIMPLE_EXTENSION_FEATURE( extendedFeatures.storage16BitFeatures, storageBuffer16BitAccess, @@ -1047,18 +1071,6 @@ Result DeviceImpl::initialize(const Desc& desc) SLANG_VK_RETURN_ON_FAIL(m_api.vkCreateSampler(m_device, &samplerInfo, nullptr, &m_defaultSampler)); } - // Create empty frame buffer. - { - ComPtr layout; - SLANG_RETURN_ON_FAIL(createFramebufferLayout({}, layout.writeRef())); - IFramebuffer::Desc desc = {}; - desc.layout = layout; - ComPtr framebuffer; - SLANG_RETURN_ON_FAIL(createFramebuffer(desc, framebuffer.writeRef())); - m_emptyFramebuffer = static_cast(framebuffer.get()); - m_emptyFramebuffer->m_renderer.breakStrongReference(); - } - return SLANG_OK; } @@ -1117,26 +1129,11 @@ Result DeviceImpl::createFramebufferLayout(const FramebufferLayoutDesc& desc, IF { RefPtr layout = new FramebufferLayoutImpl(); SLANG_RETURN_ON_FAIL(layout->init(this, desc)); + layout->m_desc = desc; returnComPtr(outLayout, layout); return SLANG_OK; } -Result DeviceImpl::createRenderPassLayout(const IRenderPassLayout::Desc& desc, IRenderPassLayout** outRenderPassLayout) -{ - RefPtr result = new RenderPassLayoutImpl(); - SLANG_RETURN_ON_FAIL(result->init(this, desc)); - returnComPtr(outRenderPassLayout, result); - return SLANG_OK; -} - -Result DeviceImpl::createFramebuffer(const IFramebuffer::Desc& desc, IFramebuffer** outFramebuffer) -{ - RefPtr fb = new FramebufferImpl(); - SLANG_RETURN_ON_FAIL(fb->init(this, desc)); - returnComPtr(outFramebuffer, fb); - return SLANG_OK; -} - Result DeviceImpl::readTexture( ITexture* texture, ResourceState state, diff --git a/src/vulkan/vk-device.h b/src/vulkan/vk-device.h index 9edd325c..f6640381 100644 --- a/src/vulkan/vk-device.h +++ b/src/vulkan/vk-device.h @@ -26,10 +26,6 @@ class DeviceImpl : public RendererBase virtual SLANG_NO_THROW Result SLANG_MCALL createFramebufferLayout(const FramebufferLayoutDesc& desc, IFramebufferLayout** outLayout) override; virtual SLANG_NO_THROW Result SLANG_MCALL - createFramebuffer(const IFramebuffer::Desc& desc, IFramebuffer** outFramebuffer) override; - virtual SLANG_NO_THROW Result SLANG_MCALL - createRenderPassLayout(const IRenderPassLayout::Desc& desc, IRenderPassLayout** outRenderPassLayout) override; - virtual SLANG_NO_THROW Result SLANG_MCALL createTexture(const TextureDesc& desc, const SubresourceData* initData, ITexture** outTexture) override; virtual SLANG_NO_THROW Result SLANG_MCALL createBuffer(const BufferDesc& desc, const void* initData, IBuffer** outBuffer) override; @@ -189,8 +185,6 @@ class DeviceImpl : public RendererBase stable_vector, 1024> m_deviceObjectsWithPotentialBackReferences; VkSampler m_defaultSampler; - - RefPtr m_emptyFramebuffer; }; } // namespace rhi::vk diff --git a/src/vulkan/vk-framebuffer.cpp b/src/vulkan/vk-framebuffer.cpp index d8de9ab4..4bc52c07 100644 --- a/src/vulkan/vk-framebuffer.cpp +++ b/src/vulkan/vk-framebuffer.cpp @@ -103,7 +103,7 @@ Result FramebufferLayoutImpl::init(DeviceImpl* renderer, const FramebufferLayout ); return SLANG_OK; } - +#if 0 FramebufferImpl::~FramebufferImpl() { m_renderer->m_api.vkDestroyFramebuffer(m_renderer->m_api.m_device, m_handle, nullptr); @@ -200,5 +200,5 @@ Result FramebufferImpl::init(DeviceImpl* renderer, const IFramebuffer::Desc& des ); return SLANG_OK; } - +#endif } // namespace rhi::vk diff --git a/src/vulkan/vk-framebuffer.h b/src/vulkan/vk-framebuffer.h index 6772b49c..139284f8 100644 --- a/src/vulkan/vk-framebuffer.h +++ b/src/vulkan/vk-framebuffer.h @@ -16,6 +16,8 @@ enum class FramebufferLayoutImpl : public FramebufferLayoutBase { public: + FramebufferLayoutDesc m_desc; + VkRenderPass m_renderPass; DeviceImpl* m_renderer; static_vector m_targetDescs; @@ -30,6 +32,7 @@ class FramebufferLayoutImpl : public FramebufferLayoutBase Result init(DeviceImpl* renderer, const FramebufferLayoutDesc& desc); }; +#if 0 class FramebufferImpl : public FramebufferBase { public: @@ -47,5 +50,6 @@ class FramebufferImpl : public FramebufferBase Result init(DeviceImpl* renderer, const IFramebuffer::Desc& desc); }; +#endif } // namespace rhi::vk diff --git a/src/vulkan/vk-helper-functions.cpp b/src/vulkan/vk-helper-functions.cpp index 1990c5a3..a36e5257 100644 --- a/src/vulkan/vk-helper-functions.cpp +++ b/src/vulkan/vk-helper-functions.cpp @@ -20,24 +20,24 @@ GfxCount calcNumRows(Format format, int height) return (GfxCount)(height + sizeInfo.blockHeight - 1) / sizeInfo.blockHeight; } -VkAttachmentLoadOp translateLoadOp(IRenderPassLayout::TargetLoadOp loadOp) +VkAttachmentLoadOp translateLoadOp(TargetLoadOp loadOp) { switch (loadOp) { - case IRenderPassLayout::TargetLoadOp::Clear: + case TargetLoadOp::Clear: return VK_ATTACHMENT_LOAD_OP_CLEAR; - case IRenderPassLayout::TargetLoadOp::Load: + case TargetLoadOp::Load: return VK_ATTACHMENT_LOAD_OP_LOAD; default: return VK_ATTACHMENT_LOAD_OP_DONT_CARE; } } -VkAttachmentStoreOp translateStoreOp(IRenderPassLayout::TargetStoreOp storeOp) +VkAttachmentStoreOp translateStoreOp(TargetStoreOp storeOp) { switch (storeOp) { - case IRenderPassLayout::TargetStoreOp::Store: + case TargetStoreOp::Store: return VK_ATTACHMENT_STORE_OP_STORE; default: return VK_ATTACHMENT_STORE_OP_DONT_CARE; diff --git a/src/vulkan/vk-helper-functions.h b/src/vulkan/vk-helper-functions.h index 1d0aaf54..35aee49f 100644 --- a/src/vulkan/vk-helper-functions.h +++ b/src/vulkan/vk-helper-functions.h @@ -144,8 +144,8 @@ struct RootBindingContext Size calcRowSize(Format format, int width); GfxCount calcNumRows(Format format, int height); -VkAttachmentLoadOp translateLoadOp(IRenderPassLayout::TargetLoadOp loadOp); -VkAttachmentStoreOp translateStoreOp(IRenderPassLayout::TargetStoreOp storeOp); +VkAttachmentLoadOp translateLoadOp(TargetLoadOp loadOp); +VkAttachmentStoreOp translateStoreOp(TargetStoreOp storeOp); VkPipelineCreateFlags translateRayTracingPipelineFlags(RayTracingPipelineFlags::Enum flags); uint32_t getMipLevelSize(uint32_t mipLevel, uint32_t size); diff --git a/src/vulkan/vk-pipeline.cpp b/src/vulkan/vk-pipeline.cpp index f4ddad64..f6ae653b 100644 --- a/src/vulkan/vk-pipeline.cpp +++ b/src/vulkan/vk-pipeline.cpp @@ -237,7 +237,21 @@ Result PipelineImpl::createVKGraphicsPipeline() depthStencilStateInfo.depthWriteEnable = desc.graphics.depthStencil.depthWriteEnable ? 1 : 0; depthStencilStateInfo.stencilTestEnable = desc.graphics.depthStencil.stencilEnable ? 1 : 0; + VkPipelineRenderingCreateInfoKHR renderingInfo = {VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR}; + static_vector colorAttachmentFormats; + for (GfxIndex i = 0; i < framebufferLayoutImpl->m_desc.renderTargetCount; ++i) + { + colorAttachmentFormats.push_back(VulkanUtil::getVkFormat(framebufferLayoutImpl->m_desc.renderTargets[i].format) + ); + } + renderingInfo.colorAttachmentCount = colorAttachmentFormats.size(); + renderingInfo.pColorAttachmentFormats = colorAttachmentFormats.data(); + renderingInfo.depthAttachmentFormat = VulkanUtil::getVkFormat(framebufferLayoutImpl->m_desc.depthStencil.format); + // TODO we should probably only set this when this is actually a stencil format + renderingInfo.stencilAttachmentFormat = VulkanUtil::getVkFormat(framebufferLayoutImpl->m_desc.depthStencil.format); + VkGraphicsPipelineCreateInfo pipelineInfo = {VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO}; + pipelineInfo.pNext = &renderingInfo; auto programImpl = static_cast(m_program.Ptr()); if (programImpl->m_stageCreateInfos.empty()) @@ -256,7 +270,6 @@ Result PipelineImpl::createVKGraphicsPipeline() pipelineInfo.pColorBlendState = &colorBlending; pipelineInfo.pDepthStencilState = &depthStencilStateInfo; pipelineInfo.layout = programImpl->m_rootObjectLayout->m_pipelineLayout; - pipelineInfo.renderPass = framebufferLayoutImpl->m_renderPass; pipelineInfo.subpass = 0; pipelineInfo.basePipelineHandle = VK_NULL_HANDLE; pipelineInfo.pDynamicState = &dynamicStateInfo; diff --git a/src/vulkan/vk-render-pass.cpp b/src/vulkan/vk-render-pass.cpp index a9fdb42b..a6f3a7e0 100644 --- a/src/vulkan/vk-render-pass.cpp +++ b/src/vulkan/vk-render-pass.cpp @@ -1,3 +1,4 @@ +#if 0 #include "vk-render-pass.h" #include "vk-helper-functions.h" @@ -79,3 +80,4 @@ Result RenderPassLayoutImpl::init(DeviceImpl* renderer, const IRenderPassLayout: } } // namespace rhi::vk +#endif diff --git a/src/vulkan/vk-render-pass.h b/src/vulkan/vk-render-pass.h deleted file mode 100644 index f0748a12..00000000 --- a/src/vulkan/vk-render-pass.h +++ /dev/null @@ -1,22 +0,0 @@ -#pragma once - -#include "vk-base.h" -#include "vk-device.h" - -namespace rhi::vk { - -class RenderPassLayoutImpl : public IRenderPassLayout, public ComObject -{ -public: - SLANG_COM_OBJECT_IUNKNOWN_ALL - IRenderPassLayout* getInterface(const Guid& guid); - -public: - VkRenderPass m_renderPass; - RefPtr m_renderer; - ~RenderPassLayoutImpl(); - - Result init(DeviceImpl* renderer, const IRenderPassLayout::Desc& desc); -}; - -} // namespace rhi::vk diff --git a/tests/test-buffer-barrier.cpp b/tests/test-buffer-barrier.cpp index 6646589e..298c0f54 100644 --- a/tests/test-buffer-barrier.cpp +++ b/tests/test-buffer-barrier.cpp @@ -85,8 +85,8 @@ void testBufferBarrier(GpuTestContext* ctx, DeviceType deviceType) Buffer outputBuffer; createFloatBuffer(device, outputBuffer, true, nullptr, 4); - auto insertBarrier = [](IResourceCommandEncoder* encoder, IBuffer* buffer, ResourceState before, ResourceState after - ) { encoder->bufferBarrier(1, &buffer, before, after); }; + auto insertBarrier = [](ICommandEncoder* encoder, IBuffer* buffer, ResourceState before, ResourceState after) + { encoder->bufferBarrier(1, &buffer, before, after); }; // We have done all the set up work, now it is time to start recording a command buffer for // GPU execution. @@ -96,7 +96,6 @@ void testBufferBarrier(GpuTestContext* ctx, DeviceType deviceType) auto commandBuffer = transientHeap->createCommandBuffer(); auto encoder = commandBuffer->encodeComputeCommands(); - auto resourceEncoder = commandBuffer->encodeResourceCommands(); // Write inputBuffer data to intermediateBuffer auto rootObjectA = encoder->bindPipeline(programA.pipeline); @@ -108,7 +107,7 @@ void testBufferBarrier(GpuTestContext* ctx, DeviceType deviceType) // Insert barrier to ensure writes to intermediateBuffer are complete before the next shader starts executing insertBarrier( - resourceEncoder, + encoder, intermediateBuffer.buffer, ResourceState::UnorderedAccess, ResourceState::ShaderResource diff --git a/tests/test-instanced-draw.cpp b/tests/test-instanced-draw.cpp index 8cff5a1a..5e9c37ec 100644 --- a/tests/test-instanced-draw.cpp +++ b/tests/test-instanced-draw.cpp @@ -103,12 +103,11 @@ class BaseDrawTest ComPtr transientHeap; ComPtr pipeline; - ComPtr renderPass; - ComPtr framebuffer; ComPtr vertexBuffer; ComPtr instanceBuffer; ComPtr colorBuffer; + ComPtr colorBufferView; void init(IDevice* device) { this->device = device; } @@ -168,30 +167,12 @@ class BaseDrawTest pipelineDesc.depthStencil.depthWriteEnable = false; REQUIRE_CALL(device->createRenderPipeline(pipelineDesc, pipeline.writeRef())); - IRenderPassLayout::Desc renderPassDesc = {}; - renderPassDesc.framebufferLayout = framebufferLayout; - renderPassDesc.renderTargetCount = 1; - IRenderPassLayout::TargetAccessDesc renderTargetAccess = {}; - renderTargetAccess.loadOp = IRenderPassLayout::TargetLoadOp::Clear; - renderTargetAccess.storeOp = IRenderPassLayout::TargetStoreOp::Store; - renderTargetAccess.initialState = ResourceState::RenderTarget; - renderTargetAccess.finalState = ResourceState::CopySource; - renderPassDesc.renderTargetAccess = &renderTargetAccess; - REQUIRE_CALL(device->createRenderPassLayout(renderPassDesc, renderPass.writeRef())); - IResourceView::Desc colorBufferViewDesc; memset(&colorBufferViewDesc, 0, sizeof(colorBufferViewDesc)); colorBufferViewDesc.format = format; colorBufferViewDesc.renderTarget.shape = TextureType::Texture2D; colorBufferViewDesc.type = IResourceView::Type::RenderTarget; - auto rtv = device->createTextureView(colorBuffer, colorBufferViewDesc); - - IFramebuffer::Desc framebufferDesc; - framebufferDesc.renderTargetCount = 1; - framebufferDesc.depthStencilView = nullptr; - framebufferDesc.renderTargetViews = rtv.readRef(); - framebufferDesc.layout = framebufferLayout; - REQUIRE_CALL(device->createFramebuffer(framebufferDesc, framebuffer.writeRef())); + REQUIRE_CALL(device->createTextureView(colorBuffer, colorBufferViewDesc, colorBufferView.writeRef())); } void checkTestResults( @@ -242,7 +223,15 @@ struct DrawInstancedTest : BaseDrawTest auto queue = device->createCommandQueue(queueDesc); auto commandBuffer = transientHeap->createCommandBuffer(); - auto encoder = commandBuffer->encodeRenderCommands(renderPass, framebuffer); + RenderPassDesc renderPass; + renderPass.colorAttachments[0].loadOp = TargetLoadOp::Clear; + renderPass.colorAttachments[0].storeOp = TargetStoreOp::Store; + renderPass.colorAttachments[0].initialState = ResourceState::RenderTarget; + renderPass.colorAttachments[0].finalState = ResourceState::CopySource; + renderPass.colorAttachments[0].view = colorBufferView; + renderPass.colorAttachmentCount = 1; + + auto encoder = commandBuffer->encodeRenderCommands(renderPass); auto rootObject = encoder->bindPipeline(pipeline); Viewport viewport = {}; @@ -291,7 +280,15 @@ struct DrawIndexedInstancedTest : BaseDrawTest auto queue = device->createCommandQueue(queueDesc); auto commandBuffer = transientHeap->createCommandBuffer(); - auto encoder = commandBuffer->encodeRenderCommands(renderPass, framebuffer); + RenderPassDesc renderPass; + renderPass.colorAttachments[0].loadOp = TargetLoadOp::Clear; + renderPass.colorAttachments[0].storeOp = TargetStoreOp::Store; + renderPass.colorAttachments[0].initialState = ResourceState::RenderTarget; + renderPass.colorAttachments[0].finalState = ResourceState::CopySource; + renderPass.colorAttachments[0].view = colorBufferView; + renderPass.colorAttachmentCount = 1; + + auto encoder = commandBuffer->encodeRenderCommands(renderPass); auto rootObject = encoder->bindPipeline(pipeline); Viewport viewport = {}; @@ -366,7 +363,15 @@ struct DrawIndirectTest : BaseDrawTest auto queue = device->createCommandQueue(queueDesc); auto commandBuffer = transientHeap->createCommandBuffer(); - auto encoder = commandBuffer->encodeRenderCommands(renderPass, framebuffer); + RenderPassDesc renderPass; + renderPass.colorAttachments[0].loadOp = TargetLoadOp::Clear; + renderPass.colorAttachments[0].storeOp = TargetStoreOp::Store; + renderPass.colorAttachments[0].initialState = ResourceState::RenderTarget; + renderPass.colorAttachments[0].finalState = ResourceState::CopySource; + renderPass.colorAttachments[0].view = colorBufferView; + renderPass.colorAttachmentCount = 1; + + auto encoder = commandBuffer->encodeRenderCommands(renderPass); auto rootObject = encoder->bindPipeline(pipeline); Viewport viewport = {}; @@ -440,7 +445,15 @@ struct DrawIndexedIndirectTest : BaseDrawTest auto queue = device->createCommandQueue(queueDesc); auto commandBuffer = transientHeap->createCommandBuffer(); - auto encoder = commandBuffer->encodeRenderCommands(renderPass, framebuffer); + RenderPassDesc renderPass; + renderPass.colorAttachments[0].loadOp = TargetLoadOp::Clear; + renderPass.colorAttachments[0].storeOp = TargetStoreOp::Store; + renderPass.colorAttachments[0].initialState = ResourceState::RenderTarget; + renderPass.colorAttachments[0].finalState = ResourceState::CopySource; + renderPass.colorAttachments[0].view = colorBufferView; + renderPass.colorAttachmentCount = 1; + + auto encoder = commandBuffer->encodeRenderCommands(renderPass); auto rootObject = encoder->bindPipeline(pipeline); Viewport viewport = {}; diff --git a/tests/test-nested-parameter-block.cpp b/tests/test-nested-parameter-block.cpp index e2fa9f3f..aa3f8d0a 100644 --- a/tests/test-nested-parameter-block.cpp +++ b/tests/test-nested-parameter-block.cpp @@ -82,6 +82,10 @@ void testNestedParameterBlock(GpuTestContext* ctx, DeviceType deviceType) materialObject.writeRef() )); + ShaderCursor materialCursor(materialObject); + materialCursor["cb"].setData(uint4{1000, 1000, 1000, 1000}); + materialCursor["data"].setResource(srvs[2]); + ComPtr sceneObject; REQUIRE_CALL(device->createMutableShaderObject( slangReflection->findTypeByName("Scene"), @@ -89,6 +93,11 @@ void testNestedParameterBlock(GpuTestContext* ctx, DeviceType deviceType) sceneObject.writeRef() )); + ShaderCursor sceneCursor(sceneObject); + sceneCursor["sceneCb"].setData(uint4{100, 100, 100, 100}); + sceneCursor["data"].setResource(srvs[1]); + sceneCursor["material"].setObject(materialObject); + ShaderCursor cursor(shaderObject); cursor["resultBuffer"].setResource(resultBufferView); cursor["scene"].setObject(sceneObject); @@ -104,15 +113,6 @@ void testNestedParameterBlock(GpuTestContext* ctx, DeviceType deviceType) auto initialData = uint4{20, 20, 20, 20}; globalCB->setData(ShaderOffset(), &initialData, sizeof(initialData)); - ShaderCursor sceneCursor(sceneObject); - sceneCursor["sceneCb"].setData(uint4{100, 100, 100, 100}); - sceneCursor["data"].setResource(srvs[1]); - sceneCursor["material"].setObject(materialObject); - - ShaderCursor materialCursor(materialObject); - materialCursor["cb"].setData(uint4{1000, 1000, 1000, 1000}); - materialCursor["data"].setResource(srvs[2]); - // We have done all the set up work, now it is time to start recording a command buffer for // GPU execution. { diff --git a/tests/test-ray-tracing.cpp b/tests/test-ray-tracing.cpp index cc2a8d95..14aaad37 100644 --- a/tests/test-ray-tracing.cpp +++ b/tests/test-ray-tracing.cpp @@ -117,6 +117,7 @@ struct BaseRayTracingTest resultTextureDesc.size.height = height; resultTextureDesc.size.depth = 1; resultTextureDesc.defaultState = ResourceState::UnorderedAccess; + resultTextureDesc.allowedStates = {ResourceState::UnorderedAccess, ResourceState::CopySource}; resultTextureDesc.format = Format::R32G32B32A32_FLOAT; resultTexture = device->createTexture(resultTextureDesc); IResourceView::Desc resultUAVDesc = {}; diff --git a/tests/test-resolve-resource-tests.cpp b/tests/test-resolve-resource-tests.cpp index eaec9ca0..2727b145 100644 --- a/tests/test-resolve-resource-tests.cpp +++ b/tests/test-resolve-resource-tests.cpp @@ -56,12 +56,11 @@ struct BaseResolveResourceTest IDevice* device; ComPtr msaaTexture; + ComPtr msaaTextureView; ComPtr dstTexture; ComPtr transientHeap; ComPtr pipeline; - ComPtr renderPass; - ComPtr framebuffer; ComPtr vertexBuffer; @@ -149,30 +148,12 @@ struct BaseResolveResourceTest pipelineDesc.depthStencil.depthWriteEnable = false; REQUIRE_CALL(device->createRenderPipeline(pipelineDesc, pipeline.writeRef())); - IRenderPassLayout::Desc renderPassDesc = {}; - renderPassDesc.framebufferLayout = framebufferLayout; - renderPassDesc.renderTargetCount = 1; - IRenderPassLayout::TargetAccessDesc renderTargetAccess = {}; - renderTargetAccess.loadOp = IRenderPassLayout::TargetLoadOp::Clear; - renderTargetAccess.storeOp = IRenderPassLayout::TargetStoreOp::Store; - renderTargetAccess.initialState = ResourceState::RenderTarget; - renderTargetAccess.finalState = ResourceState::ResolveSource; - renderPassDesc.renderTargetAccess = &renderTargetAccess; - REQUIRE_CALL(device->createRenderPassLayout(renderPassDesc, renderPass.writeRef())); - IResourceView::Desc colorBufferViewDesc; memset(&colorBufferViewDesc, 0, sizeof(colorBufferViewDesc)); colorBufferViewDesc.format = format; colorBufferViewDesc.renderTarget.shape = TextureType::Texture2D; colorBufferViewDesc.type = IResourceView::Type::RenderTarget; - auto rtv = device->createTextureView(msaaTexture, colorBufferViewDesc); - - IFramebuffer::Desc framebufferDesc; - framebufferDesc.renderTargetCount = 1; - framebufferDesc.depthStencilView = nullptr; - framebufferDesc.renderTargetViews = rtv.readRef(); - framebufferDesc.layout = framebufferLayout; - REQUIRE_CALL(device->createFramebuffer(framebufferDesc, framebuffer.writeRef())); + REQUIRE_CALL(device->createTextureView(msaaTexture, colorBufferViewDesc, msaaTextureView.writeRef())); } void submitGPUWork(SubresourceRange msaaSubresource, SubresourceRange dstSubresource, Extents extent) @@ -186,7 +167,16 @@ struct BaseResolveResourceTest auto queue = device->createCommandQueue(queueDesc); auto commandBuffer = transientHeap->createCommandBuffer(); - auto renderEncoder = commandBuffer->encodeRenderCommands(renderPass, framebuffer); + + RenderPassDesc renderPass; + renderPass.colorAttachments[0].loadOp = TargetLoadOp::Clear; + renderPass.colorAttachments[0].storeOp = TargetStoreOp::Store; + renderPass.colorAttachments[0].initialState = ResourceState::RenderTarget; + renderPass.colorAttachments[0].finalState = ResourceState::ResolveSource; + renderPass.colorAttachments[0].view = msaaTextureView; + renderPass.colorAttachmentCount = 1; + + auto renderEncoder = commandBuffer->encodeRenderCommands(renderPass); auto rootObject = renderEncoder->bindPipeline(pipeline); Viewport viewport = {}; diff --git a/tests/test-sampler-array.slang b/tests/test-sampler-array.slang index 1439f6cd..d5ad1e9b 100644 --- a/tests/test-sampler-array.slang +++ b/tests/test-sampler-array.slang @@ -16,7 +16,7 @@ struct S1 struct S0 { float data; - RaytracingAccelerationStructure acc; + // RaytracingAccelerationStructure acc; ParameterBlock s; } diff --git a/tests/test-shader-cache.cpp b/tests/test-shader-cache.cpp index 3992cc52..565f9060 100644 --- a/tests/test-shader-cache.cpp +++ b/tests/test-shader-cache.cpp @@ -697,10 +697,9 @@ struct ShaderCacheTestGraphics : ShaderCacheTest ComPtr vertexBuffer; ComPtr colorBuffer; + ComPtr colorBufferView; ComPtr inputLayout; ComPtr framebufferLayout; - ComPtr renderPass; - ComPtr framebuffer; ComPtr createVertexBuffer(IDevice* device) { @@ -762,38 +761,18 @@ struct ShaderCacheTestGraphics : ShaderCacheTest framebufferLayout = device->createFramebufferLayout(framebufferLayoutDesc); REQUIRE(framebufferLayout != nullptr); - IRenderPassLayout::Desc renderPassDesc = {}; - renderPassDesc.framebufferLayout = framebufferLayout; - renderPassDesc.renderTargetCount = 1; - IRenderPassLayout::TargetAccessDesc renderTargetAccess = {}; - renderTargetAccess.loadOp = IRenderPassLayout::TargetLoadOp::Clear; - renderTargetAccess.storeOp = IRenderPassLayout::TargetStoreOp::Store; - renderTargetAccess.initialState = ResourceState::RenderTarget; - renderTargetAccess.finalState = ResourceState::CopySource; - renderPassDesc.renderTargetAccess = &renderTargetAccess; - REQUIRE_CALL(device->createRenderPassLayout(renderPassDesc, renderPass.writeRef())); - IResourceView::Desc colorBufferViewDesc; memset(&colorBufferViewDesc, 0, sizeof(colorBufferViewDesc)); colorBufferViewDesc.format = format; colorBufferViewDesc.renderTarget.shape = TextureType::Texture2D; colorBufferViewDesc.type = IResourceView::Type::RenderTarget; - auto rtv = device->createTextureView(colorBuffer, colorBufferViewDesc); - - IFramebuffer::Desc framebufferDesc; - framebufferDesc.renderTargetCount = 1; - framebufferDesc.depthStencilView = nullptr; - framebufferDesc.renderTargetViews = rtv.readRef(); - framebufferDesc.layout = framebufferLayout; - REQUIRE_CALL(device->createFramebuffer(framebufferDesc, framebuffer.writeRef())); + REQUIRE_CALL(device->createTextureView(colorBuffer, colorBufferViewDesc, colorBufferView.writeRef())); } void freeGraphicsResources() { inputLayout = nullptr; framebufferLayout = nullptr; - renderPass = nullptr; - framebuffer = nullptr; vertexBuffer = nullptr; colorBuffer = nullptr; pipeline = nullptr; @@ -832,7 +811,15 @@ struct ShaderCacheTestGraphics : ShaderCacheTest auto queue = device->createCommandQueue(queueDesc); auto commandBuffer = transientHeap->createCommandBuffer(); - auto encoder = commandBuffer->encodeRenderCommands(renderPass, framebuffer); + RenderPassDesc renderPass; + renderPass.colorAttachments[0].loadOp = TargetLoadOp::Clear; + renderPass.colorAttachments[0].storeOp = TargetStoreOp::Store; + renderPass.colorAttachments[0].initialState = ResourceState::RenderTarget; + renderPass.colorAttachments[0].finalState = ResourceState::CopySource; + renderPass.colorAttachments[0].view = colorBufferView; + renderPass.colorAttachmentCount = 1; + + auto encoder = commandBuffer->encodeRenderCommands(renderPass); auto rootObject = encoder->bindPipeline(pipeline); Viewport viewport = {}; diff --git a/tests/test-texture-types.cpp b/tests/test-texture-types.cpp index b60c79e5..b06c2e2b 100644 --- a/tests/test-texture-types.cpp +++ b/tests/test-texture-types.cpp @@ -210,6 +210,9 @@ struct ShaderAndUnorderedTests : BaseTextureViewTest auto bufferElementCount = width * height * depth; encoder->dispatchCompute(bufferElementCount, 1, 1); + + encoder->textureBarrier(texture, texture->getDesc()->defaultState, ResourceState::CopySource); + encoder->endEncoding(); commandBuffer->close(); queue->executeCommandBuffer(commandBuffer); @@ -341,10 +344,9 @@ struct RenderTargetTests : BaseTextureViewTest ComPtr transientHeap; ComPtr pipeline; - ComPtr renderPass; - ComPtr framebuffer; ComPtr sampledTexture; + ComPtr sampledTextureView; ComPtr vertexBuffer; void createRequiredResources() @@ -429,30 +431,12 @@ struct RenderTargetTests : BaseTextureViewTest pipelineDesc.depthStencil.depthWriteEnable = false; REQUIRE_CALL(device->createRenderPipeline(pipelineDesc, pipeline.writeRef())); - IRenderPassLayout::Desc renderPassDesc = {}; - renderPassDesc.framebufferLayout = framebufferLayout; - renderPassDesc.renderTargetCount = 1; - IRenderPassLayout::TargetAccessDesc renderTargetAccess = {}; - renderTargetAccess.loadOp = IRenderPassLayout::TargetLoadOp::Clear; - renderTargetAccess.storeOp = IRenderPassLayout::TargetStoreOp::Store; - renderTargetAccess.initialState = getDefaultResourceStateForViewType(viewType); - renderTargetAccess.finalState = ResourceState::ResolveSource; - renderPassDesc.renderTargetAccess = &renderTargetAccess; - REQUIRE_CALL(device->createRenderPassLayout(renderPassDesc, renderPass.writeRef())); - IResourceView::Desc colorBufferViewDesc; memset(&colorBufferViewDesc, 0, sizeof(colorBufferViewDesc)); colorBufferViewDesc.format = textureInfo->format; colorBufferViewDesc.renderTarget.shape = textureInfo->textureType; // TODO: TextureCube? colorBufferViewDesc.type = viewType; - auto rtv = device->createTextureView(sampledTexture, colorBufferViewDesc); - - IFramebuffer::Desc framebufferDesc; - framebufferDesc.renderTargetCount = 1; - framebufferDesc.depthStencilView = nullptr; - framebufferDesc.renderTargetViews = rtv.readRef(); - framebufferDesc.layout = framebufferLayout; - REQUIRE_CALL(device->createFramebuffer(framebufferDesc, framebuffer.writeRef())); + REQUIRE_CALL(device->createTextureView(sampledTexture, colorBufferViewDesc, sampledTextureView.writeRef())); auto texelSize = getTexelSize(textureInfo->format); size_t alignment; @@ -466,11 +450,20 @@ struct RenderTargetTests : BaseTextureViewTest auto queue = device->createCommandQueue(queueDesc); auto commandBuffer = transientHeap->createCommandBuffer(); - auto renderEncoder = commandBuffer->encodeRenderCommands(renderPass, framebuffer); + + RenderPassDesc renderPass; + renderPass.colorAttachments[0].loadOp = TargetLoadOp::Clear; + renderPass.colorAttachments[0].storeOp = TargetStoreOp::Store; + renderPass.colorAttachments[0].initialState = getDefaultResourceStateForViewType(viewType); + renderPass.colorAttachments[0].finalState = ResourceState::ResolveSource; + renderPass.colorAttachments[0].view = sampledTextureView; + renderPass.colorAttachmentCount = 1; + + auto renderEncoder = commandBuffer->encodeRenderCommands(renderPass); auto rootObject = renderEncoder->bindPipeline(pipeline); Viewport viewport = {}; - viewport.maxZ = (float)textureInfo->extents.depth; + // viewport.maxZ = (float)textureInfo->extents.depth; viewport.extentX = (float)textureInfo->extents.width; viewport.extentY = (float)textureInfo->extents.height; renderEncoder->setViewportAndScissor(viewport); @@ -628,7 +621,7 @@ void testShaderAndUnordered(GpuTestContext* ctx, DeviceType deviceType) } } -void testRrenderTarget(GpuTestContext* ctx, DeviceType deviceType) +void testRenderTarget(GpuTestContext* ctx, DeviceType deviceType) { ComPtr device = createTestingDevice(ctx, deviceType); @@ -661,7 +654,7 @@ TEST_CASE("texture-types-shader-and-unordered") TEST_CASE("texture-types-render-target") { runGpuTests( - testRrenderTarget, + testRenderTarget, { DeviceType::D3D12, DeviceType::Vulkan, diff --git a/tests/testing.cpp b/tests/testing.cpp index ccb3763c..6255f296 100644 --- a/tests/testing.cpp +++ b/tests/testing.cpp @@ -68,6 +68,35 @@ void cleanupTestTempDirectories() remove_all(gTestTempDirectory); } +class DebugCallback : public IDebugCallback +{ +public: + virtual SLANG_NO_THROW void SLANG_MCALL + handleMessage(DebugMessageType type, DebugMessageSource source, const char* message) override + { + switch (type) + { + case DebugMessageType::Info: + { + INFO("Validation info: ", doctest::String(message)); + break; + } + case DebugMessageType::Warning: + { + MESSAGE("Validation warning: ", doctest::String(message)); + break; + } + case DebugMessageType::Error: + { + FAIL("Validation error: ", doctest::String(message)); + break; + } + } + } +}; + +static DebugCallback sDebugCallback; + void diagnoseIfNeeded(slang::IBlob* diagnosticsBlob) { if (diagnosticsBlob != nullptr) @@ -296,7 +325,9 @@ void compareComputeResultFuzzy(const float* result, float* expectedResult, size_ { for (size_t i = 0; i < expectedBufferSize / sizeof(float); ++i) { - CHECK_LE(abs(result[i] - expectedResult[i]), 0.01); + CHECK_LE(result[i], expectedResult[i] + 0.01f); + CHECK_GE(result[i], expectedResult[i] - 0.01f); + // CHECK_LE(abs(result[i] - expectedResult[i]), 0.01); } } @@ -367,6 +398,7 @@ ComPtr createTestingDevice( // here and render-test-main.cpp) #ifdef _DEBUG rhiEnableDebugLayer(); + rhiSetDebugCallback(&sDebugCallback); #endif REQUIRE_CALL(rhiCreateDevice(&deviceDesc, device.writeRef())); From 46e0e12097f6e577e77a8729d5bb8ad312712729 Mon Sep 17 00:00:00 2001 From: Simon Kallweit Date: Fri, 6 Sep 2024 15:30:53 +0200 Subject: [PATCH 2/8] remove framebuffer objects --- CHANGELOG | 2 + include/slang-rhi.h | 20 +- src/cuda/cuda-device.cpp | 8 - src/cuda/cuda-device.h | 3 - src/d3d11/d3d11-base.h | 1 - src/d3d11/d3d11-device.cpp | 12 +- src/d3d11/d3d11-device.h | 3 - src/d3d11/d3d11-framebuffer.h | 21 --- src/d3d12/d3d12-base.h | 1 - src/d3d12/d3d12-command-encoder.cpp | 1 + src/d3d12/d3d12-command-encoder.h | 2 +- src/d3d12/d3d12-device.cpp | 9 - src/d3d12/d3d12-device.h | 3 - src/d3d12/d3d12-framebuffer.h | 16 -- src/d3d12/d3d12-pipeline.cpp | 17 +- src/debug-layer/debug-base.h | 1 - src/debug-layer/debug-command-buffer.cpp | 1 - src/debug-layer/debug-device.cpp | 14 -- src/debug-layer/debug-device.h | 2 - src/debug-layer/debug-framebuffer.h | 16 -- src/debug-layer/debug-helper-functions.cpp | 1 - src/debug-layer/debug-helper-functions.h | 2 - src/immediate-renderer-base.h | 7 - src/metal/metal-base.h | 1 - src/metal/metal-device.cpp | 10 - src/metal/metal-device.h | 2 - src/renderer-shared.cpp | 12 +- src/renderer-shared.h | 11 +- src/vulkan/vk-base.h | 1 - src/vulkan/vk-device.cpp | 9 - src/vulkan/vk-device.h | 3 - src/vulkan/vk-framebuffer.cpp | 204 --------------------- src/vulkan/vk-framebuffer.h | 55 ------ src/vulkan/vk-pipeline.cpp | 15 +- tests/test-instanced-draw.cpp | 9 +- tests/test-ray-tracing.cpp | 7 - tests/test-resolve-resource-tests.cpp | 9 +- tests/test-shader-cache.cpp | 14 +- tests/test-texture-types.cpp | 10 +- 39 files changed, 36 insertions(+), 499 deletions(-) delete mode 100644 src/d3d11/d3d11-framebuffer.h delete mode 100644 src/d3d12/d3d12-framebuffer.h delete mode 100644 src/debug-layer/debug-framebuffer.h delete mode 100644 src/vulkan/vk-framebuffer.cpp delete mode 100644 src/vulkan/vk-framebuffer.h diff --git a/CHANGELOG b/CHANGELOG index 919f14c4..4b91294e 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,5 @@ +- implement dynamic rendering in Vulkan +- remove IFramebuffer and IFramebufferLayout - rename IFramebufferLayout::Desc -> FramebufferLayoutDesc - rename IInputLayout::Desc -> InputLayoutDesc - introduce ICommandEncoder, which is the new base interface for all command encoders (encoders don't inherit the IResourceCommandEncoder anymore) diff --git a/include/slang-rhi.h b/include/slang-rhi.h index eb7941e1..317165cd 100644 --- a/include/slang-rhi.h +++ b/include/slang-rhi.h @@ -1173,19 +1173,14 @@ struct BlendDesc struct TargetLayoutDesc { Format format = Format::Unknown; - GfxCount sampleCount = 1; }; struct FramebufferLayoutDesc { - GfxCount renderTargetCount; TargetLayoutDesc renderTargets[kMaxRenderTargetCount]; + GfxCount renderTargetCount = 0; TargetLayoutDesc depthStencil; -}; - -class IFramebufferLayout : public ISlangUnknown -{ - SLANG_COM_INTERFACE(0xe5facc0a, 0x3d48, 0x4459, {0x8e, 0xa5, 0x7d, 0xbe, 0x81, 0xba, 0x91, 0xc2}); + GfxCount sampleCount = 1; }; struct RenderPipelineDesc @@ -1193,7 +1188,7 @@ struct RenderPipelineDesc IShaderProgram* program = nullptr; IInputLayout* inputLayout = nullptr; - IFramebufferLayout* framebufferLayout = nullptr; + FramebufferLayoutDesc framebufferLayout; PrimitiveType primitiveType = PrimitiveType::Triangle; DepthStencilDesc depthStencil; RasterizerDesc rasterizer; @@ -2242,15 +2237,6 @@ class IDevice : public ISlangUnknown return view; } - virtual SLANG_NO_THROW Result SLANG_MCALL - createFramebufferLayout(FramebufferLayoutDesc const& desc, IFramebufferLayout** outFrameBuffer) = 0; - inline ComPtr createFramebufferLayout(FramebufferLayoutDesc const& desc) - { - ComPtr fb; - SLANG_RETURN_NULL_ON_FAIL(createFramebufferLayout(desc, fb.writeRef())); - return fb; - } - virtual SLANG_NO_THROW Result SLANG_MCALL createSwapchain(ISwapchain::Desc const& desc, WindowHandle window, ISwapchain** outSwapchain) = 0; inline ComPtr createSwapchain(ISwapchain::Desc const& desc, WindowHandle window) diff --git a/src/cuda/cuda-device.cpp b/src/cuda/cuda-device.cpp index 608425d9..81041a0e 100644 --- a/src/cuda/cuda-device.cpp +++ b/src/cuda/cuda-device.cpp @@ -1068,14 +1068,6 @@ DeviceImpl::createSwapchain(const ISwapchain::Desc& desc, WindowHandle window, I return SLANG_FAIL; } -SLANG_NO_THROW Result SLANG_MCALL -DeviceImpl::createFramebufferLayout(const FramebufferLayoutDesc& desc, IFramebufferLayout** outLayout) -{ - SLANG_UNUSED(desc); - SLANG_UNUSED(outLayout); - return SLANG_FAIL; -} - SLANG_NO_THROW Result SLANG_MCALL DeviceImpl::createSampler(SamplerDesc const& desc, ISampler** outSampler) { SLANG_UNUSED(desc); diff --git a/src/cuda/cuda-device.h b/src/cuda/cuda-device.h index eedca35a..75aca708 100644 --- a/src/cuda/cuda-device.h +++ b/src/cuda/cuda-device.h @@ -96,9 +96,6 @@ class DeviceImpl : public RendererBase virtual SLANG_NO_THROW Result SLANG_MCALL createSwapchain(const ISwapchain::Desc& desc, WindowHandle window, ISwapchain** outSwapchain) override; - virtual SLANG_NO_THROW Result SLANG_MCALL - createFramebufferLayout(const FramebufferLayoutDesc& desc, IFramebufferLayout** outLayout) override; - virtual SLANG_NO_THROW Result SLANG_MCALL createSampler(SamplerDesc const& desc, ISampler** outSampler) override; virtual SLANG_NO_THROW Result SLANG_MCALL diff --git a/src/d3d11/d3d11-base.h b/src/d3d11/d3d11-base.h index d17bac39..590d7635 100644 --- a/src/d3d11/d3d11-base.h +++ b/src/d3d11/d3d11-base.h @@ -53,7 +53,6 @@ class ShaderResourceViewImpl; class UnorderedAccessViewImpl; class DepthStencilViewImpl; class RenderTargetViewImpl; -class FramebufferLayoutImpl; class SwapchainImpl; class InputLayoutImpl; class QueryPoolImpl; diff --git a/src/d3d11/d3d11-device.cpp b/src/d3d11/d3d11-device.cpp index dc0579ce..1742a4e3 100644 --- a/src/d3d11/d3d11-device.cpp +++ b/src/d3d11/d3d11-device.cpp @@ -337,14 +337,6 @@ Result DeviceImpl::createSwapchain(const ISwapchain::Desc& desc, WindowHandle wi return SLANG_OK; } -Result DeviceImpl::createFramebufferLayout(const FramebufferLayoutDesc& desc, IFramebufferLayout** outLayout) -{ - RefPtr layout = new FramebufferLayoutImpl(); - layout->m_desc = desc; - returnComPtr(outLayout, layout); - return SLANG_OK; -} - void DeviceImpl::beginRenderPass(const RenderPassDesc& desc) { // Note: the framebuffer state will be flushed to the pipeline as part @@ -1614,7 +1606,7 @@ Result DeviceImpl::createRenderPipeline(const RenderPipelineDesc& inDesc, IPipel TargetBlendDesc defaultTargetBlendDesc; static const UInt kMaxTargets = D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; - int targetCount = static_cast(inDesc.framebufferLayout)->m_desc.renderTargetCount; + int targetCount = desc.framebufferLayout.renderTargetCount; if (targetCount > kMaxTargets) return SLANG_FAIL; @@ -1672,7 +1664,7 @@ Result DeviceImpl::createRenderPipeline(const RenderPipelineDesc& inDesc, IPipel pipeline->m_rasterizerState = rasterizerState; pipeline->m_blendState = blendState; pipeline->m_inputLayout = static_cast(desc.inputLayout); - pipeline->m_rtvCount = (UINT) static_cast(desc.framebufferLayout)->m_desc.renderTargetCount; + pipeline->m_rtvCount = desc.framebufferLayout.renderTargetCount; pipeline->m_blendColor[0] = 0; pipeline->m_blendColor[1] = 0; pipeline->m_blendColor[2] = 0; diff --git a/src/d3d11/d3d11-device.h b/src/d3d11/d3d11-device.h index a9b61cb9..a2bece51 100644 --- a/src/d3d11/d3d11-device.h +++ b/src/d3d11/d3d11-device.h @@ -1,6 +1,5 @@ #pragma once -#include "d3d11-framebuffer.h" #include "d3d11-pipeline.h" #include "d3d11-resource-views.h" @@ -15,8 +14,6 @@ class DeviceImpl : public ImmediateRendererBase virtual SLANG_NO_THROW Result SLANG_MCALL initialize(const Desc& desc) override; virtual SLANG_NO_THROW Result SLANG_MCALL createSwapchain(const ISwapchain::Desc& desc, WindowHandle window, ISwapchain** outSwapchain) override; - virtual SLANG_NO_THROW Result SLANG_MCALL - createFramebufferLayout(const FramebufferLayoutDesc& desc, IFramebufferLayout** outLayout) override; virtual void beginRenderPass(const RenderPassDesc& desc) override; virtual void endRenderPass() override; virtual void setStencilReference(uint32_t referenceValue) override; diff --git a/src/d3d11/d3d11-framebuffer.h b/src/d3d11/d3d11-framebuffer.h deleted file mode 100644 index 360c8d9f..00000000 --- a/src/d3d11/d3d11-framebuffer.h +++ /dev/null @@ -1,21 +0,0 @@ -#pragma once - -#include "d3d11-base.h" - -#include "core/short_vector.h" - -namespace rhi::d3d11 { - -enum -{ - kMaxUAVs = 64, - kMaxRTVs = 8, -}; - -class FramebufferLayoutImpl : public FramebufferLayoutBase -{ -public: - FramebufferLayoutDesc m_desc; -}; - -} // namespace rhi::d3d11 diff --git a/src/d3d12/d3d12-base.h b/src/d3d12/d3d12-base.h index e450ee8b..3148dbf6 100644 --- a/src/d3d12/d3d12-base.h +++ b/src/d3d12/d3d12-base.h @@ -47,7 +47,6 @@ class RenderCommandEncoderImpl; class ComputeCommandEncoderImpl; class CommandQueueImpl; class FenceImpl; -class FramebufferLayoutImpl; class QueryPoolImpl; class PlainBufferProxyQueryPoolImpl; class PipelineImpl; diff --git a/src/d3d12/d3d12-command-encoder.cpp b/src/d3d12/d3d12-command-encoder.cpp index 46976cd1..26c8a9b0 100644 --- a/src/d3d12/d3d12-command-encoder.cpp +++ b/src/d3d12/d3d12-command-encoder.cpp @@ -10,6 +10,7 @@ #include "d3d12-texture.h" #include "d3d12-transient-heap.h" #include "d3d12-vertex-layout.h" +#include "d3d12-resource-views.h" #include "core/short_vector.h" diff --git a/src/d3d12/d3d12-command-encoder.h b/src/d3d12/d3d12-command-encoder.h index ddf99ec2..ae1d0947 100644 --- a/src/d3d12/d3d12-command-encoder.h +++ b/src/d3d12/d3d12-command-encoder.h @@ -2,8 +2,8 @@ #include "d3d12-base.h" #include "d3d12-buffer.h" -#include "d3d12-framebuffer.h" #include "d3d12-submitter.h" +#include "d3d12-resource-views.h" #include "core/static_vector.h" diff --git a/src/d3d12/d3d12-device.cpp b/src/d3d12/d3d12-device.cpp index 2419374a..43f8ca27 100644 --- a/src/d3d12/d3d12-device.cpp +++ b/src/d3d12/d3d12-device.cpp @@ -2,7 +2,6 @@ #include "../nvapi/nvapi-util.h" #include "d3d12-buffer.h" #include "d3d12-fence.h" -#include "d3d12-framebuffer.h" #include "d3d12-helper-functions.h" #include "d3d12-pipeline.h" #include "d3d12-query.h" @@ -1656,14 +1655,6 @@ Result DeviceImpl::createBufferView( return SLANG_OK; } -Result DeviceImpl::createFramebufferLayout(FramebufferLayoutDesc const& desc, IFramebufferLayout** outLayout) -{ - RefPtr layout = new FramebufferLayoutImpl(); - layout->m_desc = desc; - returnComPtr(outLayout, layout); - return SLANG_OK; -} - Result DeviceImpl::createInputLayout(InputLayoutDesc const& desc, IInputLayout** outLayout) { RefPtr layout(new InputLayoutImpl); diff --git a/src/d3d12/d3d12-device.h b/src/d3d12/d3d12-device.h index 612eddcc..81146250 100644 --- a/src/d3d12/d3d12-device.h +++ b/src/d3d12/d3d12-device.h @@ -129,9 +129,6 @@ class DeviceImpl : public RendererBase createBufferView(IBuffer* buffer, IBuffer* counterBuffer, IResourceView::Desc const& desc, IResourceView** outView) override; - virtual SLANG_NO_THROW Result SLANG_MCALL - createFramebufferLayout(FramebufferLayoutDesc const& desc, IFramebufferLayout** outLayout) override; - virtual SLANG_NO_THROW Result SLANG_MCALL createInputLayout(InputLayoutDesc const& desc, IInputLayout** outLayout) override; diff --git a/src/d3d12/d3d12-framebuffer.h b/src/d3d12/d3d12-framebuffer.h deleted file mode 100644 index 263b21bf..00000000 --- a/src/d3d12/d3d12-framebuffer.h +++ /dev/null @@ -1,16 +0,0 @@ -#pragma once - -#include "d3d12-base.h" -#include "d3d12-resource-views.h" - -#include "core/short_vector.h" - -namespace rhi::d3d12 { - -class FramebufferLayoutImpl : public FramebufferLayoutBase -{ -public: - FramebufferLayoutDesc m_desc; -}; - -} // namespace rhi::d3d12 diff --git a/src/d3d12/d3d12-pipeline.cpp b/src/d3d12/d3d12-pipeline.cpp index 1b8d21f9..2169a601 100644 --- a/src/d3d12/d3d12-pipeline.cpp +++ b/src/d3d12/d3d12-pipeline.cpp @@ -1,6 +1,5 @@ #include "d3d12-pipeline.h" #include "d3d12-device.h" -#include "d3d12-framebuffer.h" #include "d3d12-pipeline-state-stream.h" #include "d3d12-shader-program.h" #include "d3d12-vertex-layout.h" @@ -66,29 +65,25 @@ Result PipelineImpl::ensureAPIPipelineCreated() psoDesc.PrimitiveTopologyType = D3DUtil::getPrimitiveType(desc.graphics.primitiveType); - auto framebufferLayout = static_cast(desc.graphics.framebufferLayout); - const int numRenderTargets = int(framebufferLayout->m_desc.renderTargetCount); + const auto& framebufferLayout = desc.graphics.framebufferLayout; + const int numRenderTargets = int(framebufferLayout.renderTargetCount); { - if (framebufferLayout->m_desc.depthStencil.format != Format::Unknown) + if (framebufferLayout.depthStencil.format != Format::Unknown) { - psoDesc.DSVFormat = D3DUtil::getMapFormat(framebufferLayout->m_desc.depthStencil.format); - psoDesc.SampleDesc.Count = framebufferLayout->m_desc.depthStencil.sampleCount; + psoDesc.DSVFormat = D3DUtil::getMapFormat(framebufferLayout.depthStencil.format); } else { psoDesc.DSVFormat = DXGI_FORMAT_UNKNOWN; - if (numRenderTargets > 0) - { - psoDesc.SampleDesc.Count = framebufferLayout->m_desc.renderTargets[0].sampleCount; - } } psoDesc.NumRenderTargets = numRenderTargets; for (Int i = 0; i < numRenderTargets; i++) { - psoDesc.RTVFormats[i] = D3DUtil::getMapFormat(framebufferLayout->m_desc.renderTargets[0].format); + psoDesc.RTVFormats[i] = D3DUtil::getMapFormat(framebufferLayout.renderTargets[0].format); } + psoDesc.SampleDesc.Count = framebufferLayout.sampleCount; psoDesc.SampleDesc.Quality = 0; psoDesc.SampleMask = UINT_MAX; } diff --git a/src/debug-layer/debug-base.h b/src/debug-layer/debug-base.h index 97924586..b563d4b3 100644 --- a/src/debug-layer/debug-base.h +++ b/src/debug-layer/debug-base.h @@ -55,7 +55,6 @@ class DebugRayTracingCommandEncoder; class DebugFence; class DebugCommandQueue; class DebugFramebuffer; -class DebugFramebufferLayout; class DebugInputLayout; class DebugPipeline; class DebugShaderProgram; diff --git a/src/debug-layer/debug-command-buffer.cpp b/src/debug-layer/debug-command-buffer.cpp index c9cacd96..88b76326 100644 --- a/src/debug-layer/debug-command-buffer.cpp +++ b/src/debug-layer/debug-command-buffer.cpp @@ -1,5 +1,4 @@ #include "debug-command-buffer.h" -#include "debug-framebuffer.h" #include "debug-helper-functions.h" namespace rhi::debug { diff --git a/src/debug-layer/debug-device.cpp b/src/debug-layer/debug-device.cpp index 6fb29324..1252766f 100644 --- a/src/debug-layer/debug-device.cpp +++ b/src/debug-layer/debug-device.cpp @@ -2,7 +2,6 @@ #include "debug-buffer.h" #include "debug-command-queue.h" #include "debug-fence.h" -#include "debug-framebuffer.h" #include "debug-helper-functions.h" #include "debug-pipeline.h" #include "debug-query.h" @@ -239,18 +238,6 @@ Result DebugDevice::createAccelerationStructure( return SLANG_OK; } -Result DebugDevice::createFramebufferLayout(FramebufferLayoutDesc const& desc, IFramebufferLayout** outFrameBuffer) -{ - SLANG_RHI_API_FUNC; - - RefPtr outObject = new DebugFramebufferLayout(); - auto result = baseObject->createFramebufferLayout(desc, outObject->baseObject.writeRef()); - if (SLANG_FAILED(result)) - return result; - returnComPtr(outFrameBuffer, outObject); - return result; -} - Result DebugDevice::createSwapchain(ISwapchain::Desc const& desc, WindowHandle window, ISwapchain** outSwapchain) { SLANG_RHI_API_FUNC; @@ -444,7 +431,6 @@ Result DebugDevice::createRenderPipeline(const RenderPipelineDesc& desc, IPipeli RenderPipelineDesc innerDesc = desc; innerDesc.program = getInnerObj(desc.program); innerDesc.inputLayout = getInnerObj(desc.inputLayout); - innerDesc.framebufferLayout = getInnerObj(desc.framebufferLayout); RefPtr outObject = new DebugPipeline(); auto result = baseObject->createRenderPipeline(innerDesc, outObject->baseObject.writeRef()); if (SLANG_FAILED(result)) diff --git a/src/debug-layer/debug-device.h b/src/debug-layer/debug-device.h index ffbb705a..0f981876 100644 --- a/src/debug-layer/debug-device.h +++ b/src/debug-layer/debug-device.h @@ -55,8 +55,6 @@ class DebugDevice : public DebugObject IAccelerationStructure** outView ) override; virtual SLANG_NO_THROW Result SLANG_MCALL - createFramebufferLayout(FramebufferLayoutDesc const& desc, IFramebufferLayout** outFrameBuffer) override; - virtual SLANG_NO_THROW Result SLANG_MCALL createSwapchain(ISwapchain::Desc const& desc, WindowHandle window, ISwapchain** outSwapchain) override; virtual SLANG_NO_THROW Result SLANG_MCALL createInputLayout(InputLayoutDesc const& desc, IInputLayout** outLayout) override; diff --git a/src/debug-layer/debug-framebuffer.h b/src/debug-layer/debug-framebuffer.h deleted file mode 100644 index 5ad4d10f..00000000 --- a/src/debug-layer/debug-framebuffer.h +++ /dev/null @@ -1,16 +0,0 @@ -#pragma once - -#include "debug-base.h" - -namespace rhi::debug { - -class DebugFramebufferLayout : public DebugObject -{ -public: - SLANG_COM_OBJECT_IUNKNOWN_ALL; - -public: - IFramebufferLayout* getInterface(const Guid& guid); -}; - -} // namespace rhi::debug diff --git a/src/debug-layer/debug-helper-functions.cpp b/src/debug-layer/debug-helper-functions.cpp index dfdb9b24..67fd8ab6 100644 --- a/src/debug-layer/debug-helper-functions.cpp +++ b/src/debug-layer/debug-helper-functions.cpp @@ -10,7 +10,6 @@ SLANG_RHI_DEBUG_GET_INTERFACE_IMPL(Device) SLANG_RHI_DEBUG_GET_INTERFACE_IMPL_PARENT(Buffer, Resource) SLANG_RHI_DEBUG_GET_INTERFACE_IMPL_PARENT(Texture, Resource) SLANG_RHI_DEBUG_GET_INTERFACE_IMPL(CommandQueue) -SLANG_RHI_DEBUG_GET_INTERFACE_IMPL(FramebufferLayout) SLANG_RHI_DEBUG_GET_INTERFACE_IMPL(InputLayout) SLANG_RHI_DEBUG_GET_INTERFACE_IMPL(Pipeline) SLANG_RHI_DEBUG_GET_INTERFACE_IMPL(ResourceView) diff --git a/src/debug-layer/debug-helper-functions.h b/src/debug-layer/debug-helper-functions.h index 31f43f7d..1b51e0b4 100644 --- a/src/debug-layer/debug-helper-functions.h +++ b/src/debug-layer/debug-helper-functions.h @@ -5,7 +5,6 @@ #include "debug-command-queue.h" #include "debug-device.h" #include "debug-fence.h" -#include "debug-framebuffer.h" #include "debug-pipeline.h" #include "debug-query.h" #include "debug-resource-views.h" @@ -160,7 +159,6 @@ SLANG_RHI_DEBUG_GET_OBJ_IMPL_UNOWNED(ComputeCommandEncoder) SLANG_RHI_DEBUG_GET_OBJ_IMPL_UNOWNED(RenderCommandEncoder) SLANG_RHI_DEBUG_GET_OBJ_IMPL_UNOWNED(ResourceCommandEncoder) SLANG_RHI_DEBUG_GET_OBJ_IMPL_UNOWNED(RayTracingCommandEncoder) -SLANG_RHI_DEBUG_GET_OBJ_IMPL(FramebufferLayout) SLANG_RHI_DEBUG_GET_OBJ_IMPL(InputLayout) SLANG_RHI_DEBUG_GET_OBJ_IMPL(Pipeline) SLANG_RHI_DEBUG_GET_OBJ_IMPL(ResourceView) diff --git a/src/immediate-renderer-base.h b/src/immediate-renderer-base.h index a4a75653..ce0a5438 100644 --- a/src/immediate-renderer-base.h +++ b/src/immediate-renderer-base.h @@ -187,13 +187,6 @@ class ImmediateComputeDeviceBase : public ImmediateRendererBase SLANG_UNUSED(outSwapchain); return SLANG_FAIL; } - virtual SLANG_NO_THROW Result SLANG_MCALL - createFramebufferLayout(const FramebufferLayoutDesc& desc, IFramebufferLayout** outLayout) override - { - SLANG_UNUSED(desc); - SLANG_UNUSED(outLayout); - return SLANG_FAIL; - } virtual SLANG_NO_THROW Result SLANG_MCALL createInputLayout(InputLayoutDesc const& desc, IInputLayout** outLayout) override diff --git a/src/metal/metal-base.h b/src/metal/metal-base.h index 45e5d374..716bf704 100644 --- a/src/metal/metal-base.h +++ b/src/metal/metal-base.h @@ -22,7 +22,6 @@ class TextureViewImpl; class TexelBufferViewImpl; class PlainBufferViewImpl; class AccelerationStructureImpl; -class FramebufferLayoutImpl; class PipelineImpl; class RayTracingPipelineImpl; class ShaderObjectLayoutImpl; diff --git a/src/metal/metal-device.cpp b/src/metal/metal-device.cpp index abd7582b..fd15fa42 100644 --- a/src/metal/metal-device.cpp +++ b/src/metal/metal-device.cpp @@ -148,16 +148,6 @@ Result DeviceImpl::createSwapchain(const ISwapchain::Desc& desc, WindowHandle wi return SLANG_OK; } -Result DeviceImpl::createFramebufferLayout(const FramebufferLayoutDesc& desc, IFramebufferLayout** outLayout) -{ - AUTORELEASEPOOL - - RefPtr layoutImpl = new FramebufferLayoutImpl; - SLANG_RETURN_ON_FAIL(layoutImpl->init(desc)); - returnComPtr(outLayout, layoutImpl); - return SLANG_OK; -} - Result DeviceImpl::readTexture( ITexture* texture, ResourceState state, diff --git a/src/metal/metal-device.h b/src/metal/metal-device.h index 0d5f8358..98627044 100644 --- a/src/metal/metal-device.h +++ b/src/metal/metal-device.h @@ -25,8 +25,6 @@ class DeviceImpl : public RendererBase virtual SLANG_NO_THROW Result SLANG_MCALL createSwapchain(const ISwapchain::Desc& desc, WindowHandle window, ISwapchain** outSwapchain) override; virtual SLANG_NO_THROW Result SLANG_MCALL - createFramebufferLayout(const FramebufferLayoutDesc& desc, IFramebufferLayout** outLayout) override; - virtual SLANG_NO_THROW Result SLANG_MCALL createTexture(const TextureDesc& desc, const SubresourceData* initData, ITexture** outTexture) override; virtual SLANG_NO_THROW Result SLANG_MCALL createBuffer(const BufferDesc& desc, const void* initData, IBuffer** outBuffer) override; diff --git a/src/renderer-shared.cpp b/src/renderer-shared.cpp index 80b4b098..3e73ee41 100644 --- a/src/renderer-shared.cpp +++ b/src/renderer-shared.cpp @@ -18,7 +18,6 @@ const Guid GUID::IID_IInputLayout = IInputLayout::getTypeGuid(); const Guid GUID::IID_IPipeline = IPipeline::getTypeGuid(); const Guid GUID::IID_ITransientResourceHeap = ITransientResourceHeap::getTypeGuid(); const Guid GUID::IID_IResourceView = IResourceView::getTypeGuid(); -const Guid GUID::IID_IFramebufferLayout = IFramebufferLayout::getTypeGuid(); const Guid GUID::IID_ISwapchain = ISwapchain::getTypeGuid(); const Guid GUID::IID_ISampler = ISampler::getTypeGuid(); @@ -208,13 +207,6 @@ IInputLayout* InputLayoutBase::getInterface(const Guid& guid) return nullptr; } -IFramebufferLayout* FramebufferLayoutBase::getInterface(const Guid& guid) -{ - if (guid == GUID::IID_ISlangUnknown || guid == GUID::IID_IFramebufferLayout) - return static_cast(this); - return nullptr; -} - IQueryPool* QueryPoolBase::getInterface(const Guid& guid) { if (guid == GUID::IID_ISlangUnknown || guid == GUID::IID_IQueryPool) @@ -252,12 +244,10 @@ void PipelineBase::initializeBase(const PipelineStateDesc& inDesc) break; } } - // Hold a strong reference to inputLayout and framebufferLayout objects to prevent it from - // destruction. + // Hold a strong reference to inputLayout object to prevent it from destruction. if (inDesc.type == PipelineType::Graphics) { inputLayout = static_cast(inDesc.graphics.inputLayout); - framebufferLayout = static_cast(inDesc.graphics.framebufferLayout); } } diff --git a/src/renderer-shared.h b/src/renderer-shared.h index 0b8788e7..3adc59da 100644 --- a/src/renderer-shared.h +++ b/src/renderer-shared.h @@ -25,7 +25,6 @@ struct GUID static const Guid IID_IPipeline; static const Guid IID_IResourceView; static const Guid IID_IFramebuffer; - static const Guid IID_IFramebufferLayout; static const Guid IID_ISwapchain; static const Guid IID_ISampler; static const Guid IID_IResource; @@ -818,13 +817,6 @@ class InputLayoutBase : public IInputLayout, public ComObject IInputLayout* getInterface(const Guid& guid); }; -class FramebufferLayoutBase : public IFramebufferLayout, public ComObject -{ -public: - SLANG_COM_OBJECT_IUNKNOWN_ALL - IFramebufferLayout* getInterface(const Guid& guid); -}; - class QueryPoolBase : public IQueryPool, public ComObject { public: @@ -944,10 +936,9 @@ class PipelineBase : public IPipeline, public ComObject } } desc; - // We need to hold inputLayout and framebufferLayout objects alive, since we may use it to + // We need to hold inputLayout object alive, since we may use it to // create specialized pipeline states later. RefPtr inputLayout; - RefPtr framebufferLayout; // The pipeline state from which this pipeline state is specialized. // If null, this pipeline is either an unspecialized pipeline. diff --git a/src/vulkan/vk-base.h b/src/vulkan/vk-base.h index c81900d7..626ad3ef 100644 --- a/src/vulkan/vk-base.h +++ b/src/vulkan/vk-base.h @@ -23,7 +23,6 @@ class TextureViewImpl; class TexelBufferViewImpl; class PlainBufferViewImpl; class AccelerationStructureImpl; -class FramebufferLayoutImpl; class RenderPassLayoutImpl; class PipelineImpl; class RayTracingPipelineImpl; diff --git a/src/vulkan/vk-device.cpp b/src/vulkan/vk-device.cpp index cb71349e..793cec23 100644 --- a/src/vulkan/vk-device.cpp +++ b/src/vulkan/vk-device.cpp @@ -1125,15 +1125,6 @@ Result DeviceImpl::createSwapchain(const ISwapchain::Desc& desc, WindowHandle wi return SLANG_OK; } -Result DeviceImpl::createFramebufferLayout(const FramebufferLayoutDesc& desc, IFramebufferLayout** outLayout) -{ - RefPtr layout = new FramebufferLayoutImpl(); - SLANG_RETURN_ON_FAIL(layout->init(this, desc)); - layout->m_desc = desc; - returnComPtr(outLayout, layout); - return SLANG_OK; -} - Result DeviceImpl::readTexture( ITexture* texture, ResourceState state, diff --git a/src/vulkan/vk-device.h b/src/vulkan/vk-device.h index f6640381..3592b367 100644 --- a/src/vulkan/vk-device.h +++ b/src/vulkan/vk-device.h @@ -1,7 +1,6 @@ #pragma once #include "vk-base.h" -#include "vk-framebuffer.h" #include "core/stable_vector.h" @@ -24,8 +23,6 @@ class DeviceImpl : public RendererBase virtual SLANG_NO_THROW Result SLANG_MCALL createSwapchain(const ISwapchain::Desc& desc, WindowHandle window, ISwapchain** outSwapchain) override; virtual SLANG_NO_THROW Result SLANG_MCALL - createFramebufferLayout(const FramebufferLayoutDesc& desc, IFramebufferLayout** outLayout) override; - virtual SLANG_NO_THROW Result SLANG_MCALL createTexture(const TextureDesc& desc, const SubresourceData* initData, ITexture** outTexture) override; virtual SLANG_NO_THROW Result SLANG_MCALL createBuffer(const BufferDesc& desc, const void* initData, IBuffer** outBuffer) override; diff --git a/src/vulkan/vk-framebuffer.cpp b/src/vulkan/vk-framebuffer.cpp deleted file mode 100644 index 4bc52c07..00000000 --- a/src/vulkan/vk-framebuffer.cpp +++ /dev/null @@ -1,204 +0,0 @@ -#include "vk-framebuffer.h" -#include "vk-device.h" -#include "vk-helper-functions.h" -#include "vk-resource-views.h" - -#include "core/static_vector.h" - -namespace rhi::vk { - -FramebufferLayoutImpl::~FramebufferLayoutImpl() -{ - m_renderer->m_api.vkDestroyRenderPass(m_renderer->m_api.m_device, m_renderPass, nullptr); -} - -Result FramebufferLayoutImpl::init(DeviceImpl* renderer, const FramebufferLayoutDesc& desc) -{ - m_renderer = renderer; - m_renderTargetCount = desc.renderTargetCount; - // Create render pass. - int numTargets = m_renderTargetCount; - m_hasDepthStencilTarget = (desc.depthStencil.format != Format::Unknown); - if (m_hasDepthStencilTarget) - { - numTargets++; - } - // We need extra space if we have depth buffer - m_targetDescs.resize(numTargets); - for (GfxIndex i = 0; i < desc.renderTargetCount; ++i) - { - auto& renderTarget = desc.renderTargets[i]; - VkAttachmentDescription& dst = m_targetDescs[i]; - - dst.flags = 0; - dst.format = VulkanUtil::getVkFormat(renderTarget.format); - if (renderTarget.format == Format::Unknown) - dst.format = VK_FORMAT_R8G8B8A8_UNORM; - dst.samples = (VkSampleCountFlagBits)renderTarget.sampleCount; - - // The following load/store/layout settings does not matter. - // In FramebufferLayout we just need a "compatible" render pass that - // can be used to create a framebuffer. A framebuffer created - // with this render pass setting can be used with actual render passes - // that has a different loadOp/storeOp/layout setting. - dst.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; - dst.storeOp = VK_ATTACHMENT_STORE_OP_STORE; - dst.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; - dst.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; - dst.initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; - dst.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; - - m_sampleCount = std::max(dst.samples, m_sampleCount); - } - - if (desc.depthStencil.format != Format::Unknown) - { - VkAttachmentDescription& dst = m_targetDescs[desc.renderTargetCount]; - dst.flags = 0; - dst.format = VulkanUtil::getVkFormat(desc.depthStencil.format); - dst.samples = (VkSampleCountFlagBits)desc.depthStencil.sampleCount; - dst.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; - dst.storeOp = VK_ATTACHMENT_STORE_OP_STORE; - dst.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD; - dst.stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE; - dst.initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; - dst.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; - - m_sampleCount = std::max(dst.samples, m_sampleCount); - } - - static_vector& colorReferences = m_colorReferences; - colorReferences.resize(desc.renderTargetCount); - for (GfxIndex i = 0; i < desc.renderTargetCount; ++i) - { - VkAttachmentReference& dst = colorReferences[i]; - dst.attachment = i; - dst.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; - } - - m_depthReference = VkAttachmentReference{}; - m_depthReference.attachment = desc.renderTargetCount; - m_depthReference.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; - - VkSubpassDescription subpassDesc = {}; - subpassDesc.flags = 0; - subpassDesc.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; - subpassDesc.inputAttachmentCount = 0u; - subpassDesc.pInputAttachments = nullptr; - subpassDesc.colorAttachmentCount = desc.renderTargetCount; - subpassDesc.pColorAttachments = colorReferences.data(); - subpassDesc.pResolveAttachments = nullptr; - subpassDesc.pDepthStencilAttachment = m_hasDepthStencilTarget ? &m_depthReference : nullptr; - subpassDesc.preserveAttachmentCount = 0u; - subpassDesc.pPreserveAttachments = nullptr; - - VkRenderPassCreateInfo renderPassCreateInfo = {}; - renderPassCreateInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; - renderPassCreateInfo.attachmentCount = numTargets; - renderPassCreateInfo.pAttachments = m_targetDescs.data(); - renderPassCreateInfo.subpassCount = 1; - renderPassCreateInfo.pSubpasses = &subpassDesc; - SLANG_VK_RETURN_ON_FAIL( - m_renderer->m_api.vkCreateRenderPass(m_renderer->m_api.m_device, &renderPassCreateInfo, nullptr, &m_renderPass) - ); - return SLANG_OK; -} -#if 0 -FramebufferImpl::~FramebufferImpl() -{ - m_renderer->m_api.vkDestroyFramebuffer(m_renderer->m_api.m_device, m_handle, nullptr); -} - -Result FramebufferImpl::init(DeviceImpl* renderer, const IFramebuffer::Desc& desc) -{ - m_renderer = renderer; - uint32_t layerCount = 0; - - auto dsv = desc.depthStencilView ? static_cast(desc.depthStencilView) : nullptr; - // Get frame dimensions from attachments. - if (dsv) - { - // If we have a depth attachment, get frame size from there. - auto size = dsv->m_texture->getDesc()->size; - auto viewDesc = dsv->getViewDesc(); - m_width = getMipLevelSize(viewDesc->subresourceRange.mipLevel, size.width); - m_height = getMipLevelSize(viewDesc->subresourceRange.mipLevel, size.height); - layerCount = viewDesc->subresourceRange.layerCount; - } - else if (desc.renderTargetCount) - { - // If we don't have a depth attachment, then we must have at least - // one color attachment. Get frame dimension from there. - auto viewImpl = static_cast(desc.renderTargetViews[0]); - auto resourceDesc = viewImpl->m_texture->getDesc(); - auto viewDesc = viewImpl->getViewDesc(); - auto size = resourceDesc->size; - m_width = getMipLevelSize(viewDesc->subresourceRange.mipLevel, size.width); - m_height = getMipLevelSize(viewDesc->subresourceRange.mipLevel, size.height); - layerCount = - (resourceDesc->type == TextureType::Texture3D) ? size.depth : viewDesc->subresourceRange.layerCount; - } - else - { - // In case we create an "empty" framebuffer, use the maximum viewport dimensions. - // This to allow arbitrary viewport sizes when rendering to the empty framebuffer. - m_width = m_renderer->m_api.m_deviceProperties.limits.maxViewportDimensions[0]; - m_height = m_renderer->m_api.m_deviceProperties.limits.maxViewportDimensions[1]; - layerCount = 1; - } - if (layerCount == 0) - layerCount = 1; - // Create render pass. - int numTargets = desc.renderTargetCount; - if (desc.depthStencilView) - numTargets++; - static_vector imageViews; - imageViews.resize(numTargets); - renderTargetViews.resize(desc.renderTargetCount); - for (GfxIndex i = 0; i < desc.renderTargetCount; ++i) - { - auto resourceView = static_cast(desc.renderTargetViews[i]); - renderTargetViews[i] = resourceView; - imageViews[i] = resourceView->m_view; - if (resourceView->m_texture->getDesc()->optimalClearValue) - { - memcpy( - &m_clearValues[i], - &resourceView->m_texture->getDesc()->optimalClearValue->color, - sizeof(ColorClearValue) - ); - } - } - - if (dsv) - { - imageViews[desc.renderTargetCount] = dsv->m_view; - depthStencilView = dsv; - if (dsv->m_texture->getDesc()->optimalClearValue) - { - memcpy( - &m_clearValues[desc.renderTargetCount], - &dsv->m_texture->getDesc()->optimalClearValue->depthStencil, - sizeof(DepthStencilClearValue) - ); - } - } - - // Create framebuffer. - m_layout = static_cast(desc.layout); - VkFramebufferCreateInfo framebufferInfo = {}; - framebufferInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; - framebufferInfo.renderPass = m_layout->m_renderPass; - framebufferInfo.attachmentCount = numTargets; - framebufferInfo.pAttachments = imageViews.data(); - framebufferInfo.width = m_width; - framebufferInfo.height = m_height; - framebufferInfo.layers = layerCount; - - SLANG_VK_RETURN_ON_FAIL( - m_renderer->m_api.vkCreateFramebuffer(m_renderer->m_api.m_device, &framebufferInfo, nullptr, &m_handle) - ); - return SLANG_OK; -} -#endif -} // namespace rhi::vk diff --git a/src/vulkan/vk-framebuffer.h b/src/vulkan/vk-framebuffer.h deleted file mode 100644 index 139284f8..00000000 --- a/src/vulkan/vk-framebuffer.h +++ /dev/null @@ -1,55 +0,0 @@ -#pragma once - -#include "vk-base.h" - -#include "core/short_vector.h" -#include "core/static_vector.h" - -namespace rhi::vk { - -enum -{ - kMaxRenderTargets = 8, - kMaxTargets = kMaxRenderTargets + 1, -}; - -class FramebufferLayoutImpl : public FramebufferLayoutBase -{ -public: - FramebufferLayoutDesc m_desc; - - VkRenderPass m_renderPass; - DeviceImpl* m_renderer; - static_vector m_targetDescs; - static_vector m_colorReferences; - VkAttachmentReference m_depthReference; - bool m_hasDepthStencilTarget; - uint32_t m_renderTargetCount; - VkSampleCountFlagBits m_sampleCount = VK_SAMPLE_COUNT_1_BIT; - -public: - ~FramebufferLayoutImpl(); - Result init(DeviceImpl* renderer, const FramebufferLayoutDesc& desc); -}; - -#if 0 -class FramebufferImpl : public FramebufferBase -{ -public: - VkFramebuffer m_handle; - short_vector> renderTargetViews; - ComPtr depthStencilView; - uint32_t m_width; - uint32_t m_height; - BreakableReference m_renderer; - VkClearValue m_clearValues[kMaxTargets]; - RefPtr m_layout; - -public: - ~FramebufferImpl(); - - Result init(DeviceImpl* renderer, const IFramebuffer::Desc& desc); -}; -#endif - -} // namespace rhi::vk diff --git a/src/vulkan/vk-pipeline.cpp b/src/vulkan/vk-pipeline.cpp index f6ae653b..87da2d3d 100644 --- a/src/vulkan/vk-pipeline.cpp +++ b/src/vulkan/vk-pipeline.cpp @@ -141,20 +141,20 @@ Result PipelineImpl::createVKGraphicsPipeline() rasterizer.pNext = &conservativeRasterInfo; } - auto framebufferLayoutImpl = static_cast(desc.graphics.framebufferLayout); + const auto& framebufferLayout = desc.graphics.framebufferLayout; auto forcedSampleCount = rasterizerDesc.forcedSampleCount; auto blendDesc = desc.graphics.blend; VkPipelineMultisampleStateCreateInfo multisampling = {}; multisampling.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; - multisampling.rasterizationSamples = (forcedSampleCount == 0) ? framebufferLayoutImpl->m_sampleCount + multisampling.rasterizationSamples = (forcedSampleCount == 0) ? VkSampleCountFlagBits(framebufferLayout.sampleCount) : VulkanUtil::translateSampleCount(forcedSampleCount); multisampling.sampleShadingEnable = VK_FALSE; // TODO: Should check if fragment shader needs this // TODO: Sample mask is dynamic in D3D12 but PSO state in Vulkan multisampling.alphaToCoverageEnable = blendDesc.alphaToCoverageEnable; multisampling.alphaToOneEnable = VK_FALSE; - auto targetCount = framebufferLayoutImpl->m_renderTargetCount; + auto targetCount = framebufferLayout.renderTargetCount; std::vector colorBlendTargets; // Regardless of whether blending is enabled, Vulkan always applies the color write mask @@ -239,16 +239,15 @@ Result PipelineImpl::createVKGraphicsPipeline() VkPipelineRenderingCreateInfoKHR renderingInfo = {VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR}; static_vector colorAttachmentFormats; - for (GfxIndex i = 0; i < framebufferLayoutImpl->m_desc.renderTargetCount; ++i) + for (GfxIndex i = 0; i < framebufferLayout.renderTargetCount; ++i) { - colorAttachmentFormats.push_back(VulkanUtil::getVkFormat(framebufferLayoutImpl->m_desc.renderTargets[i].format) - ); + colorAttachmentFormats.push_back(VulkanUtil::getVkFormat(framebufferLayout.renderTargets[i].format)); } renderingInfo.colorAttachmentCount = colorAttachmentFormats.size(); renderingInfo.pColorAttachmentFormats = colorAttachmentFormats.data(); - renderingInfo.depthAttachmentFormat = VulkanUtil::getVkFormat(framebufferLayoutImpl->m_desc.depthStencil.format); + renderingInfo.depthAttachmentFormat = VulkanUtil::getVkFormat(framebufferLayout.depthStencil.format); // TODO we should probably only set this when this is actually a stencil format - renderingInfo.stencilAttachmentFormat = VulkanUtil::getVkFormat(framebufferLayoutImpl->m_desc.depthStencil.format); + renderingInfo.stencilAttachmentFormat = VulkanUtil::getVkFormat(framebufferLayout.depthStencil.format); VkGraphicsPipelineCreateInfo pipelineInfo = {VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO}; pipelineInfo.pNext = &renderingInfo; diff --git a/tests/test-instanced-draw.cpp b/tests/test-instanced-draw.cpp index 5e9c37ec..0f238afc 100644 --- a/tests/test-instanced-draw.cpp +++ b/tests/test-instanced-draw.cpp @@ -153,16 +153,11 @@ class BaseDrawTest slangReflection )); - FramebufferLayoutDesc framebufferLayoutDesc; - framebufferLayoutDesc.renderTargetCount = 1; - framebufferLayoutDesc.renderTargets[0] = {format, 1}; - ComPtr framebufferLayout = device->createFramebufferLayout(framebufferLayoutDesc); - REQUIRE(framebufferLayout != nullptr); - RenderPipelineDesc pipelineDesc = {}; pipelineDesc.program = shaderProgram.get(); pipelineDesc.inputLayout = inputLayout; - pipelineDesc.framebufferLayout = framebufferLayout; + pipelineDesc.framebufferLayout.renderTargets[0] = {format}; + pipelineDesc.framebufferLayout.renderTargetCount = 1; pipelineDesc.depthStencil.depthTestEnable = false; pipelineDesc.depthStencil.depthWriteEnable = false; REQUIRE_CALL(device->createRenderPipeline(pipelineDesc, pipeline.writeRef())); diff --git a/tests/test-ray-tracing.cpp b/tests/test-ray-tracing.cpp index 14aaad37..0aea202a 100644 --- a/tests/test-ray-tracing.cpp +++ b/tests/test-ray-tracing.cpp @@ -43,7 +43,6 @@ struct BaseRayTracingTest { IDevice* device; - ComPtr framebufferLayout; ComPtr transientHeap; ComPtr queue; @@ -153,12 +152,6 @@ struct BaseRayTracingTest createResultTexture(); - FramebufferLayoutDesc framebufferLayoutDesc; - framebufferLayoutDesc.renderTargetCount = 1; - framebufferLayoutDesc.renderTargets[0] = {Format::R8G8B8A8_UNORM, 1}; - framebufferLayoutDesc.depthStencil = {Format::D32_FLOAT, 1}; - REQUIRE_CALL(device->createFramebufferLayout(framebufferLayoutDesc, framebufferLayout.writeRef())); - ITransientResourceHeap::Desc transientHeapDesc = {}; transientHeapDesc.constantBufferSize = 4096 * 1024; REQUIRE_CALL(device->createTransientResourceHeap(transientHeapDesc, transientHeap.writeRef())); diff --git a/tests/test-resolve-resource-tests.cpp b/tests/test-resolve-resource-tests.cpp index 2727b145..20e866f4 100644 --- a/tests/test-resolve-resource-tests.cpp +++ b/tests/test-resolve-resource-tests.cpp @@ -134,16 +134,13 @@ struct BaseResolveResourceTest slangReflection )); - FramebufferLayoutDesc framebufferLayoutDesc; - framebufferLayoutDesc.renderTargetCount = 1; - framebufferLayoutDesc.renderTargets[0] = {format, 4}; - ComPtr framebufferLayout = device->createFramebufferLayout(framebufferLayoutDesc); - REQUIRE(framebufferLayout != nullptr); RenderPipelineDesc pipelineDesc = {}; pipelineDesc.program = shaderProgram.get(); pipelineDesc.inputLayout = inputLayout; - pipelineDesc.framebufferLayout = framebufferLayout; + pipelineDesc.framebufferLayout.renderTargets[0] = {format}; + pipelineDesc.framebufferLayout.renderTargetCount = 1; + pipelineDesc.framebufferLayout.sampleCount = 4; pipelineDesc.depthStencil.depthTestEnable = false; pipelineDesc.depthStencil.depthWriteEnable = false; REQUIRE_CALL(device->createRenderPipeline(pipelineDesc, pipeline.writeRef())); diff --git a/tests/test-shader-cache.cpp b/tests/test-shader-cache.cpp index 565f9060..f239ea38 100644 --- a/tests/test-shader-cache.cpp +++ b/tests/test-shader-cache.cpp @@ -699,7 +699,6 @@ struct ShaderCacheTestGraphics : ShaderCacheTest ComPtr colorBuffer; ComPtr colorBufferView; ComPtr inputLayout; - ComPtr framebufferLayout; ComPtr createVertexBuffer(IDevice* device) { @@ -755,12 +754,6 @@ struct ShaderCacheTestGraphics : ShaderCacheTest vertexBuffer = createVertexBuffer(device); colorBuffer = createColorBuffer(device); - FramebufferLayoutDesc framebufferLayoutDesc; - framebufferLayoutDesc.renderTargetCount = 1; - framebufferLayoutDesc.renderTargets[0] = {format, 1}; - framebufferLayout = device->createFramebufferLayout(framebufferLayoutDesc); - REQUIRE(framebufferLayout != nullptr); - IResourceView::Desc colorBufferViewDesc; memset(&colorBufferViewDesc, 0, sizeof(colorBufferViewDesc)); colorBufferViewDesc.format = format; @@ -772,7 +765,6 @@ struct ShaderCacheTestGraphics : ShaderCacheTest void freeGraphicsResources() { inputLayout = nullptr; - framebufferLayout = nullptr; vertexBuffer = nullptr; colorBuffer = nullptr; pipeline = nullptr; @@ -794,7 +786,8 @@ struct ShaderCacheTestGraphics : ShaderCacheTest RenderPipelineDesc pipelineDesc = {}; pipelineDesc.program = shaderProgram.get(); pipelineDesc.inputLayout = inputLayout; - pipelineDesc.framebufferLayout = framebufferLayout; + pipelineDesc.framebufferLayout.renderTargets[0] = {format}; + pipelineDesc.framebufferLayout.renderTargetCount = 1; pipelineDesc.depthStencil.depthTestEnable = false; pipelineDesc.depthStencil.depthWriteEnable = false; REQUIRE_CALL(device->createRenderPipeline(pipelineDesc, pipeline.writeRef())); @@ -910,7 +903,8 @@ struct ShaderCacheTestGraphicsSplit : ShaderCacheTestGraphics RenderPipelineDesc pipelineDesc = {}; pipelineDesc.program = shaderProgram.get(); pipelineDesc.inputLayout = inputLayout; - pipelineDesc.framebufferLayout = framebufferLayout; + pipelineDesc.framebufferLayout.renderTargets[0] = {format}; + pipelineDesc.framebufferLayout.renderTargetCount = 1; pipelineDesc.depthStencil.depthTestEnable = false; pipelineDesc.depthStencil.depthWriteEnable = false; REQUIRE_CALL(device->createRenderPipeline(pipelineDesc, pipeline.writeRef())); diff --git a/tests/test-texture-types.cpp b/tests/test-texture-types.cpp index b06c2e2b..792075ed 100644 --- a/tests/test-texture-types.cpp +++ b/tests/test-texture-types.cpp @@ -417,16 +417,12 @@ struct RenderTargetTests : BaseTextureViewTest slangReflection )); - FramebufferLayoutDesc framebufferLayoutDesc; - framebufferLayoutDesc.renderTargetCount = 1; - framebufferLayoutDesc.renderTargets[0] = {textureInfo->format, sampleCount}; - ComPtr framebufferLayout = device->createFramebufferLayout(framebufferLayoutDesc); - REQUIRE(framebufferLayout != nullptr); - RenderPipelineDesc pipelineDesc = {}; pipelineDesc.program = shaderProgram.get(); pipelineDesc.inputLayout = inputLayout; - pipelineDesc.framebufferLayout = framebufferLayout; + pipelineDesc.framebufferLayout.renderTargets[0] = {textureInfo->format}; + pipelineDesc.framebufferLayout.renderTargetCount = 1; + pipelineDesc.framebufferLayout.sampleCount = sampleCount; pipelineDesc.depthStencil.depthTestEnable = false; pipelineDesc.depthStencil.depthWriteEnable = false; REQUIRE_CALL(device->createRenderPipeline(pipelineDesc, pipeline.writeRef())); From 030b42460f7f35e61f987123dc47ac92ae64cd66 Mon Sep 17 00:00:00 2001 From: Simon Kallweit Date: Fri, 6 Sep 2024 16:17:53 +0200 Subject: [PATCH 3/8] update metal backend --- src/core/platform.cpp | 1 + src/debug-layer/debug-command-encoder.h | 23 +++--- src/metal/metal-command-buffer.h | 7 +- src/metal/metal-command-encoder.cpp | 100 +++++++++++++++++------- src/metal/metal-command-encoder.h | 8 +- src/metal/metal-device.cpp | 1 - src/metal/metal-device.h | 1 - src/metal/metal-framebuffer.cpp | 52 ------------ src/metal/metal-framebuffer.h | 41 ---------- src/metal/metal-pipeline.cpp | 15 ++-- src/metal/metal-render-pass.cpp | 69 ---------------- src/metal/metal-render-pass.h | 21 ----- src/metal/metal-util.cpp | 28 +++++++ src/metal/metal-util.h | 3 + src/vulkan/vk-render-pass.cpp | 83 -------------------- 15 files changed, 126 insertions(+), 327 deletions(-) delete mode 100644 src/metal/metal-framebuffer.cpp delete mode 100644 src/metal/metal-framebuffer.h delete mode 100644 src/metal/metal-render-pass.cpp delete mode 100644 src/metal/metal-render-pass.h delete mode 100644 src/vulkan/vk-render-pass.cpp diff --git a/src/core/platform.cpp b/src/core/platform.cpp index c419db4a..b1e04ebb 100644 --- a/src/core/platform.cpp +++ b/src/core/platform.cpp @@ -28,6 +28,7 @@ Result loadSharedLibrary(const char* path, SharedLibraryHandle& handleOut) { return SLANG_FAIL; } + return SLANG_OK; #else SLANG_RHI_ASSERT_FAILURE("Not implemented"); #endif diff --git a/src/debug-layer/debug-command-encoder.h b/src/debug-layer/debug-command-encoder.h index 19a2f1f1..0f364db2 100644 --- a/src/debug-layer/debug-command-encoder.h +++ b/src/debug-layer/debug-command-encoder.h @@ -12,7 +12,7 @@ class DebugCommandEncoder : public ICommandEncoder virtual ICommandEncoder* getBaseObject() = 0; virtual void* getInterface(SlangUUID const& uuid) = 0; - Result queryInterface(SlangUUID const& uuid, void** outObject) + Result queryInterface(SlangUUID const& uuid, void** outObject) override { if (auto ptr = getInterface(uuid)) { @@ -21,8 +21,8 @@ class DebugCommandEncoder : public ICommandEncoder } return SLANG_E_NO_INTERFACE; } - uint32_t addRef() { return 2; } - uint32_t release() { return 2; } + uint32_t addRef() override { return 2; } + uint32_t release() override { return 2; } virtual SLANG_NO_THROW void SLANG_MCALL textureBarrier(GfxCount count, ITexture* const* textures, ResourceState src, ResourceState dst) override; @@ -69,9 +69,10 @@ class DebugResourceCommandEncoder : public UnownedDebugObject, public DebugCommandEncoder diff --git a/src/metal/metal-command-buffer.h b/src/metal/metal-command-buffer.h index 8d30a761..f46caeb2 100644 --- a/src/metal/metal-command-buffer.h +++ b/src/metal/metal-command-buffer.h @@ -43,11 +43,8 @@ class CommandBufferImpl : public ICommandBuffer, public ComObject public: virtual SLANG_NO_THROW Result SLANG_MCALL encodeResourceCommands(IResourceCommandEncoder** outEncoder) override; - virtual SLANG_NO_THROW Result SLANG_MCALL encodeRenderCommands( - const RenderPassDesc& desc, - IFramebuffer* framebuffer, - IRenderCommandEncoder** outEncoder - ) override; + virtual SLANG_NO_THROW Result SLANG_MCALL + encodeRenderCommands(const RenderPassDesc& desc, IRenderCommandEncoder** outEncoder) override; virtual SLANG_NO_THROW Result SLANG_MCALL encodeComputeCommands(IComputeCommandEncoder** outEncoder) override; virtual SLANG_NO_THROW Result SLANG_MCALL encodeRayTracingCommands(IRayTracingCommandEncoder** outEncoder) override; virtual SLANG_NO_THROW void SLANG_MCALL close() override; diff --git a/src/metal/metal-command-encoder.cpp b/src/metal/metal-command-encoder.cpp index a575f49b..43ec2410 100644 --- a/src/metal/metal-command-encoder.cpp +++ b/src/metal/metal-command-encoder.cpp @@ -3,7 +3,6 @@ #include "metal-command-buffer.h" #include "metal-helper-functions.h" #include "metal-query.h" -#include "metal-render-pass.h" #include "metal-resource-views.h" #include "metal-shader-object.h" #include "metal-shader-program.h" @@ -221,54 +220,95 @@ void ResourceCommandEncoderImpl::resolveQuery( // RenderCommandEncoderImpl -void RenderCommandEncoderImpl::beginPass(IRenderPassLayout* renderPass, IFramebuffer* framebuffer) +void RenderCommandEncoderImpl::beginPass(const RenderPassDesc& desc) { - m_renderPassLayout = static_cast(renderPass); - m_framebuffer = static_cast(framebuffer); - if (!m_framebuffer) - { - // TODO use empty framebuffer - return; - } - - // Create a copy of the render pass descriptor and fill in remaining information. - m_renderPassDesc = NS::TransferPtr(m_renderPassLayout->m_renderPassDesc->copy()); + uint32_t width = 1; + uint32_t height = 1; - m_renderPassDesc->setRenderTargetWidth(m_framebuffer->m_width); - m_renderPassDesc->setRenderTargetHeight(m_framebuffer->m_height); - - for (Index i = 0; i < m_framebuffer->m_renderTargetViews.size(); ++i) + auto visitView = [&](TextureViewImpl* view) + { + const TextureDesc* textureDesc = view->m_texture->getDesc(); + const IResourceView::Desc* viewDesc = view->getViewDesc(); + width = std::max(1u, uint32_t(textureDesc->size.width >> viewDesc->subresourceRange.mipLevel)); + height = std::max(1u, uint32_t(textureDesc->size.height >> viewDesc->subresourceRange.mipLevel)); + }; + + // Initialize render pass descriptor. + m_renderPassDesc = NS::TransferPtr(MTL::RenderPassDescriptor::alloc()->init()); + + // Setup color attachments. + m_renderTargetViews.resize(desc.colorAttachmentCount); + m_renderPassDesc->setRenderTargetArrayLength(desc.colorAttachmentCount); + for (GfxIndex i = 0; i < desc.colorAttachmentCount; ++i) { - TextureViewImpl* renderTargetView = m_framebuffer->m_renderTargetViews[i]; + const auto& attachment = desc.colorAttachments[i]; + TextureViewImpl* view = static_cast(attachment.view); + visitView(view); + m_renderTargetViews[i] = view; + MTL::RenderPassColorAttachmentDescriptor* colorAttachment = m_renderPassDesc->colorAttachments()->object(i); - colorAttachment->setTexture(renderTargetView->m_textureView.get()); - colorAttachment->setLevel(renderTargetView->m_desc.subresourceRange.mipLevel); - colorAttachment->setSlice(renderTargetView->m_desc.subresourceRange.baseArrayLayer); + colorAttachment->setLoadAction(MetalUtil::translateLoadOp(attachment.loadOp)); + colorAttachment->setStoreAction(MetalUtil::translateStoreOp(attachment.storeOp)); + if (attachment.loadOp == TargetLoadOp::Clear) + { + colorAttachment->setClearColor(MTL::ClearColor( + attachment.clearValue[0], + attachment.clearValue[1], + attachment.clearValue[2], + attachment.clearValue[3] + )); + } + colorAttachment->setTexture(view->m_textureView.get()); + colorAttachment->setLevel(view->m_desc.subresourceRange.mipLevel); + colorAttachment->setSlice(view->m_desc.subresourceRange.baseArrayLayer); } - if (m_framebuffer->m_depthStencilView) + // Setup depth stencil attachment. + if (desc.depthStencilAttachment.view) { - TextureViewImpl* depthStencilView = m_framebuffer->m_depthStencilView.get(); - MTL::PixelFormat pixelFormat = MetalUtil::translatePixelFormat(depthStencilView->m_desc.format); + const auto& attachment = desc.depthStencilAttachment; + TextureViewImpl* view = static_cast(attachment.view); + visitView(view); + m_depthStencilView = view; + MTL::PixelFormat pixelFormat = MetalUtil::translatePixelFormat(view->m_desc.format); + if (MetalUtil::isDepthFormat(pixelFormat)) { MTL::RenderPassDepthAttachmentDescriptor* depthAttachment = m_renderPassDesc->depthAttachment(); - depthAttachment->setTexture(depthStencilView->m_textureView.get()); - depthAttachment->setLevel(depthStencilView->m_desc.subresourceRange.mipLevel); - depthAttachment->setSlice(depthStencilView->m_desc.subresourceRange.baseArrayLayer); + depthAttachment->setLoadAction(MetalUtil::translateLoadOp(attachment.depthLoadOp)); + depthAttachment->setStoreAction(MetalUtil::translateStoreOp(attachment.depthStoreOp)); + if (attachment.depthLoadOp == TargetLoadOp::Clear) + { + depthAttachment->setClearDepth(attachment.depthClearValue); + } + depthAttachment->setTexture(view->m_textureView.get()); + depthAttachment->setLevel(view->m_desc.subresourceRange.mipLevel); + depthAttachment->setSlice(view->m_desc.subresourceRange.baseArrayLayer); } if (MetalUtil::isStencilFormat(pixelFormat)) { MTL::RenderPassStencilAttachmentDescriptor* stencilAttachment = m_renderPassDesc->stencilAttachment(); - stencilAttachment->setTexture(depthStencilView->m_textureView.get()); - stencilAttachment->setLevel(depthStencilView->m_desc.subresourceRange.mipLevel); - stencilAttachment->setSlice(depthStencilView->m_desc.subresourceRange.baseArrayLayer); + stencilAttachment->setLoadAction(MetalUtil::translateLoadOp(attachment.stencilLoadOp)); + stencilAttachment->setStoreAction(MetalUtil::translateStoreOp(attachment.stencilStoreOp)); + if (attachment.stencilLoadOp == TargetLoadOp::Clear) + { + stencilAttachment->setClearStencil(attachment.stencilClearValue); + } + stencilAttachment->setTexture(view->m_textureView.get()); + stencilAttachment->setLevel(view->m_desc.subresourceRange.mipLevel); + stencilAttachment->setSlice(view->m_desc.subresourceRange.baseArrayLayer); } } + + m_renderPassDesc->setRenderTargetWidth(width); + m_renderPassDesc->setRenderTargetHeight(height); } void RenderCommandEncoderImpl::endEncoding() { + m_renderTargetViews.clear(); + m_depthStencilView = nullptr; + CommandEncoderImpl::endEncodingImpl(); } @@ -403,7 +443,7 @@ Result RenderCommandEncoderImpl::prepareDraw(MTL::RenderCommandEncoder*& encoder encoder->setDepthBias(rasterDesc.depthBias, rasterDesc.slopeScaledDepthBias, rasterDesc.depthBiasClamp); encoder->setTriangleFillMode(MetalUtil::translateTriangleFillMode(rasterDesc.fillMode)); // encoder->setBlendColor(); // not supported by rhi - if (m_framebuffer->m_depthStencilView) + if (m_depthStencilView) { encoder->setDepthStencilState(pipeline->m_depthStencilState.get()); } diff --git a/src/metal/metal-command-encoder.h b/src/metal/metal-command-encoder.h index 9ebc6748..7886520d 100644 --- a/src/metal/metal-command-encoder.h +++ b/src/metal/metal-command-encoder.h @@ -2,9 +2,9 @@ #include "metal-base.h" #include "metal-pipeline.h" -#include "metal-render-pass.h" #include "core/short_vector.h" +#include "core/static_vector.h" namespace rhi::metal { @@ -148,9 +148,9 @@ class RenderCommandEncoderImpl : public IRenderCommandEncoder, public CommandEnc } public: - RefPtr m_renderPassLayout; - RefPtr m_framebuffer; NS::SharedPtr m_renderPassDesc; + static_vector, kMaxRenderTargetCount> m_renderTargetViews; + RefPtr m_depthStencilView; short_vector m_viewports; short_vector m_scissorRects; @@ -166,7 +166,7 @@ class RenderCommandEncoderImpl : public IRenderCommandEncoder, public CommandEnc uint32_t m_stencilReferenceValue = 0; public: - void beginPass(IRenderPassLayout* renderPass, IFramebuffer* framebuffer); + void beginPass(const RenderPassDesc& desc); virtual SLANG_NO_THROW void SLANG_MCALL endEncoding() override; diff --git a/src/metal/metal-device.cpp b/src/metal/metal-device.cpp index fd15fa42..ad7adffc 100644 --- a/src/metal/metal-device.cpp +++ b/src/metal/metal-device.cpp @@ -1,7 +1,6 @@ #include "metal-device.h" #include "../resource-desc-utils.h" #include "metal-buffer.h" -#include "metal-render-pass.h" #include "metal-shader-program.h" #include "metal-swap-chain.h" #include "metal-texture.h" diff --git a/src/metal/metal-device.h b/src/metal/metal-device.h index 98627044..4fa67ea6 100644 --- a/src/metal/metal-device.h +++ b/src/metal/metal-device.h @@ -3,7 +3,6 @@ #include "../simple-transient-resource-heap.h" #include "metal-base.h" #include "metal-device.h" -#include "metal-framebuffer.h" #include "core/stable_vector.h" diff --git a/src/metal/metal-framebuffer.cpp b/src/metal/metal-framebuffer.cpp deleted file mode 100644 index fa96520c..00000000 --- a/src/metal/metal-framebuffer.cpp +++ /dev/null @@ -1,52 +0,0 @@ -#include "metal-framebuffer.h" -#include "metal-device.h" -#include "metal-helper-functions.h" -#include "metal-resource-views.h" - -namespace rhi::metal { - -Result FramebufferLayoutImpl::init(const FramebufferLayoutDesc& desc) -{ - m_desc = desc; - return SLANG_OK; -} - -Result FramebufferImpl::init(DeviceImpl* device, const IFramebuffer::Desc& desc) -{ - m_device = device; - m_layout = static_cast(desc.layout); - m_renderTargetViews.resize(desc.renderTargetCount); - for (Index i = 0; i < desc.renderTargetCount; ++i) - { - m_renderTargetViews[i] = static_cast(desc.renderTargetViews[i]); - } - m_depthStencilView = static_cast(desc.depthStencilView); - - // Determine framebuffer dimensions & sample count; - m_width = 1; - m_height = 1; - m_sampleCount = 1; - - auto visitView = [this](TextureViewImpl* view) - { - const TextureDesc* textureDesc = view->m_texture->getDesc(); - const IResourceView::Desc* viewDesc = view->getViewDesc(); - m_width = std::max(1u, uint32_t(textureDesc->size.width >> viewDesc->subresourceRange.mipLevel)); - m_height = std::max(1u, uint32_t(textureDesc->size.height >> viewDesc->subresourceRange.mipLevel)); - m_sampleCount = std::max(m_sampleCount, uint32_t(textureDesc->sampleCount)); - return SLANG_OK; - }; - - for (auto view : m_renderTargetViews) - { - visitView(view); - } - if (m_depthStencilView) - { - visitView(m_depthStencilView); - } - - return SLANG_OK; -} - -} // namespace rhi::metal diff --git a/src/metal/metal-framebuffer.h b/src/metal/metal-framebuffer.h deleted file mode 100644 index fc779c89..00000000 --- a/src/metal/metal-framebuffer.h +++ /dev/null @@ -1,41 +0,0 @@ -#pragma once - -#include "metal-base.h" - -#include "core/short_vector.h" - -#include - -namespace rhi::metal { - -enum -{ - kMaxRenderTargets = 8, - kMaxTargets = kMaxRenderTargets + 1, -}; - -class FramebufferLayoutImpl : public FramebufferLayoutBase -{ -public: - FramebufferLayoutDesc m_desc; - -public: - Result init(const FramebufferLayoutDesc& desc); -}; - -class FramebufferImpl : public FramebufferBase -{ -public: - BreakableReference m_device; - RefPtr m_layout; - short_vector> m_renderTargetViews; - RefPtr m_depthStencilView; - uint32_t m_width; - uint32_t m_height; - uint32_t m_sampleCount; - -public: - Result init(DeviceImpl* device, const IFramebuffer::Desc& desc); -}; - -} // namespace rhi::metal diff --git a/src/metal/metal-pipeline.cpp b/src/metal/metal-pipeline.cpp index 42656db4..3ab16987 100644 --- a/src/metal/metal-pipeline.cpp +++ b/src/metal/metal-pipeline.cpp @@ -77,17 +77,16 @@ Result PipelineImpl::createMetalRenderPipelineState() pd->setInputPrimitiveTopology(MetalUtil::translatePrimitiveTopologyClass(desc.graphics.primitiveType)); // Set rasterization state - auto framebufferLayoutImpl = static_cast(desc.graphics.framebufferLayout); + const auto& framebufferLayout = desc.graphics.framebufferLayout; const auto& blend = desc.graphics.blend; - GfxCount sampleCount = 1; pd->setAlphaToCoverageEnabled(blend.alphaToCoverageEnable); // pd->setAlphaToOneEnabled(); // Currently not supported by rhi // pd->setRasterizationEnabled(true); // Enabled by default - for (Index i = 0; i < framebufferLayoutImpl->m_desc.renderTargetCount; ++i) + for (Index i = 0; i < framebufferLayout.renderTargetCount; ++i) { - const TargetLayoutDesc& targetLayout = framebufferLayoutImpl->m_desc.renderTargets[i]; + const TargetLayoutDesc& targetLayout = framebufferLayout.renderTargets[i]; MTL::RenderPipelineColorAttachmentDescriptor* colorAttachment = pd->colorAttachments()->object(i); colorAttachment->setPixelFormat(MetalUtil::translatePixelFormat(targetLayout.format)); @@ -101,12 +100,10 @@ Result PipelineImpl::createMetalRenderPipelineState() ); colorAttachment->setAlphaBlendOperation(MetalUtil::translateBlendOperation(targetBlendDesc.alpha.op)); colorAttachment->setWriteMask(MetalUtil::translateColorWriteMask(targetBlendDesc.writeMask)); - - sampleCount = std::max(sampleCount, targetLayout.sampleCount); } - if (framebufferLayoutImpl->m_desc.depthStencil.format != Format::Unknown) + if (framebufferLayout.depthStencil.format != Format::Unknown) { - const TargetLayoutDesc& depthStencil = framebufferLayoutImpl->m_desc.depthStencil; + const TargetLayoutDesc& depthStencil = framebufferLayout.depthStencil; MTL::PixelFormat pixelFormat = MetalUtil::translatePixelFormat(depthStencil.format); if (MetalUtil::isDepthFormat(pixelFormat)) { @@ -118,7 +115,7 @@ Result PipelineImpl::createMetalRenderPipelineState() } } - pd->setRasterSampleCount(sampleCount); + pd->setRasterSampleCount(framebufferLayout.sampleCount); NS::Error* error; m_renderPipelineState = NS::TransferPtr(m_device->m_device->newRenderPipelineState(pd.get(), &error)); diff --git a/src/metal/metal-render-pass.cpp b/src/metal/metal-render-pass.cpp deleted file mode 100644 index 512ba08a..00000000 --- a/src/metal/metal-render-pass.cpp +++ /dev/null @@ -1,69 +0,0 @@ -#include "metal-render-pass.h" - -namespace rhi::metal { - -IRenderPassLayout* RenderPassLayoutImpl::getInterface(const Guid& guid) -{ - if (guid == GUID::IID_ISlangUnknown || guid == GUID::IID_IRenderPassLayout) - return static_cast(this); - return nullptr; -} - -static inline MTL::LoadAction translateLoadOp(IRenderPassLayout::TargetLoadOp loadOp) -{ - switch (loadOp) - { - case IRenderPassLayout::TargetLoadOp::Load: - return MTL::LoadActionLoad; - case IRenderPassLayout::TargetLoadOp::Clear: - return MTL::LoadActionClear; - case IRenderPassLayout::TargetLoadOp::DontCare: - return MTL::LoadActionDontCare; - default: - return MTL::LoadAction(0); - } -} - -static inline MTL::StoreAction translateStoreOp(IRenderPassLayout::TargetStoreOp storeOp) -{ - switch (storeOp) - { - case IRenderPassLayout::TargetStoreOp::Store: - return MTL::StoreActionStore; - case IRenderPassLayout::TargetStoreOp::DontCare: - return MTL::StoreActionDontCare; - default: - return MTL::StoreAction(0); - } -} - -Result RenderPassLayoutImpl::init(DeviceImpl* device, const IRenderPassLayout::Desc& desc) -{ - m_device = device; - - FramebufferLayoutImpl* framebufferLayout = static_cast(desc.framebufferLayout); - SLANG_RHI_ASSERT(framebufferLayout); - - // Initialize render pass descriptor, filling in attachment metadata, but leaving texture data unbound. - m_renderPassDesc = NS::TransferPtr(MTL::RenderPassDescriptor::alloc()->init()); - - m_renderPassDesc->setRenderTargetArrayLength(desc.renderTargetCount); - for (GfxIndex i = 0; i < desc.renderTargetCount; ++i) - { - MTL::RenderPassColorAttachmentDescriptor* colorAttachment = m_renderPassDesc->colorAttachments()->object(i); - colorAttachment->setLoadAction(translateLoadOp(desc.renderTargetAccess[i].loadOp)); - colorAttachment->setStoreAction(translateStoreOp(desc.renderTargetAccess[i].storeOp)); - } - - if (desc.depthStencilAccess) - { - m_renderPassDesc->depthAttachment()->setLoadAction(translateLoadOp(desc.depthStencilAccess->loadOp)); - m_renderPassDesc->depthAttachment()->setStoreAction(translateStoreOp(desc.depthStencilAccess->storeOp)); - m_renderPassDesc->stencilAttachment()->setLoadAction(translateLoadOp(desc.depthStencilAccess->loadOp)); - m_renderPassDesc->stencilAttachment()->setStoreAction(translateStoreOp(desc.depthStencilAccess->storeOp)); - } - - return SLANG_OK; -} - -} // namespace rhi::metal diff --git a/src/metal/metal-render-pass.h b/src/metal/metal-render-pass.h deleted file mode 100644 index 1c162bfd..00000000 --- a/src/metal/metal-render-pass.h +++ /dev/null @@ -1,21 +0,0 @@ -#pragma once - -#include "metal-base.h" -#include "metal-device.h" - -namespace rhi::metal { - -class RenderPassLayoutImpl : public IRenderPassLayout, public ComObject -{ -public: - SLANG_COM_OBJECT_IUNKNOWN_ALL - IRenderPassLayout* getInterface(const Guid& guid); - -public: - RefPtr m_device; - NS::SharedPtr m_renderPassDesc; - - Result init(DeviceImpl* device, const IRenderPassLayout::Desc& desc); -}; - -} // namespace rhi::metal diff --git a/src/metal/metal-util.cpp b/src/metal/metal-util.cpp index e362e6e2..7adeaa05 100644 --- a/src/metal/metal-util.cpp +++ b/src/metal/metal-util.cpp @@ -590,4 +590,32 @@ MTL::TriangleFillMode MetalUtil::translateTriangleFillMode(FillMode mode) } } +MTL::LoadAction MetalUtil::translateLoadOp(TargetLoadOp loadOp) +{ + switch (loadOp) + { + case TargetLoadOp::Load: + return MTL::LoadActionLoad; + case TargetLoadOp::Clear: + return MTL::LoadActionClear; + case TargetLoadOp::DontCare: + return MTL::LoadActionDontCare; + default: + return MTL::LoadAction(0); + } +} + +MTL::StoreAction MetalUtil::translateStoreOp(TargetStoreOp storeOp) +{ + switch (storeOp) + { + case TargetStoreOp::Store: + return MTL::StoreActionStore; + case TargetStoreOp::DontCare: + return MTL::StoreActionDontCare; + default: + return MTL::StoreAction(0); + } +} + } // namespace rhi::metal diff --git a/src/metal/metal-util.h b/src/metal/metal-util.h index a11a0bf1..a3a2ba83 100644 --- a/src/metal/metal-util.h +++ b/src/metal/metal-util.h @@ -50,6 +50,9 @@ struct MetalUtil static MTL::Winding translateWinding(FrontFaceMode mode); static MTL::CullMode translateCullMode(CullMode mode); static MTL::TriangleFillMode translateTriangleFillMode(FillMode mode); + + static MTL::LoadAction translateLoadOp(TargetLoadOp loadOp); + static MTL::StoreAction translateStoreOp(TargetStoreOp storeOp); }; struct ScopedAutoreleasePool diff --git a/src/vulkan/vk-render-pass.cpp b/src/vulkan/vk-render-pass.cpp deleted file mode 100644 index a6f3a7e0..00000000 --- a/src/vulkan/vk-render-pass.cpp +++ /dev/null @@ -1,83 +0,0 @@ -#if 0 -#include "vk-render-pass.h" -#include "vk-helper-functions.h" - -#include "core/static_vector.h" - -namespace rhi::vk { - -IRenderPassLayout* RenderPassLayoutImpl::getInterface(const Guid& guid) -{ - if (guid == GUID::IID_ISlangUnknown || guid == GUID::IID_IRenderPassLayout) - return static_cast(this); - return nullptr; -} - -RenderPassLayoutImpl::~RenderPassLayoutImpl() -{ - m_renderer->m_api.vkDestroyRenderPass(m_renderer->m_api.m_device, m_renderPass, nullptr); -} - -Result RenderPassLayoutImpl::init(DeviceImpl* renderer, const IRenderPassLayout::Desc& desc) -{ - m_renderer = renderer; - - // Create render pass using load/storeOp and layouts info from `desc`. - auto framebufferLayout = static_cast(desc.framebufferLayout); - SLANG_RHI_ASSERT(desc.renderTargetCount == framebufferLayout->m_renderTargetCount); - - // We need extra space if we have depth buffer - static_vector targetDescs; - targetDescs = framebufferLayout->m_targetDescs; - for (GfxIndex i = 0; i < desc.renderTargetCount; ++i) - { - VkAttachmentDescription& dst = targetDescs[i]; - auto access = desc.renderTargetAccess[i]; - // Fill in loadOp/storeOp and layout from desc. - dst.loadOp = translateLoadOp(access.loadOp); - dst.storeOp = translateStoreOp(access.storeOp); - dst.stencilLoadOp = translateLoadOp(access.stencilLoadOp); - dst.stencilStoreOp = translateStoreOp(access.stencilStoreOp); - dst.initialLayout = VulkanUtil::mapResourceStateToLayout(access.initialState); - dst.finalLayout = VulkanUtil::mapResourceStateToLayout(access.finalState); - } - - if (framebufferLayout->m_hasDepthStencilTarget) - { - VkAttachmentDescription& dst = targetDescs[desc.renderTargetCount]; - auto access = *desc.depthStencilAccess; - dst.loadOp = translateLoadOp(access.loadOp); - dst.storeOp = translateStoreOp(access.storeOp); - dst.stencilLoadOp = translateLoadOp(access.stencilLoadOp); - dst.stencilStoreOp = translateStoreOp(access.stencilStoreOp); - dst.initialLayout = VulkanUtil::mapResourceStateToLayout(access.initialState); - dst.finalLayout = VulkanUtil::mapResourceStateToLayout(access.finalState); - } - - VkSubpassDescription subpassDesc = {}; - subpassDesc.flags = 0; - subpassDesc.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; - subpassDesc.inputAttachmentCount = 0u; - subpassDesc.pInputAttachments = nullptr; - subpassDesc.colorAttachmentCount = desc.renderTargetCount; - subpassDesc.pColorAttachments = framebufferLayout->m_colorReferences.data(); - subpassDesc.pResolveAttachments = nullptr; - subpassDesc.pDepthStencilAttachment = - framebufferLayout->m_hasDepthStencilTarget ? &framebufferLayout->m_depthReference : nullptr; - subpassDesc.preserveAttachmentCount = 0u; - subpassDesc.pPreserveAttachments = nullptr; - - VkRenderPassCreateInfo renderPassCreateInfo = {}; - renderPassCreateInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; - renderPassCreateInfo.attachmentCount = (uint32_t)targetDescs.size(); - renderPassCreateInfo.pAttachments = targetDescs.data(); - renderPassCreateInfo.subpassCount = 1; - renderPassCreateInfo.pSubpasses = &subpassDesc; - SLANG_VK_RETURN_ON_FAIL( - m_renderer->m_api.vkCreateRenderPass(m_renderer->m_api.m_device, &renderPassCreateInfo, nullptr, &m_renderPass) - ); - return SLANG_OK; -} - -} // namespace rhi::vk -#endif From 48ff4efff9fa09ea1751d39bc3dae3006aba57aa Mon Sep 17 00:00:00 2001 From: Simon Kallweit Date: Fri, 6 Sep 2024 16:49:14 +0200 Subject: [PATCH 4/8] cleanup --- src/vulkan/vk-base.h | 1 - src/vulkan/vk-command-encoder.cpp | 19 ------------------- 2 files changed, 20 deletions(-) diff --git a/src/vulkan/vk-base.h b/src/vulkan/vk-base.h index 626ad3ef..9e33af78 100644 --- a/src/vulkan/vk-base.h +++ b/src/vulkan/vk-base.h @@ -23,7 +23,6 @@ class TextureViewImpl; class TexelBufferViewImpl; class PlainBufferViewImpl; class AccelerationStructureImpl; -class RenderPassLayoutImpl; class PipelineImpl; class RayTracingPipelineImpl; class ShaderObjectLayoutImpl; diff --git a/src/vulkan/vk-command-encoder.cpp b/src/vulkan/vk-command-encoder.cpp index 4307c226..8ebd0b14 100644 --- a/src/vulkan/vk-command-encoder.cpp +++ b/src/vulkan/vk-command-encoder.cpp @@ -949,25 +949,6 @@ void ResourceCommandEncoderImpl::copyTextureToBuffer( void RenderCommandEncoderImpl::beginPass(const RenderPassDesc& desc) { -#if 0 - FramebufferImpl* framebufferImpl = static_cast(framebuffer); - if (!framebuffer) - framebufferImpl = this->m_device->m_emptyFramebuffer; - RenderPassLayoutImpl* renderPassImpl = static_cast(renderPass); - VkClearValue clearValues[kMaxTargets] = {}; - VkRenderPassBeginInfo beginInfo = {}; - beginInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; - beginInfo.framebuffer = framebufferImpl->m_handle; - beginInfo.renderPass = renderPassImpl->m_renderPass; - uint32_t targetCount = (uint32_t)framebufferImpl->renderTargetViews.size(); - if (framebufferImpl->depthStencilView) - targetCount++; - beginInfo.clearValueCount = targetCount; - beginInfo.renderArea.extent.width = framebufferImpl->m_width; - beginInfo.renderArea.extent.height = framebufferImpl->m_height; - beginInfo.pClearValues = framebufferImpl->m_clearValues; - api.vkCmdBeginRenderPass(m_vkCommandBuffer, &beginInfo, VK_SUBPASS_CONTENTS_INLINE); -#endif auto& api = *m_api; m_renderTargetViews.resize(desc.colorAttachmentCount); From 4a3f535bd2bd3885253bef9abb108c87b6d9d728 Mon Sep 17 00:00:00 2001 From: Simon Kallweit Date: Fri, 6 Sep 2024 17:37:45 +0200 Subject: [PATCH 5/8] refactor render pass descriptor --- include/slang-rhi.h | 40 +++---- src/command-writer.h | 22 +++- src/d3d11/d3d11-device.cpp | 14 +-- src/d3d12/d3d12-command-encoder.cpp | 17 +-- src/debug-layer/debug-command-buffer.cpp | 14 ++- src/immediate-renderer-base.cpp | 14 ++- src/metal/metal-command-encoder.cpp | 6 +- src/metal/metal-util.cpp | 14 +-- src/metal/metal-util.h | 4 +- src/vulkan/vk-command-buffer.cpp | 2 +- src/vulkan/vk-command-encoder.cpp | 132 +++++++++++------------ src/vulkan/vk-command-encoder.h | 3 +- src/vulkan/vk-helper-functions.cpp | 10 +- src/vulkan/vk-helper-functions.h | 4 +- tests/test-instanced-draw.cpp | 48 +++++---- tests/test-resolve-resource-tests.cpp | 12 ++- tests/test-shader-cache.cpp | 12 ++- tests/test-swapchain.cpp | 4 +- tests/test-texture-types.cpp | 12 ++- tests/testing.cpp | 1 - 20 files changed, 217 insertions(+), 168 deletions(-) diff --git a/include/slang-rhi.h b/include/slang-rhi.h index 317165cd..e03d02d2 100644 --- a/include/slang-rhi.h +++ b/include/slang-rhi.h @@ -1335,47 +1335,51 @@ struct FaceMask }; }; -enum class TargetLoadOp +enum class LoadOp { Load, Clear, DontCare }; -enum class TargetStoreOp +enum class StoreOp { Store, DontCare }; -struct RenderAttachmentDesc +struct RenderPassColorAttachment { - float clearValue[4] = {0.0f, 0.0f, 0.0f, 0.0f}; - TargetLoadOp loadOp = TargetLoadOp::DontCare; - TargetStoreOp storeOp = TargetStoreOp::Store; IResourceView* view = nullptr; - ResourceState initialState; - ResourceState finalState; + LoadOp loadOp = LoadOp::DontCare; + StoreOp storeOp = StoreOp::Store; + float clearValue[4] = {0.0f, 0.0f, 0.0f, 0.0f}; + // TODO: remove with automatic resource tracking + ResourceState initialState = ResourceState::Undefined; + ResourceState finalState = ResourceState::Undefined; }; -struct DepthStencilAttachmentDesc +struct RenderPassDepthStencilAttachment { + IResourceView* view = nullptr; + LoadOp depthLoadOp = LoadOp::DontCare; + StoreOp depthStoreOp = StoreOp::Store; float depthClearValue = 1.f; - TargetLoadOp depthLoadOp = TargetLoadOp::DontCare; - TargetStoreOp depthStoreOp = TargetStoreOp::Store; + bool depthReadOnly = false; + LoadOp stencilLoadOp = LoadOp::DontCare; + StoreOp stencilStoreOp = StoreOp::DontCare; uint8_t stencilClearValue = 0; - TargetLoadOp stencilLoadOp = TargetLoadOp::DontCare; - TargetStoreOp stencilStoreOp = TargetStoreOp::DontCare; - IResourceView* view = nullptr; - ResourceState initialState; - ResourceState finalState; + bool stencilReadOnly = false; + // TODO: remove with automatic resource tracking + ResourceState initialState = ResourceState::Undefined; + ResourceState finalState = ResourceState::Undefined; }; struct RenderPassDesc { - RenderAttachmentDesc colorAttachments[kMaxRenderTargetCount]; + RenderPassColorAttachment* colorAttachments = nullptr; GfxCount colorAttachmentCount = 0; - DepthStencilAttachmentDesc depthStencilAttachment; + RenderPassDepthStencilAttachment* depthStencilAttachment = nullptr; }; enum class QueryType diff --git a/src/command-writer.h b/src/command-writer.h index ec49128f..ce273d82 100644 --- a/src/command-writer.h +++ b/src/command-writer.h @@ -168,21 +168,33 @@ class CommandWriter void beginRenderPass(const RenderPassDesc& desc) { - auto dataOffset = encodeData(&desc, sizeof(RenderPassDesc)); + Offset colorAttachmentsOffset = + encodeData(desc.colorAttachments, sizeof(RenderPassColorAttachment) * desc.colorAttachmentCount); + Offset depthStencilAttachmentOffset = encodeData( + desc.depthStencilAttachment, + desc.depthStencilAttachment ? sizeof(RenderPassDepthStencilAttachment) : 0 + ); Offset viewsOffset = 0; for (uint32_t i = 0; i < desc.colorAttachmentCount; i++) { - auto offset = encodeObject(static_cast(desc.colorAttachments[0].view)); + auto offset = encodeObject(static_cast(desc.colorAttachments[i].view)); if (i == 0) viewsOffset = offset; } - if (desc.depthStencilAttachment.view) + if (desc.depthStencilAttachment) { - auto offset = encodeObject(static_cast(desc.depthStencilAttachment.view)); + auto offset = encodeObject(static_cast(desc.depthStencilAttachment->view)); if (desc.colorAttachmentCount == 0) viewsOffset = offset; } - m_commands.push_back(Command(CommandName::BeginRenderPass, (uint32_t)dataOffset, (uint32_t)viewsOffset)); + m_commands.push_back(Command( + CommandName::BeginRenderPass, + (uint32_t)desc.colorAttachmentCount, + (uint32_t)(desc.depthStencilAttachment ? 1 : 0), + (uint32_t)colorAttachmentsOffset, + (uint32_t)depthStencilAttachmentOffset, + (uint32_t)viewsOffset + )); } void endRenderPass() { m_commands.push_back(Command(CommandName::EndRenderPass)); } diff --git a/src/d3d11/d3d11-device.cpp b/src/d3d11/d3d11-device.cpp index 1742a4e3..60e472c9 100644 --- a/src/d3d11/d3d11-device.cpp +++ b/src/d3d11/d3d11-device.cpp @@ -351,15 +351,15 @@ void DeviceImpl::beginRenderPass(const RenderPassDesc& desc) { m_d3dRenderTargetViews[i] = static_cast(desc.colorAttachments[i].view)->m_rtv; } - m_d3dDepthStencilView = desc.depthStencilAttachment.view - ? static_cast(desc.depthStencilAttachment.view)->m_dsv + m_d3dDepthStencilView = desc.depthStencilAttachment + ? static_cast(desc.depthStencilAttachment->view)->m_dsv : nullptr; // Clear color attachments. for (Index i = 0; i < desc.colorAttachmentCount; ++i) { const auto& attachment = desc.colorAttachments[i]; - if (attachment.loadOp == TargetLoadOp::Clear) + if (attachment.loadOp == LoadOp::Clear) { m_immediateContext->ClearRenderTargetView( static_cast(attachment.view)->m_rtv, @@ -368,15 +368,15 @@ void DeviceImpl::beginRenderPass(const RenderPassDesc& desc) } } // Clear depth/stencil attachment. - if (desc.depthStencilAttachment.view) + if (desc.depthStencilAttachment) { - const auto& attachment = desc.depthStencilAttachment; + const auto& attachment = *desc.depthStencilAttachment; UINT clearFlags = 0; - if (attachment.depthLoadOp == TargetLoadOp::Clear) + if (attachment.depthLoadOp == LoadOp::Clear) { clearFlags |= D3D11_CLEAR_DEPTH; } - if (attachment.stencilLoadOp == TargetLoadOp::Clear) + if (attachment.stencilLoadOp == LoadOp::Clear) { clearFlags |= D3D11_CLEAR_STENCIL; } diff --git a/src/d3d12/d3d12-command-encoder.cpp b/src/d3d12/d3d12-command-encoder.cpp index 26c8a9b0..48db2a46 100644 --- a/src/d3d12/d3d12-command-encoder.cpp +++ b/src/d3d12/d3d12-command-encoder.cpp @@ -811,8 +811,11 @@ void RenderCommandEncoderImpl::init( m_renderTargetFinalStates[i] = desc.colorAttachments[i].finalState; renderTargetDescriptors.push_back(m_renderTargetViews[i]->m_descriptor.cpuHandle); } - m_depthStencilView = static_cast(desc.depthStencilAttachment.view); - m_depthStencilFinalState = desc.depthStencilAttachment.finalState; + if (desc.depthStencilAttachment) + { + m_depthStencilView = static_cast(desc.depthStencilAttachment->view); + m_depthStencilFinalState = desc.depthStencilAttachment->finalState; + } m_d3dCmdList->OMSetRenderTargets( (UINT)m_renderTargetViews.size(), @@ -849,15 +852,15 @@ void RenderCommandEncoderImpl::init( } } // Clear. - if (attachment.loadOp == TargetLoadOp::Clear) + if (attachment.loadOp == LoadOp::Clear) { m_d3dCmdList->ClearRenderTargetView(renderTargetDescriptors[i], attachment.clearValue, 0, nullptr); } } - if (m_depthStencilView) + if (desc.depthStencilAttachment) { - const auto& attachment = desc.depthStencilAttachment; + const auto& attachment = *desc.depthStencilAttachment; // Transit resource states. { @@ -876,11 +879,11 @@ void RenderCommandEncoderImpl::init( } // Clear. uint32_t clearFlags = 0; - if (attachment.depthLoadOp == TargetLoadOp::Clear) + if (attachment.depthLoadOp == LoadOp::Clear) { clearFlags |= D3D12_CLEAR_FLAG_DEPTH; } - if (attachment.stencilLoadOp == TargetLoadOp::Clear) + if (attachment.stencilLoadOp == LoadOp::Clear) { clearFlags |= D3D12_CLEAR_FLAG_STENCIL; } diff --git a/src/debug-layer/debug-command-buffer.cpp b/src/debug-layer/debug-command-buffer.cpp index 88b76326..50b72a81 100644 --- a/src/debug-layer/debug-command-buffer.cpp +++ b/src/debug-layer/debug-command-buffer.cpp @@ -38,13 +38,19 @@ Result DebugCommandBuffer::encodeRenderCommands(const RenderPassDesc& desc, IRen checkCommandBufferOpenWhenCreatingEncoder(); checkEncodersClosedBeforeNewEncoder(); RenderPassDesc innerDesc = desc; - for (Index i = 0; i < innerDesc.colorAttachmentCount; ++i) + short_vector innerColorAttachments; + for (Index i = 0; i < desc.colorAttachmentCount; ++i) { - innerDesc.colorAttachments[i].view = getInnerObj(desc.colorAttachments[i].view); + innerColorAttachments.push_back(desc.colorAttachments[i]); + innerColorAttachments[i].view = getInnerObj(desc.colorAttachments[i].view); } - if (innerDesc.depthStencilAttachment.view) + innerDesc.colorAttachments = innerColorAttachments.data(); + RenderPassDepthStencilAttachment innerDepthStencilAttachment; + if (desc.depthStencilAttachment) { - innerDesc.depthStencilAttachment.view = getInnerObj(desc.depthStencilAttachment.view); + innerDepthStencilAttachment = *desc.depthStencilAttachment; + innerDepthStencilAttachment.view = getInnerObj(desc.depthStencilAttachment->view); + innerDesc.depthStencilAttachment = &innerDepthStencilAttachment; } m_renderCommandEncoder.isOpen = true; SLANG_RETURN_ON_FAIL(baseObject->encodeRenderCommands(innerDesc, &m_renderCommandEncoder.baseObject)); diff --git a/src/immediate-renderer-base.cpp b/src/immediate-renderer-base.cpp index c897f4fd..46768d9d 100644 --- a/src/immediate-renderer-base.cpp +++ b/src/immediate-renderer-base.cpp @@ -533,8 +533,20 @@ class CommandBufferImpl : public ICommandBuffer, public ComObject m_renderer->bindRootShaderObject(m_writer.getObject(cmd.operands[0])); break; case CommandName::BeginRenderPass: - m_renderer->beginRenderPass(*m_writer.getData(cmd.operands[0])); + { + RenderPassDesc desc; + if (cmd.operands[0] > 0) + { + desc.colorAttachments = m_writer.getData(cmd.operands[2]); + desc.colorAttachmentCount = cmd.operands[0]; + } + if (cmd.operands[1] > 0) + { + desc.depthStencilAttachment = m_writer.getData(cmd.operands[3]); + } + m_renderer->beginRenderPass(desc); break; + } case CommandName::EndRenderPass: m_renderer->endRenderPass(); break; diff --git a/src/metal/metal-command-encoder.cpp b/src/metal/metal-command-encoder.cpp index 43ec2410..073320e5 100644 --- a/src/metal/metal-command-encoder.cpp +++ b/src/metal/metal-command-encoder.cpp @@ -249,7 +249,7 @@ void RenderCommandEncoderImpl::beginPass(const RenderPassDesc& desc) MTL::RenderPassColorAttachmentDescriptor* colorAttachment = m_renderPassDesc->colorAttachments()->object(i); colorAttachment->setLoadAction(MetalUtil::translateLoadOp(attachment.loadOp)); colorAttachment->setStoreAction(MetalUtil::translateStoreOp(attachment.storeOp)); - if (attachment.loadOp == TargetLoadOp::Clear) + if (attachment.loadOp == LoadOp::Clear) { colorAttachment->setClearColor(MTL::ClearColor( attachment.clearValue[0], @@ -277,7 +277,7 @@ void RenderCommandEncoderImpl::beginPass(const RenderPassDesc& desc) MTL::RenderPassDepthAttachmentDescriptor* depthAttachment = m_renderPassDesc->depthAttachment(); depthAttachment->setLoadAction(MetalUtil::translateLoadOp(attachment.depthLoadOp)); depthAttachment->setStoreAction(MetalUtil::translateStoreOp(attachment.depthStoreOp)); - if (attachment.depthLoadOp == TargetLoadOp::Clear) + if (attachment.depthLoadOp == LoadOp::Clear) { depthAttachment->setClearDepth(attachment.depthClearValue); } @@ -290,7 +290,7 @@ void RenderCommandEncoderImpl::beginPass(const RenderPassDesc& desc) MTL::RenderPassStencilAttachmentDescriptor* stencilAttachment = m_renderPassDesc->stencilAttachment(); stencilAttachment->setLoadAction(MetalUtil::translateLoadOp(attachment.stencilLoadOp)); stencilAttachment->setStoreAction(MetalUtil::translateStoreOp(attachment.stencilStoreOp)); - if (attachment.stencilLoadOp == TargetLoadOp::Clear) + if (attachment.stencilLoadOp == LoadOp::Clear) { stencilAttachment->setClearStencil(attachment.stencilClearValue); } diff --git a/src/metal/metal-util.cpp b/src/metal/metal-util.cpp index 7adeaa05..0457fc2a 100644 --- a/src/metal/metal-util.cpp +++ b/src/metal/metal-util.cpp @@ -590,28 +590,28 @@ MTL::TriangleFillMode MetalUtil::translateTriangleFillMode(FillMode mode) } } -MTL::LoadAction MetalUtil::translateLoadOp(TargetLoadOp loadOp) +MTL::LoadAction MetalUtil::translateLoadOp(LoadOp loadOp) { switch (loadOp) { - case TargetLoadOp::Load: + case LoadOp::Load: return MTL::LoadActionLoad; - case TargetLoadOp::Clear: + case LoadOp::Clear: return MTL::LoadActionClear; - case TargetLoadOp::DontCare: + case LoadOp::DontCare: return MTL::LoadActionDontCare; default: return MTL::LoadAction(0); } } -MTL::StoreAction MetalUtil::translateStoreOp(TargetStoreOp storeOp) +MTL::StoreAction MetalUtil::translateStoreOp(StoreOp storeOp) { switch (storeOp) { - case TargetStoreOp::Store: + case StoreOp::Store: return MTL::StoreActionStore; - case TargetStoreOp::DontCare: + case StoreOp::DontCare: return MTL::StoreActionDontCare; default: return MTL::StoreAction(0); diff --git a/src/metal/metal-util.h b/src/metal/metal-util.h index a3a2ba83..2138c5f7 100644 --- a/src/metal/metal-util.h +++ b/src/metal/metal-util.h @@ -51,8 +51,8 @@ struct MetalUtil static MTL::CullMode translateCullMode(CullMode mode); static MTL::TriangleFillMode translateTriangleFillMode(FillMode mode); - static MTL::LoadAction translateLoadOp(TargetLoadOp loadOp); - static MTL::StoreAction translateStoreOp(TargetStoreOp storeOp); + static MTL::LoadAction translateLoadOp(LoadOp loadOp); + static MTL::StoreAction translateStoreOp(StoreOp storeOp); }; struct ScopedAutoreleasePool diff --git a/src/vulkan/vk-command-buffer.cpp b/src/vulkan/vk-command-buffer.cpp index dcca3f89..4ad31660 100644 --- a/src/vulkan/vk-command-buffer.cpp +++ b/src/vulkan/vk-command-buffer.cpp @@ -86,7 +86,7 @@ Result CommandBufferImpl::encodeResourceCommands(IResourceCommandEncoder** outEn Result CommandBufferImpl::encodeRenderCommands(const RenderPassDesc& desc, IRenderCommandEncoder** outEncoder) { m_renderCommandEncoder.init(this); - m_renderCommandEncoder.beginPass(desc); + SLANG_RETURN_ON_FAIL(m_renderCommandEncoder.beginPass(desc)); *outEncoder = &m_renderCommandEncoder; return SLANG_OK; } diff --git a/src/vulkan/vk-command-encoder.cpp b/src/vulkan/vk-command-encoder.cpp index 8ebd0b14..25080313 100644 --- a/src/vulkan/vk-command-encoder.cpp +++ b/src/vulkan/vk-command-encoder.cpp @@ -947,20 +947,17 @@ void ResourceCommandEncoderImpl::copyTextureToBuffer( // RenderCommandEncoderImpl -void RenderCommandEncoderImpl::beginPass(const RenderPassDesc& desc) +Result RenderCommandEncoderImpl::beginPass(const RenderPassDesc& desc) { auto& api = *m_api; m_renderTargetViews.resize(desc.colorAttachmentCount); m_renderTargetFinalStates.resize(desc.colorAttachmentCount); - for (GfxIndex i = 0; i < desc.colorAttachmentCount; ++i) - { - m_renderTargetViews[i] = static_cast(desc.colorAttachments[i].view); - m_renderTargetFinalStates[i] = desc.colorAttachments[i].finalState; - } - m_depthStencilView = static_cast(desc.depthStencilAttachment.view); - m_depthStencilFinalState = desc.depthStencilAttachment.finalState; - + short_vector colorAttachmentInfos; + VkRenderingAttachmentInfoKHR depthAttachmentInfo = {VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR}; + VkRenderingAttachmentInfoKHR stencilAttachmentInfo = {VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR}; + bool hasDepthAttachment = false; + bool hasStencilAttachment = false; VkRect2D renderArea; renderArea.offset = {0, 0}; renderArea.extent = { @@ -969,16 +966,21 @@ void RenderCommandEncoderImpl::beginPass(const RenderPassDesc& desc) }; uint32_t layerCount = 1; - // Transition render targets from their initial state to render target state. for (GfxIndex i = 0; i < desc.colorAttachmentCount; ++i) { const auto& attachment = desc.colorAttachments[i]; TextureViewImpl* view = static_cast(attachment.view); - if (view) - { - ITexture* texture = view->m_texture; - textureBarrier(1, &texture, attachment.initialState, ResourceState::RenderTarget); - } + if (!view) + return SLANG_FAIL; + + m_renderTargetViews[i] = view; + m_renderTargetFinalStates[i] = attachment.finalState; + + // Transition state + ITexture* texture = view->m_texture; + textureBarrier(1, &texture, attachment.initialState, ResourceState::RenderTarget); + + // Determine render area const IResourceView::Desc* viewDesc = &view->m_desc; const TextureDesc* textureDesc = view->m_texture->getDesc(); uint32_t width = getMipLevelSize(viewDesc->subresourceRange.mipLevel, textureDesc->size.width); @@ -989,65 +991,65 @@ void RenderCommandEncoderImpl::beginPass(const RenderPassDesc& desc) ? textureDesc->size.depth : viewDesc->subresourceRange.layerCount; layerCount = std::max(layerCount, attachmentLayerCount); + + // Create attachment info + VkRenderingAttachmentInfoKHR attachmentInfo = {VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR}; + attachmentInfo.imageView = static_cast(attachment.view)->m_view; + attachmentInfo.imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + attachmentInfo.loadOp = translateLoadOp(attachment.loadOp); + attachmentInfo.storeOp = translateStoreOp(attachment.storeOp); + attachmentInfo.clearValue.color.float32[0] = attachment.clearValue[0]; + attachmentInfo.clearValue.color.float32[1] = attachment.clearValue[1]; + attachmentInfo.clearValue.color.float32[2] = attachment.clearValue[2]; + attachmentInfo.clearValue.color.float32[3] = attachment.clearValue[3]; + colorAttachmentInfos.push_back(attachmentInfo); } + // Transition depth stencil from its initial state to depth write state. - if (desc.depthStencilAttachment.view) + if (desc.depthStencilAttachment) { - TextureViewImpl* view = static_cast(desc.depthStencilAttachment.view); + const auto& attachment = *desc.depthStencilAttachment; + TextureViewImpl* view = static_cast(attachment.view); + if (!view) + return SLANG_FAIL; + + m_depthStencilView = static_cast(desc.depthStencilAttachment->view); + m_depthStencilCurrentState = attachment.depthReadOnly ? ResourceState::DepthRead : ResourceState::DepthWrite; + m_depthStencilFinalState = desc.depthStencilAttachment->finalState; + + // Transition state ITexture* texture = view->m_texture; - // TODO we could use DepthRead if we are not writing to the depth buffer - textureBarrier(1, &texture, desc.depthStencilAttachment.initialState, ResourceState::DepthWrite); + textureBarrier(1, &texture, attachment.initialState, m_depthStencilCurrentState); + // Determine render area const IResourceView::Desc* viewDesc = &view->m_desc; const TextureDesc* textureDesc = view->m_texture->getDesc(); uint32_t width = getMipLevelSize(viewDesc->subresourceRange.mipLevel, textureDesc->size.width); uint32_t height = getMipLevelSize(viewDesc->subresourceRange.mipLevel, textureDesc->size.height); renderArea.extent.width = std::min(renderArea.extent.width, width); renderArea.extent.height = std::min(renderArea.extent.height, height); - } - static_vector colorAttachmentInfos; - for (GfxIndex i = 0; i < desc.colorAttachmentCount; ++i) - { - const auto& attachment = desc.colorAttachments[i]; - if (attachment.view) + // Create attachment info + if (VulkanUtil::isDepthFormat(view->m_texture->m_vkformat)) { - VkRenderingAttachmentInfoKHR attachmentInfo = {VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR}; - attachmentInfo.imageView = static_cast(attachment.view)->m_view; - attachmentInfo.imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; - attachmentInfo.loadOp = translateLoadOp(attachment.loadOp); - attachmentInfo.storeOp = translateStoreOp(attachment.storeOp); - attachmentInfo.clearValue.color.float32[0] = attachment.clearValue[0]; - attachmentInfo.clearValue.color.float32[1] = attachment.clearValue[1]; - attachmentInfo.clearValue.color.float32[2] = attachment.clearValue[2]; - attachmentInfo.clearValue.color.float32[3] = attachment.clearValue[3]; - colorAttachmentInfos.push_back(attachmentInfo); + hasDepthAttachment = true; + const auto& attachment = *desc.depthStencilAttachment; + depthAttachmentInfo.imageView = static_cast(attachment.view)->m_view; + depthAttachmentInfo.imageLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; + depthAttachmentInfo.loadOp = translateLoadOp(attachment.depthLoadOp); + depthAttachmentInfo.storeOp = translateStoreOp(attachment.depthStoreOp); + depthAttachmentInfo.clearValue.depthStencil.depth = attachment.depthClearValue; + } + if (VulkanUtil::isStencilFormat(view->m_texture->m_vkformat)) + { + hasStencilAttachment = true; + const auto& attachment = *desc.depthStencilAttachment; + stencilAttachmentInfo.imageView = static_cast(attachment.view)->m_view; + stencilAttachmentInfo.imageLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; + stencilAttachmentInfo.loadOp = translateLoadOp(attachment.stencilLoadOp); + stencilAttachmentInfo.storeOp = translateStoreOp(attachment.stencilStoreOp); + stencilAttachmentInfo.clearValue.depthStencil.stencil = attachment.stencilClearValue; } - } - VkRenderingAttachmentInfo depthAttachmentInfo = {VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR}; - bool hasDepthAttachment = false; - if (desc.depthStencilAttachment.view) - { - hasDepthAttachment = true; - const auto& attachment = desc.depthStencilAttachment; - depthAttachmentInfo.imageView = static_cast(attachment.view)->m_view; - depthAttachmentInfo.imageLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; - depthAttachmentInfo.loadOp = translateLoadOp(attachment.depthLoadOp); - depthAttachmentInfo.storeOp = translateStoreOp(attachment.depthStoreOp); - depthAttachmentInfo.clearValue.depthStencil.depth = attachment.depthClearValue; - } - VkRenderingAttachmentInfo stencilAttachmentInfo = {VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR}; - bool hasStencilAttachment = false; - // TODO only set if stencil is present - if (desc.depthStencilAttachment.view) - { - hasStencilAttachment = true; - const auto& attachment = desc.depthStencilAttachment; - stencilAttachmentInfo.imageView = static_cast(attachment.view)->m_view; - stencilAttachmentInfo.imageLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; - stencilAttachmentInfo.loadOp = translateLoadOp(attachment.stencilLoadOp); - stencilAttachmentInfo.storeOp = translateStoreOp(attachment.stencilStoreOp); - stencilAttachmentInfo.clearValue.depthStencil.stencil = attachment.stencilClearValue; } VkRenderingInfoKHR renderingInfo = {VK_STRUCTURE_TYPE_RENDERING_INFO_KHR}; @@ -1068,17 +1070,13 @@ void RenderCommandEncoderImpl::endEncoding() for (Index i = 0; i < m_renderTargetViews.size(); ++i) { - if (m_renderTargetViews[i]) - { - ITexture* texture = m_renderTargetViews[i]->m_texture; - textureBarrier(1, &texture, ResourceState::RenderTarget, m_renderTargetFinalStates[i]); - } + ITexture* texture = m_renderTargetViews[i]->m_texture; + textureBarrier(1, &texture, ResourceState::RenderTarget, m_renderTargetFinalStates[i]); } if (m_depthStencilView) { ITexture* texture = m_depthStencilView->m_texture; - // TODO we could use DepthRead if we are not writing to the depth buffer - textureBarrier(1, &texture, ResourceState::DepthWrite, m_depthStencilFinalState); + textureBarrier(1, &texture, m_depthStencilCurrentState, m_depthStencilFinalState); } m_renderTargetViews.clear(); diff --git a/src/vulkan/vk-command-encoder.h b/src/vulkan/vk-command-encoder.h index 38e2bf36..43122682 100644 --- a/src/vulkan/vk-command-encoder.h +++ b/src/vulkan/vk-command-encoder.h @@ -178,13 +178,14 @@ class RenderCommandEncoderImpl : public IRenderCommandEncoder, public CommandEnc static_vector, kMaxRenderTargetCount> m_renderTargetViews; static_vector m_renderTargetFinalStates; RefPtr m_depthStencilView; + ResourceState m_depthStencilCurrentState; ResourceState m_depthStencilFinalState; std::vector m_viewports; std::vector m_scissorRects; public: - void beginPass(const RenderPassDesc& desc); + Result beginPass(const RenderPassDesc& desc); virtual SLANG_NO_THROW void SLANG_MCALL endEncoding() override; diff --git a/src/vulkan/vk-helper-functions.cpp b/src/vulkan/vk-helper-functions.cpp index a36e5257..3b40e0f5 100644 --- a/src/vulkan/vk-helper-functions.cpp +++ b/src/vulkan/vk-helper-functions.cpp @@ -20,24 +20,24 @@ GfxCount calcNumRows(Format format, int height) return (GfxCount)(height + sizeInfo.blockHeight - 1) / sizeInfo.blockHeight; } -VkAttachmentLoadOp translateLoadOp(TargetLoadOp loadOp) +VkAttachmentLoadOp translateLoadOp(LoadOp loadOp) { switch (loadOp) { - case TargetLoadOp::Clear: + case LoadOp::Clear: return VK_ATTACHMENT_LOAD_OP_CLEAR; - case TargetLoadOp::Load: + case LoadOp::Load: return VK_ATTACHMENT_LOAD_OP_LOAD; default: return VK_ATTACHMENT_LOAD_OP_DONT_CARE; } } -VkAttachmentStoreOp translateStoreOp(TargetStoreOp storeOp) +VkAttachmentStoreOp translateStoreOp(StoreOp storeOp) { switch (storeOp) { - case TargetStoreOp::Store: + case StoreOp::Store: return VK_ATTACHMENT_STORE_OP_STORE; default: return VK_ATTACHMENT_STORE_OP_DONT_CARE; diff --git a/src/vulkan/vk-helper-functions.h b/src/vulkan/vk-helper-functions.h index 35aee49f..2c41c183 100644 --- a/src/vulkan/vk-helper-functions.h +++ b/src/vulkan/vk-helper-functions.h @@ -144,8 +144,8 @@ struct RootBindingContext Size calcRowSize(Format format, int width); GfxCount calcNumRows(Format format, int height); -VkAttachmentLoadOp translateLoadOp(TargetLoadOp loadOp); -VkAttachmentStoreOp translateStoreOp(TargetStoreOp storeOp); +VkAttachmentLoadOp translateLoadOp(LoadOp loadOp); +VkAttachmentStoreOp translateStoreOp(StoreOp storeOp); VkPipelineCreateFlags translateRayTracingPipelineFlags(RayTracingPipelineFlags::Enum flags); uint32_t getMipLevelSize(uint32_t mipLevel, uint32_t size); diff --git a/tests/test-instanced-draw.cpp b/tests/test-instanced-draw.cpp index 0f238afc..5fc68578 100644 --- a/tests/test-instanced-draw.cpp +++ b/tests/test-instanced-draw.cpp @@ -218,12 +218,14 @@ struct DrawInstancedTest : BaseDrawTest auto queue = device->createCommandQueue(queueDesc); auto commandBuffer = transientHeap->createCommandBuffer(); + RenderPassColorAttachment colorAttachment; + colorAttachment.view = colorBufferView; + colorAttachment.loadOp = LoadOp::Clear; + colorAttachment.storeOp = StoreOp::Store; + colorAttachment.initialState = ResourceState::RenderTarget; + colorAttachment.finalState = ResourceState::CopySource; RenderPassDesc renderPass; - renderPass.colorAttachments[0].loadOp = TargetLoadOp::Clear; - renderPass.colorAttachments[0].storeOp = TargetStoreOp::Store; - renderPass.colorAttachments[0].initialState = ResourceState::RenderTarget; - renderPass.colorAttachments[0].finalState = ResourceState::CopySource; - renderPass.colorAttachments[0].view = colorBufferView; + renderPass.colorAttachments = &colorAttachment; renderPass.colorAttachmentCount = 1; auto encoder = commandBuffer->encodeRenderCommands(renderPass); @@ -275,12 +277,14 @@ struct DrawIndexedInstancedTest : BaseDrawTest auto queue = device->createCommandQueue(queueDesc); auto commandBuffer = transientHeap->createCommandBuffer(); + RenderPassColorAttachment colorAttachment; + colorAttachment.view = colorBufferView; + colorAttachment.loadOp = LoadOp::Clear; + colorAttachment.storeOp = StoreOp::Store; + colorAttachment.initialState = ResourceState::RenderTarget; + colorAttachment.finalState = ResourceState::CopySource; RenderPassDesc renderPass; - renderPass.colorAttachments[0].loadOp = TargetLoadOp::Clear; - renderPass.colorAttachments[0].storeOp = TargetStoreOp::Store; - renderPass.colorAttachments[0].initialState = ResourceState::RenderTarget; - renderPass.colorAttachments[0].finalState = ResourceState::CopySource; - renderPass.colorAttachments[0].view = colorBufferView; + renderPass.colorAttachments = &colorAttachment; renderPass.colorAttachmentCount = 1; auto encoder = commandBuffer->encodeRenderCommands(renderPass); @@ -358,12 +362,14 @@ struct DrawIndirectTest : BaseDrawTest auto queue = device->createCommandQueue(queueDesc); auto commandBuffer = transientHeap->createCommandBuffer(); + RenderPassColorAttachment colorAttachment; + colorAttachment.view = colorBufferView; + colorAttachment.loadOp = LoadOp::Clear; + colorAttachment.storeOp = StoreOp::Store; + colorAttachment.initialState = ResourceState::RenderTarget; + colorAttachment.finalState = ResourceState::CopySource; RenderPassDesc renderPass; - renderPass.colorAttachments[0].loadOp = TargetLoadOp::Clear; - renderPass.colorAttachments[0].storeOp = TargetStoreOp::Store; - renderPass.colorAttachments[0].initialState = ResourceState::RenderTarget; - renderPass.colorAttachments[0].finalState = ResourceState::CopySource; - renderPass.colorAttachments[0].view = colorBufferView; + renderPass.colorAttachments = &colorAttachment; renderPass.colorAttachmentCount = 1; auto encoder = commandBuffer->encodeRenderCommands(renderPass); @@ -440,12 +446,14 @@ struct DrawIndexedIndirectTest : BaseDrawTest auto queue = device->createCommandQueue(queueDesc); auto commandBuffer = transientHeap->createCommandBuffer(); + RenderPassColorAttachment colorAttachment; + colorAttachment.view = colorBufferView; + colorAttachment.loadOp = LoadOp::Clear; + colorAttachment.storeOp = StoreOp::Store; + colorAttachment.initialState = ResourceState::RenderTarget; + colorAttachment.finalState = ResourceState::CopySource; RenderPassDesc renderPass; - renderPass.colorAttachments[0].loadOp = TargetLoadOp::Clear; - renderPass.colorAttachments[0].storeOp = TargetStoreOp::Store; - renderPass.colorAttachments[0].initialState = ResourceState::RenderTarget; - renderPass.colorAttachments[0].finalState = ResourceState::CopySource; - renderPass.colorAttachments[0].view = colorBufferView; + renderPass.colorAttachments = &colorAttachment; renderPass.colorAttachmentCount = 1; auto encoder = commandBuffer->encodeRenderCommands(renderPass); diff --git a/tests/test-resolve-resource-tests.cpp b/tests/test-resolve-resource-tests.cpp index 20e866f4..924e2996 100644 --- a/tests/test-resolve-resource-tests.cpp +++ b/tests/test-resolve-resource-tests.cpp @@ -165,12 +165,14 @@ struct BaseResolveResourceTest auto commandBuffer = transientHeap->createCommandBuffer(); + RenderPassColorAttachment colorAttachment; + colorAttachment.view = msaaTextureView; + colorAttachment.loadOp = LoadOp::Clear; + colorAttachment.storeOp = StoreOp::Store; + colorAttachment.initialState = ResourceState::RenderTarget; + colorAttachment.finalState = ResourceState::ResolveSource; RenderPassDesc renderPass; - renderPass.colorAttachments[0].loadOp = TargetLoadOp::Clear; - renderPass.colorAttachments[0].storeOp = TargetStoreOp::Store; - renderPass.colorAttachments[0].initialState = ResourceState::RenderTarget; - renderPass.colorAttachments[0].finalState = ResourceState::ResolveSource; - renderPass.colorAttachments[0].view = msaaTextureView; + renderPass.colorAttachments = &colorAttachment; renderPass.colorAttachmentCount = 1; auto renderEncoder = commandBuffer->encodeRenderCommands(renderPass); diff --git a/tests/test-shader-cache.cpp b/tests/test-shader-cache.cpp index f239ea38..5f32bfa7 100644 --- a/tests/test-shader-cache.cpp +++ b/tests/test-shader-cache.cpp @@ -804,12 +804,14 @@ struct ShaderCacheTestGraphics : ShaderCacheTest auto queue = device->createCommandQueue(queueDesc); auto commandBuffer = transientHeap->createCommandBuffer(); + RenderPassColorAttachment colorAttachment; + colorAttachment.view = colorBufferView; + colorAttachment.loadOp = LoadOp::Clear; + colorAttachment.storeOp = StoreOp::Store; + colorAttachment.initialState = ResourceState::RenderTarget; + colorAttachment.finalState = ResourceState::CopySource; RenderPassDesc renderPass; - renderPass.colorAttachments[0].loadOp = TargetLoadOp::Clear; - renderPass.colorAttachments[0].storeOp = TargetStoreOp::Store; - renderPass.colorAttachments[0].initialState = ResourceState::RenderTarget; - renderPass.colorAttachments[0].finalState = ResourceState::CopySource; - renderPass.colorAttachments[0].view = colorBufferView; + renderPass.colorAttachments = &colorAttachment; renderPass.colorAttachmentCount = 1; auto encoder = commandBuffer->encodeRenderCommands(renderPass); diff --git a/tests/test-swapchain.cpp b/tests/test-swapchain.cpp index 02ec61d0..35205624 100644 --- a/tests/test-swapchain.cpp +++ b/tests/test-swapchain.cpp @@ -160,8 +160,8 @@ struct SwapchainResizeTest renderPassDesc.framebufferLayout = framebufferLayout; renderPassDesc.renderTargetCount = 1; IRenderPassLayout::TargetAccessDesc renderTargetAccess = {}; - renderTargetAccess.loadOp = IRenderPassLayout::TargetLoadOp::Clear; - renderTargetAccess.storeOp = IRenderPassLayout::TargetStoreOp::Store; + renderTargetAccess.loadOp = IRenderPassLayout::LoadOp::Clear; + renderTargetAccess.storeOp = IRenderPassLayout::StoreOp::Store; renderTargetAccess.initialState = ResourceState::Undefined; renderTargetAccess.finalState = ResourceState::Present; renderPassDesc.renderTargetAccess = &renderTargetAccess; diff --git a/tests/test-texture-types.cpp b/tests/test-texture-types.cpp index 792075ed..e27aead3 100644 --- a/tests/test-texture-types.cpp +++ b/tests/test-texture-types.cpp @@ -447,12 +447,14 @@ struct RenderTargetTests : BaseTextureViewTest auto commandBuffer = transientHeap->createCommandBuffer(); + RenderPassColorAttachment colorAttachment; + colorAttachment.view = sampledTextureView; + colorAttachment.loadOp = LoadOp::Clear; + colorAttachment.storeOp = StoreOp::Store; + colorAttachment.initialState = getDefaultResourceStateForViewType(viewType); + colorAttachment.finalState = ResourceState::ResolveSource; RenderPassDesc renderPass; - renderPass.colorAttachments[0].loadOp = TargetLoadOp::Clear; - renderPass.colorAttachments[0].storeOp = TargetStoreOp::Store; - renderPass.colorAttachments[0].initialState = getDefaultResourceStateForViewType(viewType); - renderPass.colorAttachments[0].finalState = ResourceState::ResolveSource; - renderPass.colorAttachments[0].view = sampledTextureView; + renderPass.colorAttachments = &colorAttachment; renderPass.colorAttachmentCount = 1; auto renderEncoder = commandBuffer->encodeRenderCommands(renderPass); diff --git a/tests/testing.cpp b/tests/testing.cpp index 6255f296..cc438743 100644 --- a/tests/testing.cpp +++ b/tests/testing.cpp @@ -327,7 +327,6 @@ void compareComputeResultFuzzy(const float* result, float* expectedResult, size_ { CHECK_LE(result[i], expectedResult[i] + 0.01f); CHECK_GE(result[i], expectedResult[i] - 0.01f); - // CHECK_LE(abs(result[i] - expectedResult[i]), 0.01); } } From 7272c36f8aab30d35965d4f43138dce13baaa047 Mon Sep 17 00:00:00 2001 From: Simon Kallweit Date: Fri, 6 Sep 2024 21:54:50 +0200 Subject: [PATCH 6/8] fix metal --- src/metal/metal-command-buffer.cpp | 2 +- src/metal/metal-command-encoder.cpp | 12 +++++++++--- src/metal/metal-command-encoder.h | 2 +- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/metal/metal-command-buffer.cpp b/src/metal/metal-command-buffer.cpp index 1b2fda03..739da6e0 100644 --- a/src/metal/metal-command-buffer.cpp +++ b/src/metal/metal-command-buffer.cpp @@ -30,7 +30,7 @@ Result CommandBufferImpl::encodeResourceCommands(IResourceCommandEncoder** outEn Result CommandBufferImpl::encodeRenderCommands(const RenderPassDesc& desc, IRenderCommandEncoder** outEncoder) { m_renderCommandEncoder.init(this); - m_renderCommandEncoder.beginPass(desc); + SLANG_RETURN_ON_FAIL(m_renderCommandEncoder.beginPass(desc)); *outEncoder = &m_renderCommandEncoder; return SLANG_OK; } diff --git a/src/metal/metal-command-encoder.cpp b/src/metal/metal-command-encoder.cpp index 073320e5..417ef889 100644 --- a/src/metal/metal-command-encoder.cpp +++ b/src/metal/metal-command-encoder.cpp @@ -220,7 +220,7 @@ void ResourceCommandEncoderImpl::resolveQuery( // RenderCommandEncoderImpl -void RenderCommandEncoderImpl::beginPass(const RenderPassDesc& desc) +Result RenderCommandEncoderImpl::beginPass(const RenderPassDesc& desc) { uint32_t width = 1; uint32_t height = 1; @@ -243,6 +243,8 @@ void RenderCommandEncoderImpl::beginPass(const RenderPassDesc& desc) { const auto& attachment = desc.colorAttachments[i]; TextureViewImpl* view = static_cast(attachment.view); + if (!view) + return SLANG_FAIL; visitView(view); m_renderTargetViews[i] = view; @@ -264,10 +266,12 @@ void RenderCommandEncoderImpl::beginPass(const RenderPassDesc& desc) } // Setup depth stencil attachment. - if (desc.depthStencilAttachment.view) + if (desc.depthStencilAttachment) { - const auto& attachment = desc.depthStencilAttachment; + const auto& attachment = *desc.depthStencilAttachment; TextureViewImpl* view = static_cast(attachment.view); + if (!view) + return SLANG_FAIL; visitView(view); m_depthStencilView = view; MTL::PixelFormat pixelFormat = MetalUtil::translatePixelFormat(view->m_desc.format); @@ -302,6 +306,8 @@ void RenderCommandEncoderImpl::beginPass(const RenderPassDesc& desc) m_renderPassDesc->setRenderTargetWidth(width); m_renderPassDesc->setRenderTargetHeight(height); + + return SLANG_OK; } void RenderCommandEncoderImpl::endEncoding() diff --git a/src/metal/metal-command-encoder.h b/src/metal/metal-command-encoder.h index 7886520d..a4281efa 100644 --- a/src/metal/metal-command-encoder.h +++ b/src/metal/metal-command-encoder.h @@ -166,7 +166,7 @@ class RenderCommandEncoderImpl : public IRenderCommandEncoder, public CommandEnc uint32_t m_stencilReferenceValue = 0; public: - void beginPass(const RenderPassDesc& desc); + Result beginPass(const RenderPassDesc& desc); virtual SLANG_NO_THROW void SLANG_MCALL endEncoding() override; From 322d9419275a50afa46ce756d716a1d955b027c1 Mon Sep 17 00:00:00 2001 From: Simon Kallweit Date: Fri, 6 Sep 2024 23:31:35 +0200 Subject: [PATCH 7/8] refactor render pipeline desc --- include/slang-rhi.h | 38 +++++-------- src/core/short_vector.h | 20 ++++--- src/d3d11/d3d11-device.cpp | 53 +++++++++--------- src/d3d11/d3d11-device.h | 6 +-- src/d3d11/d3d11-helper-functions.cpp | 2 +- src/d3d11/d3d11-helper-functions.h | 2 +- src/d3d12/d3d12-command-encoder.cpp | 2 +- src/d3d12/d3d12-command-encoder.h | 4 +- src/d3d12/d3d12-pipeline.cpp | 76 +++++++++++++------------- src/metal/metal-command-encoder.h | 2 +- src/renderer-shared.cpp | 13 ++++- src/renderer-shared.h | 77 ++------------------------- src/vulkan/vk-command-encoder.cpp | 2 + src/vulkan/vk-command-encoder.h | 4 +- src/vulkan/vk-pipeline.cpp | 54 +++++++++---------- tests/test-instanced-draw.cpp | 6 ++- tests/test-resolve-resource-tests.cpp | 8 +-- tests/test-shader-cache.cpp | 12 +++-- tests/test-shared-buffer.cpp | 3 ++ tests/test-shared-texture.cpp | 3 ++ tests/test-texture-types.cpp | 8 +-- 21 files changed, 167 insertions(+), 228 deletions(-) diff --git a/include/slang-rhi.h b/include/slang-rhi.h index e03d02d2..417d7916 100644 --- a/include/slang-rhi.h +++ b/include/slang-rhi.h @@ -83,9 +83,6 @@ enum class AccessFlag Write, }; -// TODO: Needed? Shouldn't be hard-coded if so -const GfxCount kMaxRenderTargetCount = 8; - class ITransientResourceHeap; class IPersistentShaderCache; @@ -1068,8 +1065,10 @@ struct DepthStencilOpDesc ComparisonFunc stencilFunc = ComparisonFunc::Always; }; -struct DepthStencilDesc +struct DepthStencilState { + Format format = Format::Unknown; + bool depthTestEnable = false; bool depthWriteEnable = true; ComparisonFunc depthFunc = ComparisonFunc::Less; @@ -1155,8 +1154,9 @@ struct AspectBlendDesc BlendOp op = BlendOp::Add; }; -struct TargetBlendDesc +struct ColorTargetState { + Format format = Format::Unknown; AspectBlendDesc color; AspectBlendDesc alpha; bool enableBlend = false; @@ -1164,23 +1164,12 @@ struct TargetBlendDesc RenderTargetWriteMaskT writeMask = RenderTargetWriteMask::EnableAll; }; -struct BlendDesc +struct MultisampleState { - TargetBlendDesc targets[kMaxRenderTargetCount]; - bool alphaToCoverageEnable = false; -}; - -struct TargetLayoutDesc -{ - Format format = Format::Unknown; -}; - -struct FramebufferLayoutDesc -{ - TargetLayoutDesc renderTargets[kMaxRenderTargetCount]; - GfxCount renderTargetCount = 0; - TargetLayoutDesc depthStencil; GfxCount sampleCount = 1; + uint32_t sampleMask = 0xFFFFFFFF; + bool alphaToCoverageEnable = false; + bool alphaToOneEnable = false; }; struct RenderPipelineDesc @@ -1188,11 +1177,12 @@ struct RenderPipelineDesc IShaderProgram* program = nullptr; IInputLayout* inputLayout = nullptr; - FramebufferLayoutDesc framebufferLayout; PrimitiveType primitiveType = PrimitiveType::Triangle; - DepthStencilDesc depthStencil; + ColorTargetState* targets = nullptr; + GfxCount targetCount = 0; + DepthStencilState depthStencil; RasterizerDesc rasterizer; - BlendDesc blend; + MultisampleState multisample; }; struct ComputePipelineDesc @@ -1223,7 +1213,7 @@ struct RayTracingPipelineDesc { IShaderProgram* program = nullptr; GfxCount hitGroupCount = 0; - const HitGroupDesc* hitGroups = nullptr; + HitGroupDesc* hitGroups = nullptr; int maxRecursion = 0; Size maxRayPayloadSize = 0; Size maxAttributeSizeInBytes = 8; diff --git a/src/core/short_vector.h b/src/core/short_vector.h index b975814e..7aeced84 100644 --- a/src/core/short_vector.h +++ b/src/core/short_vector.h @@ -92,13 +92,12 @@ class short_vector /// Default constructor. short_vector() noexcept - : m_data(m_short_data) + : m_data((value_type*)m_short_data) , m_size(0) , m_capacity(N) { } -#if 0 /// Size constructor. short_vector(size_type size, const value_type& value) : m_data(m_short_data) @@ -108,11 +107,9 @@ class short_vector if (size > m_capacity) grow(size); for (size_type i = 0; i < size; ++i) - m_data[i] = value; + push_back(value); } -#endif -#if 0 /// Initializer list constructor. short_vector(std::initializer_list list) : m_data(m_short_data) @@ -122,13 +119,12 @@ class short_vector for (const auto& value : list) push_back(value); } -#endif ~short_vector() { - if (m_data != m_short_data) + detail::destruct_range(m_data, m_data + m_size); + if ((void*)m_data != (void*)m_short_data) { - detail::destruct_range(m_data, m_data + m_size); std::free(m_data); } } @@ -170,7 +166,9 @@ class short_vector short_vector& operator=(short_vector&& other) { - if (other.m_data == other.m_short_data) + if (this == &other) + return *this; + if ((void*)other.m_data == (void*)other.m_short_data) { detail::move_range(other.m_data, other.m_data + other.m_size, m_data); } @@ -271,12 +269,12 @@ class short_vector m_capacity = new_capacity; value_type* new_data = reinterpret_cast(std::malloc(m_capacity * sizeof(T))); detail::move_range(m_data, m_data + m_size, new_data); - if (m_data != m_short_data) + if ((void*)m_data != (void*)m_short_data) std::free(m_data); m_data = new_data; } - value_type m_short_data[N]; + uint8_t m_short_data[sizeof(value_type) * N]; value_type* m_data; size_type m_size; size_type m_capacity; diff --git a/src/d3d11/d3d11-device.cpp b/src/d3d11/d3d11-device.cpp index 60e472c9..c1ac6cf7 100644 --- a/src/d3d11/d3d11-device.cpp +++ b/src/d3d11/d3d11-device.cpp @@ -1600,61 +1600,60 @@ Result DeviceImpl::createRenderPipeline(const RenderPipelineDesc& inDesc, IPipel ComPtr blendState; { - auto& srcDesc = desc.blend; D3D11_BLEND_DESC dstDesc = {}; - TargetBlendDesc defaultTargetBlendDesc; + ColorTargetState defaultTargetState; static const UInt kMaxTargets = D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; - int targetCount = desc.framebufferLayout.renderTargetCount; + int targetCount = desc.targetCount; if (targetCount > kMaxTargets) return SLANG_FAIL; for (GfxIndex ii = 0; ii < kMaxTargets; ++ii) { - TargetBlendDesc const* srcTargetBlendDescPtr = nullptr; + const ColorTargetState* targetState = nullptr; if (ii < targetCount) { - srcTargetBlendDescPtr = &srcDesc.targets[ii]; + targetState = &desc.targets[ii]; } else if (targetCount == 0) { - srcTargetBlendDescPtr = &defaultTargetBlendDesc; + targetState = &defaultTargetState; } else { - srcTargetBlendDescPtr = &srcDesc.targets[targetCount - 1]; + targetState = &desc.targets[targetCount - 1]; } - auto& srcTargetBlendDesc = *srcTargetBlendDescPtr; - auto& dstTargetBlendDesc = dstDesc.RenderTarget[ii]; + auto& srcTarget = *targetState; + auto& dstTarget = dstDesc.RenderTarget[ii]; - if (isBlendDisabled(srcTargetBlendDesc)) + if (isBlendDisabled(srcTarget)) { - dstTargetBlendDesc.BlendEnable = false; - dstTargetBlendDesc.BlendOp = D3D11_BLEND_OP_ADD; - dstTargetBlendDesc.BlendOpAlpha = D3D11_BLEND_OP_ADD; - dstTargetBlendDesc.SrcBlend = D3D11_BLEND_ONE; - dstTargetBlendDesc.SrcBlendAlpha = D3D11_BLEND_ONE; - dstTargetBlendDesc.DestBlend = D3D11_BLEND_ZERO; - dstTargetBlendDesc.DestBlendAlpha = D3D11_BLEND_ZERO; + dstTarget.BlendEnable = false; + dstTarget.BlendOp = D3D11_BLEND_OP_ADD; + dstTarget.BlendOpAlpha = D3D11_BLEND_OP_ADD; + dstTarget.SrcBlend = D3D11_BLEND_ONE; + dstTarget.SrcBlendAlpha = D3D11_BLEND_ONE; + dstTarget.DestBlend = D3D11_BLEND_ZERO; + dstTarget.DestBlendAlpha = D3D11_BLEND_ZERO; } else { - dstTargetBlendDesc.BlendEnable = true; - dstTargetBlendDesc.BlendOp = translateBlendOp(srcTargetBlendDesc.color.op); - dstTargetBlendDesc.BlendOpAlpha = translateBlendOp(srcTargetBlendDesc.alpha.op); - dstTargetBlendDesc.SrcBlend = translateBlendFactor(srcTargetBlendDesc.color.srcFactor); - dstTargetBlendDesc.SrcBlendAlpha = translateBlendFactor(srcTargetBlendDesc.alpha.srcFactor); - dstTargetBlendDesc.DestBlend = translateBlendFactor(srcTargetBlendDesc.color.dstFactor); - dstTargetBlendDesc.DestBlendAlpha = translateBlendFactor(srcTargetBlendDesc.alpha.dstFactor); + dstTarget.BlendEnable = true; + dstTarget.BlendOp = translateBlendOp(srcTarget.color.op); + dstTarget.BlendOpAlpha = translateBlendOp(srcTarget.alpha.op); + dstTarget.SrcBlend = translateBlendFactor(srcTarget.color.srcFactor); + dstTarget.SrcBlendAlpha = translateBlendFactor(srcTarget.alpha.srcFactor); + dstTarget.DestBlend = translateBlendFactor(srcTarget.color.dstFactor); + dstTarget.DestBlendAlpha = translateBlendFactor(srcTarget.alpha.dstFactor); } - dstTargetBlendDesc.RenderTargetWriteMask = translateRenderTargetWriteMask(srcTargetBlendDesc.writeMask); + dstTarget.RenderTargetWriteMask = translateRenderTargetWriteMask(srcTarget.writeMask); } dstDesc.IndependentBlendEnable = targetCount > 1; - dstDesc.AlphaToCoverageEnable = srcDesc.alphaToCoverageEnable; + dstDesc.AlphaToCoverageEnable = desc.multisample.alphaToCoverageEnable; SLANG_RETURN_ON_FAIL(m_device->CreateBlendState(&dstDesc, blendState.writeRef())); } @@ -1664,7 +1663,7 @@ Result DeviceImpl::createRenderPipeline(const RenderPipelineDesc& inDesc, IPipel pipeline->m_rasterizerState = rasterizerState; pipeline->m_blendState = blendState; pipeline->m_inputLayout = static_cast(desc.inputLayout); - pipeline->m_rtvCount = desc.framebufferLayout.renderTargetCount; + pipeline->m_rtvCount = desc.targetCount; pipeline->m_blendColor[0] = 0; pipeline->m_blendColor[1] = 0; pipeline->m_blendColor[2] = 0; diff --git a/src/d3d11/d3d11-device.h b/src/d3d11/d3d11-device.h index a2bece51..35bcf0e7 100644 --- a/src/d3d11/d3d11-device.h +++ b/src/d3d11/d3d11-device.h @@ -113,13 +113,9 @@ class DeviceImpl : public ImmediateRendererBase ComPtr m_backBufferTexture; ComPtr m_dxgiFactory; - short_vector m_d3dRenderTargetViews; + short_vector m_d3dRenderTargetViews; ID3D11DepthStencilView* m_d3dDepthStencilView; - RefPtr m_currentColorAttachments[kMaxRenderTargetCount]; - GfxCount m_currentColorAttachmentCount = 0; - RefPtr m_currentDepthStencilAttachment; - RefPtr m_currentPipeline; ComPtr m_disjointQuery; diff --git a/src/d3d11/d3d11-helper-functions.cpp b/src/d3d11/d3d11-helper-functions.cpp index 40279d2d..81b8089e 100644 --- a/src/d3d11/d3d11-helper-functions.cpp +++ b/src/d3d11/d3d11-helper-functions.cpp @@ -218,7 +218,7 @@ bool isBlendDisabled(AspectBlendDesc const& desc) return desc.op == BlendOp::Add && desc.srcFactor == BlendFactor::One && desc.dstFactor == BlendFactor::Zero; } -bool isBlendDisabled(TargetBlendDesc const& desc) +bool isBlendDisabled(ColorTargetState const& desc) { return isBlendDisabled(desc.color) && isBlendDisabled(desc.alpha); } diff --git a/src/d3d11/d3d11-helper-functions.h b/src/d3d11/d3d11-helper-functions.h index 470c248d..1c6d30d1 100644 --- a/src/d3d11/d3d11-helper-functions.h +++ b/src/d3d11/d3d11-helper-functions.h @@ -255,7 +255,7 @@ D3D11_STENCIL_OP translateStencilOp(StencilOp op); D3D11_FILL_MODE translateFillMode(FillMode mode); D3D11_CULL_MODE translateCullMode(CullMode mode); bool isBlendDisabled(AspectBlendDesc const& desc); -bool isBlendDisabled(TargetBlendDesc const& desc); +bool isBlendDisabled(ColorTargetState const& desc); D3D11_BLEND_OP translateBlendOp(BlendOp op); D3D11_BLEND translateBlendFactor(BlendFactor factor); D3D11_COLOR_WRITE_ENABLE translateRenderTargetWriteMask(RenderTargetWriteMaskT mask); diff --git a/src/d3d12/d3d12-command-encoder.cpp b/src/d3d12/d3d12-command-encoder.cpp index 48db2a46..16f5aeb7 100644 --- a/src/d3d12/d3d12-command-encoder.cpp +++ b/src/d3d12/d3d12-command-encoder.cpp @@ -804,7 +804,7 @@ void RenderCommandEncoderImpl::init( m_renderTargetViews.resize(desc.colorAttachmentCount); m_renderTargetFinalStates.resize(desc.colorAttachmentCount); - static_vector renderTargetDescriptors; + short_vector renderTargetDescriptors; for (Index i = 0; i < desc.colorAttachmentCount; i++) { m_renderTargetViews[i] = static_cast(desc.colorAttachments[i].view); diff --git a/src/d3d12/d3d12-command-encoder.h b/src/d3d12/d3d12-command-encoder.h index ae1d0947..eeb42a5d 100644 --- a/src/d3d12/d3d12-command-encoder.h +++ b/src/d3d12/d3d12-command-encoder.h @@ -166,8 +166,8 @@ class RenderCommandEncoderImpl : public IRenderCommandEncoder, public CommandEnc } public: - static_vector, kMaxRenderTargetCount> m_renderTargetViews; - static_vector m_renderTargetFinalStates; + short_vector> m_renderTargetViews; + short_vector m_renderTargetFinalStates; RefPtr m_depthStencilView; ResourceState m_depthStencilFinalState; diff --git a/src/d3d12/d3d12-pipeline.cpp b/src/d3d12/d3d12-pipeline.cpp index 2169a601..eaaf95aa 100644 --- a/src/d3d12/d3d12-pipeline.cpp +++ b/src/d3d12/d3d12-pipeline.cpp @@ -19,19 +19,19 @@ namespace rhi::d3d12 { -void PipelineImpl::init(const RenderPipelineDesc& inDesc) +void PipelineImpl::init(const RenderPipelineDesc& desc) { PipelineStateDesc pipelineDesc; pipelineDesc.type = PipelineType::Graphics; - pipelineDesc.graphics = inDesc; + pipelineDesc.graphics = desc; initializeBase(pipelineDesc); } -void PipelineImpl::init(const ComputePipelineDesc& inDesc) +void PipelineImpl::init(const ComputePipelineDesc& desc) { PipelineStateDesc pipelineDesc; pipelineDesc.type = PipelineType::Compute; - pipelineDesc.compute = inDesc; + pipelineDesc.compute = desc; initializeBase(pipelineDesc); } @@ -65,13 +65,12 @@ Result PipelineImpl::ensureAPIPipelineCreated() psoDesc.PrimitiveTopologyType = D3DUtil::getPrimitiveType(desc.graphics.primitiveType); - const auto& framebufferLayout = desc.graphics.framebufferLayout; - const int numRenderTargets = int(framebufferLayout.renderTargetCount); + const int numRenderTargets = desc.graphics.targetCount; { - if (framebufferLayout.depthStencil.format != Format::Unknown) + if (desc.graphics.depthStencil.format != Format::Unknown) { - psoDesc.DSVFormat = D3DUtil::getMapFormat(framebufferLayout.depthStencil.format); + psoDesc.DSVFormat = D3DUtil::getMapFormat(desc.graphics.depthStencil.format); } else { @@ -80,12 +79,12 @@ Result PipelineImpl::ensureAPIPipelineCreated() psoDesc.NumRenderTargets = numRenderTargets; for (Int i = 0; i < numRenderTargets; i++) { - psoDesc.RTVFormats[i] = D3DUtil::getMapFormat(framebufferLayout.renderTargets[0].format); + psoDesc.RTVFormats[i] = D3DUtil::getMapFormat(desc.graphics.targets[i].format); } - psoDesc.SampleDesc.Count = framebufferLayout.sampleCount; + psoDesc.SampleDesc.Count = desc.graphics.multisample.sampleCount; psoDesc.SampleDesc.Quality = 0; - psoDesc.SampleMask = UINT_MAX; + psoDesc.SampleMask = desc.graphics.multisample.sampleMask; } { @@ -109,29 +108,32 @@ Result PipelineImpl::ensureAPIPipelineCreated() { D3D12_BLEND_DESC& blend = psoDesc.BlendState; blend.IndependentBlendEnable = FALSE; - blend.AlphaToCoverageEnable = desc.graphics.blend.alphaToCoverageEnable ? TRUE : FALSE; + blend.AlphaToCoverageEnable = desc.graphics.multisample.alphaToCoverageEnable ? TRUE : FALSE; blend.RenderTarget[0].RenderTargetWriteMask = (uint8_t)RenderTargetWriteMask::EnableAll; for (GfxIndex i = 0; i < numRenderTargets; i++) { auto& d3dDesc = blend.RenderTarget[i]; - d3dDesc.BlendEnable = desc.graphics.blend.targets[i].enableBlend ? TRUE : FALSE; - d3dDesc.BlendOp = D3DUtil::getBlendOp(desc.graphics.blend.targets[i].color.op); - d3dDesc.BlendOpAlpha = D3DUtil::getBlendOp(desc.graphics.blend.targets[i].alpha.op); - d3dDesc.DestBlend = D3DUtil::getBlendFactor(desc.graphics.blend.targets[i].color.dstFactor); - d3dDesc.DestBlendAlpha = D3DUtil::getBlendFactor(desc.graphics.blend.targets[i].alpha.dstFactor); + d3dDesc.BlendEnable = desc.graphics.targets[i].enableBlend ? TRUE : FALSE; + d3dDesc.BlendOp = D3DUtil::getBlendOp(desc.graphics.targets[i].color.op); + d3dDesc.BlendOpAlpha = D3DUtil::getBlendOp(desc.graphics.targets[i].alpha.op); + d3dDesc.DestBlend = D3DUtil::getBlendFactor(desc.graphics.targets[i].color.dstFactor); + d3dDesc.DestBlendAlpha = D3DUtil::getBlendFactor(desc.graphics.targets[i].alpha.dstFactor); d3dDesc.LogicOp = D3D12_LOGIC_OP_NOOP; d3dDesc.LogicOpEnable = FALSE; - d3dDesc.RenderTargetWriteMask = desc.graphics.blend.targets[i].writeMask; - d3dDesc.SrcBlend = D3DUtil::getBlendFactor(desc.graphics.blend.targets[i].color.srcFactor); - d3dDesc.SrcBlendAlpha = D3DUtil::getBlendFactor(desc.graphics.blend.targets[i].alpha.srcFactor); + d3dDesc.RenderTargetWriteMask = desc.graphics.targets[i].writeMask; + d3dDesc.SrcBlend = D3DUtil::getBlendFactor(desc.graphics.targets[i].color.srcFactor); + d3dDesc.SrcBlendAlpha = D3DUtil::getBlendFactor(desc.graphics.targets[i].alpha.srcFactor); } + auto equalBlendState = [](const ColorTargetState& a, const ColorTargetState& b) + { + return a.enableBlend == b.enableBlend && a.color.op == b.color.op && + a.color.srcFactor == b.color.srcFactor && a.color.dstFactor == b.color.dstFactor && + a.alpha.op == b.alpha.op && a.alpha.srcFactor == b.alpha.srcFactor && + a.alpha.dstFactor == b.alpha.dstFactor && a.writeMask == b.writeMask; + }; for (GfxIndex i = 1; i < numRenderTargets; i++) { - if (memcmp( - &desc.graphics.blend.targets[i], - &desc.graphics.blend.targets[0], - sizeof(desc.graphics.blend.targets[0]) - ) != 0) + if (!equalBlendState(desc.graphics.targets[i], desc.graphics.targets[0])) { blend.IndependentBlendEnable = TRUE; break; @@ -344,11 +346,11 @@ RayTracingPipelineImpl::RayTracingPipelineImpl(DeviceImpl* device) { } -void RayTracingPipelineImpl::init(const RayTracingPipelineDesc& inDesc) +void RayTracingPipelineImpl::init(const RayTracingPipelineDesc& desc) { PipelineStateDesc pipelineDesc; pipelineDesc.type = PipelineType::RayTracing; - pipelineDesc.rayTracing.set(inDesc); + pipelineDesc.rayTracing = desc; initializeBase(pipelineDesc); } @@ -451,26 +453,26 @@ Result RayTracingPipelineImpl::ensureAPIPipelineCreated() } } - for (Index i = 0; i < desc.rayTracing.hitGroupDescs.size(); i++) + for (Index i = 0; i < desc.rayTracing.hitGroupCount; i++) { auto& hitGroup = desc.rayTracing.hitGroups[i]; D3D12_HIT_GROUP_DESC hitGroupDesc = {}; - hitGroupDesc.Type = hitGroup.intersectionEntryPoint.empty() ? D3D12_HIT_GROUP_TYPE_TRIANGLES - : D3D12_HIT_GROUP_TYPE_PROCEDURAL_PRIMITIVE; + hitGroupDesc.Type = hitGroup.intersectionEntryPoint ? D3D12_HIT_GROUP_TYPE_PROCEDURAL_PRIMITIVE + : D3D12_HIT_GROUP_TYPE_TRIANGLES; - if (!hitGroup.anyHitEntryPoint.empty()) + if (hitGroup.anyHitEntryPoint) { - hitGroupDesc.AnyHitShaderImport = getWStr(hitGroup.anyHitEntryPoint.data()); + hitGroupDesc.AnyHitShaderImport = getWStr(hitGroup.anyHitEntryPoint); } - if (!hitGroup.closestHitEntryPoint.empty()) + if (hitGroup.closestHitEntryPoint) { - hitGroupDesc.ClosestHitShaderImport = getWStr(hitGroup.closestHitEntryPoint.data()); + hitGroupDesc.ClosestHitShaderImport = getWStr(hitGroup.closestHitEntryPoint); } - if (!hitGroup.intersectionEntryPoint.empty()) + if (hitGroup.intersectionEntryPoint) { - hitGroupDesc.IntersectionShaderImport = getWStr(hitGroup.intersectionEntryPoint.data()); + hitGroupDesc.IntersectionShaderImport = getWStr(hitGroup.intersectionEntryPoint); } - hitGroupDesc.HitGroupExport = getWStr(hitGroup.hitGroupName.data()); + hitGroupDesc.HitGroupExport = getWStr(hitGroup.hitGroupName); D3D12_STATE_SUBOBJECT hitGroupSubObject = {}; hitGroupSubObject.Type = D3D12_STATE_SUBOBJECT_TYPE_HIT_GROUP; diff --git a/src/metal/metal-command-encoder.h b/src/metal/metal-command-encoder.h index a4281efa..3b84acff 100644 --- a/src/metal/metal-command-encoder.h +++ b/src/metal/metal-command-encoder.h @@ -149,7 +149,7 @@ class RenderCommandEncoderImpl : public IRenderCommandEncoder, public CommandEnc public: NS::SharedPtr m_renderPassDesc; - static_vector, kMaxRenderTargetCount> m_renderTargetViews; + short_vector> m_renderTargetViews; RefPtr m_depthStencilView; short_vector m_viewports; diff --git a/src/renderer-shared.cpp b/src/renderer-shared.cpp index 3e73ee41..9ed516f6 100644 --- a/src/renderer-shared.cpp +++ b/src/renderer-shared.cpp @@ -231,6 +231,16 @@ void PipelineBase::initializeBase(const PipelineStateDesc& inDesc) { desc = inDesc; + descHolder.holdList(desc.graphics.targets, desc.graphics.targetCount); + descHolder.holdList(desc.rayTracing.hitGroups, desc.rayTracing.hitGroupCount); + for (Index i = 0; i < desc.rayTracing.hitGroupCount; i++) + { + descHolder.holdString(desc.rayTracing.hitGroups[i].hitGroupName); + descHolder.holdString(desc.rayTracing.hitGroups[i].closestHitEntryPoint); + descHolder.holdString(desc.rayTracing.hitGroups[i].anyHitEntryPoint); + descHolder.holdString(desc.rayTracing.hitGroups[i].intersectionEntryPoint); + } + auto program = desc.getProgram(); m_program = program; isSpecializable = false; @@ -1006,8 +1016,7 @@ Result RendererBase::maybeSpecializePipeline( { auto pipelineDesc = currentPipeline->desc.rayTracing; pipelineDesc.program = static_cast(specializedProgram.get()); - SLANG_RETURN_ON_FAIL(createRayTracingPipeline(pipelineDesc.get(), specializedPipelineComPtr.writeRef()) - ); + SLANG_RETURN_ON_FAIL(createRayTracingPipeline(pipelineDesc, specializedPipelineComPtr.writeRef())); break; } default: diff --git a/src/renderer-shared.h b/src/renderer-shared.h index 3adc59da..0bec7d68 100644 --- a/src/renderer-shared.h +++ b/src/renderer-shared.h @@ -836,79 +836,6 @@ enum class PipelineType CountOf, }; -struct OwnedHitGroupDesc -{ - std::string hitGroupName; - std::string closestHitEntryPoint; - std::string anyHitEntryPoint; - std::string intersectionEntryPoint; - - void set(const HitGroupDesc& desc) - { - hitGroupName = desc.hitGroupName ? desc.hitGroupName : ""; - closestHitEntryPoint = desc.closestHitEntryPoint ? desc.closestHitEntryPoint : ""; - anyHitEntryPoint = desc.anyHitEntryPoint ? desc.anyHitEntryPoint : ""; - intersectionEntryPoint = desc.intersectionEntryPoint ? desc.intersectionEntryPoint : ""; - } - - HitGroupDesc get() - { - HitGroupDesc desc; - desc.hitGroupName = hitGroupName.data(); - desc.closestHitEntryPoint = closestHitEntryPoint.data(); - desc.anyHitEntryPoint = anyHitEntryPoint.data(); - desc.intersectionEntryPoint = intersectionEntryPoint.data(); - return desc; - } -}; - -struct OwnedRayTracingPipelineDesc -{ - RefPtr program; - std::vector hitGroups; - std::vector hitGroupDescs; - int maxRecursion = 0; - Size maxRayPayloadSize = 0; - Size maxAttributeSizeInBytes = 8; - RayTracingPipelineFlags::Enum flags = RayTracingPipelineFlags::None; - - RayTracingPipelineDesc get() - { - // TODO horrible hack to update the c-strings after this struct is copied. - for (int32_t i = 0; i < hitGroupDescs.size(); i++) - { - hitGroupDescs[i] = hitGroups[i].get(); - } - RayTracingPipelineDesc desc; - desc.program = program.Ptr(); - desc.hitGroupCount = (int32_t)hitGroupDescs.size(); - desc.hitGroups = hitGroupDescs.data(); - desc.maxRecursion = maxRecursion; - desc.maxRayPayloadSize = maxRayPayloadSize; - desc.maxAttributeSizeInBytes = maxAttributeSizeInBytes; - desc.flags = flags; - return desc; - } - - void set(const RayTracingPipelineDesc& inDesc) - { - program = static_cast(inDesc.program); - hitGroups.resize(inDesc.hitGroupCount); - hitGroupDescs.resize(inDesc.hitGroupCount); - for (int32_t i = 0; i < inDesc.hitGroupCount; i++) - { - OwnedHitGroupDesc ownedHitGroupDesc; - ownedHitGroupDesc.set(inDesc.hitGroups[i]); - hitGroups[i] = ownedHitGroupDesc; - hitGroupDescs[i] = hitGroups[i].get(); - } - maxRecursion = inDesc.maxRecursion; - maxRayPayloadSize = inDesc.maxRayPayloadSize; - maxAttributeSizeInBytes = inDesc.maxAttributeSizeInBytes; - flags = inDesc.flags; - } -}; - class PipelineBase : public IPipeline, public ComObject { public: @@ -920,7 +847,7 @@ class PipelineBase : public IPipeline, public ComObject PipelineType type; RenderPipelineDesc graphics; ComputePipelineDesc compute; - OwnedRayTracingPipelineDesc rayTracing; + RayTracingPipelineDesc rayTracing; ShaderProgramBase* getProgram() { switch (type) @@ -936,6 +863,8 @@ class PipelineBase : public IPipeline, public ComObject } } desc; + StructHolder descHolder; + // We need to hold inputLayout object alive, since we may use it to // create specialized pipeline states later. RefPtr inputLayout; diff --git a/src/vulkan/vk-command-encoder.cpp b/src/vulkan/vk-command-encoder.cpp index 25080313..5ba59fc2 100644 --- a/src/vulkan/vk-command-encoder.cpp +++ b/src/vulkan/vk-command-encoder.cpp @@ -1061,6 +1061,8 @@ Result RenderCommandEncoderImpl::beginPass(const RenderPassDesc& desc) renderingInfo.pStencilAttachment = hasStencilAttachment ? &stencilAttachmentInfo : nullptr; api.vkCmdBeginRenderingKHR(m_vkCommandBuffer, &renderingInfo); + + return SLANG_OK; } void RenderCommandEncoderImpl::endEncoding() diff --git a/src/vulkan/vk-command-encoder.h b/src/vulkan/vk-command-encoder.h index 43122682..6cf68bef 100644 --- a/src/vulkan/vk-command-encoder.h +++ b/src/vulkan/vk-command-encoder.h @@ -175,8 +175,8 @@ class RenderCommandEncoderImpl : public IRenderCommandEncoder, public CommandEnc } public: - static_vector, kMaxRenderTargetCount> m_renderTargetViews; - static_vector m_renderTargetFinalStates; + short_vector> m_renderTargetViews; + short_vector m_renderTargetFinalStates; RefPtr m_depthStencilView; ResourceState m_depthStencilCurrentState; ResourceState m_depthStencilFinalState; diff --git a/src/vulkan/vk-pipeline.cpp b/src/vulkan/vk-pipeline.cpp index 87da2d3d..3009c7a5 100644 --- a/src/vulkan/vk-pipeline.cpp +++ b/src/vulkan/vk-pipeline.cpp @@ -62,7 +62,7 @@ void PipelineImpl::init(const RayTracingPipelineDesc& inDesc) { PipelineStateDesc pipelineDesc; pipelineDesc.type = PipelineType::RayTracing; - pipelineDesc.rayTracing.set(inDesc); + pipelineDesc.rayTracing = inDesc; initializeBase(pipelineDesc); } @@ -141,20 +141,19 @@ Result PipelineImpl::createVKGraphicsPipeline() rasterizer.pNext = &conservativeRasterInfo; } - const auto& framebufferLayout = desc.graphics.framebufferLayout; auto forcedSampleCount = rasterizerDesc.forcedSampleCount; - auto blendDesc = desc.graphics.blend; VkPipelineMultisampleStateCreateInfo multisampling = {}; multisampling.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; - multisampling.rasterizationSamples = (forcedSampleCount == 0) ? VkSampleCountFlagBits(framebufferLayout.sampleCount) - : VulkanUtil::translateSampleCount(forcedSampleCount); + multisampling.rasterizationSamples = (forcedSampleCount == 0) + ? VkSampleCountFlagBits(desc.graphics.multisample.sampleCount) + : VulkanUtil::translateSampleCount(forcedSampleCount); multisampling.sampleShadingEnable = VK_FALSE; // TODO: Should check if fragment shader needs this // TODO: Sample mask is dynamic in D3D12 but PSO state in Vulkan - multisampling.alphaToCoverageEnable = blendDesc.alphaToCoverageEnable; - multisampling.alphaToOneEnable = VK_FALSE; + multisampling.alphaToCoverageEnable = desc.graphics.multisample.alphaToCoverageEnable; + multisampling.alphaToOneEnable = desc.graphics.multisample.alphaToOneEnable; - auto targetCount = framebufferLayout.renderTargetCount; + auto targetCount = desc.graphics.targetCount; std::vector colorBlendTargets; // Regardless of whether blending is enabled, Vulkan always applies the color write mask @@ -179,17 +178,17 @@ Result PipelineImpl::createVKGraphicsPipeline() colorBlendTargets.resize(targetCount); for (GfxIndex i = 0; i < targetCount; ++i) { - auto& rhiBlendDesc = blendDesc.targets[i]; + auto& target = desc.graphics.targets[i]; auto& vkBlendDesc = colorBlendTargets[i]; - vkBlendDesc.blendEnable = rhiBlendDesc.enableBlend; - vkBlendDesc.srcColorBlendFactor = VulkanUtil::translateBlendFactor(rhiBlendDesc.color.srcFactor); - vkBlendDesc.dstColorBlendFactor = VulkanUtil::translateBlendFactor(rhiBlendDesc.color.dstFactor); - vkBlendDesc.colorBlendOp = VulkanUtil::translateBlendOp(rhiBlendDesc.color.op); - vkBlendDesc.srcAlphaBlendFactor = VulkanUtil::translateBlendFactor(rhiBlendDesc.alpha.srcFactor); - vkBlendDesc.dstAlphaBlendFactor = VulkanUtil::translateBlendFactor(rhiBlendDesc.alpha.dstFactor); - vkBlendDesc.alphaBlendOp = VulkanUtil::translateBlendOp(rhiBlendDesc.alpha.op); - vkBlendDesc.colorWriteMask = (VkColorComponentFlags)rhiBlendDesc.writeMask; + vkBlendDesc.blendEnable = target.enableBlend; + vkBlendDesc.srcColorBlendFactor = VulkanUtil::translateBlendFactor(target.color.srcFactor); + vkBlendDesc.dstColorBlendFactor = VulkanUtil::translateBlendFactor(target.color.dstFactor); + vkBlendDesc.colorBlendOp = VulkanUtil::translateBlendOp(target.color.op); + vkBlendDesc.srcAlphaBlendFactor = VulkanUtil::translateBlendFactor(target.alpha.srcFactor); + vkBlendDesc.dstAlphaBlendFactor = VulkanUtil::translateBlendFactor(target.alpha.dstFactor); + vkBlendDesc.alphaBlendOp = VulkanUtil::translateBlendOp(target.alpha.op); + vkBlendDesc.colorWriteMask = (VkColorComponentFlags)target.writeMask; } } @@ -238,16 +237,16 @@ Result PipelineImpl::createVKGraphicsPipeline() depthStencilStateInfo.stencilTestEnable = desc.graphics.depthStencil.stencilEnable ? 1 : 0; VkPipelineRenderingCreateInfoKHR renderingInfo = {VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR}; - static_vector colorAttachmentFormats; - for (GfxIndex i = 0; i < framebufferLayout.renderTargetCount; ++i) + short_vector colorAttachmentFormats; + for (GfxIndex i = 0; i < desc.graphics.targetCount; ++i) { - colorAttachmentFormats.push_back(VulkanUtil::getVkFormat(framebufferLayout.renderTargets[i].format)); + colorAttachmentFormats.push_back(VulkanUtil::getVkFormat(desc.graphics.targets[i].format)); } renderingInfo.colorAttachmentCount = colorAttachmentFormats.size(); renderingInfo.pColorAttachmentFormats = colorAttachmentFormats.data(); - renderingInfo.depthAttachmentFormat = VulkanUtil::getVkFormat(framebufferLayout.depthStencil.format); + renderingInfo.depthAttachmentFormat = VulkanUtil::getVkFormat(desc.graphics.depthStencil.format); // TODO we should probably only set this when this is actually a stencil format - renderingInfo.stencilAttachmentFormat = VulkanUtil::getVkFormat(framebufferLayout.depthStencil.format); + renderingInfo.stencilAttachmentFormat = VulkanUtil::getVkFormat(desc.graphics.depthStencil.format); VkGraphicsPipelineCreateInfo pipelineInfo = {VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO}; pipelineInfo.pNext = &renderingInfo; @@ -416,7 +415,7 @@ Result RayTracingPipelineImpl::createVKRayTracingPipeline() shaderGroupNameToIndex.emplace(shaderGroupName, shaderGroupIndex); } - for (int32_t i = 0; i < desc.rayTracing.hitGroups.size(); ++i) + for (int32_t i = 0; i < desc.rayTracing.hitGroupCount; ++i) { VkRayTracingShaderGroupCreateInfoKHR shaderGroupInfo = { VK_STRUCTURE_TYPE_RAY_TRACING_SHADER_GROUP_CREATE_INFO_KHR @@ -424,16 +423,15 @@ Result RayTracingPipelineImpl::createVKRayTracingPipeline() auto& groupDesc = desc.rayTracing.hitGroups[i]; shaderGroupInfo.pNext = nullptr; - shaderGroupInfo.type = (!groupDesc.intersectionEntryPoint.empty()) + shaderGroupInfo.type = groupDesc.intersectionEntryPoint ? VK_RAY_TRACING_SHADER_GROUP_TYPE_PROCEDURAL_HIT_GROUP_KHR : VK_RAY_TRACING_SHADER_GROUP_TYPE_TRIANGLES_HIT_GROUP_KHR; shaderGroupInfo.generalShader = VK_SHADER_UNUSED_KHR; shaderGroupInfo.closestHitShader = - findEntryPointIndexByName(entryPointNameToIndex, groupDesc.closestHitEntryPoint.c_str()); - shaderGroupInfo.anyHitShader = - findEntryPointIndexByName(entryPointNameToIndex, groupDesc.anyHitEntryPoint.c_str()); + findEntryPointIndexByName(entryPointNameToIndex, groupDesc.closestHitEntryPoint); + shaderGroupInfo.anyHitShader = findEntryPointIndexByName(entryPointNameToIndex, groupDesc.anyHitEntryPoint); shaderGroupInfo.intersectionShader = - findEntryPointIndexByName(entryPointNameToIndex, groupDesc.intersectionEntryPoint.c_str()); + findEntryPointIndexByName(entryPointNameToIndex, groupDesc.intersectionEntryPoint); shaderGroupInfo.pShaderGroupCaptureReplayHandle = nullptr; auto shaderGroupIndex = Index(shaderGroupInfos.size()); diff --git a/tests/test-instanced-draw.cpp b/tests/test-instanced-draw.cpp index 5fc68578..30bfebb4 100644 --- a/tests/test-instanced-draw.cpp +++ b/tests/test-instanced-draw.cpp @@ -153,11 +153,13 @@ class BaseDrawTest slangReflection )); + ColorTargetState colorTarget; + colorTarget.format = format; RenderPipelineDesc pipelineDesc = {}; pipelineDesc.program = shaderProgram.get(); pipelineDesc.inputLayout = inputLayout; - pipelineDesc.framebufferLayout.renderTargets[0] = {format}; - pipelineDesc.framebufferLayout.renderTargetCount = 1; + pipelineDesc.targets = &colorTarget; + pipelineDesc.targetCount = 1; pipelineDesc.depthStencil.depthTestEnable = false; pipelineDesc.depthStencil.depthWriteEnable = false; REQUIRE_CALL(device->createRenderPipeline(pipelineDesc, pipeline.writeRef())); diff --git a/tests/test-resolve-resource-tests.cpp b/tests/test-resolve-resource-tests.cpp index 924e2996..bfbc64e4 100644 --- a/tests/test-resolve-resource-tests.cpp +++ b/tests/test-resolve-resource-tests.cpp @@ -135,14 +135,16 @@ struct BaseResolveResourceTest )); + ColorTargetState target; + target.format = format; RenderPipelineDesc pipelineDesc = {}; pipelineDesc.program = shaderProgram.get(); pipelineDesc.inputLayout = inputLayout; - pipelineDesc.framebufferLayout.renderTargets[0] = {format}; - pipelineDesc.framebufferLayout.renderTargetCount = 1; - pipelineDesc.framebufferLayout.sampleCount = 4; + pipelineDesc.targets = ⌖ + pipelineDesc.targetCount = 1; pipelineDesc.depthStencil.depthTestEnable = false; pipelineDesc.depthStencil.depthWriteEnable = false; + pipelineDesc.multisample.sampleCount = 4; REQUIRE_CALL(device->createRenderPipeline(pipelineDesc, pipeline.writeRef())); IResourceView::Desc colorBufferViewDesc; diff --git a/tests/test-shader-cache.cpp b/tests/test-shader-cache.cpp index 5f32bfa7..372b173d 100644 --- a/tests/test-shader-cache.cpp +++ b/tests/test-shader-cache.cpp @@ -783,11 +783,13 @@ struct ShaderCacheTestGraphics : ShaderCacheTest slangReflection )); + ColorTargetState target; + target.format = format; RenderPipelineDesc pipelineDesc = {}; pipelineDesc.program = shaderProgram.get(); pipelineDesc.inputLayout = inputLayout; - pipelineDesc.framebufferLayout.renderTargets[0] = {format}; - pipelineDesc.framebufferLayout.renderTargetCount = 1; + pipelineDesc.targets = ⌖ + pipelineDesc.targetCount = 1; pipelineDesc.depthStencil.depthTestEnable = false; pipelineDesc.depthStencil.depthWriteEnable = false; REQUIRE_CALL(device->createRenderPipeline(pipelineDesc, pipeline.writeRef())); @@ -902,11 +904,13 @@ struct ShaderCacheTestGraphicsSplit : ShaderCacheTestGraphics ComPtr shaderProgram = device->createShaderProgram(programDesc); + ColorTargetState target; + target.format = format; RenderPipelineDesc pipelineDesc = {}; pipelineDesc.program = shaderProgram.get(); pipelineDesc.inputLayout = inputLayout; - pipelineDesc.framebufferLayout.renderTargets[0] = {format}; - pipelineDesc.framebufferLayout.renderTargetCount = 1; + pipelineDesc.targets = ⌖ + pipelineDesc.targetCount = 1; pipelineDesc.depthStencil.depthTestEnable = false; pipelineDesc.depthStencil.depthWriteEnable = false; REQUIRE_CALL(device->createRenderPipeline(pipelineDesc, pipeline.writeRef())); diff --git a/tests/test-shared-buffer.cpp b/tests/test-shared-buffer.cpp index af93428c..aa3cf3f2 100644 --- a/tests/test-shared-buffer.cpp +++ b/tests/test-shared-buffer.cpp @@ -91,6 +91,9 @@ void testSharedBuffer(GpuTestContext* ctx, DeviceType deviceType) #if SLANG_WIN64 TEST_CASE("shared-buffer-cuda") { + if (!rhiIsDeviceTypeSupported(DeviceType::CUDA)) + SKIP("CUDA not supported"); + runGpuTests( testSharedBuffer, { diff --git a/tests/test-shared-texture.cpp b/tests/test-shared-texture.cpp index 94c38f9c..1e270ada 100644 --- a/tests/test-shared-texture.cpp +++ b/tests/test-shared-texture.cpp @@ -195,6 +195,9 @@ void testSharedTexture(GpuTestContext* ctx, DeviceType deviceType) #if SLANG_WIN64 TEST_CASE("shared-texture-cuda") { + if (!rhiIsDeviceTypeSupported(DeviceType::CUDA)) + SKIP("CUDA not supported"); + runGpuTests( testSharedTexture, { diff --git a/tests/test-texture-types.cpp b/tests/test-texture-types.cpp index e27aead3..dcf73eff 100644 --- a/tests/test-texture-types.cpp +++ b/tests/test-texture-types.cpp @@ -417,14 +417,16 @@ struct RenderTargetTests : BaseTextureViewTest slangReflection )); + ColorTargetState target; + target.format = textureInfo->format; RenderPipelineDesc pipelineDesc = {}; pipelineDesc.program = shaderProgram.get(); pipelineDesc.inputLayout = inputLayout; - pipelineDesc.framebufferLayout.renderTargets[0] = {textureInfo->format}; - pipelineDesc.framebufferLayout.renderTargetCount = 1; - pipelineDesc.framebufferLayout.sampleCount = sampleCount; + pipelineDesc.targets = ⌖ + pipelineDesc.targetCount = 1; pipelineDesc.depthStencil.depthTestEnable = false; pipelineDesc.depthStencil.depthWriteEnable = false; + pipelineDesc.multisample.sampleCount = sampleCount; REQUIRE_CALL(device->createRenderPipeline(pipelineDesc, pipeline.writeRef())); IResourceView::Desc colorBufferViewDesc; From 95f759bd0a7a3fc4bb059f1f9177eab8a091ecae Mon Sep 17 00:00:00 2001 From: Simon Kallweit Date: Sat, 7 Sep 2024 00:30:21 +0200 Subject: [PATCH 8/8] metal fixes --- src/metal/metal-command-encoder.cpp | 1 - src/metal/metal-command-encoder.h | 1 - src/metal/metal-pipeline.cpp | 40 ++++++++++++----------------- 3 files changed, 17 insertions(+), 25 deletions(-) diff --git a/src/metal/metal-command-encoder.cpp b/src/metal/metal-command-encoder.cpp index 417ef889..659eabe7 100644 --- a/src/metal/metal-command-encoder.cpp +++ b/src/metal/metal-command-encoder.cpp @@ -440,7 +440,6 @@ Result RenderCommandEncoderImpl::prepareDraw(MTL::RenderCommandEncoder*& encoder encoder->setScissorRects(m_scissorRects.data(), m_scissorRects.size()); const RasterizerDesc& rasterDesc = pipeline->desc.graphics.rasterizer; - const DepthStencilDesc& depthStencilDesc = pipeline->desc.graphics.depthStencil; encoder->setFrontFacingWinding(MetalUtil::translateWinding(rasterDesc.frontFace)); encoder->setCullMode(MetalUtil::translateCullMode(rasterDesc.cullMode)); encoder->setDepthClipMode( diff --git a/src/metal/metal-command-encoder.h b/src/metal/metal-command-encoder.h index 3b84acff..359761eb 100644 --- a/src/metal/metal-command-encoder.h +++ b/src/metal/metal-command-encoder.h @@ -4,7 +4,6 @@ #include "metal-pipeline.h" #include "core/short_vector.h" -#include "core/static_vector.h" namespace rhi::metal { diff --git a/src/metal/metal-pipeline.cpp b/src/metal/metal-pipeline.cpp index 3ab16987..8552d473 100644 --- a/src/metal/metal-pipeline.cpp +++ b/src/metal/metal-pipeline.cpp @@ -34,7 +34,7 @@ void PipelineImpl::init(const RayTracingPipelineDesc& desc) { PipelineStateDesc pipelineDesc; pipelineDesc.type = PipelineType::RayTracing; - pipelineDesc.rayTracing.set(desc); + pipelineDesc.rayTracing = desc; initializeBase(pipelineDesc); } @@ -76,34 +76,28 @@ Result PipelineImpl::createMetalRenderPipelineState() pd->setVertexDescriptor(vertexDescriptor.get()); pd->setInputPrimitiveTopology(MetalUtil::translatePrimitiveTopologyClass(desc.graphics.primitiveType)); - // Set rasterization state - const auto& framebufferLayout = desc.graphics.framebufferLayout; - const auto& blend = desc.graphics.blend; - - pd->setAlphaToCoverageEnabled(blend.alphaToCoverageEnable); + pd->setAlphaToCoverageEnabled(desc.graphics.multisample.alphaToCoverageEnable); // pd->setAlphaToOneEnabled(); // Currently not supported by rhi // pd->setRasterizationEnabled(true); // Enabled by default - for (Index i = 0; i < framebufferLayout.renderTargetCount; ++i) + for (Index i = 0; i < desc.graphics.targetCount; ++i) { - const TargetLayoutDesc& targetLayout = framebufferLayout.renderTargets[i]; + const ColorTargetState& targetState = desc.graphics.targets[i]; MTL::RenderPipelineColorAttachmentDescriptor* colorAttachment = pd->colorAttachments()->object(i); - colorAttachment->setPixelFormat(MetalUtil::translatePixelFormat(targetLayout.format)); - - const TargetBlendDesc& targetBlendDesc = blend.targets[i]; - colorAttachment->setBlendingEnabled(targetBlendDesc.enableBlend); - colorAttachment->setSourceRGBBlendFactor(MetalUtil::translateBlendFactor(targetBlendDesc.color.srcFactor)); - colorAttachment->setDestinationRGBBlendFactor(MetalUtil::translateBlendFactor(targetBlendDesc.color.dstFactor)); - colorAttachment->setRgbBlendOperation(MetalUtil::translateBlendOperation(targetBlendDesc.color.op)); - colorAttachment->setSourceAlphaBlendFactor(MetalUtil::translateBlendFactor(targetBlendDesc.alpha.srcFactor)); - colorAttachment->setDestinationAlphaBlendFactor(MetalUtil::translateBlendFactor(targetBlendDesc.alpha.dstFactor) - ); - colorAttachment->setAlphaBlendOperation(MetalUtil::translateBlendOperation(targetBlendDesc.alpha.op)); - colorAttachment->setWriteMask(MetalUtil::translateColorWriteMask(targetBlendDesc.writeMask)); + colorAttachment->setPixelFormat(MetalUtil::translatePixelFormat(targetState.format)); + + colorAttachment->setBlendingEnabled(targetState.enableBlend); + colorAttachment->setSourceRGBBlendFactor(MetalUtil::translateBlendFactor(targetState.color.srcFactor)); + colorAttachment->setDestinationRGBBlendFactor(MetalUtil::translateBlendFactor(targetState.color.dstFactor)); + colorAttachment->setRgbBlendOperation(MetalUtil::translateBlendOperation(targetState.color.op)); + colorAttachment->setSourceAlphaBlendFactor(MetalUtil::translateBlendFactor(targetState.alpha.srcFactor)); + colorAttachment->setDestinationAlphaBlendFactor(MetalUtil::translateBlendFactor(targetState.alpha.dstFactor)); + colorAttachment->setAlphaBlendOperation(MetalUtil::translateBlendOperation(targetState.alpha.op)); + colorAttachment->setWriteMask(MetalUtil::translateColorWriteMask(targetState.writeMask)); } - if (framebufferLayout.depthStencil.format != Format::Unknown) + if (desc.graphics.depthStencil.format != Format::Unknown) { - const TargetLayoutDesc& depthStencil = framebufferLayout.depthStencil; + const DepthStencilState& depthStencil = desc.graphics.depthStencil; MTL::PixelFormat pixelFormat = MetalUtil::translatePixelFormat(depthStencil.format); if (MetalUtil::isDepthFormat(pixelFormat)) { @@ -115,7 +109,7 @@ Result PipelineImpl::createMetalRenderPipelineState() } } - pd->setRasterSampleCount(framebufferLayout.sampleCount); + pd->setRasterSampleCount(desc.graphics.multisample.sampleCount); NS::Error* error; m_renderPipelineState = NS::TransferPtr(m_device->m_device->newRenderPipelineState(pd.get(), &error));