[PATCH vkd3d 5/6] vkd3d-shader: Parse the semantic index in hlsl_parse().

Zebediah Figura zfigura at codeweavers.com
Tue Apr 20 23:29:00 CDT 2021


Signed-off-by: Zebediah Figura <zfigura at codeweavers.com>
---
 libs/vkd3d-shader/hlsl.c         | 28 +++++++++--------
 libs/vkd3d-shader/hlsl.h         | 15 ++++++---
 libs/vkd3d-shader/hlsl.y         | 34 +++++++++++++--------
 libs/vkd3d-shader/hlsl_codegen.c | 52 +++++++++++++++++++++-----------
 4 files changed, 83 insertions(+), 46 deletions(-)

diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c
index b48bd250..19b676bd 100644
--- a/libs/vkd3d-shader/hlsl.c
+++ b/libs/vkd3d-shader/hlsl.c
@@ -93,7 +93,7 @@ struct hlsl_ir_var *hlsl_get_var(struct hlsl_scope *scope, const char *name)
 void hlsl_free_var(struct hlsl_ir_var *decl)
 {
     vkd3d_free((void *)decl->name);
-    vkd3d_free((void *)decl->semantic);
+    vkd3d_free((void *)decl->semantic.name);
     vkd3d_free((void *)decl->reg_reservation);
     vkd3d_free(decl);
 }
@@ -326,7 +326,7 @@ struct hlsl_type *hlsl_type_clone(struct hlsl_ctx *ctx, struct hlsl_type *old, u
                 {
                     LIST_FOR_EACH_ENTRY_SAFE(field, old_field, type->e.elements, struct hlsl_struct_field, entry)
                     {
-                        vkd3d_free((void *)field->semantic);
+                        vkd3d_free((void *)field->semantic.name);
                         vkd3d_free((void *)field->name);
                         vkd3d_free(field);
                     }
@@ -338,8 +338,11 @@ struct hlsl_type *hlsl_type_clone(struct hlsl_ctx *ctx, struct hlsl_type *old, u
                 field->loc = old_field->loc;
                 field->type = hlsl_type_clone(ctx, old_field->type, default_majority);
                 field->name = vkd3d_strdup(old_field->name);
-                if (old_field->semantic)
-                    field->semantic = vkd3d_strdup(old_field->semantic);
+                if (old_field->semantic.name)
+                {
+                    field->semantic.name = vkd3d_strdup(old_field->semantic.name);
+                    field->semantic.index = old_field->semantic.index;
+                }
                 field->reg_offset = reg_size;
                 reg_size += field->type->reg_size;
                 list_add_tail(type->e.elements, &field->entry);
@@ -388,7 +391,7 @@ struct hlsl_ir_expr *hlsl_new_copy(struct hlsl_ir_node *node)
 }
 
 struct hlsl_ir_var *hlsl_new_var(const char *name, struct hlsl_type *type, const struct vkd3d_shader_location loc,
-        const char *semantic, const struct hlsl_reg_reservation *reg_reservation)
+        const struct hlsl_semantic *semantic, const struct hlsl_reg_reservation *reg_reservation)
 {
     struct hlsl_ir_var *var;
 
@@ -398,7 +401,8 @@ struct hlsl_ir_var *hlsl_new_var(const char *name, struct hlsl_type *type, const
     var->name = name;
     var->data_type = type;
     var->loc = loc;
-    var->semantic = semantic;
+    if (semantic)
+        var->semantic = *semantic;
     var->reg_reservation = reg_reservation;
     return var;
 }
@@ -555,7 +559,7 @@ bool hlsl_type_is_void(const struct hlsl_type *type)
 }
 
 struct hlsl_ir_function_decl *hlsl_new_func_decl(struct hlsl_ctx *ctx, struct hlsl_type *return_type,
-        struct list *parameters, const char *semantic, struct vkd3d_shader_location loc)
+        struct list *parameters, const struct hlsl_semantic *semantic, struct vkd3d_shader_location loc)
 {
     struct hlsl_ir_function_decl *decl;
 
@@ -876,8 +880,8 @@ static void dump_ir_var(struct vkd3d_string_buffer *buffer, const struct hlsl_ir
     if (var->is_uniform)
         vkd3d_string_buffer_printf(buffer, "uniform ");
     vkd3d_string_buffer_printf(buffer, "%s %s", debug_hlsl_type(var->data_type), var->name);
-    if (var->semantic)
-        vkd3d_string_buffer_printf(buffer, " : %s", var->semantic);
+    if (var->semantic.name)
+        vkd3d_string_buffer_printf(buffer, " : %s%u", var->semantic.name, var->semantic.index);
 }
 
 static void dump_deref(struct vkd3d_string_buffer *buffer, const struct hlsl_deref *deref)
@@ -1179,7 +1183,7 @@ void hlsl_free_type(struct hlsl_type *type)
         LIST_FOR_EACH_ENTRY_SAFE(field, next_field, type->e.elements, struct hlsl_struct_field, entry)
         {
             vkd3d_free((void *)field->name);
-            vkd3d_free((void *)field->semantic);
+            vkd3d_free((void *)field->semantic.name);
             vkd3d_free(field);
         }
     }
@@ -1662,14 +1666,14 @@ int hlsl_compile_shader(const struct vkd3d_shader_code *hlsl, const struct vkd3d
 
     LIST_FOR_EACH_ENTRY(var, entry_func->parameters, struct hlsl_ir_var, param_entry)
     {
-        if (var->data_type->type != HLSL_CLASS_STRUCT && !var->semantic
+        if (var->data_type->type != HLSL_CLASS_STRUCT && !var->semantic.name
                 && (var->is_input_varying || var->is_output_varying))
             hlsl_error(&ctx, var->loc, VKD3D_SHADER_ERROR_HLSL_MISSING_SEMANTIC,
                     "Parameter \"%s\" is missing a semantic.", var->name);
     }
 
     if (!hlsl_type_is_void(entry_func->return_type)
-            && entry_func->return_type->type != HLSL_CLASS_STRUCT && !entry_func->return_var->semantic)
+            && entry_func->return_type->type != HLSL_CLASS_STRUCT && !entry_func->return_var->semantic.name)
         hlsl_error(&ctx, entry_func->loc, VKD3D_SHADER_ERROR_HLSL_MISSING_SEMANTIC,
                 "Entry point \"%s\" is missing a return value semantic.", entry_point);
 
diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h
index 0c755f46..b77ee078 100644
--- a/libs/vkd3d-shader/hlsl.h
+++ b/libs/vkd3d-shader/hlsl.h
@@ -129,13 +129,19 @@ struct hlsl_type
     unsigned int bytecode_offset;
 };
 
+struct hlsl_semantic
+{
+    const char *name;
+    uint32_t index;
+};
+
 struct hlsl_struct_field
 {
     struct list entry;
     struct vkd3d_shader_location loc;
     struct hlsl_type *type;
     const char *name;
-    const char *semantic;
+    struct hlsl_semantic semantic;
     unsigned int reg_offset;
 
     unsigned int name_bytecode_offset;
@@ -215,7 +221,7 @@ struct hlsl_ir_var
     struct hlsl_type *data_type;
     struct vkd3d_shader_location loc;
     const char *name;
-    const char *semantic;
+    struct hlsl_semantic semantic;
     const struct hlsl_reg_reservation *reg_reservation;
     struct list scope_entry, param_entry, extern_entry;
 
@@ -557,7 +563,8 @@ struct hlsl_ir_expr *hlsl_new_cast(struct hlsl_ir_node *node, struct hlsl_type *
         struct vkd3d_shader_location *loc) DECLSPEC_HIDDEN;
 struct hlsl_ir_expr *hlsl_new_copy(struct hlsl_ir_node *node) DECLSPEC_HIDDEN;
 struct hlsl_ir_function_decl *hlsl_new_func_decl(struct hlsl_ctx *ctx, struct hlsl_type *return_type,
-        struct list *parameters, const char *semantic, struct vkd3d_shader_location loc) DECLSPEC_HIDDEN;
+        struct list *parameters, const struct hlsl_semantic *semantic,
+        struct vkd3d_shader_location loc) DECLSPEC_HIDDEN;
 struct hlsl_ir_if *hlsl_new_if(struct hlsl_ir_node *condition, struct vkd3d_shader_location loc) DECLSPEC_HIDDEN;
 struct hlsl_ir_jump *hlsl_new_jump(enum hlsl_ir_jump_type type, struct vkd3d_shader_location loc) DECLSPEC_HIDDEN;
 struct hlsl_ir_load *hlsl_new_load(struct hlsl_ir_var *var, struct hlsl_ir_node *offset, struct hlsl_type *type,
@@ -579,7 +586,7 @@ struct hlsl_ir_constant *hlsl_new_uint_constant(struct hlsl_ctx *ctx, unsigned i
 struct hlsl_ir_node *hlsl_new_unary_expr(enum hlsl_ir_expr_op op, struct hlsl_ir_node *arg,
         struct vkd3d_shader_location loc) DECLSPEC_HIDDEN;
 struct hlsl_ir_var *hlsl_new_var(const char *name, struct hlsl_type *type, const struct vkd3d_shader_location loc,
-        const char *semantic, const struct hlsl_reg_reservation *reg_reservation) DECLSPEC_HIDDEN;
+        const struct hlsl_semantic *semantic, const struct hlsl_reg_reservation *reg_reservation) DECLSPEC_HIDDEN;
 struct hlsl_ir_load *hlsl_new_var_load(struct hlsl_ir_var *var, const struct vkd3d_shader_location loc) DECLSPEC_HIDDEN;
 
 void hlsl_error(struct hlsl_ctx *ctx, const struct vkd3d_shader_location loc, enum vkd3d_shader_error error,
diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y
index 8cd80533..893bad9a 100644
--- a/libs/vkd3d-shader/hlsl.y
+++ b/libs/vkd3d-shader/hlsl.y
@@ -32,14 +32,14 @@ struct parse_parameter
 {
     struct hlsl_type *type;
     const char *name;
-    const char *semantic;
+    struct hlsl_semantic semantic;
     const struct hlsl_reg_reservation *reg_reservation;
     unsigned int modifiers;
 };
 
 struct parse_colon_attribute
 {
-    const char *semantic;
+    struct hlsl_semantic semantic;
     struct hlsl_reg_reservation *reg_reservation;
 };
 
@@ -63,7 +63,7 @@ struct parse_variable_def
 
     char *name;
     struct parse_array_sizes arrays;
-    const char *semantic;
+    struct hlsl_semantic semantic;
     struct hlsl_reg_reservation *reg_reservation;
     struct parse_initializer initializer;
 };
@@ -763,7 +763,7 @@ static bool add_func_parameter(struct hlsl_ctx *ctx, struct list *list,
     if (param->type->type == HLSL_CLASS_MATRIX)
         assert(param->type->modifiers & HLSL_MODIFIERS_MAJORITY_MASK);
 
-    if (!(var = hlsl_new_var(param->name, param->type, loc, param->semantic, param->reg_reservation)))
+    if (!(var = hlsl_new_var(param->name, param->type, loc, &param->semantic, param->reg_reservation)))
         return false;
     var->is_param = 1;
 
@@ -1384,7 +1384,7 @@ static void free_parse_variable_def(struct parse_variable_def *v)
     free_parse_initializer(&v->initializer);
     vkd3d_free(v->arrays.sizes);
     vkd3d_free(v->name);
-    vkd3d_free((void *)v->semantic);
+    vkd3d_free((void *)v->semantic.name);
     vkd3d_free(v->reg_reservation);
     vkd3d_free(v);
 }
@@ -1424,7 +1424,7 @@ static struct list *declare_vars(struct hlsl_ctx *ctx, struct hlsl_type *basic_t
         if (type->type != HLSL_CLASS_MATRIX)
             check_invalid_matrix_modifiers(ctx, modifiers, v->loc);
 
-        if (!(var = hlsl_new_var(v->name, type, v->loc, v->semantic, v->reg_reservation)))
+        if (!(var = hlsl_new_var(v->name, type, v->loc, &v->semantic, v->reg_reservation)))
         {
             free_parse_variable_def(v);
             continue;
@@ -1459,7 +1459,7 @@ static struct list *declare_vars(struct hlsl_ctx *ctx, struct hlsl_type *basic_t
                             "Modifiers '%s' are not allowed on local variables.", string->buffer);
                 vkd3d_string_buffer_release(&ctx->string_buffers, string);
             }
-            if (var->semantic)
+            if (var->semantic.name)
                 hlsl_error(ctx, var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_SEMANTIC,
                         "Semantics are not allowed on local variables.");
         }
@@ -1590,6 +1590,7 @@ static struct list *declare_vars(struct hlsl_ctx *ctx, struct hlsl_type *basic_t
     enum parse_assign_op assign_op;
     struct hlsl_reg_reservation *reg_reservation;
     struct parse_colon_attribute colon_attribute;
+    struct hlsl_semantic semantic;
 }
 
 %token KW_BLENDSTATE
@@ -1755,13 +1756,14 @@ static struct list *declare_vars(struct hlsl_ctx *ctx, struct hlsl_type *basic_t
 %type <modifiers> var_modifiers
 
 %type <name> any_identifier
-%type <name> semantic
 %type <name> var_identifier
 
 %type <parameter> parameter
 
 %type <reg_reservation> register_opt
 
+%type <semantic> semantic
+
 %type <type> base_type
 %type <type> field_type
 %type <type> named_struct_spec
@@ -1978,7 +1980,7 @@ func_prototype:
                         "\"%s\" was previously declared here.", $3);
                 YYABORT;
             }
-            if (hlsl_type_is_void($2) && $7.semantic)
+            if (hlsl_type_is_void($2) && $7.semantic.name)
             {
                 hlsl_error(ctx, @7, VKD3D_SHADER_ERROR_HLSL_INVALID_SEMANTIC,
                         "Semantics are not allowed on void functions.");
@@ -1989,7 +1991,7 @@ func_prototype:
                 FIXME("Unexpected register reservation for a function.\n");
                 vkd3d_free($7.reg_reservation);
             }
-            if (!($$.decl = hlsl_new_func_decl(ctx, $2, $5, $7.semantic, @3)))
+            if (!($$.decl = hlsl_new_func_decl(ctx, $2, $5, &$7.semantic, @3)))
                 YYABORT;
             $$.name = $3;
             ctx->cur_function = $$.decl;
@@ -2020,7 +2022,7 @@ var_identifier:
 colon_attribute:
       %empty
         {
-            $$.semantic = NULL;
+            $$.semantic.name = NULL;
             $$.reg_reservation = NULL;
         }
     | semantic
@@ -2030,14 +2032,20 @@ colon_attribute:
         }
     | register_opt
         {
-            $$.semantic = NULL;
+            $$.semantic.name = NULL;
             $$.reg_reservation = $1;
         }
 
 semantic:
       ':' any_identifier
         {
-            $$ = $2;
+            char *p;
+
+            for (p = $2 + strlen($2); p > $2 && isdigit(p[-1]); --p)
+                ;
+            $$.name = $2;
+            $$.index = atoi(p);
+            *p = 0;
         }
 
 /* FIXME: Writemasks */
diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c
index 21ebcfc2..b1faa8a0 100644
--- a/libs/vkd3d-shader/hlsl_codegen.c
+++ b/libs/vkd3d-shader/hlsl_codegen.c
@@ -71,9 +71,10 @@ static void prepend_uniform_copy(struct hlsl_ctx *ctx, struct list *instrs, stru
 }
 
 static void prepend_input_copy(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_var *var,
-        struct hlsl_type *type, unsigned int field_offset, const char *semantic)
+        struct hlsl_type *type, unsigned int field_offset, const struct hlsl_semantic *semantic)
 {
     struct vkd3d_string_buffer *name;
+    struct hlsl_semantic new_semantic;
     struct hlsl_ir_constant *offset;
     struct hlsl_ir_store *store;
     struct hlsl_ir_var *varying;
@@ -84,13 +85,21 @@ static void prepend_input_copy(struct hlsl_ctx *ctx, struct list *instrs, struct
         ctx->failed = true;
         return;
     }
-    vkd3d_string_buffer_printf(name, "<input-%s>", semantic);
-    if (!(varying = hlsl_new_var(vkd3d_strdup(name->buffer), type, var->loc, vkd3d_strdup(semantic), NULL)))
+    vkd3d_string_buffer_printf(name, "<input-%s%u>", semantic->name, semantic->index);
+    if (!(new_semantic.name = vkd3d_strdup(semantic->name)))
     {
         vkd3d_string_buffer_release(&ctx->string_buffers, name);
         ctx->failed = true;
         return;
     }
+    new_semantic.index = semantic->index;
+    if (!(varying = hlsl_new_var(vkd3d_strdup(name->buffer), type, var->loc, &new_semantic, NULL)))
+    {
+        vkd3d_string_buffer_release(&ctx->string_buffers, name);
+        vkd3d_free((void *)new_semantic.name);
+        ctx->failed = true;
+        return;
+    }
     vkd3d_string_buffer_release(&ctx->string_buffers, name);
     varying->is_input_varying = 1;
     varying->is_param = var->is_param;
@@ -128,8 +137,8 @@ static void prepend_input_struct_copy(struct hlsl_ctx *ctx, struct list *instrs,
     {
         if (field->type->type == HLSL_CLASS_STRUCT)
             prepend_input_struct_copy(ctx, instrs, var, field->type, field_offset + field->reg_offset);
-        else if (field->semantic)
-            prepend_input_copy(ctx, instrs, var, field->type, field_offset + field->reg_offset, field->semantic);
+        else if (field->semantic.name)
+            prepend_input_copy(ctx, instrs, var, field->type, field_offset + field->reg_offset, &field->semantic);
         else
             hlsl_error(ctx, field->loc, VKD3D_SHADER_ERROR_HLSL_MISSING_SEMANTIC,
                     "Field '%s' is missing a semantic.", field->name);
@@ -143,16 +152,17 @@ static void prepend_input_var_copy(struct hlsl_ctx *ctx, struct list *instrs, st
 {
     if (var->data_type->type == HLSL_CLASS_STRUCT)
         prepend_input_struct_copy(ctx, instrs, var, var->data_type, 0);
-    else if (var->semantic)
-        prepend_input_copy(ctx, instrs, var, var->data_type, 0, var->semantic);
+    else if (var->semantic.name)
+        prepend_input_copy(ctx, instrs, var, var->data_type, 0, &var->semantic);
 
     var->is_input_varying = 0;
 }
 
 static void append_output_copy(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_var *var,
-        struct hlsl_type *type, unsigned int field_offset, const char *semantic)
+        struct hlsl_type *type, unsigned int field_offset, const struct hlsl_semantic *semantic)
 {
     struct vkd3d_string_buffer *name;
+    struct hlsl_semantic new_semantic;
     struct hlsl_ir_constant *offset;
     struct hlsl_ir_store *store;
     struct hlsl_ir_var *varying;
@@ -163,9 +173,17 @@ static void append_output_copy(struct hlsl_ctx *ctx, struct list *instrs, struct
         ctx->failed = true;
         return;
     }
-    vkd3d_string_buffer_printf(name, "<output-%s>", semantic);
-    if (!(varying = hlsl_new_var(vkd3d_strdup(name->buffer), type, var->loc, vkd3d_strdup(semantic), NULL)))
+    vkd3d_string_buffer_printf(name, "<output-%s%u>", semantic->name, semantic->index);
+    if (!(new_semantic.name = vkd3d_strdup(semantic->name)))
+    {
+        vkd3d_string_buffer_release(&ctx->string_buffers, name);
+        ctx->failed = true;
+        return;
+    }
+    new_semantic.index = semantic->index;
+    if (!(varying = hlsl_new_var(vkd3d_strdup(name->buffer), type, var->loc, &new_semantic, NULL)))
     {
+        vkd3d_free((void *)new_semantic.name);
         vkd3d_string_buffer_release(&ctx->string_buffers, name);
         ctx->failed = true;
         return;
@@ -207,8 +225,8 @@ static void append_output_struct_copy(struct hlsl_ctx *ctx, struct list *instrs,
     {
         if (field->type->type == HLSL_CLASS_STRUCT)
             append_output_struct_copy(ctx, instrs, var, field->type, field_offset + field->reg_offset);
-        else if (field->semantic)
-            append_output_copy(ctx, instrs, var, field->type, field_offset + field->reg_offset, field->semantic);
+        else if (field->semantic.name)
+            append_output_copy(ctx, instrs, var, field->type, field_offset + field->reg_offset, &field->semantic);
         else
             hlsl_error(ctx, field->loc, VKD3D_SHADER_ERROR_HLSL_MISSING_SEMANTIC,
                     "Field '%s' is missing a semantic.", field->name);
@@ -222,8 +240,8 @@ static void append_output_var_copy(struct hlsl_ctx *ctx, struct list *instrs, st
 {
     if (var->data_type->type == HLSL_CLASS_STRUCT)
         append_output_struct_copy(ctx, instrs, var, var->data_type, 0);
-    else if (var->semantic)
-        append_output_copy(ctx, instrs, var, var->data_type, 0, var->semantic);
+    else if (var->semantic.name)
+        append_output_copy(ctx, instrs, var, var->data_type, 0, &var->semantic);
 
     var->is_output_varying = 0;
 }
@@ -1186,7 +1204,7 @@ static void write_sm1_uniforms(struct hlsl_ctx *ctx, struct bytecode_buffer *buf
 
     LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry)
     {
-        if (!var->semantic && var->reg.allocated)
+        if (!var->semantic.name && var->reg.allocated)
         {
             ++uniform_count;
 
@@ -1224,7 +1242,7 @@ static void write_sm1_uniforms(struct hlsl_ctx *ctx, struct bytecode_buffer *buf
 
     LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry)
     {
-        if (!var->semantic && var->reg.allocated)
+        if (!var->semantic.name && var->reg.allocated)
         {
             put_dword(buffer, 0); /* name */
             put_dword(buffer, D3DXRS_FLOAT4 | (var->reg.id << 16));
@@ -1238,7 +1256,7 @@ static void write_sm1_uniforms(struct hlsl_ctx *ctx, struct bytecode_buffer *buf
 
     LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry)
     {
-        if (!var->semantic && var->reg.allocated)
+        if (!var->semantic.name && var->reg.allocated)
         {
             set_dword(buffer, vars_start + (uniform_count * 5), (buffer->count - ctab_start) * sizeof(*buffer->data));
             put_string(buffer, var->name);
-- 
2.31.1




More information about the wine-devel mailing list