[PATCH vkd3d 8/8] vkd3d-shader/hlsl: Propagate constant loads.

Francisco Casas fcasas at codeweavers.com
Wed May 4 14:57:56 CDT 2022


Signed-off-by: Francisco Casas <fcasas at codeweavers.com>

However, I wonder if we can achieve the same result lowering the loads
from a constant value, and that have a constant offset in hlsl_fold_constants().



May 3, 2022 6:14 AM, "Giovanni Mascellani" <gmascellani at codeweavers.com> wrote:

> Signed-off-by: Giovanni Mascellani <gmascellani at 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)
> -- 
> 2.36.0



More information about the wine-devel mailing list