This patch is something of an argument for storing the resource and sampler variables as hlsl_src rather than hlsl_deref. I'm still inclined to avoid this, because that would require the variable to be unchanged between the load and resource load, and that feels like a tricky and dangerous invariant to preserve.
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- Makefile.am | 3 --- libs/vkd3d-shader/hlsl_codegen.c | 39 +++++++++++++++++++++++++++++--- 2 files changed, 36 insertions(+), 6 deletions(-)
diff --git a/Makefile.am b/Makefile.am index 0c2fbf7d7..80742d97a 100644 --- a/Makefile.am +++ b/Makefile.am @@ -307,9 +307,6 @@ XFAIL_TESTS = \ tests/hlsl-vector-indexing.shader_test \ tests/hlsl-vector-indexing-uniform.shader_test \ tests/max.shader_test \ - tests/sampler.shader_test \ - tests/texture-load.shader_test \ - tests/texture-load-typed.shader_test \ tests/trigonometry.shader_test endif
diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index 41c48e065..bc2a160cf 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -397,8 +397,8 @@ static struct hlsl_ir_node *copy_propagation_compute_replacement(const struct co return node; }
-static bool copy_propagation_analyze_load(struct hlsl_ctx *ctx, struct hlsl_ir_load *load, - struct copy_propagation_state *state) +static bool copy_propagation_transform_load(struct hlsl_ctx *ctx, + struct hlsl_ir_load *load, struct copy_propagation_state *state) { struct hlsl_ir_node *node = &load->node, *new_node; struct hlsl_type *type = node->data_type; @@ -439,6 +439,35 @@ static bool copy_propagation_analyze_load(struct hlsl_ctx *ctx, struct hlsl_ir_l return true; }
+static bool copy_propagation_transform_object_load(struct hlsl_ctx *ctx, + struct hlsl_deref *deref, struct copy_propagation_state *state) +{ + struct hlsl_ir_load *load; + struct hlsl_ir_node *node; + unsigned int swizzle; + + if (!(node = copy_propagation_compute_replacement(state, deref, 1, &swizzle))) + return false; + + /* Only HLSL_IR_LOAD can produce an object. */ + load = hlsl_ir_load(node); + deref->var = load->src.var; + hlsl_src_remove(&deref->offset); + hlsl_src_from_node(&deref->offset, load->src.offset.node); + return true; +} + +static bool copy_propagation_transform_resource_load(struct hlsl_ctx *ctx, + struct hlsl_ir_resource_load *load, struct copy_propagation_state *state) +{ + bool progress = false; + + progress |= copy_propagation_transform_object_load(ctx, &load->resource, state); + if (load->sampler.var) + progress |= copy_propagation_transform_object_load(ctx, &load->sampler, state); + return progress; +} + static void copy_propagation_record_store(struct hlsl_ctx *ctx, struct hlsl_ir_store *store, struct copy_propagation_state *state) { @@ -475,7 +504,11 @@ static bool copy_propagation_transform_block(struct hlsl_ctx *ctx, struct hlsl_b switch (instr->type) { case HLSL_IR_LOAD: - progress |= copy_propagation_analyze_load(ctx, hlsl_ir_load(instr), state); + progress |= copy_propagation_transform_load(ctx, hlsl_ir_load(instr), state); + break; + + case HLSL_IR_RESOURCE_LOAD: + progress |= copy_propagation_transform_resource_load(ctx, hlsl_ir_resource_load(instr), state); break;
case HLSL_IR_STORE: