So, what I actually want is rather simple in theory, but I can't get it to work in practice.
I simply want read and write access to a dynamically-sized array of floats from (raytracing) shaders. I think the right thing is to declare this array as an UAV.
However, I've tried to declare it as a RWTexture1D<float> as well as a RWBuffer<float>. But for both I'm receiving the error that the dimension is too large. The dimension I specified was around 100k, but it seems like RWBuffer<float> is limited to 25k and RWTexture1D<float> is limited to 16384. What can I do?
EDIT: This is the code:
D3D12_UNORDERED_ACCESS_VIEW_DESC unordered_access_view_desc{};
unordered_access_view_desc.Buffer.NumElements = 100000;
unordered_access_view_desc.Format = DXGI_FORMAT_R32_FLOAT;
unordered_access_view_desc.ViewDimension = D3D12_UAV_DIMENSION_BUFFER;
d3d.device->CreateUnorderedAccessView(resource, nullptr, &unordered_access_view_desc, handle);
and the error:
The Dimensions of the View are invalid due to at least one of the following conditions. Assuming this Format (0x29, R32_FLOAT), FirstElement (value = 0) must be between 0 and the maximum offset of the Buffer, 24999, inclusively.
I don't get this. If the format would be DXGI_FORMAT_R32G32B32A32_FLOAT instead and I would choose Buffer.NumElements = 25000 I would end up with allocating the same amount of memory.
But even when I use this hack, is it really not possible to create a 1-dimensional array of size > 25000? Even a simple 2-dimensional texture of size 512x512 has more values (262144). Do I really need to create such a 2-dimensional texture and reindex appropriately?
EDIT: This is the code with CreateBuffer I'm using:
D3D12_HEAP_PROPERTIES heapDesc = {};
heapDesc.Type = D3D12_HEAP_TYPE_DEFAULT;
heapDesc.CreationNodeMask = 1;
heapDesc.VisibleNodeMask = 1;
D3D12_RESOURCE_DESC resourceDesc = {};
resourceDesc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
resourceDesc.Height = 1;
resourceDesc.DepthOrArraySize = 1;
resourceDesc.MipLevels = 1;
resourceDesc.Format = DXGI_FORMAT_UNKNOWN;
resourceDesc.SampleDesc.Count = 1;
resourceDesc.SampleDesc.Quality = 0;
resourceDesc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
resourceDesc.Width = /* ... */;
resourceDesc.Flags = D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS;
device->CreateCommittedResource(&heapDesc, D3D12_HEAP_FLAG_NONE, &resourceDesc, D3D12_RESOURCE_STATE_UNORDERED_ACCESS, nullptr, IID_PPV_ARGS(&myresource));
and this is the one for CreateCommitedResource:
D3D12_HEAP_PROPERTIES const DefaultHeapProperties =
{
D3D12_HEAP_TYPE_DEFAULT,
D3D12_CPU_PAGE_PROPERTY_UNKNOWN,
D3D12_MEMORY_POOL_UNKNOWN,
0, 0
};
D3D12_RESOURCE_DESC resource_desc{};
resource_desc.DepthOrArraySize = 1;
resource_desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
//resource_desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
resource_desc.Format = DXGI_FORMAT_UNKNOWN;
//resource_desc.Format = DXGI_FORMAT_R32_FLOAT;
resource_desc.Flags = D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS;
resource_desc.Width = static_cast<UINT64>(resources.raytracingData.bootstrap_sample_count);
resource_desc.Height = 1;
//resource_desc.Width = /* ... */;
resource_desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
resource_desc.MipLevels = 1;
resource_desc.SampleDesc.Count = 1;
device->CreateCommittedResource(&DefaultHeapProperties, D3D12_HEAP_FLAG_NONE, &resource_desc, D3D12_RESOURCE_STATE_UNORDERED_ACCESS, nullptr, IID_PPV_ARGS(&myresource));
In order to use more elements, you need to use structuredBuffers, so in your hlsl code you need to use
Also the code to setup the view is different, this needs to be set as :
To create the resource you can continue using CreateCommittedResource: