summaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/gfx/d3d11/render-d3d11.cpp23
-rw-r--r--tools/gfx/d3d12/render-d3d12.cpp219
-rw-r--r--tools/gfx/open-gl/render-gl.cpp23
-rw-r--r--tools/gfx/renderer-shared.cpp22
-rw-r--r--tools/gfx/renderer-shared.h23
-rw-r--r--tools/gfx/vulkan/render-vk.cpp23
-rw-r--r--tools/platform/windows/win-window.cpp21
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