vkd3d-shader/d3dbc: Don't write inconsequential MOVs.

CASTs from floats to integers are implemented as mere MOVs. These often,
but not always, end up moving the value from one register to the same
register.

This patch avoids writing the MOV instructions if they have no effect.
This commit is contained in:
Francisco Casas 2024-05-09 12:32:35 -04:00 committed by Henri Verbeet
parent daa13934a4
commit b92baa40ec
Notes: Henri Verbeet 2024-07-09 21:09:52 +02:00
Approved-by: Elizabeth Figura (@zfigura)
Approved-by: Henri Verbeet (@hverbeet)
Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/893

View File

@ -1882,6 +1882,32 @@ struct sm1_instruction
unsigned int has_dst; unsigned int has_dst;
}; };
static bool is_inconsequential_instr(const struct sm1_instruction *instr)
{
const struct sm1_src_register *src = &instr->srcs[0];
const struct sm1_dst_register *dst = &instr->dst;
unsigned int i;
if (instr->opcode != D3DSIO_MOV)
return false;
if (dst->mod != D3DSPDM_NONE)
return false;
if (src->mod != D3DSPSM_NONE)
return false;
if (src->type != dst->type)
return false;
if (src->reg != dst->reg)
return false;
for (i = 0; i < 4; ++i)
{
if ((dst->writemask & (1 << i)) && (vsir_swizzle_get_component(src->swizzle, i) != i))
return false;
}
return true;
}
static void write_sm1_dst_register(struct vkd3d_bytecode_buffer *buffer, const struct sm1_dst_register *reg) static void write_sm1_dst_register(struct vkd3d_bytecode_buffer *buffer, const struct sm1_dst_register *reg)
{ {
assert(reg->writemask); assert(reg->writemask);
@ -1901,6 +1927,9 @@ static void d3dbc_write_instruction(struct d3dbc_compiler *d3dbc, const struct s
uint32_t token = instr->opcode; uint32_t token = instr->opcode;
unsigned int i; unsigned int i;
if (is_inconsequential_instr(instr))
return;
token |= VKD3D_SM1_INSTRUCTION_FLAGS_MASK & (instr->flags << VKD3D_SM1_INSTRUCTION_FLAGS_SHIFT); token |= VKD3D_SM1_INSTRUCTION_FLAGS_MASK & (instr->flags << VKD3D_SM1_INSTRUCTION_FLAGS_SHIFT);
if (version->major > 1) if (version->major > 1)