mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-12-16 00:17:03 +00:00
D3D12 Render Targets (#72)
Implements BeginRenderSubpass on the D3D12 backend. Descriptors for render target and depth stencil views are recorded in a descriptor heap for each framebuffer. For now, we still have the hack where no attachment renders to the backbuffer, so the CommandBuffer records those when necessary when it is submitted. This PR also enables input states for D3D12 which are mostly working. One failure seems to be happening because our texture copies are not yet correct.
This commit is contained in:
@@ -31,7 +31,7 @@ namespace backend {
|
||||
namespace d3d12 {
|
||||
void Init(ComPtr<ID3D12Device> d3d12Device, nxtProcTable* procs, nxtDevice* device);
|
||||
ComPtr<ID3D12CommandQueue> GetCommandQueue(nxtDevice device);
|
||||
void SetNextRenderTargetDescriptor(nxtDevice device, D3D12_CPU_DESCRIPTOR_HANDLE renderTargetDescriptor);
|
||||
void SetNextTexture(nxtDevice device, ComPtr<ID3D12Resource> resource, ComPtr<ID3D12Resource> depthResource);
|
||||
uint64_t GetSerial(const nxtDevice device);
|
||||
void NextSerial(nxtDevice device);
|
||||
void ExecuteCommandLists(nxtDevice device, std::initializer_list<ID3D12CommandList*> commandLists);
|
||||
@@ -87,6 +87,7 @@ namespace utils {
|
||||
swapChainDesc.BufferCount = kFrameCount;
|
||||
swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
|
||||
swapChainDesc.SampleDesc.Count = 1;
|
||||
swapChainDesc.SampleDesc.Quality = 0;
|
||||
|
||||
HWND win32Window = glfwGetWin32Window(window);
|
||||
ComPtr<IDXGISwapChain1> swapChain1;
|
||||
@@ -99,23 +100,43 @@ namespace utils {
|
||||
&swapChain1
|
||||
));
|
||||
ASSERT_SUCCESS(swapChain1.As(&swapChain));
|
||||
|
||||
// Describe and create a render target view (RTV) descriptor heap.
|
||||
D3D12_DESCRIPTOR_HEAP_DESC rtvHeapDesc = {};
|
||||
rtvHeapDesc.NumDescriptors = kFrameCount;
|
||||
rtvHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV;
|
||||
rtvHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
|
||||
ASSERT_SUCCESS(d3d12Device->CreateDescriptorHeap(&rtvHeapDesc, IID_PPV_ARGS(&renderTargetViewHeap)));
|
||||
|
||||
rtvDescriptorSize = d3d12Device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV);
|
||||
|
||||
// Create a RTV for each frame.
|
||||
|
||||
// Create a render target and depth stencil resource for each frame.
|
||||
{
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE renderTargetViewHandle = renderTargetViewHeap->GetCPUDescriptorHandleForHeapStart();
|
||||
D3D12_HEAP_PROPERTIES dsvHeapProperties;
|
||||
dsvHeapProperties.Type = D3D12_HEAP_TYPE_DEFAULT;
|
||||
dsvHeapProperties.CreationNodeMask = 0;
|
||||
dsvHeapProperties.VisibleNodeMask = 0;
|
||||
dsvHeapProperties.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
|
||||
dsvHeapProperties.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;
|
||||
|
||||
D3D12_RESOURCE_DESC dsvDesc;
|
||||
dsvDesc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
|
||||
dsvDesc.Alignment = 0;
|
||||
dsvDesc.Width = width;
|
||||
dsvDesc.Height = height;
|
||||
dsvDesc.DepthOrArraySize = 1;
|
||||
dsvDesc.MipLevels = 0;
|
||||
dsvDesc.Format = DXGI_FORMAT_D32_FLOAT_S8X24_UINT;
|
||||
dsvDesc.SampleDesc.Count = 1;
|
||||
dsvDesc.SampleDesc.Quality = 0;
|
||||
dsvDesc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;
|
||||
dsvDesc.Flags = D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL;
|
||||
|
||||
D3D12_CLEAR_VALUE dsvClear;
|
||||
dsvClear.Format = DXGI_FORMAT_D32_FLOAT_S8X24_UINT;
|
||||
dsvClear.DepthStencil.Depth = 1.0f;
|
||||
dsvClear.DepthStencil.Stencil = 0;
|
||||
|
||||
for (uint32_t n = 0; n < kFrameCount; ++n) {
|
||||
ASSERT_SUCCESS(swapChain->GetBuffer(n, IID_PPV_ARGS(&renderTargetResources[n])));
|
||||
d3d12Device->CreateRenderTargetView(renderTargetResources[n].Get(), nullptr, renderTargetViewHandle);
|
||||
renderTargetViewHandle.ptr += rtvDescriptorSize;
|
||||
ASSERT_SUCCESS(d3d12Device->CreateCommittedResource(
|
||||
&dsvHeapProperties,
|
||||
D3D12_HEAP_FLAG_NONE,
|
||||
&dsvDesc,
|
||||
D3D12_RESOURCE_STATE_DEPTH_WRITE,
|
||||
&dsvClear,
|
||||
IID_PPV_ARGS(&depthStencilResources[n])));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -147,9 +168,7 @@ namespace utils {
|
||||
backend::d3d12::NextSerial(backendDevice);
|
||||
}
|
||||
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE renderTargetViewHandle = renderTargetViewHeap->GetCPUDescriptorHandleForHeapStart();
|
||||
renderTargetViewHandle.ptr += rtvDescriptorSize * renderTargetIndex;
|
||||
backend::d3d12::SetNextRenderTargetDescriptor(backendDevice, renderTargetViewHandle);
|
||||
backend::d3d12::SetNextTexture(backendDevice, renderTargetResources[renderTargetIndex], depthStencilResources[renderTargetIndex]);
|
||||
}
|
||||
|
||||
void SwapBuffers() override {
|
||||
@@ -198,9 +217,7 @@ namespace utils {
|
||||
lastSerialRenderTargetWasUsed[renderTargetIndex] = backend::d3d12::GetSerial(backendDevice);
|
||||
|
||||
// Tell the backend to render to the current render target
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE renderTargetViewHandle = renderTargetViewHeap->GetCPUDescriptorHandleForHeapStart();
|
||||
renderTargetViewHandle.ptr += rtvDescriptorSize * renderTargetIndex;
|
||||
backend::d3d12::SetNextRenderTargetDescriptor(backendDevice, renderTargetViewHandle);
|
||||
backend::d3d12::SetNextTexture(backendDevice, renderTargetResources[renderTargetIndex], depthStencilResources[renderTargetIndex]);
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -214,9 +231,8 @@ namespace utils {
|
||||
ComPtr<ID3D12Device> d3d12Device;
|
||||
ComPtr<ID3D12CommandQueue> commandQueue;
|
||||
ComPtr<IDXGISwapChain3> swapChain;
|
||||
ComPtr<ID3D12DescriptorHeap> renderTargetViewHeap;
|
||||
ComPtr<ID3D12Resource> renderTargetResources[kFrameCount];
|
||||
uint32_t rtvDescriptorSize;
|
||||
ComPtr<ID3D12Resource> depthStencilResources[kFrameCount];
|
||||
|
||||
// Frame synchronization. Updated every frame
|
||||
uint32_t renderTargetIndex;
|
||||
|
||||
Reference in New Issue
Block a user