diff options
Diffstat (limited to 'tools')
| -rw-r--r-- | tools/gfx/d3d11/render-d3d11.cpp | 23 | ||||
| -rw-r--r-- | tools/gfx/d3d12/render-d3d12.cpp | 219 | ||||
| -rw-r--r-- | tools/gfx/open-gl/render-gl.cpp | 23 | ||||
| -rw-r--r-- | tools/gfx/renderer-shared.cpp | 22 | ||||
| -rw-r--r-- | tools/gfx/renderer-shared.h | 23 | ||||
| -rw-r--r-- | tools/gfx/vulkan/render-vk.cpp | 23 | ||||
| -rw-r--r-- | tools/platform/windows/win-window.cpp | 21 |
7 files changed, 199 insertions, 155 deletions
diff --git a/tools/gfx/d3d11/render-d3d11.cpp b/tools/gfx/d3d11/render-d3d11.cpp index f5dbcc0a7..a011f2760 100644 --- a/tools/gfx/d3d11/render-d3d11.cpp +++ b/tools/gfx/d3d11/render-d3d11.cpp @@ -265,20 +265,9 @@ protected: float m_clearValue[4]; }; - class FramebufferLayoutImpl - : public IFramebufferLayout - , public ComObject + class FramebufferLayoutImpl : public FramebufferLayoutBase { public: - SLANG_COM_OBJECT_IUNKNOWN_ALL - IFramebufferLayout* getInterface(const Guid& guid) - { - if (guid == GfxGUID::IID_ISlangUnknown || guid == GfxGUID::IID_IFramebufferLayout) - return static_cast<IFramebufferLayout*>(this); - return nullptr; - } - - public: ShortList<IFramebufferLayout::AttachmentLayout> m_renderTargets; bool m_hasDepthStencil = false; IFramebufferLayout::AttachmentLayout m_depthStencil; @@ -345,17 +334,9 @@ protected: } }; - class InputLayoutImpl: public IInputLayout, public ComObject + class InputLayoutImpl: public InputLayoutBase { public: - SLANG_COM_OBJECT_IUNKNOWN_ALL - IInputLayout* getInterface(const Guid& guid) - { - if (guid == GfxGUID::IID_ISlangUnknown || guid == GfxGUID::IID_IInputLayout) - return static_cast<IInputLayout*>(this); - return nullptr; - } - public: ComPtr<ID3D11InputLayout> m_layout; }; diff --git a/tools/gfx/d3d12/render-d3d12.cpp b/tools/gfx/d3d12/render-d3d12.cpp index e02f7d656..5026ad111 100644 --- a/tools/gfx/d3d12/render-d3d12.cpp +++ b/tools/gfx/d3d12/render-d3d12.cpp @@ -257,20 +257,9 @@ public: } }; - class FramebufferLayoutImpl - : public IFramebufferLayout - , public ComObject + class FramebufferLayoutImpl : public FramebufferLayoutBase { public: - SLANG_COM_OBJECT_IUNKNOWN_ALL - IFramebufferLayout* getInterface(const Guid& guid) - { - if (guid == GfxGUID::IID_ISlangUnknown || guid == GfxGUID::IID_IFramebufferLayout) - return static_cast<IFramebufferLayout*>(this); - return nullptr; - } - - public: ShortList<IFramebufferLayout::AttachmentLayout> m_renderTargets; bool m_hasDepthStencil = false; IFramebufferLayout::AttachmentLayout m_depthStencil; @@ -313,17 +302,9 @@ public: } }; - class InputLayoutImpl: public IInputLayout, public ComObject + class InputLayoutImpl : public InputLayoutBase { public: - SLANG_COM_OBJECT_IUNKNOWN_ALL - IInputLayout* getInterface(const Guid& guid) - { - if (guid == GfxGUID::IID_ISlangUnknown || guid == GfxGUID::IID_IInputLayout) - return static_cast<IInputLayout*>(this); - return nullptr; - } - public: List<D3D12_INPUT_ELEMENT_DESC> m_elements; List<char> m_text; ///< Holds all strings to keep in scope }; @@ -1033,6 +1014,35 @@ public: return result; } + Result addDescriptorRange( + Index physicalDescriptorSetIndex, + D3D12_DESCRIPTOR_RANGE_TYPE rangeType, + UINT registerIndex, + UINT spaceIndex, + UINT count) + { + auto& descriptorSet = m_descriptorSets[physicalDescriptorSetIndex]; + + D3D12_DESCRIPTOR_RANGE range = {}; + range.RangeType = rangeType; + range.NumDescriptors = count; + range.BaseShaderRegister = registerIndex; + range.RegisterSpace = spaceIndex; + range.OffsetInDescriptorsFromTableStart = D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND; + + if (range.RangeType == D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER) + { + descriptorSet.m_samplerRanges.add(range); + descriptorSet.m_samplerCount += range.NumDescriptors; + } + else + { + descriptorSet.m_resourceRanges.add(range); + descriptorSet.m_resourceCount += range.NumDescriptors; + } + + return SLANG_OK; + } /// Add one descriptor range as specified in Slang reflection information to the layout. /// /// The layout information is taken from `typeLayout` for the descriptor @@ -1056,8 +1066,6 @@ public: Index logicalDescriptorSetIndex, Index descriptorRangeIndex) { - auto& descriptorSet = m_descriptorSets[physicalDescriptorSetIndex]; - auto bindingType = typeLayout->getDescriptorSetDescriptorRangeType(logicalDescriptorSetIndex, descriptorRangeIndex); auto count = typeLayout->getDescriptorSetDescriptorRangeDescriptorCount(logicalDescriptorSetIndex, descriptorRangeIndex); auto index = typeLayout->getDescriptorSetDescriptorRangeIndexOffset(logicalDescriptorSetIndex, descriptorRangeIndex); @@ -1066,25 +1074,12 @@ public: D3D12_DESCRIPTOR_RANGE_TYPE rangeType; SLANG_RETURN_ON_FAIL(translateDescriptorRangeType(bindingType, &rangeType)); - D3D12_DESCRIPTOR_RANGE range = {}; - range.RangeType = rangeType; - range.NumDescriptors = (UINT) count; - range.BaseShaderRegister = (UINT) index + offset[rangeType]; - range.RegisterSpace = (UINT) space; - range.OffsetInDescriptorsFromTableStart = D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND; - - if (range.RangeType == D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER) - { - descriptorSet.m_samplerRanges.add(range); - descriptorSet.m_samplerCount += range.NumDescriptors; - } - else - { - descriptorSet.m_resourceRanges.add(range); - descriptorSet.m_resourceCount += range.NumDescriptors; - } - - return SLANG_OK; + return addDescriptorRange( + physicalDescriptorSetIndex, + rangeType, + (UINT)index + offset[rangeType], + (UINT)space, + (UINT)count); } /// Add one binding range to the computed layout. @@ -1196,14 +1191,11 @@ public: addBindingRange(typeLayout, physicalDescriptorSetIndex, offset, bindingRangeIndex); } - // Next we need to recurse on the various sub-objects that the type might contain. + // Next we need to add any sub binding ranges in `ConstantBuffer` bindings. // Index subObjectCount = typeLayout->getSubObjectRangeCount(); for (Index subObjectRangeIndex = 0; subObjectRangeIndex < subObjectCount; subObjectRangeIndex++) { - // There are a few different concerns being tackled at once here, which depend on - // the type of each sub-object range. - // auto bindingRangeIndex = typeLayout->getSubObjectRangeBindingRangeIndex(subObjectRangeIndex); auto bindingType = typeLayout->getBindingRangeType(bindingRangeIndex); switch (bindingType) @@ -1221,55 +1213,116 @@ public: // guarantee that the descritpors used by non-sub-object binding ranges are all // contiguous. // - addBindingRange(typeLayout, physicalDescriptorSetIndex, offset, bindingRangeIndex); + // This call will add all descriptor ranges reported in `typeLayout` that is associated + // with `bindingRangeIndex`. + // + addBindingRange( + typeLayout, + physicalDescriptorSetIndex, + offset, + bindingRangeIndex); + + // We also need to recurse into the element type of the constant buffer to add + // any binding ranges defined in the element type. + auto subObjectType = + typeLayout->getBindingRangeLeafTypeLayout(bindingRangeIndex); + BindingRegisterOffset subOffset; + subOffset.spaceOffset = + offset.spaceOffset + + (uint32_t)typeLayout->getSubObjectRangeSpaceOffset( + subObjectRangeIndex); + addParameterBlocks( + _unwrapParameterGroups(subObjectType), + physicalDescriptorSetIndex, + subOffset); } break; + default: + break; + } + } + + addParameterBlocks(typeLayout, physicalDescriptorSetIndex, offset); + } + /// Add child parameter blocks defined in `typeLayout` to the root signature. + void addParameterBlocks( + slang::TypeLayoutReflection* typeLayout, + Index physicalDescriptorSetIndex, + BindingRegisterOffset const& offset) + { + Index subObjectCount = typeLayout->getSubObjectRangeCount(); + for (Index subObjectRangeIndex = 0; subObjectRangeIndex < subObjectCount; + subObjectRangeIndex++) + { + // There are a few different concerns being tackled at once here, which depend + // on the type of each sub-object range. + // + auto bindingRangeIndex = + typeLayout->getSubObjectRangeBindingRangeIndex(subObjectRangeIndex); + auto bindingType = typeLayout->getBindingRangeType(bindingRangeIndex); + switch (bindingType) + { case slang::BindingType::ParameterBlock: { - // A parameter block (`ParameterBlock<ConcreteType>`) will always map to a distinct - // descriptor set, and its contained view/sampler binding ranges will be bound - // through that set. + // A parameter block (`ParameterBlock<ConcreteType>`) will always map to + // a distinct descriptor set, and its contained view/sampler binding + // ranges will be bound through that set. // auto blockPhysicalDescriptorSetIndex = addDescriptorSet(); - // We will need to recursively add the binding ranges implied by the type of - // the parameter block. + // We will need to recursively add the binding ranges implied by the + // type of the parameter block. // - auto blockTypeLayout = typeLayout->getBindingRangeLeafTypeLayout(bindingRangeIndex); - - // One important detail is that the `blockTypeLayout` does not know the base register - // space that the contents of the block should use. All descriptor ranges stored in - // that layout will by default use a space offset of zero. + auto blockTypeLayout = + typeLayout->getBindingRangeLeafTypeLayout(bindingRangeIndex); + + // One important detail is that the `blockTypeLayout` does not know the + // base register space that the contents of the block should use. All + // descriptor ranges stored in that layout will by default use a space + // offset of zero. // - // We need to compute the space offset to apply when recursing into that block type - // based on the binding range we are processing here. + // We need to compute the space offset to apply when recursing into that + // block type based on the binding range we are processing here. // - auto blockLogicalDescriptorSetIndex = typeLayout->getBindingRangeDescriptorSetIndex(bindingRangeIndex); - auto blockSpaceOffset = typeLayout->getDescriptorSetSpaceOffset(blockLogicalDescriptorSetIndex); - - // The space offset for this binding range should be added to any additional space - // offset that was being passed down from above this layer. + auto spaceOffset = + typeLayout->getSubObjectRangeSpaceOffset(subObjectRangeIndex); + // The space offset for this binding range should be added to any + // additional space offset that was being passed down from above this + // layer. // - // Any other offset information (register offsets) should be ignored at this point, - // because `register` offsets from outside of the block don't affect layout within - // the block. + // Any other offset information (register offsets) should be ignored at + // this point, because `register` offsets from outside of the block + // don't affect layout within the block. // BindingRegisterOffset blockOffset; - blockOffset.spaceOffset = offset.spaceOffset + (uint32_t) blockSpaceOffset; - - // Once we have all the details worked out, we can write the binding ranges for the - // block's type into the newly-allocated descriptor set. - // - // Note: there is an important subtlety going on here. We are passing in the type - // `blockTypeLayout` which corresponds to `ParameterBlock<ConcreteType>` and *not* to - // `ConcreteType` alone. Because of that detail, the binding/descriptor ranges will - // include any "default constant buffer" range that needed to be allocated based - // on `ConcreteType`. - // - // TODO: validate that this logic is right. + blockOffset.spaceOffset = offset.spaceOffset + (uint32_t)spaceOffset; + + // Note: there is an important subtlety going on here. We are passing in + // the type `blockTypeLayout` which corresponds to + // `ParameterBlock<ConcreteType>` and *not* to `ConcreteType` alone. + // We call `_unwrapParameterGroups` on `blockTypeLayout` get the layout + // for the element type. + auto elementLayout = _unwrapParameterGroups(blockTypeLayout); + + // If the element type requires constant buffer storage, add an + // implicit constant buffer descriptor in descriptor set. + if (elementLayout->getSize(SLANG_PARAMETER_CATEGORY_UNIFORM) != 0) + { + addDescriptorRange( + blockPhysicalDescriptorSetIndex, + D3D12_DESCRIPTOR_RANGE_TYPE_CBV, + 0, + blockOffset.spaceOffset, + 1); + blockOffset.offsetForRangeType[D3D12_DESCRIPTOR_RANGE_TYPE_CBV] = 1; + } + + // Once we have all the details worked out, we can write the binding + // ranges for the block's type into the newly-allocated descriptor set. // - addBindingRangesAndParameterBlocks(blockTypeLayout, blockPhysicalDescriptorSetIndex, blockOffset); + addBindingRangesAndParameterBlocks( + elementLayout, blockPhysicalDescriptorSetIndex, blockOffset); } break; @@ -2521,7 +2574,7 @@ public: if (uuid == GfxGUID::IID_ISlangUnknown || uuid == GfxGUID::IID_ICommandEncoder || uuid == GfxGUID::IID_IRenderCommandEncoder) { - returnComPtr(outObject, static_cast<IRenderCommandEncoder*>(this)); + *outObject = static_cast<IRenderCommandEncoder*>(this); return SLANG_OK; } *outObject = nullptr; @@ -2903,7 +2956,7 @@ public: if (uuid == GfxGUID::IID_ISlangUnknown || uuid == GfxGUID::IID_ICommandEncoder || uuid == GfxGUID::IID_IComputeCommandEncoder) { - returnComPtr(outObject, static_cast<IComputeCommandEncoder*>(this)); + *outObject = static_cast<IComputeCommandEncoder*>(this); return SLANG_OK; } *outObject = nullptr; @@ -4804,7 +4857,7 @@ Result D3D12Device::createProgram(const IShaderProgram::Desc& desc, IShaderProgr (SlangInt)i, 0, kernelCode.writeRef(), diagnostics.writeRef()); if (diagnostics) { - printf("%s\n", diagnostics->getBufferPointer()); + printf("%s\n", (char*)diagnostics->getBufferPointer()); // TODO: report compile error. } SLANG_RETURN_ON_FAIL(compileResult); diff --git a/tools/gfx/open-gl/render-gl.cpp b/tools/gfx/open-gl/render-gl.cpp index c0b739096..fb8502485 100644 --- a/tools/gfx/open-gl/render-gl.cpp +++ b/tools/gfx/open-gl/render-gl.cpp @@ -201,17 +201,9 @@ public: GLsizei offset; }; - class InputLayoutImpl: public IInputLayout, public ComObject + class InputLayoutImpl : public InputLayoutBase { public: - SLANG_COM_OBJECT_IUNKNOWN_ALL - IInputLayout* getInterface(const Guid& guid) - { - if (guid == GfxGUID::IID_ISlangUnknown || guid == GfxGUID::IID_IInputLayout) - return static_cast<IInputLayout*>(this); - return nullptr; - } - public: VertexAttributeDesc m_attributes[kMaxVertexStreams]; UInt m_attributeCount = 0; }; @@ -329,20 +321,9 @@ public: GLuint m_bufferID; }; - class FramebufferLayoutImpl - : public IFramebufferLayout - , public ComObject + class FramebufferLayoutImpl : public FramebufferLayoutBase { public: - SLANG_COM_OBJECT_IUNKNOWN_ALL - IFramebufferLayout* getInterface(const Guid& guid) - { - if (guid == GfxGUID::IID_ISlangUnknown || guid == GfxGUID::IID_IFramebufferLayout) - return static_cast<IFramebufferLayout*>(this); - return nullptr; - } - - public: ShortList<IFramebufferLayout::AttachmentLayout> m_renderTargets; bool m_hasDepthStencil = false; IFramebufferLayout::AttachmentLayout m_depthStencil; diff --git a/tools/gfx/renderer-shared.cpp b/tools/gfx/renderer-shared.cpp index 333f1df54..2a12b777c 100644 --- a/tools/gfx/renderer-shared.cpp +++ b/tools/gfx/renderer-shared.cpp @@ -183,6 +183,20 @@ IShaderProgram* gfx::ShaderProgramBase::getInterface(const Guid& guid) return nullptr; } +IInputLayout* gfx::InputLayoutBase::getInterface(const Guid& guid) +{ + if (guid == GfxGUID::IID_ISlangUnknown || guid == GfxGUID::IID_IInputLayout) + return static_cast<IInputLayout*>(this); + return nullptr; +} + +IFramebufferLayout* gfx::FramebufferLayoutBase::getInterface(const Guid& guid) +{ + if (guid == GfxGUID::IID_ISlangUnknown || guid == GfxGUID::IID_IFramebufferLayout) + return static_cast<IFramebufferLayout*>(this); + return nullptr; +} + IPipelineState* gfx::PipelineStateBase::getInterface(const Guid& guid) { if (guid == GfxGUID::IID_ISlangUnknown || guid == GfxGUID::IID_IPipelineState) @@ -197,6 +211,14 @@ void PipelineStateBase::initializeBase(const PipelineStateDesc& inDesc) auto program = desc.getProgram(); m_program = program; isSpecializable = (program->slangProgram && program->slangProgram->getSpecializationParamCount() != 0); + + // Hold a strong reference to inputLayout and framebufferLayout objects to prevent it from + // destruction. + if (inDesc.type == PipelineType::Graphics) + { + inputLayout = static_cast<InputLayoutBase*>(inDesc.graphics.inputLayout); + framebufferLayout = static_cast<FramebufferLayoutBase*>(inDesc.graphics.framebufferLayout); + } } IDevice* gfx::RendererBase::getInterface(const Guid& guid) diff --git a/tools/gfx/renderer-shared.h b/tools/gfx/renderer-shared.h index ec33a3054..b19e0539b 100644 --- a/tools/gfx/renderer-shared.h +++ b/tools/gfx/renderer-shared.h @@ -395,6 +395,24 @@ public: ComPtr<slang::IComponentType> slangProgram; }; +class InputLayoutBase + : public IInputLayout + , public Slang::ComObject +{ +public: + SLANG_COM_OBJECT_IUNKNOWN_ALL + IInputLayout* getInterface(const Slang::Guid& guid); +}; + +class FramebufferLayoutBase + : public IFramebufferLayout + , public Slang::ComObject +{ +public: + SLANG_COM_OBJECT_IUNKNOWN_ALL + IFramebufferLayout* getInterface(const Slang::Guid& guid); +}; + class PipelineStateBase : public IPipelineState , public Slang::ComObject @@ -414,6 +432,11 @@ public: } } desc; + // We need to hold inputLayout and framebufferLayout objects alive, since we may use it to + // create specialized pipeline states later. + Slang::RefPtr<InputLayoutBase> inputLayout; + Slang::RefPtr<FramebufferLayoutBase> framebufferLayout; + // The pipeline state from which this pipeline state is specialized. // If null, this pipeline is either an unspecialized pipeline. Slang::RefPtr<PipelineStateBase> unspecializedPipelineState = nullptr; diff --git a/tools/gfx/vulkan/render-vk.cpp b/tools/gfx/vulkan/render-vk.cpp index 2ce51790a..315c8d7ce 100644 --- a/tools/gfx/vulkan/render-vk.cpp +++ b/tools/gfx/vulkan/render-vk.cpp @@ -153,17 +153,9 @@ public: const VulkanApi* m_api; }; - class InputLayoutImpl : public IInputLayout, public ComObject + class InputLayoutImpl : public InputLayoutBase { public: - SLANG_COM_OBJECT_IUNKNOWN_ALL - IInputLayout* getInterface(const Guid& guid) - { - if (guid == GfxGUID::IID_ISlangUnknown || guid == GfxGUID::IID_IInputLayout) - return static_cast<IInputLayout*>(this); - return nullptr; - } - public: List<VkVertexInputAttributeDescription> m_vertexDescs; int m_vertexSize; }; @@ -310,20 +302,9 @@ public: VkDeviceSize size; }; - class FramebufferLayoutImpl - : public IFramebufferLayout - , public ComObject + class FramebufferLayoutImpl : public FramebufferLayoutBase { public: - SLANG_COM_OBJECT_IUNKNOWN_ALL - IFramebufferLayout* getInterface(const Guid& guid) - { - if (guid == GfxGUID::IID_ISlangUnknown || guid == GfxGUID::IID_IFramebufferLayout) - return static_cast<IFramebufferLayout*>(this); - return nullptr; - } - - public: VkRenderPass m_renderPass; RefPtr<VKDevice> m_renderer; Array<VkAttachmentDescription, kMaxAttachments> m_attachmentDescs; diff --git a/tools/platform/windows/win-window.cpp b/tools/platform/windows/win-window.cpp index 0d80eda7b..a0175a911 100644 --- a/tools/platform/windows/win-window.cpp +++ b/tools/platform/windows/win-window.cpp @@ -294,6 +294,8 @@ void Application::run(Window* mainWindow, bool waitForEvents) while (!Win32AppContext::isTerminated) { doEventsImpl(waitForEvents); + if (Win32AppContext::isTerminated) + break; if (mainWindow) { mainWindow->events.mainLoop(); @@ -343,14 +345,7 @@ public: Win32AppContext::windows[handle] = this; } - ~Win32PlatformWindow() - { - if (handle) - { - Win32AppContext::windows.Remove(handle); - } - DestroyWindow(handle); - } + ~Win32PlatformWindow() { close(); } virtual void setClientSize(uint32_t width, uint32_t height) override { @@ -401,7 +396,15 @@ public: MoveWindow(handle, left, top, width, height, FALSE); } - virtual void close() override {} + virtual void close() override + { + if (handle) + { + Win32AppContext::windows.Remove(handle); + } + DestroyWindow(handle); + handle = NULL; + } virtual bool getFocused() override { return GetFocus() == handle; } virtual bool getVisible() override { return visible; } virtual WindowHandle getNativeHandle() override |
