Module: vkd3d Branch: master Commit: a0f5d70792d203e1a9a9e9e64aa5afdda9b553c1 URL: https://gitlab.winehq.org/wine/vkd3d/-/commit/a0f5d70792d203e1a9a9e9e64aa5af...
Author: Conor McCarthy cmccarthy@codeweavers.com Date: Tue Nov 14 00:50:30 2023 +1000
vkd3d-shader/dxil: Support global variable initialisers.
---
libs/vkd3d-shader/d3d_asm.c | 43 ++++++++++++++++++++++------- libs/vkd3d-shader/dxil.c | 47 +++++++++++++++++++++++++------- libs/vkd3d-shader/spirv.c | 6 ++++ libs/vkd3d-shader/vkd3d_shader_private.h | 2 ++ 4 files changed, 78 insertions(+), 20 deletions(-)
diff --git a/libs/vkd3d-shader/d3d_asm.c b/libs/vkd3d-shader/d3d_asm.c index f6d511e7..82d1d71d 100644 --- a/libs/vkd3d-shader/d3d_asm.c +++ b/libs/vkd3d-shader/d3d_asm.c @@ -1595,6 +1595,36 @@ static void shader_print_opcode(struct vkd3d_d3d_asm_compiler *compiler, enum vk shader_opcode_names[opcode], compiler->colours.reset); }
+static void shader_dump_icb(struct vkd3d_d3d_asm_compiler *compiler, + const struct vkd3d_shader_immediate_constant_buffer *icb) +{ + struct vkd3d_string_buffer *buffer = &compiler->buffer; + unsigned int i, j; + + vkd3d_string_buffer_printf(buffer, " {\n"); + if (icb->component_count == 1) + { + for (i = 0; i < icb->element_count; ) + { + for (j = 0; i < icb->element_count && j < 4; ++i, ++j) + shader_print_hex_literal(compiler, !j ? " " : ", ", icb->data[i], ""); + vkd3d_string_buffer_printf(buffer, "\n"); + } + } + else + { + assert(icb->component_count == VKD3D_VEC4_SIZE); + for (i = 0; i < icb->element_count; ++i) + { + shader_print_hex_literal(compiler, " {", icb->data[4 * i + 0], ""); + shader_print_hex_literal(compiler, ", ", icb->data[4 * i + 1], ""); + shader_print_hex_literal(compiler, ", ", icb->data[4 * i + 2], ""); + shader_print_hex_literal(compiler, ", ", icb->data[4 * i + 3], "},\n"); + } + } + shader_addline(buffer, "}"); +} + static void shader_dump_instruction(struct vkd3d_d3d_asm_compiler *compiler, const struct vkd3d_shader_instruction *ins) { @@ -1656,16 +1686,7 @@ static void shader_dump_instruction(struct vkd3d_d3d_asm_compiler *compiler, break;
case VKD3DSIH_DCL_IMMEDIATE_CONSTANT_BUFFER: - vkd3d_string_buffer_printf(buffer, " {\n"); - 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], ""); - shader_print_hex_literal(compiler, ", ", ins->declaration.icb->data[4 * i + 2], ""); - shader_print_hex_literal(compiler, ", ", ins->declaration.icb->data[4 * i + 3], "},\n"); - } - shader_addline(buffer, "}"); + shader_dump_icb(compiler, ins->declaration.icb); break;
case VKD3DSIH_DCL_INDEX_RANGE: @@ -1681,6 +1702,8 @@ static void shader_dump_instruction(struct vkd3d_d3d_asm_compiler *compiler, shader_print_uint_literal(compiler, ", ", ins->declaration.indexable_temp.component_count, ""); if (ins->declaration.indexable_temp.alignment) shader_print_uint_literal(compiler, ", align ", ins->declaration.indexable_temp.alignment, ""); + if (ins->declaration.indexable_temp.initialiser) + shader_dump_icb(compiler, ins->declaration.indexable_temp.initialiser); break;
case VKD3DSIH_DCL_INPUT_PS: diff --git a/libs/vkd3d-shader/dxil.c b/libs/vkd3d-shader/dxil.c index 1929fcb4..5990b6df 100644 --- a/libs/vkd3d-shader/dxil.c +++ b/libs/vkd3d-shader/dxil.c @@ -2603,7 +2603,7 @@ static struct vkd3d_shader_instruction *sm6_parser_add_instruction(struct sm6_pa }
static void sm6_parser_declare_indexable_temp(struct sm6_parser *sm6, const struct sm6_type *elem_type, - unsigned int count, unsigned int alignment, struct sm6_value *dst) + unsigned int count, unsigned int alignment, unsigned int init, struct sm6_value *dst) { enum vkd3d_data_type data_type = vkd3d_data_type_from_sm6_type(elem_type); struct vkd3d_shader_instruction *ins; @@ -2614,6 +2614,8 @@ static void sm6_parser_declare_indexable_temp(struct sm6_parser *sm6, const stru ins->declaration.indexable_temp.alignment = alignment; ins->declaration.indexable_temp.data_type = data_type; ins->declaration.indexable_temp.component_count = 1; + /* The initialiser value index will be resolved later so forward references can be handled. */ + ins->declaration.indexable_temp.initialiser = (void *)(uintptr_t)init;
register_init_with_id(&dst->u.reg, VKD3DSPR_IDXTEMP, data_type, ins->declaration.indexable_temp.register_idx); } @@ -2726,14 +2728,7 @@ static bool sm6_parser_declare_global(struct sm6_parser *sm6, const struct dxil_ dst->type = type; dst->value_type = VALUE_TYPE_REG;
- if (init) - { - FIXME("Unsupported initialiser.\n"); - vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, - "Global variable initialisers are not supported."); - return false; - } - else if (is_constant) + if (is_constant && !init) { WARN("Constant array has no initialiser.\n"); vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, @@ -2743,7 +2738,7 @@ static bool sm6_parser_declare_global(struct sm6_parser *sm6, const struct dxil_
if (address_space == ADDRESS_SPACE_DEFAULT) { - sm6_parser_declare_indexable_temp(sm6, scalar_type, count, alignment, dst); + sm6_parser_declare_indexable_temp(sm6, scalar_type, count, alignment, init, dst); } else if (address_space == ADDRESS_SPACE_GROUPSHARED) { @@ -2764,9 +2759,30 @@ static bool sm6_parser_declare_global(struct sm6_parser *sm6, const struct dxil_ return true; }
+static const struct vkd3d_shader_immediate_constant_buffer *resolve_forward_initialiser( + size_t index, struct sm6_parser *sm6) +{ + const struct sm6_value *value; + + assert(index); + --index; + if (!(value = sm6_parser_get_value_safe(sm6, index)) || !sm6_value_is_icb(value)) + { + WARN("Invalid initialiser index %zu.\n", index); + vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, + "Global variable initialiser value index %zu is invalid.", index); + return NULL; + } + else + { + return value->u.icb; + } +} + static enum vkd3d_result sm6_parser_globals_init(struct sm6_parser *sm6) { const struct dxil_block *block = &sm6->root_block; + struct vkd3d_shader_instruction *ins; const struct dxil_record *record; enum vkd3d_result ret; uint64_t version; @@ -2819,6 +2835,17 @@ static enum vkd3d_result sm6_parser_globals_init(struct sm6_parser *sm6) return ret; }
+ /* Resolve initialiser forward references. */ + for (i = 0; i < sm6->p.instructions.count; ++i) + { + ins = &sm6->p.instructions.elements[i]; + if (ins->handler_idx == VKD3DSIH_DCL_INDEXABLE_TEMP && ins->declaration.indexable_temp.initialiser) + { + ins->declaration.indexable_temp.initialiser = resolve_forward_initialiser( + (uintptr_t)ins->declaration.indexable_temp.initialiser, sm6); + } + } + return VKD3D_OK; }
diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c index e6fb0a12..67c5e383 100644 --- a/libs/vkd3d-shader/spirv.c +++ b/libs/vkd3d-shader/spirv.c @@ -5497,6 +5497,12 @@ static void spirv_compiler_emit_dcl_indexable_temp(struct spirv_compiler *compil
if (temp->alignment) WARN("Ignoring alignment %u.\n", temp->alignment); + if (temp->initialiser) + { + FIXME("Initialisers are not supported.\n"); + spirv_compiler_error(compiler, VKD3D_SHADER_ERROR_SPV_NOT_IMPLEMENTED, + "Initialisers for indexable temps are not supported."); + }
function_location = spirv_compiler_get_current_function_location(compiler); vkd3d_spirv_begin_function_stream_insertion(builder, function_location); diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h index e4e0ca42..fc6c5fca 100644 --- a/libs/vkd3d-shader/vkd3d_shader_private.h +++ b/libs/vkd3d-shader/vkd3d_shader_private.h @@ -95,6 +95,7 @@ enum vkd3d_shader_error VKD3D_SHADER_ERROR_SPV_OUT_OF_MEMORY = 2005, VKD3D_SHADER_ERROR_SPV_INVALID_TYPE = 2006, VKD3D_SHADER_ERROR_SPV_INVALID_HANDLER = 2007, + VKD3D_SHADER_ERROR_SPV_NOT_IMPLEMENTED = 2008,
VKD3D_SHADER_WARNING_SPV_INVALID_SWIZZLE = 2300,
@@ -806,6 +807,7 @@ struct vkd3d_shader_indexable_temp unsigned int alignment; enum vkd3d_data_type data_type; unsigned int component_count; + const struct vkd3d_shader_immediate_constant_buffer *initialiser; };
struct vkd3d_shader_register_index