Jump to content
  • Advertisement
pcmaster

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

This topic is 378 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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

Edited by pcmaster

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
Share on other sites

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!

 

Edited by pcmaster

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!