Hello all,
I'm attempting to get a simple implementation of tiled resources working in Direct3D12. I implemented much of this in a standalone project but for discussion purposes I chose the D3D12HelloTexture project as a starting point, you can find it here: https://github.com/Microsoft/DirectX-Graphics-Samples/tree/master/Samples/D3D12HelloWorld. I'm stuck trying to figure out what specifically I've done to cause the following error:
My modifications to D3D12HelloTexture.cpp are as follows:
1.) Use feature level 12_1 instead of 11_1
2.) To allow creation of reserved resource, change the texture layout to D3D12_TEXTURE_LAYOUT_64KB_UNDEFINED_SWIZZLE.
3.) To allow clearing of the reserved resource after a call to UpdateTileMappings, use texture flag D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET and add a render target view to the RTV descriptor heap.
4.) To create the tile pool for the reserved resource, create a heap with type default and flags D3D12_HEAP_FLAG_ALLOW_ONLY_RT_DS_TEXTURES. The size of this tile pool is calculated using GetRequiredIntermediateSize on the reserved resource.
5.) After creating reserved texture, upload heap, and tile pool, synchronize using WaitForPreviousFrame. Then this code:
// update the tile mapping
m_commandQueue->UpdateTileMappings(m_texture.Get(),
1, NULL, NULL,
tilePool.Get(),
1, NULL, NULL, NULL,
D3D12_TILE_MAPPING_FLAG_NONE);
D3D12_RENDER_TARGET_VIEW_DESC rtvDesc = {};
rtvDesc.Format = texFormat;
rtvDesc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D;
CD3DX12_CPU_DESCRIPTOR_HANDLE rtvHandle(m_rtvHeap->GetCPUDescriptorHandleForHeapStart());
rtvHandle.Offset(FrameCount, m_rtvDescriptorSize);
m_device->CreateRenderTargetView(m_texture.Get(), &rtvDesc, rtvHandle);
ThrowIfFailed(m_commandAllocator->Reset());
ThrowIfFailed(m_commandList->Reset(m_commandAllocator.Get(), m_pipelineState.Get()));
float clearColor[4] = { 0.0f, 1.0f, 0.0f, 1.0f };
m_commandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_texture.Get(), D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET));
m_commandList->ClearRenderTargetView(rtvHandle, clearColor, 0, NULL);
m_commandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_texture.Get(), D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE));
ThrowIfFailed(m_commandList->Close());
// Execute the command list.
m_commandQueue->ExecuteCommandLists(_countof(ppCommandLists), ppCommandLists);
WaitForPreviousFrame();
Full source of the modified D3D12HelloTexture.cpp can be found here: http://codeshare.io/2j1Lg
I can run all of this code, and if I avoid actually drawing anything, the device is happy. As soon as I try to draw a triangle with this tiled texture, I get the aforementioned error, found through an exception on the call m_swapChain->Present(1, 0).
If anyone has their own example of D3D12 tiled resources I'd love to see it. In searching for examples, I can only find DX11 implementations that vary enough from DX12 that I can't figure out how to apply that information successfully.