From: Francisco Casas fcasas@codeweavers.com
--- libs/vkd3d-shader/hlsl_codegen.c | 43 +++++++++++++++++++++---- tests/swizzle-constant-prop.shader_test | 6 ++-- 2 files changed, 39 insertions(+), 10 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index fdb66c71..1ca35d34 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -719,7 +719,8 @@ static struct hlsl_ir_node *copy_propagation_compute_replacement(struct hlsl_ctx }
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) + const struct copy_propagation_state *state, const struct hlsl_ir_load *load, + unsigned int swizzle, unsigned int comp_count) { const struct hlsl_ir_var *var = load->src.var; union hlsl_constant_value values[4] = {0}; @@ -732,9 +733,10 @@ 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) + for (i = 0; i < comp_count; ++i) { - struct copy_propagation_value *value = copy_propagation_get_value(state, var, start + i); + unsigned int k = start + ((swizzle >> i * 2) & 3); + struct copy_propagation_value *value = copy_propagation_get_value(state, var, k);
if (!value || value->node->type != HLSL_IR_CONSTANT) return NULL; @@ -742,14 +744,16 @@ 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, hlsl_get_vector_type(ctx, load->node.data_type->base_type, comp_count), + &load->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("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, + debug_hlsl_swizzle(swizzle, comp_count), cons); return &cons->node; }
@@ -757,10 +761,10 @@ static bool copy_propagation_transform_load(struct hlsl_ctx *ctx, struct hlsl_ir_load *load, struct copy_propagation_state *state) { struct hlsl_ir_node *instr = &load->node, *new_instr; + unsigned int swizzle = HLSL_SWIZZLE(X, Y, Z, W); struct hlsl_type *type = instr->data_type; struct hlsl_ir_swizzle *swizzle_node; unsigned int dimx = 0; - unsigned int swizzle;
switch (type->type) { @@ -781,7 +785,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_load_constant_replacement(ctx, state, load, swizzle, dimx))) { list_add_before(&instr->entry, &new_instr->entry); hlsl_replace_node(instr, new_instr); @@ -832,6 +836,27 @@ 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; + struct hlsl_type *type = swizzle->node.data_type; + struct hlsl_ir_load *load; + + if (swizzle->val.node->type != HLSL_IR_LOAD) + return false; + load = hlsl_ir_load(swizzle->val.node); + + if ((new_instr = copy_propagation_compute_load_constant_replacement(ctx, state, load, swizzle->swizzle, type->dimx))) + { + 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 +1020,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]