I have a 1-dimensional texture declared as RWTexture1D<float> : register(u1);
. I'm writing to this texture in one ray generation shader and read from it from another. I don't need to read the from the texture on the CPU side.
Before the ray generation shader which writes to it is executed, I need to set all values contained in it to zero. I thought ClearUnorderedAccessViewFloat
would be the function which does that.
Now, the heap descriptor is created is creates by the following code:
D3D12_DESCRIPTOR_HEAP_DESC desc{};
desc.NumDescriptors = /* ... */;
desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV;
desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE;
d3d.device->CreateDescriptorHeap(&desc, IID_PPV_ARGS(&m_descriptor_heap));
D3D12_CPU_DESCRIPTOR_HANDLE handle = m_descriptor_heap->GetCPUDescriptorHandleForHeapStart();
m_uav_desc_size = d3d.device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
And the code for clearing is:
CD3DX12_GPU_DESCRIPTOR_HANDLE const gpu_handle{
m_descriptor_heap->GetGPUDescriptorHandleForHeapStart(),
m_descriptor_heap_size,
m_uav_desc_size
};
CD3DX12_CPU_DESCRIPTOR_HANDLE const cpu_handle{
m_descriptor_heap->GetCPUDescriptorHandleForHeapStart(),
m_descriptor_heap_size,
m_uav_desc_size
};
FLOAT const clear_value = 0;
m_cmd_list->ClearUnorderedAccessViewFloat(gpu_handle, cpu_handle, m_texture1d, &clear_value, 0, nullptr);
Unfortunately, this gives the following error:
D3D12 ERROR: ID3D12CommandList::ClearUnorderedAccessViewFloat: Specified descriptor handle ptr=0x0000000000000043 points to a descriptor heap type that is CPU write only, so reading it is invalid. UnorderedAccessViewCPUHandle is the issue. [ EXECUTION ERROR #646: INVALID_DESCRIPTOR_HANDLE]
In this post the same problem is described: https://stackoverflow.com/a/72889175/547231.
The answer says that I should create two descriptor heaps; one with D3D12_DESCRIPTOR_HEAP_FLAG_NONE
. However, I don't get that. How do I ensure that they point to the same resources? How would I need to modify the code for ClearUnorderedAccessViewFloat
?
You need to have both shader visible and not visible heap. You create your gpu UAV from shader visible heap, and cpu UAV from not visible heap.
So you will have 2 heaps,
gpu_descriptor_heap
andcpu_descriptor_heap
.gpu_descriptor_heap
will be created withD3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE
, thecpu_descriptor_heap
withD3D12_DESCRIPTOR_HEAP_FLAG_NONE
.To ensure they are pointing to the same resource, you can call
CreateUnorderedAccessView
twice, passing in both cases handles from those heaps withGetCPUDescriptorHandleForHeapStart
, or you can call it once for your cpu heap and then callCopyDescriptors
to copy it to your shader visible heap.