FUnorderedAccessViewRHIRef FD3D12DynamicRHI::RHICreateUnorderedAccessView(FStructuredBufferRHIParamRef StructuredBufferRHI, bool bUseUAVCounter, bool bAppendBuffer) { FD3D12StructuredBuffer* StructuredBuffer = FD3D12DynamicRHI::ResourceCast(StructuredBufferRHI); const D3D12_RESOURCE_DESC& BufferDesc = StructuredBuffer->Resource->GetDesc(); const uint32 BufferUsage = StructuredBuffer->GetUsage(); const bool bByteAccessBuffer = (BufferUsage & BUF_ByteAddressBuffer) != 0; const bool bStructuredBuffer = !bByteAccessBuffer; check(bByteAccessBuffer != bStructuredBuffer); // You can't have a structured buffer that allows raw views D3D12_UNORDERED_ACCESS_VIEW_DESC UAVDesc ={}; UAVDesc.ViewDimension = D3D12_UAV_DIMENSION_BUFFER; UAVDesc.Format = DXGI_FORMAT_UNKNOWN; uint32 EffectiveStride = StructuredBuffer->GetStride(); if (bByteAccessBuffer) { UAVDesc.Format = DXGI_FORMAT_R32_TYPELESS; EffectiveStride = 4; } else if (BufferUsage & BUF_DrawIndirect) { UAVDesc.Format = DXGI_FORMAT_R32_UINT; EffectiveStride = 4; } UAVDesc.Buffer.FirstElement = StructuredBuffer->ResourceLocation->GetOffset() / EffectiveStride; UAVDesc.Buffer.NumElements = StructuredBuffer->ResourceLocation->GetEffectiveBufferSize() / EffectiveStride; UAVDesc.Buffer.StructureByteStride = bStructuredBuffer ? EffectiveStride : 0; UAVDesc.Buffer.Flags = D3D12_BUFFER_UAV_FLAG_NONE; UAVDesc.Buffer.CounterOffsetInBytes = 0; const bool bNeedsCounterResource = bAppendBuffer | bUseUAVCounter; TRefCountPtr<FD3D12Resource> CounterResource; if (bNeedsCounterResource) { GetRHIDevice()->GetResourceHelper().CreateBuffer(D3D12_HEAP_TYPE_DEFAULT, 4, CounterResource.GetInitReference(), D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS); } if (bByteAccessBuffer) { UAVDesc.Buffer.Flags |= D3D12_BUFFER_UAV_FLAG_RAW; } return new FD3D12UnorderedAccessView(GetRHIDevice(), &UAVDesc, StructuredBuffer->ResourceLocation, CounterResource); }
FUnorderedAccessViewRHIRef FD3D12DynamicRHI::RHICreateUnorderedAccessView(FStructuredBufferRHIParamRef StructuredBufferRHI, bool bUseUAVCounter, bool bAppendBuffer) { FD3D12StructuredBuffer* StructuredBuffer = FD3D12DynamicRHI::ResourceCast(StructuredBufferRHI); FD3D12ResourceLocation& Location = StructuredBuffer->ResourceLocation; const D3D12_RESOURCE_DESC& BufferDesc = Location.GetResource()->GetDesc(); const uint32 BufferUsage = StructuredBuffer->GetUsage(); const bool bByteAccessBuffer = (BufferUsage & BUF_ByteAddressBuffer) != 0; const bool bStructuredBuffer = !bByteAccessBuffer; check(bByteAccessBuffer != bStructuredBuffer); // You can't have a structured buffer that allows raw views D3D12_UNORDERED_ACCESS_VIEW_DESC UAVDesc = {}; UAVDesc.ViewDimension = D3D12_UAV_DIMENSION_BUFFER; UAVDesc.Format = DXGI_FORMAT_UNKNOWN; uint32 EffectiveStride = StructuredBuffer->GetStride(); if (bByteAccessBuffer) { UAVDesc.Format = DXGI_FORMAT_R32_TYPELESS; EffectiveStride = 4; } else if (BufferUsage & BUF_DrawIndirect) { UAVDesc.Format = DXGI_FORMAT_R32_UINT; EffectiveStride = 4; } UAVDesc.Buffer.FirstElement = Location.GetOffsetFromBaseOfResource() / EffectiveStride; UAVDesc.Buffer.NumElements = Location.GetSize() / EffectiveStride; UAVDesc.Buffer.StructureByteStride = bStructuredBuffer ? EffectiveStride : 0; UAVDesc.Buffer.Flags = D3D12_BUFFER_UAV_FLAG_NONE; UAVDesc.Buffer.CounterOffsetInBytes = 0; const bool bNeedsCounterResource = bAppendBuffer | bUseUAVCounter; if (bByteAccessBuffer) { UAVDesc.Buffer.Flags |= D3D12_BUFFER_UAV_FLAG_RAW; } return CreateUAV(UAVDesc, StructuredBuffer, bNeedsCounterResource); }