33 #include <d3dcompiler.h>
35 #pragma comment(lib, "d3dcompiler") // Automatically link with d3dcompiler.lib as we are using D3DCompile() below.
85 { 2.0f/(R-L), 0.0
f, 0.0
f, 0.0
f },
86 { 0.0f, 2.0f/(
T-B), 0.0
f, 0.0
f },
87 { 0.0f, 0.0f, 0.5f, 0.0f },
88 { (R+L)/(L-R), (
T+B)/(B-
T), 0.5f, 1.0f },
90 memcpy(&vertex_constant_buffer.
mvp, mvp,
sizeof(mvp));
95 memset(&vp, 0,
sizeof(D3D12_VIEWPORT));
100 vp.TopLeftX = vp.TopLeftY = 0.0f;
101 ctx->RSSetViewports(1, &vp);
106 D3D12_VERTEX_BUFFER_VIEW vbv;
107 memset(&vbv, 0,
sizeof(D3D12_VERTEX_BUFFER_VIEW));
110 vbv.StrideInBytes =
stride;
111 ctx->IASetVertexBuffers(0, 1, &vbv);
112 D3D12_INDEX_BUFFER_VIEW ibv;
113 memset(&ibv, 0,
sizeof(D3D12_INDEX_BUFFER_VIEW));
114 ibv.BufferLocation = fr->
IndexBuffer->GetGPUVirtualAddress();
116 ibv.Format =
sizeof(
ImDrawIdx) == 2 ? DXGI_FORMAT_R16_UINT : DXGI_FORMAT_R32_UINT;
117 ctx->IASetIndexBuffer(&ibv);
118 ctx->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
121 ctx->SetGraphicsRoot32BitConstants(0, 16, &vertex_constant_buffer, 0);
124 const float blend_factor[4] = { 0.f, 0.f, 0.f, 0.f };
125 ctx->OMSetBlendFactor(blend_factor);
146 D3D12_HEAP_PROPERTIES
props;
147 memset(&
props, 0,
sizeof(D3D12_HEAP_PROPERTIES));
148 props.Type = D3D12_HEAP_TYPE_UPLOAD;
149 props.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
150 props.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;
151 D3D12_RESOURCE_DESC
desc;
152 memset(&
desc, 0,
sizeof(D3D12_RESOURCE_DESC));
153 desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
156 desc.DepthOrArraySize = 1;
158 desc.Format = DXGI_FORMAT_UNKNOWN;
159 desc.SampleDesc.Count = 1;
160 desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
161 desc.Flags = D3D12_RESOURCE_FLAG_NONE;
169 D3D12_HEAP_PROPERTIES
props;
170 memset(&
props, 0,
sizeof(D3D12_HEAP_PROPERTIES));
171 props.Type = D3D12_HEAP_TYPE_UPLOAD;
172 props.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
173 props.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;
174 D3D12_RESOURCE_DESC
desc;
175 memset(&
desc, 0,
sizeof(D3D12_RESOURCE_DESC));
176 desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
179 desc.DepthOrArraySize = 1;
181 desc.Format = DXGI_FORMAT_UNKNOWN;
182 desc.SampleDesc.Count = 1;
183 desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
184 desc.Flags = D3D12_RESOURCE_FLAG_NONE;
190 void* vtx_resource, *idx_resource;
192 memset(&
range, 0,
sizeof(D3D12_RANGE));
215 int global_vtx_offset = 0;
216 int global_idx_offset = 0;
221 for (
int cmd_i = 0; cmd_i < cmd_list->
CmdBuffer.
Size; cmd_i++)
237 ctx->SetGraphicsRootDescriptorTable(1, *(D3D12_GPU_DESCRIPTOR_HANDLE*)&pcmd->
TextureId);
238 ctx->RSSetScissorRects(1, &
r);
257 D3D12_HEAP_PROPERTIES
props;
258 memset(&
props, 0,
sizeof(D3D12_HEAP_PROPERTIES));
259 props.Type = D3D12_HEAP_TYPE_DEFAULT;
260 props.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
261 props.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;
263 D3D12_RESOURCE_DESC
desc;
265 desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
269 desc.DepthOrArraySize = 1;
271 desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
272 desc.SampleDesc.Count = 1;
273 desc.SampleDesc.Quality = 0;
274 desc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;
275 desc.Flags = D3D12_RESOURCE_FLAG_NONE;
277 ID3D12Resource* pTexture =
NULL;
279 D3D12_RESOURCE_STATE_COPY_DEST,
NULL, IID_PPV_ARGS(&pTexture));
281 UINT uploadPitch = (
width * 4 + D3D12_TEXTURE_DATA_PITCH_ALIGNMENT - 1u) & ~(D3D12_TEXTURE_DATA_PITCH_ALIGNMENT - 1u);
282 UINT uploadSize =
height * uploadPitch;
283 desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
285 desc.Width = uploadSize;
287 desc.DepthOrArraySize = 1;
289 desc.Format = DXGI_FORMAT_UNKNOWN;
290 desc.SampleDesc.Count = 1;
291 desc.SampleDesc.Quality = 0;
292 desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
293 desc.Flags = D3D12_RESOURCE_FLAG_NONE;
295 props.Type = D3D12_HEAP_TYPE_UPLOAD;
296 props.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
297 props.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;
299 ID3D12Resource* uploadBuffer =
NULL;
301 D3D12_RESOURCE_STATE_GENERIC_READ,
NULL, IID_PPV_ARGS(&uploadBuffer));
305 D3D12_RANGE
range = { 0, uploadSize };
306 hr = uploadBuffer->Map(0, &
range, &mapped);
309 memcpy((
void*) ((uintptr_t) mapped +
y * uploadPitch),
pixels +
y *
width * 4,
width * 4);
310 uploadBuffer->Unmap(0, &
range);
312 D3D12_TEXTURE_COPY_LOCATION srcLocation = {};
313 srcLocation.pResource = uploadBuffer;
314 srcLocation.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT;
315 srcLocation.PlacedFootprint.Footprint.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
316 srcLocation.PlacedFootprint.Footprint.Width =
width;
317 srcLocation.PlacedFootprint.Footprint.Height =
height;
318 srcLocation.PlacedFootprint.Footprint.Depth = 1;
319 srcLocation.PlacedFootprint.Footprint.RowPitch = uploadPitch;
321 D3D12_TEXTURE_COPY_LOCATION dstLocation = {};
322 dstLocation.pResource = pTexture;
323 dstLocation.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
324 dstLocation.SubresourceIndex = 0;
326 D3D12_RESOURCE_BARRIER barrier = {};
327 barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
328 barrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
329 barrier.Transition.pResource = pTexture;
330 barrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES;
331 barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_COPY_DEST;
332 barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE;
334 ID3D12Fence* fence =
NULL;
335 hr =
g_pd3dDevice->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&fence));
338 HANDLE event = CreateEvent(0, 0, 0, 0);
341 D3D12_COMMAND_QUEUE_DESC queueDesc = {};
342 queueDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT;
343 queueDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE;
344 queueDesc.NodeMask = 1;
346 ID3D12CommandQueue* cmdQueue =
NULL;
347 hr =
g_pd3dDevice->CreateCommandQueue(&queueDesc, IID_PPV_ARGS(&cmdQueue));
350 ID3D12CommandAllocator* cmdAlloc =
NULL;
351 hr =
g_pd3dDevice->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(&cmdAlloc));
354 ID3D12GraphicsCommandList* cmdList =
NULL;
355 hr =
g_pd3dDevice->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, cmdAlloc,
NULL, IID_PPV_ARGS(&cmdList));
358 cmdList->CopyTextureRegion(&dstLocation, 0, 0, 0, &srcLocation,
NULL);
359 cmdList->ResourceBarrier(1, &barrier);
361 hr = cmdList->Close();
364 cmdQueue->ExecuteCommandLists(1, (ID3D12CommandList*
const*) &cmdList);
365 hr = cmdQueue->Signal(fence, 1);
368 fence->SetEventOnCompletion(1,
event);
369 WaitForSingleObject(
event, INFINITE);
376 uploadBuffer->Release();
379 D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc;
380 ZeroMemory(&srvDesc,
sizeof(srvDesc));
381 srvDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
382 srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D;
383 srvDesc.Texture2D.MipLevels =
desc.MipLevels;
384 srvDesc.Texture2D.MostDetailedMip = 0;
385 srvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
405 D3D12_DESCRIPTOR_RANGE descRange = {};
406 descRange.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV;
407 descRange.NumDescriptors = 1;
408 descRange.BaseShaderRegister = 0;
409 descRange.RegisterSpace = 0;
410 descRange.OffsetInDescriptorsFromTableStart = 0;
412 D3D12_ROOT_PARAMETER
param[2] = {};
414 param[0].ParameterType = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS;
415 param[0].Constants.ShaderRegister = 0;
416 param[0].Constants.RegisterSpace = 0;
417 param[0].Constants.Num32BitValues = 16;
418 param[0].ShaderVisibility = D3D12_SHADER_VISIBILITY_VERTEX;
420 param[1].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
421 param[1].DescriptorTable.NumDescriptorRanges = 1;
422 param[1].DescriptorTable.pDescriptorRanges = &descRange;
423 param[1].ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL;
425 D3D12_STATIC_SAMPLER_DESC staticSampler = {};
426 staticSampler.Filter = D3D12_FILTER_MIN_MAG_MIP_LINEAR;
427 staticSampler.AddressU = D3D12_TEXTURE_ADDRESS_MODE_WRAP;
428 staticSampler.AddressV = D3D12_TEXTURE_ADDRESS_MODE_WRAP;
429 staticSampler.AddressW = D3D12_TEXTURE_ADDRESS_MODE_WRAP;
430 staticSampler.MipLODBias = 0.f;
431 staticSampler.MaxAnisotropy = 0;
432 staticSampler.ComparisonFunc = D3D12_COMPARISON_FUNC_ALWAYS;
433 staticSampler.BorderColor = D3D12_STATIC_BORDER_COLOR_TRANSPARENT_BLACK;
434 staticSampler.MinLOD = 0.f;
435 staticSampler.MaxLOD = 0.f;
436 staticSampler.ShaderRegister = 0;
437 staticSampler.RegisterSpace = 0;
438 staticSampler.ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL;
440 D3D12_ROOT_SIGNATURE_DESC
desc = {};
443 desc.NumStaticSamplers = 1;
444 desc.pStaticSamplers = &staticSampler;
446 D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT |
447 D3D12_ROOT_SIGNATURE_FLAG_DENY_HULL_SHADER_ROOT_ACCESS |
448 D3D12_ROOT_SIGNATURE_FLAG_DENY_DOMAIN_SHADER_ROOT_ACCESS |
449 D3D12_ROOT_SIGNATURE_FLAG_DENY_GEOMETRY_SHADER_ROOT_ACCESS;
451 ID3DBlob* blob =
NULL;
452 if (D3D12SerializeRootSignature(&
desc, D3D_ROOT_SIGNATURE_VERSION_1, &blob,
NULL) != S_OK)
465 D3D12_GRAPHICS_PIPELINE_STATE_DESC psoDesc;
466 memset(&psoDesc, 0,
sizeof(D3D12_GRAPHICS_PIPELINE_STATE_DESC));
467 psoDesc.NodeMask = 1;
468 psoDesc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE;
470 psoDesc.SampleMask = UINT_MAX;
471 psoDesc.NumRenderTargets = 1;
473 psoDesc.SampleDesc.Count = 1;
474 psoDesc.Flags = D3D12_PIPELINE_STATE_FLAG_NONE;
478 static const char* vertexShader =
479 "cbuffer vertexBuffer : register(b0) \
481 float4x4 ProjectionMatrix; \
485 float2 pos : POSITION;\
486 float4 col : COLOR0;\
487 float2 uv : TEXCOORD0;\
492 float4 pos : SV_POSITION;\
493 float4 col : COLOR0;\
494 float2 uv : TEXCOORD0;\
497 PS_INPUT main(VS_INPUT input)\
500 output.pos = mul( ProjectionMatrix, float4(input.pos.xy, 0.f, 1.f));\
501 output.col = input.col;\
502 output.uv = input.uv;\
506 D3DCompile(vertexShader, strlen(vertexShader),
NULL,
NULL,
NULL,
"main",
"vs_5_0", 0, 0, &
g_pVertexShaderBlob,
NULL);
512 static D3D12_INPUT_ELEMENT_DESC local_layout[] = {
513 {
"POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (UINT)
IM_OFFSETOF(
ImDrawVert, pos), D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
514 {
"TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (UINT)
IM_OFFSETOF(
ImDrawVert, uv), D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
515 {
"COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, (UINT)
IM_OFFSETOF(
ImDrawVert, col), D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
517 psoDesc.InputLayout = { local_layout, 3 };
522 static const char* pixelShader =
525 float4 pos : SV_POSITION;\
526 float4 col : COLOR0;\
527 float2 uv : TEXCOORD0;\
529 SamplerState sampler0 : register(s0);\
530 Texture2D texture0 : register(t0);\
532 float4 main(PS_INPUT input) : SV_Target\
534 float4 out_col = input.col * texture0.Sample(sampler0, input.uv); \
538 D3DCompile(pixelShader, strlen(pixelShader),
NULL,
NULL,
NULL,
"main",
"ps_5_0", 0, 0, &
g_pPixelShaderBlob,
NULL);
546 D3D12_BLEND_DESC&
desc = psoDesc.BlendState;
547 desc.AlphaToCoverageEnable =
false;
548 desc.RenderTarget[0].BlendEnable =
true;
549 desc.RenderTarget[0].SrcBlend = D3D12_BLEND_SRC_ALPHA;
550 desc.RenderTarget[0].DestBlend = D3D12_BLEND_INV_SRC_ALPHA;
551 desc.RenderTarget[0].BlendOp = D3D12_BLEND_OP_ADD;
552 desc.RenderTarget[0].SrcBlendAlpha = D3D12_BLEND_INV_SRC_ALPHA;
553 desc.RenderTarget[0].DestBlendAlpha = D3D12_BLEND_ZERO;
554 desc.RenderTarget[0].BlendOpAlpha = D3D12_BLEND_OP_ADD;
555 desc.RenderTarget[0].RenderTargetWriteMask = D3D12_COLOR_WRITE_ENABLE_ALL;
560 D3D12_RASTERIZER_DESC&
desc = psoDesc.RasterizerState;
561 desc.FillMode = D3D12_FILL_MODE_SOLID;
562 desc.CullMode = D3D12_CULL_MODE_NONE;
563 desc.FrontCounterClockwise = FALSE;
564 desc.DepthBias = D3D12_DEFAULT_DEPTH_BIAS;
565 desc.DepthBiasClamp = D3D12_DEFAULT_DEPTH_BIAS_CLAMP;
566 desc.SlopeScaledDepthBias = D3D12_DEFAULT_SLOPE_SCALED_DEPTH_BIAS;
567 desc.DepthClipEnable =
true;
568 desc.MultisampleEnable = FALSE;
569 desc.AntialiasedLineEnable = FALSE;
570 desc.ForcedSampleCount = 0;
571 desc.ConservativeRaster = D3D12_CONSERVATIVE_RASTERIZATION_MODE_OFF;
576 D3D12_DEPTH_STENCIL_DESC&
desc = psoDesc.DepthStencilState;
577 desc.DepthEnable =
false;
578 desc.DepthWriteMask = D3D12_DEPTH_WRITE_MASK_ALL;
579 desc.DepthFunc = D3D12_COMPARISON_FUNC_ALWAYS;
580 desc.StencilEnable =
false;
581 desc.FrontFace.StencilFailOp =
desc.FrontFace.StencilDepthFailOp =
desc.FrontFace.StencilPassOp = D3D12_STENCIL_OP_KEEP;
582 desc.FrontFace.StencilFunc = D3D12_COMPARISON_FUNC_ALWAYS;
616 bool ImGui_ImplDX12_Init(ID3D12Device* device,
int num_frames_in_flight, DXGI_FORMAT rtv_format, ID3D12DescriptorHeap* cbv_srv_heap,
617 D3D12_CPU_DESCRIPTOR_HANDLE font_srv_cpu_desc_handle, D3D12_GPU_DESCRIPTOR_HANDLE font_srv_gpu_desc_handle)
634 for (
int i = 0;
i < num_frames_in_flight;
i++)