vkd3d-shader/hlsl: Introduce vsir_src_from_hlsl_node().

This allows constants to be inlined for sm4.
This commit is contained in:
Francisco Casas 2024-10-25 21:37:35 -03:00 committed by Henri Verbeet
parent 6f52bb6b1a
commit 404644bad3
Notes: Henri Verbeet 2024-11-04 17:12:25 +01:00
Approved-by: Elizabeth Figura (@zfigura)
Approved-by: Henri Verbeet (@hverbeet)
Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/1242

View File

@ -6615,7 +6615,7 @@ static enum vkd3d_data_type vsir_data_type_from_hlsl_instruction(struct hlsl_ctx
return vsir_data_type_from_hlsl_type(ctx, instr->data_type); return vsir_data_type_from_hlsl_type(ctx, instr->data_type);
} }
static uint32_t sm1_generate_vsir_get_src_swizzle(uint32_t src_writemask, uint32_t dst_writemask) static uint32_t generate_vsir_get_src_swizzle(uint32_t src_writemask, uint32_t dst_writemask)
{ {
uint32_t swizzle; uint32_t swizzle;
@ -6773,6 +6773,50 @@ static struct vkd3d_shader_instruction *generate_vsir_add_program_instruction(
return ins; return ins;
} }
static void vsir_src_from_hlsl_constant_value(struct vkd3d_shader_src_param *src,
struct hlsl_ctx *ctx, const struct hlsl_constant_value *value,
enum vkd3d_data_type type, unsigned int width, unsigned int map_writemask)
{
unsigned int i, j;
vsir_src_param_init(src, VKD3DSPR_IMMCONST, type, 0);
if (width == 1)
{
src->reg.u.immconst_u32[0] = value->u[0].u;
return;
}
src->reg.dimension = VSIR_DIMENSION_VEC4;
for (i = 0, j = 0; i < 4; ++i)
{
if ((map_writemask & (1u << i)) && (j < width))
src->reg.u.immconst_u32[i] = value->u[j++].u;
else
src->reg.u.immconst_u32[i] = 0;
}
}
static void vsir_src_from_hlsl_node(struct vkd3d_shader_src_param *src,
struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, uint32_t map_writemask)
{
struct hlsl_ir_constant *constant;
if (hlsl_version_ge(ctx, 4, 0) && instr->type == HLSL_IR_CONSTANT)
{
/* In SM4 constants are inlined */
constant = hlsl_ir_constant(instr);
vsir_src_from_hlsl_constant_value(src, ctx, &constant->value,
vsir_data_type_from_hlsl_instruction(ctx, instr), instr->data_type->dimx, map_writemask);
}
else
{
vsir_register_init(&src->reg, VKD3DSPR_TEMP, vsir_data_type_from_hlsl_instruction(ctx, instr), 1);
src->reg.idx[0].offset = instr->reg.id;
src->reg.dimension = VSIR_DIMENSION_VEC4;
src->swizzle = generate_vsir_get_src_swizzle(instr->reg.writemask, map_writemask);
}
}
static void sm1_generate_vsir_instr_constant(struct hlsl_ctx *ctx, static void sm1_generate_vsir_instr_constant(struct hlsl_ctx *ctx,
struct vsir_program *program, struct hlsl_ir_constant *constant) struct vsir_program *program, struct hlsl_ir_constant *constant)
{ {
@ -6790,7 +6834,7 @@ static void sm1_generate_vsir_instr_constant(struct hlsl_ctx *ctx,
src_param = &ins->src[0]; src_param = &ins->src[0];
vsir_register_init(&src_param->reg, VKD3DSPR_CONST, VKD3D_DATA_FLOAT, 1); vsir_register_init(&src_param->reg, VKD3DSPR_CONST, VKD3D_DATA_FLOAT, 1);
src_param->reg.idx[0].offset = constant->reg.id; src_param->reg.idx[0].offset = constant->reg.id;
src_param->swizzle = sm1_generate_vsir_get_src_swizzle(constant->reg.writemask, instr->reg.writemask); src_param->swizzle = generate_vsir_get_src_swizzle(constant->reg.writemask, instr->reg.writemask);
dst_param = &ins->dst[0]; dst_param = &ins->dst[0];
vsir_register_init(&dst_param->reg, VKD3DSPR_TEMP, VKD3D_DATA_FLOAT, 1); vsir_register_init(&dst_param->reg, VKD3DSPR_TEMP, VKD3D_DATA_FLOAT, 1);
@ -6832,9 +6876,7 @@ static void sm1_generate_vsir_instr_expr_single_instr_op(struct hlsl_ctx *ctx, s
struct hlsl_ir_node *operand = expr->operands[i].node; struct hlsl_ir_node *operand = expr->operands[i].node;
src_param = &ins->src[i]; src_param = &ins->src[i];
vsir_register_init(&src_param->reg, VKD3DSPR_TEMP, VKD3D_DATA_FLOAT, 1); vsir_src_from_hlsl_node(src_param, ctx, operand,
src_param->reg.idx[0].offset = operand->reg.id;
src_param->swizzle = sm1_generate_vsir_get_src_swizzle(operand->reg.writemask,
map_src_swizzles ? dst_param->write_mask : VKD3DSP_WRITEMASK_ALL); map_src_swizzles ? dst_param->write_mask : VKD3DSP_WRITEMASK_ALL);
src_param->modifiers = src_mod; src_param->modifiers = src_mod;
} }
@ -6856,7 +6898,7 @@ static void sm1_generate_vsir_instr_expr_per_component_instr_op(struct hlsl_ctx
VKD3D_ASSERT(instr->reg.allocated); VKD3D_ASSERT(instr->reg.allocated);
VKD3D_ASSERT(operand); VKD3D_ASSERT(operand);
src_swizzle = sm1_generate_vsir_get_src_swizzle(operand->reg.writemask, instr->reg.writemask); src_swizzle = generate_vsir_get_src_swizzle(operand->reg.writemask, instr->reg.writemask);
for (i = 0; i < 4; ++i) for (i = 0; i < 4; ++i)
{ {
if (instr->reg.writemask & (1u << i)) if (instr->reg.writemask & (1u << i))
@ -6902,7 +6944,7 @@ static void sm1_generate_vsir_instr_expr_sincos(struct hlsl_ctx *ctx, struct vsi
src_param = &ins->src[0]; src_param = &ins->src[0];
vsir_register_init(&src_param->reg, VKD3DSPR_TEMP, VKD3D_DATA_FLOAT, 1); vsir_register_init(&src_param->reg, VKD3DSPR_TEMP, VKD3D_DATA_FLOAT, 1);
src_param->reg.idx[0].offset = operand->reg.id; src_param->reg.idx[0].offset = operand->reg.id;
src_param->swizzle = sm1_generate_vsir_get_src_swizzle(operand->reg.writemask, VKD3DSP_WRITEMASK_ALL); src_param->swizzle = generate_vsir_get_src_swizzle(operand->reg.writemask, VKD3DSP_WRITEMASK_ALL);
if (ctx->profile->major_version < 3) if (ctx->profile->major_version < 3)
{ {
@ -7263,7 +7305,7 @@ static void sm1_generate_vsir_init_src_param_from_deref(struct hlsl_ctx *ctx,
vsir_register_init(&src_param->reg, type, VKD3D_DATA_FLOAT, 1); vsir_register_init(&src_param->reg, type, VKD3D_DATA_FLOAT, 1);
src_param->reg.idx[0].offset = register_index; src_param->reg.idx[0].offset = register_index;
src_param->swizzle = sm1_generate_vsir_get_src_swizzle(writemask, dst_writemask); src_param->swizzle = generate_vsir_get_src_swizzle(writemask, dst_writemask);
if (deref->rel_offset.node) if (deref->rel_offset.node)
hlsl_fixme(ctx, loc, "Translate relative addressing on src register for vsir."); hlsl_fixme(ctx, loc, "Translate relative addressing on src register for vsir.");
@ -7342,9 +7384,7 @@ static void sm1_generate_vsir_instr_resource_load(struct hlsl_ctx *ctx,
dst_param->write_mask = instr->reg.writemask; dst_param->write_mask = instr->reg.writemask;
src_param = &ins->src[0]; src_param = &ins->src[0];
vsir_register_init(&src_param->reg, VKD3DSPR_TEMP, VKD3D_DATA_FLOAT, 1); vsir_src_from_hlsl_node(src_param, ctx, coords, VKD3DSP_WRITEMASK_ALL);
src_param->reg.idx[0].offset = coords->reg.id;
src_param->swizzle = sm1_generate_vsir_get_src_swizzle(coords->reg.writemask, VKD3DSP_WRITEMASK_ALL);
sm1_generate_vsir_init_src_param_from_deref(ctx, &ins->src[1], &load->resource, sm1_generate_vsir_init_src_param_from_deref(ctx, &ins->src[1], &load->resource,
VKD3DSP_WRITEMASK_ALL, &ins->location); VKD3DSP_WRITEMASK_ALL, &ins->location);
@ -7352,14 +7392,10 @@ static void sm1_generate_vsir_instr_resource_load(struct hlsl_ctx *ctx,
if (load->load_type == HLSL_RESOURCE_SAMPLE_GRAD) if (load->load_type == HLSL_RESOURCE_SAMPLE_GRAD)
{ {
src_param = &ins->src[2]; src_param = &ins->src[2];
vsir_register_init(&src_param->reg, VKD3DSPR_TEMP, VKD3D_DATA_FLOAT, 1); vsir_src_from_hlsl_node(src_param, ctx, ddx, VKD3DSP_WRITEMASK_ALL);
src_param->reg.idx[0].offset = ddx->reg.id;
src_param->swizzle = sm1_generate_vsir_get_src_swizzle(ddx->reg.writemask, VKD3DSP_WRITEMASK_ALL);
src_param = &ins->src[3]; src_param = &ins->src[3];
vsir_register_init(&src_param->reg, VKD3DSPR_TEMP, VKD3D_DATA_FLOAT, 1); vsir_src_from_hlsl_node(src_param, ctx, ddy, VKD3DSP_WRITEMASK_ALL);
src_param->reg.idx[0].offset = ddy->reg.id;
src_param->swizzle = sm1_generate_vsir_get_src_swizzle(ddy->reg.writemask, VKD3DSP_WRITEMASK_ALL);
} }
} }
@ -7389,6 +7425,7 @@ static void generate_vsir_instr_swizzle(struct hlsl_ctx *ctx,
swizzle = vsir_swizzle_from_hlsl(swizzle); swizzle = vsir_swizzle_from_hlsl(swizzle);
src_param = &ins->src[0]; src_param = &ins->src[0];
VKD3D_ASSERT(val->type != HLSL_IR_CONSTANT);
vsir_register_init(&src_param->reg, VKD3DSPR_TEMP, vsir_data_type_from_hlsl_instruction(ctx, val), 1); vsir_register_init(&src_param->reg, VKD3DSPR_TEMP, vsir_data_type_from_hlsl_instruction(ctx, val), 1);
src_param->reg.idx[0].offset = val->reg.id; src_param->reg.idx[0].offset = val->reg.id;
src_param->reg.dimension = VSIR_DIMENSION_VEC4; src_param->reg.dimension = VSIR_DIMENSION_VEC4;
@ -7409,9 +7446,7 @@ static void sm1_generate_vsir_instr_store(struct hlsl_ctx *ctx, struct vsir_prog
sm1_generate_vsir_init_dst_param_from_deref(ctx, &ins->dst[0], &store->lhs, &ins->location, store->writemask); sm1_generate_vsir_init_dst_param_from_deref(ctx, &ins->dst[0], &store->lhs, &ins->location, store->writemask);
src_param = &ins->src[0]; src_param = &ins->src[0];
vsir_register_init(&src_param->reg, VKD3DSPR_TEMP, VKD3D_DATA_FLOAT, 1); vsir_src_from_hlsl_node(src_param, ctx, rhs, ins->dst[0].write_mask);
src_param->reg.idx[0].offset = rhs->reg.id;
src_param->swizzle = sm1_generate_vsir_get_src_swizzle(rhs->reg.writemask, ins->dst[0].write_mask);
} }
static void sm1_generate_vsir_instr_jump(struct hlsl_ctx *ctx, static void sm1_generate_vsir_instr_jump(struct hlsl_ctx *ctx,
@ -7446,7 +7481,6 @@ static void sm1_generate_vsir_instr_if(struct hlsl_ctx *ctx, struct vsir_program
struct vkd3d_shader_src_param *src_param; struct vkd3d_shader_src_param *src_param;
struct hlsl_ir_node *instr = &iff->node; struct hlsl_ir_node *instr = &iff->node;
struct vkd3d_shader_instruction *ins; struct vkd3d_shader_instruction *ins;
uint32_t swizzle;
if (hlsl_version_lt(ctx, 2, 1)) if (hlsl_version_lt(ctx, 2, 1))
{ {
@ -7459,19 +7493,12 @@ static void sm1_generate_vsir_instr_if(struct hlsl_ctx *ctx, struct vsir_program
return; return;
ins->flags = VKD3D_SHADER_REL_OP_NE; ins->flags = VKD3D_SHADER_REL_OP_NE;
swizzle = hlsl_swizzle_from_writemask(condition->reg.writemask);
swizzle = vsir_swizzle_from_hlsl(swizzle);
src_param = &ins->src[0]; src_param = &ins->src[0];
vsir_register_init(&src_param->reg, VKD3DSPR_TEMP, VKD3D_DATA_FLOAT, 1); vsir_src_from_hlsl_node(src_param, ctx, condition, VKD3DSP_WRITEMASK_ALL);
src_param->reg.idx[0].offset = condition->reg.id;
src_param->swizzle = swizzle;
src_param->modifiers = 0; src_param->modifiers = 0;
src_param = &ins->src[1]; src_param = &ins->src[1];
vsir_register_init(&src_param->reg, VKD3DSPR_TEMP, VKD3D_DATA_FLOAT, 1); vsir_src_from_hlsl_node(src_param, ctx, condition, VKD3DSP_WRITEMASK_ALL);
src_param->reg.idx[0].offset = condition->reg.id;
src_param->swizzle = swizzle;
src_param->modifiers = VKD3DSPSM_NEG; src_param->modifiers = VKD3DSPSM_NEG;
sm1_generate_vsir_block(ctx, &iff->then_block, program); sm1_generate_vsir_block(ctx, &iff->then_block, program);