Skip to content

Commit 3058410

Browse files
committed
Merge pull request godotengine#114076 from blueskythlikesclouds/d3d12-reduce-unnecessary-calls
Reduce unnecessary calls in D3D12 driver.
2 parents 5638ad0 + b1647ba commit 3058410

2 files changed

Lines changed: 66 additions & 55 deletions

File tree

drivers/d3d12/rendering_device_driver_d3d12.cpp

Lines changed: 51 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -2295,12 +2295,6 @@ void RenderingDeviceDriverD3D12::command_pipeline_barrier(CommandBufferID p_cmd_
22952295
return;
22962296
}
22972297

2298-
// The command list must support the required interface.
2299-
const CommandBufferInfo *cmd_buf_info = (const CommandBufferInfo *)(p_cmd_buffer.id);
2300-
ComPtr<ID3D12GraphicsCommandList7> cmd_list_7;
2301-
HRESULT res = cmd_buf_info->cmd_list->QueryInterface(cmd_list_7.GetAddressOf());
2302-
ERR_FAIL_COND(FAILED(res));
2303-
23042298
// Convert the RDD barriers to D3D12 enhanced barriers.
23052299
thread_local LocalVector<D3D12_GLOBAL_BARRIER> global_barriers;
23062300
thread_local LocalVector<D3D12_BUFFER_BARRIER> buffer_barriers;
@@ -2390,7 +2384,8 @@ void RenderingDeviceDriverD3D12::command_pipeline_barrier(CommandBufferID p_cmd_
23902384
}
23912385

23922386
if (barrier_groups_count) {
2393-
cmd_list_7->Barrier(barrier_groups_count, barrier_groups);
2387+
const CommandBufferInfo *cmd_buf_info = (const CommandBufferInfo *)(p_cmd_buffer.id);
2388+
cmd_buf_info->cmd_list_7->Barrier(barrier_groups_count, barrier_groups);
23942389
}
23952390
}
23962391

@@ -2558,6 +2553,9 @@ void RenderingDeviceDriverD3D12::command_pool_free(CommandPoolID p_cmd_pool) {
25582553
cmd_buf_elem = cmd_buf_elem->next();
25592554

25602555
cmd_buf_info->cmd_list.Reset();
2556+
cmd_buf_info->cmd_list_1.Reset();
2557+
cmd_buf_info->cmd_list_5.Reset();
2558+
cmd_buf_info->cmd_list_7.Reset();
25612559
cmd_buf_info->cmd_allocator.Reset();
25622560

25632561
resource_descriptor_heap_pool.free(cmd_buf_info->uav_alloc);
@@ -2633,6 +2631,10 @@ RDD::CommandBufferID RenderingDeviceDriverD3D12::command_buffer_create(CommandPo
26332631
cmd_buf_info->cmd_allocator = cmd_allocator;
26342632
cmd_buf_info->cmd_list = cmd_list;
26352633

2634+
cmd_list->QueryInterface(cmd_buf_info->cmd_list_1.GetAddressOf());
2635+
cmd_list->QueryInterface(cmd_buf_info->cmd_list_5.GetAddressOf());
2636+
cmd_list->QueryInterface(cmd_buf_info->cmd_list_7.GetAddressOf());
2637+
26362638
cmd_buf_info->uav_alloc = uav_alloc;
26372639
cmd_buf_info->rtv_alloc = rtv_alloc;
26382640
cmd_buf_info->dsv_alloc = dsv_alloc;
@@ -2670,6 +2672,7 @@ void RenderingDeviceDriverD3D12::command_buffer_end(CommandBufferID p_cmd_buffer
26702672
cmd_buf_info->graphics_root_signature_crc = 0;
26712673
cmd_buf_info->compute_pso = nullptr;
26722674
cmd_buf_info->compute_root_signature_crc = 0;
2675+
cmd_buf_info->pending_dyn_params = true;
26732676
cmd_buf_info->descriptor_heaps_set = false;
26742677
}
26752678

@@ -4321,15 +4324,11 @@ void RenderingDeviceDriverD3D12::command_begin_render_pass(CommandBufferID p_cmd
43214324
}
43224325

43234326
if (fb_info->vrs_attachment && fsr_capabilities.attachment_supported) {
4324-
ComPtr<ID3D12GraphicsCommandList5> cmd_list_5;
4325-
cmd_buf_info->cmd_list->QueryInterface(cmd_list_5.GetAddressOf());
4326-
if (cmd_list_5) {
4327-
static const D3D12_SHADING_RATE_COMBINER COMBINERS[D3D12_RS_SET_SHADING_RATE_COMBINER_COUNT] = {
4328-
D3D12_SHADING_RATE_COMBINER_PASSTHROUGH,
4329-
D3D12_SHADING_RATE_COMBINER_OVERRIDE,
4330-
};
4331-
cmd_list_5->RSSetShadingRate(D3D12_SHADING_RATE_1X1, COMBINERS);
4332-
}
4327+
static const D3D12_SHADING_RATE_COMBINER COMBINERS[D3D12_RS_SET_SHADING_RATE_COMBINER_COUNT] = {
4328+
D3D12_SHADING_RATE_COMBINER_PASSTHROUGH,
4329+
D3D12_SHADING_RATE_COMBINER_OVERRIDE,
4330+
};
4331+
cmd_buf_info->cmd_list_5->RSSetShadingRate(D3D12_SHADING_RATE_1X1, COMBINERS);
43334332
}
43344333

43354334
cmd_buf_info->render_pass_state.current_subpass = UINT32_MAX;
@@ -4541,12 +4540,8 @@ void RenderingDeviceDriverD3D12::command_end_render_pass(CommandBufferID p_cmd_b
45414540
const FramebufferInfo *fb_info = cmd_buf_info->render_pass_state.fb_info;
45424541
const RenderPassInfo *pass_info = cmd_buf_info->render_pass_state.pass_info;
45434542

4544-
if (fsr_capabilities.attachment_supported) {
4545-
ComPtr<ID3D12GraphicsCommandList5> cmd_list_5;
4546-
cmd_buf_info->cmd_list->QueryInterface(cmd_list_5.GetAddressOf());
4547-
if (cmd_list_5) {
4548-
cmd_list_5->RSSetShadingRateImage(nullptr);
4549-
}
4543+
if (fb_info->vrs_attachment && fsr_capabilities.attachment_supported) {
4544+
cmd_buf_info->cmd_list_5->RSSetShadingRateImage(nullptr);
45504545
}
45514546

45524547
auto _transition_subresources = [&](TextureInfo *p_texture_info, D3D12_RESOURCE_STATES p_states) {
@@ -4762,37 +4757,46 @@ void RenderingDeviceDriverD3D12::command_render_clear_attachments(CommandBufferI
47624757

47634758
void RenderingDeviceDriverD3D12::command_bind_render_pipeline(CommandBufferID p_cmd_buffer, PipelineID p_pipeline) {
47644759
CommandBufferInfo *cmd_buf_info = (CommandBufferInfo *)p_cmd_buffer.id;
4765-
const PipelineInfo *pipeline_info = (const PipelineInfo *)p_pipeline.id;
4766-
4767-
if (cmd_buf_info->graphics_pso == pipeline_info->pso.Get()) {
4768-
return;
4769-
}
47704760

4761+
const PipelineInfo *pipeline_info = (const PipelineInfo *)p_pipeline.id;
47714762
const ShaderInfo *shader_info_in = pipeline_info->shader_info;
47724763
const RenderPipelineInfo &render_info = pipeline_info->render_info;
47734764

4774-
cmd_buf_info->cmd_list->SetPipelineState(pipeline_info->pso.Get());
4765+
if (cmd_buf_info->graphics_pso != pipeline_info->pso.Get()) {
4766+
cmd_buf_info->cmd_list->SetPipelineState(pipeline_info->pso.Get());
4767+
4768+
cmd_buf_info->graphics_pso = pipeline_info->pso.Get();
4769+
cmd_buf_info->compute_pso = nullptr;
4770+
}
4771+
47754772
if (cmd_buf_info->graphics_root_signature_crc != shader_info_in->root_signature_crc) {
47764773
cmd_buf_info->cmd_list->SetGraphicsRootSignature(shader_info_in->root_signature.Get());
47774774
cmd_buf_info->graphics_root_signature_crc = shader_info_in->root_signature_crc;
47784775
}
47794776

4780-
cmd_buf_info->cmd_list->IASetPrimitiveTopology(render_info.dyn_params.primitive_topology);
4781-
cmd_buf_info->cmd_list->OMSetBlendFactor(render_info.dyn_params.blend_constant.components);
4782-
cmd_buf_info->cmd_list->OMSetStencilRef(render_info.dyn_params.stencil_reference);
4777+
if (cmd_buf_info->pending_dyn_params || (cmd_buf_info->dyn_params.primitive_topology != render_info.dyn_params.primitive_topology)) {
4778+
cmd_buf_info->cmd_list->IASetPrimitiveTopology(render_info.dyn_params.primitive_topology);
4779+
cmd_buf_info->dyn_params.primitive_topology = render_info.dyn_params.primitive_topology;
4780+
}
47834781

4784-
if (misc_features_support.depth_bounds_supported) {
4785-
ComPtr<ID3D12GraphicsCommandList1> command_list_1;
4786-
cmd_buf_info->cmd_list->QueryInterface(command_list_1.GetAddressOf());
4787-
if (command_list_1) {
4788-
command_list_1->OMSetDepthBounds(render_info.dyn_params.depth_bounds_min, render_info.dyn_params.depth_bounds_max);
4789-
}
4782+
if (cmd_buf_info->pending_dyn_params || (cmd_buf_info->dyn_params.blend_constant != render_info.dyn_params.blend_constant)) {
4783+
cmd_buf_info->cmd_list->OMSetBlendFactor(render_info.dyn_params.blend_constant.components);
4784+
cmd_buf_info->dyn_params.blend_constant = render_info.dyn_params.blend_constant;
47904785
}
47914786

4792-
cmd_buf_info->render_pass_state.vf_info = render_info.vf_info;
4787+
if (cmd_buf_info->pending_dyn_params || (cmd_buf_info->dyn_params.stencil_reference != render_info.dyn_params.stencil_reference)) {
4788+
cmd_buf_info->cmd_list->OMSetStencilRef(render_info.dyn_params.stencil_reference);
4789+
cmd_buf_info->dyn_params.stencil_reference = render_info.dyn_params.stencil_reference;
4790+
}
47934791

4794-
cmd_buf_info->graphics_pso = pipeline_info->pso.Get();
4795-
cmd_buf_info->compute_pso = nullptr;
4792+
if (misc_features_support.depth_bounds_supported && (cmd_buf_info->pending_dyn_params || (cmd_buf_info->dyn_params.depth_bounds_min != render_info.dyn_params.depth_bounds_min) || (cmd_buf_info->dyn_params.depth_bounds_max != render_info.dyn_params.depth_bounds_max))) {
4793+
cmd_buf_info->cmd_list_1->OMSetDepthBounds(render_info.dyn_params.depth_bounds_min, render_info.dyn_params.depth_bounds_max);
4794+
cmd_buf_info->dyn_params.depth_bounds_min = render_info.dyn_params.depth_bounds_min;
4795+
cmd_buf_info->dyn_params.depth_bounds_max = render_info.dyn_params.depth_bounds_max;
4796+
}
4797+
4798+
cmd_buf_info->pending_dyn_params = false;
4799+
cmd_buf_info->render_pass_state.vf_info = render_info.vf_info;
47964800
}
47974801

47984802
void RenderingDeviceDriverD3D12::command_bind_render_uniform_sets(CommandBufferID p_cmd_buffer, VectorView<UniformSetID> p_uniform_sets, ShaderID p_shader, uint32_t p_first_set_index, uint32_t p_set_count, uint32_t p_dynamic_offsets) {
@@ -5336,21 +5340,21 @@ RDD::PipelineID RenderingDeviceDriverD3D12::render_pipeline_create(
53365340

53375341
void RenderingDeviceDriverD3D12::command_bind_compute_pipeline(CommandBufferID p_cmd_buffer, PipelineID p_pipeline) {
53385342
CommandBufferInfo *cmd_buf_info = (CommandBufferInfo *)p_cmd_buffer.id;
5343+
53395344
const PipelineInfo *pipeline_info = (const PipelineInfo *)p_pipeline.id;
5345+
const ShaderInfo *shader_info_in = pipeline_info->shader_info;
53405346

5341-
if (cmd_buf_info->compute_pso == pipeline_info->pso.Get()) {
5342-
return;
5347+
if (cmd_buf_info->compute_pso != pipeline_info->pso.Get()) {
5348+
cmd_buf_info->cmd_list->SetPipelineState(pipeline_info->pso.Get());
5349+
5350+
cmd_buf_info->compute_pso = pipeline_info->pso.Get();
5351+
cmd_buf_info->graphics_pso = nullptr;
53435352
}
53445353

5345-
const ShaderInfo *shader_info_in = pipeline_info->shader_info;
5346-
cmd_buf_info->cmd_list->SetPipelineState(pipeline_info->pso.Get());
53475354
if (cmd_buf_info->compute_root_signature_crc != shader_info_in->root_signature_crc) {
53485355
cmd_buf_info->cmd_list->SetComputeRootSignature(shader_info_in->root_signature.Get());
53495356
cmd_buf_info->compute_root_signature_crc = shader_info_in->root_signature_crc;
53505357
}
5351-
5352-
cmd_buf_info->compute_pso = pipeline_info->pso.Get();
5353-
cmd_buf_info->graphics_pso = nullptr;
53545358
}
53555359

53565360
void RenderingDeviceDriverD3D12::command_bind_compute_uniform_sets(CommandBufferID p_cmd_buffer, VectorView<UniformSetID> p_uniform_sets, ShaderID p_shader, uint32_t p_first_set_index, uint32_t p_set_count, uint32_t p_dynamic_offsets) {

drivers/d3d12/rendering_device_driver_d3d12.h

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -483,6 +483,14 @@ class RenderingDeviceDriverD3D12 : public RenderingDeviceDriver {
483483
uint32_t vertex_buffer_count = 0;
484484
};
485485

486+
struct DynParams {
487+
D3D12_PRIMITIVE_TOPOLOGY primitive_topology = {};
488+
Color blend_constant;
489+
float depth_bounds_min = 0.0f;
490+
float depth_bounds_max = 1.0f;
491+
uint32_t stencil_reference = 0;
492+
};
493+
486494
// Leveraging knowledge of actual usage and D3D12 specifics (namely, command lists from the same allocator
487495
// can't be freely begun and ended), an allocator per list works better.
488496
struct CommandBufferInfo {
@@ -491,10 +499,16 @@ class RenderingDeviceDriverD3D12 : public RenderingDeviceDriver {
491499

492500
Microsoft::WRL::ComPtr<ID3D12CommandAllocator> cmd_allocator;
493501
Microsoft::WRL::ComPtr<ID3D12GraphicsCommandList> cmd_list;
502+
Microsoft::WRL::ComPtr<ID3D12GraphicsCommandList1> cmd_list_1;
503+
Microsoft::WRL::ComPtr<ID3D12GraphicsCommandList5> cmd_list_5;
504+
Microsoft::WRL::ComPtr<ID3D12GraphicsCommandList7> cmd_list_7;
494505

495506
ID3D12PipelineState *graphics_pso = nullptr;
496507
ID3D12PipelineState *compute_pso = nullptr;
497508

509+
DynParams dyn_params;
510+
bool pending_dyn_params = true;
511+
498512
uint32_t graphics_root_signature_crc = 0;
499513
uint32_t compute_root_signature_crc = 0;
500514

@@ -710,14 +724,7 @@ class RenderingDeviceDriverD3D12 : public RenderingDeviceDriver {
710724

711725
struct RenderPipelineInfo {
712726
const VertexFormatInfo *vf_info = nullptr;
713-
714-
struct {
715-
D3D12_PRIMITIVE_TOPOLOGY primitive_topology = {};
716-
Color blend_constant;
717-
float depth_bounds_min = 0.0f;
718-
float depth_bounds_max = 0.0f;
719-
uint32_t stencil_reference = 0;
720-
} dyn_params;
727+
DynParams dyn_params;
721728
};
722729

723730
struct PipelineInfo {

0 commit comments

Comments
 (0)