mirror of
https://gitlab.winehq.org/wine/vkd3d.git
synced 2025-09-12 18:50:22 -07:00
vkd3d-shader/ir: Introduce vsir_program_lower_instructions().
It is meant as generic pass to host all program changes to single instructions that do not require keeping a global state, intstead of having to loop through the whole program many times.
This commit is contained in:
committed by
Alexandre Julliard
parent
a7dc6dcce2
commit
8a17a5a08b
Notes:
Alexandre Julliard
2024-04-15 22:23:02 +02:00
Approved-by: Giovanni Mascellani (@giomasce) Approved-by: Conor McCarthy (@cmccarthy) Approved-by: Henri Verbeet (@hverbeet) Approved-by: Alexandre Julliard (@julliard) Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/779
@@ -94,39 +94,33 @@ static bool vsir_instruction_init_with_params(struct vsir_program *program,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static enum vkd3d_result vsir_program_lower_texkills(struct vsir_program *program)
|
static enum vkd3d_result vsir_program_lower_texkill(struct vsir_program *program,
|
||||||
|
struct vkd3d_shader_instruction *texkill, unsigned int *tmp_idx)
|
||||||
{
|
{
|
||||||
|
const unsigned int components_read = 3 + (program->shader_version.major >= 2);
|
||||||
struct vkd3d_shader_instruction_array *instructions = &program->instructions;
|
struct vkd3d_shader_instruction_array *instructions = &program->instructions;
|
||||||
struct vkd3d_shader_instruction *texkill_ins, *ins;
|
size_t pos = texkill - instructions->elements;
|
||||||
unsigned int components_read = 3 + (program->shader_version.major >= 2);
|
struct vkd3d_shader_instruction *ins;
|
||||||
unsigned int tmp_idx = ~0u;
|
unsigned int j;
|
||||||
unsigned int i, k;
|
|
||||||
|
|
||||||
for (i = 0; i < instructions->count; ++i)
|
if (!shader_instruction_array_insert_at(instructions, pos + 1, components_read + 1))
|
||||||
{
|
|
||||||
texkill_ins = &instructions->elements[i];
|
|
||||||
|
|
||||||
if (texkill_ins->handler_idx != VKD3DSIH_TEXKILL)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (!shader_instruction_array_insert_at(instructions, i + 1, components_read + 1))
|
|
||||||
return VKD3D_ERROR_OUT_OF_MEMORY;
|
return VKD3D_ERROR_OUT_OF_MEMORY;
|
||||||
|
|
||||||
if (tmp_idx == ~0u)
|
if (*tmp_idx == ~0u)
|
||||||
tmp_idx = program->temp_count++;
|
*tmp_idx = program->temp_count++;
|
||||||
|
|
||||||
/* tmp = ins->dst[0] < 0 */
|
/* tmp = ins->dst[0] < 0 */
|
||||||
|
|
||||||
ins = &instructions->elements[i + 1];
|
ins = &instructions->elements[pos + 1];
|
||||||
if (!vsir_instruction_init_with_params(program, ins, &texkill_ins->location, VKD3DSIH_LTO, 1, 2))
|
if (!vsir_instruction_init_with_params(program, ins, &texkill->location, VKD3DSIH_LTO, 1, 2))
|
||||||
return VKD3D_ERROR_OUT_OF_MEMORY;
|
return VKD3D_ERROR_OUT_OF_MEMORY;
|
||||||
|
|
||||||
vsir_register_init(&ins->dst[0].reg, VKD3DSPR_TEMP, VKD3D_DATA_UINT, 1);
|
vsir_register_init(&ins->dst[0].reg, VKD3DSPR_TEMP, VKD3D_DATA_UINT, 1);
|
||||||
ins->dst[0].reg.dimension = VSIR_DIMENSION_VEC4;
|
ins->dst[0].reg.dimension = VSIR_DIMENSION_VEC4;
|
||||||
ins->dst[0].reg.idx[0].offset = tmp_idx;
|
ins->dst[0].reg.idx[0].offset = *tmp_idx;
|
||||||
ins->dst[0].write_mask = VKD3DSP_WRITEMASK_ALL;
|
ins->dst[0].write_mask = VKD3DSP_WRITEMASK_ALL;
|
||||||
|
|
||||||
ins->src[0].reg = texkill_ins->dst[0].reg;
|
ins->src[0].reg = texkill->dst[0].reg;
|
||||||
ins->src[0].swizzle = VKD3D_SHADER_NO_SWIZZLE;
|
ins->src[0].swizzle = VKD3D_SHADER_NO_SWIZZLE;
|
||||||
vsir_register_init(&ins->src[1].reg, VKD3DSPR_IMMCONST, VKD3D_DATA_FLOAT, 0);
|
vsir_register_init(&ins->src[1].reg, VKD3DSPR_IMMCONST, VKD3D_DATA_FLOAT, 0);
|
||||||
ins->src[1].reg.dimension = VSIR_DIMENSION_VEC4;
|
ins->src[1].reg.dimension = VSIR_DIMENSION_VEC4;
|
||||||
@@ -139,41 +133,65 @@ static enum vkd3d_result vsir_program_lower_texkills(struct vsir_program *progra
|
|||||||
/* tmp.x = tmp.x || tmp.z */
|
/* tmp.x = tmp.x || tmp.z */
|
||||||
/* tmp.x = tmp.x || tmp.w, if sm >= 2.0 */
|
/* tmp.x = tmp.x || tmp.w, if sm >= 2.0 */
|
||||||
|
|
||||||
for (k = 1; k < components_read; ++k)
|
for (j = 1; j < components_read; ++j)
|
||||||
{
|
{
|
||||||
ins = &instructions->elements[i + 1 + k];
|
ins = &instructions->elements[pos + 1 + j];
|
||||||
if (!(vsir_instruction_init_with_params(program, ins, &texkill_ins->location, VKD3DSIH_OR, 1, 2)))
|
if (!(vsir_instruction_init_with_params(program, ins, &texkill->location, VKD3DSIH_OR, 1, 2)))
|
||||||
return VKD3D_ERROR_OUT_OF_MEMORY;
|
return VKD3D_ERROR_OUT_OF_MEMORY;
|
||||||
|
|
||||||
vsir_register_init(&ins->dst[0].reg, VKD3DSPR_TEMP, VKD3D_DATA_UINT, 1);
|
vsir_register_init(&ins->dst[0].reg, VKD3DSPR_TEMP, VKD3D_DATA_UINT, 1);
|
||||||
ins->dst[0].reg.dimension = VSIR_DIMENSION_VEC4;
|
ins->dst[0].reg.dimension = VSIR_DIMENSION_VEC4;
|
||||||
ins->dst[0].reg.idx[0].offset = tmp_idx;
|
ins->dst[0].reg.idx[0].offset = *tmp_idx;
|
||||||
ins->dst[0].write_mask = VKD3DSP_WRITEMASK_0;
|
ins->dst[0].write_mask = VKD3DSP_WRITEMASK_0;
|
||||||
|
|
||||||
vsir_register_init(&ins->src[0].reg, VKD3DSPR_TEMP, VKD3D_DATA_UINT, 1);
|
vsir_register_init(&ins->src[0].reg, VKD3DSPR_TEMP, VKD3D_DATA_UINT, 1);
|
||||||
ins->src[0].reg.dimension = VSIR_DIMENSION_VEC4;
|
ins->src[0].reg.dimension = VSIR_DIMENSION_VEC4;
|
||||||
ins->src[0].reg.idx[0].offset = tmp_idx;
|
ins->src[0].reg.idx[0].offset = *tmp_idx;
|
||||||
ins->src[0].swizzle = VKD3D_SHADER_SWIZZLE(X, X, X, X);
|
ins->src[0].swizzle = VKD3D_SHADER_SWIZZLE(X, X, X, X);
|
||||||
vsir_register_init(&ins->src[1].reg, VKD3DSPR_TEMP, VKD3D_DATA_UINT, 1);
|
vsir_register_init(&ins->src[1].reg, VKD3DSPR_TEMP, VKD3D_DATA_UINT, 1);
|
||||||
ins->src[1].reg.dimension = VSIR_DIMENSION_VEC4;
|
ins->src[1].reg.dimension = VSIR_DIMENSION_VEC4;
|
||||||
ins->src[1].reg.idx[0].offset = tmp_idx;
|
ins->src[1].reg.idx[0].offset = *tmp_idx;
|
||||||
ins->src[1].swizzle = vkd3d_shader_create_swizzle(k, k, k, k);
|
ins->src[1].swizzle = vkd3d_shader_create_swizzle(j, j, j, j);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* discard_nz tmp.x */
|
/* discard_nz tmp.x */
|
||||||
|
|
||||||
ins = &instructions->elements[i + 1 + components_read];
|
ins = &instructions->elements[pos + 1 + components_read];
|
||||||
if (!(vsir_instruction_init_with_params(program, ins, &texkill_ins->location, VKD3DSIH_DISCARD, 0, 1)))
|
if (!(vsir_instruction_init_with_params(program, ins, &texkill->location, VKD3DSIH_DISCARD, 0, 1)))
|
||||||
return VKD3D_ERROR_OUT_OF_MEMORY;
|
return VKD3D_ERROR_OUT_OF_MEMORY;
|
||||||
ins->flags = VKD3D_SHADER_CONDITIONAL_OP_NZ;
|
ins->flags = VKD3D_SHADER_CONDITIONAL_OP_NZ;
|
||||||
|
|
||||||
vsir_register_init(&ins->src[0].reg, VKD3DSPR_TEMP, VKD3D_DATA_UINT, 1);
|
vsir_register_init(&ins->src[0].reg, VKD3DSPR_TEMP, VKD3D_DATA_UINT, 1);
|
||||||
ins->src[0].reg.dimension = VSIR_DIMENSION_VEC4;
|
ins->src[0].reg.dimension = VSIR_DIMENSION_VEC4;
|
||||||
ins->src[0].reg.idx[0].offset = tmp_idx;
|
ins->src[0].reg.idx[0].offset = *tmp_idx;
|
||||||
ins->src[0].swizzle = VKD3D_SHADER_SWIZZLE(X, X, X, X);
|
ins->src[0].swizzle = VKD3D_SHADER_SWIZZLE(X, X, X, X);
|
||||||
|
|
||||||
/* Make the original instruction no-op */
|
/* Make the original instruction no-op */
|
||||||
vkd3d_shader_instruction_make_nop(texkill_ins);
|
vkd3d_shader_instruction_make_nop(texkill);
|
||||||
|
|
||||||
|
return VKD3D_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static enum vkd3d_result vsir_program_lower_instructions(struct vsir_program *program)
|
||||||
|
{
|
||||||
|
struct vkd3d_shader_instruction_array *instructions = &program->instructions;
|
||||||
|
unsigned int tmp_idx = ~0u, i;
|
||||||
|
enum vkd3d_result ret;
|
||||||
|
|
||||||
|
for (i = 0; i < instructions->count; ++i)
|
||||||
|
{
|
||||||
|
struct vkd3d_shader_instruction *ins = &instructions->elements[i];
|
||||||
|
|
||||||
|
switch (ins->handler_idx)
|
||||||
|
{
|
||||||
|
case VKD3DSIH_TEXKILL:
|
||||||
|
if ((ret = vsir_program_lower_texkill(program, ins, &tmp_idx)) < 0)
|
||||||
|
return ret;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return VKD3D_OK;
|
return VKD3D_OK;
|
||||||
@@ -5751,7 +5769,7 @@ enum vkd3d_result vsir_program_normalise(struct vsir_program *program, uint64_t
|
|||||||
|
|
||||||
remove_dcl_temps(program);
|
remove_dcl_temps(program);
|
||||||
|
|
||||||
if ((result = vsir_program_lower_texkills(program)) < 0)
|
if ((result = vsir_program_lower_instructions(program)) < 0)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
if (program->shader_version.major >= 6)
|
if (program->shader_version.major >= 6)
|
||||||
|
Reference in New Issue
Block a user