summaryrefslogtreecommitdiffstats
path: root/tools/gfx/d3d12
diff options
context:
space:
mode:
authorskallweitNV <64953474+skallweitNV@users.noreply.github.com>2024-05-14 00:39:49 +0200
committerGitHub <noreply@github.com>2024-05-13 15:39:49 -0700
commit9f23046138629f78995d54a7722ad6749bd84db9 (patch)
tree25ac343566f896cae547046ac7e960441874ec00 /tools/gfx/d3d12
parent04d3dd51125182767d90c318895a6232ec4ee750 (diff)
[gfx] specify resource view buffer range in bytes (#4149)
* refactor gfx buffer range to use byte range * create buffer view with zero struct stride for ClearUnorderedAccessViewUint/Float * create buffer descriptors on demand * avoid copying gfx.dll --------- Co-authored-by: Yong He <yonghe@outlook.com>
Diffstat (limited to 'tools/gfx/d3d12')
-rw-r--r--tools/gfx/d3d12/d3d12-command-encoder.cpp9
-rw-r--r--tools/gfx/d3d12/d3d12-device.cpp12
-rw-r--r--tools/gfx/d3d12/d3d12-resource-views.cpp101
-rw-r--r--tools/gfx/d3d12/d3d12-resource-views.h1
-rw-r--r--tools/gfx/d3d12/d3d12-shader-object.cpp16
5 files changed, 45 insertions, 94 deletions
diff --git a/tools/gfx/d3d12/d3d12-command-encoder.cpp b/tools/gfx/d3d12/d3d12-command-encoder.cpp
index b88bf3168..ff50dcc5f 100644
--- a/tools/gfx/d3d12/d3d12-command-encoder.cpp
+++ b/tools/gfx/d3d12/d3d12-command-encoder.cpp
@@ -384,11 +384,14 @@ void ResourceCommandEncoderImpl::clearResourceView(
case IResourceView::Type::UnorderedAccess:
{
ID3D12Resource* d3dResource = nullptr;
+ D3D12Descriptor descriptor = viewImpl->m_descriptor;
switch (viewImpl->m_resource->getType())
{
case IResource::Type::Buffer:
d3dResource = static_cast<BufferResourceImpl*>(viewImpl->m_resource.Ptr())
->m_resource.getResource();
+ // D3D12 requires a UAV descriptor with zero buffer stride for calling ClearUnorderedAccessViewUint/Float.
+ viewImpl->getBufferDescriptorForBinding(m_commandBuffer->m_renderer, viewImpl, 0, descriptor);
break;
default:
d3dResource = static_cast<TextureResourceImpl*>(viewImpl->m_resource.Ptr())
@@ -407,7 +410,7 @@ void ResourceCommandEncoderImpl::clearResourceView(
this->m_commandBuffer->m_renderer->m_device->CopyDescriptorsSimple(
1,
m_commandBuffer->m_transientHeap->getCurrentViewHeap().getCpuHandle(gpuHandleIndex),
- viewImpl->m_descriptor.cpuHandle,
+ descriptor.cpuHandle,
D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
if (flags & ClearResourceViewFlags::FloatClearValues)
@@ -415,7 +418,7 @@ void ResourceCommandEncoderImpl::clearResourceView(
m_commandBuffer->m_cmdList->ClearUnorderedAccessViewFloat(
m_commandBuffer->m_transientHeap->getCurrentViewHeap().getGpuHandle(
gpuHandleIndex),
- viewImpl->m_descriptor.cpuHandle,
+ descriptor.cpuHandle,
d3dResource,
clearValue->color.floatValues,
0,
@@ -426,7 +429,7 @@ void ResourceCommandEncoderImpl::clearResourceView(
m_commandBuffer->m_cmdList->ClearUnorderedAccessViewUint(
m_commandBuffer->m_transientHeap->getCurrentViewHeap().getGpuHandle(
gpuHandleIndex),
- viewImpl->m_descriptor.cpuHandle,
+ descriptor.cpuHandle,
d3dResource,
clearValue->color.uintValues,
0,
diff --git a/tools/gfx/d3d12/d3d12-device.cpp b/tools/gfx/d3d12/d3d12-device.cpp
index 03f9997f4..6be37b079 100644
--- a/tools/gfx/d3d12/d3d12-device.cpp
+++ b/tools/gfx/d3d12/d3d12-device.cpp
@@ -1674,15 +1674,9 @@ Result DeviceImpl::createBufferView(
viewImpl->m_counterResource = counterResourceImpl;
viewImpl->m_desc = desc;
- SLANG_RETURN_ON_FAIL(createD3D12BufferDescriptor(
- resourceImpl,
- counterResourceImpl,
- desc,
- this,
- m_cpuViewHeap.get(),
- &viewImpl->m_descriptor));
- if (viewImpl->m_descriptor.cpuHandle.ptr != 0)
- viewImpl->m_allocator = m_cpuViewHeap.get();
+ // Buffer view descriptors are created on demand.
+ viewImpl->m_descriptor = {0};
+ viewImpl->m_allocator = m_cpuViewHeap.get();
returnComPtr(outView, viewImpl);
return SLANG_OK;
diff --git a/tools/gfx/d3d12/d3d12-resource-views.cpp b/tools/gfx/d3d12/d3d12-resource-views.cpp
index b0b441f87..b156f6ab6 100644
--- a/tools/gfx/d3d12/d3d12-resource-views.cpp
+++ b/tools/gfx/d3d12/d3d12-resource-views.cpp
@@ -23,6 +23,7 @@ SlangResult createD3D12BufferDescriptor(
BufferResourceImpl* buffer,
BufferResourceImpl* counterBuffer,
IResourceView::Desc const& desc,
+ uint32_t bufferStride,
DeviceImpl* device,
D3D12GeneralExpandingDescriptorHeap* descriptorHeap,
D3D12Descriptor* outDescriptor)
@@ -32,6 +33,9 @@ SlangResult createD3D12BufferDescriptor(
auto resourceDesc = *resourceImpl->getDesc();
const auto counterResourceImpl = static_cast<BufferResourceImpl*>(counterBuffer);
+ uint64_t offset = desc.bufferRange.offset;
+ uint64_t size = desc.bufferRange.size == 0 ? buffer->getDesc()->sizeInBytes - offset : desc.bufferRange.size;
+
switch (desc.type)
{
default:
@@ -42,39 +46,29 @@ SlangResult createD3D12BufferDescriptor(
D3D12_UNORDERED_ACCESS_VIEW_DESC uavDesc = {};
uavDesc.ViewDimension = D3D12_UAV_DIMENSION_BUFFER;
uavDesc.Format = D3DUtil::getMapFormat(desc.format);
- uavDesc.Buffer.FirstElement = desc.bufferRange.firstElement;
- uint64_t viewSize = 0;
- if (desc.bufferElementSize)
+ if (bufferStride)
{
- uavDesc.Buffer.StructureByteStride = (UINT)desc.bufferElementSize;
- uavDesc.Buffer.NumElements =
- desc.bufferRange.elementCount == 0
- ? UINT(resourceDesc.sizeInBytes / desc.bufferElementSize)
- : (UINT)desc.bufferRange.elementCount;
- viewSize = (uint64_t)desc.bufferElementSize * uavDesc.Buffer.NumElements;
+ uavDesc.Buffer.FirstElement = offset / bufferStride;
+ uavDesc.Buffer.NumElements = UINT(size / bufferStride);
+ uavDesc.Buffer.StructureByteStride = bufferStride;
}
else if (desc.format == Format::Unknown)
{
uavDesc.Format = DXGI_FORMAT_R32_TYPELESS;
- uavDesc.Buffer.NumElements = desc.bufferRange.elementCount == 0
- ? UINT(resourceDesc.sizeInBytes / 4)
- : UINT(desc.bufferRange.elementCount / 4);
+ uavDesc.Buffer.FirstElement = offset / 4;
+ uavDesc.Buffer.NumElements = UINT(size / 4);
uavDesc.Buffer.Flags |= D3D12_BUFFER_UAV_FLAG_RAW;
- viewSize = 4ull * uavDesc.Buffer.NumElements;
}
else
{
FormatInfo sizeInfo;
gfxGetFormatInfo(desc.format, &sizeInfo);
assert(sizeInfo.pixelsPerBlock == 1);
- uavDesc.Buffer.NumElements =
- desc.bufferRange.elementCount == 0
- ? UINT(resourceDesc.sizeInBytes / sizeInfo.blockSizeInBytes)
- : (UINT)desc.bufferRange.elementCount;
- viewSize = (uint64_t)uavDesc.Buffer.NumElements * sizeInfo.blockSizeInBytes;
+ uavDesc.Buffer.FirstElement = offset / sizeInfo.blockSizeInBytes;
+ uavDesc.Buffer.NumElements = UINT(size / sizeInfo.blockSizeInBytes);
}
- if (viewSize >= (1ull << 32) - 8)
+ if (size >= (1ull << 32) - 8)
{
// D3D12 does not support view descriptors that has size near 4GB.
// We will not create actual SRV/UAVs for such large buffers.
@@ -99,40 +93,30 @@ SlangResult createD3D12BufferDescriptor(
D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc = {};
srvDesc.ViewDimension = D3D12_SRV_DIMENSION_BUFFER;
srvDesc.Format = D3DUtil::getMapFormat(desc.format);
- srvDesc.Buffer.StructureByteStride = 0;
- srvDesc.Buffer.FirstElement = desc.bufferRange.firstElement;
srvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
- uint64_t viewSize = 0;
- if (desc.bufferElementSize)
+ if (bufferStride)
{
- srvDesc.Buffer.StructureByteStride = (UINT)desc.bufferElementSize;
- srvDesc.Buffer.NumElements =
- desc.bufferRange.elementCount == 0
- ? UINT(resourceDesc.sizeInBytes / desc.bufferElementSize)
- : (UINT)desc.bufferRange.elementCount;
- viewSize = (uint64_t)desc.bufferElementSize * srvDesc.Buffer.NumElements;
+ srvDesc.Buffer.FirstElement = offset / bufferStride;
+ srvDesc.Buffer.NumElements = UINT(size / bufferStride);
+ srvDesc.Buffer.StructureByteStride = bufferStride;
}
else if (desc.format == Format::Unknown)
{
srvDesc.Format = DXGI_FORMAT_R32_TYPELESS;
- srvDesc.Buffer.NumElements = desc.bufferRange.elementCount == 0
- ? UINT(resourceDesc.sizeInBytes / 4)
- : UINT(desc.bufferRange.elementCount / 4);
+ srvDesc.Buffer.FirstElement = offset / 4;
+ srvDesc.Buffer.NumElements = UINT(size / 4);
srvDesc.Buffer.Flags |= D3D12_BUFFER_SRV_FLAG_RAW;
- viewSize = 4ull * srvDesc.Buffer.NumElements;
}
else
{
FormatInfo sizeInfo;
gfxGetFormatInfo(desc.format, &sizeInfo);
assert(sizeInfo.pixelsPerBlock == 1);
- srvDesc.Buffer.NumElements =
- desc.bufferRange.elementCount == 0
- ? UINT(resourceDesc.sizeInBytes / sizeInfo.blockSizeInBytes)
- : (UINT)desc.bufferRange.elementCount;
- viewSize = (uint64_t)srvDesc.Buffer.NumElements * sizeInfo.blockSizeInBytes;
+ srvDesc.Buffer.FirstElement = offset / sizeInfo.blockSizeInBytes;
+ srvDesc.Buffer.NumElements = UINT(size / sizeInfo.blockSizeInBytes);
}
- if (viewSize >= (1ull << 32) - 8)
+
+ if (size >= (1ull << 32) - 8)
{
// D3D12 does not support view descriptors that has size near 4GB.
// We will not create actual SRV/UAVs for such large buffers.
@@ -158,14 +142,7 @@ SlangResult ResourceViewInternalImpl::getBufferDescriptorForBinding(
uint32_t bufferStride,
D3D12Descriptor& outDescriptor)
{
- // If stride is 0, just use the default descriptor.
- if (bufferStride == 0)
- {
- outDescriptor = m_descriptor;
- return SLANG_OK;
- }
-
- // Otherwise, look for an existing descriptor from the cache if it exists.
+ // Look for an existing descriptor from the cache if it exists.
if (auto descriptor = m_mapBufferStrideToDescriptor.tryGetValue(bufferStride))
{
outDescriptor = *descriptor;
@@ -176,39 +153,11 @@ SlangResult ResourceViewInternalImpl::getBufferDescriptorForBinding(
// the given buffer stride.
auto bufferResImpl = static_cast<BufferResourceImpl*>(view->m_resource.get());
auto desc = view->m_desc;
- uint64_t bufferSize = 0;
- if (desc.bufferElementSize == 0)
- {
- // If buffer element size is 0, we assume the buffer range from original desc is in bytes.
- bufferSize = desc.bufferRange.elementCount;
- if (bufferSize == 0)
- {
- bufferSize = bufferResImpl->getDesc()->sizeInBytes - desc.bufferRange.firstElement;
- }
- desc.bufferElementSize = bufferStride;
- desc.bufferRange.firstElement /= bufferStride;
- desc.bufferRange.elementCount = bufferSize / bufferStride;
- }
- else
- {
- // If buffer element size is not 0, we assume the buffer range from original desc is in elements
- // of original stride.
- if (desc.bufferRange.elementCount == 0)
- {
- bufferSize = bufferResImpl->getDesc()->sizeInBytes - desc.bufferRange.firstElement * desc.bufferElementSize;
- }
- else
- {
- bufferSize = desc.bufferRange.elementCount * desc.bufferElementSize;
- }
- desc.bufferElementSize = bufferStride;
- desc.bufferRange.firstElement = desc.bufferRange.firstElement * desc.bufferElementSize / bufferStride;
- desc.bufferRange.elementCount = bufferSize / bufferStride;
- }
SLANG_RETURN_ON_FAIL(createD3D12BufferDescriptor(
bufferResImpl,
static_cast<BufferResourceImpl*>(view->m_counterResource.get()),
desc,
+ bufferStride,
device,
m_allocator,
&outDescriptor));
diff --git a/tools/gfx/d3d12/d3d12-resource-views.h b/tools/gfx/d3d12/d3d12-resource-views.h
index f8c6654f2..ac80a9368 100644
--- a/tools/gfx/d3d12/d3d12-resource-views.h
+++ b/tools/gfx/d3d12/d3d12-resource-views.h
@@ -39,6 +39,7 @@ SlangResult createD3D12BufferDescriptor(
BufferResourceImpl* buffer,
BufferResourceImpl* counterBuffer,
IResourceView::Desc const& desc,
+ uint32_t bufferStride,
DeviceImpl* device,
D3D12GeneralExpandingDescriptorHeap* descriptorHeap,
D3D12Descriptor* outDescriptor);
diff --git a/tools/gfx/d3d12/d3d12-shader-object.cpp b/tools/gfx/d3d12/d3d12-shader-object.cpp
index 3d38df5ab..beb88b636 100644
--- a/tools/gfx/d3d12/d3d12-shader-object.cpp
+++ b/tools/gfx/d3d12/d3d12-shader-object.cpp
@@ -965,13 +965,17 @@ Result ShaderObjectImpl::setResource(ShaderOffset const& offset, IResourceView*
}
auto descriptorSlotIndex = bindingRange.baseIndex + (int32_t)offset.bindingArrayIndex;
- D3D12Descriptor srcDescriptor = {};
+ D3D12Descriptor srcDescriptor = internalResourceView->m_descriptor;
- SLANG_RETURN_ON_FAIL(internalResourceView->getBufferDescriptorForBinding(
- static_cast<DeviceImpl*>(m_device.get()),
- resourceViewImpl,
- bindingRange.bufferElementStride,
- srcDescriptor));
+ // Buffer descriptors are created on demand.
+ if (!srcDescriptor.cpuHandle.ptr)
+ {
+ SLANG_RETURN_ON_FAIL(internalResourceView->getBufferDescriptorForBinding(
+ static_cast<DeviceImpl*>(m_device.get()),
+ resourceViewImpl,
+ bindingRange.bufferElementStride,
+ srcDescriptor));
+ }
if (srcDescriptor.cpuHandle.ptr)
{