summaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorYong He <yonghe@outlook.com>2021-07-08 13:30:17 -0700
committerGitHub <noreply@github.com>2021-07-08 16:30:17 -0400
commit09950676b3f73bb9967aea183d27a30d63098475 (patch)
treeaba3e69b72554b07da1188fd44d5f3ce3d90da26 /tools
parent06c4926ec51ce9548f2dc44ee948a467d588def8 (diff)
Implement gfx inline ray tracing on D3D12. (#1902)
* Update VS projects to 2019. * Empty commit to trigger build * Implement gfx inline ray tracing on D3D12.
Diffstat (limited to 'tools')
-rw-r--r--tools/copy-hlsl-libs.bat4
-rw-r--r--tools/gfx/cpu/render-cpu.cpp6
-rw-r--r--tools/gfx/cuda/render-cuda.cpp11
-rw-r--r--tools/gfx/d3d/d3d-util.cpp93
-rw-r--r--tools/gfx/d3d/d3d-util.h27
-rw-r--r--tools/gfx/d3d11/render-d3d11.cpp11
-rw-r--r--tools/gfx/d3d12/render-d3d12.cpp687
-rw-r--r--tools/gfx/debug-layer.cpp89
-rw-r--r--tools/gfx/debug-layer.h4
-rw-r--r--tools/gfx/open-gl/render-gl.cpp4
-rw-r--r--tools/gfx/renderer-shared.h12
-rw-r--r--tools/gfx/vulkan/render-vk.cpp35
-rw-r--r--tools/gfx/vulkan/vk-util.cpp2
13 files changed, 695 insertions, 290 deletions
diff --git a/tools/copy-hlsl-libs.bat b/tools/copy-hlsl-libs.bat
index 2cd309aca..806cbfde7 100644
--- a/tools/copy-hlsl-libs.bat
+++ b/tools/copy-hlsl-libs.bat
@@ -7,7 +7,7 @@ set PLATFORM=%~3
robocopy "../../external/slang-binaries/bin/%PLATFORM%" "%TARGET_DIR%" d3dcompiler_47.dll /r:0 >nul
-robocopy "%SOURCE_DIR%" "%TARGET_DIR%" dxcompiler.dll /r:0 >nul
-robocopy "%SOURCE_DIR%" "%TARGET_DIR%" dxil.dll /r:0 >nul
+robocopy "%SOURCE_DIR%" "%TARGET_DIR%" dxcompiler.dll /xn /r:0 >nul
+robocopy "%SOURCE_DIR%" "%TARGET_DIR%" dxil.dll /xn /r:0 >nul
exit /b 0
diff --git a/tools/gfx/cpu/render-cpu.cpp b/tools/gfx/cpu/render-cpu.cpp
index af1fcc65a..56804f15e 100644
--- a/tools/gfx/cpu/render-cpu.cpp
+++ b/tools/gfx/cpu/render-cpu.cpp
@@ -379,12 +379,12 @@ public:
protected:
CPUResourceView(Kind kind, Desc const& desc)
: m_kind(kind)
- , m_desc(desc)
- {}
+ {
+ m_desc = desc;
+ }
private:
Kind m_kind;
- Desc m_desc;
};
class CPUBufferView : public CPUResourceView
diff --git a/tools/gfx/cuda/render-cuda.cpp b/tools/gfx/cuda/render-cuda.cpp
index ffd197e57..2fb8a2ce8 100644
--- a/tools/gfx/cuda/render-cuda.cpp
+++ b/tools/gfx/cuda/render-cuda.cpp
@@ -239,7 +239,6 @@ public:
class CUDAResourceView : public ResourceViewBase
{
public:
- Desc desc;
RefPtr<MemoryCUDAResource> memoryResource = nullptr;
RefPtr<TextureCUDAResource> textureResource = nullptr;
void* proxyBuffer = nullptr;
@@ -447,7 +446,7 @@ public:
viewDesc.type = IResourceView::Type::UnorderedAccess;
m_bufferView = new CUDAResourceView();
m_bufferView->proxyBuffer = m_cpuBuffer.getBuffer();
- m_bufferView->desc = viewDesc;
+ m_bufferView->m_desc = viewDesc;
}
return SLANG_OK;
}
@@ -466,7 +465,7 @@ public:
viewDesc.type = IResourceView::Type::UnorderedAccess;
m_bufferView = new CUDAResourceView();
m_bufferView->memoryResource = m_bufferResource;
- m_bufferView->desc = viewDesc;
+ m_bufferView->m_desc = viewDesc;
}
auto oldSize = m_bufferResource->getDesc()->sizeInBytes;
if ((size_t)count != oldSize)
@@ -571,7 +570,7 @@ public:
if (cudaView->textureResource)
{
- if (cudaView->desc.type == IResourceView::Type::UnorderedAccess)
+ if (cudaView->m_desc.type == IResourceView::Type::UnorderedAccess)
{
auto handle = cudaView->textureResource->m_cudaSurfObj;
setData(offset, &handle, sizeof(uint64_t));
@@ -1727,7 +1726,7 @@ public:
ITextureResource* texture, IResourceView::Desc const& desc, IResourceView** outView) override
{
RefPtr<CUDAResourceView> view = new CUDAResourceView();
- view->desc = desc;
+ view->m_desc = desc;
view->textureResource = dynamic_cast<TextureCUDAResource*>(texture);
returnComPtr(outView, view);
return SLANG_OK;
@@ -1737,7 +1736,7 @@ public:
IBufferResource* buffer, IResourceView::Desc const& desc, IResourceView** outView) override
{
RefPtr<CUDAResourceView> view = new CUDAResourceView();
- view->desc = desc;
+ view->m_desc = desc;
view->memoryResource = dynamic_cast<MemoryCUDAResource*>(buffer);
returnComPtr(outView, view);
return SLANG_OK;
diff --git a/tools/gfx/d3d/d3d-util.cpp b/tools/gfx/d3d/d3d-util.cpp
index 7db1ce585..1f8e5bf7b 100644
--- a/tools/gfx/d3d/d3d-util.cpp
+++ b/tools/gfx/d3d/d3d-util.cpp
@@ -114,6 +114,8 @@ D3D12_DEPTH_STENCILOP_DESC D3DUtil::translateStencilOpDesc(DepthStencilOpDesc de
case Format::R_Float32: return DXGI_FORMAT_R32_FLOAT;
case Format::RGBA_Unorm_UInt8: return DXGI_FORMAT_R8G8B8A8_UNORM;
case Format::BGRA_Unorm_UInt8: return DXGI_FORMAT_B8G8R8A8_UNORM;
+ case Format::RGBA_Snorm_UInt16: return DXGI_FORMAT_R16G16B16A16_SNORM;
+ case Format::RG_Snorm_UInt16: return DXGI_FORMAT_R16G16_SNORM;
case Format::RGBA_Float16: return DXGI_FORMAT_R16G16B16A16_FLOAT;
case Format::RG_Float16: return DXGI_FORMAT_R16G16_FLOAT;
@@ -133,29 +135,33 @@ D3D12_RESOURCE_STATES D3DUtil::translateResourceState(ResourceState state)
{
switch (state)
{
- case gfx::ResourceState::Undefined:
+ case ResourceState::Undefined:
return D3D12_RESOURCE_STATE_COMMON;
- case gfx::ResourceState::ShaderResource:
+ case ResourceState::ShaderResource:
return D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE |
D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE;
- case gfx::ResourceState::UnorderedAccess:
+ case ResourceState::UnorderedAccess:
return D3D12_RESOURCE_STATE_UNORDERED_ACCESS;
- case gfx::ResourceState::RenderTarget:
+ case ResourceState::RenderTarget:
return D3D12_RESOURCE_STATE_RENDER_TARGET;
- case gfx::ResourceState::DepthRead:
+ case ResourceState::DepthRead:
return D3D12_RESOURCE_STATE_DEPTH_READ;
- case gfx::ResourceState::DepthWrite:
+ case ResourceState::DepthWrite:
return D3D12_RESOURCE_STATE_DEPTH_WRITE;
- case gfx::ResourceState::Present:
+ case ResourceState::Present:
return D3D12_RESOURCE_STATE_PRESENT;
- case gfx::ResourceState::CopySource:
+ case ResourceState::CopySource:
return D3D12_RESOURCE_STATE_COPY_SOURCE;
- case gfx::ResourceState::CopyDestination:
+ case ResourceState::CopyDestination:
return D3D12_RESOURCE_STATE_COPY_DEST;
- case gfx::ResourceState::ResolveSource:
+ case ResourceState::ResolveSource:
return D3D12_RESOURCE_STATE_RESOLVE_SOURCE;
- case gfx::ResourceState::ResolveDestination:
+ case ResourceState::ResolveDestination:
return D3D12_RESOURCE_STATE_RESOLVE_DEST;
+#if SLANG_GFX_HAS_DXR_SUPPORT
+ case ResourceState::AccelerationStructure:
+ return D3D12_RESOURCE_STATE_RAYTRACING_ACCELERATION_STRUCTURE;
+#endif
default:
return D3D12_RESOURCE_STATE_COMMON;
}
@@ -583,4 +589,67 @@ bool D3DUtil::isUAVBinding(slang::BindingType bindingType)
return SLANG_OK;
}
-} // renderer_test
+#if SLANG_GFX_HAS_DXR_SUPPORT
+Result D3DAccelerationStructureInputsBuilder::build(
+ const IAccelerationStructure::BuildInputs& buildInputs,
+ IDebugCallback* callback)
+{
+ if (buildInputs.geometryDescs)
+ {
+ geomDescs.setCount(buildInputs.descCount);
+ for (Index i = 0; i < geomDescs.getCount(); i++)
+ {
+ auto& inputGeomDesc = buildInputs.geometryDescs[i];
+ geomDescs[i].Flags = translateGeometryFlags(inputGeomDesc.flags);
+ switch (inputGeomDesc.type)
+ {
+ case IAccelerationStructure::GeometryType::Triangles:
+ geomDescs[i].Type = D3D12_RAYTRACING_GEOMETRY_TYPE_TRIANGLES;
+ geomDescs[i].Triangles.IndexBuffer = inputGeomDesc.content.triangles.indexData;
+ geomDescs[i].Triangles.IndexCount = inputGeomDesc.content.triangles.indexCount;
+ geomDescs[i].Triangles.IndexFormat =
+ D3DUtil::getMapFormat(inputGeomDesc.content.triangles.indexFormat);
+ geomDescs[i].Triangles.Transform3x4 = inputGeomDesc.content.triangles.transform3x4;
+ geomDescs[i].Triangles.VertexBuffer.StartAddress =
+ inputGeomDesc.content.triangles.vertexData;
+ geomDescs[i].Triangles.VertexBuffer.StrideInBytes =
+ inputGeomDesc.content.triangles.vertexStride;
+ geomDescs[i].Triangles.VertexCount = inputGeomDesc.content.triangles.vertexCount;
+ geomDescs[i].Triangles.VertexFormat =
+ D3DUtil::getMapFormat(inputGeomDesc.content.triangles.vertexFormat);
+ break;
+ case IAccelerationStructure::GeometryType::ProcedurePrimitives:
+ geomDescs[i].Type = D3D12_RAYTRACING_GEOMETRY_TYPE_PROCEDURAL_PRIMITIVE_AABBS;
+ geomDescs[i].AABBs.AABBCount = inputGeomDesc.content.proceduralAABBs.count;
+ geomDescs[i].AABBs.AABBs.StartAddress = inputGeomDesc.content.proceduralAABBs.data;
+ geomDescs[i].AABBs.AABBs.StrideInBytes =
+ inputGeomDesc.content.proceduralAABBs.stride;
+ break;
+ default:
+ callback->handleMessage(
+ DebugMessageType::Error,
+ DebugMessageSource::Layer,
+ "invalid value of IAccelerationStructure::GeometryType.");
+ return SLANG_E_INVALID_ARG;
+ }
+ }
+ }
+ desc.DescsLayout = D3D12_ELEMENTS_LAYOUT_ARRAY;
+ desc.NumDescs = buildInputs.descCount;
+ switch (buildInputs.kind)
+ {
+ case IAccelerationStructure::Kind::TopLevel:
+ desc.Type = D3D12_RAYTRACING_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL;
+ desc.InstanceDescs = buildInputs.instanceDescs;
+ break;
+ case IAccelerationStructure::Kind::BottomLevel:
+ desc.Type = D3D12_RAYTRACING_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL;
+ desc.pGeometryDescs = geomDescs.getBuffer();
+ break;
+ }
+ desc.Flags = (D3D12_RAYTRACING_ACCELERATION_STRUCTURE_BUILD_FLAGS)buildInputs.flags;
+ return SLANG_OK;
+}
+#endif
+
+} // namespace gfx
diff --git a/tools/gfx/d3d/d3d-util.h b/tools/gfx/d3d/d3d-util.h
index fc2353818..e570c6ff6 100644
--- a/tools/gfx/d3d/d3d-util.h
+++ b/tools/gfx/d3d/d3d-util.h
@@ -17,6 +17,15 @@
#include <dxgi.h>
#include <d3d12.h>
+#if defined(__ID3D12Device5_FWD_DEFINED__) && defined(__ID3D12GraphicsCommandList4_FWD_DEFINED__)
+# define SLANG_GFX_HAS_DXR_SUPPORT 1
+#else
+# define SLANG_GFX_HAS_DXR_SUPPORT 0
+typedef ISlangUnknown ID3D12Device5;
+typedef ISlangUnknown ID3D12GraphicsCommandList4;
+
+#endif
+
namespace gfx {
class D3DUtil
@@ -87,4 +96,22 @@ class D3DUtil
};
+#if SLANG_GFX_HAS_DXR_SUPPORT
+struct D3DAccelerationStructureInputsBuilder
+{
+ D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_INPUTS desc = {};
+ D3D12_RAYTRACING_ACCELERATION_STRUCTURE_PREBUILD_INFO prebuildInfo = {};
+ Slang::List<D3D12_RAYTRACING_GEOMETRY_DESC> geomDescs;
+ Slang::Result build(
+ const IAccelerationStructure::BuildInputs& buildInputs,
+ IDebugCallback* callback);
+
+private:
+ D3D12_RAYTRACING_GEOMETRY_FLAGS translateGeometryFlags(
+ IAccelerationStructure::GeometryFlags::Enum flags)
+ {
+ return (D3D12_RAYTRACING_GEOMETRY_FLAGS)flags;
+ }
+};
+#endif
} // renderer_test
diff --git a/tools/gfx/d3d11/render-d3d11.cpp b/tools/gfx/d3d11/render-d3d11.cpp
index d74888812..8c1c6be1e 100644
--- a/tools/gfx/d3d11/render-d3d11.cpp
+++ b/tools/gfx/d3d11/render-d3d11.cpp
@@ -2863,6 +2863,8 @@ Result D3D11Device::createTextureView(ITextureResource* texture, IResourceView::
RefPtr<RenderTargetViewImpl> viewImpl = new RenderTargetViewImpl();
viewImpl->m_type = ResourceViewImpl::Type::RTV;
viewImpl->m_rtv = rtv;
+ viewImpl->m_desc = desc;
+
memcpy(
viewImpl->m_clearValue,
&resourceImpl->getDesc()->optimalClearValue.color,
@@ -2881,6 +2883,8 @@ Result D3D11Device::createTextureView(ITextureResource* texture, IResourceView::
viewImpl->m_type = ResourceViewImpl::Type::DSV;
viewImpl->m_dsv = dsv;
viewImpl->m_clearValue = resourceImpl->getDesc()->optimalClearValue.depthStencil;
+ viewImpl->m_desc = desc;
+
returnComPtr(outView, viewImpl);
return SLANG_OK;
}
@@ -2894,6 +2898,8 @@ Result D3D11Device::createTextureView(ITextureResource* texture, IResourceView::
RefPtr<UnorderedAccessViewImpl> viewImpl = new UnorderedAccessViewImpl();
viewImpl->m_type = ResourceViewImpl::Type::UAV;
viewImpl->m_uav = uav;
+ viewImpl->m_desc = desc;
+
returnComPtr(outView, viewImpl);
return SLANG_OK;
}
@@ -2907,6 +2913,8 @@ Result D3D11Device::createTextureView(ITextureResource* texture, IResourceView::
RefPtr<ShaderResourceViewImpl> viewImpl = new ShaderResourceViewImpl();
viewImpl->m_type = ResourceViewImpl::Type::SRV;
viewImpl->m_srv = srv;
+ viewImpl->m_desc = desc;
+
returnComPtr(outView, viewImpl);
return SLANG_OK;
}
@@ -2952,6 +2960,8 @@ Result D3D11Device::createBufferView(IBufferResource* buffer, IResourceView::Des
RefPtr<UnorderedAccessViewImpl> viewImpl = new UnorderedAccessViewImpl();
viewImpl->m_type = ResourceViewImpl::Type::UAV;
viewImpl->m_uav = uav;
+ viewImpl->m_desc = desc;
+
returnComPtr(outView, viewImpl);
return SLANG_OK;
}
@@ -2997,6 +3007,7 @@ Result D3D11Device::createBufferView(IBufferResource* buffer, IResourceView::Des
RefPtr<ShaderResourceViewImpl> viewImpl = new ShaderResourceViewImpl();
viewImpl->m_type = ResourceViewImpl::Type::SRV;
viewImpl->m_srv = srv;
+ viewImpl->m_desc = desc;
returnComPtr(outView, viewImpl);
return SLANG_OK;
}
diff --git a/tools/gfx/d3d12/render-d3d12.cpp b/tools/gfx/d3d12/render-d3d12.cpp
index b8c95ef3a..277491ccd 100644
--- a/tools/gfx/d3d12/render-d3d12.cpp
+++ b/tools/gfx/d3d12/render-d3d12.cpp
@@ -147,6 +147,15 @@ public:
~D3D12Device();
+#if SLANG_GFX_HAS_DXR_SUPPORT
+ virtual SLANG_NO_THROW Result SLANG_MCALL getAccelerationStructurePrebuildInfo(
+ const IAccelerationStructure::BuildInputs& buildInputs,
+ IAccelerationStructure::PrebuildInfo* outPrebuildInfo) override;
+ virtual SLANG_NO_THROW Result SLANG_MCALL createAccelerationStructure(
+ const IAccelerationStructure::CreateDesc& desc,
+ IAccelerationStructure** outView) override;
+#endif
+
public:
static const Int kMaxNumRenderFrames = 4;
@@ -170,6 +179,7 @@ public:
bool m_isWarp;
ComPtr<IDXGIFactory> m_dxgiFactory;
ComPtr<ID3D12Device> m_device;
+ ComPtr<ID3D12Device5> m_device5;
ComPtr<IDXGIAdapter> m_adapter;
DXGI_ADAPTER_DESC m_desc;
DXGI_ADAPTER_DESC1 m_desc1;
@@ -240,16 +250,20 @@ public:
}
};
- class ResourceViewImpl : public ResourceViewBase
+ class ResourceViewInternalImpl
{
public:
- RefPtr<Resource> m_resource;
D3D12Descriptor m_descriptor;
RefPtr<D3D12GeneralDescriptorHeap> m_allocator;
- ~ResourceViewImpl()
- {
- m_allocator->free(m_descriptor);
- }
+ ~ResourceViewInternalImpl() { m_allocator->free(m_descriptor); }
+ };
+
+ class ResourceViewImpl
+ : public ResourceViewBase
+ , public ResourceViewInternalImpl
+ {
+ public:
+ RefPtr<Resource> m_resource;
};
class FramebufferLayoutImpl : public FramebufferLayoutBase
@@ -374,6 +388,48 @@ public:
UINT64 m_eventValue = 0;
};
+ /// Implements the IQueryPool interface with a plain buffer.
+ /// Used for query types that does not correspond to a D3D query,
+ /// such as ray-tracing acceleration structure post-build info.
+ class PlainBufferProxyQueryPoolImpl
+ : public IQueryPool
+ , public ComObject
+ {
+ 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:
+ uint32_t m_stride = 0;
+ Result init(const IQueryPool::Desc& desc, D3D12Device* device, uint32_t stride);
+
+ virtual SLANG_NO_THROW Result SLANG_MCALL
+ getResult(SlangInt queryIndex, SlangInt count, uint64_t* data) override
+ {
+ ComPtr<ISlangBlob> blob;
+ SLANG_RETURN_ON_FAIL(m_device->readBufferResource(
+ m_bufferResource, m_stride * queryIndex, m_stride * count,
+ blob.writeRef()));
+ for (Int i = 0; i < count; i++)
+ {
+ memcpy(
+ data + i,
+ (uint8_t*)blob->getBufferPointer() + m_stride * i,
+ sizeof(uint64_t));
+ }
+ return SLANG_OK;
+ }
+ public:
+ QueryType m_queryType;
+ RefPtr<BufferResourceImpl> m_bufferResource;
+ RefPtr<D3D12Device> m_device;
+ };
+
struct BoundVertexBuffer
{
RefPtr<BufferResourceImpl> m_buffer;
@@ -1315,6 +1371,7 @@ public:
case slang::BindingType::RawBuffer:
case slang::BindingType::Texture:
case slang::BindingType::TypedBuffer:
+ case slang::BindingType::RayTracingAccelerationStructure:
*outType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV;
return SLANG_OK;
case slang::BindingType::MutableRawBuffer:
@@ -1691,219 +1748,6 @@ public:
// addPendingResourceBindingRanges(typeLayout, physicalDescriptorSetIndex, pendingOffset);
}
-#if 0
- /// Add child parameter blocks defined in `typeLayout` to the root signature.
- void addParameterBlocks(
- slang::TypeLayoutReflection* typeLayout,
- Index physicalDescriptorSetIndex,
- BindingRegisterOffsetPair 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::ConstantBuffer:
- {
- // 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);
- auto spaceOffset = (uint32_t)typeLayout->getSubObjectRangeSpaceOffset(subObjectRangeIndex);
-
- BindingRegisterOffsetPair subOffset;
- subOffset.primary.spaceOffset = offset.primary.spaceOffset + spaceOffset;
- subOffset.pending.spaceOffset = offset.pending.spaceOffset + spaceOffset;
- addParameterBlocks(
- _unwrapParameterGroups(subObjectType),
- physicalDescriptorSetIndex,
- subOffset);
- }
- break;
-
- 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.
- //
- auto blockPhysicalDescriptorSetIndex = addDescriptorSet();
-
- // 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.
- //
- // 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 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.
- //
- BindingRegisterOffsetPair blockOffset;
- blockOffset.primary.spaceOffset = offset.primary.spaceOffset + (uint32_t)spaceOffset;
- blockOffset.pending.spaceOffset = offset.pending.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.primary.spaceOffset,
- 1);
- blockOffset.primary.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.
- //
- addAsConstantBuffer(
- elementLayout, blockPhysicalDescriptorSetIndex, blockOffset);
- }
- break;
-
- case slang::BindingType::ExistentialValue:
- // TODO: Need to handle this case here.
- break;
-
- default:
- break;
- }
- }
-
-// addPendingParameterBlocks(typeLayout, physicalDescriptorSetIndex, offset);
- }
-#endif
-
-#if 0
- void addPendingResourceBindingRanges(
- slang::TypeLayoutReflection* typeLayout,
- Index physicalDescriptorSetIndex,
- BindingRegisterOffsetPair const& offset)
- {
- Index subObjectRangeCount = typeLayout->getSubObjectRangeCount();
- for (Index subObjectRangeIndex = 0; subObjectRangeIndex < subObjectRangeCount; subObjectRangeIndex++)
- {
- auto bindingRangeIndex = typeLayout->getSubObjectRangeBindingRangeIndex(subObjectRangeIndex);
- auto bindingType = typeLayout->getBindingRangeType(bindingRangeIndex);
- switch (bindingType)
- {
- case slang::BindingType::ExistentialValue:
- {
- // Any nested binding ranges in the sub-object will "leak" into the
- // binding ranges for the surrounding context.
- //
- auto subObjectTypeLayout = typeLayout->getBindingRangeLeafTypeLayout(bindingRangeIndex);
- auto specializedTypeLayout = subObjectTypeLayout->getPendingDataTypeLayout();
- if(specializedTypeLayout)
- {
- // TODO: We need to compute the offsets that should be applied to
- // any resources bound via the sub-object.
- BindingRegisterOffsetPair subOffset = offset;
- subOffset.primary += BindingRegisterOffset(typeLayout->getSubObjectRangePendingDataOffset(subObjectRangeIndex));
-
- addResourceBindingRanges(specializedTypeLayout, physicalDescriptorSetIndex, subOffset);
- }
- }
- break;
-
- case slang::BindingType::ConstantBuffer:
- {
- auto subObjectTypeLayout = typeLayout->getBindingRangeLeafTypeLayout(bindingRangeIndex);
- auto elementTypeLayout = subObjectTypeLayout->getElementTypeLayout();
- SLANG_ASSERT(elementTypeLayout);
-
- BindingRegisterOffsetPair subOffset = offset;
- subOffset.primary += BindingRegisterOffset(typeLayout->getSubObjectRangePendingDataOffset(subObjectRangeIndex));
-
- addPendingResourceBindingRanges(elementTypeLayout, physicalDescriptorSetIndex, subOffset);
- }
- break;
-
- default:
- break;
- }
- }
- }
-#endif
-
-#if 0
- void addPendingParameterBlocks(
- slang::TypeLayoutReflection* typeLayout,
- Index physicalDescriptorSetIndex,
- BindingRegisterOffset const& offset)
- {
- Index subObjectRangeCount = typeLayout->getSubObjectRangeCount();
- for (Index subObjectRangeIndex = 0; subObjectRangeIndex < subObjectRangeCount; subObjectRangeIndex++)
- {
- auto bindingRangeIndex = typeLayout->getSubObjectRangeBindingRangeIndex(subObjectRangeIndex);
- auto bindingType = typeLayout->getBindingRangeType(bindingRangeIndex);
- switch (bindingType)
- {
- case slang::BindingType::ExistentialValue:
- {
- // Any nested binding ranges in the sub-object will "leak" into the
- // binding ranges for the surrounding context.
- //
- auto subObjectTypeLayout = typeLayout->getBindingRangeLeafTypeLayout(bindingRangeIndex);
- auto pendingTypeLayout = subObjectTypeLayout->getPendingDataTypeLayout();
- if(pendingTypeLayout)
- {
- // TODO: We need to compute the offsets that should be applied to
- // any resources bound via the sub-object.
- BindingRegisterOffset subOffset = offset;
-
- addParameterBlocks(pendingTypeLayout, physicalDescriptorSetIndex, subOffset);
- }
- }
- break;
-
- case slang::BindingType::ConstantBuffer:
- case slang::BindingType::ParameterBlock:
- {
- auto subObjectTypeLayout = typeLayout->getBindingRangeLeafTypeLayout(bindingRangeIndex);
- BindingRegisterOffset subOffset = offset;
- addPendingParameterBlocks(subObjectTypeLayout, physicalDescriptorSetIndex, subOffset);
- }
- break;
-
- default:
- break;
- }
- }
- }
-#endif
-
D3D12_ROOT_SIGNATURE_DESC& build()
{
for (Index i = 0; i < m_descriptorSets.getCount(); i++)
@@ -2168,30 +2012,7 @@ public:
}
SLANG_NO_THROW Result SLANG_MCALL
- setResource(ShaderOffset const& offset, IResourceView* resourceView) SLANG_OVERRIDE
- {
- if (offset.bindingRangeIndex < 0)
- return SLANG_E_INVALID_ARG;
- auto layout = getLayout();
- if (offset.bindingRangeIndex >= layout->getBindingRangeCount())
- return SLANG_E_INVALID_ARG;
-
- auto resourceViewImpl = static_cast<ResourceViewImpl*>(resourceView);
-
- auto& bindingRange = layout->getBindingRange(offset.bindingRangeIndex);
- auto descriptorSlotIndex = bindingRange.baseIndex + (int32_t)offset.bindingArrayIndex;
- // Hold a reference to the resource to prevent its destruction.
- m_boundResources[bindingRange.baseIndex + offset.bindingArrayIndex] =
- resourceViewImpl->m_resource;
- ID3D12Device* d3dDevice = static_cast<D3D12Device*>(getDevice())->m_device;
- d3dDevice->CopyDescriptorsSimple(
- 1,
- m_descriptorSet.resourceTable.getCpuHandle(
- bindingRange.baseIndex + (int32_t)offset.bindingArrayIndex),
- resourceViewImpl->m_descriptor.cpuHandle,
- D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
- return SLANG_OK;
- }
+ setResource(ShaderOffset const& offset, IResourceView* resourceView) SLANG_OVERRIDE;
SLANG_NO_THROW Result SLANG_MCALL
setSampler(ShaderOffset const& offset, ISamplerState* sampler) SLANG_OVERRIDE
@@ -3070,6 +2891,8 @@ public:
virtual void comFree() override { m_transientHeap.breakStrongReference(); }
public:
ComPtr<ID3D12GraphicsCommandList> m_cmdList;
+ ComPtr<ID3D12GraphicsCommandList4> m_cmdList4;
+
BreakableReference<TransientResourceHeapImpl> m_transientHeap;
// Weak reference is fine here since `m_transientHeap` already holds strong reference to
// device.
@@ -3091,6 +2914,10 @@ public:
};
m_cmdList->SetDescriptorHeaps(SLANG_COUNT_OF(heaps), heaps);
m_rootShaderObject.init(renderer);
+
+#if SLANG_GFX_HAS_DXR_SUPPORT
+ m_cmdList->QueryInterface<ID3D12GraphicsCommandList4>(m_cmdList4.writeRef());
+#endif
}
class RenderCommandEncoderImpl
@@ -3568,11 +3395,61 @@ public:
*outEncoder = &m_resourceCommandEncoder;
}
+#if SLANG_GFX_HAS_DXR_SUPPORT
+ class RayTracingCommandEncoderImpl : public IRayTracingCommandEncoder
+ {
+ public:
+ CommandBufferImpl* m_commandBuffer;
+ void init(D3D12Device* renderer, CommandBufferImpl* commandBuffer)
+ {
+ m_commandBuffer = commandBuffer;
+ }
+ virtual SLANG_NO_THROW void SLANG_MCALL buildAccelerationStructure(
+ const IAccelerationStructure::BuildDesc& desc,
+ int propertyQueryCount,
+ AccelerationStructureQueryDesc* queryDescs) override;
+ virtual SLANG_NO_THROW void SLANG_MCALL copyAccelerationStructure(
+ IAccelerationStructure* dest,
+ IAccelerationStructure* src,
+ AccelerationStructureCopyMode mode) override;
+ virtual SLANG_NO_THROW void SLANG_MCALL queryAccelerationStructureProperties(
+ int accelerationStructureCount,
+ IAccelerationStructure* const* accelerationStructures,
+ int queryCount,
+ AccelerationStructureQueryDesc* queryDescs) override;
+ virtual SLANG_NO_THROW void SLANG_MCALL serializeAccelerationStructure(
+ DeviceAddress dest,
+ IAccelerationStructure* source) override;
+ virtual SLANG_NO_THROW void SLANG_MCALL deserializeAccelerationStructure(
+ IAccelerationStructure* dest,
+ DeviceAddress source) override;
+ virtual SLANG_NO_THROW void SLANG_MCALL memoryBarrier(
+ int count,
+ IAccelerationStructure* const* structures,
+ AccessFlag::Enum sourceAccess,
+ AccessFlag::Enum destAccess) override;
+ virtual SLANG_NO_THROW void SLANG_MCALL endEncoding() {}
+ virtual SLANG_NO_THROW void SLANG_MCALL
+ writeTimestamp(IQueryPool* pool, SlangInt index) override
+ {
+ static_cast<QueryPoolImpl*>(pool)->writeTimestamp(
+ m_commandBuffer->m_cmdList, index);
+ }
+ };
+ RayTracingCommandEncoderImpl m_rayTracingCommandEncoder;
+ virtual SLANG_NO_THROW void SLANG_MCALL
+ encodeRayTracingCommands(IRayTracingCommandEncoder** outEncoder) override
+ {
+ m_rayTracingCommandEncoder.init(m_renderer, this);
+ *outEncoder = &m_rayTracingCommandEncoder;
+ }
+#else
virtual SLANG_NO_THROW void SLANG_MCALL
encodeRayTracingCommands(IRayTracingCommandEncoder** outEncoder) override
{
*outEncoder = nullptr;
}
+#endif
virtual SLANG_NO_THROW void SLANG_MCALL close() override { m_cmdList->Close(); }
};
@@ -3810,6 +3687,7 @@ public:
DeviceInfo m_deviceInfo;
ID3D12Device* m_device = nullptr;
+ ID3D12Device5* m_device5 = nullptr;
VirtualObjectPool m_queueIndexAllocator;
@@ -4284,11 +4162,6 @@ static bool _isSupportedNVAPIOp(ID3D12Device* dev, uint32_t op)
Result D3D12Device::initialize(const Desc& desc)
{
- SLANG_RETURN_ON_FAIL(slangContext.initialize(
- desc.slang,
- SLANG_DXBC,
- "sm_5_1",
- makeArray(slang::PreprocessorMacroDesc{ "__D3D12__", "1" }).getView()));
SLANG_RETURN_ON_FAIL(RendererBase::initialize(desc));
@@ -4483,6 +4356,17 @@ Result D3D12Device::initialize(const Desc& desc)
m_info.adapterName = m_adapterName.begin();
}
+ // Initialize DXR interface.
+#if SLANG_GFX_HAS_DXR_SUPPORT
+ m_device->QueryInterface<ID3D12Device5>(m_deviceInfo.m_device5.writeRef());
+ m_device5 = m_deviceInfo.m_device5.get();
+#endif
+ SLANG_RETURN_ON_FAIL(slangContext.initialize(
+ desc.slang,
+ m_device5 ? SLANG_DXIL : SLANG_DXBC,
+ m_device5 ? "sm_6_5" : "sm_5_1",
+ makeArray(slang::PreprocessorMacroDesc{"__D3D12__", "1"}).getView()));
+
m_isInitialized = true;
return SLANG_OK;
}
@@ -4540,6 +4424,7 @@ static D3D12_RESOURCE_FLAGS _calcResourceFlag(ResourceState state)
case ResourceState::DepthWrite:
return D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL;
case ResourceState::UnorderedAccess:
+ case ResourceState::AccelerationStructure:
return D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS;
default:
return D3D12_RESOURCE_FLAG_NONE;
@@ -4944,7 +4829,7 @@ Result D3D12Device::createTextureView(ITextureResource* texture, IResourceView::
RefPtr<ResourceViewImpl> viewImpl = new ResourceViewImpl();
viewImpl->m_resource = resourceImpl;
-
+ viewImpl->m_desc = desc;
switch (desc.type)
{
default:
@@ -5045,6 +4930,7 @@ Result D3D12Device::createBufferView(IBufferResource* buffer, IResourceView::Des
RefPtr<ResourceViewImpl> viewImpl = new ResourceViewImpl();
viewImpl->m_resource = resourceImpl;
+ viewImpl->m_desc = desc;
switch (desc.type)
{
@@ -5620,11 +5506,308 @@ Result D3D12Device::QueryPoolImpl::init(const IQueryPool::Desc& desc, D3D12Devic
return SLANG_OK;
}
+Result D3D12Device::PlainBufferProxyQueryPoolImpl::init(
+ const IQueryPool::Desc& desc,
+ D3D12Device* device,
+ uint32_t stride)
+{
+ ComPtr<IBufferResource> bufferResource;
+ IBufferResource::Desc bufferDesc = {};
+ bufferDesc.defaultState = ResourceState::UnorderedAccess;
+ bufferDesc.elementSize = 0;
+ bufferDesc.type = IResource::Type::Buffer;
+ bufferDesc.sizeInBytes = desc.count * sizeof(uint64_t);
+ bufferDesc.format = Format::Unknown;
+ SLANG_RETURN_ON_FAIL(
+ device->createBufferResource(bufferDesc, nullptr, bufferResource.writeRef()));
+ m_bufferResource = static_cast<D3D12Device::BufferResourceImpl*>(bufferResource.get());
+ m_queryType = desc.type;
+ m_device = device;
+ m_stride = stride;
+ return SLANG_OK;
+}
+
Result D3D12Device::createQueryPool(const IQueryPool::Desc& desc, IQueryPool** outState)
{
- RefPtr<QueryPoolImpl> queryPoolImpl = new QueryPoolImpl();
- SLANG_RETURN_ON_FAIL(queryPoolImpl->init(desc, this));
- returnComPtr(outState, queryPoolImpl);
+ switch (desc.type)
+ {
+ case QueryType::AccelerationStructureCompactedSize:
+ case QueryType::AccelerationStructureSerializedSize:
+ {
+ RefPtr<PlainBufferProxyQueryPoolImpl> queryPoolImpl =
+ new PlainBufferProxyQueryPoolImpl();
+ uint32_t stride = 8;
+ if (desc.type == QueryType::AccelerationStructureSerializedSize)
+ stride = 16;
+ SLANG_RETURN_ON_FAIL(queryPoolImpl->init(desc, this, stride));
+ returnComPtr(outState, queryPoolImpl);
+ return SLANG_OK;
+ }
+ default:
+ {
+ RefPtr<QueryPoolImpl> queryPoolImpl = new QueryPoolImpl();
+ SLANG_RETURN_ON_FAIL(queryPoolImpl->init(desc, this));
+ returnComPtr(outState, queryPoolImpl);
+ return SLANG_OK;
+ }
+ }
+}
+
+#if SLANG_GFX_HAS_DXR_SUPPORT
+
+class D3D12AccelerationStructureImpl
+ : public AccelerationStructureBase
+ , public D3D12Device::ResourceViewInternalImpl
+{
+public:
+ RefPtr<D3D12Device::BufferResourceImpl> m_buffer;
+ uint64_t m_offset;
+ uint64_t m_size;
+ ComPtr<ID3D12Device5> m_device5;
+
+public:
+ virtual SLANG_NO_THROW DeviceAddress SLANG_MCALL getDeviceAddress() override
+ {
+ return m_buffer->getDeviceAddress() + m_offset;
+ }
+};
+
+Result D3D12Device::getAccelerationStructurePrebuildInfo(
+ const IAccelerationStructure::BuildInputs& buildInputs,
+ IAccelerationStructure::PrebuildInfo* outPrebuildInfo)
+{
+ if (!m_device5)
+ return SLANG_E_NOT_AVAILABLE;
+
+ D3DAccelerationStructureInputsBuilder inputsBuilder;
+ SLANG_RETURN_ON_FAIL(inputsBuilder.build(buildInputs, getDebugCallback()));
+
+ D3D12_RAYTRACING_ACCELERATION_STRUCTURE_PREBUILD_INFO prebuildInfo;
+ m_device5->GetRaytracingAccelerationStructurePrebuildInfo(&inputsBuilder.desc, &prebuildInfo);
+
+ outPrebuildInfo->resultDataMaxSize = prebuildInfo.ResultDataMaxSizeInBytes;
+ outPrebuildInfo->scratchDataSize = prebuildInfo.ScratchDataSizeInBytes;
+ outPrebuildInfo->updateScratchDataSize = prebuildInfo.UpdateScratchDataSizeInBytes;
+ return SLANG_OK;
+}
+
+Result D3D12Device::createAccelerationStructure(
+ const IAccelerationStructure::CreateDesc& desc,
+ IAccelerationStructure** outAS)
+{
+ RefPtr<D3D12AccelerationStructureImpl> result = new D3D12AccelerationStructureImpl();
+ result->m_device5 = m_device5;
+ result->m_buffer = static_cast<BufferResourceImpl*>(desc.buffer);
+ result->m_size = desc.size;
+ result->m_offset = desc.offset;
+ result->m_allocator = m_cpuViewHeap;
+ result->m_desc.type = IResourceView::Type::AccelerationStructure;
+ SLANG_RETURN_ON_FAIL(m_cpuViewHeap->allocate(&result->m_descriptor));
+ D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc;
+ srvDesc.Format = DXGI_FORMAT_UNKNOWN;
+ srvDesc.ViewDimension = D3D12_SRV_DIMENSION_RAYTRACING_ACCELERATION_STRUCTURE;
+ srvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
+ srvDesc.RaytracingAccelerationStructure.Location =
+ result->m_buffer->getDeviceAddress()+ desc.offset;
+ m_device->CreateShaderResourceView(nullptr, &srvDesc, result->m_descriptor.cpuHandle);
+ returnComPtr(outAS, result);
+ return SLANG_OK;
+}
+
+void translatePostBuildInfoDescs(
+ int propertyQueryCount,
+ AccelerationStructureQueryDesc* queryDescs,
+ List<D3D12_RAYTRACING_ACCELERATION_STRUCTURE_POSTBUILD_INFO_DESC>& postBuildInfoDescs)
+{
+ postBuildInfoDescs.setCount(propertyQueryCount);
+ for (int i = 0; i < propertyQueryCount; i++)
+ {
+ switch (queryDescs[i].queryType)
+ {
+ case QueryType::AccelerationStructureCompactedSize:
+ postBuildInfoDescs[i].InfoType =
+ D3D12_RAYTRACING_ACCELERATION_STRUCTURE_POSTBUILD_INFO_COMPACTED_SIZE;
+ postBuildInfoDescs[i].DestBuffer =
+ static_cast<D3D12Device::PlainBufferProxyQueryPoolImpl*>(queryDescs[i].queryPool)
+ ->m_bufferResource->getDeviceAddress() +
+ sizeof(D3D12_RAYTRACING_ACCELERATION_STRUCTURE_POSTBUILD_INFO_COMPACTED_SIZE_DESC) *
+ queryDescs[i].firstQueryIndex;
+ break;
+ case QueryType::AccelerationStructureSerializedSize:
+ postBuildInfoDescs[i].InfoType =
+ D3D12_RAYTRACING_ACCELERATION_STRUCTURE_POSTBUILD_INFO_SERIALIZATION;
+ postBuildInfoDescs[i].DestBuffer =
+ static_cast<D3D12Device::PlainBufferProxyQueryPoolImpl*>(queryDescs[i].queryPool)
+ ->m_bufferResource->getDeviceAddress() +
+ sizeof(D3D12_RAYTRACING_ACCELERATION_STRUCTURE_POSTBUILD_INFO_SERIALIZATION_DESC) *
+ queryDescs[i].firstQueryIndex;
+ break;
+ }
+ }
+}
+
+void D3D12Device::CommandBufferImpl::RayTracingCommandEncoderImpl::buildAccelerationStructure(
+ const IAccelerationStructure::BuildDesc& desc,
+ int propertyQueryCount,
+ AccelerationStructureQueryDesc* queryDescs)
+{
+ if (!m_commandBuffer->m_cmdList4)
+ {
+ getDebugCallback()->handleMessage(
+ DebugMessageType::Error,
+ DebugMessageSource::Layer,
+ "Ray-tracing is not supported on current system.");
+ return;
+ }
+ D3D12AccelerationStructureImpl* destASImpl = nullptr;
+ if (desc.dest)
+ destASImpl = static_cast<D3D12AccelerationStructureImpl*>(desc.dest);
+ D3D12AccelerationStructureImpl* srcASImpl = nullptr;
+ if (desc.source)
+ srcASImpl = static_cast<D3D12AccelerationStructureImpl*>(desc.source);
+
+ D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_DESC buildDesc = {};
+ buildDesc.DestAccelerationStructureData = destASImpl->getDeviceAddress();
+ buildDesc.SourceAccelerationStructureData = srcASImpl?srcASImpl->getDeviceAddress() : 0;
+ buildDesc.ScratchAccelerationStructureData = desc.scratchData;
+ D3DAccelerationStructureInputsBuilder builder;
+ builder.build(desc.inputs, getDebugCallback());
+ buildDesc.Inputs = builder.desc;
+
+ List<D3D12_RAYTRACING_ACCELERATION_STRUCTURE_POSTBUILD_INFO_DESC> postBuildInfoDescs;
+ translatePostBuildInfoDescs(propertyQueryCount, queryDescs, postBuildInfoDescs);
+ m_commandBuffer->m_cmdList4->BuildRaytracingAccelerationStructure(
+ &buildDesc, (UINT)propertyQueryCount, postBuildInfoDescs.getBuffer());
+}
+
+void D3D12Device::CommandBufferImpl::RayTracingCommandEncoderImpl::copyAccelerationStructure(
+ IAccelerationStructure* dest,
+ IAccelerationStructure* src,
+ AccelerationStructureCopyMode mode)
+{
+ auto destASImpl = static_cast<D3D12AccelerationStructureImpl*>(dest);
+ auto srcASImpl = static_cast<D3D12AccelerationStructureImpl*>(src);
+ D3D12_RAYTRACING_ACCELERATION_STRUCTURE_COPY_MODE copyMode;
+ switch (mode)
+ {
+ case AccelerationStructureCopyMode::Clone:
+ copyMode = D3D12_RAYTRACING_ACCELERATION_STRUCTURE_COPY_MODE_CLONE;
+ break;
+ case AccelerationStructureCopyMode::Compact:
+ copyMode = D3D12_RAYTRACING_ACCELERATION_STRUCTURE_COPY_MODE_COMPACT;
+ break;
+ default:
+ getDebugCallback()->handleMessage(
+ DebugMessageType::Error,
+ DebugMessageSource::Layer,
+ "Unsupported AccelerationStructureCopyMode.");
+ return;
+ }
+ m_commandBuffer->m_cmdList4->CopyRaytracingAccelerationStructure(
+ destASImpl->getDeviceAddress(), srcASImpl->getDeviceAddress(), copyMode);
+}
+
+void D3D12Device::CommandBufferImpl::RayTracingCommandEncoderImpl::
+ queryAccelerationStructureProperties(
+ int accelerationStructureCount,
+ IAccelerationStructure* const* accelerationStructures,
+ int queryCount,
+ AccelerationStructureQueryDesc* queryDescs)
+{
+ List<D3D12_RAYTRACING_ACCELERATION_STRUCTURE_POSTBUILD_INFO_DESC> postBuildInfoDescs;
+ List<DeviceAddress> asAddresses;
+ asAddresses.setCount(accelerationStructureCount);
+ for (int i = 0; i < accelerationStructureCount; i++)
+ asAddresses[i] = accelerationStructures[i]->getDeviceAddress();
+ translatePostBuildInfoDescs(queryCount, queryDescs, postBuildInfoDescs);
+ m_commandBuffer->m_cmdList4->EmitRaytracingAccelerationStructurePostbuildInfo(
+ postBuildInfoDescs.getBuffer(),
+ (UINT)accelerationStructureCount,
+ asAddresses.getBuffer());
+}
+
+void D3D12Device::CommandBufferImpl::RayTracingCommandEncoderImpl::serializeAccelerationStructure(
+ DeviceAddress dest,
+ IAccelerationStructure* src)
+{
+ auto srcASImpl = static_cast<D3D12AccelerationStructureImpl*>(src);
+ m_commandBuffer->m_cmdList4->CopyRaytracingAccelerationStructure(
+ dest,
+ srcASImpl->getDeviceAddress(),
+ D3D12_RAYTRACING_ACCELERATION_STRUCTURE_COPY_MODE_SERIALIZE);
+}
+
+void D3D12Device::CommandBufferImpl::RayTracingCommandEncoderImpl::deserializeAccelerationStructure(
+ IAccelerationStructure* dest,
+ DeviceAddress source)
+{
+ auto destASImpl = static_cast<D3D12AccelerationStructureImpl*>(dest);
+ m_commandBuffer->m_cmdList4->CopyRaytracingAccelerationStructure(
+ dest->getDeviceAddress(),
+ source,
+ D3D12_RAYTRACING_ACCELERATION_STRUCTURE_COPY_MODE_DESERIALIZE);
+}
+
+void D3D12Device::CommandBufferImpl::RayTracingCommandEncoderImpl::memoryBarrier(
+ int count,
+ IAccelerationStructure* const* structures,
+ AccessFlag::Enum sourceAccess,
+ AccessFlag::Enum destAccess)
+{
+ ShortList<D3D12_RESOURCE_BARRIER> barriers;
+ barriers.setCount(count);
+ for (int i = 0; i < count; i++)
+ {
+ barriers[i].Type = D3D12_RESOURCE_BARRIER_TYPE_UAV;
+ barriers[i].UAV.pResource = static_cast<D3D12AccelerationStructureImpl*>(structures[i])
+ ->m_buffer->m_resource.getResource();
+ }
+ m_commandBuffer->m_cmdList4->ResourceBarrier((UINT)count, barriers.getArrayView().getBuffer());
+}
+
+#endif // SLANG_GFX_HAS_DXR_SUPPORT
+Result D3D12Device::ShaderObjectImpl::setResource(ShaderOffset const& offset, IResourceView* resourceView)
+{
+ if (offset.bindingRangeIndex < 0)
+ return SLANG_E_INVALID_ARG;
+ auto layout = getLayout();
+ if (offset.bindingRangeIndex >= layout->getBindingRangeCount())
+ return SLANG_E_INVALID_ARG;
+
+ auto& bindingRange = layout->getBindingRange(offset.bindingRangeIndex);
+
+ ResourceViewInternalImpl* internalResourceView = nullptr;
+ switch (resourceView->getViewDesc()->type)
+ {
+#if SLANG_GFX_HAS_DXR_SUPPORT
+ case IResourceView::Type::AccelerationStructure:
+ {
+ auto asImpl = static_cast<D3D12AccelerationStructureImpl*>(resourceView);
+ // Hold a reference to the resource to prevent its destruction.
+ m_boundResources[bindingRange.baseIndex + offset.bindingArrayIndex] = asImpl->m_buffer;
+ internalResourceView = asImpl;
+ }
+ break;
+#endif
+ default:
+ {
+ auto resourceViewImpl = static_cast<ResourceViewImpl*>(resourceView);
+ // Hold a reference to the resource to prevent its destruction.
+ m_boundResources[bindingRange.baseIndex + offset.bindingArrayIndex] =
+ resourceViewImpl->m_resource;
+ internalResourceView = resourceViewImpl;
+ }
+ break;
+ }
+
+ auto descriptorSlotIndex = bindingRange.baseIndex + (int32_t)offset.bindingArrayIndex;
+ ID3D12Device* d3dDevice = static_cast<D3D12Device*>(getDevice())->m_device;
+ d3dDevice->CopyDescriptorsSimple(
+ 1,
+ m_descriptorSet.resourceTable.getCpuHandle(
+ bindingRange.baseIndex + (int32_t)offset.bindingArrayIndex),
+ internalResourceView->m_descriptor.cpuHandle,
+ D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
return SLANG_OK;
}
diff --git a/tools/gfx/debug-layer.cpp b/tools/gfx/debug-layer.cpp
index 7ad0dd31c..77dd8543e 100644
--- a/tools/gfx/debug-layer.cpp
+++ b/tools/gfx/debug-layer.cpp
@@ -180,6 +180,78 @@ SLANG_GFX_DEBUG_GET_OBJ_IMPL(AccelerationStructure)
#undef SLANG_GFX_DEBUG_GET_OBJ_IMPL
+void validateAccelerationStructureBuildInputs(
+ const IAccelerationStructure::BuildInputs& buildInputs)
+{
+ switch (buildInputs.kind)
+ {
+ case IAccelerationStructure::Kind::TopLevel:
+ if (!buildInputs.instanceDescs)
+ {
+ GFX_DIAGNOSE_ERROR("IAccelerationStructure::BuildInputs::instanceDescs cannot be null "
+ "when creating a top-level acceleration structure.");
+ }
+ break;
+ case IAccelerationStructure::Kind::BottomLevel:
+ if (!buildInputs.geometryDescs)
+ {
+ GFX_DIAGNOSE_ERROR("IAccelerationStructure::BuildInputs::geometryDescs cannot be null "
+ "when creating a bottom-level acceleration structure.");
+ }
+ for (int i = 0; i < buildInputs.descCount; i++)
+ {
+ switch (buildInputs.geometryDescs[i].type)
+ {
+ case IAccelerationStructure::GeometryType::Triangles:
+ switch (buildInputs.geometryDescs[i].content.triangles.vertexFormat)
+ {
+ case Format::RGB_Float32:
+ case Format::RG_Float32:
+ case Format::RGBA_Float16:
+ case Format::RG_Float16:
+ case Format::RGBA_Snorm_UInt16:
+ case Format::RG_Snorm_UInt16:
+ break;
+ default:
+ GFX_DIAGNOSE_ERROR(
+ "Unsupported IAccelerationStructure::TriangleDesc::vertexFormat. Valid "
+ "values are RGB_Float32, RG_Float32, RGBA_Float16, RG_Float16, "
+ "RGBA_Snorm_UInt16 or RG_Snorm_UInt16.");
+ }
+ if (buildInputs.geometryDescs[i].content.triangles.indexCount)
+ {
+ switch (buildInputs.geometryDescs[i].content.triangles.indexFormat)
+ {
+ case Format::R_UInt32:
+ case Format::R_UInt16:
+ break;
+ default:
+ GFX_DIAGNOSE_ERROR(
+ "Unsupported IAccelerationStructure::TriangleDesc::indexFormat. Valid "
+ "values are R_UInt32 or R_UInt16.");
+ }
+ if (!buildInputs.geometryDescs[i].content.triangles.indexData)
+ {
+ GFX_DIAGNOSE_ERROR(
+ "IAccelerationStructure::TriangleDesc::indexData cannot be null if "
+ "IAccelerationStructure::TriangleDesc::indexCount is not 0");
+ }
+ }
+ if (!buildInputs.geometryDescs[i].content.triangles.vertexData)
+ {
+ GFX_DIAGNOSE_ERROR(
+ "IAccelerationStructure::TriangleDesc::vertexData cannot be null.");
+ }
+ break;
+ }
+ }
+ break;
+ default:
+ GFX_DIAGNOSE_ERROR("Invalid value of IAccelerationStructure::Kind.");
+ break;
+ }
+}
+
Result DebugDevice::getFeatures(const char** outFeatures, UInt bufferSize, UInt* outFeatureCount)
{
SLANG_GFX_API_FUNC;
@@ -306,7 +378,7 @@ Result DebugDevice::getAccelerationStructurePrebuildInfo(
IAccelerationStructure::PrebuildInfo* outPrebuildInfo)
{
SLANG_GFX_API_FUNC;
-
+ validateAccelerationStructureBuildInputs(buildInputs);
return baseObject->getAccelerationStructurePrebuildInfo(buildInputs, outPrebuildInfo);
}
@@ -892,6 +964,7 @@ void DebugRayTracingCommandEncoder::buildAccelerationStructure(
{
innerQueryDesc.queryPool = getInnerObj(innerQueryDesc.queryPool);
}
+ validateAccelerationStructureBuildInputs(desc.inputs);
baseObject->buildAccelerationStructure(
innerDesc, propertyQueryCount, innerQueryDescs.getBuffer());
}
@@ -1228,4 +1301,18 @@ DeviceAddress DebugAccelerationStructure::getDeviceAddress()
return baseObject->getDeviceAddress();
}
+IResourceView::Desc* DebugResourceView::getViewDesc()
+{
+ SLANG_GFX_API_FUNC;
+
+ return baseObject->getViewDesc();
+}
+
+IResourceView::Desc* DebugAccelerationStructure::getViewDesc()
+{
+ SLANG_GFX_API_FUNC;
+
+ return baseObject->getViewDesc();
+}
+
} // namespace gfx
diff --git a/tools/gfx/debug-layer.h b/tools/gfx/debug-layer.h
index 8ab1146d0..49ef99f99 100644
--- a/tools/gfx/debug-layer.h
+++ b/tools/gfx/debug-layer.h
@@ -160,6 +160,7 @@ public:
public:
IResourceView* getInterface(const Slang::Guid& guid);
+ virtual SLANG_NO_THROW Desc* SLANG_MCALL getViewDesc() override;
};
class DebugAccelerationStructure : public DebugObject<IAccelerationStructure>
@@ -170,6 +171,7 @@ public:
public:
IAccelerationStructure* getInterface(const Slang::Guid& guid);
virtual SLANG_NO_THROW DeviceAddress SLANG_MCALL getDeviceAddress() override;
+ virtual SLANG_NO_THROW Desc* SLANG_MCALL getViewDesc() override;
};
class DebugSamplerState : public DebugObject<ISamplerState>
@@ -341,7 +343,7 @@ public:
virtual SLANG_NO_THROW void SLANG_MCALL deserializeAccelerationStructure(
IAccelerationStructure* dest,
DeviceAddress source) override;
- virtual SLANG_NO_THROW void memoryBarrier(
+ virtual SLANG_NO_THROW void SLANG_MCALL memoryBarrier(
int count,
IAccelerationStructure* const* structures,
AccessFlag::Enum sourceAccess,
diff --git a/tools/gfx/open-gl/render-gl.cpp b/tools/gfx/open-gl/render-gl.cpp
index 92f8680d7..776806a49 100644
--- a/tools/gfx/open-gl/render-gl.cpp
+++ b/tools/gfx/open-gl/render-gl.cpp
@@ -2502,6 +2502,8 @@ SLANG_NO_THROW Result SLANG_MCALL GLDevice::createTextureView(
viewImpl->m_textureID = resourceImpl->m_handle;
viewImpl->type = ResourceViewImpl::Type::Texture;
viewImpl->m_target = resourceImpl->m_target;
+ viewImpl->m_desc = desc;
+
if (desc.type == IResourceView::Type::ShaderResource)
{
viewImpl->access = GL_READ_ONLY;
@@ -2532,6 +2534,8 @@ SLANG_NO_THROW Result SLANG_MCALL GLDevice::createBufferView(
viewImpl->type = ResourceViewImpl::Type::Buffer;
viewImpl->m_resource = resourceImpl;
viewImpl->m_bufferID = resourceImpl->m_handle;
+ viewImpl->m_desc = desc;
+
returnComPtr(outView, viewImpl);
return SLANG_OK;
}
diff --git a/tools/gfx/renderer-shared.h b/tools/gfx/renderer-shared.h
index e3580b9b6..6863a95a0 100644
--- a/tools/gfx/renderer-shared.h
+++ b/tools/gfx/renderer-shared.h
@@ -245,22 +245,30 @@ protected:
Desc m_desc;
};
+class ResourceViewInternalBase : public Slang::ComObject
+{};
+
class ResourceViewBase
: public IResourceView
- , public Slang::ComObject
+ , public ResourceViewInternalBase
{
public:
+ Desc m_desc = {};
SLANG_COM_OBJECT_IUNKNOWN_ALL
IResourceView* getInterface(const Slang::Guid& guid);
+ virtual SLANG_NO_THROW Desc* SLANG_MCALL getViewDesc() override { return &m_desc; }
};
class AccelerationStructureBase
: public IAccelerationStructure
- , public Slang::ComObject
+ , public ResourceViewInternalBase
{
public:
+ IResourceView::Desc m_desc = {};
+
SLANG_COM_OBJECT_IUNKNOWN_ALL
IAccelerationStructure* getInterface(const Slang::Guid& guid);
+ virtual SLANG_NO_THROW Desc* SLANG_MCALL getViewDesc() override { return &m_desc; }
};
class RendererBase;
diff --git a/tools/gfx/vulkan/render-vk.cpp b/tools/gfx/vulkan/render-vk.cpp
index 10cc7aae5..90bd49868 100644
--- a/tools/gfx/vulkan/render-vk.cpp
+++ b/tools/gfx/vulkan/render-vk.cpp
@@ -2352,9 +2352,16 @@ public:
if (offset.bindingRangeIndex >= layout->getBindingRangeCount())
return SLANG_E_INVALID_ARG;
auto& bindingRange = layout->getBindingRange(offset.bindingRangeIndex);
-
- m_resourceViews[bindingRange.baseIndex + offset.bindingArrayIndex] =
- static_cast<ResourceViewImpl*>(resourceView);
+ if (resourceView->getViewDesc()->type == IResourceView::Type::AccelerationStructure)
+ {
+ m_resourceViews[bindingRange.baseIndex + offset.bindingArrayIndex] =
+ static_cast<AccelerationStructureImpl*>(resourceView);
+ }
+ else
+ {
+ m_resourceViews[bindingRange.baseIndex + offset.bindingArrayIndex] =
+ static_cast<ResourceViewImpl*>(resourceView);
+ }
return SLANG_OK;
}
@@ -2640,7 +2647,7 @@ public:
RootBindingContext& context,
BindingOffset const& offset,
VkDescriptorType descriptorType,
- ArrayView<RefPtr<ResourceViewImpl>> resourceViews)
+ ArrayView<RefPtr<ResourceViewInternalBase>> resourceViews)
{
auto descriptorSet = context.descriptorSets[offset.bindingSet];
@@ -2675,7 +2682,7 @@ public:
RootBindingContext& context,
BindingOffset const& offset,
VkDescriptorType descriptorType,
- ArrayView<RefPtr<ResourceViewImpl>> resourceViews)
+ ArrayView<RefPtr<ResourceViewInternalBase>> resourceViews)
{
auto descriptorSet = context.descriptorSets[offset.bindingSet];
@@ -2735,15 +2742,15 @@ public:
RootBindingContext& context,
BindingOffset const& offset,
VkDescriptorType descriptorType,
- ArrayView<RefPtr<ResourceViewImpl>> resourceViews)
+ ArrayView<RefPtr<ResourceViewInternalBase>> resourceViews)
{
auto descriptorSet = context.descriptorSets[offset.bindingSet];
Index count = resourceViews.getCount();
for (Index i = 0; i < count; ++i)
{
- auto accelerationStructure = static_cast<AccelerationStructureImpl*>(
- static_cast<IResourceView*>(resourceViews[i].Ptr()));
+ auto accelerationStructure =
+ static_cast<AccelerationStructureImpl*>(resourceViews[i].Ptr());
VkWriteDescriptorSetAccelerationStructureKHR writeAS = {};
writeAS.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR;
@@ -2765,7 +2772,7 @@ public:
RootBindingContext& context,
BindingOffset const& offset,
VkDescriptorType descriptorType,
- ArrayView<RefPtr<ResourceViewImpl>> resourceViews)
+ ArrayView<RefPtr<ResourceViewInternalBase>> resourceViews)
{
auto descriptorSet = context.descriptorSets[offset.bindingSet];
@@ -3218,7 +3225,7 @@ public:
return SLANG_OK;
}
- List<RefPtr<ResourceViewImpl>> m_resourceViews;
+ List<RefPtr<ResourceViewInternalBase>> m_resourceViews;
List<RefPtr<SamplerStateImpl>> m_samplers;
@@ -4274,7 +4281,7 @@ public:
m_commandBuffer->m_commandBuffer, &copyInfo);
}
- virtual SLANG_NO_THROW void memoryBarrier(
+ virtual SLANG_NO_THROW void SLANG_MCALL memoryBarrier(
int count,
IAccelerationStructure* const* structures,
AccessFlag::Enum srcAccess,
@@ -5837,6 +5844,7 @@ Result VKDevice::createAccelerationStructure(
resultAS->m_size = desc.size;
resultAS->m_buffer = static_cast<BufferResourceImpl*>(desc.buffer);
resultAS->m_device = this;
+ resultAS->m_desc.type = IResourceView::Type::AccelerationStructure;
VkAccelerationStructureCreateInfoKHR createInfo = {VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_KHR};
createInfo.buffer = resultAS->m_buffer->m_buffer.m_buffer;
createInfo.offset = desc.offset;
@@ -6620,6 +6628,7 @@ Result VKDevice::createTextureView(ITextureResource* texture, IResourceView::Des
SLANG_UNIMPLEMENTED_X("Unknown TextureViewDesc type.");
break;
}
+ view->m_desc = desc;
m_api.vkCreateImageView(m_device, &createInfo, nullptr, &view->m_view);
returnComPtr(outView, view);
return SLANG_OK;
@@ -6670,6 +6679,8 @@ Result VKDevice::createBufferView(IBufferResource* buffer, IResourceView::Desc c
viewImpl->m_buffer = resourceImpl;
viewImpl->offset = 0;
viewImpl->size = size;
+ viewImpl->m_desc = desc;
+
returnComPtr(outView, viewImpl);
return SLANG_OK;
}
@@ -6692,6 +6703,8 @@ Result VKDevice::createBufferView(IBufferResource* buffer, IResourceView::Desc c
RefPtr<TexelBufferResourceViewImpl> viewImpl = new TexelBufferResourceViewImpl(this);
viewImpl->m_buffer = resourceImpl;
viewImpl->m_view = view;
+ viewImpl->m_desc = desc;
+
returnComPtr(outView, viewImpl);
return SLANG_OK;
}
diff --git a/tools/gfx/vulkan/vk-util.cpp b/tools/gfx/vulkan/vk-util.cpp
index 4971e3f3d..c138254c0 100644
--- a/tools/gfx/vulkan/vk-util.cpp
+++ b/tools/gfx/vulkan/vk-util.cpp
@@ -22,6 +22,8 @@ namespace gfx {
case Format::RGBA_Unorm_UInt8: return VK_FORMAT_R8G8B8A8_UNORM;
case Format::BGRA_Unorm_UInt8: return VK_FORMAT_B8G8R8A8_UNORM;
+ case Format::RGBA_Snorm_UInt16: return VK_FORMAT_R16G16B16A16_SNORM;
+ case Format::RG_Snorm_UInt16: return VK_FORMAT_R16G16_SNORM;
case Format::R_UInt32: return VK_FORMAT_R32_UINT;
case Format::D_Float32: return VK_FORMAT_D32_SFLOAT;