-- v2: vkd3d-shader/hlsl: Allow case-insenstive names for shader objects types. vkd3d-shader/hlsl: Initial support for string constants. vkd3d-shader/hlsl: Use unsigned type for "dword" alias. vkd3d-shader/hlsl: Support case-insensitive lookup for selected builtin types.
From: Nikolay Sivov nsivov@codeweavers.com
--- Makefile.am | 1 + libs/vkd3d-shader/hlsl.c | 33 ++++++++++++++++++++++++++----- tests/hlsl-type-names.shader_test | 19 ++++++++++++++++++ 3 files changed, 48 insertions(+), 5 deletions(-) create mode 100644 tests/hlsl-type-names.shader_test
diff --git a/Makefile.am b/Makefile.am index f9199472..9080d907 100644 --- a/Makefile.am +++ b/Makefile.am @@ -113,6 +113,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/logic-operations.shader_test \ diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index 5dbdaf7e..b77f3d6b 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -542,6 +542,24 @@ struct hlsl_type *hlsl_new_uav_type(struct hlsl_ctx *ctx, enum hlsl_sampler_dim return type; }
+static const char * get_case_insensitive_typename(const char *name) +{ + static const char *const names[] = + { + "dword", + "float", + "matrix", + "string", + "vector", + }; + 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) { struct rb_entry *entry = rb_get(&scope->types, name); @@ -549,6 +567,12 @@ struct hlsl_type *hlsl_get_type(struct hlsl_scope *scope, const char *name, bool if (entry) return RB_ENTRY_VALUE(entry, struct hlsl_type, scope_entry);
+ if (!scope->upper && (name = get_case_insensitive_typename(name))) + { + if ((entry = rb_get(&scope->types, name))) + return RB_ENTRY_VALUE(entry, struct hlsl_type, scope_entry); + } + if (recursive && scope->upper) return hlsl_get_type(scope->upper, name, recursive); return NULL; @@ -2743,11 +2767,10 @@ static void declare_predefined_types(struct hlsl_ctx *ctx) } effect_types[] = { - {"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}, - {"STRING", HLSL_CLASS_OBJECT, HLSL_TYPE_STRING, 1, 1}, + {"dword", HLSL_CLASS_SCALAR, HLSL_TYPE_INT, 1, 1}, + {"vector", HLSL_CLASS_VECTOR, HLSL_TYPE_FLOAT, 4, 1}, + {"matrix", HLSL_CLASS_MATRIX, HLSL_TYPE_FLOAT, 4, 4}, + {"string", HLSL_CLASS_OBJECT, HLSL_TYPE_STRING, 1, 1}, {"TEXTURE", HLSL_CLASS_OBJECT, HLSL_TYPE_TEXTURE, 1, 1}, {"PIXELSHADER", HLSL_CLASS_OBJECT, HLSL_TYPE_PIXELSHADER, 1, 1}, {"VERTEXSHADER", HLSL_CLASS_OBJECT, HLSL_TYPE_VERTEXSHADER, 1, 1}, diff --git a/tests/hlsl-type-names.shader_test b/tests/hlsl-type-names.shader_test new file mode 100644 index 00000000..f6506f6e --- /dev/null +++ b/tests/hlsl-type-names.shader_test @@ -0,0 +1,19 @@ +[pixel shader] +float4 main() : sv_target +{ + vector<fLoat, 4> f1 = {1.0, 2.0, 3.0, 4.0}; + flOat f2 = 5.0; + dWord d = 6; + MaTrix m = { + 0.0, 7.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, + }; + Vector v; + return float4(f1.x, m._12, d, f2); +} + +[test] +draw quad +probe all rgba (1.0, 7.0, 6.0, 5.0)
From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- libs/vkd3d-shader/hlsl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index b77f3d6b..84aeda7c 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -2767,7 +2767,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_UINT, 1, 1}, {"vector", HLSL_CLASS_VECTOR, HLSL_TYPE_FLOAT, 4, 1}, {"matrix", HLSL_CLASS_MATRIX, HLSL_TYPE_FLOAT, 4, 4}, {"string", HLSL_CLASS_OBJECT, HLSL_TYPE_STRING, 1, 1},
From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- libs/vkd3d-shader/hlsl.c | 20 +++++++++++++++++++- libs/vkd3d-shader/hlsl.h | 3 +++ libs/vkd3d-shader/hlsl.l | 7 ++++++- libs/vkd3d-shader/hlsl.y | 16 +++++++++++++++- 4 files changed, 43 insertions(+), 3 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index 84aeda7c..6100d508 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -978,7 +978,8 @@ struct hlsl_ir_constant *hlsl_new_constant(struct hlsl_ctx *ctx, struct hlsl_typ { struct hlsl_ir_constant *c;
- assert(type->type <= HLSL_CLASS_VECTOR); + assert(type->type <= HLSL_CLASS_VECTOR + || (type->type == HLSL_CLASS_OBJECT && type->base_type == HLSL_TYPE_STRING));
if (!(c = hlsl_alloc(ctx, sizeof(*c)))) return NULL; @@ -1035,6 +1036,19 @@ struct hlsl_ir_constant *hlsl_new_uint_constant(struct hlsl_ctx *ctx, unsigned i return c; }
+struct hlsl_ir_constant *hlsl_new_string_constant(struct hlsl_ctx *ctx, const char *s, + const struct vkd3d_shader_location *loc) +{ + struct hlsl_ir_constant *c; + + c = hlsl_new_constant(ctx, hlsl_get_type(ctx->globals, "string", false), loc); + + if (c) + c->value[0].s = s; + + return c; +} + struct hlsl_ir_node *hlsl_new_expr(struct hlsl_ctx *ctx, enum hlsl_ir_expr_op op, struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS], struct hlsl_type *data_type, const struct vkd3d_shader_location *loc) @@ -2060,6 +2074,10 @@ static void dump_ir_constant(struct vkd3d_string_buffer *buffer, const struct hl vkd3d_string_buffer_printf(buffer, "%u ", value->u); break;
+ case HLSL_TYPE_STRING: + vkd3d_string_buffer_printf(buffer, "%s ", value->s); + break; + default: vkd3d_unreachable(); } diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index 81b1a61d..b754a4c6 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -611,6 +611,7 @@ struct hlsl_ir_constant int32_t i; float f; double d; + const char *s; } value[4]; /* Constant register of type 'c' where the constant value is stored for SM1. */ struct hlsl_reg reg; @@ -1051,6 +1052,8 @@ struct hlsl_ir_resource_load *hlsl_new_resource_load(struct hlsl_ctx *ctx, const struct hlsl_resource_load_params *params, const struct vkd3d_shader_location *loc); struct hlsl_ir_resource_store *hlsl_new_resource_store(struct hlsl_ctx *ctx, const struct hlsl_deref *resource, struct hlsl_ir_node *coords, struct hlsl_ir_node *value, const struct vkd3d_shader_location *loc); +struct hlsl_ir_constant *hlsl_new_string_constant(struct hlsl_ctx *ctx, const char *s, + const struct vkd3d_shader_location *loc); struct hlsl_type *hlsl_new_struct_type(struct hlsl_ctx *ctx, const char *name, struct hlsl_struct_field *fields, size_t field_count); struct hlsl_ir_swizzle *hlsl_new_swizzle(struct hlsl_ctx *ctx, DWORD s, unsigned int components, diff --git a/libs/vkd3d-shader/hlsl.l b/libs/vkd3d-shader/hlsl.l index 69ed9d9d..00a33e8a 100644 --- a/libs/vkd3d-shader/hlsl.l +++ b/libs/vkd3d-shader/hlsl.l @@ -117,7 +117,6 @@ shared {return KW_SHARED; } stateblock {return KW_STATEBLOCK; } stateblock_state {return KW_STATEBLOCK_STATE; } static {return KW_STATIC; } -string {return KW_STRING; } struct {return KW_STRUCT; } switch {return KW_SWITCH; } tbuffer {return KW_TBUFFER; } @@ -212,6 +211,12 @@ row_major {return KW_ROW_MAJOR; } return C_INTEGER; }
+"([^\"]|\.)*" { + struct hlsl_ctx *ctx = yyget_extra(yyscanner); + yylval->strval = hlsl_strdup(ctx, yytext); + return C_STRING; + } + {DOUBLESLASHCOMMENT} {}
{WS}+ {} diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index 76b0eae7..06fba41b 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -3509,6 +3509,7 @@ static bool add_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hl INT intval; FLOAT floatval; bool boolval; + char *strval; char *name; DWORD modifiers; struct hlsl_ir_node *instr; @@ -3580,7 +3581,6 @@ static bool add_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hl %token KW_STATEBLOCK %token KW_STATEBLOCK_STATE %token KW_STATIC -%token KW_STRING %token KW_STRUCT %token KW_SWITCH %token KW_TBUFFER @@ -3636,6 +3636,8 @@ static bool add_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hl %token <intval> C_INTEGER %token <intval> PRE_LINE
+%token <strval> C_STRING + %type <list> add_expr %type <list> assignment_expr %type <list> bitand_expr @@ -4952,6 +4954,18 @@ primary_expr: YYABORT; } } + | C_STRING + { + struct hlsl_ir_constant *c; + + if (!(c = hlsl_new_string_constant(ctx, $1, &@1))) + YYABORT; + if (!($$ = make_list(ctx, &c->node))) + { + hlsl_free_instr(&c->node); + YYABORT; + } + } | VAR_IDENTIFIER { struct hlsl_ir_load *load;
From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- libs/vkd3d-shader/hlsl.c | 6 ++++-- tests/hlsl-type-names.shader_test | 4 ++++ 2 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index 6100d508..cde6637d 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -549,8 +549,10 @@ static const char * get_case_insensitive_typename(const char *name) "dword", "float", "matrix", + "pixelshader", "string", "vector", + "vertexshader", }; unsigned int i;
@@ -2790,8 +2792,8 @@ static void declare_predefined_types(struct hlsl_ctx *ctx) {"matrix", HLSL_CLASS_MATRIX, HLSL_TYPE_FLOAT, 4, 4}, {"string", HLSL_CLASS_OBJECT, HLSL_TYPE_STRING, 1, 1}, {"TEXTURE", HLSL_CLASS_OBJECT, HLSL_TYPE_TEXTURE, 1, 1}, - {"PIXELSHADER", HLSL_CLASS_OBJECT, HLSL_TYPE_PIXELSHADER, 1, 1}, - {"VERTEXSHADER", HLSL_CLASS_OBJECT, HLSL_TYPE_VERTEXSHADER, 1, 1}, + {"pixelshader", HLSL_CLASS_OBJECT, HLSL_TYPE_PIXELSHADER, 1, 1}, + {"vertexshader", HLSL_CLASS_OBJECT, HLSL_TYPE_VERTEXSHADER, 1, 1}, };
for (bt = 0; bt <= HLSL_TYPE_LAST_SCALAR; ++bt) diff --git a/tests/hlsl-type-names.shader_test b/tests/hlsl-type-names.shader_test index f6506f6e..797baf8e 100644 --- a/tests/hlsl-type-names.shader_test +++ b/tests/hlsl-type-names.shader_test @@ -1,4 +1,8 @@ [pixel shader] + +verteXshader vs; +pixelShader ps; + float4 main() : sv_target { vector<fLoat, 4> f1 = {1.0, 2.0, 3.0, 4.0};
On Mon Feb 20 20:24:33 2023 +0000, Henri Verbeet wrote:
From patch 1/4:
+static const char * get_case_insensitive_typename(const char *name) +{ + static const char *names[] = + { + "dword", + "float", + "matrix", + "string", + "vector", + };
We'd want the names[] array itself to be const as well, right? (I.e., "static const char *const names[] = ...")
Right, pushed that.
I don't think this approach is quite going to work. Consider the following shader:
typedef float2 Dword;
float4 main() : sv_target { DWORD f = 1.0; return f; }
It seems that redefining these types is legal (although it doesn't seem to be legal to redefine lowercase "dword" as a type?). E.g. that shader compiles as-is, but if the first line is changed to "DWORD" it will predictably fail (float2 to float4 implicit conversion).
It also seems that at least "vector" and "string" should be case-insensitive keywords rather than typedefs. That's mostly out of scope here, but it does mean that patch 3/4 is going in the wrong direction.
From patch 3/4:
@@ -3509,6 +3509,7 @@ static bool add_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hl INT intval; FLOAT floatval; bool boolval;
- char *strval; char *name; DWORD modifiers; struct hlsl_ir_node *instr;
I'd just rename "name" rather than adding a new union value.
@@ -611,6 +611,7 @@ struct hlsl_ir_constant int32_t i; float f; double d;
} value[4];const char *s;
This is going to need special handling when the constant is cloned or freed.
Yes, looks like it's more convoluted. "vector" and "string" are lowercase tokens that can't be used for variable names for instance. Doing "float2 sTring;" is valid, but "sTring" can't be used as a type after that. Reusing names of already declared variables as typenames is universally disallowed, so that's good.