[D3D12] Texture Upload Heap

Started by
1 comment, last by Funkymunky 8 years, 8 months ago

I am trying to render a textured quad. If I just use a heap of type D3D12_HEAP_TYPE_UPLOAD then I can see the texture perfectly. But I want to use a heap of type D3D12_HEAP_TYPE_DEFAULT and use a D3D12_HEAP_TYPE_UPLOAD to copy the data to it.

So everything works when I call:

  • CreateCommittedResource(&CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD)... IID_PPV_ARGS(&textureUpload));
  • textureUpload->WriteToSubresource(...
  • device->CreateDescriptorHeap(...
  • device->CreateShaderResourceView(textureUpload.Get()...

With this I see my texture just fine. But when I try to do it like so, I just get a black quad:

  • CreateCommittedResource(&CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT)... IID_PPV_ARGS(&texture));
  • CreateCommittedResource(&CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD)... IID_PPV_ARGS(&textureUpload));
  • UpdateSubresources(commandList, texture.Get(), textureUpload.Get()...
  • commandList->ResourceBarrier(...
  • device->CreateDescriptorHeap(...
  • device->CreateShaderResourceView(texture.Get()...

Is there something blatantly wrong that I'm doing??

Advertisement
I think I came across a similar issue when trying to use textures in a pre-release version of D3D12 a few months back. You can read the details on page 4 of the D3D12 documentation thread, although it might not be relevant.

Assuming you're using VS2015, you can use the graphics debugger to capture a frame and inspect your "texture" default heap committed resource. If it's the same problem then the texture mip levels will be garbled and/or black.

The problem was that directly copying subresources from an upload heap buffer to a default heap buffer leaves texture subresources unable to be correctly accessed by the GPU from a default heap, and I believe (though I may be wrong) this is because the GPU expects default heap texture data to be laid out in a hardware specific way.

The solution was rather than using generic update/copy/writesubresource methods when copying textures to a default heap (as you would for non-texture buffers), you have to copy texture subresource data using CommandList::CopyTextureRegion. That way the GPU copies the subresource data to the default heap with the layout the hardware expects for texture accesses from GPU-only memory.

Hope it helps, though if anyone knows it's changed since, I'd be glad of the updated info also. smile.png

The graphics debugger is awesome. Absolutely awesome. Unfortunately for me it just confirms what I'm seeing; the CBV_SRV_UAV Resource is all black. Proper size and format, but every pixel is (0, 0, 0, 0).

Further, I'm using UpdateSubresources, a function out of the d3dx12.h header that they included with the samples. It calls CommandList::CopyTextureRegion to perform the upload.

Perhaps it's important that I'm not generating a mipmap chain? I can't see why it would work with D3D12_HEAP_TYPE_UPLOAD and not D3D12_HEAP_TYPE_DEFAULT though...

**EDIT**

Got it. I needed to call ID3D12CommandQueue::ExecuteCommandLists before I went into my rendering loop. In retrospect this seems obvious; without telling the GPU to execute the CopyTextureRegion command, it will get thrown away when I call ID3D12GraphicsCommandList::Reset prior to submitting my rendering calls.

Guess I've gotta keep wrapping my head around the methodology of DX12. Thanks for the help!

This topic is closed to new replies.

Advertisement