mirror of
https://gitlab.winehq.org/wine/vkd3d.git
synced 2025-09-12 18:50:22 -07:00
vkd3d-shader: Normalize TEXKILL to use a source register.
This commit is contained in:
committed by
Henri Verbeet
parent
50ca4a2101
commit
315247bf02
Notes:
Henri Verbeet
2025-04-30 17:02:44 +02:00
Approved-by: Francisco Casas (@fcasas) Approved-by: Henri Verbeet (@hverbeet) Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/1475
@@ -1215,6 +1215,7 @@ static void shader_sm1_read_instruction(struct vkd3d_shader_sm1_parser *sm1, str
|
|||||||
struct vkd3d_shader_src_param *src_params, *predicate;
|
struct vkd3d_shader_src_param *src_params, *predicate;
|
||||||
const struct vkd3d_sm1_opcode_info *opcode_info;
|
const struct vkd3d_sm1_opcode_info *opcode_info;
|
||||||
struct vsir_program *program = sm1->p.program;
|
struct vsir_program *program = sm1->p.program;
|
||||||
|
unsigned int vsir_dst_count, vsir_src_count;
|
||||||
struct vkd3d_shader_dst_param *dst_param;
|
struct vkd3d_shader_dst_param *dst_param;
|
||||||
const uint32_t **ptr = &sm1->ptr;
|
const uint32_t **ptr = &sm1->ptr;
|
||||||
uint32_t opcode_token;
|
uint32_t opcode_token;
|
||||||
@@ -1241,6 +1242,17 @@ static void shader_sm1_read_instruction(struct vkd3d_shader_sm1_parser *sm1, str
|
|||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (opcode_info->vkd3d_opcode == VKD3DSIH_TEXKILL)
|
||||||
|
{
|
||||||
|
vsir_src_count = 1;
|
||||||
|
vsir_dst_count = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vsir_src_count = opcode_info->src_count;
|
||||||
|
vsir_dst_count = opcode_info->dst_count;
|
||||||
|
}
|
||||||
|
|
||||||
vsir_instruction_init(ins, &sm1->p.location, opcode_info->vkd3d_opcode);
|
vsir_instruction_init(ins, &sm1->p.location, opcode_info->vkd3d_opcode);
|
||||||
ins->flags = (opcode_token & VKD3D_SM1_INSTRUCTION_FLAGS_MASK) >> VKD3D_SM1_INSTRUCTION_FLAGS_SHIFT;
|
ins->flags = (opcode_token & VKD3D_SM1_INSTRUCTION_FLAGS_MASK) >> VKD3D_SM1_INSTRUCTION_FLAGS_SHIFT;
|
||||||
ins->coissue = opcode_token & VKD3D_SM1_COISSUE;
|
ins->coissue = opcode_token & VKD3D_SM1_COISSUE;
|
||||||
@@ -1248,9 +1260,9 @@ static void shader_sm1_read_instruction(struct vkd3d_shader_sm1_parser *sm1, str
|
|||||||
ins->structured = false;
|
ins->structured = false;
|
||||||
predicated = !!(opcode_token & VKD3D_SM1_INSTRUCTION_PREDICATED);
|
predicated = !!(opcode_token & VKD3D_SM1_INSTRUCTION_PREDICATED);
|
||||||
ins->predicate = predicate = predicated ? vsir_program_get_src_params(program, 1) : NULL;
|
ins->predicate = predicate = predicated ? vsir_program_get_src_params(program, 1) : NULL;
|
||||||
ins->dst_count = opcode_info->dst_count;
|
ins->dst_count = vsir_dst_count;
|
||||||
ins->dst = dst_param = vsir_program_get_dst_params(program, ins->dst_count);
|
ins->dst = dst_param = vsir_program_get_dst_params(program, ins->dst_count);
|
||||||
ins->src_count = opcode_info->src_count;
|
ins->src_count = vsir_src_count;
|
||||||
ins->src = src_params = vsir_program_get_src_params(program, ins->src_count);
|
ins->src = src_params = vsir_program_get_src_params(program, ins->src_count);
|
||||||
if ((!predicate && predicated) || (!src_params && ins->src_count) || (!dst_param && ins->dst_count))
|
if ((!predicate && predicated) || (!src_params && ins->src_count) || (!dst_param && ins->dst_count))
|
||||||
{
|
{
|
||||||
@@ -1298,6 +1310,25 @@ static void shader_sm1_read_instruction(struct vkd3d_shader_sm1_parser *sm1, str
|
|||||||
shader_sm1_read_immconst(sm1, &p, &src_params[0], VSIR_DIMENSION_VEC4, VKD3D_DATA_INT);
|
shader_sm1_read_immconst(sm1, &p, &src_params[0], VSIR_DIMENSION_VEC4, VKD3D_DATA_INT);
|
||||||
shader_sm1_scan_register(sm1, &dst_param->reg, dst_param->write_mask, true);
|
shader_sm1_scan_register(sm1, &dst_param->reg, dst_param->write_mask, true);
|
||||||
}
|
}
|
||||||
|
else if (ins->opcode == VKD3DSIH_TEXKILL)
|
||||||
|
{
|
||||||
|
/* TEXKILL, uniquely, encodes its argument as a destination, when it is
|
||||||
|
* semantically a source. Since we have multiple passes which operate
|
||||||
|
* generically on sources or destinations, normalize that. */
|
||||||
|
const struct vkd3d_shader_register *reg;
|
||||||
|
struct vkd3d_shader_dst_param tmp_dst;
|
||||||
|
|
||||||
|
reg = &tmp_dst.reg;
|
||||||
|
shader_sm1_read_dst_param(sm1, &p, &tmp_dst);
|
||||||
|
shader_sm1_scan_register(sm1, reg, tmp_dst.write_mask, false);
|
||||||
|
|
||||||
|
vsir_src_param_init(&src_params[0], reg->type, reg->data_type, reg->idx_count);
|
||||||
|
src_params[0].reg = *reg;
|
||||||
|
src_params[0].swizzle = vsir_swizzle_from_writemask(tmp_dst.write_mask);
|
||||||
|
|
||||||
|
if (ins->predicate)
|
||||||
|
shader_sm1_read_src_param(sm1, &p, predicate);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Destination token */
|
/* Destination token */
|
||||||
@@ -1834,6 +1865,27 @@ static void d3dbc_write_instruction(struct d3dbc_compiler *d3dbc, const struct v
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void d3dbc_write_texkill(struct d3dbc_compiler *d3dbc, const struct vkd3d_shader_instruction *ins)
|
||||||
|
{
|
||||||
|
const struct vkd3d_shader_register *reg = &ins->src[0].reg;
|
||||||
|
struct vkd3d_shader_instruction tmp;
|
||||||
|
struct vkd3d_shader_dst_param dst;
|
||||||
|
|
||||||
|
/* TEXKILL, uniquely, encodes its argument as a destination, when it is
|
||||||
|
* semantically a source. We store it as a source in vsir, so convert it. */
|
||||||
|
|
||||||
|
vsir_dst_param_init(&dst, reg->type, reg->data_type, reg->idx_count);
|
||||||
|
dst.reg = *reg;
|
||||||
|
dst.write_mask = mask_from_swizzle(ins->src[0].swizzle);
|
||||||
|
|
||||||
|
tmp = *ins;
|
||||||
|
tmp.dst_count = 1;
|
||||||
|
tmp.dst = &dst;
|
||||||
|
tmp.src_count = 0;
|
||||||
|
|
||||||
|
d3dbc_write_instruction(d3dbc, &tmp);
|
||||||
|
}
|
||||||
|
|
||||||
static void d3dbc_write_vsir_def(struct d3dbc_compiler *d3dbc, const struct vkd3d_shader_instruction *ins)
|
static void d3dbc_write_vsir_def(struct d3dbc_compiler *d3dbc, const struct vkd3d_shader_instruction *ins)
|
||||||
{
|
{
|
||||||
const struct vkd3d_shader_version *version = &d3dbc->program->shader_version;
|
const struct vkd3d_shader_version *version = &d3dbc->program->shader_version;
|
||||||
@@ -1938,6 +1990,10 @@ static void d3dbc_write_vsir_instruction(struct d3dbc_compiler *d3dbc, const str
|
|||||||
d3dbc_write_vsir_dcl(d3dbc, ins);
|
d3dbc_write_vsir_dcl(d3dbc, ins);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case VKD3DSIH_TEXKILL:
|
||||||
|
d3dbc_write_texkill(d3dbc, ins);
|
||||||
|
break;
|
||||||
|
|
||||||
case VKD3DSIH_ABS:
|
case VKD3DSIH_ABS:
|
||||||
case VKD3DSIH_ADD:
|
case VKD3DSIH_ADD:
|
||||||
case VKD3DSIH_CMP:
|
case VKD3DSIH_CMP:
|
||||||
@@ -1959,7 +2015,6 @@ static void d3dbc_write_vsir_instruction(struct d3dbc_compiler *d3dbc, const str
|
|||||||
case VKD3DSIH_SINCOS:
|
case VKD3DSIH_SINCOS:
|
||||||
case VKD3DSIH_SLT:
|
case VKD3DSIH_SLT:
|
||||||
case VKD3DSIH_TEX:
|
case VKD3DSIH_TEX:
|
||||||
case VKD3DSIH_TEXKILL:
|
|
||||||
case VKD3DSIH_TEXLDD:
|
case VKD3DSIH_TEXLDD:
|
||||||
d3dbc_write_instruction(d3dbc, ins);
|
d3dbc_write_instruction(d3dbc, ins);
|
||||||
break;
|
break;
|
||||||
|
@@ -9263,10 +9263,10 @@ static void sm1_generate_vsir_instr_jump(struct hlsl_ctx *ctx,
|
|||||||
|
|
||||||
if (jump->type == HLSL_IR_JUMP_DISCARD_NEG)
|
if (jump->type == HLSL_IR_JUMP_DISCARD_NEG)
|
||||||
{
|
{
|
||||||
if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_TEXKILL, 1, 0)))
|
if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_TEXKILL, 0, 1)))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
vsir_dst_from_hlsl_node(&ins->dst[0], ctx, condition);
|
vsir_src_from_hlsl_node(&ins->src[0], ctx, condition, VKD3DSP_WRITEMASK_ALL);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@@ -622,7 +622,7 @@ static enum vkd3d_result vsir_program_lower_texkill(struct vsir_program *program
|
|||||||
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->src[0] < 0 */
|
||||||
|
|
||||||
ins = &instructions->elements[pos + 1];
|
ins = &instructions->elements[pos + 1];
|
||||||
if (!vsir_instruction_init_with_params(program, ins, &texkill->location, VKD3DSIH_LTO, 1, 2))
|
if (!vsir_instruction_init_with_params(program, ins, &texkill->location, VKD3DSIH_LTO, 1, 2))
|
||||||
@@ -633,7 +633,7 @@ static enum vkd3d_result vsir_program_lower_texkill(struct vsir_program *program
|
|||||||
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->dst[0].reg;
|
ins->src[0].reg = texkill->src[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;
|
||||||
|
Reference in New Issue
Block a user