mirror of
https://gitlab.winehq.org/wine/vkd3d.git
synced 2025-09-12 18:50:22 -07:00
vkd3d-shader/hlsl: Mark stores dirty on interlocked operation in vectorize_stores().
This commit is contained in:
committed by
Henri Verbeet
parent
758a4bef09
commit
a975c56695
Notes:
Henri Verbeet
2025-05-05 15:28:08 +02:00
Approved-by: Conor McCarthy (@cmccarthy) Approved-by: Elizabeth Figura (@zfigura) Approved-by: Henri Verbeet (@hverbeet) Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/1470
@@ -2895,6 +2895,16 @@ static void record_vectorizable_store(struct hlsl_ctx *ctx, struct hlsl_block *b
|
|||||||
++state->count;
|
++state->count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void mark_store_groups_dirty(struct hlsl_ctx *ctx,
|
||||||
|
struct vectorize_stores_state *state, struct hlsl_ir_var *var)
|
||||||
|
{
|
||||||
|
for (unsigned int i = 0; i < state->count; ++i)
|
||||||
|
{
|
||||||
|
if (state->groups[i].stores[0]->lhs.var == var)
|
||||||
|
state->groups[i].dirty = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void find_vectorizable_store_groups(struct hlsl_ctx *ctx, struct hlsl_block *block,
|
static void find_vectorizable_store_groups(struct hlsl_ctx *ctx, struct hlsl_block *block,
|
||||||
struct vectorize_stores_state *state)
|
struct vectorize_stores_state *state)
|
||||||
{
|
{
|
||||||
@@ -2908,20 +2918,21 @@ static void find_vectorizable_store_groups(struct hlsl_ctx *ctx, struct hlsl_blo
|
|||||||
}
|
}
|
||||||
else if (instr->type == HLSL_IR_LOAD)
|
else if (instr->type == HLSL_IR_LOAD)
|
||||||
{
|
{
|
||||||
struct hlsl_ir_var *var = hlsl_ir_load(instr)->src.var;
|
|
||||||
|
|
||||||
/* By vectorizing store A with store B, we are effectively moving
|
/* By vectorizing store A with store B, we are effectively moving
|
||||||
* store A down to happen at the same time as store B.
|
* store A down to happen at the same time as store B.
|
||||||
* If there was a load of the same variable between the two, this
|
* If there was a load of the same variable between the two, this
|
||||||
* would be incorrect.
|
* would be incorrect.
|
||||||
* Therefore invalidate all stores to this variable. As above, we
|
* Therefore invalidate all stores to this variable. As above, we
|
||||||
* could be more granular if necessary. */
|
* could be more granular if necessary. */
|
||||||
|
mark_store_groups_dirty(ctx, state, hlsl_ir_load(instr)->src.var);
|
||||||
for (unsigned int i = 0; i < state->count; ++i)
|
|
||||||
{
|
|
||||||
if (state->groups[i].stores[0]->lhs.var == var)
|
|
||||||
state->groups[i].dirty = true;
|
|
||||||
}
|
}
|
||||||
|
else if (instr->type == HLSL_IR_INTERLOCKED)
|
||||||
|
{
|
||||||
|
/* An interlocked operation can be used on shared memory variables,
|
||||||
|
* and it is at the same time both a store and a load, thus, we
|
||||||
|
* should also mark all stores to this variable as dirty once we
|
||||||
|
* find one.*/
|
||||||
|
mark_store_groups_dirty(ctx, state, hlsl_ir_interlocked(instr)->dst.var);
|
||||||
}
|
}
|
||||||
else if (instr->type == HLSL_IR_IF)
|
else if (instr->type == HLSL_IR_IF)
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user