mirror of
https://gitlab.winehq.org/wine/vkd3d.git
synced 2025-09-12 18:50:22 -07:00
vkd3d-shader/dxil: Reimplement aggregate indexing using specialized value types.
As opposed to just touching the vsir register description, which should be removed soon.
This commit is contained in:
committed by
Henri Verbeet
parent
6a85df013b
commit
bd6dbd096f
Notes:
Henri Verbeet
2025-05-24 21:47:24 +02:00
Approved-by: Henri Verbeet (@hverbeet) Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/1495
@@ -655,6 +655,12 @@ enum sm6_value_type
|
|||||||
VALUE_TYPE_INVALID,
|
VALUE_TYPE_INVALID,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct sm6_index
|
||||||
|
{
|
||||||
|
const struct sm6_value *index;
|
||||||
|
bool is_in_bounds;
|
||||||
|
};
|
||||||
|
|
||||||
struct sm6_function_data
|
struct sm6_function_data
|
||||||
{
|
{
|
||||||
const char *name;
|
const char *name;
|
||||||
@@ -678,16 +684,19 @@ struct sm6_icb_data
|
|||||||
{
|
{
|
||||||
unsigned int data_id;
|
unsigned int data_id;
|
||||||
unsigned int id;
|
unsigned int id;
|
||||||
|
struct sm6_index index;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct sm6_idxtemp_data
|
struct sm6_idxtemp_data
|
||||||
{
|
{
|
||||||
unsigned int id;
|
unsigned int id;
|
||||||
|
struct sm6_index index;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct sm6_groupsharedmem_data
|
struct sm6_groupsharedmem_data
|
||||||
{
|
{
|
||||||
unsigned int id;
|
unsigned int id;
|
||||||
|
struct sm6_index index;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct sm6_value
|
struct sm6_value
|
||||||
@@ -2433,6 +2442,9 @@ static enum vkd3d_data_type vkd3d_data_type_from_sm6_type(const struct sm6_type
|
|||||||
return VKD3D_DATA_UINT;
|
return VKD3D_DATA_UINT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void register_index_address_init(struct vkd3d_shader_register_index *idx, const struct sm6_value *address,
|
||||||
|
struct sm6_parser *sm6);
|
||||||
|
|
||||||
static void sm6_register_from_value(struct vkd3d_shader_register *reg, const struct sm6_value *value,
|
static void sm6_register_from_value(struct vkd3d_shader_register *reg, const struct sm6_value *value,
|
||||||
struct sm6_parser *sm6)
|
struct sm6_parser *sm6)
|
||||||
{
|
{
|
||||||
@@ -2452,15 +2464,24 @@ static void sm6_register_from_value(struct vkd3d_shader_register *reg, const str
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case VALUE_TYPE_ICB:
|
case VALUE_TYPE_ICB:
|
||||||
register_init_with_id(reg, VKD3DSPR_IMMCONSTBUFFER, data_type, value->u.icb.id);
|
vsir_register_init(reg, VKD3DSPR_IMMCONSTBUFFER, data_type, 2);
|
||||||
|
reg->idx[0].offset = value->u.icb.id;
|
||||||
|
register_index_address_init(®->idx[1], value->u.icb.index.index, sm6);
|
||||||
|
reg->idx[1].is_in_bounds = value->u.icb.index.is_in_bounds;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case VALUE_TYPE_IDXTEMP:
|
case VALUE_TYPE_IDXTEMP:
|
||||||
register_init_with_id(reg, VKD3DSPR_IDXTEMP, data_type, value->u.idxtemp.id);
|
vsir_register_init(reg, VKD3DSPR_IDXTEMP, data_type, 2);
|
||||||
|
reg->idx[0].offset = value->u.idxtemp.id;
|
||||||
|
register_index_address_init(®->idx[1], value->u.idxtemp.index.index, sm6);
|
||||||
|
reg->idx[1].is_in_bounds = value->u.idxtemp.index.is_in_bounds;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case VALUE_TYPE_GROUPSHAREDMEM:
|
case VALUE_TYPE_GROUPSHAREDMEM:
|
||||||
register_init_with_id(reg, VKD3DSPR_GROUPSHAREDMEM, data_type, value->u.groupsharedmem.id);
|
vsir_register_init(reg, VKD3DSPR_GROUPSHAREDMEM, data_type, 2);
|
||||||
|
reg->idx[0].offset = value->u.groupsharedmem.id;
|
||||||
|
register_index_address_init(®->idx[1], value->u.groupsharedmem.index.index, sm6);
|
||||||
|
reg->idx[1].is_in_bounds = value->u.groupsharedmem.index.is_in_bounds;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case VALUE_TYPE_UNDEFINED:
|
case VALUE_TYPE_UNDEFINED:
|
||||||
@@ -2572,12 +2593,12 @@ static void src_param_make_constant_uint(struct vkd3d_shader_src_param *param, u
|
|||||||
static void register_index_address_init(struct vkd3d_shader_register_index *idx, const struct sm6_value *address,
|
static void register_index_address_init(struct vkd3d_shader_register_index *idx, const struct sm6_value *address,
|
||||||
struct sm6_parser *sm6)
|
struct sm6_parser *sm6)
|
||||||
{
|
{
|
||||||
if (sm6_value_is_constant(address))
|
if (address && sm6_value_is_constant(address))
|
||||||
{
|
{
|
||||||
idx->offset = sm6_value_get_constant_uint(address);
|
idx->offset = sm6_value_get_constant_uint(address);
|
||||||
idx->rel_addr = NULL;
|
idx->rel_addr = NULL;
|
||||||
}
|
}
|
||||||
else if (sm6_value_is_undef(address))
|
else if (!address || sm6_value_is_undef(address))
|
||||||
{
|
{
|
||||||
idx->offset = 0;
|
idx->offset = 0;
|
||||||
idx->rel_addr = NULL;
|
idx->rel_addr = NULL;
|
||||||
@@ -3132,13 +3153,34 @@ static enum vkd3d_result value_allocate_constant_array(struct sm6_value *dst, co
|
|||||||
return VKD3D_OK;
|
return VKD3D_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct sm6_index *sm6_get_value_index(struct sm6_parser *sm6, struct sm6_value *value)
|
||||||
|
{
|
||||||
|
switch (value->value_type)
|
||||||
|
{
|
||||||
|
case VALUE_TYPE_ICB:
|
||||||
|
return &value->u.icb.index;
|
||||||
|
|
||||||
|
case VALUE_TYPE_IDXTEMP:
|
||||||
|
return &value->u.idxtemp.index;
|
||||||
|
|
||||||
|
case VALUE_TYPE_GROUPSHAREDMEM:
|
||||||
|
return &value->u.groupsharedmem.index;
|
||||||
|
|
||||||
|
default:
|
||||||
|
WARN("Cannot index into value of type %#x.\n", value->value_type);
|
||||||
|
vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND,
|
||||||
|
"Cannot index into value of type %#x.", value->value_type);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static enum vkd3d_result sm6_parser_init_constexpr_gep(struct sm6_parser *sm6, const struct dxil_record *record,
|
static enum vkd3d_result sm6_parser_init_constexpr_gep(struct sm6_parser *sm6, const struct dxil_record *record,
|
||||||
struct sm6_value *dst)
|
struct sm6_value *dst)
|
||||||
{
|
{
|
||||||
const struct sm6_type *elem_type, *pointee_type, *gep_type, *ptr_type;
|
const struct sm6_type *elem_type, *pointee_type, *gep_type, *ptr_type;
|
||||||
struct vkd3d_shader_register reg;
|
|
||||||
struct sm6_value *operands[3];
|
struct sm6_value *operands[3];
|
||||||
unsigned int i, j, offset;
|
unsigned int i, j, offset;
|
||||||
|
struct sm6_index *index;
|
||||||
uint64_t value;
|
uint64_t value;
|
||||||
|
|
||||||
i = 0;
|
i = 0;
|
||||||
@@ -3180,9 +3222,13 @@ static enum vkd3d_result sm6_parser_init_constexpr_gep(struct sm6_parser *sm6, c
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sm6_register_from_value(®, operands[0], sm6);
|
*dst = *operands[0];
|
||||||
|
index = sm6_get_value_index(sm6, dst);
|
||||||
|
|
||||||
if (reg.idx_count > 1)
|
if (!index)
|
||||||
|
return VKD3D_ERROR_INVALID_SHADER;
|
||||||
|
|
||||||
|
if (index->index)
|
||||||
{
|
{
|
||||||
WARN("Unsupported stacked GEP.\n");
|
WARN("Unsupported stacked GEP.\n");
|
||||||
vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND,
|
vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND,
|
||||||
@@ -3205,8 +3251,6 @@ static enum vkd3d_result sm6_parser_init_constexpr_gep(struct sm6_parser *sm6, c
|
|||||||
return VKD3D_ERROR_INVALID_SHADER;
|
return VKD3D_ERROR_INVALID_SHADER;
|
||||||
}
|
}
|
||||||
|
|
||||||
dst->structure_stride = operands[0]->structure_stride;
|
|
||||||
|
|
||||||
ptr_type = operands[0]->type;
|
ptr_type = operands[0]->type;
|
||||||
if (!sm6_type_is_pointer(ptr_type))
|
if (!sm6_type_is_pointer(ptr_type))
|
||||||
{
|
{
|
||||||
@@ -3243,10 +3287,11 @@ static enum vkd3d_result sm6_parser_init_constexpr_gep(struct sm6_parser *sm6, c
|
|||||||
"Module does not define a pointer type for a constexpr GEP result.");
|
"Module does not define a pointer type for a constexpr GEP result.");
|
||||||
return VKD3D_ERROR_INVALID_SHADER;
|
return VKD3D_ERROR_INVALID_SHADER;
|
||||||
}
|
}
|
||||||
dst->reg = reg;
|
|
||||||
dst->reg.idx[1].offset = offset;
|
index->index = operands[2];
|
||||||
dst->reg.idx[1].is_in_bounds = record->code == CST_CODE_CE_INBOUNDS_GEP;
|
index->is_in_bounds = record->code == CST_CODE_CE_INBOUNDS_GEP;
|
||||||
dst->reg.idx_count = 2;
|
|
||||||
|
sm6_register_from_value(&dst->reg, dst, sm6);
|
||||||
|
|
||||||
return VKD3D_OK;
|
return VKD3D_OK;
|
||||||
}
|
}
|
||||||
@@ -7210,9 +7255,8 @@ static void sm6_parser_emit_gep(struct sm6_parser *sm6, const struct dxil_record
|
|||||||
unsigned int elem_idx, operand_idx = 2;
|
unsigned int elem_idx, operand_idx = 2;
|
||||||
enum bitcode_address_space addr_space;
|
enum bitcode_address_space addr_space;
|
||||||
const struct sm6_value *elem_value;
|
const struct sm6_value *elem_value;
|
||||||
struct vkd3d_shader_register reg;
|
|
||||||
const struct sm6_value *src;
|
const struct sm6_value *src;
|
||||||
bool is_in_bounds;
|
struct sm6_index *index;
|
||||||
|
|
||||||
if (!dxil_record_validate_operand_min_count(record, 5, sm6)
|
if (!dxil_record_validate_operand_min_count(record, 5, sm6)
|
||||||
|| !(type = sm6_parser_get_type(sm6, record->operands[1]))
|
|| !(type = sm6_parser_get_type(sm6, record->operands[1]))
|
||||||
@@ -7224,9 +7268,13 @@ static void sm6_parser_emit_gep(struct sm6_parser *sm6, const struct dxil_record
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
sm6_register_from_value(®, src, sm6);
|
*dst = *src;
|
||||||
|
index = sm6_get_value_index(sm6, dst);
|
||||||
|
|
||||||
if (reg.idx_count > 1)
|
if (!index)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (index->index)
|
||||||
{
|
{
|
||||||
WARN("Unsupported stacked GEP.\n");
|
WARN("Unsupported stacked GEP.\n");
|
||||||
vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND,
|
vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND,
|
||||||
@@ -7234,8 +7282,6 @@ static void sm6_parser_emit_gep(struct sm6_parser *sm6, const struct dxil_record
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
is_in_bounds = record->operands[0];
|
|
||||||
|
|
||||||
if ((pointee_type = src->type->u.pointer.type) != type)
|
if ((pointee_type = src->type->u.pointer.type) != type)
|
||||||
{
|
{
|
||||||
WARN("Type mismatch, type %u width %u vs type %u width %u.\n", type->class,
|
WARN("Type mismatch, type %u width %u vs type %u width %u.\n", type->class,
|
||||||
@@ -7295,13 +7341,10 @@ static void sm6_parser_emit_gep(struct sm6_parser *sm6, const struct dxil_record
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
reg.idx[1].offset = 0;
|
index->index = elem_value;
|
||||||
register_index_address_init(®.idx[1], elem_value, sm6);
|
index->is_in_bounds = record->operands[0];
|
||||||
reg.idx[1].is_in_bounds = is_in_bounds;
|
|
||||||
reg.idx_count = 2;
|
|
||||||
|
|
||||||
dst->reg = reg;
|
sm6_register_from_value(&dst->reg, dst, sm6);
|
||||||
dst->structure_stride = src->structure_stride;
|
|
||||||
|
|
||||||
ins->opcode = VKD3DSIH_NOP;
|
ins->opcode = VKD3DSIH_NOP;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user