Shadow of the Tomb Raider does not re-bind all descriptor tables after setting a new root signature if tessellation is enabled, which causes some descriptors to be left undefined.
Signed-off-by: Philip Rebohle philip.rebohle@tu-dortmund.de --- In order to run with tessellation enabled, SotTR currently requires a root signature version fix (patch 172080) as well as the vicp patch from my tessellation series (patch 171410), both of which don't seem to have been reviewed yet.
libs/vkd3d/command.c | 10 ++++------ libs/vkd3d/state.c | 8 ++++++++ libs/vkd3d/vkd3d_private.h | 3 +++ 3 files changed, 15 insertions(+), 6 deletions(-)
diff --git a/libs/vkd3d/command.c b/libs/vkd3d/command.c index c401349..0532ec0 100644 --- a/libs/vkd3d/command.c +++ b/libs/vkd3d/command.c @@ -2539,8 +2539,8 @@ static void d3d12_command_list_prepare_descriptors(struct d3d12_command_list *li root_signature->vk_set_layout); bindings->in_use = false;
- bindings->descriptor_table_dirty_mask |= bindings->descriptor_table_active_mask; - bindings->push_descriptor_dirty_mask |= bindings->push_descriptor_active_mask; + bindings->descriptor_table_dirty_mask |= bindings->descriptor_table_active_mask & root_signature->descriptor_table_mask; + bindings->push_descriptor_dirty_mask |= bindings->push_descriptor_active_mask & root_signature->push_descriptor_mask; }
static bool vk_write_descriptor_set_from_d3d12_desc(VkWriteDescriptorSet *vk_descriptor_write, @@ -4030,10 +4030,8 @@ static void d3d12_command_list_set_root_signature(struct d3d12_command_list *lis
bindings->root_signature = root_signature; bindings->descriptor_set = VK_NULL_HANDLE; - bindings->descriptor_table_dirty_mask = 0; - bindings->descriptor_table_active_mask = 0; - bindings->push_descriptor_dirty_mask = 0; - bindings->push_descriptor_active_mask = 0; + bindings->descriptor_table_dirty_mask = bindings->descriptor_table_active_mask & root_signature->descriptor_table_mask; + bindings->push_descriptor_dirty_mask = bindings->push_descriptor_active_mask & root_signature->push_descriptor_mask; }
static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRootSignature(ID3D12GraphicsCommandList1 *iface, diff --git a/libs/vkd3d/state.c b/libs/vkd3d/state.c index 9dc5cff..a321fa4 100644 --- a/libs/vkd3d/state.c +++ b/libs/vkd3d/state.c @@ -600,12 +600,16 @@ static HRESULT d3d12_root_signature_init_root_descriptor_tables(struct d3d12_roo unsigned int i, j, k, range_count; uint32_t vk_binding;
+ root_signature->descriptor_table_mask = 0; + for (i = 0; i < desc->NumParameters; ++i) { const D3D12_ROOT_PARAMETER *p = &desc->pParameters[i]; if (p->ParameterType != D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE) continue;
+ root_signature->descriptor_table_mask |= 1ull << i; + table = &root_signature->parameters[i].u.descriptor_table; range_count = p->u.DescriptorTable.NumDescriptorRanges;
@@ -666,6 +670,8 @@ static HRESULT d3d12_root_signature_init_root_descriptors(struct d3d12_root_sign VkDescriptorSetLayoutBinding *cur_binding = context->current_binding; unsigned int i;
+ root_signature->push_descriptor_mask = 0; + for (i = 0; i < desc->NumParameters; ++i) { const D3D12_ROOT_PARAMETER *p = &desc->pParameters[i]; @@ -674,6 +680,8 @@ static HRESULT d3d12_root_signature_init_root_descriptors(struct d3d12_root_sign && p->ParameterType != D3D12_ROOT_PARAMETER_TYPE_UAV) continue;
+ root_signature->push_descriptor_mask |= 1u << i; + if (p->u.Descriptor.RegisterSpace) { FIXME("Unhandled register space %u for parameter %u.\n", p->u.Descriptor.RegisterSpace, i); diff --git a/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/vkd3d_private.h index 1cb40f2..2d62fda 100644 --- a/libs/vkd3d/vkd3d_private.h +++ b/libs/vkd3d/vkd3d_private.h @@ -678,6 +678,9 @@ struct d3d12_root_signature unsigned int parameter_count; uint32_t main_set;
+ uint64_t descriptor_table_mask; + uint32_t push_descriptor_mask; + D3D12_ROOT_SIGNATURE_FLAGS flags;
unsigned int descriptor_count;
Signed-off-by: Philip Rebohle philip.rebohle@tu-dortmund.de --- tests/d3d12.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+)
diff --git a/tests/d3d12.c b/tests/d3d12.c index 2ec74a1..999e22c 100644 --- a/tests/d3d12.c +++ b/tests/d3d12.c @@ -16496,6 +16496,36 @@ static void test_update_descriptor_tables_after_root_signature_change(void) D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE); check_sub_resource_uint(context.render_target, 0, queue, command_list, 0xff00ff00, 0);
+ reset_command_list(command_list, context.allocator); + transition_resource_state(command_list, context.render_target, + D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET); + + ID3D12GraphicsCommandList_SetDescriptorHeaps(command_list, ARRAY_SIZE(heaps), heaps); + + ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL); + + ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, false, NULL); + ID3D12GraphicsCommandList_SetPipelineState(command_list, pipeline_state2); + ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, root_signature2); + + ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); + ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport); + ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect); + + ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(command_list, 0, + get_gpu_descriptor_handle(&context, heap, 0)); + ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(command_list, 1, + ID3D12DescriptorHeap_GetGPUDescriptorHandleForHeapStart(sampler_heap)); + + ID3D12GraphicsCommandList_SetPipelineState(command_list, pipeline_state); + ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, root_signature); + + ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0); + + transition_resource_state(command_list, context.render_target, + D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE); + check_sub_resource_uint(context.render_target, 0, queue, command_list, 0xff00ff00, 0); + ID3D12PipelineState_Release(pipeline_state); ID3D12PipelineState_Release(pipeline_state2); ID3D12RootSignature_Release(root_signature);
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com