From: Francisco Casas fcasas@codeweavers.com
--- libs/vkd3d-shader/hlsl_codegen.c | 68 +++++++++++++++++++++++++ tests/swizzle-constant-prop.shader_test | 6 +-- 2 files changed, 71 insertions(+), 3 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index 9bdbd57c..4cd08be9 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -753,6 +753,56 @@ static struct hlsl_ir_node *copy_propagation_compute_load_constant_replacement(s return &cons->node; }
+static struct hlsl_ir_node *copy_propagation_compute_swizzle_constant_replacement(struct hlsl_ctx *ctx, + const struct copy_propagation_state *state, const struct hlsl_ir_swizzle *swizzle) +{ + unsigned int start, count, i, c, swizzle_bits, n_comps; + union hlsl_constant_value values[4] = {0}; + const struct hlsl_ir_load *load; + struct hlsl_ir_constant *cons; + const struct hlsl_ir_var *var; + + if (swizzle->val.node->type != HLSL_IR_LOAD) + return NULL; + load = hlsl_ir_load(swizzle->val.node); + var = load->src.var; + + if (load->node.data_type->type != HLSL_CLASS_SCALAR && load->node.data_type->type != HLSL_CLASS_VECTOR) + return NULL; + + if (!hlsl_component_index_range_from_deref(ctx, &load->src, &start, &count)) + return NULL; + + swizzle_bits = swizzle->swizzle; + n_comps = swizzle->node.data_type->dimx; + for (i = 0; i < n_comps; ++i) + { + struct copy_propagation_value *value; + + c = swizzle_bits & 3; + assert(c < count); + value = copy_propagation_get_value(state, var, start + c); + + if (!value || value->node->type != HLSL_IR_CONSTANT) + return NULL; + + values[i] = hlsl_ir_constant(value->node)->value[value->component]; + + swizzle_bits >>= 2; + } + + if (!(cons = hlsl_new_constant(ctx, swizzle->node.data_type, &swizzle->node.loc))) + return NULL; + cons->value[0] = values[0]; + cons->value[1] = values[1]; + cons->value[2] = values[2]; + cons->value[3] = values[3]; + + TRACE("Swizzle from %s[%u-%u]%s turned into a constant %p.\n", var->name, start, start + count, + debug_hlsl_swizzle(swizzle->swizzle, n_comps), cons); + return &cons->node; +} + static bool copy_propagation_transform_load(struct hlsl_ctx *ctx, struct hlsl_ir_load *load, struct copy_propagation_state *state) { @@ -832,6 +882,20 @@ static bool copy_propagation_transform_resource_load(struct hlsl_ctx *ctx, return progress; }
+static bool copy_propagation_transform_swizzle(struct hlsl_ctx *ctx, + struct hlsl_ir_swizzle *swizzle, struct copy_propagation_state *state) +{ + struct hlsl_ir_node *instr = &swizzle->node, *new_instr; + + if ((new_instr = copy_propagation_compute_swizzle_constant_replacement(ctx, state, swizzle))) + { + list_add_before(&instr->entry, &new_instr->entry); + hlsl_replace_node(instr, new_instr); + return true; + } + return false; +} + static bool copy_propagation_transform_resource_store(struct hlsl_ctx *ctx, struct hlsl_ir_resource_store *store, struct copy_propagation_state *state) { @@ -995,6 +1059,10 @@ static bool copy_propagation_transform_block(struct hlsl_ctx *ctx, struct hlsl_b copy_propagation_record_store(ctx, hlsl_ir_store(instr), state); break;
+ case HLSL_IR_SWIZZLE: + copy_propagation_transform_swizzle(ctx, hlsl_ir_swizzle(instr), state); + break; + case HLSL_IR_IF: progress |= copy_propagation_process_if(ctx, hlsl_ir_if(instr), state); break; diff --git a/tests/swizzle-constant-prop.shader_test b/tests/swizzle-constant-prop.shader_test index 0a13b4df..86eb3f19 100644 --- a/tests/swizzle-constant-prop.shader_test +++ b/tests/swizzle-constant-prop.shader_test @@ -10,7 +10,7 @@ size (4, 4) 13 13 13 13 14 14 14 14 14 15 15 15 16 16 16 16
-[pixel shader todo] +[pixel shader] Texture2D tex; uniform int i;
@@ -22,8 +22,8 @@ float4 main() : sv_target
[test] uniform 0 int 4 -todo draw quad -todo probe all rgba (110, 210, 410, 410) +draw quad +probe all rgba (110, 210, 410, 410)
[pixel shader todo]