diff options
Diffstat (limited to 'tools/gfx/d3d12/render-d3d12.cpp')
| -rw-r--r-- | tools/gfx/d3d12/render-d3d12.cpp | 115 |
1 files changed, 53 insertions, 62 deletions
diff --git a/tools/gfx/d3d12/render-d3d12.cpp b/tools/gfx/d3d12/render-d3d12.cpp index 28c00d08e..4d5dfda80 100644 --- a/tools/gfx/d3d12/render-d3d12.cpp +++ b/tools/gfx/d3d12/render-d3d12.cpp @@ -8,6 +8,7 @@ #include "../transient-resource-heap-base.h" #include "../simple-render-pass-layout.h" #include "../d3d/d3d-swapchain.h" +#include "../mutable-shader-object.h" #include "core/slang-blob.h" #include "core/slang-basic.h" #include "core/slang-chunked-list.h" @@ -117,6 +118,8 @@ public: ShaderObjectLayoutBase** outLayout) override; virtual Result createShaderObject(ShaderObjectLayoutBase* layout, IShaderObject** outObject) override; + virtual Result createMutableShaderObject( + ShaderObjectLayoutBase* layout, IShaderObject** outObject) override; virtual SLANG_NO_THROW Result SLANG_MCALL createProgram(const IShaderProgram::Desc& desc, IShaderProgram** outProgram) override; @@ -248,18 +251,9 @@ public: } }; - class SamplerStateImpl : public ISamplerState, public ComObject + class SamplerStateImpl : public SamplerStateBase { public: - SLANG_COM_OBJECT_IUNKNOWN_ALL - - ISamplerState* getInterface(const Guid& guid) - { - if (guid == GfxGUID::IID_ISlangUnknown || guid == GfxGUID::IID_ISamplerState) - return static_cast<ISamplerState*>(this); - return nullptr; - } - public: D3D12Descriptor m_descriptor; Slang::RefPtr<D3D12GeneralDescriptorHeap> m_allocator; ~SamplerStateImpl() @@ -292,20 +286,9 @@ public: IFramebufferLayout::AttachmentLayout m_depthStencil; }; - class FramebufferImpl - : public IFramebuffer - , public ComObject + class FramebufferImpl : public FramebufferBase { public: - SLANG_COM_OBJECT_IUNKNOWN_ALL - IFramebuffer* getInterface(const Guid& guid) - { - if (guid == GfxGUID::IID_ISlangUnknown || guid == GfxGUID::IID_IFramebuffer) - return static_cast<IFramebuffer*>(this); - return nullptr; - } - - public: ShortList<RefPtr<ResourceViewImpl>> renderTargetViews; RefPtr<ResourceViewImpl> depthStencilView; ShortList<D3D12_CPU_DESCRIPTOR_HANDLE> renderTargetDescriptors; @@ -381,17 +364,9 @@ public: }; #endif - class QueryPoolImpl : public IQueryPool, public ComObject + class QueryPoolImpl : public QueryPoolBase { public: - SLANG_COM_OBJECT_IUNKNOWN_ALL - IQueryPool* getInterface(const Guid& guid) - { - if (guid == GfxGUID::IID_ISlangUnknown || guid == GfxGUID::IID_IQueryPool) - return static_cast<IQueryPool*>(this); - return nullptr; - } - public: Result init(const IQueryPool::Desc& desc, D3D12Device* device); virtual SLANG_NO_THROW Result SLANG_MCALL getResult(SlangInt queryIndex, SlangInt count, uint64_t* data) override @@ -604,10 +579,10 @@ public: } class TransientResourceHeapImpl - : public TransientResourceHeapBase<D3D12Device, BufferResourceImpl> + : public TransientResourceHeapBaseImpl<D3D12Device, BufferResourceImpl> { private: - typedef TransientResourceHeapBase<D3D12Device, BufferResourceImpl> Super; + typedef TransientResourceHeapBaseImpl<D3D12Device, BufferResourceImpl> Super; public: ComPtr<ID3D12CommandAllocator> m_commandAllocator; List<ComPtr<ID3D12GraphicsCommandList>> m_d3dCommandListPool; @@ -1280,6 +1255,7 @@ public: uint32_t getResourceSlotCount() { return m_ownCounts.resource; } uint32_t getSamplerSlotCount() { return m_ownCounts.sampler; } Index getSubObjectSlotCount() { return m_subObjectCount; } + Index getSubObjectCount() { return m_subObjectCount; } uint32_t getTotalResourceDescriptorCount() { return m_totalCounts.resource; } uint32_t getTotalSamplerDescriptorCount() { return m_totalCounts.sampler; } @@ -2012,9 +1988,9 @@ public: class ShaderObjectImpl : public ShaderObjectBaseImpl< - ShaderObjectImpl, - ShaderObjectLayoutImpl, - SimpleShaderObjectData> + ShaderObjectImpl, + ShaderObjectLayoutImpl, + SimpleShaderObjectData> { public: static Result create( @@ -2070,6 +2046,8 @@ public: memcpy(dest + offset, data, size); + m_isConstantBufferDirty = true; + return SLANG_OK; } @@ -2145,7 +2123,9 @@ public: m_layout = layout; - m_upToDateConstantBufferHeapVersion = 0; + m_constantBufferTransientHeap = nullptr; + m_constantBufferTransientHeapVersion = 0; + m_isConstantBufferDirty = true; // If the layout tells us that there is any uniform data, // then we will allocate a CPU memory buffer to hold that data @@ -2172,7 +2152,7 @@ public: // but does *not* include any descriptors that are managed // as part of sub-objects. // - if(auto resourceCount = layout->getResourceSlotCount()) + if (auto resourceCount = layout->getResourceSlotCount()) { m_descriptorSet.resourceTable.allocate(viewHeap, resourceCount); @@ -2182,7 +2162,7 @@ public: // m_boundResources.setCount(resourceCount); } - if(auto samplerCount = layout->getSamplerSlotCount()) + if (auto samplerCount = layout->getSamplerSlotCount()) { m_descriptorSet.samplerTable.allocate(samplerHeap, samplerCount); } @@ -2331,24 +2311,27 @@ public: return SLANG_OK; } + bool shouldAllocateConstantBuffer(TransientResourceHeapImpl* transientHeap) + { + return m_isConstantBufferDirty || m_constantBufferTransientHeap != transientHeap || + m_constantBufferTransientHeapVersion != transientHeap->getVersion(); + } + /// Ensure that the `m_ordinaryDataBuffer` has been created, if it is needed Result _ensureOrdinaryDataBufferCreatedIfNeeded( PipelineCommandEncoder* encoder, ShaderObjectLayoutImpl* specializedLayout) { - // If we have already created a buffer to hold ordinary data, then we should - // simply re-use that buffer rather than re-create it. - // - // TODO: Simply re-using the buffer without any kind of validation checks - // means that we are assuming that users cannot or will not perform any `set` - // operations on a shader object once an operation has requested this buffer - // be created. We need to enforce that rule if we want to rely on it. + // If data has been changed since last allocation/filling of constant buffer, + // we will need to allocate a new one. // - if (m_upToDateConstantBufferHeapVersion == - encoder->m_commandBuffer->m_transientHeap->getVersion()) + if (!shouldAllocateConstantBuffer(encoder->m_transientHeap)) { return SLANG_OK; } + m_isConstantBufferDirty = false; + m_constantBufferTransientHeap = encoder->m_transientHeap; + m_constantBufferTransientHeapVersion = encoder->m_transientHeap->getVersion(); // Computing the size of the ordinary data buffer is *not* just as simple // as using the size of the `m_ordinayData` array that we store. The reason @@ -2360,8 +2343,6 @@ public: m_constantBufferSize = specializedLayout->getTotalOrdinaryDataSize(); if (m_constantBufferSize == 0) { - m_upToDateConstantBufferHeapVersion = - encoder->m_commandBuffer->m_transientHeap->getVersion(); return SLANG_OK; } @@ -2385,11 +2366,6 @@ public: m_constantBufferSize, specializedLayout)); - // Update version tracker so that we don't redundantly alloc and fill in - // constant buffers for the same transient heap. - m_upToDateConstantBufferHeapVersion = - encoder->m_commandBuffer->m_transientHeap->getVersion(); - { // We also create and store a descriptor for our root constant buffer // into the descriptor table allocation that was reserved for them. @@ -2689,12 +2665,12 @@ public: size_t m_constantBufferOffset = 0; size_t m_constantBufferSize = 0; - /// The version number of the transient resource heap that contains up-to-date - /// constant buffer content for this shader object. If this is equal to the version number - /// of currently active transient heap, then the current set-up of constant buffer contents - /// as defined by the above `m_constantBuffer*` fields is valid and up-to-date so we can - /// use them directly. - uint64_t m_upToDateConstantBufferHeapVersion; + /// Dirty bit tracking whether the constant buffer needs to be updated. + bool m_isConstantBufferDirty = true; + /// The transient heap from which the constant buffer is allocated. + TransientResourceHeapImpl* m_constantBufferTransientHeap; + /// The version of the transient heap when the constant buffer is allocated. + uint64_t m_constantBufferTransientHeapVersion; /// Get the layout of this shader object with specialization arguments considered /// @@ -2734,6 +2710,9 @@ public: RefPtr<ShaderObjectLayoutImpl> m_specializedLayout; }; + class MutableShaderObjectImpl : public MutableShaderObject<MutableShaderObjectImpl, ShaderObjectLayoutImpl> + {}; + class RootShaderObjectImpl : public ShaderObjectImpl { typedef ShaderObjectImpl Super; @@ -3455,7 +3434,6 @@ public: ResourceState src, ResourceState dst) override { - assert(!"Unimplemented"); } virtual SLANG_NO_THROW void SLANG_MCALL endEncoding() {} virtual SLANG_NO_THROW void SLANG_MCALL writeTimestamp(IQueryPool* pool, SlangInt index) override @@ -5380,6 +5358,19 @@ Result D3D12Device::createShaderObject( return SLANG_OK; } +Result D3D12Device::createMutableShaderObject( + ShaderObjectLayoutBase* layout, + IShaderObject** outObject) +{ + auto layoutImpl = static_cast<ShaderObjectLayoutImpl*>(layout); + + RefPtr<MutableShaderObjectImpl> result = new MutableShaderObjectImpl(); + SLANG_RETURN_ON_FAIL(result->init(this, layoutImpl)); + returnComPtr(outObject, result); + + return SLANG_OK; +} + Result D3D12Device::createGraphicsPipelineState(const GraphicsPipelineStateDesc& inDesc, IPipelineState** outState) { GraphicsPipelineStateDesc desc = inDesc; |
