From: Conor McCarthy cmccarthy@codeweavers.com
The relative-addressed case in shader_register_normalise_arrayed_addressing() leaves the control point id in idx[0], while for constant register indices it is placed in idx[1]. The latter case could be fixed instead, but placing the control point count in the outer dimension is more logical. --- libs/vkd3d-shader/ir.c | 7 +++++++ libs/vkd3d-shader/spirv.c | 20 ++++++++++---------- tests/d3d12.c | 1 - 3 files changed, 17 insertions(+), 11 deletions(-)
diff --git a/libs/vkd3d-shader/ir.c b/libs/vkd3d-shader/ir.c index d6ff42ab2..4ee4076a7 100644 --- a/libs/vkd3d-shader/ir.c +++ b/libs/vkd3d-shader/ir.c @@ -897,6 +897,13 @@ static unsigned int shader_register_normalise_arrayed_addressing(struct vkd3d_sh reg->idx[id_idx + 1].rel_addr = NULL; reg->idx[id_idx + 1].offset = reg->idx[id_idx].offset; reg->idx[id_idx].offset -= register_index; + if (id_idx) + { + /* idx[id_idx] now contains the array index, which must be moved below the control point id. */ + struct vkd3d_shader_register_index tmp = reg->idx[id_idx]; + reg->idx[id_idx] = reg->idx[id_idx - 1]; + reg->idx[id_idx - 1] = tmp; + } ++id_idx; } /* Otherwise we have no address for the arrayed register, so insert one. This happens e.g. where diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c index 067ba1b2d..23f249ee3 100644 --- a/libs/vkd3d-shader/spirv.c +++ b/libs/vkd3d-shader/spirv.c @@ -4770,7 +4770,7 @@ static uint32_t spirv_compiler_emit_builtin_variable_v(struct spirv_compiler *co assert(size_count <= ARRAY_SIZE(sizes)); memcpy(sizes, array_sizes, size_count * sizeof(sizes[0])); array_sizes = sizes; - sizes[size_count - 1] = max(sizes[size_count - 1], builtin->spirv_array_size); + sizes[0] = max(sizes[0], builtin->spirv_array_size);
id = spirv_compiler_emit_array_variable(compiler, &builder->global_stream, storage_class, builtin->component_type, builtin->component_count, array_sizes, size_count); @@ -4841,12 +4841,12 @@ static uint32_t spirv_compiler_emit_input(struct spirv_compiler *compiler,
builtin = get_spirv_builtin_for_sysval(compiler, sysval);
- array_sizes[0] = (reg_type == VKD3DSPR_PATCHCONST ? 0 : compiler->input_control_point_count); - array_sizes[1] = signature_element->register_count; - if (array_sizes[1] == 1 && !vsir_sysval_semantic_is_tess_factor(signature_element->sysval_semantic) - && (!vsir_sysval_semantic_is_clip_cull(signature_element->sysval_semantic) || array_sizes[0])) + array_sizes[0] = signature_element->register_count; + array_sizes[1] = (reg_type == VKD3DSPR_PATCHCONST ? 0 : compiler->input_control_point_count); + if (array_sizes[0] == 1 && !vsir_sysval_semantic_is_tess_factor(signature_element->sysval_semantic) + && (!vsir_sysval_semantic_is_clip_cull(signature_element->sysval_semantic) || array_sizes[1])) { - array_sizes[1] = 0; + array_sizes[0] = 0; }
write_mask = signature_element->mask; @@ -5183,10 +5183,10 @@ static void spirv_compiler_emit_output(struct spirv_compiler *compiler, /* Don't use builtins for TCS -> TES varyings. See spirv_compiler_emit_input(). */ if (compiler->shader_type == VKD3D_SHADER_TYPE_HULL && !is_patch_constant) sysval = VKD3D_SHADER_SV_NONE; - array_sizes[0] = (reg_type == VKD3DSPR_PATCHCONST ? 0 : compiler->output_control_point_count); - array_sizes[1] = signature_element->register_count; - if (array_sizes[1] == 1 && !vsir_sysval_semantic_is_tess_factor(signature_element->sysval_semantic)) - array_sizes[1] = 0; + array_sizes[0] = signature_element->register_count; + array_sizes[1] = (reg_type == VKD3DSPR_PATCHCONST ? 0 : compiler->output_control_point_count); + if (array_sizes[0] == 1 && !vsir_sysval_semantic_is_tess_factor(signature_element->sysval_semantic)) + array_sizes[0] = 0;
builtin = vkd3d_get_spirv_builtin(compiler, reg_type, sysval);
diff --git a/tests/d3d12.c b/tests/d3d12.c index 9154db138..6bdb5f7a4 100644 --- a/tests/d3d12.c +++ b/tests/d3d12.c @@ -37822,7 +37822,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, 0xcc996633, 0);
destroy_test_context(&context);