From 891217664a41b7f24bd535c821978d8fb8650c48 Mon Sep 17 00:00:00 2001 From: Nikolay Sivov Date: Sun, 19 Feb 2023 01:44:20 +0100 Subject: [PATCH] vkd3d-shader/hlsl: Support case-insensitive lookup for builtin 'dword' type. --- Makefile.am | 1 + libs/vkd3d-shader/hlsl.c | 39 +++++++++++++++++++++++---- libs/vkd3d-shader/hlsl.h | 2 +- libs/vkd3d-shader/hlsl.l | 2 +- libs/vkd3d-shader/hlsl.y | 4 +-- tests/hlsl-type-names.shader_test | 44 +++++++++++++++++++++++++++++++ 6 files changed, 83 insertions(+), 9 deletions(-) create mode 100644 tests/hlsl-type-names.shader_test diff --git a/Makefile.am b/Makefile.am index ebda192d..29692432 100644 --- a/Makefile.am +++ b/Makefile.am @@ -115,6 +115,7 @@ vkd3d_shader_tests = \ tests/hlsl-struct-assignment.shader_test \ tests/hlsl-struct-semantics.shader_test \ tests/hlsl-transpose.shader_test \ + tests/hlsl-type-names.shader_test \ tests/hlsl-vector-indexing.shader_test \ tests/hlsl-vector-indexing-uniform.shader_test \ tests/lit.shader_test \ diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index 42a1d52f..2ed63043 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -604,15 +604,44 @@ struct hlsl_type *hlsl_new_uav_type(struct hlsl_ctx *ctx, enum hlsl_sampler_dim return type; } -struct hlsl_type *hlsl_get_type(struct hlsl_scope *scope, const char *name, bool recursive) +static const char * get_case_insensitive_typename(const char *name) +{ + static const char *const names[] = + { + "dword", + }; + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(names); ++i) + { + if (!ascii_strcasecmp(names[i], name)) + return names[i]; + } + + return NULL; +} + +struct hlsl_type *hlsl_get_type(struct hlsl_scope *scope, const char *name, bool recursive, bool case_insensitive) { struct rb_entry *entry = rb_get(&scope->types, name); if (entry) return RB_ENTRY_VALUE(entry, struct hlsl_type, scope_entry); - if (recursive && scope->upper) - return hlsl_get_type(scope->upper, name, recursive); + if (scope->upper) + { + if (recursive) + return hlsl_get_type(scope->upper, name, recursive, case_insensitive); + } + else + { + if (case_insensitive && (name = get_case_insensitive_typename(name))) + { + if ((entry = rb_get(&scope->types, name))) + return RB_ENTRY_VALUE(entry, struct hlsl_type, scope_entry); + } + } + return NULL; } @@ -807,7 +836,7 @@ struct hlsl_type *hlsl_type_clone(struct hlsl_ctx *ctx, struct hlsl_type *old, bool hlsl_scope_add_type(struct hlsl_scope *scope, struct hlsl_type *type) { - if (hlsl_get_type(scope, type->name, false)) + if (hlsl_get_type(scope, type->name, false, false)) return false; rb_put(&scope->types, type->name, &type->scope_entry); @@ -2808,7 +2837,7 @@ static void declare_predefined_types(struct hlsl_ctx *ctx) } effect_types[] = { - {"DWORD", HLSL_CLASS_SCALAR, HLSL_TYPE_INT, 1, 1}, + {"dword", HLSL_CLASS_SCALAR, HLSL_TYPE_INT, 1, 1}, {"FLOAT", HLSL_CLASS_SCALAR, HLSL_TYPE_FLOAT, 1, 1}, {"VECTOR", HLSL_CLASS_VECTOR, HLSL_TYPE_FLOAT, 4, 1}, {"MATRIX", HLSL_CLASS_MATRIX, HLSL_TYPE_FLOAT, 4, 4}, diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index 6fa627ed..62049e8d 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -1005,7 +1005,7 @@ void hlsl_free_var(struct hlsl_ir_var *decl); struct hlsl_ir_function *hlsl_get_function(struct hlsl_ctx *ctx, const char *name); struct hlsl_ir_function_decl *hlsl_get_func_decl(struct hlsl_ctx *ctx, const char *name); -struct hlsl_type *hlsl_get_type(struct hlsl_scope *scope, const char *name, bool recursive); +struct hlsl_type *hlsl_get_type(struct hlsl_scope *scope, const char *name, bool recursive, bool case_insensitive); struct hlsl_ir_var *hlsl_get_var(struct hlsl_scope *scope, const char *name); struct hlsl_type *hlsl_get_element_type_from_path_index(struct hlsl_ctx *ctx, const struct hlsl_type *type, diff --git a/libs/vkd3d-shader/hlsl.l b/libs/vkd3d-shader/hlsl.l index 69ed9d9d..59f31fcd 100644 --- a/libs/vkd3d-shader/hlsl.l +++ b/libs/vkd3d-shader/hlsl.l @@ -181,7 +181,7 @@ row_major {return KW_ROW_MAJOR; } yylval->name = hlsl_strdup(ctx, yytext); if (hlsl_get_var(ctx->cur_scope, yytext) || hlsl_get_function(ctx, yytext)) return VAR_IDENTIFIER; - else if (hlsl_get_type(ctx->cur_scope, yytext, true)) + else if (hlsl_get_type(ctx->cur_scope, yytext, true, true)) return TYPE_IDENTIFIER; else return NEW_IDENTIFIER; diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index 6c618912..4b26a179 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -4711,7 +4711,7 @@ type_no_void: } | TYPE_IDENTIFIER { - $$ = hlsl_get_type(ctx->cur_scope, $1, true); + $$ = hlsl_get_type(ctx->cur_scope, $1, true, true); if ($$->is_minimum_precision) { if (ctx->profile->major_version < 4) @@ -4728,7 +4728,7 @@ type_no_void: } | KW_STRUCT TYPE_IDENTIFIER { - $$ = hlsl_get_type(ctx->cur_scope, $2, true); + $$ = hlsl_get_type(ctx->cur_scope, $2, true, true); if ($$->type != HLSL_CLASS_STRUCT) hlsl_error(ctx, &@1, VKD3D_SHADER_ERROR_HLSL_REDEFINED, "\"%s\" redefined as a structure.", $2); vkd3d_free($2); diff --git a/tests/hlsl-type-names.shader_test b/tests/hlsl-type-names.shader_test new file mode 100644 index 00000000..f90ea587 --- /dev/null +++ b/tests/hlsl-type-names.shader_test @@ -0,0 +1,44 @@ +[pixel shader] +typedef float2 Dword; +typedef float3 dWord; + +float4 f() +{ + typedef Dword dword; + dword v1 = {1, 2}; + DWORD v4 = 4; + return float4(v1.x, v1.y, 3, v4); +} + +float4 f2() +{ + typedef dword dword; + dword v = 1; + return float4(v, v, v, v); +} + +float4 main() : SV_TARGET +{ + return f() + f2(); +} + +[test] +draw quad +probe all rgba (2.0, 3.0, 4.0, 5.0) + +% The "dword" alias is pre-defined as lowercase +[pixel shader fail] +typedef float2 dword; + +float4 main() : sv_target +{ + return float4(0, 0, 0, 0); +} + +[pixel shader fail] +struct DWORD s; + +float4 main() : sv_target +{ + return float4(0, 0, 0, 0); +}