From: Francisco Casas fcasas@codeweavers.com
Also rename it to hlsl_replace_node().
Signed-off-by: Francisco Casas fcasas@codeweavers.com Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- libs/vkd3d-shader/hlsl.c | 14 ++++++++++++++ libs/vkd3d-shader/hlsl.h | 2 ++ libs/vkd3d-shader/hlsl_codegen.c | 25 ++++++------------------- 3 files changed, 22 insertions(+), 19 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index 8a0f4b017..a9a427707 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -1400,6 +1400,20 @@ void hlsl_dump_function(struct hlsl_ctx *ctx, const struct hlsl_ir_function_decl vkd3d_string_buffer_cleanup(&buffer); }
+void hlsl_replace_node(struct hlsl_ir_node *old, struct hlsl_ir_node *new) +{ + struct hlsl_src *src, *next; + + LIST_FOR_EACH_ENTRY_SAFE(src, next, &old->uses, struct hlsl_src, entry) + { + hlsl_src_remove(src); + hlsl_src_from_node(src, new); + } + list_remove(&old->entry); + hlsl_free_instr(old); +} + + void hlsl_free_type(struct hlsl_type *type) { struct hlsl_struct_field *field, *next_field; diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index 3a69165e5..67fe1a8d5 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -713,6 +713,8 @@ void hlsl_dump_function(struct hlsl_ctx *ctx, const struct hlsl_ir_function_decl
int hlsl_emit_dxbc(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func, struct vkd3d_shader_code *out);
+void hlsl_replace_node(struct hlsl_ir_node *old, struct hlsl_ir_node *new); + void hlsl_free_instr(struct hlsl_ir_node *node); void hlsl_free_instr_list(struct list *list); void hlsl_free_type(struct hlsl_type *type); diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index eac3513c9..77ddd979a 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -224,19 +224,6 @@ static bool transform_ir(struct hlsl_ctx *ctx, bool (*func)(struct hlsl_ctx *ctx return progress; }
-static void replace_node(struct hlsl_ir_node *old, struct hlsl_ir_node *new) -{ - struct hlsl_src *src, *next; - - LIST_FOR_EACH_ENTRY_SAFE(src, next, &old->uses, struct hlsl_src, entry) - { - hlsl_src_remove(src); - hlsl_src_from_node(src, new); - } - list_remove(&old->entry); - hlsl_free_instr(old); -} - /* Lower casts from vec1 to vecN to swizzles. */ static bool lower_broadcasts(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) { @@ -267,7 +254,7 @@ static bool lower_broadcasts(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, v return false; list_add_after(&new_cast->node.entry, &swizzle->node.entry);
- replace_node(&cast->node, &swizzle->node); + hlsl_replace_node(&cast->node, &swizzle->node); return true; }
@@ -437,7 +424,7 @@ static bool copy_propagation_transform_load(struct hlsl_ctx *ctx, list_add_before(&node->entry, &swizzle_node->node.entry); new_node = &swizzle_node->node; } - replace_node(node, new_node); + hlsl_replace_node(node, new_node); return true; }
@@ -566,7 +553,7 @@ static bool fold_redundant_casts(struct hlsl_ctx *ctx, struct hlsl_ir_node *inst if (hlsl_types_are_equal(src_type, dst_type) || (src_type->base_type == dst_type->base_type && is_vec1(src_type) && is_vec1(dst_type))) { - replace_node(&expr->node, expr->operands[0].node); + hlsl_replace_node(&expr->node, expr->operands[0].node); return true; } } @@ -708,7 +695,7 @@ static bool lower_narrowing_casts(struct hlsl_ctx *ctx, struct hlsl_ir_node *ins return false; list_add_after(&new_cast->node.entry, &swizzle->node.entry);
- replace_node(&cast->node, &swizzle->node); + hlsl_replace_node(&cast->node, &swizzle->node); return true; }
@@ -842,7 +829,7 @@ static bool fold_constants(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, voi }
list_add_before(&expr->node.entry, &res->node.entry); - replace_node(&expr->node, &res->node); + hlsl_replace_node(&expr->node, &res->node); return true; }
@@ -862,7 +849,7 @@ static bool remove_trivial_swizzles(struct hlsl_ctx *ctx, struct hlsl_ir_node *i if (((swizzle->swizzle >> (2 * i)) & 3) != i) return false;
- replace_node(instr, swizzle->val.node); + hlsl_replace_node(instr, swizzle->val.node);
return true; }
From: Francisco Casas fcasas@codeweavers.com
Also rename it to hlsl_fold_constants().
Signed-off-by: Francisco Casas fcasas@codeweavers.com Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- Makefile.am | 1 + libs/vkd3d-shader/hlsl.h | 2 + libs/vkd3d-shader/hlsl_codegen.c | 133 +--------------------- libs/vkd3d-shader/hlsl_constant_ops.c | 152 ++++++++++++++++++++++++++ 4 files changed, 156 insertions(+), 132 deletions(-) create mode 100644 libs/vkd3d-shader/hlsl_constant_ops.c
diff --git a/Makefile.am b/Makefile.am index 7a7bd6a7a..c3ba3febc 100644 --- a/Makefile.am +++ b/Makefile.am @@ -207,6 +207,7 @@ libvkd3d_shader_la_SOURCES = \ libs/vkd3d-shader/hlsl.c \ libs/vkd3d-shader/hlsl.h \ libs/vkd3d-shader/hlsl_codegen.c \ + libs/vkd3d-shader/hlsl_constant_ops.c \ libs/vkd3d-shader/hlsl_sm1.c \ libs/vkd3d-shader/hlsl_sm4.c \ libs/vkd3d-shader/preproc.h \ diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index 67fe1a8d5..be515e326 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -795,6 +795,8 @@ unsigned int hlsl_offset_from_deref_safe(struct hlsl_ctx *ctx, const struct hlsl struct hlsl_reg hlsl_reg_from_deref(struct hlsl_ctx *ctx, const struct hlsl_deref *deref, const struct hlsl_type *type);
+bool hlsl_fold_constants(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context); + bool hlsl_sm1_register_from_semantic(struct hlsl_ctx *ctx, const struct hlsl_semantic *semantic, bool output, D3DSHADER_PARAM_REGISTER_TYPE *type, unsigned int *reg); bool hlsl_sm1_usage_from_semantic(const struct hlsl_semantic *semantic, D3DDECLUSAGE *usage, uint32_t *usage_idx); diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index 77ddd979a..17a7649fc 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -702,137 +702,6 @@ static bool lower_narrowing_casts(struct hlsl_ctx *ctx, struct hlsl_ir_node *ins return false; }
-static bool fold_constants(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) -{ - struct hlsl_ir_constant *arg1, *arg2 = NULL, *res; - struct hlsl_ir_expr *expr; - unsigned int i, dimx; - - if (instr->type != HLSL_IR_EXPR) - return false; - expr = hlsl_ir_expr(instr); - - for (i = 0; i < ARRAY_SIZE(expr->operands); ++i) - { - if (expr->operands[i].node && expr->operands[i].node->type != HLSL_IR_CONSTANT) - return false; - } - arg1 = hlsl_ir_constant(expr->operands[0].node); - if (expr->operands[1].node) - arg2 = hlsl_ir_constant(expr->operands[1].node); - dimx = instr->data_type->dimx; - - if (!(res = hlsl_alloc(ctx, sizeof(*res)))) - return false; - init_node(&res->node, HLSL_IR_CONSTANT, instr->data_type, instr->loc); - - switch (instr->data_type->base_type) - { - case HLSL_TYPE_FLOAT: - { - switch (expr->op) - { - case HLSL_OP1_CAST: - if (instr->data_type->dimx != arg1->node.data_type->dimx - || instr->data_type->dimy != arg1->node.data_type->dimy) - { - FIXME("Cast from %s to %s.\n", debug_hlsl_type(ctx, arg1->node.data_type), - debug_hlsl_type(ctx, instr->data_type)); - vkd3d_free(res); - return false; - } - - switch (arg1->node.data_type->base_type) - { - case HLSL_TYPE_INT: - for (i = 0; i < dimx; ++i) - res->value[i].f = arg1->value[i].i; - break; - - case HLSL_TYPE_UINT: - for (i = 0; i < dimx; ++i) - res->value[i].f = arg1->value[i].u; - break; - - default: - FIXME("Cast from %s to %s.\n", debug_hlsl_type(ctx, arg1->node.data_type), - debug_hlsl_type(ctx, instr->data_type)); - vkd3d_free(res); - return false; - } - break; - - default: - FIXME("Fold float op %#x.\n", expr->op); - vkd3d_free(res); - return false; - } - break; - } - - case HLSL_TYPE_UINT: - { - switch (expr->op) - { - case HLSL_OP1_CAST: - if (instr->data_type->dimx != arg1->node.data_type->dimx - || instr->data_type->dimy != arg1->node.data_type->dimy) - { - FIXME("Cast from %s to %s.\n", debug_hlsl_type(ctx, arg1->node.data_type), - debug_hlsl_type(ctx, instr->data_type)); - vkd3d_free(res); - return false; - } - - switch (arg1->node.data_type->base_type) - { - case HLSL_TYPE_INT: - for (i = 0; i < dimx; ++i) - res->value[i].i = arg1->value[i].u; - break; - - default: - FIXME("Cast from %s to %s.\n", debug_hlsl_type(ctx, arg1->node.data_type), - debug_hlsl_type(ctx, instr->data_type)); - vkd3d_free(res); - return false; - } - break; - - case HLSL_OP1_NEG: - for (i = 0; i < instr->data_type->dimx; ++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[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[i].u = arg1->value[i].u * arg2->value[i].u; - break; - - default: - FIXME("Fold uint op %#x.\n", expr->op); - vkd3d_free(res); - return false; - } - break; - } - - default: - FIXME("Fold type %#x op %#x.\n", instr->data_type->base_type, expr->op); - vkd3d_free(res); - return false; - } - - list_add_before(&expr->node.entry, &res->node.entry); - hlsl_replace_node(&expr->node, &res->node); - return true; -} - static bool remove_trivial_swizzles(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) { struct hlsl_ir_swizzle *swizzle; @@ -1785,7 +1654,7 @@ int hlsl_emit_dxbc(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_fun transform_ir(ctx, lower_narrowing_casts, body, NULL); do { - progress = transform_ir(ctx, fold_constants, body, NULL); + progress = transform_ir(ctx, hlsl_fold_constants, body, NULL); progress |= copy_propagation_execute(ctx, body); } while (progress); diff --git a/libs/vkd3d-shader/hlsl_constant_ops.c b/libs/vkd3d-shader/hlsl_constant_ops.c new file mode 100644 index 000000000..9e19cef4b --- /dev/null +++ b/libs/vkd3d-shader/hlsl_constant_ops.c @@ -0,0 +1,152 @@ +/* + * HLSL constant value operations for constant folding + * + * Copyright 2022 Francisco Casas for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "hlsl.h" + +bool hlsl_fold_constants(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) +{ + struct hlsl_ir_constant *arg1, *arg2 = NULL, *res; + struct hlsl_ir_expr *expr; + unsigned int i, dimx; + + if (instr->type != HLSL_IR_EXPR) + return false; + expr = hlsl_ir_expr(instr); + + for (i = 0; i < ARRAY_SIZE(expr->operands); ++i) + { + if (expr->operands[i].node && expr->operands[i].node->type != HLSL_IR_CONSTANT) + return false; + } + arg1 = hlsl_ir_constant(expr->operands[0].node); + if (expr->operands[1].node) + arg2 = hlsl_ir_constant(expr->operands[1].node); + dimx = instr->data_type->dimx; + + if (!(res = hlsl_alloc(ctx, sizeof(*res)))) + return false; + init_node(&res->node, HLSL_IR_CONSTANT, instr->data_type, instr->loc); + + switch (instr->data_type->base_type) + { + case HLSL_TYPE_FLOAT: + { + switch (expr->op) + { + case HLSL_OP1_CAST: + if (instr->data_type->dimx != arg1->node.data_type->dimx + || instr->data_type->dimy != arg1->node.data_type->dimy) + { + FIXME("Cast from %s to %s.\n", debug_hlsl_type(ctx, arg1->node.data_type), + debug_hlsl_type(ctx, instr->data_type)); + vkd3d_free(res); + return false; + } + + switch (arg1->node.data_type->base_type) + { + case HLSL_TYPE_INT: + for (i = 0; i < dimx; ++i) + res->value[i].f = arg1->value[i].i; + break; + + case HLSL_TYPE_UINT: + for (i = 0; i < dimx; ++i) + res->value[i].f = arg1->value[i].u; + break; + + default: + FIXME("Cast from %s to %s.\n", debug_hlsl_type(ctx, arg1->node.data_type), + debug_hlsl_type(ctx, instr->data_type)); + vkd3d_free(res); + return false; + } + break; + + default: + FIXME("Fold float op %#x.\n", expr->op); + vkd3d_free(res); + return false; + } + break; + } + + case HLSL_TYPE_UINT: + { + switch (expr->op) + { + case HLSL_OP1_CAST: + if (instr->data_type->dimx != arg1->node.data_type->dimx + || instr->data_type->dimy != arg1->node.data_type->dimy) + { + FIXME("Cast from %s to %s.\n", debug_hlsl_type(ctx, arg1->node.data_type), + debug_hlsl_type(ctx, instr->data_type)); + vkd3d_free(res); + return false; + } + + switch (arg1->node.data_type->base_type) + { + case HLSL_TYPE_INT: + for (i = 0; i < dimx; ++i) + res->value[i].i = arg1->value[i].u; + break; + + default: + FIXME("Cast from %s to %s.\n", debug_hlsl_type(ctx, arg1->node.data_type), + debug_hlsl_type(ctx, instr->data_type)); + vkd3d_free(res); + return false; + } + break; + + case HLSL_OP1_NEG: + for (i = 0; i < instr->data_type->dimx; ++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[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[i].u = arg1->value[i].u * arg2->value[i].u; + break; + + default: + FIXME("Fold uint op %#x.\n", expr->op); + vkd3d_free(res); + return false; + } + break; + } + + default: + FIXME("Fold type %#x op %#x.\n", instr->data_type->base_type, expr->op); + vkd3d_free(res); + return false; + } + + list_add_before(&expr->node.entry, &res->node.entry); + hlsl_replace_node(&expr->node, &res->node); + return true; +}
Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com
Il 11/02/22 04:48, Zebediah Figura ha scritto:
From: Francisco Casas fcasas@codeweavers.com
Also rename it to hlsl_fold_constants().
Signed-off-by: Francisco Casas fcasas@codeweavers.com Signed-off-by: Zebediah Figura zfigura@codeweavers.com
Makefile.am | 1 + libs/vkd3d-shader/hlsl.h | 2 + libs/vkd3d-shader/hlsl_codegen.c | 133 +--------------------- libs/vkd3d-shader/hlsl_constant_ops.c | 152 ++++++++++++++++++++++++++ 4 files changed, 156 insertions(+), 132 deletions(-) create mode 100644 libs/vkd3d-shader/hlsl_constant_ops.c
diff --git a/Makefile.am b/Makefile.am index 7a7bd6a7a..c3ba3febc 100644 --- a/Makefile.am +++ b/Makefile.am @@ -207,6 +207,7 @@ libvkd3d_shader_la_SOURCES = \ libs/vkd3d-shader/hlsl.c \ libs/vkd3d-shader/hlsl.h \ libs/vkd3d-shader/hlsl_codegen.c \
- libs/vkd3d-shader/hlsl_constant_ops.c \ libs/vkd3d-shader/hlsl_sm1.c \ libs/vkd3d-shader/hlsl_sm4.c \ libs/vkd3d-shader/preproc.h \
diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index 67fe1a8d5..be515e326 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -795,6 +795,8 @@ unsigned int hlsl_offset_from_deref_safe(struct hlsl_ctx *ctx, const struct hlsl struct hlsl_reg hlsl_reg_from_deref(struct hlsl_ctx *ctx, const struct hlsl_deref *deref, const struct hlsl_type *type);
+bool hlsl_fold_constants(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context);
- bool hlsl_sm1_register_from_semantic(struct hlsl_ctx *ctx, const struct hlsl_semantic *semantic, bool output, D3DSHADER_PARAM_REGISTER_TYPE *type, unsigned int *reg); bool hlsl_sm1_usage_from_semantic(const struct hlsl_semantic *semantic, D3DDECLUSAGE *usage, uint32_t *usage_idx);
diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index 77ddd979a..17a7649fc 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -702,137 +702,6 @@ static bool lower_narrowing_casts(struct hlsl_ctx *ctx, struct hlsl_ir_node *ins return false; }
-static bool fold_constants(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) -{
- struct hlsl_ir_constant *arg1, *arg2 = NULL, *res;
- struct hlsl_ir_expr *expr;
- unsigned int i, dimx;
- if (instr->type != HLSL_IR_EXPR)
return false;
- expr = hlsl_ir_expr(instr);
- for (i = 0; i < ARRAY_SIZE(expr->operands); ++i)
- {
if (expr->operands[i].node && expr->operands[i].node->type != HLSL_IR_CONSTANT)
return false;
- }
- arg1 = hlsl_ir_constant(expr->operands[0].node);
- if (expr->operands[1].node)
arg2 = hlsl_ir_constant(expr->operands[1].node);
- dimx = instr->data_type->dimx;
- if (!(res = hlsl_alloc(ctx, sizeof(*res))))
return false;
- init_node(&res->node, HLSL_IR_CONSTANT, instr->data_type, instr->loc);
- switch (instr->data_type->base_type)
- {
case HLSL_TYPE_FLOAT:
{
switch (expr->op)
{
case HLSL_OP1_CAST:
if (instr->data_type->dimx != arg1->node.data_type->dimx
|| instr->data_type->dimy != arg1->node.data_type->dimy)
{
FIXME("Cast from %s to %s.\n", debug_hlsl_type(ctx, arg1->node.data_type),
debug_hlsl_type(ctx, instr->data_type));
vkd3d_free(res);
return false;
}
switch (arg1->node.data_type->base_type)
{
case HLSL_TYPE_INT:
for (i = 0; i < dimx; ++i)
res->value[i].f = arg1->value[i].i;
break;
case HLSL_TYPE_UINT:
for (i = 0; i < dimx; ++i)
res->value[i].f = arg1->value[i].u;
break;
default:
FIXME("Cast from %s to %s.\n", debug_hlsl_type(ctx, arg1->node.data_type),
debug_hlsl_type(ctx, instr->data_type));
vkd3d_free(res);
return false;
}
break;
default:
FIXME("Fold float op %#x.\n", expr->op);
vkd3d_free(res);
return false;
}
break;
}
case HLSL_TYPE_UINT:
{
switch (expr->op)
{
case HLSL_OP1_CAST:
if (instr->data_type->dimx != arg1->node.data_type->dimx
|| instr->data_type->dimy != arg1->node.data_type->dimy)
{
FIXME("Cast from %s to %s.\n", debug_hlsl_type(ctx, arg1->node.data_type),
debug_hlsl_type(ctx, instr->data_type));
vkd3d_free(res);
return false;
}
switch (arg1->node.data_type->base_type)
{
case HLSL_TYPE_INT:
for (i = 0; i < dimx; ++i)
res->value[i].i = arg1->value[i].u;
break;
default:
FIXME("Cast from %s to %s.\n", debug_hlsl_type(ctx, arg1->node.data_type),
debug_hlsl_type(ctx, instr->data_type));
vkd3d_free(res);
return false;
}
break;
case HLSL_OP1_NEG:
for (i = 0; i < instr->data_type->dimx; ++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[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[i].u = arg1->value[i].u * arg2->value[i].u;
break;
default:
FIXME("Fold uint op %#x.\n", expr->op);
vkd3d_free(res);
return false;
}
break;
}
default:
FIXME("Fold type %#x op %#x.\n", instr->data_type->base_type, expr->op);
vkd3d_free(res);
return false;
- }
- list_add_before(&expr->node.entry, &res->node.entry);
- hlsl_replace_node(&expr->node, &res->node);
- return true;
-}
- static bool remove_trivial_swizzles(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) { struct hlsl_ir_swizzle *swizzle;
@@ -1785,7 +1654,7 @@ int hlsl_emit_dxbc(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_fun transform_ir(ctx, lower_narrowing_casts, body, NULL); do {
progress = transform_ir(ctx, fold_constants, body, NULL);
progress = transform_ir(ctx, hlsl_fold_constants, body, NULL); progress |= copy_propagation_execute(ctx, body); } while (progress);
diff --git a/libs/vkd3d-shader/hlsl_constant_ops.c b/libs/vkd3d-shader/hlsl_constant_ops.c new file mode 100644 index 000000000..9e19cef4b --- /dev/null +++ b/libs/vkd3d-shader/hlsl_constant_ops.c @@ -0,0 +1,152 @@ +/*
- HLSL constant value operations for constant folding
- Copyright 2022 Francisco Casas for CodeWeavers
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- */
+#include "hlsl.h"
+bool hlsl_fold_constants(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) +{
- struct hlsl_ir_constant *arg1, *arg2 = NULL, *res;
- struct hlsl_ir_expr *expr;
- unsigned int i, dimx;
- if (instr->type != HLSL_IR_EXPR)
return false;
- expr = hlsl_ir_expr(instr);
- for (i = 0; i < ARRAY_SIZE(expr->operands); ++i)
- {
if (expr->operands[i].node && expr->operands[i].node->type != HLSL_IR_CONSTANT)
return false;
- }
- arg1 = hlsl_ir_constant(expr->operands[0].node);
- if (expr->operands[1].node)
arg2 = hlsl_ir_constant(expr->operands[1].node);
- dimx = instr->data_type->dimx;
- if (!(res = hlsl_alloc(ctx, sizeof(*res))))
return false;
- init_node(&res->node, HLSL_IR_CONSTANT, instr->data_type, instr->loc);
- switch (instr->data_type->base_type)
- {
case HLSL_TYPE_FLOAT:
{
switch (expr->op)
{
case HLSL_OP1_CAST:
if (instr->data_type->dimx != arg1->node.data_type->dimx
|| instr->data_type->dimy != arg1->node.data_type->dimy)
{
FIXME("Cast from %s to %s.\n", debug_hlsl_type(ctx, arg1->node.data_type),
debug_hlsl_type(ctx, instr->data_type));
vkd3d_free(res);
return false;
}
switch (arg1->node.data_type->base_type)
{
case HLSL_TYPE_INT:
for (i = 0; i < dimx; ++i)
res->value[i].f = arg1->value[i].i;
break;
case HLSL_TYPE_UINT:
for (i = 0; i < dimx; ++i)
res->value[i].f = arg1->value[i].u;
break;
default:
FIXME("Cast from %s to %s.\n", debug_hlsl_type(ctx, arg1->node.data_type),
debug_hlsl_type(ctx, instr->data_type));
vkd3d_free(res);
return false;
}
break;
default:
FIXME("Fold float op %#x.\n", expr->op);
vkd3d_free(res);
return false;
}
break;
}
case HLSL_TYPE_UINT:
{
switch (expr->op)
{
case HLSL_OP1_CAST:
if (instr->data_type->dimx != arg1->node.data_type->dimx
|| instr->data_type->dimy != arg1->node.data_type->dimy)
{
FIXME("Cast from %s to %s.\n", debug_hlsl_type(ctx, arg1->node.data_type),
debug_hlsl_type(ctx, instr->data_type));
vkd3d_free(res);
return false;
}
switch (arg1->node.data_type->base_type)
{
case HLSL_TYPE_INT:
for (i = 0; i < dimx; ++i)
res->value[i].i = arg1->value[i].u;
break;
default:
FIXME("Cast from %s to %s.\n", debug_hlsl_type(ctx, arg1->node.data_type),
debug_hlsl_type(ctx, instr->data_type));
vkd3d_free(res);
return false;
}
break;
case HLSL_OP1_NEG:
for (i = 0; i < instr->data_type->dimx; ++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[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[i].u = arg1->value[i].u * arg2->value[i].u;
break;
default:
FIXME("Fold uint op %#x.\n", expr->op);
vkd3d_free(res);
return false;
}
break;
}
default:
FIXME("Fold type %#x op %#x.\n", instr->data_type->base_type, expr->op);
vkd3d_free(res);
return false;
- }
- list_add_before(&expr->node.entry, &res->node.entry);
- hlsl_replace_node(&expr->node, &res->node);
- return true;
+}
Signed-off-by: Matteo Bruni mbruni@codeweavers.com
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
From: Francisco Casas fcasas@codeweavers.com
Signed-off-by: Francisco Casas fcasas@codeweavers.com Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- v3: Resent with some minor modifications: avoid initializers after statements; add line breaks between switch cases; simplify trace messages; make function names into proper verbs.
I don't hold strong opinions one way or another on whether this should live in a separate file.
Makefile.am | 1 - libs/vkd3d-shader/hlsl_constant_ops.c | 328 ++++++++++++++++++-------- 2 files changed, 229 insertions(+), 100 deletions(-)
diff --git a/Makefile.am b/Makefile.am index c3ba3febc..f9f5a3b33 100644 --- a/Makefile.am +++ b/Makefile.am @@ -94,7 +94,6 @@ vkd3d_shader_tests = \ tests/hlsl-vector-indexing.shader_test \ tests/hlsl-vector-indexing-uniform.shader_test \ tests/math.shader_test \ - tests/max.shader_test \ tests/pow.shader_test \ tests/preproc-if.shader_test \ tests/preproc-ifdef.shader_test \ diff --git a/libs/vkd3d-shader/hlsl_constant_ops.c b/libs/vkd3d-shader/hlsl_constant_ops.c index 9e19cef4b..8e48cd8a3 100644 --- a/libs/vkd3d-shader/hlsl_constant_ops.c +++ b/libs/vkd3d-shader/hlsl_constant_ops.c @@ -20,11 +20,213 @@
#include "hlsl.h"
+static bool fold_cast(struct hlsl_ctx *ctx, struct hlsl_ir_constant *dst, + struct hlsl_ir_constant *src) +{ + unsigned int k; + uint32_t u; + int32_t i; + double d; + float f; + bool b; + + if (dst->node.data_type->dimx != src->node.data_type->dimx + || dst->node.data_type->dimy != src->node.data_type->dimy) + { + FIXME("Cast from %s to %s.\n", debug_hlsl_type(ctx, src->node.data_type), + debug_hlsl_type(ctx, dst->node.data_type)); + return false; + } + + for (k = 0; k < 4; k++) + { + switch (src->node.data_type->base_type) + { + case HLSL_TYPE_FLOAT: + case HLSL_TYPE_HALF: + u = src->value[k].f; + i = src->value[k].f; + f = src->value[k].f; + d = src->value[k].f; + b = src->value[k].f; + break; + + case HLSL_TYPE_DOUBLE: + u = src->value[k].d; + i = src->value[k].d; + f = src->value[k].d; + d = src->value[k].d; + b = src->value[k].d; + break; + + case HLSL_TYPE_INT: + u = src->value[k].i; + i = src->value[k].i; + f = src->value[k].i; + d = src->value[k].i; + b = src->value[k].i; + break; + + case HLSL_TYPE_UINT: + u = src->value[k].u; + i = src->value[k].u; + f = src->value[k].u; + d = src->value[k].u; + b = src->value[k].u; + break; + + case HLSL_TYPE_BOOL: + u = src->value[k].b; + i = src->value[k].b; + f = src->value[k].b; + d = src->value[k].b; + b = src->value[k].b; + break; + + default: + FIXME("Cast from %s to %s.\n", debug_hlsl_type(ctx, src->node.data_type), + debug_hlsl_type(ctx, dst->node.data_type)); + return false; + } + + switch (dst->node.data_type->base_type) + { + case HLSL_TYPE_FLOAT: + case HLSL_TYPE_HALF: + dst->value[k].f = f; + break; + + case HLSL_TYPE_DOUBLE: + dst->value[k].d = d; + break; + + case HLSL_TYPE_INT: + dst->value[k].i = i; + break; + + case HLSL_TYPE_UINT: + dst->value[k].u = u; + break; + + case HLSL_TYPE_BOOL: + dst->value[k].b = b; + break; + + default: + FIXME("Cast from %s to %s.\n", debug_hlsl_type(ctx, src->node.data_type), + debug_hlsl_type(ctx, dst->node.data_type)); + return false; + } + } + return true; +} + +static bool fold_neg(struct hlsl_ctx *ctx, struct hlsl_ir_constant *dst, + struct hlsl_ir_constant *src) +{ + enum hlsl_base_type type = dst->node.data_type->base_type; + unsigned int k; + + assert(type == src->node.data_type->base_type); + + for (k = 0; k < 4; k++) + { + switch (type) + { + case HLSL_TYPE_FLOAT: + case HLSL_TYPE_HALF: + dst->value[k].f = -src->value[k].f; + break; + + case HLSL_TYPE_DOUBLE: + dst->value[k].d = -src->value[k].d; + break; + + case HLSL_TYPE_INT: + case HLSL_TYPE_UINT: + dst->value[k].u = -src->value[k].u; + break; + + default: + FIXME("Fold negation for type %s.\n", debug_hlsl_type(ctx, dst->node.data_type)); + return false; + } + } + return true; +} + +static bool fold_add(struct hlsl_ctx *ctx, struct hlsl_ir_constant *dst, + struct hlsl_ir_constant *src1, struct hlsl_ir_constant *src2) +{ + enum hlsl_base_type type = dst->node.data_type->base_type; + unsigned int k; + + assert(type == src1->node.data_type->base_type); + assert(type == src2->node.data_type->base_type); + + for (k = 0; k < 4; k++) + { + switch (type) + { + case HLSL_TYPE_FLOAT: + case HLSL_TYPE_HALF: + dst->value[k].f = src1->value[k].f + src2->value[k].f; + break; + + case HLSL_TYPE_DOUBLE: + dst->value[k].d = src1->value[k].d + src2->value[k].d; + break; + + case HLSL_TYPE_INT: + case HLSL_TYPE_UINT: + dst->value[k].u = src1->value[k].u + src2->value[k].u; + break; + + default: + FIXME("Fold addition for type %s.\n", debug_hlsl_type(ctx, dst->node.data_type)); + return false; + } + } + return true; +} + +static bool fold_mul(struct hlsl_ctx *ctx, struct hlsl_ir_constant *dst, + struct hlsl_ir_constant *src1, struct hlsl_ir_constant *src2) +{ + enum hlsl_base_type type = dst->node.data_type->base_type; + + assert(type == src1->node.data_type->base_type); + assert(type == src2->node.data_type->base_type); + + for (int k = 0; k < 4; k++) + { + switch (type) + { + case HLSL_TYPE_FLOAT: + case HLSL_TYPE_HALF: + dst->value[k].f = src1->value[k].f * src2->value[k].f; + break; + case HLSL_TYPE_DOUBLE: + dst->value[k].d = src1->value[k].d * src2->value[k].d; + break; + case HLSL_TYPE_INT: + case HLSL_TYPE_UINT: + dst->value[k].u = src1->value[k].u * src2->value[k].u; + break; + default: + FIXME("Fold multiplication for type %s.\n", debug_hlsl_type(ctx, dst->node.data_type)); + return false; + } + } + return true; +} + bool hlsl_fold_constants(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) { struct hlsl_ir_constant *arg1, *arg2 = NULL, *res; struct hlsl_ir_expr *expr; - unsigned int i, dimx; + unsigned int i; + bool success;
if (instr->type != HLSL_IR_EXPR) return false; @@ -38,115 +240,43 @@ bool hlsl_fold_constants(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void arg1 = hlsl_ir_constant(expr->operands[0].node); if (expr->operands[1].node) arg2 = hlsl_ir_constant(expr->operands[1].node); - dimx = instr->data_type->dimx;
if (!(res = hlsl_alloc(ctx, sizeof(*res)))) return false; init_node(&res->node, HLSL_IR_CONSTANT, instr->data_type, instr->loc);
- switch (instr->data_type->base_type) + switch (expr->op) { - case HLSL_TYPE_FLOAT: - { - switch (expr->op) - { - case HLSL_OP1_CAST: - if (instr->data_type->dimx != arg1->node.data_type->dimx - || instr->data_type->dimy != arg1->node.data_type->dimy) - { - FIXME("Cast from %s to %s.\n", debug_hlsl_type(ctx, arg1->node.data_type), - debug_hlsl_type(ctx, instr->data_type)); - vkd3d_free(res); - return false; - } - - switch (arg1->node.data_type->base_type) - { - case HLSL_TYPE_INT: - for (i = 0; i < dimx; ++i) - res->value[i].f = arg1->value[i].i; - break; - - case HLSL_TYPE_UINT: - for (i = 0; i < dimx; ++i) - res->value[i].f = arg1->value[i].u; - break; - - default: - FIXME("Cast from %s to %s.\n", debug_hlsl_type(ctx, arg1->node.data_type), - debug_hlsl_type(ctx, instr->data_type)); - vkd3d_free(res); - return false; - } - break; - - default: - FIXME("Fold float op %#x.\n", expr->op); - vkd3d_free(res); - return false; - } + case HLSL_OP1_CAST: + success = fold_cast(ctx, res, arg1); break; - }
- case HLSL_TYPE_UINT: - { - switch (expr->op) - { - case HLSL_OP1_CAST: - if (instr->data_type->dimx != arg1->node.data_type->dimx - || instr->data_type->dimy != arg1->node.data_type->dimy) - { - FIXME("Cast from %s to %s.\n", debug_hlsl_type(ctx, arg1->node.data_type), - debug_hlsl_type(ctx, instr->data_type)); - vkd3d_free(res); - return false; - } - - switch (arg1->node.data_type->base_type) - { - case HLSL_TYPE_INT: - for (i = 0; i < dimx; ++i) - res->value[i].i = arg1->value[i].u; - break; - - default: - FIXME("Cast from %s to %s.\n", debug_hlsl_type(ctx, arg1->node.data_type), - debug_hlsl_type(ctx, instr->data_type)); - vkd3d_free(res); - return false; - } - break; - - case HLSL_OP1_NEG: - for (i = 0; i < instr->data_type->dimx; ++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[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[i].u = arg1->value[i].u * arg2->value[i].u; - break; - - default: - FIXME("Fold uint op %#x.\n", expr->op); - vkd3d_free(res); - return false; - } + case HLSL_OP1_NEG: + success = fold_neg(ctx, res, arg1); + break; + + case HLSL_OP2_ADD: + success = fold_add(ctx, res, arg1, arg2); + break; + + case HLSL_OP2_MUL: + success = fold_mul(ctx, res, arg1, arg2); break; - }
default: - FIXME("Fold type %#x op %#x.\n", instr->data_type->base_type, expr->op); - vkd3d_free(res); - return false; + FIXME("Fold "%s" expression.\n", debug_hlsl_expr_op(expr->op)); + success = false; + break; }
- list_add_before(&expr->node.entry, &res->node.entry); - hlsl_replace_node(&expr->node, &res->node); - return true; + if (success) + { + list_add_before(&expr->node.entry, &res->node.entry); + hlsl_replace_node(&expr->node, &res->node); + } + else + { + vkd3d_free(res); + } + return success; }
Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com --- Though I think you forgot to split the switch cases with newlines in fold_mul().
Also, I wouldn't dislike a small comment saying that we're handling signed integers together with unsigned integers to avoid undefined behavior. It's not necessarily obvious for anybody reading the code.
Il 11/02/22 04:48, Zebediah Figura ha scritto:
From: Francisco Casas fcasas@codeweavers.com
Signed-off-by: Francisco Casas fcasas@codeweavers.com Signed-off-by: Zebediah Figura zfigura@codeweavers.com
v3: Resent with some minor modifications: avoid initializers after statements; add line breaks between switch cases; simplify trace messages; make function names into proper verbs.
I don't hold strong opinions one way or another on whether this should live in a separate file.
Makefile.am | 1 - libs/vkd3d-shader/hlsl_constant_ops.c | 328 ++++++++++++++++++-------- 2 files changed, 229 insertions(+), 100 deletions(-)
diff --git a/Makefile.am b/Makefile.am index c3ba3febc..f9f5a3b33 100644 --- a/Makefile.am +++ b/Makefile.am @@ -94,7 +94,6 @@ vkd3d_shader_tests = \ tests/hlsl-vector-indexing.shader_test \ tests/hlsl-vector-indexing-uniform.shader_test \ tests/math.shader_test \
- tests/max.shader_test \ tests/pow.shader_test \ tests/preproc-if.shader_test \ tests/preproc-ifdef.shader_test \
diff --git a/libs/vkd3d-shader/hlsl_constant_ops.c b/libs/vkd3d-shader/hlsl_constant_ops.c index 9e19cef4b..8e48cd8a3 100644 --- a/libs/vkd3d-shader/hlsl_constant_ops.c +++ b/libs/vkd3d-shader/hlsl_constant_ops.c @@ -20,11 +20,213 @@
#include "hlsl.h"
+static bool fold_cast(struct hlsl_ctx *ctx, struct hlsl_ir_constant *dst,
struct hlsl_ir_constant *src)
+{
- unsigned int k;
- uint32_t u;
- int32_t i;
- double d;
- float f;
- bool b;
- if (dst->node.data_type->dimx != src->node.data_type->dimx
|| dst->node.data_type->dimy != src->node.data_type->dimy)
- {
FIXME("Cast from %s to %s.\n", debug_hlsl_type(ctx, src->node.data_type),
debug_hlsl_type(ctx, dst->node.data_type));
return false;
- }
- for (k = 0; k < 4; k++)
- {
switch (src->node.data_type->base_type)
{
case HLSL_TYPE_FLOAT:
case HLSL_TYPE_HALF:
u = src->value[k].f;
i = src->value[k].f;
f = src->value[k].f;
d = src->value[k].f;
b = src->value[k].f;
break;
case HLSL_TYPE_DOUBLE:
u = src->value[k].d;
i = src->value[k].d;
f = src->value[k].d;
d = src->value[k].d;
b = src->value[k].d;
break;
case HLSL_TYPE_INT:
u = src->value[k].i;
i = src->value[k].i;
f = src->value[k].i;
d = src->value[k].i;
b = src->value[k].i;
break;
case HLSL_TYPE_UINT:
u = src->value[k].u;
i = src->value[k].u;
f = src->value[k].u;
d = src->value[k].u;
b = src->value[k].u;
break;
case HLSL_TYPE_BOOL:
u = src->value[k].b;
i = src->value[k].b;
f = src->value[k].b;
d = src->value[k].b;
b = src->value[k].b;
break;
default:
FIXME("Cast from %s to %s.\n", debug_hlsl_type(ctx, src->node.data_type),
debug_hlsl_type(ctx, dst->node.data_type));
return false;
}
switch (dst->node.data_type->base_type)
{
case HLSL_TYPE_FLOAT:
case HLSL_TYPE_HALF:
dst->value[k].f = f;
break;
case HLSL_TYPE_DOUBLE:
dst->value[k].d = d;
break;
case HLSL_TYPE_INT:
dst->value[k].i = i;
break;
case HLSL_TYPE_UINT:
dst->value[k].u = u;
break;
case HLSL_TYPE_BOOL:
dst->value[k].b = b;
break;
default:
FIXME("Cast from %s to %s.\n", debug_hlsl_type(ctx, src->node.data_type),
debug_hlsl_type(ctx, dst->node.data_type));
return false;
}
- }
- return true;
+}
+static bool fold_neg(struct hlsl_ctx *ctx, struct hlsl_ir_constant *dst,
struct hlsl_ir_constant *src)
+{
- enum hlsl_base_type type = dst->node.data_type->base_type;
- unsigned int k;
- assert(type == src->node.data_type->base_type);
- for (k = 0; k < 4; k++)
- {
switch (type)
{
case HLSL_TYPE_FLOAT:
case HLSL_TYPE_HALF:
dst->value[k].f = -src->value[k].f;
break;
case HLSL_TYPE_DOUBLE:
dst->value[k].d = -src->value[k].d;
break;
case HLSL_TYPE_INT:
case HLSL_TYPE_UINT:
dst->value[k].u = -src->value[k].u;
break;
default:
FIXME("Fold negation for type %s.\n", debug_hlsl_type(ctx, dst->node.data_type));
return false;
}
- }
- return true;
+}
+static bool fold_add(struct hlsl_ctx *ctx, struct hlsl_ir_constant *dst,
struct hlsl_ir_constant *src1, struct hlsl_ir_constant *src2)
+{
- enum hlsl_base_type type = dst->node.data_type->base_type;
- unsigned int k;
- assert(type == src1->node.data_type->base_type);
- assert(type == src2->node.data_type->base_type);
- for (k = 0; k < 4; k++)
- {
switch (type)
{
case HLSL_TYPE_FLOAT:
case HLSL_TYPE_HALF:
dst->value[k].f = src1->value[k].f + src2->value[k].f;
break;
case HLSL_TYPE_DOUBLE:
dst->value[k].d = src1->value[k].d + src2->value[k].d;
break;
case HLSL_TYPE_INT:
case HLSL_TYPE_UINT:
dst->value[k].u = src1->value[k].u + src2->value[k].u;
break;
default:
FIXME("Fold addition for type %s.\n", debug_hlsl_type(ctx, dst->node.data_type));
return false;
}
- }
- return true;
+}
+static bool fold_mul(struct hlsl_ctx *ctx, struct hlsl_ir_constant *dst,
struct hlsl_ir_constant *src1, struct hlsl_ir_constant *src2)
+{
- enum hlsl_base_type type = dst->node.data_type->base_type;
- assert(type == src1->node.data_type->base_type);
- assert(type == src2->node.data_type->base_type);
- for (int k = 0; k < 4; k++)
- {
switch (type)
{
case HLSL_TYPE_FLOAT:
case HLSL_TYPE_HALF:
dst->value[k].f = src1->value[k].f * src2->value[k].f;
break;
case HLSL_TYPE_DOUBLE:
dst->value[k].d = src1->value[k].d * src2->value[k].d;
break;
case HLSL_TYPE_INT:
case HLSL_TYPE_UINT:
dst->value[k].u = src1->value[k].u * src2->value[k].u;
break;
default:
FIXME("Fold multiplication for type %s.\n", debug_hlsl_type(ctx, dst->node.data_type));
return false;
}
- }
- return true;
+}
- bool hlsl_fold_constants(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) { struct hlsl_ir_constant *arg1, *arg2 = NULL, *res; struct hlsl_ir_expr *expr;
- unsigned int i, dimx;
unsigned int i;
bool success;
if (instr->type != HLSL_IR_EXPR) return false;
@@ -38,115 +240,43 @@ bool hlsl_fold_constants(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void arg1 = hlsl_ir_constant(expr->operands[0].node); if (expr->operands[1].node) arg2 = hlsl_ir_constant(expr->operands[1].node);
dimx = instr->data_type->dimx;
if (!(res = hlsl_alloc(ctx, sizeof(*res)))) return false; init_node(&res->node, HLSL_IR_CONSTANT, instr->data_type, instr->loc);
switch (instr->data_type->base_type)
- switch (expr->op) {
case HLSL_TYPE_FLOAT:
{
switch (expr->op)
{
case HLSL_OP1_CAST:
if (instr->data_type->dimx != arg1->node.data_type->dimx
|| instr->data_type->dimy != arg1->node.data_type->dimy)
{
FIXME("Cast from %s to %s.\n", debug_hlsl_type(ctx, arg1->node.data_type),
debug_hlsl_type(ctx, instr->data_type));
vkd3d_free(res);
return false;
}
switch (arg1->node.data_type->base_type)
{
case HLSL_TYPE_INT:
for (i = 0; i < dimx; ++i)
res->value[i].f = arg1->value[i].i;
break;
case HLSL_TYPE_UINT:
for (i = 0; i < dimx; ++i)
res->value[i].f = arg1->value[i].u;
break;
default:
FIXME("Cast from %s to %s.\n", debug_hlsl_type(ctx, arg1->node.data_type),
debug_hlsl_type(ctx, instr->data_type));
vkd3d_free(res);
return false;
}
break;
default:
FIXME("Fold float op %#x.\n", expr->op);
vkd3d_free(res);
return false;
}
case HLSL_OP1_CAST:
success = fold_cast(ctx, res, arg1); break;
}
case HLSL_TYPE_UINT:
{
switch (expr->op)
{
case HLSL_OP1_CAST:
if (instr->data_type->dimx != arg1->node.data_type->dimx
|| instr->data_type->dimy != arg1->node.data_type->dimy)
{
FIXME("Cast from %s to %s.\n", debug_hlsl_type(ctx, arg1->node.data_type),
debug_hlsl_type(ctx, instr->data_type));
vkd3d_free(res);
return false;
}
switch (arg1->node.data_type->base_type)
{
case HLSL_TYPE_INT:
for (i = 0; i < dimx; ++i)
res->value[i].i = arg1->value[i].u;
break;
default:
FIXME("Cast from %s to %s.\n", debug_hlsl_type(ctx, arg1->node.data_type),
debug_hlsl_type(ctx, instr->data_type));
vkd3d_free(res);
return false;
}
break;
case HLSL_OP1_NEG:
for (i = 0; i < instr->data_type->dimx; ++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[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[i].u = arg1->value[i].u * arg2->value[i].u;
break;
default:
FIXME("Fold uint op %#x.\n", expr->op);
vkd3d_free(res);
return false;
}
case HLSL_OP1_NEG:
success = fold_neg(ctx, res, arg1);
break;
case HLSL_OP2_ADD:
success = fold_add(ctx, res, arg1, arg2);
break;
case HLSL_OP2_MUL:
success = fold_mul(ctx, res, arg1, arg2); break;
} default:
FIXME("Fold type %#x op %#x.\n", instr->data_type->base_type, expr->op);
vkd3d_free(res);
return false;
FIXME("Fold \"%s\" expression.\n", debug_hlsl_expr_op(expr->op));
success = false;
break; }
- list_add_before(&expr->node.entry, &res->node.entry);
- hlsl_replace_node(&expr->node, &res->node);
- return true;
- if (success)
- {
list_add_before(&expr->node.entry, &res->node.entry);
hlsl_replace_node(&expr->node, &res->node);
- }
- else
- {
vkd3d_free(res);
- }
- return success; }
Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com
Il 11/02/22 04:48, Zebediah Figura ha scritto:
From: Francisco Casas fcasas@codeweavers.com
Also rename it to hlsl_replace_node().
Signed-off-by: Francisco Casas fcasas@codeweavers.com Signed-off-by: Zebediah Figura zfigura@codeweavers.com
libs/vkd3d-shader/hlsl.c | 14 ++++++++++++++ libs/vkd3d-shader/hlsl.h | 2 ++ libs/vkd3d-shader/hlsl_codegen.c | 25 ++++++------------------- 3 files changed, 22 insertions(+), 19 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index 8a0f4b017..a9a427707 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -1400,6 +1400,20 @@ void hlsl_dump_function(struct hlsl_ctx *ctx, const struct hlsl_ir_function_decl vkd3d_string_buffer_cleanup(&buffer); }
+void hlsl_replace_node(struct hlsl_ir_node *old, struct hlsl_ir_node *new) +{
- struct hlsl_src *src, *next;
- LIST_FOR_EACH_ENTRY_SAFE(src, next, &old->uses, struct hlsl_src, entry)
- {
hlsl_src_remove(src);
hlsl_src_from_node(src, new);
- }
- list_remove(&old->entry);
- hlsl_free_instr(old);
+}
- void hlsl_free_type(struct hlsl_type *type) { struct hlsl_struct_field *field, *next_field;
diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index 3a69165e5..67fe1a8d5 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -713,6 +713,8 @@ void hlsl_dump_function(struct hlsl_ctx *ctx, const struct hlsl_ir_function_decl
int hlsl_emit_dxbc(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func, struct vkd3d_shader_code *out);
+void hlsl_replace_node(struct hlsl_ir_node *old, struct hlsl_ir_node *new);
- void hlsl_free_instr(struct hlsl_ir_node *node); void hlsl_free_instr_list(struct list *list); void hlsl_free_type(struct hlsl_type *type);
diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index eac3513c9..77ddd979a 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -224,19 +224,6 @@ static bool transform_ir(struct hlsl_ctx *ctx, bool (*func)(struct hlsl_ctx *ctx return progress; }
-static void replace_node(struct hlsl_ir_node *old, struct hlsl_ir_node *new) -{
- struct hlsl_src *src, *next;
- LIST_FOR_EACH_ENTRY_SAFE(src, next, &old->uses, struct hlsl_src, entry)
- {
hlsl_src_remove(src);
hlsl_src_from_node(src, new);
- }
- list_remove(&old->entry);
- hlsl_free_instr(old);
-}
- /* Lower casts from vec1 to vecN to swizzles. */ static bool lower_broadcasts(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) {
@@ -267,7 +254,7 @@ static bool lower_broadcasts(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, v return false; list_add_after(&new_cast->node.entry, &swizzle->node.entry);
replace_node(&cast->node, &swizzle->node);
hlsl_replace_node(&cast->node, &swizzle->node); return true; }
@@ -437,7 +424,7 @@ static bool copy_propagation_transform_load(struct hlsl_ctx *ctx, list_add_before(&node->entry, &swizzle_node->node.entry); new_node = &swizzle_node->node; }
- replace_node(node, new_node);
- hlsl_replace_node(node, new_node); return true; }
@@ -566,7 +553,7 @@ static bool fold_redundant_casts(struct hlsl_ctx *ctx, struct hlsl_ir_node *inst if (hlsl_types_are_equal(src_type, dst_type) || (src_type->base_type == dst_type->base_type && is_vec1(src_type) && is_vec1(dst_type))) {
replace_node(&expr->node, expr->operands[0].node);
hlsl_replace_node(&expr->node, expr->operands[0].node); return true; } }
@@ -708,7 +695,7 @@ static bool lower_narrowing_casts(struct hlsl_ctx *ctx, struct hlsl_ir_node *ins return false; list_add_after(&new_cast->node.entry, &swizzle->node.entry);
replace_node(&cast->node, &swizzle->node);
hlsl_replace_node(&cast->node, &swizzle->node); return true; }
@@ -842,7 +829,7 @@ static bool fold_constants(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, voi }
list_add_before(&expr->node.entry, &res->node.entry);
- replace_node(&expr->node, &res->node);
- hlsl_replace_node(&expr->node, &res->node); return true; }
@@ -862,7 +849,7 @@ static bool remove_trivial_swizzles(struct hlsl_ctx *ctx, struct hlsl_ir_node *i if (((swizzle->swizzle >> (2 * i)) & 3) != i) return false;
- replace_node(instr, swizzle->val.node);
hlsl_replace_node(instr, swizzle->val.node);
return true; }