mirror of
https://gitlab.winehq.org/wine/vkd3d.git
synced 2025-01-28 13:05:02 -08:00
vkd3d-shader/dxil: Read immediate constant arrays.
This commit is contained in:
parent
57280673e5
commit
df4e1b7393
Notes:
Alexandre Julliard
2023-10-11 22:54:06 +02: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/400
@ -1646,7 +1646,8 @@ static void shader_dump_instruction(struct vkd3d_d3d_asm_compiler *compiler,
|
||||
|
||||
case VKD3DSIH_DCL_IMMEDIATE_CONSTANT_BUFFER:
|
||||
vkd3d_string_buffer_printf(buffer, " {\n");
|
||||
for (i = 0; i < ins->declaration.icb->vec4_count; ++i)
|
||||
assert(ins->declaration.icb->component_count == VKD3D_VEC4_SIZE);
|
||||
for (i = 0; i < ins->declaration.icb->element_count; ++i)
|
||||
{
|
||||
shader_print_hex_literal(compiler, " {", ins->declaration.icb->data[4 * i + 0], "");
|
||||
shader_print_hex_literal(compiler, ", ", ins->declaration.icb->data[4 * i + 1], "");
|
||||
|
@ -1324,6 +1324,11 @@ static bool sm6_type_is_numeric_aggregate(const struct sm6_type *type)
|
||||
}
|
||||
}
|
||||
|
||||
static bool sm6_type_is_array(const struct sm6_type *type)
|
||||
{
|
||||
return type->class == TYPE_CLASS_ARRAY;
|
||||
}
|
||||
|
||||
static inline bool sm6_type_is_struct(const struct sm6_type *type)
|
||||
{
|
||||
return type->class == TYPE_CLASS_STRUCT;
|
||||
@ -1916,12 +1921,80 @@ static inline double bitcast_uint64_to_double(uint64_t value)
|
||||
return u.double_value;
|
||||
}
|
||||
|
||||
static enum vkd3d_result register_allocate_constant_array(struct vkd3d_shader_register *reg, const struct sm6_type *type,
|
||||
const uint64_t *operands, struct sm6_parser *sm6)
|
||||
{
|
||||
struct vkd3d_shader_immediate_constant_buffer *icb;
|
||||
const struct sm6_type *elem_type;
|
||||
unsigned int i, size, count;
|
||||
|
||||
elem_type = type->u.array.elem_type;
|
||||
/* Multidimensional arrays are emitted in flattened form. */
|
||||
if (elem_type->class != TYPE_CLASS_INTEGER && elem_type->class != TYPE_CLASS_FLOAT)
|
||||
{
|
||||
FIXME("Unhandled element type %u for data array.\n", elem_type->class);
|
||||
vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND,
|
||||
"The element data type for an immediate constant buffer is not scalar integer or floating point.");
|
||||
return VKD3D_ERROR_INVALID_SHADER;
|
||||
}
|
||||
|
||||
/* Arrays of bool are not used in DXIL. dxc will emit an array of int32 instead if necessary. */
|
||||
if (!(size = elem_type->u.width / CHAR_BIT))
|
||||
{
|
||||
WARN("Invalid data type width %u.\n", elem_type->u.width);
|
||||
vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND,
|
||||
"An immediate constant buffer is declared with boolean elements.");
|
||||
return VKD3D_ERROR_INVALID_SHADER;
|
||||
}
|
||||
size = max(size, sizeof(icb->data[0]));
|
||||
count = type->u.array.count * size / sizeof(icb->data[0]);
|
||||
|
||||
if (!(icb = vkd3d_malloc(offsetof(struct vkd3d_shader_immediate_constant_buffer, data[count]))))
|
||||
{
|
||||
ERR("Failed to allocate buffer, count %u.\n", count);
|
||||
vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY,
|
||||
"Out of memory allocating an immediate constant buffer of count %u.", count);
|
||||
return VKD3D_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
if ((reg->idx[0].offset = shader_instruction_array_add_icb(&sm6->p.instructions, icb)) == UINT_MAX)
|
||||
{
|
||||
ERR("Failed to store icb object.\n");
|
||||
vkd3d_free(icb);
|
||||
vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY,
|
||||
"Out of memory storing an immediate constant buffer object.");
|
||||
return VKD3D_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
reg->type = VKD3DSPR_IMMCONSTBUFFER;
|
||||
reg->idx_count = 1;
|
||||
|
||||
icb->data_type = vkd3d_data_type_from_sm6_type(elem_type);
|
||||
icb->element_count = type->u.array.count;
|
||||
icb->component_count = 1;
|
||||
|
||||
count = type->u.array.count;
|
||||
if (size > sizeof(icb->data[0]))
|
||||
{
|
||||
uint64_t *data = (uint64_t *)icb->data;
|
||||
for (i = 0; i < count; ++i)
|
||||
data[i] = operands[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < count; ++i)
|
||||
icb->data[i] = operands[i];
|
||||
}
|
||||
|
||||
return VKD3D_OK;
|
||||
}
|
||||
|
||||
static enum vkd3d_result sm6_parser_constants_init(struct sm6_parser *sm6, const struct dxil_block *block)
|
||||
{
|
||||
enum vkd3d_shader_register_type reg_type = VKD3DSPR_INVALID;
|
||||
const struct sm6_type *type, *elem_type;
|
||||
enum vkd3d_data_type reg_data_type;
|
||||
const struct dxil_record *record;
|
||||
enum vkd3d_result ret;
|
||||
struct sm6_value *dst;
|
||||
size_t i, value_idx;
|
||||
uint64_t value;
|
||||
@ -1974,7 +2047,14 @@ static enum vkd3d_result sm6_parser_constants_init(struct sm6_parser *sm6, const
|
||||
switch (record->code)
|
||||
{
|
||||
case CST_CODE_NULL:
|
||||
/* Register constant data is already zero-filled. */
|
||||
if (sm6_type_is_array(type))
|
||||
{
|
||||
FIXME("Constant null arrays are not supported.\n");
|
||||
vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND,
|
||||
"Constant null arrays are not supported.");
|
||||
return VKD3D_ERROR_INVALID_SHADER;
|
||||
}
|
||||
/* For non-aggregates, register constant data is already zero-filled. */
|
||||
break;
|
||||
|
||||
case CST_CODE_INTEGER:
|
||||
@ -2017,7 +2097,19 @@ static enum vkd3d_result sm6_parser_constants_init(struct sm6_parser *sm6, const
|
||||
break;
|
||||
|
||||
case CST_CODE_DATA:
|
||||
WARN("Unhandled constant array.\n");
|
||||
if (!sm6_type_is_array(type))
|
||||
{
|
||||
WARN("Invalid type %u for data constant idx %zu.\n", type->class, value_idx);
|
||||
vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND,
|
||||
"The type of a constant array is not an array type.");
|
||||
return VKD3D_ERROR_INVALID_SHADER;
|
||||
}
|
||||
if (!dxil_record_validate_operand_count(record, type->u.array.count, type->u.array.count, sm6))
|
||||
return VKD3D_ERROR_INVALID_SHADER;
|
||||
|
||||
if ((ret = register_allocate_constant_array(&dst->u.reg, type, record->operands, sm6)) < 0)
|
||||
return ret;
|
||||
|
||||
break;
|
||||
|
||||
case CST_CODE_UNDEF:
|
||||
|
@ -5686,15 +5686,18 @@ static void spirv_compiler_emit_dcl_immediate_constant_buffer(struct spirv_compi
|
||||
struct vkd3d_symbol reg_symbol;
|
||||
unsigned int i;
|
||||
|
||||
if (!(elements = vkd3d_calloc(icb->vec4_count, sizeof(*elements))))
|
||||
assert(icb->data_type == VKD3D_DATA_FLOAT);
|
||||
assert(icb->component_count == VKD3D_VEC4_SIZE);
|
||||
|
||||
if (!(elements = vkd3d_calloc(icb->element_count, sizeof(*elements))))
|
||||
return;
|
||||
for (i = 0; i < icb->vec4_count; ++i)
|
||||
for (i = 0; i < icb->element_count; ++i)
|
||||
elements[i] = spirv_compiler_get_constant(compiler,
|
||||
VKD3D_SHADER_COMPONENT_FLOAT, VKD3D_VEC4_SIZE, &icb->data[4 * i]);
|
||||
type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_FLOAT, VKD3D_VEC4_SIZE);
|
||||
length_id = spirv_compiler_get_constant_uint(compiler, icb->vec4_count);
|
||||
length_id = spirv_compiler_get_constant_uint(compiler, icb->element_count);
|
||||
type_id = vkd3d_spirv_get_op_type_array(builder, type_id, length_id);
|
||||
const_id = vkd3d_spirv_build_op_constant_composite(builder, type_id, elements, icb->vec4_count);
|
||||
const_id = vkd3d_spirv_build_op_constant_composite(builder, type_id, elements, icb->element_count);
|
||||
ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassPrivate, type_id);
|
||||
icb_id = vkd3d_spirv_build_op_variable(builder, &builder->global_stream,
|
||||
ptr_type_id, SpvStorageClassPrivate, const_id);
|
||||
|
@ -784,7 +784,9 @@ static void shader_sm4_read_shader_data(struct vkd3d_shader_instruction *ins, ui
|
||||
ins->handler_idx = VKD3DSIH_INVALID;
|
||||
return;
|
||||
}
|
||||
icb->vec4_count = icb_size / 4;
|
||||
icb->data_type = VKD3D_DATA_FLOAT;
|
||||
icb->component_count = VKD3D_VEC4_SIZE;
|
||||
icb->element_count = icb_size / VKD3D_VEC4_SIZE;
|
||||
memcpy(icb->data, tokens, sizeof(*tokens) * icb_size);
|
||||
shader_instruction_array_add_icb(&priv->p.instructions, icb);
|
||||
ins->declaration.icb = icb;
|
||||
|
@ -1852,14 +1852,14 @@ bool shader_instruction_array_reserve(struct vkd3d_shader_instruction_array *ins
|
||||
return true;
|
||||
}
|
||||
|
||||
bool shader_instruction_array_add_icb(struct vkd3d_shader_instruction_array *instructions,
|
||||
unsigned int shader_instruction_array_add_icb(struct vkd3d_shader_instruction_array *instructions,
|
||||
struct vkd3d_shader_immediate_constant_buffer *icb)
|
||||
{
|
||||
if (!vkd3d_array_reserve((void **)&instructions->icbs, &instructions->icb_capacity, instructions->icb_count + 1,
|
||||
sizeof(*instructions->icbs)))
|
||||
return false;
|
||||
instructions->icbs[instructions->icb_count++] = icb;
|
||||
return true;
|
||||
return UINT_MAX;
|
||||
instructions->icbs[instructions->icb_count] = icb;
|
||||
return instructions->icb_count++;
|
||||
}
|
||||
|
||||
static struct vkd3d_shader_src_param *shader_instruction_array_clone_src_params(
|
||||
|
@ -716,7 +716,10 @@ struct vkd3d_shader_version
|
||||
|
||||
struct vkd3d_shader_immediate_constant_buffer
|
||||
{
|
||||
unsigned int vec4_count;
|
||||
enum vkd3d_data_type data_type;
|
||||
/* total count is element_count * component_count */
|
||||
unsigned int element_count;
|
||||
unsigned int component_count;
|
||||
uint32_t data[];
|
||||
};
|
||||
|
||||
@ -1102,7 +1105,7 @@ struct vkd3d_shader_instruction_array
|
||||
|
||||
bool shader_instruction_array_init(struct vkd3d_shader_instruction_array *instructions, unsigned int reserve);
|
||||
bool shader_instruction_array_reserve(struct vkd3d_shader_instruction_array *instructions, unsigned int reserve);
|
||||
bool shader_instruction_array_add_icb(struct vkd3d_shader_instruction_array *instructions,
|
||||
unsigned int shader_instruction_array_add_icb(struct vkd3d_shader_instruction_array *instructions,
|
||||
struct vkd3d_shader_immediate_constant_buffer *icb);
|
||||
bool shader_instruction_array_clone_instruction(struct vkd3d_shader_instruction_array *instructions,
|
||||
unsigned int dst, unsigned int src);
|
||||
|
Loading…
x
Reference in New Issue
Block a user