mirror of
https://gitlab.winehq.org/wine/vkd3d.git
synced 2024-11-21 16:46:41 -08:00
vkd3d-shader/dxil: Implement the DXIL ALLOCA instruction.
This commit is contained in:
parent
df82c61482
commit
2d5f2bf7a4
Notes:
Alexandre Julliard
2023-12-11 23:20:30 +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/498
@ -29,6 +29,9 @@ static const uint64_t MAX_ALIGNMENT_EXPONENT = 29;
|
||||
static const uint64_t GLOBALVAR_FLAG_IS_CONSTANT = 1;
|
||||
static const uint64_t GLOBALVAR_FLAG_EXPLICIT_TYPE = 2;
|
||||
static const unsigned int GLOBALVAR_ADDRESS_SPACE_SHIFT = 2;
|
||||
static const uint64_t ALLOCA_FLAG_IN_ALLOCA = 0x20;
|
||||
static const uint64_t ALLOCA_FLAG_EXPLICIT_TYPE = 0x40;
|
||||
static const uint64_t ALLOCA_ALIGNMENT_MASK = ALLOCA_FLAG_IN_ALLOCA - 1;
|
||||
static const unsigned int SHADER_DESCRIPTOR_TYPE_COUNT = 4;
|
||||
|
||||
static const unsigned int dx_max_thread_group_size[3] = {1024, 1024, 64};
|
||||
@ -2688,12 +2691,15 @@ static void sm6_parser_declare_icb(struct sm6_parser *sm6, const struct sm6_type
|
||||
}
|
||||
|
||||
static void sm6_parser_declare_indexable_temp(struct sm6_parser *sm6, const struct sm6_type *elem_type,
|
||||
unsigned int count, unsigned int alignment, unsigned int init, struct sm6_value *dst)
|
||||
unsigned int count, unsigned int alignment, unsigned int init, struct vkd3d_shader_instruction *ins,
|
||||
struct sm6_value *dst)
|
||||
{
|
||||
enum vkd3d_data_type data_type = vkd3d_data_type_from_sm6_type(elem_type);
|
||||
struct vkd3d_shader_instruction *ins;
|
||||
|
||||
ins = sm6_parser_add_instruction(sm6, VKD3DSIH_DCL_INDEXABLE_TEMP);
|
||||
if (ins)
|
||||
vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_DCL_INDEXABLE_TEMP);
|
||||
else
|
||||
ins = sm6_parser_add_instruction(sm6, VKD3DSIH_DCL_INDEXABLE_TEMP);
|
||||
ins->declaration.indexable_temp.register_idx = sm6->indexable_temp_count++;
|
||||
ins->declaration.indexable_temp.register_size = count;
|
||||
ins->declaration.indexable_temp.alignment = alignment;
|
||||
@ -2826,7 +2832,7 @@ static bool sm6_parser_declare_global(struct sm6_parser *sm6, const struct dxil_
|
||||
if (is_constant)
|
||||
sm6_parser_declare_icb(sm6, scalar_type, count, alignment, init, dst);
|
||||
else
|
||||
sm6_parser_declare_indexable_temp(sm6, scalar_type, count, alignment, init, dst);
|
||||
sm6_parser_declare_indexable_temp(sm6, scalar_type, count, alignment, init, NULL, dst);
|
||||
}
|
||||
else if (address_space == ADDRESS_SPACE_GROUPSHARED)
|
||||
{
|
||||
@ -3019,6 +3025,81 @@ static struct sm6_block *sm6_block_create()
|
||||
return block;
|
||||
}
|
||||
|
||||
static void sm6_parser_emit_alloca(struct sm6_parser *sm6, const struct dxil_record *record,
|
||||
struct vkd3d_shader_instruction *ins, struct sm6_value *dst)
|
||||
{
|
||||
const struct sm6_type *type[2], *elem_type;
|
||||
const struct sm6_value *size;
|
||||
unsigned int i, alignment;
|
||||
uint64_t packed_operands;
|
||||
|
||||
if (!dxil_record_validate_operand_count(record, 4, 4, sm6))
|
||||
return;
|
||||
|
||||
for (i = 0; i < 2; ++i)
|
||||
{
|
||||
if (!(type[i] = sm6_parser_get_type(sm6, record->operands[i])))
|
||||
return;
|
||||
}
|
||||
|
||||
packed_operands = record->operands[3];
|
||||
if (packed_operands & ALLOCA_FLAG_IN_ALLOCA)
|
||||
WARN("Ignoring in_alloca flag.\n");
|
||||
if (!(packed_operands & ALLOCA_FLAG_EXPLICIT_TYPE))
|
||||
{
|
||||
FIXME("Unhandled implicit type.\n");
|
||||
vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND,
|
||||
"Implicit result type for ALLOCA instructions is not supported.");
|
||||
return;
|
||||
}
|
||||
packed_operands &= ~(ALLOCA_FLAG_IN_ALLOCA | ALLOCA_FLAG_EXPLICIT_TYPE);
|
||||
|
||||
if (!sm6_type_is_array(type[0]) || !sm6_type_is_numeric(elem_type = type[0]->u.array.elem_type))
|
||||
{
|
||||
WARN("Type is not a numeric array.\n");
|
||||
vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND,
|
||||
"Result type of an ALLOCA instruction is not a numeric array.");
|
||||
return;
|
||||
}
|
||||
/* The second type operand is the type of the allocation size operand, in case it is a
|
||||
* forward reference. We only support a constant size, so no forward ref support is needed. */
|
||||
if (!sm6_type_is_integer(type[1]))
|
||||
{
|
||||
WARN("Size operand type is not scalar integer.\n");
|
||||
vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND,
|
||||
"The type of the allocation size operand of an ALLOCA instruction is not scalar integer.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(dst->type = sm6_type_get_pointer_to_type(type[0], ADDRESS_SPACE_DEFAULT, sm6)))
|
||||
{
|
||||
WARN("Failed to get pointer type for type class %u.\n", type[0]->class);
|
||||
vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_MODULE,
|
||||
"Module does not define a pointer type for an ALLOCA instruction.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(size = sm6_parser_get_value_safe(sm6, record->operands[2])))
|
||||
return;
|
||||
/* A size of 1 means one instance of type[0], i.e. one array. */
|
||||
if (sm6_value_get_constant_uint(size) != 1)
|
||||
{
|
||||
FIXME("Allocation size is not 1.\n");
|
||||
vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND,
|
||||
"ALLOCA instruction allocation sizes other than 1 are not supported.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!bitcode_parse_alignment(packed_operands & ALLOCA_ALIGNMENT_MASK, &alignment))
|
||||
WARN("Invalid alignment %"PRIu64".\n", packed_operands);
|
||||
packed_operands &= ~ALLOCA_ALIGNMENT_MASK;
|
||||
|
||||
if (packed_operands)
|
||||
WARN("Ignoring flags %#"PRIx64".\n", packed_operands);
|
||||
|
||||
sm6_parser_declare_indexable_temp(sm6, elem_type, type[0]->u.array.count, alignment, 0, ins, dst);
|
||||
}
|
||||
|
||||
static enum vkd3d_shader_opcode map_binary_op(uint64_t code, const struct sm6_type *type_a,
|
||||
const struct sm6_type *type_b, struct sm6_parser *sm6)
|
||||
{
|
||||
@ -4578,6 +4659,9 @@ static enum vkd3d_result sm6_parser_function_init(struct sm6_parser *sm6, const
|
||||
record = block->records[i];
|
||||
switch (record->code)
|
||||
{
|
||||
case FUNC_CODE_INST_ALLOCA:
|
||||
sm6_parser_emit_alloca(sm6, record, ins, dst);
|
||||
break;
|
||||
case FUNC_CODE_INST_BINOP:
|
||||
sm6_parser_emit_binop(sm6, record, ins, dst);
|
||||
break;
|
||||
|
Loading…
x
Reference in New Issue
Block a user