From: Francisco Casas fcasas@codeweavers.com
HLSL_ARRAY_ELEMENTS_COUNT_IMPLICIT is used as a temporal value for elements_count for implicit size arrays. It is replaced by the correct value after parsing the initializer.
Signed-off-by: Francisco Casas fcasas@codeweavers.com --- libs/vkd3d-shader/hlsl.c | 13 ++++- libs/vkd3d-shader/hlsl.h | 2 + libs/vkd3d-shader/hlsl.y | 50 ++++++++++++++++++- libs/vkd3d-shader/hlsl_sm1.c | 1 + libs/vkd3d-shader/hlsl_sm4.c | 1 + ...lsl-initializer-implicit-array.shader_test | 4 +- 6 files changed, 67 insertions(+), 4 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index 7239b183..1d272866 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -126,6 +126,7 @@ static bool hlsl_type_is_row_major(const struct hlsl_type *type)
static unsigned int get_array_size(const struct hlsl_type *type) { + assert(type->e.array.elements_count != HLSL_ARRAY_ELEMENTS_COUNT_IMPLICIT); if (type->type == HLSL_CLASS_ARRAY) return get_array_size(type->e.array.type) * type->e.array.elements_count; return 1; @@ -166,6 +167,7 @@ static void hlsl_type_calculate_reg_size(struct hlsl_ctx *ctx, struct hlsl_type unsigned int element_size = type->e.array.type->reg_size;
assert(element_size); + assert(type->e.array.elements_count != HLSL_ARRAY_ELEMENTS_COUNT_IMPLICIT); if (is_sm4) type->reg_size = (type->e.array.elements_count - 1) * align(element_size, 4) + element_size; else @@ -328,6 +330,9 @@ struct hlsl_type *hlsl_new_array_type(struct hlsl_ctx *ctx, struct hlsl_type *ba
list_add_tail(&ctx->types, &type->entry);
+ if (type->e.array.elements_count == HLSL_ARRAY_ELEMENTS_COUNT_IMPLICIT) + TRACE("Implicit element count.\n"); + return type; }
@@ -410,6 +415,7 @@ unsigned int hlsl_type_component_count(struct hlsl_type *type) } if (type->type == HLSL_CLASS_ARRAY) { + assert(type->e.array.elements_count != HLSL_ARRAY_ELEMENTS_COUNT_IMPLICIT); return hlsl_type_component_count(type->e.array.type) * type->e.array.elements_count; } if (type->type != HLSL_CLASS_STRUCT) @@ -1023,7 +1029,12 @@ struct vkd3d_string_buffer *hlsl_type_to_string(struct hlsl_ctx *ctx, const stru }
for (t = type; t->type == HLSL_CLASS_ARRAY; t = t->e.array.type) - vkd3d_string_buffer_printf(string, "[%u]", t->e.array.elements_count); + { + if (t->e.array.elements_count == HLSL_ARRAY_ELEMENTS_COUNT_IMPLICIT) + vkd3d_string_buffer_printf(string, "[<undefined>]"); + else + vkd3d_string_buffer_printf(string, "[%u]", t->e.array.elements_count); + } return string; }
diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index 28b2ff1b..94597999 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -227,6 +227,8 @@ struct hlsl_src
#define HLSL_MODIFIERS_MAJORITY_MASK (HLSL_MODIFIER_ROW_MAJOR | HLSL_MODIFIER_COLUMN_MAJOR)
+#define HLSL_ARRAY_ELEMENTS_COUNT_IMPLICIT 0xffffffff + struct hlsl_reg_reservation { char type; diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index 905dbfc5..e7fe74d8 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -1606,7 +1606,27 @@ static struct list *declare_vars(struct hlsl_ctx *ctx, struct hlsl_type *basic_t
type = basic_type; for (i = 0; i < v->arrays.count; ++i) + { + if (v->arrays.sizes[i] == HLSL_ARRAY_ELEMENTS_COUNT_IMPLICIT) + { + unsigned int size = initializer_size(&v->initializer); + unsigned int elem_components = hlsl_type_component_count(type); + + assert(v->initializer.args_count); + + v->arrays.sizes[i] = (size + elem_components - 1)/elem_components; + + if (size % elem_components != 0) + { + hlsl_error(ctx, &v->loc, VKD3D_SHADER_ERROR_HLSL_WRONG_PARAMETER_COUNT, + "Cannot initialize implicit array with %u components, expected a multiple of %u.", + size, elem_components); + free_parse_initializer(&v->initializer); + v->initializer.args_count = 0; + } + } type = hlsl_new_array_type(ctx, type, v->arrays.sizes[i]); + } vkd3d_free(v->arrays.sizes);
if (type->type != HLSL_CLASS_MATRIX) @@ -2464,6 +2484,7 @@ static bool add_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hl %token <name> TYPE_IDENTIFIER
%type <arrays> arrays +%type <arrays> implicit_arrays
%type <assign_op> assign_op
@@ -3108,7 +3129,7 @@ variables_def: }
variable_decl: - any_identifier arrays colon_attribute + any_identifier implicit_arrays colon_attribute { $$ = hlsl_alloc(ctx, sizeof(*$$)); $$->loc = @1; @@ -3137,6 +3158,15 @@ state_block:
variable_def: variable_decl + { + if ($$->arrays.sizes && $$->arrays.sizes[$$->arrays.count - 1] == HLSL_ARRAY_ELEMENTS_COUNT_IMPLICIT) + { + hlsl_error(ctx, &@1, VKD3D_SHADER_ERROR_HLSL_MISSING_INITIALIZER, + "Implicit array requires initializer."); + free_parse_variable_def($$); + YYABORT; + } + } | variable_decl '=' complex_initializer { $$ = $1; @@ -3188,6 +3218,24 @@ arrays: $$.sizes[$$.count++] = size; }
+implicit_arrays: + arrays + | '[' ']' arrays + { + uint32_t *new_array; + + $$ = $3; + + if (!(new_array = hlsl_realloc(ctx, $$.sizes, ($$.count + 1) * sizeof(*new_array)))) + { + vkd3d_free($$.sizes); + YYABORT; + } + + $$.sizes = new_array; + $$.sizes[$$.count++] = HLSL_ARRAY_ELEMENTS_COUNT_IMPLICIT; + } + var_modifiers: %empty { diff --git a/libs/vkd3d-shader/hlsl_sm1.c b/libs/vkd3d-shader/hlsl_sm1.c index 0cdd3917..30380fa2 100644 --- a/libs/vkd3d-shader/hlsl_sm1.c +++ b/libs/vkd3d-shader/hlsl_sm1.c @@ -234,6 +234,7 @@ static const struct hlsl_type *get_array_type(const struct hlsl_type *type)
static unsigned int get_array_size(const struct hlsl_type *type) { + assert(type->e.array.elements_count != HLSL_ARRAY_ELEMENTS_COUNT_IMPLICIT); if (type->type == HLSL_CLASS_ARRAY) return get_array_size(type->e.array.type) * type->e.array.elements_count; return 1; diff --git a/libs/vkd3d-shader/hlsl_sm4.c b/libs/vkd3d-shader/hlsl_sm4.c index 8afa9333..2dcfdb88 100644 --- a/libs/vkd3d-shader/hlsl_sm4.c +++ b/libs/vkd3d-shader/hlsl_sm4.c @@ -252,6 +252,7 @@ static const struct hlsl_type *get_array_type(const struct hlsl_type *type)
static unsigned int get_array_size(const struct hlsl_type *type) { + assert(type->e.array.elements_count != HLSL_ARRAY_ELEMENTS_COUNT_IMPLICIT); if (type->type == HLSL_CLASS_ARRAY) return get_array_size(type->e.array.type) * type->e.array.elements_count; return 1; diff --git a/tests/hlsl-initializer-implicit-array.shader_test b/tests/hlsl-initializer-implicit-array.shader_test index d2b94da4..91b6f049 100644 --- a/tests/hlsl-initializer-implicit-array.shader_test +++ b/tests/hlsl-initializer-implicit-array.shader_test @@ -6,8 +6,8 @@ float4 main() : SV_TARGET }
[test] -todo draw quad -todo probe all rgba (50, 60, 70, 80) +draw quad +probe all rgba (50, 60, 70, 80)
[pixel shader fail]