From: Francisco Casas fcasas@codeweavers.com
--- libs/vkd3d-shader/hlsl_codegen.c | 64 +++++++++++++++++++++---- tests/swizzle-constant-prop.shader_test | 6 +-- 2 files changed, 58 insertions(+), 12 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index 9bdbd57c..fdd25c93 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -718,13 +718,32 @@ static struct hlsl_ir_node *copy_propagation_compute_replacement(struct hlsl_ctx return instr; }
-static struct hlsl_ir_node *copy_propagation_compute_load_constant_replacement(struct hlsl_ctx *ctx, - const struct copy_propagation_state *state, const struct hlsl_ir_load *load) +static struct hlsl_ir_node *copy_propagation_compute_constant_replacement(struct hlsl_ctx *ctx, + const struct copy_propagation_state *state, const struct hlsl_ir_node *instr) { - const struct hlsl_ir_var *var = load->src.var; union hlsl_constant_value values[4] = {0}; + const struct hlsl_ir_swizzle *swizzle; + unsigned int start, count, comps, i; + const struct hlsl_ir_load *load; + const struct hlsl_ir_var *var; struct hlsl_ir_constant *cons; - unsigned int start, count, i; + + if (instr->type == HLSL_IR_SWIZZLE && hlsl_ir_swizzle(instr)->val.node->type == HLSL_IR_LOAD) + { + swizzle = hlsl_ir_swizzle(instr); + load = hlsl_ir_load(swizzle->val.node); + } + else if (instr->type == HLSL_IR_LOAD) + { + swizzle = NULL; + load = hlsl_ir_load(instr); + } + else + { + return NULL; + } + + var = load->src.var;
if (load->node.data_type->type != HLSL_CLASS_SCALAR && load->node.data_type->type != HLSL_CLASS_VECTOR) return NULL; @@ -732,9 +751,17 @@ static struct hlsl_ir_node *copy_propagation_compute_load_constant_replacement(s if (!hlsl_component_index_range_from_deref(ctx, &load->src, &start, &count)) return NULL;
- for (i = 0; i < count; ++i) + comps = instr->data_type->dimx; + for (i = 0; i < comps; ++i) { - struct copy_propagation_value *value = copy_propagation_get_value(state, var, start + i); + struct copy_propagation_value *value; + unsigned int k; + + if (swizzle) + k = start + ((swizzle->swizzle >> i * 2) & 3); + else + k = start + i; + value = copy_propagation_get_value(state, var, k);
if (!value || value->node->type != HLSL_IR_CONSTANT) return NULL; @@ -742,14 +769,15 @@ static struct hlsl_ir_node *copy_propagation_compute_load_constant_replacement(s values[i] = hlsl_ir_constant(value->node)->value[value->component]; }
- if (!(cons = hlsl_new_constant(ctx, load->node.data_type, &load->node.loc))) + if (!(cons = hlsl_new_constant(ctx, instr->data_type, &instr->loc))) return NULL; cons->value[0] = values[0]; cons->value[1] = values[1]; cons->value[2] = values[2]; cons->value[3] = values[3];
- TRACE("Load from %s[%u-%u] turned into a constant %p.\n", var->name, start, start + count, cons); + TRACE("Load from %s[%u-%u]%s turned into a constant %p.\n", var->name, start, start + count, + swizzle ? debug_hlsl_swizzle(swizzle->swizzle, comps) : "", cons); return &cons->node; }
@@ -781,7 +809,7 @@ static bool copy_propagation_transform_load(struct hlsl_ctx *ctx, return false; }
- if ((new_instr = copy_propagation_compute_load_constant_replacement(ctx, state, load))) + if ((new_instr = copy_propagation_compute_constant_replacement(ctx, state, &load->node))) { list_add_before(&instr->entry, &new_instr->entry); hlsl_replace_node(instr, new_instr); @@ -832,6 +860,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_constant_replacement(ctx, state, instr))) + { + 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 +1037,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: + progress |= 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 9aed5e19..e9aa52a4 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]