Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com --- libs/vkd3d-shader/hlsl_codegen.c | 60 ++++++++++++++++++++++++++++++++ tests/sampler-offset.shader_test | 6 ++-- 2 files changed, 63 insertions(+), 3 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index 7c401e14..0942a86c 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -406,6 +406,59 @@ static void copy_propagation_set_value(struct copy_propagation_var_def *var_def, } }
+static struct hlsl_ir_node *copy_propagation_compute_constant(struct hlsl_ctx *ctx, struct copy_propagation_state *state, + const struct hlsl_deref *deref, unsigned int count, const struct vkd3d_shader_location *loc) +{ + const struct hlsl_ir_var *var = deref->var; + enum hlsl_base_type type = HLSL_TYPE_VOID; + struct hlsl_ir_constant *constant = NULL; + struct hlsl_ir_node *store_nodes[4]; + unsigned store_components[4]; + unsigned int i, offset; + + if (!hlsl_offset_from_deref(ctx, deref, &offset)) + return NULL; + + if (var->data_type->type != HLSL_CLASS_OBJECT) + assert(offset + count <= var->data_type->reg_size); + + for (i = 0; i < count; ++i) + { + struct copy_propagation_value *value = copy_propagation_get_value(state, var, offset + i); + struct hlsl_ir_node *store_node; + enum hlsl_base_type store_type; + + if (!value) + return NULL; + + store_node = value->node; + if (!store_node || store_node->type != HLSL_IR_CONSTANT) + return NULL; + + store_type = store_node->data_type->base_type; + + if (type == HLSL_TYPE_VOID) + type = store_type; + else if (type != store_type) + return NULL; + + store_nodes[i] = store_node; + store_components[i] = value->component; + } + + if (!(constant = hlsl_new_uint_constant(ctx, 0, loc))) + return NULL; + constant->node.data_type = hlsl_get_vector_type(ctx, type, count); + + for (i = 0; i < count; ++i) + constant->value[i] = hlsl_ir_constant(store_nodes[i])->value[store_components[i]]; + + TRACE("Load from %s[%d-%d] reconstructed as constant value.\n", + var->name, offset, offset + count); + + return &constant->node; +} + static struct hlsl_ir_node *copy_propagation_compute_replacement(struct hlsl_ctx *ctx, const struct copy_propagation_state *state, const struct hlsl_deref *deref, unsigned int count, unsigned int *swizzle) @@ -474,6 +527,13 @@ static bool copy_propagation_transform_load(struct hlsl_ctx *ctx, return false; }
+ if ((new_node = copy_propagation_compute_constant(ctx, state, &load->src, dimx, &node->loc))) + { + list_add_before(&node->entry, &new_node->entry); + hlsl_replace_node(node, new_node); + return true; + } + if ((new_node = copy_propagation_compute_replacement(ctx, state, &load->src, dimx, &swizzle))) { if (type->type != HLSL_CLASS_OBJECT) diff --git a/tests/sampler-offset.shader_test b/tests/sampler-offset.shader_test index f47d5bff..6f8357df 100644 --- a/tests/sampler-offset.shader_test +++ b/tests/sampler-offset.shader_test @@ -22,7 +22,7 @@ float4 main() : sv_target }
[test] -todo draw quad +draw quad probe all rgba (0.1, 0.2, 0.5, 0.0)
@@ -36,7 +36,7 @@ float4 main() : sv_target }
[test] -todo draw quad +draw quad probe all rgba (0.2, 0.2, 0.0, 0.4)
@@ -50,5 +50,5 @@ float4 main() : sv_target }
[test] -todo draw quad +draw quad probe all rgba (0.0, 0.2, 0.0, 0.4)