mirror of
https://gitlab.winehq.org/wine/vkd3d.git
synced 2025-01-28 13:05:02 -08:00
vkd3d-shader/dxil: Support forward-referenced value ids.
This commit is contained in:
parent
7f87a3e5fc
commit
efddcc9a99
Notes:
Alexandre Julliard
2024-02-07 23:26:14 +01:00
Approved-by: Giovanni Mascellani (@giomasce) Approved-by: Henri Verbeet (@hverbeet) Approved-by: Alexandre Julliard (@julliard) Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/590
@ -2179,21 +2179,29 @@ static enum vkd3d_data_type vkd3d_data_type_from_sm6_type(const struct sm6_type
|
||||
}
|
||||
|
||||
static void register_init_ssa_vector(struct vkd3d_shader_register *reg, const struct sm6_type *type,
|
||||
unsigned int component_count, struct sm6_parser *sm6)
|
||||
unsigned int component_count, struct sm6_value *value, struct sm6_parser *sm6)
|
||||
{
|
||||
enum vkd3d_data_type data_type;
|
||||
unsigned int id;
|
||||
|
||||
id = sm6_parser_alloc_ssa_id(sm6);
|
||||
if (value && register_is_ssa(&value->u.reg) && value->u.reg.idx[0].offset)
|
||||
{
|
||||
id = value->u.reg.idx[0].offset;
|
||||
TRACE("Using forward-allocated id %u.\n", id);
|
||||
}
|
||||
else
|
||||
{
|
||||
id = sm6_parser_alloc_ssa_id(sm6);
|
||||
}
|
||||
data_type = vkd3d_data_type_from_sm6_type(sm6_type_get_scalar_type(type, 0));
|
||||
register_init_with_id(reg, VKD3DSPR_SSA, data_type, id);
|
||||
reg->dimension = component_count > 1 ? VSIR_DIMENSION_VEC4 : VSIR_DIMENSION_SCALAR;
|
||||
}
|
||||
|
||||
static void register_init_ssa_scalar(struct vkd3d_shader_register *reg, const struct sm6_type *type,
|
||||
struct sm6_parser *sm6)
|
||||
struct sm6_value *value, struct sm6_parser *sm6)
|
||||
{
|
||||
register_init_ssa_vector(reg, type, 1, sm6);
|
||||
register_init_ssa_vector(reg, sm6_type_get_scalar_type(type, 0), 1, value, sm6);
|
||||
}
|
||||
|
||||
static void dst_param_init(struct vkd3d_shader_dst_param *param)
|
||||
@ -2218,10 +2226,10 @@ static void dst_param_init_vector(struct vkd3d_shader_dst_param *param, unsigned
|
||||
}
|
||||
|
||||
static void dst_param_init_ssa_scalar(struct vkd3d_shader_dst_param *param, const struct sm6_type *type,
|
||||
struct sm6_parser *sm6)
|
||||
struct sm6_value *value, struct sm6_parser *sm6)
|
||||
{
|
||||
dst_param_init(param);
|
||||
register_init_ssa_scalar(¶m->reg, type, sm6);
|
||||
register_init_ssa_scalar(¶m->reg, type, value, sm6);
|
||||
}
|
||||
|
||||
static inline void src_param_init(struct vkd3d_shader_src_param *param)
|
||||
@ -2278,7 +2286,7 @@ static void instruction_dst_param_init_ssa_scalar(struct vkd3d_shader_instructio
|
||||
struct vkd3d_shader_dst_param *param = instruction_dst_params_alloc(ins, 1, sm6);
|
||||
struct sm6_value *dst = sm6_parser_get_current_value(sm6);
|
||||
|
||||
dst_param_init_ssa_scalar(param, dst->type, sm6);
|
||||
dst_param_init_ssa_scalar(param, dst->type, dst, sm6);
|
||||
param->write_mask = VKD3DSP_WRITEMASK_0;
|
||||
dst->u.reg = param->reg;
|
||||
}
|
||||
@ -2290,7 +2298,7 @@ static void instruction_dst_param_init_ssa_vector(struct vkd3d_shader_instructio
|
||||
struct sm6_value *dst = sm6_parser_get_current_value(sm6);
|
||||
|
||||
dst_param_init_vector(param, component_count);
|
||||
register_init_ssa_vector(¶m->reg, sm6_type_get_scalar_type(dst->type, 0), component_count, sm6);
|
||||
register_init_ssa_vector(¶m->reg, sm6_type_get_scalar_type(dst->type, 0), component_count, dst, sm6);
|
||||
dst->u.reg = param->reg;
|
||||
}
|
||||
|
||||
@ -2453,6 +2461,7 @@ static const struct sm6_value *sm6_parser_get_value_safe(struct sm6_parser *sm6,
|
||||
static size_t sm6_parser_get_value_idx_by_ref(struct sm6_parser *sm6, const struct dxil_record *record,
|
||||
const struct sm6_type *fwd_type, unsigned int *rec_idx)
|
||||
{
|
||||
struct sm6_value *value;
|
||||
unsigned int idx;
|
||||
uint64_t val_ref;
|
||||
size_t operand;
|
||||
@ -2466,24 +2475,40 @@ static size_t sm6_parser_get_value_idx_by_ref(struct sm6_parser *sm6, const stru
|
||||
if (operand == SIZE_MAX)
|
||||
return SIZE_MAX;
|
||||
|
||||
if (operand >= sm6->value_count)
|
||||
if (operand >= sm6->value_count && !fwd_type)
|
||||
{
|
||||
if (!fwd_type)
|
||||
{
|
||||
/* Forward references are followed by a type id unless an earlier operand set the type,
|
||||
* or it is contained in a function declaration. */
|
||||
if (!dxil_record_validate_operand_min_count(record, idx + 1, sm6))
|
||||
return SIZE_MAX;
|
||||
if (!(fwd_type = sm6_parser_get_type(sm6, record->operands[idx++])))
|
||||
return SIZE_MAX;
|
||||
}
|
||||
FIXME("Forward value references are not supported yet.\n");
|
||||
vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND,
|
||||
"Unsupported value forward reference.");
|
||||
return SIZE_MAX;
|
||||
/* Forward references are followed by a type id unless an earlier operand set the type,
|
||||
* or it is contained in a function declaration. */
|
||||
if (!dxil_record_validate_operand_min_count(record, idx + 1, sm6))
|
||||
return SIZE_MAX;
|
||||
if (!(fwd_type = sm6_parser_get_type(sm6, record->operands[idx++])))
|
||||
return SIZE_MAX;
|
||||
}
|
||||
*rec_idx = idx;
|
||||
|
||||
if (fwd_type)
|
||||
{
|
||||
value = &sm6->values[operand];
|
||||
if (value->type)
|
||||
{
|
||||
if (value->type != fwd_type)
|
||||
{
|
||||
WARN("Value already has a mismatching type.\n");
|
||||
vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_TYPE_MISMATCH,
|
||||
"The type of a source value does not match the predefined type.");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
value->type = fwd_type;
|
||||
value->value_type = VALUE_TYPE_REG;
|
||||
register_init_with_id(&value->u.reg, VKD3DSPR_SSA, vkd3d_data_type_from_sm6_type(
|
||||
sm6_type_get_scalar_type(fwd_type, 0)), sm6_parser_alloc_ssa_id(sm6));
|
||||
value->u.reg.dimension = sm6_type_is_scalar(fwd_type) ? VSIR_DIMENSION_SCALAR
|
||||
: VSIR_DIMENSION_VEC4;
|
||||
}
|
||||
}
|
||||
|
||||
return operand;
|
||||
}
|
||||
|
||||
@ -3479,7 +3504,7 @@ static void sm6_parser_emit_binop(struct sm6_parser *sm6, const struct dxil_reco
|
||||
|
||||
dst_param_init(&dst_params[0]);
|
||||
dst_param_init(&dst_params[1]);
|
||||
register_init_ssa_scalar(&dst_params[index].reg, a->type, sm6);
|
||||
register_init_ssa_scalar(&dst_params[index].reg, a->type, dst, sm6);
|
||||
vsir_register_init(&dst_params[index ^ 1].reg, VKD3DSPR_NULL, VKD3D_DATA_UNUSED, 0);
|
||||
dst->u.reg = dst_params[index].reg;
|
||||
}
|
||||
@ -3992,7 +4017,7 @@ static void sm6_parser_emit_dx_sincos(struct sm6_parser *sm6, enum dx_intrinsic_
|
||||
dst_params = instruction_dst_params_alloc(ins, 2, sm6);
|
||||
dst_param_init(&dst_params[0]);
|
||||
dst_param_init(&dst_params[1]);
|
||||
register_init_ssa_scalar(&dst_params[index].reg, dst->type, sm6);
|
||||
register_init_ssa_scalar(&dst_params[index].reg, dst->type, dst, sm6);
|
||||
vsir_register_init(&dst_params[index ^ 1].reg, VKD3DSPR_NULL, VKD3D_DATA_UNUSED, 0);
|
||||
dst->u.reg = dst_params[index].reg;
|
||||
}
|
||||
@ -4931,7 +4956,7 @@ static void sm6_parser_emit_phi(struct sm6_parser *sm6, const struct dxil_record
|
||||
}
|
||||
|
||||
dst->type = type;
|
||||
register_init_ssa_scalar(&dst->u.reg, type, sm6);
|
||||
register_init_ssa_scalar(&dst->u.reg, type, dst, sm6);
|
||||
|
||||
if (!(phi = sm6_block_phi_require_space(code_block, sm6)))
|
||||
return;
|
||||
@ -5504,6 +5529,7 @@ static enum vkd3d_result sm6_parser_function_init(struct sm6_parser *sm6, const
|
||||
struct vkd3d_shader_instruction *ins;
|
||||
size_t i, block_idx, block_count;
|
||||
const struct dxil_record *record;
|
||||
const struct sm6_type *fwd_type;
|
||||
bool ret_found, is_terminator;
|
||||
struct sm6_block *code_block;
|
||||
struct sm6_value *dst;
|
||||
@ -5580,6 +5606,7 @@ static enum vkd3d_result sm6_parser_function_init(struct sm6_parser *sm6, const
|
||||
ins->handler_idx = VKD3DSIH_INVALID;
|
||||
|
||||
dst = sm6_parser_get_current_value(sm6);
|
||||
fwd_type = dst->type;
|
||||
dst->type = NULL;
|
||||
dst->value_type = VALUE_TYPE_REG;
|
||||
is_terminator = false;
|
||||
@ -5659,6 +5686,13 @@ static enum vkd3d_result sm6_parser_function_init(struct sm6_parser *sm6, const
|
||||
else
|
||||
assert(ins->handler_idx == VKD3DSIH_NOP);
|
||||
|
||||
if (dst->type && fwd_type && dst->type != fwd_type)
|
||||
{
|
||||
WARN("Type mismatch.\n");
|
||||
vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_TYPE_MISMATCH,
|
||||
"The type of a result value does not match the type defined by a forward reference.");
|
||||
}
|
||||
|
||||
sm6->value_count += !!dst->type;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user