Module: vkd3d Branch: master Commit: 1bba18aa75863ba862b1ff90fd31ee74fd6ec7ef URL: https://gitlab.winehq.org/wine/vkd3d/-/commit/1bba18aa75863ba862b1ff90fd31ee...
Author: Francisco Casas fcasas@codeweavers.com Date: Wed Jul 20 17:42:13 2022 -0400
vkd3d-shader/hlsl: Invalidate components more precisely in copy propagation.
Signed-off-by: Francisco Casas fcasas@codeweavers.com
---
libs/vkd3d-shader/hlsl.c | 17 +++++++++++ libs/vkd3d-shader/hlsl.h | 1 + libs/vkd3d-shader/hlsl_codegen.c | 63 ++++++++++++++++++++++++++++++++-------- 3 files changed, 69 insertions(+), 12 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index b3c02e18..38df7e8a 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -140,6 +140,23 @@ unsigned int hlsl_type_major_size(const struct hlsl_type *type) return type->dimx; }
+unsigned int hlsl_type_element_count(const struct hlsl_type *type) +{ + switch (type->type) + { + case HLSL_CLASS_VECTOR: + return type->dimx; + case HLSL_CLASS_MATRIX: + return hlsl_type_major_size(type); + case HLSL_CLASS_ARRAY: + return type->e.array.elements_count; + case HLSL_CLASS_STRUCT: + return type->e.record.field_count; + default: + return 0; + } +} + static unsigned int get_array_size(const struct hlsl_type *type) { if (type->type == HLSL_CLASS_ARRAY) diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index d63fef97..54902c37 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -814,6 +814,7 @@ struct hlsl_type *hlsl_type_get_component_type(struct hlsl_ctx *ctx, struct hlsl bool hlsl_type_is_row_major(const struct hlsl_type *type); unsigned int hlsl_type_minor_size(const struct hlsl_type *type); unsigned int hlsl_type_major_size(const struct hlsl_type *type); +unsigned int hlsl_type_element_count(const struct hlsl_type *type); unsigned int hlsl_type_get_sm4_offset(const struct hlsl_type *type, unsigned int offset); bool hlsl_types_are_equal(const struct hlsl_type *t1, const struct hlsl_type *t2);
diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index 9e234ca3..7f76fce1 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -606,15 +606,58 @@ static void copy_propagation_invalidate_variable(struct copy_propagation_var_def } }
-static void copy_propagation_invalidate_whole_variable(struct copy_propagation_var_def *var_def) +static void copy_propagation_invalidate_variable_from_deref_recurse(struct hlsl_ctx *ctx, + struct copy_propagation_var_def *var_def, const struct hlsl_deref *deref, + struct hlsl_type *type, unsigned int depth, unsigned int comp_start, unsigned char writemask) { - unsigned int component_count = hlsl_type_component_count(var_def->var->data_type); - unsigned i; + unsigned int i, subtype_comp_count; + struct hlsl_ir_node *path_node; + struct hlsl_type *subtype;
- TRACE("Invalidate variable %s.\n", var_def->var->name); + if (depth == deref->path_len) + { + copy_propagation_invalidate_variable(var_def, comp_start, writemask); + return; + }
- for (i = 0; i < component_count; ++i) - var_def->values[i].state = VALUE_STATE_DYNAMICALLY_WRITTEN; + path_node = deref->path[depth].node; + subtype = hlsl_get_element_type_from_path_index(ctx, type, path_node); + + if (type->type == HLSL_CLASS_STRUCT) + { + unsigned int idx = hlsl_ir_constant(path_node)->value[0].u; + + for (i = 0; i < idx; ++i) + comp_start += hlsl_type_component_count(type->e.record.fields[i].type); + + copy_propagation_invalidate_variable_from_deref_recurse(ctx, var_def, deref, subtype, + depth + 1, comp_start, writemask); + } + else + { + subtype_comp_count = hlsl_type_component_count(subtype); + + if (path_node->type == HLSL_IR_CONSTANT) + { + copy_propagation_invalidate_variable_from_deref_recurse(ctx, var_def, deref, subtype, + depth + 1, hlsl_ir_constant(path_node)->value[0].u * subtype_comp_count, writemask); + } + else + { + for (i = 0; i < hlsl_type_element_count(type); ++i) + { + copy_propagation_invalidate_variable_from_deref_recurse(ctx, var_def, deref, subtype, + depth + 1, i * subtype_comp_count, writemask); + } + } + } +} + +static void copy_propagation_invalidate_variable_from_deref(struct hlsl_ctx *ctx, + struct copy_propagation_var_def *var_def, const struct hlsl_deref *deref, unsigned char writemask) +{ + copy_propagation_invalidate_variable_from_deref_recurse(ctx, var_def, deref, deref->var->data_type, + 0, 0, writemask); }
static void copy_propagation_set_value(struct copy_propagation_var_def *var_def, unsigned int comp, @@ -765,7 +808,7 @@ static void copy_propagation_record_store(struct hlsl_ctx *ctx, struct hlsl_ir_s } else { - copy_propagation_invalidate_whole_variable(var_def); + copy_propagation_invalidate_variable_from_deref(ctx, var_def, lhs, store->writemask); } }
@@ -796,15 +839,11 @@ static void copy_propagation_invalidate_from_block(struct hlsl_ctx *ctx, struct struct copy_propagation_var_def *var_def; struct hlsl_deref *lhs = &store->lhs; struct hlsl_ir_var *var = lhs->var; - unsigned int start, count;
if (!(var_def = copy_propagation_create_var_def(ctx, state, var))) continue;
- if (hlsl_component_index_range_from_deref(ctx, lhs, &start, &count)) - copy_propagation_invalidate_variable(var_def, start, store->writemask); - else - copy_propagation_invalidate_whole_variable(var_def); + copy_propagation_invalidate_variable_from_deref(ctx, var_def, lhs, store->writemask);
break; }