diff options
| author | skallweitNV <64953474+skallweitNV@users.noreply.github.com> | 2024-05-14 00:39:49 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-05-13 15:39:49 -0700 |
| commit | 9f23046138629f78995d54a7722ad6749bd84db9 (patch) | |
| tree | 25ac343566f896cae547046ac7e960441874ec00 /tools/gfx/d3d12 | |
| parent | 04d3dd51125182767d90c318895a6232ec4ee750 (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.cpp | 9 | ||||
| -rw-r--r-- | tools/gfx/d3d12/d3d12-device.cpp | 12 | ||||
| -rw-r--r-- | tools/gfx/d3d12/d3d12-resource-views.cpp | 101 | ||||
| -rw-r--r-- | tools/gfx/d3d12/d3d12-resource-views.h | 1 | ||||
| -rw-r--r-- | tools/gfx/d3d12/d3d12-shader-object.cpp | 16 |
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) { |
