From 79ec2fe9f2dcc4872530b123e1851c08083ccad7 Mon Sep 17 00:00:00 2001 From: Giovanni Mascellani Date: Fri, 9 May 2025 14:42:57 +0200 Subject: [PATCH] vkd3d-shader/dxil: Generate specialized values in sm6_parser_constants_init() for casts. Depending on the casted operand, the generated values can be ICB, IDXTEMP or GROUPSHAREDMEM. The cast decoding code is entirely moved to the second pass, so that we avoid abusing registers to temporarily store other data. --- libs/vkd3d-shader/dxil.c | 112 +++++++++++++++++++++++---------------- 1 file changed, 66 insertions(+), 46 deletions(-) diff --git a/libs/vkd3d-shader/dxil.c b/libs/vkd3d-shader/dxil.c index a8d0a3a15..7a8c151f0 100644 --- a/libs/vkd3d-shader/dxil.c +++ b/libs/vkd3d-shader/dxil.c @@ -2337,7 +2337,16 @@ static bool sm6_value_is_ssa(const struct sm6_value *value) static bool sm6_value_is_numeric_array(const struct sm6_value *value) { - return sm6_value_is_register(value) && register_is_numeric_array(&value->reg); + switch (value->value_type) + { + case VALUE_TYPE_ICB: + case VALUE_TYPE_IDXTEMP: + case VALUE_TYPE_GROUPSHAREDMEM: + return true; + + default: + return false; + } } static inline unsigned int sm6_value_get_constant_uint(const struct sm6_value *value) @@ -3443,6 +3452,48 @@ static enum vkd3d_result sm6_parser_constants_init(struct sm6_parser *sm6, const return ret; break; + case CST_CODE_CE_CAST: + /* Resolve later in case forward refs exist. */ + dst->type = type; + dst->value_type = VALUE_TYPE_INVALID; + break; + + case CST_CODE_UNDEF: + dxil_record_validate_operand_max_count(record, 0, sm6); + dst->value_type = VALUE_TYPE_UNDEFINED; + sm6_register_from_value(&dst->reg, dst, sm6); + break; + + default: + vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, + "Constant code %u is unhandled.", record->code); + dst->value_type = VALUE_TYPE_INVALID; + sm6_register_from_value(&dst->reg, dst, sm6); + break; + } + + if (record->attachment) + vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_IGNORING_ATTACHMENT, + "Ignoring a metadata attachment for a constant."); + + ++sm6->value_count; + } + + value_idx = base_value_idx; + + for (i = 0; i < block->record_count; ++i) + { + sm6->p.location.column = i; + record = block->records[i]; + + switch (record->code) + { + case CST_CODE_SETTYPE: + continue; + + default: + break; + case CST_CODE_CE_CAST: if (!dxil_record_validate_operand_count(record, 3, 3, sm6)) return VKD3D_ERROR_INVALID_SHADER; @@ -3479,59 +3530,28 @@ static enum vkd3d_result sm6_parser_constants_init(struct sm6_parser *sm6, const return VKD3D_ERROR_INVALID_SHADER; } - /* Resolve later in case forward refs exist. */ + dst = &sm6->values[value_idx]; + src = &sm6->values[value]; + + if (!sm6_value_is_numeric_array(src)) + { + vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, + "Constexpr cast source value is not a global array element."); + return VKD3D_ERROR_INVALID_SHADER; + } + + type = dst->type; + *dst = *src; dst->type = type; - dst->reg.type = VKD3DSPR_COUNT; - dst->reg.idx[0].offset = value; - break; - case CST_CODE_UNDEF: - dxil_record_validate_operand_max_count(record, 0, sm6); - dst->value_type = VALUE_TYPE_UNDEFINED; - sm6_register_from_value(&dst->reg, dst, sm6); - break; - - default: - FIXME("Unhandled constant code %u.\n", record->code); - vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, - "Constant code %u is unhandled.", record->code); - dst->value_type = VALUE_TYPE_INVALID; sm6_register_from_value(&dst->reg, dst, sm6); break; } - if (record->attachment) - { - WARN("Ignoring metadata attachment.\n"); - vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_IGNORING_ATTACHMENT, - "Ignoring a metadata attachment for a constant."); - } - - ++sm6->value_count; + ++value_idx; } - /* Resolve cast forward refs. */ - for (i = base_value_idx; i < sm6->value_count; ++i) - { - dst = &sm6->values[i]; - if (dst->reg.type != VKD3DSPR_COUNT) - continue; - - type = dst->type; - - src = &sm6->values[dst->reg.idx[0].offset]; - if (!sm6_value_is_numeric_array(src)) - { - WARN("Value is not an array.\n"); - vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, - "Constexpr cast source value is not a global array element."); - return VKD3D_ERROR_INVALID_SHADER; - } - - *dst = *src; - dst->type = type; - dst->reg.data_type = vkd3d_data_type_from_sm6_type(type->u.pointer.type); - } + VKD3D_ASSERT(value_idx == sm6->value_count); return VKD3D_OK; }