From: Conor McCarthy cmccarthy@codeweavers.com
FXC may erroneously emit a dcl_indexrange beyond the bounds of the addressed range. If this includes a sysval, it will be erroneously included in the arrayed signature element. We could trim more than one from the end, but it is very rare to have even one. A sysval at index 0 is a more complex case, which is not handled. --- libs/vkd3d-shader/ir.c | 13 ++++++++++++- tests/d3d12.c | 1 - 2 files changed, 12 insertions(+), 2 deletions(-)
diff --git a/libs/vkd3d-shader/ir.c b/libs/vkd3d-shader/ir.c index 7a3c9d681..b63fcab53 100644 --- a/libs/vkd3d-shader/ir.c +++ b/libs/vkd3d-shader/ir.c @@ -650,10 +650,15 @@ static void io_normaliser_add_index_range(struct io_normaliser *normaliser, { const struct vkd3d_shader_index_range *range = &ins->declaration.index_range; const struct vkd3d_shader_register *reg = &range->dst.reg; + unsigned int register_count = range->register_count; + enum vkd3d_shader_sysval_semantic sysval_semantic; unsigned int reg_idx, write_mask, element_idx; const struct shader_signature *signature; uint8_t (*range_map)[VKD3D_VEC4_SIZE];
+ if (!register_count) + return; + switch (reg->type) { case VKD3DSPR_INPUT: @@ -685,7 +690,13 @@ static void io_normaliser_add_index_range(struct io_normaliser *normaliser, reg_idx = reg->idx[reg->idx_count - 1].offset; write_mask = range->dst.write_mask; element_idx = shader_signature_find_element_for_reg(signature, reg_idx, write_mask); - range_map_set_register_range(range_map, reg_idx, range->register_count, + sysval_semantic = signature->elements[element_idx + register_count - 1].sysval_semantic; + /* Trim the last element if it's a non-arrayable sysval. FXC seems to forbid actual addressing + * of such a sysval, but it can erroneously include it in a dcl_indexrange. */ + register_count -= sysval_semantic && !vsir_sysval_semantic_is_tess_factor(sysval_semantic) + && !vsir_sysval_semantic_is_clip_cull(sysval_semantic); + + range_map_set_register_range(range_map, reg_idx, register_count, signature->elements[element_idx].mask, true); }
diff --git a/tests/d3d12.c b/tests/d3d12.c index b84c58543..ec6e065c0 100644 --- a/tests/d3d12.c +++ b/tests/d3d12.c @@ -37739,7 +37739,6 @@ static void test_hull_shader_punned_array(void) transition_resource_state(command_list, context.render_target, D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
- todo check_sub_resource_uint(context.render_target, 0, queue, command_list, 0xff00ff00, 0);
destroy_test_context(&context);