0
ID3D12GraphicsCommandList& commandList = *com_ptr;
FLOAT values[4] = { 1,1,1,1 };
commandList.ClearUnorderedAccessViewFloat(m_gpuUavHandle, m_cpuUavHandle, m_resource.get(), values, 0, nullptr);

I'm getting the following runtime error:

Access violation reading location 0x0000000000000140

However, m_cpuUavHandle.ptr has value 326 which is only 6 bytes after the location of the access violation 320 (=140 in hexidecimal).

Since in Direct3d12 you manually calculate the handle address, it seems that there is room for something to go wrong

m_cpuUavHandle = CD3DX12_CPU_DESCRIPTOR_HANDLE(m_descriptorHeap.get()->GetCPUDescriptorHandleForHeapStart(), offset, m_cbvSrvUavDescriptorSize);

Edit:

I succeeded reproducing this in the DirectX 12 samples (and uploaded it to github) and this time got a debug message

D3D12 ERROR: ID3D12CommandList::ClearUnorderedAccessViewFloat: Specified descriptor handle ptr=0x0000000000000021 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]

Now m_cpuUavHandle.ptr=33 and the location of the access violation is at 32 (0x0000000000000020 in hexidecimal).

In my main project I think the exception is hit before the debug message is printed due to threading issues.

Now in my main project I'm getting

Access violation reading location 0x0000000000000000.

which is still six bytes before m_cpuUavHandle.ptr = 6, so I'm not sure if this is right

Tom Huntington
  • 2,260
  • 10
  • 20
  • First enable the Debug Device and look for output. Your 'commandList' is also some kind of specific type because you are not using the ``->`` operator, so what's it's type? If it's a wrapper, make sure the method matches the actual COM type parameter orders. – Chuck Walbourn Feb 09 '22 at 05:05
  • @ChuckWalbourn It's just a reference `ID3D12GraphicsCommandList& commandList = *com_ptr` I have have at the start of my render loop, make's it easy to pass around to methods of child objects – Tom Huntington Jul 05 '22 at 20:38
  • 1
    Well your cpu handle cannot come from a shader visible heap as the message says, and in your sample on github it is from shader visible heap... – mateeeeeee Jul 05 '22 at 21:45
  • See here: https://learn.microsoft.com/en-us/windows/win32/api/d3d12/nf-d3d12-id3d12graphicscommandlist-clearunorderedaccessviewfloat the Important section – mateeeeeee Jul 05 '22 at 21:53
  • Yeh I know there's two issues, but fixing that one will not solve the other: `Specified descriptor handle ptr=0x0000000000000021 points to a descriptor heap type that is CPU write only, so reading it is invalid. UnorderedAccessViewCPUHandle is the issue.` – Tom Huntington Jul 05 '22 at 21:54
  • 1
    Maybe I misunderstood you but the message you quoted is the one I am talking about. CPU write only heap IS shader visible heap. – mateeeeeee Jul 05 '22 at 21:56
  • @mateeeeeee yes sorry I was also getting `D3D12 ERROR: ID3D12CommandList::ClearUnorderedAccessViewFloat: ClearUnorderedAccessView* methodsare not compatible with Structured Buffers. StructuredByteStride is set to 32 for resource 0x000002DB11511A00:'m_particleBuffer1[0]'. [ RESOURCE_MANIPULATION ERROR #1156: CLEARUNORDEREDACCESSVIEW_INCOMPATIBLE_WITH_STRUCTURED_BUFFERS]` – Tom Huntington Jul 05 '22 at 22:03
  • 1
    Have you tried creating other UAV (not the one you are using for RWStructuredBuffer) for that resource, for example with format R32_UINT and clearing with ClearUnorderedAccessViewUint? I guess you could also try R32_FLOAT and ClearUnorderedAccessViewFloat. So you would have two uavs for that structured buffer, one for clearing, and another one for writing. You can always also run a compute shader to do clearing. – mateeeeeee Jul 05 '22 at 22:07
  • @mateeeeeee thanks, I could have never though shader visible heap from the message but I believe you are correct after looking at the docs! I'm now going to understand shader visible heaps https://learn.microsoft.com/en-us/windows/win32/direct3d12/shader-visible-descriptor-heaps – Tom Huntington Jul 05 '22 at 22:10
  • 1
    You can also see the table here https://learn.microsoft.com/en-us/windows/win32/direct3d12/non-shader-visible-descriptor-heaps – mateeeeeee Jul 05 '22 at 22:12
  • Yes I should have just created another UAV to get rid of the other error. Running a compute shader to clear UAVs is what I'm doing now, but it's not that scalable – Tom Huntington Jul 05 '22 at 22:13

1 Answers1

0

mateeeeee solved this in the comments. The docs specify that the cpu descriptor must refer to a non-shader visible heap (one created with D3D12_DESCRIPTOR_HEAP_FLAG_NONE).

For me the solution is to just have two identical CBV_SRV_UAV heaps one created with D3D12_DESCRIPTOR_HEAP_DESC::Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE for calling ClearUnorderedAccessViewFloat and the other created with D3D12_DESCRIPTOR_HEAP_DESC::Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE for everything else.

It is important to note that the cpu descriptor and gpu descriptor arguments for ClearUnorderedAccessViewFloat must come from different heaps.

Tom Huntington
  • 2,260
  • 10
  • 20