This allows us to more easily manipulate individual elements in a type-agnostic way. For example, it allows easier implementation of constant swizzle folding.
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- libs/vkd3d-shader/hlsl.c | 14 ++++++++------ libs/vkd3d-shader/hlsl.h | 14 +++++++------- libs/vkd3d-shader/hlsl.y | 17 +++++++++-------- libs/vkd3d-shader/hlsl_codegen.c | 22 ++++++++++++---------- libs/vkd3d-shader/hlsl_sm4.c | 2 +- 5 files changed, 37 insertions(+), 32 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index 96473d057..8a2286c45 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -535,7 +535,7 @@ struct hlsl_ir_constant *hlsl_new_uint_constant(struct hlsl_ctx *ctx, unsigned i if (!(c = hlsl_alloc(ctx, sizeof(*c)))) return NULL; init_node(&c->node, HLSL_IR_CONSTANT, ctx->builtin_types.scalar[HLSL_TYPE_UINT], loc); - c->value.u[0] = n; + c->value[0].u = n; return c; }
@@ -1018,26 +1018,28 @@ static void dump_ir_constant(struct vkd3d_string_buffer *buffer, const struct hl vkd3d_string_buffer_printf(buffer, "{"); for (x = 0; x < type->dimx; ++x) { + const union hlsl_constant_value *value = &constant->value[x]; + switch (type->base_type) { case HLSL_TYPE_BOOL: - vkd3d_string_buffer_printf(buffer, "%s ", constant->value.b[x] ? "true" : "false"); + vkd3d_string_buffer_printf(buffer, "%s ", value->b ? "true" : "false"); break;
case HLSL_TYPE_DOUBLE: - vkd3d_string_buffer_printf(buffer, "%.16e ", constant->value.d[x]); + vkd3d_string_buffer_printf(buffer, "%.16e ", value->d); break;
case HLSL_TYPE_FLOAT: - vkd3d_string_buffer_printf(buffer, "%.8e ", constant->value.f[x]); + vkd3d_string_buffer_printf(buffer, "%.8e ", value->f); break;
case HLSL_TYPE_INT: - vkd3d_string_buffer_printf(buffer, "%d ", constant->value.i[x]); + vkd3d_string_buffer_printf(buffer, "%d ", value->i); break;
case HLSL_TYPE_UINT: - vkd3d_string_buffer_printf(buffer, "%u ", constant->value.u[x]); + vkd3d_string_buffer_printf(buffer, "%u ", value->u); break;
default: diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index ce1f1b756..7079171b8 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -374,14 +374,14 @@ struct hlsl_ir_store struct hlsl_ir_constant { struct hlsl_ir_node node; - union + union hlsl_constant_value { - unsigned u[4]; - int i[4]; - float f[4]; - double d[4]; - bool b[4]; - } value; + uint32_t u; + int32_t i; + float f; + double d; + bool b; + } value[4]; struct hlsl_reg reg; };
diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index 2b381dc8a..2206d641d 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -828,20 +828,21 @@ static unsigned int evaluate_array_dimension(struct hlsl_ir_node *node) case HLSL_IR_CONSTANT: { struct hlsl_ir_constant *constant = hlsl_ir_constant(node); + const union hlsl_constant_value *value = &constant->value[0];
switch (constant->node.data_type->base_type) { case HLSL_TYPE_UINT: - return constant->value.u[0]; + return value->u; case HLSL_TYPE_INT: - return constant->value.i[0]; + return value->i; case HLSL_TYPE_FLOAT: case HLSL_TYPE_HALF: - return constant->value.f[0]; + return value->f; case HLSL_TYPE_DOUBLE: - return constant->value.d[0]; + return value->d; case HLSL_TYPE_BOOL: - return constant->value.b[0]; + return value->b; default: assert(0); return 0; @@ -2770,7 +2771,7 @@ primary_expr: if (!(c = hlsl_alloc(ctx, sizeof(*c)))) YYABORT; init_node(&c->node, HLSL_IR_CONSTANT, ctx->builtin_types.scalar[HLSL_TYPE_FLOAT], @1); - c->value.f[0] = $1; + c->value[0].f = $1; if (!($$ = make_list(ctx, &c->node))) YYABORT; } @@ -2781,7 +2782,7 @@ primary_expr: if (!(c = hlsl_alloc(ctx, sizeof(*c)))) YYABORT; init_node(&c->node, HLSL_IR_CONSTANT, ctx->builtin_types.scalar[HLSL_TYPE_INT], @1); - c->value.i[0] = $1; + c->value[0].i = $1; if (!($$ = make_list(ctx, &c->node))) YYABORT; } @@ -2792,7 +2793,7 @@ primary_expr: if (!(c = hlsl_alloc(ctx, sizeof(*c)))) YYABORT; init_node(&c->node, HLSL_IR_CONSTANT, ctx->builtin_types.scalar[HLSL_TYPE_BOOL], @1); - c->value.b[0] = $1; + c->value[0].b = $1; if (!($$ = make_list(ctx, &c->node))) YYABORT; } diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index 275920159..8bd9d1385 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -413,12 +413,12 @@ static bool fold_constants(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, voi { case HLSL_TYPE_INT: for (i = 0; i < dimx; ++i) - res->value.f[i] = arg1->value.i[i]; + res->value[i].f = arg1->value[i].i; break;
case HLSL_TYPE_UINT: for (i = 0; i < dimx; ++i) - res->value.f[i] = arg1->value.u[i]; + res->value[i].f = arg1->value[i].u; break;
default: @@ -443,17 +443,17 @@ static bool fold_constants(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, voi { case HLSL_OP1_NEG: for (i = 0; i < instr->data_type->dimx; ++i) - res->value.u[i] = -arg1->value.u[i]; + res->value[i].u = -arg1->value[i].u; break;
case HLSL_OP2_ADD: for (i = 0; i < instr->data_type->dimx; ++i) - res->value.u[i] = arg1->value.u[i] + arg2->value.u[i]; + res->value[i].u = arg1->value[i].u + arg2->value[i].u; break;
case HLSL_OP2_MUL: for (i = 0; i < instr->data_type->dimx; ++i) - res->value.u[i] = arg1->value.u[i] * arg2->value.u[i]; + res->value[i].u = arg1->value[i].u * arg2->value[i].u; break;
default: @@ -920,28 +920,30 @@ static void allocate_const_registers_recurse(struct hlsl_ctx *ctx, struct list * { for (x = 0, i = 0; x < 4; ++x) { + const union hlsl_constant_value *value; float f;
if (!(writemask & (1u << x))) continue; + value = &constant->value[i++];
switch (type->base_type) { case HLSL_TYPE_BOOL: - f = constant->value.b[i++]; + f = value->b; break;
case HLSL_TYPE_FLOAT: case HLSL_TYPE_HALF: - f = constant->value.f[i++]; + f = value->f; break;
case HLSL_TYPE_INT: - f = constant->value.i[i++]; + f = value->i; break;
case HLSL_TYPE_UINT: - f = constant->value.u[i++]; + f = value->u; break;
case HLSL_TYPE_DOUBLE: @@ -1208,7 +1210,7 @@ struct hlsl_reg hlsl_reg_from_deref(const struct hlsl_deref *deref, const struct ret.allocated = var->reg.allocated; ret.id = var->reg.id; if (offset_node) - offset = hlsl_ir_constant(offset_node)->value.u[0]; + offset = hlsl_ir_constant(offset_node)->value[0].u; ret.id += offset / 4;
if (type_is_single_reg(var->data_type)) diff --git a/libs/vkd3d-shader/hlsl_sm4.c b/libs/vkd3d-shader/hlsl_sm4.c index b347e3526..5558a1ff2 100644 --- a/libs/vkd3d-shader/hlsl_sm4.c +++ b/libs/vkd3d-shader/hlsl_sm4.c @@ -962,7 +962,7 @@ static void write_sm4_constant(struct hlsl_ctx *ctx, instr.srcs[0].reg.idx[0] = constant->reg.id; instr.srcs[0].reg.idx_count = 1; for (i = 0; i < dimx; ++i) - instr.srcs[0].reg.immconst_uint[i] = constant->value.u[i]; + instr.srcs[0].reg.immconst_uint[i] = constant->value[i].u; instr.src_count = 1,
write_sm4_instruction(buffer, &instr);
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- libs/vkd3d-shader/hlsl.h | 9 +++++++++ libs/vkd3d-shader/hlsl.y | 6 +++--- 2 files changed, 12 insertions(+), 3 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index 7079171b8..c69dc4a08 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -559,6 +559,15 @@ static inline void *hlsl_alloc(struct hlsl_ctx *ctx, size_t size) return ptr; }
+static inline void *hlsl_realloc(struct hlsl_ctx *ctx, void *ptr, size_t size) +{ + void *ret = vkd3d_realloc(ptr, size); + + if (!ret) + ctx->result = VKD3D_ERROR_OUT_OF_MEMORY; + return ret; +} + static inline char *hlsl_strdup(struct hlsl_ctx *ctx, const char *string) { char *ptr = vkd3d_strdup(string); diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index 2206d641d..dc2d31044 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -1997,7 +1997,7 @@ preproc_directive:
ctx->location.line = $1; if (strcmp($2, ctx->location.source_name)) - new_array = vkd3d_realloc(ctx->source_files, + new_array = hlsl_realloc(ctx, ctx->source_files, sizeof(*ctx->source_files) * (ctx->source_files_count + 1));
if (new_array) @@ -2544,7 +2544,7 @@ arrays: YYABORT; }
- if (!(new_array = vkd3d_realloc($$.sizes, ($$.count + 1) * sizeof(*new_array)))) + if (!(new_array = hlsl_realloc(ctx, $$.sizes, ($$.count + 1) * sizeof(*new_array)))) { vkd3d_free($$.sizes); YYABORT; @@ -2636,7 +2636,7 @@ initializer_expr_list: | initializer_expr_list ',' initializer_expr { $$ = $1; - if (!($$.args = vkd3d_realloc($$.args, ($$.args_count + 1) * sizeof(*$$.args)))) + if (!($$.args = hlsl_realloc(ctx, $$.args, ($$.args_count + 1) * sizeof(*$$.args)))) YYABORT; $$.args[$$.args_count++] = node_from_list($3); list_move_tail($$.instrs, $3);
Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com
Il 20/09/21 23:40, Zebediah Figura ha scritto:
Signed-off-by: Zebediah Figura zfigura@codeweavers.com
libs/vkd3d-shader/hlsl.h | 9 +++++++++ libs/vkd3d-shader/hlsl.y | 6 +++--- 2 files changed, 12 insertions(+), 3 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index 7079171b8..c69dc4a08 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -559,6 +559,15 @@ static inline void *hlsl_alloc(struct hlsl_ctx *ctx, size_t size) return ptr; }
+static inline void *hlsl_realloc(struct hlsl_ctx *ctx, void *ptr, size_t size) +{
- void *ret = vkd3d_realloc(ptr, size);
- if (!ret)
ctx->result = VKD3D_ERROR_OUT_OF_MEMORY;
- return ret;
+}
- static inline char *hlsl_strdup(struct hlsl_ctx *ctx, const char *string) { char *ptr = vkd3d_strdup(string);
diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index 2206d641d..dc2d31044 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -1997,7 +1997,7 @@ preproc_directive:
ctx->location.line = $1; if (strcmp($2, ctx->location.source_name))
new_array = vkd3d_realloc(ctx->source_files,
new_array = hlsl_realloc(ctx, ctx->source_files, sizeof(*ctx->source_files) * (ctx->source_files_count + 1)); if (new_array)
@@ -2544,7 +2544,7 @@ arrays: YYABORT; }
if (!(new_array = vkd3d_realloc($$.sizes, ($$.count + 1) * sizeof(*new_array))))
if (!(new_array = hlsl_realloc(ctx, $$.sizes, ($$.count + 1) * sizeof(*new_array)))) { vkd3d_free($$.sizes); YYABORT;
@@ -2636,7 +2636,7 @@ initializer_expr_list: | initializer_expr_list ',' initializer_expr { $$ = $1;
if (!($$.args = vkd3d_realloc($$.args, ($$.args_count + 1) * sizeof(*$$.args))))
if (!($$.args = hlsl_realloc(ctx, $$.args, ($$.args_count + 1) * sizeof(*$$.args)))) YYABORT; $$.args[$$.args_count++] = node_from_list($3); list_move_tail($$.instrs, $3);
Signed-off-by: Matteo Bruni mbruni@codeweavers.com
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- libs/vkd3d-shader/hlsl.y | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index dc2d31044..20f88f915 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -2694,7 +2694,8 @@ selection_statement: if (!(instr = hlsl_new_if(ctx, condition, @1))) YYABORT; list_move_tail(&instr->then_instrs, $5.then_instrs); - list_move_tail(&instr->else_instrs, $5.else_instrs); + if ($5.else_instrs) + list_move_tail(&instr->else_instrs, $5.else_instrs); vkd3d_free($5.then_instrs); vkd3d_free($5.else_instrs); if (condition->data_type->dimx > 1 || condition->data_type->dimy > 1)
Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com
Il 20/09/21 23:40, Zebediah Figura ha scritto:
Signed-off-by: Zebediah Figura zfigura@codeweavers.com
libs/vkd3d-shader/hlsl.y | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index dc2d31044..20f88f915 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -2694,7 +2694,8 @@ selection_statement: if (!(instr = hlsl_new_if(ctx, condition, @1))) YYABORT; list_move_tail(&instr->then_instrs, $5.then_instrs);
list_move_tail(&instr->else_instrs, $5.else_instrs);
if ($5.else_instrs)
list_move_tail(&instr->else_instrs, $5.else_instrs); vkd3d_free($5.then_instrs); vkd3d_free($5.else_instrs); if (condition->data_type->dimx > 1 || condition->data_type->dimy > 1)
Signed-off-by: Matteo Bruni mbruni@codeweavers.com
From: Giovanni Mascellani gmascellani@codeweavers.com
Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com Signed-off-by: Zebediah Figura zfigura@codeweavers.com Signed-off-by: Matteo Bruni mbruni@codeweavers.com --- v2 (Matteo): Simplify hlsl_offset_from_deref() a bit, use (offset % 4) instead of (offset & 3) for consistency.
libs/vkd3d-shader/hlsl.h | 1 + libs/vkd3d-shader/hlsl_codegen.c | 30 ++++++++++++++++-------------- libs/vkd3d-shader/hlsl_sm4.c | 6 ++++-- 3 files changed, 21 insertions(+), 16 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index c69dc4a0..27afeedd 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -687,6 +687,7 @@ unsigned int hlsl_combine_writemasks(unsigned int first, unsigned int second); unsigned int hlsl_map_swizzle(unsigned int swizzle, unsigned int writemask); unsigned int hlsl_swizzle_from_writemask(unsigned int writemask);
+unsigned int hlsl_offset_from_deref(const struct hlsl_deref *deref); struct hlsl_reg hlsl_reg_from_deref(const struct hlsl_deref *deref, const struct hlsl_type *type);
bool hlsl_sm1_register_from_semantic(struct hlsl_ctx *ctx, const struct hlsl_semantic *semantic, diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index 8bd9d138..9efc3dad 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -1187,30 +1187,32 @@ static bool type_is_single_reg(const struct hlsl_type *type) return type->type == HLSL_CLASS_SCALAR || type->type == HLSL_CLASS_VECTOR; }
-struct hlsl_reg hlsl_reg_from_deref(const struct hlsl_deref *deref, const struct hlsl_type *type) +unsigned int hlsl_offset_from_deref(const struct hlsl_deref *deref) { struct hlsl_ir_node *offset_node = deref->offset.node; - const struct hlsl_ir_var *var = deref->var; - struct hlsl_reg ret = {0}; - unsigned int offset = 0; + + if (!offset_node) + return 0;
/* We should always have generated a cast to UINT. */ - if (offset_node) - assert(offset_node->data_type->type == HLSL_CLASS_SCALAR - && offset_node->data_type->base_type == HLSL_TYPE_UINT); + assert(offset_node->data_type->type == HLSL_CLASS_SCALAR + && offset_node->data_type->base_type == HLSL_TYPE_UINT);
- if (offset_node && offset_node->type != HLSL_IR_CONSTANT) + if (offset_node->type != HLSL_IR_CONSTANT) { FIXME("Dereference with non-constant offset of type %s.\n", hlsl_node_type_to_string(offset_node->type)); offset_node = NULL; }
- ret = var->reg; + return hlsl_ir_constant(offset_node)->value[0].u; +} + +struct hlsl_reg hlsl_reg_from_deref(const struct hlsl_deref *deref, const struct hlsl_type *type) +{ + const struct hlsl_ir_var *var = deref->var; + struct hlsl_reg ret = var->reg; + unsigned int offset = hlsl_offset_from_deref(deref);
- ret.allocated = var->reg.allocated; - ret.id = var->reg.id; - if (offset_node) - offset = hlsl_ir_constant(offset_node)->value[0].u; ret.id += offset / 4;
if (type_is_single_reg(var->data_type)) @@ -1221,7 +1223,7 @@ struct hlsl_reg hlsl_reg_from_deref(const struct hlsl_deref *deref, const struct else { assert(type_is_single_reg(type)); - ret.writemask = ((1 << type->dimx) - 1) << (offset & 3); + ret.writemask = ((1 << type->dimx) - 1) << (offset % 4); } return ret; } diff --git a/libs/vkd3d-shader/hlsl_sm4.c b/libs/vkd3d-shader/hlsl_sm4.c index 5558a1ff..500c9f43 100644 --- a/libs/vkd3d-shader/hlsl_sm4.c +++ b/libs/vkd3d-shader/hlsl_sm4.c @@ -612,12 +612,14 @@ static void sm4_register_from_deref(struct hlsl_ctx *ctx, struct sm4_register *r
if (var->is_uniform) { + unsigned int offset = hlsl_offset_from_deref(deref) + var->buffer_offset; + reg->type = VKD3D_SM4_RT_CONSTBUFFER; reg->dim = VKD3D_SM4_DIMENSION_VEC4; reg->idx[0] = var->buffer->reg.id; - reg->idx[1] = var->buffer_offset / 4; + reg->idx[1] = offset / 4; reg->idx_count = 2; - *writemask = ((1u << data_type->dimx) - 1) << (var->buffer_offset & 3); + *writemask = ((1u << data_type->dimx) - 1) << (offset & 3); } else if (var->is_input_semantic) {
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
From: Giovanni Mascellani gmascellani@codeweavers.com
Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- libs/vkd3d-shader/hlsl.h | 1 + libs/vkd3d-shader/hlsl_codegen.c | 20 +++++++++++--------- libs/vkd3d-shader/hlsl_sm4.c | 6 ++++-- 3 files changed, 16 insertions(+), 11 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index c69dc4a08..27afeedd4 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -687,6 +687,7 @@ unsigned int hlsl_combine_writemasks(unsigned int first, unsigned int second); unsigned int hlsl_map_swizzle(unsigned int swizzle, unsigned int writemask); unsigned int hlsl_swizzle_from_writemask(unsigned int writemask);
+unsigned int hlsl_offset_from_deref(const struct hlsl_deref *deref); struct hlsl_reg hlsl_reg_from_deref(const struct hlsl_deref *deref, const struct hlsl_type *type);
bool hlsl_sm1_register_from_semantic(struct hlsl_ctx *ctx, const struct hlsl_semantic *semantic, diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index 8bd9d1385..1ac15e328 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -1187,12 +1187,9 @@ static bool type_is_single_reg(const struct hlsl_type *type) return type->type == HLSL_CLASS_SCALAR || type->type == HLSL_CLASS_VECTOR; }
-struct hlsl_reg hlsl_reg_from_deref(const struct hlsl_deref *deref, const struct hlsl_type *type) +unsigned int hlsl_offset_from_deref(const struct hlsl_deref *deref) { struct hlsl_ir_node *offset_node = deref->offset.node; - const struct hlsl_ir_var *var = deref->var; - struct hlsl_reg ret = {0}; - unsigned int offset = 0;
/* We should always have generated a cast to UINT. */ if (offset_node) @@ -1205,12 +1202,17 @@ struct hlsl_reg hlsl_reg_from_deref(const struct hlsl_deref *deref, const struct offset_node = NULL; }
- ret = var->reg; - - ret.allocated = var->reg.allocated; - ret.id = var->reg.id; if (offset_node) - offset = hlsl_ir_constant(offset_node)->value[0].u; + return hlsl_ir_constant(offset_node)->value[0].u; + return 0; +} + +struct hlsl_reg hlsl_reg_from_deref(const struct hlsl_deref *deref, const struct hlsl_type *type) +{ + const struct hlsl_ir_var *var = deref->var; + struct hlsl_reg ret = var->reg; + unsigned int offset = hlsl_offset_from_deref(deref); + ret.id += offset / 4;
if (type_is_single_reg(var->data_type)) diff --git a/libs/vkd3d-shader/hlsl_sm4.c b/libs/vkd3d-shader/hlsl_sm4.c index 5558a1ff2..500c9f434 100644 --- a/libs/vkd3d-shader/hlsl_sm4.c +++ b/libs/vkd3d-shader/hlsl_sm4.c @@ -612,12 +612,14 @@ static void sm4_register_from_deref(struct hlsl_ctx *ctx, struct sm4_register *r
if (var->is_uniform) { + unsigned int offset = hlsl_offset_from_deref(deref) + var->buffer_offset; + reg->type = VKD3D_SM4_RT_CONSTBUFFER; reg->dim = VKD3D_SM4_DIMENSION_VEC4; reg->idx[0] = var->buffer->reg.id; - reg->idx[1] = var->buffer_offset / 4; + reg->idx[1] = offset / 4; reg->idx_count = 2; - *writemask = ((1u << data_type->dimx) - 1) << (var->buffer_offset & 3); + *writemask = ((1u << data_type->dimx) - 1) << (offset & 3); } else if (var->is_input_semantic) {
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- libs/vkd3d-shader/hlsl.y | 111 ++++++++++++++++++++++----------------- 1 file changed, 63 insertions(+), 48 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index 20f88f915..e9eac555a 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -1700,6 +1700,66 @@ static struct list *add_call(struct hlsl_ctx *ctx, const char *name, return params->instrs; }
+static struct list *add_constructor(struct hlsl_ctx *ctx, struct hlsl_type *type, + struct parse_initializer *params, struct vkd3d_shader_location loc) +{ + unsigned int i, writemask_offset = 0; + struct hlsl_ir_store *store; + static unsigned int counter; + struct hlsl_ir_load *load; + struct hlsl_ir_var *var; + char name[23]; + + if (type->type == HLSL_CLASS_MATRIX) + hlsl_fixme(ctx, loc, "Matrix constructor."); + + sprintf(name, "<constructor-%x>", counter++); + if (!(var = hlsl_new_synthetic_var(ctx, name, type, loc))) + return NULL; + + for (i = 0; i < params->args_count; ++i) + { + struct hlsl_ir_node *arg = params->args[i]; + unsigned int width; + + if (arg->data_type->type == HLSL_CLASS_OBJECT) + { + struct vkd3d_string_buffer *string; + + if ((string = hlsl_type_to_string(ctx, arg->data_type))) + hlsl_error(ctx, arg->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, + "Invalid type %s for constructor argument.", string->buffer); + hlsl_release_string_buffer(ctx, string); + continue; + } + width = hlsl_type_component_count(arg->data_type); + + if (width > 4) + { + FIXME("Constructor argument with %u components.\n", width); + continue; + } + + if (!(arg = add_implicit_conversion(ctx, params->instrs, arg, + ctx->builtin_types.vector[type->base_type][width - 1], &arg->loc))) + continue; + + if (!(store = hlsl_new_store(ctx, var, NULL, arg, + ((1u << width) - 1) << writemask_offset, arg->loc))) + return NULL; + list_add_tail(params->instrs, &store->node.entry); + + writemask_offset += width; + } + + if (!(load = hlsl_new_var_load(ctx, var, loc))) + return NULL; + list_add_tail(params->instrs, &load->node.entry); + + vkd3d_free(params->args); + return params->instrs; +} + }
%locations @@ -2915,13 +2975,6 @@ postfix_expr: /* var_modifiers is necessary to avoid shift/reduce conflicts. */ | var_modifiers type '(' initializer_expr_list ')' { - unsigned int i, writemask_offset = 0; - struct hlsl_ir_store *store; - static unsigned int counter; - struct hlsl_ir_load *load; - struct hlsl_ir_var *var; - char name[23]; - if ($1) { hlsl_error(ctx, @1, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER, @@ -2946,49 +2999,11 @@ postfix_expr: YYABORT; }
- if ($2->type == HLSL_CLASS_MATRIX) - hlsl_fixme(ctx, @2, "Matrix constructor."); - - sprintf(name, "<constructor-%x>", counter++); - if (!(var = hlsl_new_synthetic_var(ctx, name, $2, @2))) - YYABORT; - for (i = 0; i < $4.args_count; ++i) + if (!($$ = add_constructor(ctx, $2, &$4, @2))) { - struct hlsl_ir_node *arg = $4.args[i]; - unsigned int width; - - if (arg->data_type->type == HLSL_CLASS_OBJECT) - { - struct vkd3d_string_buffer *string; - - if ((string = hlsl_type_to_string(ctx, arg->data_type))) - hlsl_error(ctx, arg->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, - "Invalid type %s for constructor argument.", string->buffer); - hlsl_release_string_buffer(ctx, string); - continue; - } - width = hlsl_type_component_count(arg->data_type); - - if (width > 4) - { - FIXME("Constructor argument with %u components.\n", width); - continue; - } - - if (!(arg = add_implicit_conversion(ctx, $4.instrs, arg, - ctx->builtin_types.vector[$2->base_type][width - 1], &arg->loc))) - continue; - - if (!(store = hlsl_new_store(ctx, var, NULL, arg, - ((1 << width) - 1) << writemask_offset, arg->loc))) - YYABORT; - writemask_offset += width; - list_add_tail($4.instrs, &store->node.entry); - } - vkd3d_free($4.args); - if (!(load = hlsl_new_var_load(ctx, var, @2))) + free_parse_initializer(&$4); YYABORT; - $$ = append_unop($4.instrs, &load->node); + } }
unary_expr:
Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com -- The other error branches in the bison rule are missing a "free_parse_initializer(&$4)", right? Maybe it's not this commit's scope, but still there seems to be a resource leak.
Thanks, Giovanni.
Il 20/09/21 23:40, Zebediah Figura ha scritto:
Signed-off-by: Zebediah Figura zfigura@codeweavers.com
libs/vkd3d-shader/hlsl.y | 111 ++++++++++++++++++++++----------------- 1 file changed, 63 insertions(+), 48 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index 20f88f915..e9eac555a 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -1700,6 +1700,66 @@ static struct list *add_call(struct hlsl_ctx *ctx, const char *name, return params->instrs; }
+static struct list *add_constructor(struct hlsl_ctx *ctx, struct hlsl_type *type,
struct parse_initializer *params, struct vkd3d_shader_location loc)
+{
- unsigned int i, writemask_offset = 0;
- struct hlsl_ir_store *store;
- static unsigned int counter;
- struct hlsl_ir_load *load;
- struct hlsl_ir_var *var;
- char name[23];
- if (type->type == HLSL_CLASS_MATRIX)
hlsl_fixme(ctx, loc, "Matrix constructor.");
- sprintf(name, "<constructor-%x>", counter++);
- if (!(var = hlsl_new_synthetic_var(ctx, name, type, loc)))
return NULL;
- for (i = 0; i < params->args_count; ++i)
- {
struct hlsl_ir_node *arg = params->args[i];
unsigned int width;
if (arg->data_type->type == HLSL_CLASS_OBJECT)
{
struct vkd3d_string_buffer *string;
if ((string = hlsl_type_to_string(ctx, arg->data_type)))
hlsl_error(ctx, arg->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE,
"Invalid type %s for constructor argument.", string->buffer);
hlsl_release_string_buffer(ctx, string);
continue;
}
width = hlsl_type_component_count(arg->data_type);
if (width > 4)
{
FIXME("Constructor argument with %u components.\n", width);
continue;
}
if (!(arg = add_implicit_conversion(ctx, params->instrs, arg,
ctx->builtin_types.vector[type->base_type][width - 1], &arg->loc)))
continue;
if (!(store = hlsl_new_store(ctx, var, NULL, arg,
((1u << width) - 1) << writemask_offset, arg->loc)))
return NULL;
list_add_tail(params->instrs, &store->node.entry);
writemask_offset += width;
- }
- if (!(load = hlsl_new_var_load(ctx, var, loc)))
return NULL;
- list_add_tail(params->instrs, &load->node.entry);
- vkd3d_free(params->args);
- return params->instrs;
+}
}
%locations
@@ -2915,13 +2975,6 @@ postfix_expr: /* var_modifiers is necessary to avoid shift/reduce conflicts. */ | var_modifiers type '(' initializer_expr_list ')' {
unsigned int i, writemask_offset = 0;
struct hlsl_ir_store *store;
static unsigned int counter;
struct hlsl_ir_load *load;
struct hlsl_ir_var *var;
char name[23];
if ($1) { hlsl_error(ctx, @1, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER,
@@ -2946,49 +2999,11 @@ postfix_expr: YYABORT; }
if ($2->type == HLSL_CLASS_MATRIX)
hlsl_fixme(ctx, @2, "Matrix constructor.");
sprintf(name, "<constructor-%x>", counter++);
if (!(var = hlsl_new_synthetic_var(ctx, name, $2, @2)))
YYABORT;
for (i = 0; i < $4.args_count; ++i)
if (!($$ = add_constructor(ctx, $2, &$4, @2))) {
struct hlsl_ir_node *arg = $4.args[i];
unsigned int width;
if (arg->data_type->type == HLSL_CLASS_OBJECT)
{
struct vkd3d_string_buffer *string;
if ((string = hlsl_type_to_string(ctx, arg->data_type)))
hlsl_error(ctx, arg->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE,
"Invalid type %s for constructor argument.", string->buffer);
hlsl_release_string_buffer(ctx, string);
continue;
}
width = hlsl_type_component_count(arg->data_type);
if (width > 4)
{
FIXME("Constructor argument with %u components.\n", width);
continue;
}
if (!(arg = add_implicit_conversion(ctx, $4.instrs, arg,
ctx->builtin_types.vector[$2->base_type][width - 1], &arg->loc)))
continue;
if (!(store = hlsl_new_store(ctx, var, NULL, arg,
((1 << width) - 1) << writemask_offset, arg->loc)))
YYABORT;
writemask_offset += width;
list_add_tail($4.instrs, &store->node.entry);
}
vkd3d_free($4.args);
if (!(load = hlsl_new_var_load(ctx, var, @2)))
free_parse_initializer(&$4); YYABORT;
$$ = append_unop($4.instrs, &load->node);
} }
unary_expr:
On Tue, Sep 21, 2021 at 12:01 PM Giovanni Mascellani gmascellani@codeweavers.com wrote:
Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com
The other error branches in the bison rule are missing a "free_parse_initializer(&$4)", right? Maybe it's not this commit's scope, but still there seems to be a resource leak.
That seems right. There are probably more leaks (especially in error cases), patches fixing them are certainly welcome.
Thanks, Giovanni.
Signed-off-by: Matteo Bruni mbruni@codeweavers.com
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com
Il 20/09/21 23:40, Zebediah Figura ha scritto:
This allows us to more easily manipulate individual elements in a type-agnostic way. For example, it allows easier implementation of constant swizzle folding.
Signed-off-by: Zebediah Figura zfigura@codeweavers.com
libs/vkd3d-shader/hlsl.c | 14 ++++++++------ libs/vkd3d-shader/hlsl.h | 14 +++++++------- libs/vkd3d-shader/hlsl.y | 17 +++++++++-------- libs/vkd3d-shader/hlsl_codegen.c | 22 ++++++++++++---------- libs/vkd3d-shader/hlsl_sm4.c | 2 +- 5 files changed, 37 insertions(+), 32 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index 96473d057..8a2286c45 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -535,7 +535,7 @@ struct hlsl_ir_constant *hlsl_new_uint_constant(struct hlsl_ctx *ctx, unsigned i if (!(c = hlsl_alloc(ctx, sizeof(*c)))) return NULL; init_node(&c->node, HLSL_IR_CONSTANT, ctx->builtin_types.scalar[HLSL_TYPE_UINT], loc);
- c->value.u[0] = n;
- c->value[0].u = n; return c; }
@@ -1018,26 +1018,28 @@ static void dump_ir_constant(struct vkd3d_string_buffer *buffer, const struct hl vkd3d_string_buffer_printf(buffer, "{"); for (x = 0; x < type->dimx; ++x) {
const union hlsl_constant_value *value = &constant->value[x];
switch (type->base_type) { case HLSL_TYPE_BOOL:
vkd3d_string_buffer_printf(buffer, "%s ", constant->value.b[x] ? "true" : "false");
vkd3d_string_buffer_printf(buffer, "%s ", value->b ? "true" : "false"); break; case HLSL_TYPE_DOUBLE:
vkd3d_string_buffer_printf(buffer, "%.16e ", constant->value.d[x]);
vkd3d_string_buffer_printf(buffer, "%.16e ", value->d); break; case HLSL_TYPE_FLOAT:
vkd3d_string_buffer_printf(buffer, "%.8e ", constant->value.f[x]);
vkd3d_string_buffer_printf(buffer, "%.8e ", value->f); break; case HLSL_TYPE_INT:
vkd3d_string_buffer_printf(buffer, "%d ", constant->value.i[x]);
vkd3d_string_buffer_printf(buffer, "%d ", value->i); break; case HLSL_TYPE_UINT:
vkd3d_string_buffer_printf(buffer, "%u ", constant->value.u[x]);
vkd3d_string_buffer_printf(buffer, "%u ", value->u); break; default:
diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index ce1f1b756..7079171b8 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -374,14 +374,14 @@ struct hlsl_ir_store struct hlsl_ir_constant { struct hlsl_ir_node node;
- union
- union hlsl_constant_value {
unsigned u[4];
int i[4];
float f[4];
double d[4];
bool b[4];
- } value;
uint32_t u;
int32_t i;
float f;
double d;
bool b;
- } value[4]; struct hlsl_reg reg; };
diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index 2b381dc8a..2206d641d 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -828,20 +828,21 @@ static unsigned int evaluate_array_dimension(struct hlsl_ir_node *node) case HLSL_IR_CONSTANT: { struct hlsl_ir_constant *constant = hlsl_ir_constant(node);
const union hlsl_constant_value *value = &constant->value[0]; switch (constant->node.data_type->base_type) { case HLSL_TYPE_UINT:
return constant->value.u[0];
return value->u; case HLSL_TYPE_INT:
return constant->value.i[0];
return value->i; case HLSL_TYPE_FLOAT: case HLSL_TYPE_HALF:
return constant->value.f[0];
return value->f; case HLSL_TYPE_DOUBLE:
return constant->value.d[0];
return value->d; case HLSL_TYPE_BOOL:
return constant->value.b[0];
return value->b; default: assert(0); return 0;
@@ -2770,7 +2771,7 @@ primary_expr: if (!(c = hlsl_alloc(ctx, sizeof(*c)))) YYABORT; init_node(&c->node, HLSL_IR_CONSTANT, ctx->builtin_types.scalar[HLSL_TYPE_FLOAT], @1);
c->value.f[0] = $1;
c->value[0].f = $1; if (!($$ = make_list(ctx, &c->node))) YYABORT; }
@@ -2781,7 +2782,7 @@ primary_expr: if (!(c = hlsl_alloc(ctx, sizeof(*c)))) YYABORT; init_node(&c->node, HLSL_IR_CONSTANT, ctx->builtin_types.scalar[HLSL_TYPE_INT], @1);
c->value.i[0] = $1;
c->value[0].i = $1; if (!($$ = make_list(ctx, &c->node))) YYABORT; }
@@ -2792,7 +2793,7 @@ primary_expr: if (!(c = hlsl_alloc(ctx, sizeof(*c)))) YYABORT; init_node(&c->node, HLSL_IR_CONSTANT, ctx->builtin_types.scalar[HLSL_TYPE_BOOL], @1);
c->value.b[0] = $1;
c->value[0].b = $1; if (!($$ = make_list(ctx, &c->node))) YYABORT; }
diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index 275920159..8bd9d1385 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -413,12 +413,12 @@ static bool fold_constants(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, voi { case HLSL_TYPE_INT: for (i = 0; i < dimx; ++i)
res->value.f[i] = arg1->value.i[i];
res->value[i].f = arg1->value[i].i; break; case HLSL_TYPE_UINT: for (i = 0; i < dimx; ++i)
res->value.f[i] = arg1->value.u[i];
res->value[i].f = arg1->value[i].u; break; default:
@@ -443,17 +443,17 @@ static bool fold_constants(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, voi { case HLSL_OP1_NEG: for (i = 0; i < instr->data_type->dimx; ++i)
res->value.u[i] = -arg1->value.u[i];
res->value[i].u = -arg1->value[i].u; break; case HLSL_OP2_ADD: for (i = 0; i < instr->data_type->dimx; ++i)
res->value.u[i] = arg1->value.u[i] + arg2->value.u[i];
res->value[i].u = arg1->value[i].u + arg2->value[i].u; break; case HLSL_OP2_MUL: for (i = 0; i < instr->data_type->dimx; ++i)
res->value.u[i] = arg1->value.u[i] * arg2->value.u[i];
res->value[i].u = arg1->value[i].u * arg2->value[i].u; break; default:
@@ -920,28 +920,30 @@ static void allocate_const_registers_recurse(struct hlsl_ctx *ctx, struct list * { for (x = 0, i = 0; x < 4; ++x) {
const union hlsl_constant_value *value; float f; if (!(writemask & (1u << x))) continue;
value = &constant->value[i++]; switch (type->base_type) { case HLSL_TYPE_BOOL:
f = constant->value.b[i++];
f = value->b; break; case HLSL_TYPE_FLOAT: case HLSL_TYPE_HALF:
f = constant->value.f[i++];
f = value->f; break; case HLSL_TYPE_INT:
f = constant->value.i[i++];
f = value->i; break; case HLSL_TYPE_UINT:
f = constant->value.u[i++];
f = value->u; break; case HLSL_TYPE_DOUBLE:
@@ -1208,7 +1210,7 @@ struct hlsl_reg hlsl_reg_from_deref(const struct hlsl_deref *deref, const struct ret.allocated = var->reg.allocated; ret.id = var->reg.id; if (offset_node)
offset = hlsl_ir_constant(offset_node)->value.u[0];
offset = hlsl_ir_constant(offset_node)->value[0].u; ret.id += offset / 4; if (type_is_single_reg(var->data_type))
diff --git a/libs/vkd3d-shader/hlsl_sm4.c b/libs/vkd3d-shader/hlsl_sm4.c index b347e3526..5558a1ff2 100644 --- a/libs/vkd3d-shader/hlsl_sm4.c +++ b/libs/vkd3d-shader/hlsl_sm4.c @@ -962,7 +962,7 @@ static void write_sm4_constant(struct hlsl_ctx *ctx, instr.srcs[0].reg.idx[0] = constant->reg.id; instr.srcs[0].reg.idx_count = 1; for (i = 0; i < dimx; ++i)
instr.srcs[0].reg.immconst_uint[i] = constant->value.u[i];
instr.srcs[0].reg.immconst_uint[i] = constant->value[i].u; instr.src_count = 1, write_sm4_instruction(buffer, &instr);