vkd3d-shader/hlsl: Apply copy propagation to swizzled loads.

This commit is contained in:
Zebediah Figura 2023-01-12 17:26:03 -06:00 committed by Alexandre Julliard
parent 18adf0d726
commit b7d34e8307
Notes: Alexandre Julliard 2023-01-24 22:27:58 +01:00
Approved-by: Giovanni Mascellani (@giomasce)
Approved-by: Zebediah Figura (@zfigura)
Approved-by: Henri Verbeet (@hverbeet)
Approved-by: Alexandre Julliard (@julliard)
Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/51
2 changed files with 52 additions and 22 deletions

View File

@ -556,6 +556,9 @@ static bool lower_broadcasts(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, v
* store instructions, as long as the rhs is the same in every case. This basic
* detection is implemented by copy_propagation_replace_with_single_instr().
*
* In some cases, the load itself might not have a single source, but a
* subsequent swizzle might; hence we also try to replace swizzles of loads.
*
* We use the same infrastructure to implement a more specialized
* transformation. We recognize sequences of the form:
*
@ -770,11 +773,11 @@ static void copy_propagation_set_value(struct copy_propagation_var_def *var_def,
}
static bool copy_propagation_replace_with_single_instr(struct hlsl_ctx *ctx,
const struct copy_propagation_state *state, struct hlsl_ir_load *load)
const struct copy_propagation_state *state, const struct hlsl_deref *deref,
unsigned int swizzle, struct hlsl_ir_node *instr)
{
const struct hlsl_deref *deref = &load->src;
const unsigned int instr_component_count = hlsl_type_component_count(instr->data_type);
const struct hlsl_ir_var *var = deref->var;
struct hlsl_ir_node *instr = &load->node;
struct hlsl_ir_node *new_instr = NULL;
unsigned int start, count, i;
unsigned int ret_swizzle = 0;
@ -782,11 +785,11 @@ static bool copy_propagation_replace_with_single_instr(struct hlsl_ctx *ctx,
if (!hlsl_component_index_range_from_deref(ctx, deref, &start, &count))
return false;
for (i = 0; i < count; ++i)
for (i = 0; i < instr_component_count; ++i)
{
struct copy_propagation_value *value = copy_propagation_get_value(state, var, start + i);
struct copy_propagation_value *value;
if (!value)
if (!(value = copy_propagation_get_value(state, var, start + hlsl_swizzle_get_component(swizzle, i))))
return false;
if (!new_instr)
@ -795,14 +798,16 @@ static bool copy_propagation_replace_with_single_instr(struct hlsl_ctx *ctx,
}
else if (new_instr != value->node)
{
TRACE("No single source for propagating load from %s[%u-%u].\n", var->name, start, start + count);
TRACE("No single source for propagating load from %s[%u-%u]%s\n",
var->name, start, start + count, debug_hlsl_swizzle(swizzle, instr_component_count));
return false;
}
ret_swizzle |= value->component << HLSL_SWIZZLE_SHIFT(i);
}
TRACE("Load from %s[%u-%u] propagated as instruction %p%s.\n",
var->name, start, start + count, new_instr, debug_hlsl_swizzle(ret_swizzle, count));
TRACE("Load from %s[%u-%u]%s propagated as instruction %p%s.\n",
var->name, start, start + count, debug_hlsl_swizzle(swizzle, instr_component_count),
new_instr, debug_hlsl_swizzle(ret_swizzle, instr_component_count));
if (instr->data_type->type != HLSL_CLASS_OBJECT)
{
@ -819,22 +824,24 @@ static bool copy_propagation_replace_with_single_instr(struct hlsl_ctx *ctx,
}
static bool copy_propagation_replace_with_constant_vector(struct hlsl_ctx *ctx,
const struct copy_propagation_state *state, struct hlsl_ir_load *load)
const struct copy_propagation_state *state, const struct hlsl_deref *deref,
unsigned int swizzle, struct hlsl_ir_node *instr)
{
const struct hlsl_ir_var *var = load->src.var;
const unsigned int instr_component_count = hlsl_type_component_count(instr->data_type);
const struct hlsl_ir_var *var = deref->var;
union hlsl_constant_value values[4] = {0};
struct hlsl_ir_node *instr = &load->node;
struct hlsl_ir_constant *cons;
unsigned int start, count, i;
if (!hlsl_component_index_range_from_deref(ctx, &load->src, &start, &count))
if (!hlsl_component_index_range_from_deref(ctx, deref, &start, &count))
return false;
for (i = 0; i < count; ++i)
for (i = 0; i < instr_component_count; ++i)
{
struct copy_propagation_value *value = copy_propagation_get_value(state, var, start + i);
struct copy_propagation_value *value;
if (!value || value->node->type != HLSL_IR_CONSTANT)
if (!(value = copy_propagation_get_value(state, var, start + hlsl_swizzle_get_component(swizzle, i)))
|| value->node->type != HLSL_IR_CONSTANT)
return false;
values[i] = hlsl_ir_constant(value->node)->value[value->component];
@ -848,7 +855,8 @@ static bool copy_propagation_replace_with_constant_vector(struct hlsl_ctx *ctx,
cons->value[3] = values[3];
list_add_before(&instr->entry, &cons->node.entry);
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, instr_component_count), cons);
hlsl_replace_node(instr, &cons->node);
return true;
@ -874,10 +882,28 @@ static bool copy_propagation_transform_load(struct hlsl_ctx *ctx,
return false;
}
if (copy_propagation_replace_with_constant_vector(ctx, state, load))
if (copy_propagation_replace_with_constant_vector(ctx, state, &load->src, HLSL_SWIZZLE(X, Y, Z, W), &load->node))
return true;
if (copy_propagation_replace_with_single_instr(ctx, state, load))
if (copy_propagation_replace_with_single_instr(ctx, state, &load->src, HLSL_SWIZZLE(X, Y, Z, W), &load->node))
return true;
return false;
}
static bool copy_propagation_transform_swizzle(struct hlsl_ctx *ctx,
struct hlsl_ir_swizzle *swizzle, struct copy_propagation_state *state)
{
struct hlsl_ir_load *load;
if (swizzle->val.node->type != HLSL_IR_LOAD)
return false;
load = hlsl_ir_load(swizzle->val.node);
if (copy_propagation_replace_with_constant_vector(ctx, state, &load->src, swizzle->swizzle, &swizzle->node))
return true;
if (copy_propagation_replace_with_single_instr(ctx, state, &load->src, swizzle->swizzle, &swizzle->node))
return true;
return false;
@ -1081,6 +1107,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;

View File

@ -13,7 +13,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;
@ -25,8 +25,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]