Unbind UAV, then write to it - DX 11 vs 12

Started by
5 comments, last by pcmaster 6 years, 4 months ago

Hello!

I can see that when there's a write to UAVs in CS or PS, and I bind a null ID3D11UnorderedAccessView into a used UAV slot, the GPU won't hang and the writes are silently dropped. I hope I amn't dreaming.

With DX12, I can't seem to emulate this. I reckon it's impossible. The shader just reads the descriptor of the UAV (from a register/offset based on the root signature layout) and does an "image_store" at some offset from the base address. If it's unmapped, bang, we're dead. I tried zeroing out that GPU visible UAV's range in the table, same result. Such an all-zero UAV descriptor doesn't seem very legit. That's expected.

Am I right? How does DX11 do it that it survives this? Does it silently patch the shader or what? Thanks, .P

Advertisement

How did you zero it out? Did you call ZeroMemory (or similar) on the CPU descriptor handle? That's... not the right way to do it. What you're looking for is a null view. You can call CreateUnorderedAccessView with a null resource, but you must pass a valid view desc. That'll set up the descriptor such that reads return 0 (or last-written data, depending on architecture) and writes are dropped.

Hi, SoL! I was looking exactly for this, is it actually documented anywhere? :) I'm on an unnamed architecture where I could do a memset... as I say it didn't seem very legit. I'm just trying what you propose.

It does work!


D3D12_UNORDERED_ACCESS_VIEW_DESC dummyUavDesc = {};
dummyUavDesc.ViewDimension = D3D12_UAV_DIMENSION_TEXTURE3D;
dummyUavDesc.Texture3D.FirstWSlice = 0;
dummyUavDesc.Texture3D.MipSlice = 0;
dummyUavDesc.Texture3D.WSize = 2048;
dummyUavDesc.Format = DXGI_FORMAT_R8G8B8A8_SNORM;
pD3D12Device->CreateUnorderedAccessView(nullptr, nullptr, &dummyUavDesc, cpuHandle);

CreateUnorderedAccessView writes all zeroes to the cpuHandle designated memory. CopyDescriptors() copies the zeroes correctly to the contiguous GPU visible descriptor table and the GPU recognises this. All cool. Thank you SoL!

 

On 11/28/2017 at 8:02 AM, pcmaster said:

Hi, SoL! I was looking exactly for this, is it actually documented anywhere? I'm on an unnamed architecture where I could do a memset... as I say it didn't seem very legit. I'm just trying what you propose.

It's mentioned in the docs for CreateUnorderedAccessView:

At least one of pResource or pDesc must be provided. A null pResource is used to initialize a null descriptor, which guarantees D3D11-like null binding behavior (reading 0s, writes are discarded), but must have a valid pDesc in order to determine the descriptor type.

It's also mentioned here in the programming guide.

One thing to watch out for is there's no way to have a NULL descriptor for a UAV or SRV  that's bound as a root SRV/UAV parameter. In this case there's really no descriptor (you're just passing a GPU pointer to the buffer data), so you forego any bounds checking on reads or writes. Just like raw pointer access on the CPU, reading or writing out-of-bounds will result in undefined behavior.

Thank you MJP for pointing that out. Our UAVs are in a table, fortunately.

This topic is closed to new replies.

Advertisement