From: Nikolay Sivov nsivov@codeweavers.com
--- 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 c8812892..fb5c7a99 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 d6a87b3f..42a7d21b 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -542,15 +542,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; }
@@ -745,7 +774,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); @@ -2746,7 +2775,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 0183f702..2c0530d6 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -999,7 +999,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 e0e0e5ce..6d388cb8 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -4643,7 +4643,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) @@ -4660,7 +4660,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..b9be6af4 --- /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(v.x, v.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); +}