From 163779da5108ad8d54c1d3fdaef6fa276b8bd36b Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 29 Mar 2019 16:18:26 +0100 Subject: [PATCH] Examples: DirectX12: Various tidying up. --- examples/imgui_impl_dx11.cpp | 2 +- examples/imgui_impl_dx12.cpp | 95 +++++++++++++++++------------------- 2 files changed, 47 insertions(+), 50 deletions(-) diff --git a/examples/imgui_impl_dx11.cpp b/examples/imgui_impl_dx11.cpp index a686d6bb2..060d86cd7 100644 --- a/examples/imgui_impl_dx11.cpp +++ b/examples/imgui_impl_dx11.cpp @@ -90,7 +90,7 @@ void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data) return; } - // Copy and convert all vertices into a single contiguous buffer + // Upload vertex/index data into a single contiguous GPU buffer D3D11_MAPPED_SUBRESOURCE vtx_resource, idx_resource; if (ctx->Map(g_pVB, 0, D3D11_MAP_WRITE_DISCARD, 0, &vtx_resource) != S_OK) return; diff --git a/examples/imgui_impl_dx12.cpp b/examples/imgui_impl_dx12.cpp index f9e1884f8..04fe7fd0b 100644 --- a/examples/imgui_impl_dx12.cpp +++ b/examples/imgui_impl_dx12.cpp @@ -12,6 +12,7 @@ // CHANGELOG // (minor and older changes stripped away, please see git history for details) +// 2019-03-29: Misc: Various minor tidying up. // 2018-12-03: Misc: Added #pragma comment statement to automatically link with d3dcompiler.lib when using D3DCompile(). // 2018-11-30: Misc: Setting up io.BackendRendererName so it can be displayed in the About Window. // 2018-06-12: DirectX12: Moved the ID3D12GraphicsCommandList* parameter from NewFrame() to RenderDrawData(). @@ -43,14 +44,14 @@ static D3D12_GPU_DESCRIPTOR_HANDLE g_hFontSrvGpuDescHandle = {}; struct FrameResources { - ID3D12Resource* IB; - ID3D12Resource* VB; - int VertexBufferSize; - int IndexBufferSize; + ID3D12Resource* IndexBuffer; + ID3D12Resource* VertexBuffer; + int IndexBufferSize; + int VertexBufferSize; }; -static FrameResources* g_pFrameResources = NULL; -static UINT g_numFramesInFlight = 0; -static UINT g_frameIndex = UINT_MAX; +static FrameResources* g_pFrameResources = NULL; +static UINT g_numFramesInFlight = 0; +static UINT g_frameIndex = UINT_MAX; struct VERTEX_CONSTANT_BUFFER { @@ -64,17 +65,13 @@ void ImGui_ImplDX12_RenderDrawData(ImDrawData* draw_data, ID3D12GraphicsCommandL // FIXME: I'm assuming that this only gets called once per frame! // If not, we can't just re-allocate the IB or VB, we'll have to do a proper allocator. g_frameIndex = g_frameIndex + 1; - FrameResources* frameResources = &g_pFrameResources[g_frameIndex % g_numFramesInFlight]; - ID3D12Resource* g_pVB = frameResources->VB; - ID3D12Resource* g_pIB = frameResources->IB; - int g_VertexBufferSize = frameResources->VertexBufferSize; - int g_IndexBufferSize = frameResources->IndexBufferSize; + FrameResources* fr = &g_pFrameResources[g_frameIndex % g_numFramesInFlight]; // Create and grow vertex/index buffers if needed - if (!g_pVB || g_VertexBufferSize < draw_data->TotalVtxCount) + if (fr->VertexBuffer == NULL || fr->VertexBufferSize < draw_data->TotalVtxCount) { - if (g_pVB) { g_pVB->Release(); g_pVB = NULL; } - g_VertexBufferSize = draw_data->TotalVtxCount + 5000; + if (fr->VertexBuffer != NULL) { fr->VertexBuffer->Release(); fr->VertexBuffer = NULL; } + fr->VertexBufferSize = draw_data->TotalVtxCount + 5000; D3D12_HEAP_PROPERTIES props; memset(&props, 0, sizeof(D3D12_HEAP_PROPERTIES)); props.Type = D3D12_HEAP_TYPE_UPLOAD; @@ -83,7 +80,7 @@ void ImGui_ImplDX12_RenderDrawData(ImDrawData* draw_data, ID3D12GraphicsCommandL D3D12_RESOURCE_DESC desc; memset(&desc, 0, sizeof(D3D12_RESOURCE_DESC)); desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER; - desc.Width = g_VertexBufferSize * sizeof(ImDrawVert); + desc.Width = fr->VertexBufferSize * sizeof(ImDrawVert); desc.Height = 1; desc.DepthOrArraySize = 1; desc.MipLevels = 1; @@ -91,15 +88,13 @@ void ImGui_ImplDX12_RenderDrawData(ImDrawData* draw_data, ID3D12GraphicsCommandL desc.SampleDesc.Count = 1; desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR; desc.Flags = D3D12_RESOURCE_FLAG_NONE; - if (g_pd3dDevice->CreateCommittedResource(&props, D3D12_HEAP_FLAG_NONE, &desc, D3D12_RESOURCE_STATE_GENERIC_READ, NULL, IID_PPV_ARGS(&g_pVB)) < 0) + if (g_pd3dDevice->CreateCommittedResource(&props, D3D12_HEAP_FLAG_NONE, &desc, D3D12_RESOURCE_STATE_GENERIC_READ, NULL, IID_PPV_ARGS(&fr->VertexBuffer)) < 0) return; - frameResources->VB = g_pVB; - frameResources->VertexBufferSize = g_VertexBufferSize; } - if (!g_pIB || g_IndexBufferSize < draw_data->TotalIdxCount) + if (fr->IndexBuffer == NULL || fr->IndexBufferSize < draw_data->TotalIdxCount) { - if (g_pIB) { g_pIB->Release(); g_pIB = NULL; } - g_IndexBufferSize = draw_data->TotalIdxCount + 10000; + if (fr->IndexBuffer != NULL) { fr->IndexBuffer->Release(); fr->IndexBuffer = NULL; } + fr->IndexBufferSize = draw_data->TotalIdxCount + 10000; D3D12_HEAP_PROPERTIES props; memset(&props, 0, sizeof(D3D12_HEAP_PROPERTIES)); props.Type = D3D12_HEAP_TYPE_UPLOAD; @@ -108,7 +103,7 @@ void ImGui_ImplDX12_RenderDrawData(ImDrawData* draw_data, ID3D12GraphicsCommandL D3D12_RESOURCE_DESC desc; memset(&desc, 0, sizeof(D3D12_RESOURCE_DESC)); desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER; - desc.Width = g_IndexBufferSize * sizeof(ImDrawIdx); + desc.Width = fr->IndexBufferSize * sizeof(ImDrawIdx); desc.Height = 1; desc.DepthOrArraySize = 1; desc.MipLevels = 1; @@ -116,19 +111,17 @@ void ImGui_ImplDX12_RenderDrawData(ImDrawData* draw_data, ID3D12GraphicsCommandL desc.SampleDesc.Count = 1; desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR; desc.Flags = D3D12_RESOURCE_FLAG_NONE; - if (g_pd3dDevice->CreateCommittedResource(&props, D3D12_HEAP_FLAG_NONE, &desc, D3D12_RESOURCE_STATE_GENERIC_READ, NULL, IID_PPV_ARGS(&g_pIB)) < 0) + if (g_pd3dDevice->CreateCommittedResource(&props, D3D12_HEAP_FLAG_NONE, &desc, D3D12_RESOURCE_STATE_GENERIC_READ, NULL, IID_PPV_ARGS(&fr->IndexBuffer)) < 0) return; - frameResources->IB = g_pIB; - frameResources->IndexBufferSize = g_IndexBufferSize; } - // Copy and convert all vertices into a single contiguous buffer + // Upload vertex/index data into a single contiguous GPU buffer void* vtx_resource, *idx_resource; D3D12_RANGE range; memset(&range, 0, sizeof(D3D12_RANGE)); - if (g_pVB->Map(0, &range, &vtx_resource) != S_OK) + if (fr->VertexBuffer->Map(0, &range, &vtx_resource) != S_OK) return; - if (g_pIB->Map(0, &range, &idx_resource) != S_OK) + if (fr->IndexBuffer->Map(0, &range, &idx_resource) != S_OK) return; ImDrawVert* vtx_dst = (ImDrawVert*)vtx_resource; ImDrawIdx* idx_dst = (ImDrawIdx*)idx_resource; @@ -140,14 +133,13 @@ void ImGui_ImplDX12_RenderDrawData(ImDrawData* draw_data, ID3D12GraphicsCommandL vtx_dst += cmd_list->VtxBuffer.Size; idx_dst += cmd_list->IdxBuffer.Size; } - g_pVB->Unmap(0, &range); - g_pIB->Unmap(0, &range); + fr->VertexBuffer->Unmap(0, &range); + fr->IndexBuffer->Unmap(0, &range); // Setup orthographic projection matrix into our constant buffer // Our visible imgui space lies from draw_data->DisplayPos (top left) to draw_data->DisplayPos+data_data->DisplaySize (bottom right). VERTEX_CONSTANT_BUFFER vertex_constant_buffer; { - VERTEX_CONSTANT_BUFFER* constant_buffer = &vertex_constant_buffer; float L = draw_data->DisplayPos.x; float R = draw_data->DisplayPos.x + draw_data->DisplaySize.x; float T = draw_data->DisplayPos.y; @@ -159,7 +151,7 @@ void ImGui_ImplDX12_RenderDrawData(ImDrawData* draw_data, ID3D12GraphicsCommandL { 0.0f, 0.0f, 0.5f, 0.0f }, { (R+L)/(L-R), (T+B)/(B-T), 0.5f, 1.0f }, }; - memcpy(&constant_buffer->mvp, mvp, sizeof(mvp)); + memcpy(&vertex_constant_buffer.mvp, mvp, sizeof(mvp)); } // Setup viewport @@ -177,14 +169,14 @@ void ImGui_ImplDX12_RenderDrawData(ImDrawData* draw_data, ID3D12GraphicsCommandL unsigned int offset = 0; D3D12_VERTEX_BUFFER_VIEW vbv; memset(&vbv, 0, sizeof(D3D12_VERTEX_BUFFER_VIEW)); - vbv.BufferLocation = g_pVB->GetGPUVirtualAddress() + offset; - vbv.SizeInBytes = g_VertexBufferSize * stride; + vbv.BufferLocation = fr->VertexBuffer->GetGPUVirtualAddress() + offset; + vbv.SizeInBytes = fr->VertexBufferSize * stride; vbv.StrideInBytes = stride; ctx->IASetVertexBuffers(0, 1, &vbv); D3D12_INDEX_BUFFER_VIEW ibv; memset(&ibv, 0, sizeof(D3D12_INDEX_BUFFER_VIEW)); - ibv.BufferLocation = g_pIB->GetGPUVirtualAddress(); - ibv.SizeInBytes = g_IndexBufferSize * sizeof(ImDrawIdx); + ibv.BufferLocation = fr->IndexBuffer->GetGPUVirtualAddress(); + ibv.SizeInBytes = fr->IndexBufferSize * sizeof(ImDrawIdx); ibv.Format = sizeof(ImDrawIdx) == 2 ? DXGI_FORMAT_R16_UINT : DXGI_FORMAT_R32_UINT; ctx->IASetIndexBuffer(&ibv); ctx->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); @@ -192,7 +184,7 @@ void ImGui_ImplDX12_RenderDrawData(ImDrawData* draw_data, ID3D12GraphicsCommandL ctx->SetGraphicsRootSignature(g_pRootSignature); ctx->SetGraphicsRoot32BitConstants(0, 16, &vertex_constant_buffer, 0); - // Setup render state + // Setup blend factor const float blend_factor[4] = { 0.f, 0.f, 0.f, 0.f }; ctx->OMSetBlendFactor(blend_factor); @@ -208,10 +200,12 @@ void ImGui_ImplDX12_RenderDrawData(ImDrawData* draw_data, ID3D12GraphicsCommandL const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; if (pcmd->UserCallback) { + // User callback (registered via ImDrawList::AddCallback) pcmd->UserCallback(cmd_list, pcmd); } else { + // Apply Scissor, Bind texture, Draw const D3D12_RECT r = { (LONG)(pcmd->ClipRect.x - clip_off.x), (LONG)(pcmd->ClipRect.y - clip_off.y), (LONG)(pcmd->ClipRect.z - clip_off.x), (LONG)(pcmd->ClipRect.w - clip_off.y) }; ctx->SetGraphicsRootDescriptorTable(1, *(D3D12_GPU_DESCRIPTOR_HANDLE*)&pcmd->TextureId); ctx->RSSetScissorRects(1, &r); @@ -490,9 +484,9 @@ bool ImGui_ImplDX12_CreateDeviceObjects() // Create the input layout static D3D12_INPUT_ELEMENT_DESC local_layout[] = { - { "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (size_t)(&((ImDrawVert*)0)->pos), D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }, - { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (size_t)(&((ImDrawVert*)0)->uv), D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }, - { "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, (size_t)(&((ImDrawVert*)0)->col), D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }, + { "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, IM_OFFSETOF(ImDrawVert, pos), D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }, + { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, IM_OFFSETOF(ImDrawVert, uv), D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }, + { "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, IM_OFFSETOF(ImDrawVert, col), D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }, }; psoDesc.InputLayout = { local_layout, 3 }; } @@ -576,15 +570,17 @@ void ImGui_ImplDX12_InvalidateDeviceObjects() if (!g_pd3dDevice) return; + ImGuiIO& io = ImGui::GetIO(); if (g_pVertexShaderBlob) { g_pVertexShaderBlob->Release(); g_pVertexShaderBlob = NULL; } if (g_pPixelShaderBlob) { g_pPixelShaderBlob->Release(); g_pPixelShaderBlob = NULL; } if (g_pRootSignature) { g_pRootSignature->Release(); g_pRootSignature = NULL; } if (g_pPipelineState) { g_pPipelineState->Release(); g_pPipelineState = NULL; } - if (g_pFontTextureResource) { g_pFontTextureResource->Release(); g_pFontTextureResource = NULL; ImGui::GetIO().Fonts->TexID = NULL; } // We copied g_pFontTextureView to io.Fonts->TexID so let's clear that as well. + if (g_pFontTextureResource) { g_pFontTextureResource->Release(); g_pFontTextureResource = NULL; io.Fonts->TexID = NULL; } // We copied g_pFontTextureView to io.Fonts->TexID so let's clear that as well. for (UINT i = 0; i < g_numFramesInFlight; i++) { - if (g_pFrameResources[i].IB) { g_pFrameResources[i].IB->Release(); g_pFrameResources[i].IB = NULL; } - if (g_pFrameResources[i].VB) { g_pFrameResources[i].VB->Release(); g_pFrameResources[i].VB = NULL; } + FrameResources* fr = &g_pFrameResources[i]; + if (fr->IndexBuffer) { fr->IndexBuffer->Release(); fr->IndexBuffer = NULL; } + if (fr->VertexBuffer) { fr->VertexBuffer->Release(); fr->VertexBuffer = NULL; } } } @@ -605,10 +601,11 @@ bool ImGui_ImplDX12_Init(ID3D12Device* device, int num_frames_in_flight, DXGI_FO // Create buffers with a default size (they will later be grown as needed) for (int i = 0; i < num_frames_in_flight; i++) { - g_pFrameResources[i].IB = NULL; - g_pFrameResources[i].VB = NULL; - g_pFrameResources[i].VertexBufferSize = 5000; - g_pFrameResources[i].IndexBufferSize = 10000; + FrameResources* fr = &g_pFrameResources[i]; + fr->IndexBuffer = NULL; + fr->VertexBuffer = NULL; + fr->IndexBufferSize = 10000; + fr->VertexBufferSize = 5000; } return true; @@ -618,10 +615,10 @@ void ImGui_ImplDX12_Shutdown() { ImGui_ImplDX12_InvalidateDeviceObjects(); delete[] g_pFrameResources; + g_pFrameResources = NULL; g_pd3dDevice = NULL; g_hFontSrvCpuDescHandle.ptr = 0; g_hFontSrvGpuDescHandle.ptr = 0; - g_pFrameResources = NULL; g_numFramesInFlight = 0; g_frameIndex = UINT_MAX; }