|
@@ -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;
|
|
|
}
|