mirror of
https://gitlab.winehq.org/wine/vkd3d.git
synced 2024-11-21 16:46:41 -08:00
vkd3d-shader/hlsl: Store SM4 semantic declarations in the vsir program.
This commit is contained in:
parent
5ea946aa90
commit
64c4a3a442
Notes:
Henri Verbeet
2024-11-05 20:05:42 +01:00
Approved-by: Francisco Casas (@fcasas) Approved-by: Elizabeth Figura (@zfigura) Approved-by: Henri Verbeet (@hverbeet) Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/1238
@ -7642,6 +7642,123 @@ static void replace_instr_with_last_vsir_instr(struct hlsl_ctx *ctx,
|
||||
hlsl_replace_node(instr, vsir_instr);
|
||||
}
|
||||
|
||||
static void sm4_generate_vsir_instr_dcl_semantic(struct hlsl_ctx *ctx, struct vsir_program *program,
|
||||
const struct hlsl_ir_var *var, bool is_patch_constant_func, struct hlsl_block *block,
|
||||
const struct vkd3d_shader_location *loc)
|
||||
{
|
||||
const struct vkd3d_shader_version *version = &program->shader_version;
|
||||
const bool output = var->is_output_semantic;
|
||||
enum vkd3d_shader_sysval_semantic semantic;
|
||||
struct vkd3d_shader_dst_param *dst_param;
|
||||
struct vkd3d_shader_instruction *ins;
|
||||
enum vkd3d_shader_register_type type;
|
||||
enum vkd3d_shader_opcode opcode;
|
||||
uint32_t write_mask;
|
||||
unsigned int idx;
|
||||
bool has_idx;
|
||||
|
||||
sm4_sysval_semantic_from_semantic_name(&semantic, version, ctx->semantic_compat_mapping,
|
||||
ctx->domain, var->semantic.name, var->semantic.index, output, is_patch_constant_func);
|
||||
if (semantic == ~0u)
|
||||
semantic = VKD3D_SHADER_SV_NONE;
|
||||
|
||||
if (var->is_input_semantic)
|
||||
{
|
||||
switch (semantic)
|
||||
{
|
||||
case VKD3D_SHADER_SV_NONE:
|
||||
opcode = (version->type == VKD3D_SHADER_TYPE_PIXEL)
|
||||
? VKD3DSIH_DCL_INPUT_PS : VKD3DSIH_DCL_INPUT;
|
||||
break;
|
||||
|
||||
case VKD3D_SHADER_SV_INSTANCE_ID:
|
||||
case VKD3D_SHADER_SV_IS_FRONT_FACE:
|
||||
case VKD3D_SHADER_SV_PRIMITIVE_ID:
|
||||
case VKD3D_SHADER_SV_SAMPLE_INDEX:
|
||||
case VKD3D_SHADER_SV_VERTEX_ID:
|
||||
opcode = (version->type == VKD3D_SHADER_TYPE_PIXEL)
|
||||
? VKD3DSIH_DCL_INPUT_PS_SGV : VKD3DSIH_DCL_INPUT_SGV;
|
||||
break;
|
||||
|
||||
default:
|
||||
opcode = (version->type == VKD3D_SHADER_TYPE_PIXEL)
|
||||
? VKD3DSIH_DCL_INPUT_PS_SIV : VKD3DSIH_DCL_INPUT_SIV;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (semantic == VKD3D_SHADER_SV_NONE || version->type == VKD3D_SHADER_TYPE_PIXEL)
|
||||
opcode = VKD3DSIH_DCL_OUTPUT;
|
||||
else
|
||||
opcode = VKD3DSIH_DCL_OUTPUT_SIV;
|
||||
}
|
||||
|
||||
if (sm4_register_from_semantic_name(version, var->semantic.name, output, &type, &has_idx))
|
||||
{
|
||||
if (has_idx)
|
||||
idx = var->semantic.index;
|
||||
write_mask = (1u << var->data_type->dimx) - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (output)
|
||||
type = VKD3DSPR_OUTPUT;
|
||||
else if (version->type == VKD3D_SHADER_TYPE_DOMAIN)
|
||||
type = VKD3DSPR_PATCHCONST;
|
||||
else
|
||||
type = VKD3DSPR_INPUT;
|
||||
|
||||
has_idx = true;
|
||||
idx = var->regs[HLSL_REGSET_NUMERIC].id;
|
||||
write_mask = var->regs[HLSL_REGSET_NUMERIC].writemask;
|
||||
}
|
||||
|
||||
if (!(ins = generate_vsir_add_program_instruction(ctx, program, loc, opcode, 0, 0)))
|
||||
return;
|
||||
|
||||
if (opcode == VKD3DSIH_DCL_OUTPUT)
|
||||
{
|
||||
VKD3D_ASSERT(semantic == VKD3D_SHADER_SV_NONE
|
||||
|| semantic == VKD3D_SHADER_SV_TARGET || type != VKD3DSPR_OUTPUT);
|
||||
dst_param = &ins->declaration.dst;
|
||||
}
|
||||
else if (opcode == VKD3DSIH_DCL_INPUT || opcode == VKD3DSIH_DCL_INPUT_PS)
|
||||
{
|
||||
VKD3D_ASSERT(semantic == VKD3D_SHADER_SV_NONE);
|
||||
dst_param = &ins->declaration.dst;
|
||||
}
|
||||
else
|
||||
{
|
||||
VKD3D_ASSERT(semantic != VKD3D_SHADER_SV_NONE);
|
||||
ins->declaration.register_semantic.sysval_semantic = vkd3d_siv_from_sysval_indexed(semantic,
|
||||
var->semantic.index);
|
||||
dst_param = &ins->declaration.register_semantic.reg;
|
||||
}
|
||||
|
||||
if (has_idx)
|
||||
{
|
||||
vsir_register_init(&dst_param->reg, type, VKD3D_DATA_FLOAT, 1);
|
||||
dst_param->reg.idx[0].offset = idx;
|
||||
}
|
||||
else
|
||||
{
|
||||
vsir_register_init(&dst_param->reg, type, VKD3D_DATA_FLOAT, 0);
|
||||
}
|
||||
|
||||
if (shader_sm4_is_scalar_register(&dst_param->reg))
|
||||
dst_param->reg.dimension = VSIR_DIMENSION_SCALAR;
|
||||
else
|
||||
dst_param->reg.dimension = VSIR_DIMENSION_VEC4;
|
||||
|
||||
dst_param->write_mask = write_mask;
|
||||
|
||||
if (var->is_input_semantic && version->type == VKD3D_SHADER_TYPE_PIXEL)
|
||||
ins->flags = sm4_get_interpolation_mode(var->data_type, var->storage_modifiers);
|
||||
|
||||
add_last_vsir_instr_to_block(ctx, program, block);
|
||||
}
|
||||
|
||||
static void sm4_generate_vsir_instr_dcl_temps(struct hlsl_ctx *ctx, struct vsir_program *program,
|
||||
uint32_t temp_count, struct hlsl_block *block, const struct vkd3d_shader_location *loc)
|
||||
{
|
||||
@ -7731,6 +7848,7 @@ static void sm4_generate_vsir_block(struct hlsl_ctx *ctx, struct hlsl_block *blo
|
||||
static void sm4_generate_vsir_add_function(struct hlsl_ctx *ctx,
|
||||
struct hlsl_ir_function_decl *func, uint64_t config_flags, struct vsir_program *program)
|
||||
{
|
||||
bool is_patch_constant_func = func == ctx->patch_constant_func;
|
||||
struct hlsl_block block = {0};
|
||||
struct hlsl_scope *scope;
|
||||
struct hlsl_ir_var *var;
|
||||
@ -7745,6 +7863,13 @@ static void sm4_generate_vsir_add_function(struct hlsl_ctx *ctx,
|
||||
|
||||
hlsl_block_init(&block);
|
||||
|
||||
LIST_FOR_EACH_ENTRY(var, &func->extern_vars, struct hlsl_ir_var, extern_entry)
|
||||
{
|
||||
if ((var->is_input_semantic && var->last_read)
|
||||
|| (var->is_output_semantic && var->first_write))
|
||||
sm4_generate_vsir_instr_dcl_semantic(ctx, program, var, is_patch_constant_func, &block, &var->loc);
|
||||
}
|
||||
|
||||
if (temp_count)
|
||||
sm4_generate_vsir_instr_dcl_temps(ctx, program, temp_count, &block, &func->loc);
|
||||
|
||||
|
@ -2235,7 +2235,7 @@ static bool shader_sm4_read_param(struct vkd3d_shader_sm4_parser *priv, const ui
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool shader_sm4_is_scalar_register(const struct vkd3d_shader_register *reg)
|
||||
bool shader_sm4_is_scalar_register(const struct vkd3d_shader_register *reg)
|
||||
{
|
||||
switch (reg->type)
|
||||
{
|
||||
@ -4856,114 +4856,6 @@ static void write_sm4_dcl_textures(const struct tpf_compiler *tpf, const struct
|
||||
}
|
||||
}
|
||||
|
||||
static void tpf_write_dcl_semantic(const struct tpf_compiler *tpf,
|
||||
const struct hlsl_ir_var *var, bool is_patch_constant_func)
|
||||
{
|
||||
const struct vkd3d_shader_version *version = &tpf->program->shader_version;
|
||||
const bool output = var->is_output_semantic;
|
||||
enum vkd3d_shader_sysval_semantic semantic;
|
||||
bool has_idx;
|
||||
|
||||
struct sm4_instruction instr =
|
||||
{
|
||||
.dsts[0].reg.dimension = VSIR_DIMENSION_VEC4,
|
||||
.dst_count = 1,
|
||||
};
|
||||
|
||||
if (sm4_register_from_semantic_name(version, var->semantic.name, output, &instr.dsts[0].reg.type, &has_idx))
|
||||
{
|
||||
if (has_idx)
|
||||
{
|
||||
instr.dsts[0].reg.idx[0].offset = var->semantic.index;
|
||||
instr.dsts[0].reg.idx_count = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
instr.dsts[0].reg.idx_count = 0;
|
||||
}
|
||||
instr.dsts[0].write_mask = (1 << var->data_type->dimx) - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (output)
|
||||
instr.dsts[0].reg.type = VKD3DSPR_OUTPUT;
|
||||
else if (version->type == VKD3D_SHADER_TYPE_DOMAIN)
|
||||
instr.dsts[0].reg.type = VKD3DSPR_PATCHCONST;
|
||||
else
|
||||
instr.dsts[0].reg.type = VKD3DSPR_INPUT;
|
||||
|
||||
instr.dsts[0].reg.idx[0].offset = var->regs[HLSL_REGSET_NUMERIC].id;
|
||||
instr.dsts[0].reg.idx_count = 1;
|
||||
instr.dsts[0].write_mask = var->regs[HLSL_REGSET_NUMERIC].writemask;
|
||||
}
|
||||
|
||||
if (shader_sm4_is_scalar_register(&instr.dsts[0].reg))
|
||||
instr.dsts[0].reg.dimension = VSIR_DIMENSION_SCALAR;
|
||||
|
||||
sm4_sysval_semantic_from_semantic_name(&semantic, version, tpf->ctx->semantic_compat_mapping,
|
||||
tpf->ctx->domain, var->semantic.name, var->semantic.index, output, is_patch_constant_func);
|
||||
if (semantic == ~0u)
|
||||
semantic = VKD3D_SHADER_SV_NONE;
|
||||
|
||||
if (var->is_input_semantic)
|
||||
{
|
||||
switch (semantic)
|
||||
{
|
||||
case VKD3D_SHADER_SV_NONE:
|
||||
instr.opcode = (version->type == VKD3D_SHADER_TYPE_PIXEL)
|
||||
? VKD3D_SM4_OP_DCL_INPUT_PS : VKD3D_SM4_OP_DCL_INPUT;
|
||||
break;
|
||||
|
||||
case VKD3D_SHADER_SV_INSTANCE_ID:
|
||||
case VKD3D_SHADER_SV_IS_FRONT_FACE:
|
||||
case VKD3D_SHADER_SV_PRIMITIVE_ID:
|
||||
case VKD3D_SHADER_SV_SAMPLE_INDEX:
|
||||
case VKD3D_SHADER_SV_VERTEX_ID:
|
||||
instr.opcode = (version->type == VKD3D_SHADER_TYPE_PIXEL)
|
||||
? VKD3D_SM4_OP_DCL_INPUT_PS_SGV : VKD3D_SM4_OP_DCL_INPUT_SGV;
|
||||
break;
|
||||
|
||||
default:
|
||||
instr.opcode = (version->type == VKD3D_SHADER_TYPE_PIXEL)
|
||||
? VKD3D_SM4_OP_DCL_INPUT_PS_SIV : VKD3D_SM4_OP_DCL_INPUT_SIV;
|
||||
break;
|
||||
}
|
||||
|
||||
if (version->type == VKD3D_SHADER_TYPE_PIXEL)
|
||||
{
|
||||
enum vkd3d_shader_interpolation_mode mode;
|
||||
|
||||
mode = sm4_get_interpolation_mode(var->data_type, var->storage_modifiers);
|
||||
instr.extra_bits |= mode << VKD3D_SM4_INTERPOLATION_MODE_SHIFT;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (semantic == VKD3D_SHADER_SV_NONE || version->type == VKD3D_SHADER_TYPE_PIXEL)
|
||||
instr.opcode = VKD3D_SM4_OP_DCL_OUTPUT;
|
||||
else
|
||||
instr.opcode = VKD3D_SM4_OP_DCL_OUTPUT_SIV;
|
||||
}
|
||||
|
||||
if (instr.opcode == VKD3D_SM4_OP_DCL_OUTPUT)
|
||||
{
|
||||
VKD3D_ASSERT(semantic == VKD3D_SHADER_SV_NONE || semantic == VKD3D_SHADER_SV_TARGET
|
||||
|| instr.dsts[0].reg.type != VKD3DSPR_OUTPUT);
|
||||
}
|
||||
else if (instr.opcode == VKD3D_SM4_OP_DCL_INPUT || instr.opcode == VKD3D_SM4_OP_DCL_INPUT_PS)
|
||||
{
|
||||
VKD3D_ASSERT(semantic == VKD3D_SHADER_SV_NONE);
|
||||
}
|
||||
else
|
||||
{
|
||||
VKD3D_ASSERT(semantic != VKD3D_SHADER_SV_NONE);
|
||||
instr.idx_count = 1;
|
||||
instr.idx[0] = vkd3d_siv_from_sysval_indexed(semantic, var->semantic.index);
|
||||
}
|
||||
|
||||
write_sm4_instruction(tpf, &instr);
|
||||
}
|
||||
|
||||
static void tpf_dcl_temps(const struct tpf_compiler *tpf, unsigned int count)
|
||||
{
|
||||
struct sm4_instruction instr =
|
||||
@ -4990,6 +4882,41 @@ static void tpf_dcl_indexable_temp(const struct tpf_compiler *tpf, const struct
|
||||
write_sm4_instruction(tpf, &instr);
|
||||
}
|
||||
|
||||
static void tpf_dcl_semantic(const struct tpf_compiler *tpf, enum vkd3d_sm4_opcode opcode,
|
||||
const struct vkd3d_shader_dst_param *dst, uint32_t interpolation_flags)
|
||||
{
|
||||
struct sm4_instruction instr =
|
||||
{
|
||||
.opcode = opcode,
|
||||
|
||||
.dsts[0] = *dst,
|
||||
.dst_count = 1,
|
||||
|
||||
.extra_bits = interpolation_flags << VKD3D_SM4_INTERPOLATION_MODE_SHIFT,
|
||||
};
|
||||
|
||||
write_sm4_instruction(tpf, &instr);
|
||||
}
|
||||
|
||||
static void tpf_dcl_siv_semantic(const struct tpf_compiler *tpf, enum vkd3d_sm4_opcode opcode,
|
||||
const struct vkd3d_shader_register_semantic *semantic, uint32_t interpolation_flags)
|
||||
{
|
||||
struct sm4_instruction instr =
|
||||
{
|
||||
.opcode = opcode,
|
||||
|
||||
.dsts[0] = semantic->reg,
|
||||
.dst_count = 1,
|
||||
|
||||
.idx[0] = semantic->sysval_semantic,
|
||||
.idx_count = 1,
|
||||
|
||||
.extra_bits = interpolation_flags << VKD3D_SM4_INTERPOLATION_MODE_SHIFT,
|
||||
};
|
||||
|
||||
write_sm4_instruction(tpf, &instr);
|
||||
}
|
||||
|
||||
static void tpf_dcl_thread_group(const struct tpf_compiler *tpf, const struct vsir_thread_group_size *group_size)
|
||||
{
|
||||
struct sm4_instruction instr =
|
||||
@ -6529,6 +6456,38 @@ static void tpf_handle_instruction(struct tpf_compiler *tpf, const struct vkd3d_
|
||||
tpf_dcl_indexable_temp(tpf, &ins->declaration.indexable_temp);
|
||||
break;
|
||||
|
||||
case VKD3DSIH_DCL_INPUT:
|
||||
tpf_dcl_semantic(tpf, VKD3D_SM4_OP_DCL_INPUT, &ins->declaration.dst, 0);
|
||||
break;
|
||||
|
||||
case VKD3DSIH_DCL_INPUT_PS:
|
||||
tpf_dcl_semantic(tpf, VKD3D_SM4_OP_DCL_INPUT_PS, &ins->declaration.dst, ins->flags);
|
||||
break;
|
||||
|
||||
case VKD3DSIH_DCL_INPUT_PS_SGV:
|
||||
tpf_dcl_siv_semantic(tpf, VKD3D_SM4_OP_DCL_INPUT_PS_SGV, &ins->declaration.register_semantic, 0);
|
||||
break;
|
||||
|
||||
case VKD3DSIH_DCL_INPUT_PS_SIV:
|
||||
tpf_dcl_siv_semantic(tpf, VKD3D_SM4_OP_DCL_INPUT_PS_SIV, &ins->declaration.register_semantic, ins->flags);
|
||||
break;
|
||||
|
||||
case VKD3DSIH_DCL_INPUT_SGV:
|
||||
tpf_dcl_siv_semantic(tpf, VKD3D_SM4_OP_DCL_INPUT_SGV, &ins->declaration.register_semantic, 0);
|
||||
break;
|
||||
|
||||
case VKD3DSIH_DCL_INPUT_SIV:
|
||||
tpf_dcl_siv_semantic(tpf, VKD3D_SM4_OP_DCL_INPUT_SIV, &ins->declaration.register_semantic, 0);
|
||||
break;
|
||||
|
||||
case VKD3DSIH_DCL_OUTPUT:
|
||||
tpf_dcl_semantic(tpf, VKD3D_SM4_OP_DCL_OUTPUT, &ins->declaration.dst, 0);
|
||||
break;
|
||||
|
||||
case VKD3DSIH_DCL_OUTPUT_SIV:
|
||||
tpf_dcl_siv_semantic(tpf, VKD3D_SM4_OP_DCL_OUTPUT_SIV, &ins->declaration.register_semantic, 0);
|
||||
break;
|
||||
|
||||
case VKD3DSIH_MOV:
|
||||
tpf_simple_instruction(tpf, ins);
|
||||
break;
|
||||
@ -6621,16 +6580,6 @@ static void write_sm4_block(struct tpf_compiler *tpf, const struct hlsl_block *b
|
||||
|
||||
static void tpf_write_shader_function(struct tpf_compiler *tpf, struct hlsl_ir_function_decl *func)
|
||||
{
|
||||
struct hlsl_ctx *ctx = tpf->ctx;
|
||||
const struct hlsl_ir_var *var;
|
||||
|
||||
LIST_FOR_EACH_ENTRY(var, &func->extern_vars, struct hlsl_ir_var, extern_entry)
|
||||
{
|
||||
if ((var->is_input_semantic && var->last_read)
|
||||
|| (var->is_output_semantic && var->first_write))
|
||||
tpf_write_dcl_semantic(tpf, var, func == ctx->patch_constant_func);
|
||||
}
|
||||
|
||||
if (tpf->program->shader_version.type == VKD3D_SHADER_TYPE_COMPUTE)
|
||||
tpf_dcl_thread_group(tpf, &tpf->program->thread_group_size);
|
||||
|
||||
|
@ -1620,6 +1620,7 @@ bool sm1_usage_from_semantic_name(const char *semantic_name,
|
||||
uint32_t semantic_index, enum vkd3d_decl_usage *usage, uint32_t *usage_idx);
|
||||
bool sm4_register_from_semantic_name(const struct vkd3d_shader_version *version,
|
||||
const char *semantic_name, bool output, enum vkd3d_shader_register_type *type, bool *has_idx);
|
||||
bool shader_sm4_is_scalar_register(const struct vkd3d_shader_register *reg);
|
||||
bool sm4_sysval_semantic_from_semantic_name(enum vkd3d_shader_sysval_semantic *sysval_semantic,
|
||||
const struct vkd3d_shader_version *version, bool semantic_compat_mapping, enum vkd3d_tessellator_domain domain,
|
||||
const char *semantic_name, unsigned int semantic_idx, bool output, bool is_patch_constant_func);
|
||||
|
Loading…
Reference in New Issue
Block a user