2025-10-01 07:50:19 +10:00
|
|
|
From 29ba3145cd22f1e29bb71b166cedfa8aedf95a4a Mon Sep 17 00:00:00 2001
|
2025-09-30 07:58:05 +10:00
|
|
|
From: Alistair Leslie-Hughes <leslie_alistair@hotmail.com>
|
|
|
|
|
Date: Tue, 30 Sep 2025 07:43:05 +1000
|
|
|
|
|
Subject: [PATCH] Updated vkd3d to b4174f52521fa4921babad6f1c374d5e9c218c95.
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
libs/vkd3d/libs/vkd3d-shader/ir.c | 427 ++++++++++--------
|
|
|
|
|
libs/vkd3d/libs/vkd3d-shader/msl.c | 15 +
|
|
|
|
|
libs/vkd3d/libs/vkd3d-shader/spirv.c | 44 +-
|
|
|
|
|
.../libs/vkd3d-shader/vkd3d_shader_private.h | 16 +-
|
|
|
|
|
4 files changed, 282 insertions(+), 220 deletions(-)
|
|
|
|
|
|
|
|
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/ir.c b/libs/vkd3d/libs/vkd3d-shader/ir.c
|
|
|
|
|
index d765b5acccd..43bd799d2eb 100644
|
|
|
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/ir.c
|
|
|
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/ir.c
|
|
|
|
|
@@ -502,6 +502,14 @@ bool shader_instruction_array_insert_at(struct vkd3d_shader_instruction_array *a
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
+struct vkd3d_shader_instruction *shader_instruction_array_append(struct vkd3d_shader_instruction_array *array)
|
|
|
|
|
+{
|
|
|
|
|
+ if (!shader_instruction_array_insert_at(array, array->count, 1))
|
|
|
|
|
+ return NULL;
|
|
|
|
|
+
|
|
|
|
|
+ return &array->elements[array->count - 1];
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
bool vsir_program_add_icb(struct vsir_program *program, struct vkd3d_shader_immediate_constant_buffer *icb)
|
|
|
|
|
{
|
|
|
|
|
if (!vkd3d_array_reserve((void **)&program->icbs, &program->icb_capacity,
|
|
|
|
|
@@ -3842,6 +3850,17 @@ static enum vkd3d_result vsir_program_remove_dead_code(struct vsir_program *prog
|
|
|
|
|
return VKD3D_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
+/* NOTE: This invalidates all iterators, since the position of the
|
|
|
|
|
+ * vkd3d_shader_instruction_array itself changes. */
|
|
|
|
|
+static void vsir_program_replace_instructions(struct vsir_program *program,
|
|
|
|
|
+ struct vkd3d_shader_instruction_array *array)
|
|
|
|
|
+{
|
|
|
|
|
+ shader_instruction_array_destroy(&program->instructions);
|
|
|
|
|
+
|
|
|
|
|
+ program->instructions = *array;
|
|
|
|
|
+ memset(array, 0, sizeof(*array));
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
struct cf_flattener_if_info
|
|
|
|
|
{
|
|
|
|
|
struct vkd3d_shader_src_param *false_param;
|
|
|
|
|
@@ -3865,7 +3884,7 @@ struct cf_flattener_switch_case
|
|
|
|
|
|
|
|
|
|
struct cf_flattener_switch_info
|
|
|
|
|
{
|
|
|
|
|
- size_t ins_location;
|
|
|
|
|
+ struct vsir_program_iterator ins_it;
|
|
|
|
|
const struct vkd3d_shader_src_param *condition;
|
|
|
|
|
unsigned int id;
|
|
|
|
|
unsigned int merge_block_id;
|
|
|
|
|
@@ -3900,9 +3919,7 @@ struct cf_flattener
|
|
|
|
|
struct vkd3d_shader_location location;
|
|
|
|
|
enum vkd3d_result status;
|
|
|
|
|
|
|
|
|
|
- struct vkd3d_shader_instruction *instructions;
|
|
|
|
|
- size_t instruction_capacity;
|
|
|
|
|
- size_t instruction_count;
|
|
|
|
|
+ struct vkd3d_shader_instruction_array instructions;
|
|
|
|
|
|
|
|
|
|
unsigned int block_id;
|
|
|
|
|
const char **block_names;
|
|
|
|
|
@@ -3925,18 +3942,6 @@ static void cf_flattener_set_error(struct cf_flattener *flattener, enum vkd3d_re
|
|
|
|
|
flattener->status = error;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
-static struct vkd3d_shader_instruction *cf_flattener_require_space(struct cf_flattener *flattener, size_t count)
|
|
|
|
|
-{
|
|
|
|
|
- if (!vkd3d_array_reserve((void **)&flattener->instructions, &flattener->instruction_capacity,
|
|
|
|
|
- flattener->instruction_count + count, sizeof(*flattener->instructions)))
|
|
|
|
|
- {
|
|
|
|
|
- ERR("Failed to allocate instructions.\n");
|
|
|
|
|
- cf_flattener_set_error(flattener, VKD3D_ERROR_OUT_OF_MEMORY);
|
|
|
|
|
- return NULL;
|
|
|
|
|
- }
|
|
|
|
|
- return &flattener->instructions[flattener->instruction_count];
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
static bool cf_flattener_copy_instruction(struct cf_flattener *flattener,
|
|
|
|
|
const struct vkd3d_shader_instruction *instruction)
|
|
|
|
|
{
|
|
|
|
|
@@ -3945,11 +3950,10 @@ static bool cf_flattener_copy_instruction(struct cf_flattener *flattener,
|
|
|
|
|
if (instruction->opcode == VSIR_OP_NOP)
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
- if (!(dst_ins = cf_flattener_require_space(flattener, 1)))
|
|
|
|
|
+ if (!(dst_ins = shader_instruction_array_append(&flattener->instructions)))
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
*dst_ins = *instruction;
|
|
|
|
|
- ++flattener->instruction_count;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -3977,12 +3981,13 @@ static void cf_flattener_emit_label(struct cf_flattener *flattener, unsigned int
|
|
|
|
|
{
|
|
|
|
|
struct vkd3d_shader_instruction *ins;
|
|
|
|
|
|
|
|
|
|
- if (!(ins = cf_flattener_require_space(flattener, 1)))
|
|
|
|
|
+ if (!(ins = shader_instruction_array_append(&flattener->instructions)))
|
|
|
|
|
return;
|
|
|
|
|
- if (vsir_instruction_init_label(ins, &flattener->location, label_id, flattener->program))
|
|
|
|
|
- ++flattener->instruction_count;
|
|
|
|
|
- else
|
|
|
|
|
+ if (!vsir_instruction_init_label(ins, &flattener->location, label_id, flattener->program))
|
|
|
|
|
+ {
|
|
|
|
|
+ vkd3d_shader_instruction_make_nop(ins);
|
|
|
|
|
cf_flattener_set_error(flattener, VKD3D_ERROR_OUT_OF_MEMORY);
|
|
|
|
|
+ }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* For conditional branches, this returns the false target branch parameter. */
|
|
|
|
|
@@ -3994,14 +3999,17 @@ static struct vkd3d_shader_src_param *cf_flattener_emit_branch(struct cf_flatten
|
|
|
|
|
struct vkd3d_shader_src_param *src_params, *false_branch_param;
|
|
|
|
|
struct vkd3d_shader_instruction *ins;
|
|
|
|
|
|
|
|
|
|
- if (!(ins = cf_flattener_require_space(flattener, 1)))
|
|
|
|
|
+ if (!(ins = shader_instruction_array_append(&flattener->instructions)))
|
|
|
|
|
return NULL;
|
|
|
|
|
vsir_instruction_init(ins, &flattener->location, VSIR_OP_BRANCH);
|
|
|
|
|
|
|
|
|
|
if (condition)
|
|
|
|
|
{
|
|
|
|
|
if (!(src_params = instruction_src_params_alloc(ins, 4 + !!continue_block_id, flattener)))
|
|
|
|
|
+ {
|
|
|
|
|
+ vkd3d_shader_instruction_make_nop(ins);
|
|
|
|
|
return NULL;
|
|
|
|
|
+ }
|
|
|
|
|
src_params[0] = *condition;
|
|
|
|
|
if (flags == VKD3D_SHADER_CONDITIONAL_OP_Z)
|
|
|
|
|
{
|
|
|
|
|
@@ -4022,7 +4030,10 @@ static struct vkd3d_shader_src_param *cf_flattener_emit_branch(struct cf_flatten
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (!(src_params = instruction_src_params_alloc(ins, merge_block_id ? 3 : 1, flattener)))
|
|
|
|
|
+ {
|
|
|
|
|
+ vkd3d_shader_instruction_make_nop(ins);
|
|
|
|
|
return NULL;
|
|
|
|
|
+ }
|
|
|
|
|
vsir_src_param_init_label(&src_params[0], true_id);
|
|
|
|
|
if (merge_block_id)
|
|
|
|
|
{
|
|
|
|
|
@@ -4034,8 +4045,6 @@ static struct vkd3d_shader_src_param *cf_flattener_emit_branch(struct cf_flatten
|
|
|
|
|
false_branch_param = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- ++flattener->instruction_count;
|
|
|
|
|
-
|
|
|
|
|
return false_branch_param;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -4141,8 +4150,12 @@ static enum vkd3d_result cf_flattener_iterate_instruction_array(struct cf_flatte
|
|
|
|
|
is_hull_shader = program->shader_version.type == VKD3D_SHADER_TYPE_HULL;
|
|
|
|
|
after_declarations_section = is_hull_shader;
|
|
|
|
|
|
|
|
|
|
- if (!cf_flattener_require_space(flattener, instructions->count + 1))
|
|
|
|
|
+ if (!shader_instruction_array_reserve(&flattener->instructions, instructions->count + 1))
|
|
|
|
|
+ {
|
|
|
|
|
+ ERR("Failed to allocate instructions.\n");
|
|
|
|
|
+ cf_flattener_set_error(flattener, VKD3D_ERROR_OUT_OF_MEMORY);
|
|
|
|
|
return VKD3D_ERROR_OUT_OF_MEMORY;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
|
|
it = vsir_program_iterator(instructions);
|
|
|
|
|
for (instruction = vsir_program_iterator_head(&it); instruction; instruction = vsir_program_iterator_next(&it))
|
|
|
|
|
@@ -4282,13 +4295,14 @@ static enum vkd3d_result cf_flattener_iterate_instruction_array(struct cf_flatte
|
|
|
|
|
|
|
|
|
|
merge_block_id = cf_flattener_alloc_block_id(flattener);
|
|
|
|
|
|
|
|
|
|
- cf_info->u.switch_.ins_location = flattener->instruction_count;
|
|
|
|
|
cf_info->u.switch_.condition = src;
|
|
|
|
|
|
|
|
|
|
- if (!(dst_ins = cf_flattener_require_space(flattener, 1)))
|
|
|
|
|
+ if (!(dst_ins = shader_instruction_array_append(&flattener->instructions)))
|
|
|
|
|
return VKD3D_ERROR_OUT_OF_MEMORY;
|
|
|
|
|
vsir_instruction_init(dst_ins, &instruction->location, VSIR_OP_SWITCH_MONOLITHIC);
|
|
|
|
|
- ++flattener->instruction_count;
|
|
|
|
|
+
|
|
|
|
|
+ cf_info->u.switch_.ins_it = vsir_program_iterator(&flattener->instructions);
|
|
|
|
|
+ vsir_program_iterator_tail(&cf_info->u.switch_.ins_it);
|
|
|
|
|
|
|
|
|
|
cf_info->u.switch_.id = flattener->switch_id;
|
|
|
|
|
cf_info->u.switch_.merge_block_id = merge_block_id;
|
|
|
|
|
@@ -4321,8 +4335,12 @@ static enum vkd3d_result cf_flattener_iterate_instruction_array(struct cf_flatte
|
|
|
|
|
/* The SWITCH instruction is completed when the endswitch
|
|
|
|
|
* instruction is processed because we do not know the number
|
|
|
|
|
* of case statements or the default block id in advance.*/
|
|
|
|
|
- dst_ins = &flattener->instructions[cf_info->u.switch_.ins_location];
|
|
|
|
|
- if (!(src_params = instruction_src_params_alloc(dst_ins, cf_info->u.switch_.cases_count * 2 + 3, flattener)))
|
|
|
|
|
+ /* NOTE: This relies on iterators not being invalidated
|
|
|
|
|
+ * when new instructions are appended to the
|
|
|
|
|
+ * vkd3d_shader_instruction_array. */
|
|
|
|
|
+ dst_ins = vsir_program_iterator_current(&cf_info->u.switch_.ins_it);
|
|
|
|
|
+ if (!(src_params = instruction_src_params_alloc(dst_ins,
|
|
|
|
|
+ cf_info->u.switch_.cases_count * 2 + 3, flattener)))
|
|
|
|
|
{
|
|
|
|
|
vkd3d_free(cf_info->u.switch_.cases);
|
|
|
|
|
return VKD3D_ERROR_OUT_OF_MEMORY;
|
|
|
|
|
@@ -4485,16 +4503,13 @@ static enum vkd3d_result vsir_program_flatten_control_flow_constructs(struct vsi
|
|
|
|
|
|
|
|
|
|
if ((result = cf_flattener_iterate_instruction_array(&flattener, message_context)) >= 0)
|
|
|
|
|
{
|
|
|
|
|
- vkd3d_free(program->instructions.elements);
|
|
|
|
|
- program->instructions.elements = flattener.instructions;
|
|
|
|
|
- program->instructions.capacity = flattener.instruction_capacity;
|
|
|
|
|
- program->instructions.count = flattener.instruction_count;
|
|
|
|
|
+ vsir_program_replace_instructions(program, &flattener.instructions);
|
|
|
|
|
program->block_count = flattener.block_id;
|
|
|
|
|
program->cf_type = VSIR_CF_BLOCKS;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
- vkd3d_free(flattener.instructions);
|
|
|
|
|
+ shader_instruction_array_destroy(&flattener.instructions);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
vkd3d_free(flattener.control_flow_info);
|
|
|
|
|
@@ -4511,17 +4526,6 @@ static unsigned int label_from_src_param(const struct vkd3d_shader_src_param *pa
|
|
|
|
|
return param->reg.idx[0].offset;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
-static bool reserve_instructions(struct vkd3d_shader_instruction **instructions, size_t *capacity, size_t count)
|
|
|
|
|
-{
|
|
|
|
|
- if (!vkd3d_array_reserve((void **)instructions, capacity, count, sizeof(**instructions)))
|
|
|
|
|
- {
|
|
|
|
|
- ERR("Failed to allocate instructions.\n");
|
|
|
|
|
- return false;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- return true;
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
/* A record represents replacing a jump from block `switch_label' to
|
|
|
|
|
* block `target_label' with a jump from block `if_label' to block
|
|
|
|
|
* `target_label'. */
|
|
|
|
|
@@ -4555,14 +4559,14 @@ static enum vkd3d_result vsir_program_lower_switch_to_selection_ladder(struct vs
|
|
|
|
|
{
|
|
|
|
|
unsigned int block_count = program->block_count, ssa_count = program->ssa_count, current_label = 0, if_label;
|
|
|
|
|
struct vsir_program_iterator it = vsir_program_iterator(&program->instructions);
|
|
|
|
|
- size_t ins_capacity = 0, ins_count = 0, map_capacity = 0, map_count = 0;
|
|
|
|
|
- struct vkd3d_shader_instruction *instructions = NULL;
|
|
|
|
|
struct lower_switch_to_if_ladder_block_mapping *block_map = NULL;
|
|
|
|
|
- struct vkd3d_shader_instruction *ins;
|
|
|
|
|
+ struct vkd3d_shader_instruction_array instructions = {0};
|
|
|
|
|
+ struct vkd3d_shader_instruction *ins, *dst_ins;
|
|
|
|
|
+ size_t map_capacity = 0, map_count = 0;
|
|
|
|
|
|
|
|
|
|
VKD3D_ASSERT(program->cf_type == VSIR_CF_BLOCKS);
|
|
|
|
|
|
|
|
|
|
- if (!reserve_instructions(&instructions, &ins_capacity, program->instructions.count))
|
|
|
|
|
+ if (!shader_instruction_array_reserve(&instructions, program->instructions.count))
|
|
|
|
|
goto fail;
|
|
|
|
|
|
|
|
|
|
/* First subpass: convert SWITCH_MONOLITHIC instructions to
|
|
|
|
|
@@ -4576,18 +4580,18 @@ static enum vkd3d_result vsir_program_lower_switch_to_selection_ladder(struct vs
|
|
|
|
|
{
|
|
|
|
|
case VSIR_OP_LABEL:
|
|
|
|
|
current_label = label_from_src_param(&ins->src[0]);
|
|
|
|
|
- if (!reserve_instructions(&instructions, &ins_capacity, ins_count + 1))
|
|
|
|
|
+ if (!(dst_ins = shader_instruction_array_append(&instructions)))
|
|
|
|
|
goto fail;
|
|
|
|
|
- instructions[ins_count++] = *ins;
|
|
|
|
|
+ *dst_ins = *ins;
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
case VSIR_OP_SWITCH_MONOLITHIC:
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
- if (!reserve_instructions(&instructions, &ins_capacity, ins_count + 1))
|
|
|
|
|
+ if (!(dst_ins = shader_instruction_array_append(&instructions)))
|
|
|
|
|
goto fail;
|
|
|
|
|
- instructions[ins_count++] = *ins;
|
|
|
|
|
+ *dst_ins = *ins;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -4598,17 +4602,18 @@ static enum vkd3d_result vsir_program_lower_switch_to_selection_ladder(struct vs
|
|
|
|
|
* just have to jump to the default label. */
|
|
|
|
|
if (case_count == 0)
|
|
|
|
|
{
|
|
|
|
|
- if (!reserve_instructions(&instructions, &ins_capacity, ins_count + 1))
|
|
|
|
|
+ if (!(dst_ins = shader_instruction_array_append(&instructions)))
|
|
|
|
|
goto fail;
|
|
|
|
|
|
|
|
|
|
- if (!vsir_instruction_init_with_params(program, &instructions[ins_count],
|
|
|
|
|
- &ins->location, VSIR_OP_BRANCH, 0, 1))
|
|
|
|
|
+ if (!vsir_instruction_init_with_params(program, dst_ins, &ins->location, VSIR_OP_BRANCH, 0, 1))
|
|
|
|
|
+ {
|
|
|
|
|
+ vkd3d_shader_instruction_make_nop(dst_ins);
|
|
|
|
|
goto fail;
|
|
|
|
|
- vsir_src_param_init_label(&instructions[ins_count].src[0], default_label);
|
|
|
|
|
- ++ins_count;
|
|
|
|
|
+ }
|
|
|
|
|
+ vsir_src_param_init_label(&dst_ins->src[0], default_label);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- if (!reserve_instructions(&instructions, &ins_capacity, ins_count + 3 * case_count - 1))
|
|
|
|
|
+ if (!shader_instruction_array_reserve(&instructions, instructions.count + 3 * case_count - 1))
|
|
|
|
|
goto fail;
|
|
|
|
|
|
|
|
|
|
if_label = current_label;
|
|
|
|
|
@@ -4617,13 +4622,15 @@ static enum vkd3d_result vsir_program_lower_switch_to_selection_ladder(struct vs
|
|
|
|
|
{
|
|
|
|
|
unsigned int fallthrough_label, case_label = label_from_src_param(&ins->src[3 + 2 * j + 1]);
|
|
|
|
|
|
|
|
|
|
- if (!vsir_instruction_init_with_params(program,
|
|
|
|
|
- &instructions[ins_count], &ins->location, VSIR_OP_IEQ, 1, 2))
|
|
|
|
|
+ dst_ins = shader_instruction_array_append(&instructions);
|
|
|
|
|
+ if (!vsir_instruction_init_with_params(program, dst_ins, &ins->location, VSIR_OP_IEQ, 1, 2))
|
|
|
|
|
+ {
|
|
|
|
|
+ vkd3d_shader_instruction_make_nop(dst_ins);
|
|
|
|
|
goto fail;
|
|
|
|
|
- dst_param_init_ssa_bool(&instructions[ins_count].dst[0], ssa_count);
|
|
|
|
|
- instructions[ins_count].src[0] = ins->src[0];
|
|
|
|
|
- instructions[ins_count].src[1] = ins->src[3 + 2 * j];
|
|
|
|
|
- ++ins_count;
|
|
|
|
|
+ }
|
|
|
|
|
+ dst_param_init_ssa_bool(&dst_ins->dst[0], ssa_count);
|
|
|
|
|
+ dst_ins->src[0] = ins->src[0];
|
|
|
|
|
+ dst_ins->src[1] = ins->src[3 + 2 * j];
|
|
|
|
|
|
|
|
|
|
/* For all cases except the last one we fall through to
|
|
|
|
|
* the following case; the last one has to jump to the
|
|
|
|
|
@@ -4633,13 +4640,15 @@ static enum vkd3d_result vsir_program_lower_switch_to_selection_ladder(struct vs
|
|
|
|
|
else
|
|
|
|
|
fallthrough_label = block_count + 1;
|
|
|
|
|
|
|
|
|
|
- if (!vsir_instruction_init_with_params(program, &instructions[ins_count],
|
|
|
|
|
- &ins->location, VSIR_OP_BRANCH, 0, 3))
|
|
|
|
|
+ dst_ins = shader_instruction_array_append(&instructions);
|
|
|
|
|
+ if (!vsir_instruction_init_with_params(program, dst_ins, &ins->location, VSIR_OP_BRANCH, 0, 3))
|
|
|
|
|
+ {
|
|
|
|
|
+ vkd3d_shader_instruction_make_nop(dst_ins);
|
|
|
|
|
goto fail;
|
|
|
|
|
- src_param_init_ssa_bool(&instructions[ins_count].src[0], ssa_count);
|
|
|
|
|
- vsir_src_param_init_label(&instructions[ins_count].src[1], case_label);
|
|
|
|
|
- vsir_src_param_init_label(&instructions[ins_count].src[2], fallthrough_label);
|
|
|
|
|
- ++ins_count;
|
|
|
|
|
+ }
|
|
|
|
|
+ src_param_init_ssa_bool(&dst_ins->src[0], ssa_count);
|
|
|
|
|
+ vsir_src_param_init_label(&dst_ins->src[1], case_label);
|
|
|
|
|
+ vsir_src_param_init_label(&dst_ins->src[2], fallthrough_label);
|
|
|
|
|
|
|
|
|
|
++ssa_count;
|
|
|
|
|
|
|
|
|
|
@@ -4655,29 +4664,28 @@ static enum vkd3d_result vsir_program_lower_switch_to_selection_ladder(struct vs
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
- if (!vsir_instruction_init_with_params(program,
|
|
|
|
|
- &instructions[ins_count], &ins->location, VSIR_OP_LABEL, 0, 1))
|
|
|
|
|
+ dst_ins = shader_instruction_array_append(&instructions);
|
|
|
|
|
+ if (!vsir_instruction_init_with_params(program, dst_ins, &ins->location, VSIR_OP_LABEL, 0, 1))
|
|
|
|
|
+ {
|
|
|
|
|
+ vkd3d_shader_instruction_make_nop(dst_ins);
|
|
|
|
|
goto fail;
|
|
|
|
|
- vsir_src_param_init_label(&instructions[ins_count].src[0], ++block_count);
|
|
|
|
|
- ++ins_count;
|
|
|
|
|
+ }
|
|
|
|
|
+ vsir_src_param_init_label(&dst_ins->src[0], ++block_count);
|
|
|
|
|
|
|
|
|
|
if_label = block_count;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- vkd3d_free(program->instructions.elements);
|
|
|
|
|
+ vsir_program_replace_instructions(program, &instructions);
|
|
|
|
|
vkd3d_free(block_map);
|
|
|
|
|
- program->instructions.elements = instructions;
|
|
|
|
|
- program->instructions.capacity = ins_capacity;
|
|
|
|
|
- program->instructions.count = ins_count;
|
|
|
|
|
program->block_count = block_count;
|
|
|
|
|
program->ssa_count = ssa_count;
|
|
|
|
|
|
|
|
|
|
return VKD3D_OK;
|
|
|
|
|
|
|
|
|
|
fail:
|
|
|
|
|
- vkd3d_free(instructions);
|
|
|
|
|
+ shader_instruction_array_destroy(&instructions);
|
|
|
|
|
vkd3d_free(block_map);
|
|
|
|
|
|
|
|
|
|
return VKD3D_ERROR_OUT_OF_MEMORY;
|
|
|
|
|
@@ -4748,11 +4756,11 @@ static enum vkd3d_result vsir_program_materialise_phi_ssas_to_temps(struct vsir_
|
|
|
|
|
struct vsir_transformation_context *ctx)
|
|
|
|
|
{
|
|
|
|
|
struct vsir_program_iterator it = vsir_program_iterator(&program->instructions);
|
|
|
|
|
- size_t ins_capacity = 0, ins_count = 0, phi_count, incoming_count;
|
|
|
|
|
struct ssas_to_temps_block_info *info, *block_info = NULL;
|
|
|
|
|
- struct vkd3d_shader_instruction *instructions = NULL;
|
|
|
|
|
+ struct vkd3d_shader_instruction_array instructions = {0};
|
|
|
|
|
+ struct vkd3d_shader_instruction *ins, *dst_ins;
|
|
|
|
|
struct ssas_to_temps_alloc alloc = {0};
|
|
|
|
|
- struct vkd3d_shader_instruction *ins;
|
|
|
|
|
+ size_t phi_count, incoming_count;
|
|
|
|
|
unsigned int current_label = 0;
|
|
|
|
|
|
|
|
|
|
VKD3D_ASSERT(program->cf_type == VSIR_CF_BLOCKS);
|
|
|
|
|
@@ -4809,7 +4817,7 @@ static enum vkd3d_result vsir_program_materialise_phi_ssas_to_temps(struct vsir_
|
|
|
|
|
if (!phi_count)
|
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
|
|
- if (!reserve_instructions(&instructions, &ins_capacity, program->instructions.count + incoming_count - phi_count))
|
|
|
|
|
+ if (!shader_instruction_array_reserve(&instructions, program->instructions.count + incoming_count - phi_count))
|
|
|
|
|
goto fail;
|
|
|
|
|
|
|
|
|
|
for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it))
|
|
|
|
|
@@ -4837,9 +4845,12 @@ static enum vkd3d_result vsir_program_materialise_phi_ssas_to_temps(struct vsir_
|
|
|
|
|
{
|
|
|
|
|
struct phi_incoming_to_temp *incoming = &info->incomings[j];
|
|
|
|
|
|
|
|
|
|
- mov_ins = &instructions[ins_count++];
|
|
|
|
|
+ mov_ins = shader_instruction_array_append(&instructions);
|
|
|
|
|
if (!vsir_instruction_init_with_params(program, mov_ins, &ins->location, VSIR_OP_MOV, 1, 0))
|
|
|
|
|
+ {
|
|
|
|
|
+ vkd3d_shader_instruction_make_nop(mov_ins);
|
|
|
|
|
goto fail;
|
|
|
|
|
+ }
|
|
|
|
|
*mov_ins->dst = *incoming->dst;
|
|
|
|
|
mov_ins->src = incoming->src;
|
|
|
|
|
mov_ins->src_count = 1;
|
|
|
|
|
@@ -4853,13 +4864,11 @@ static enum vkd3d_result vsir_program_materialise_phi_ssas_to_temps(struct vsir_
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- instructions[ins_count++] = *ins;
|
|
|
|
|
+ dst_ins = shader_instruction_array_append(&instructions);
|
|
|
|
|
+ *dst_ins = *ins;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- vkd3d_free(program->instructions.elements);
|
|
|
|
|
- program->instructions.elements = instructions;
|
|
|
|
|
- program->instructions.capacity = ins_capacity;
|
|
|
|
|
- program->instructions.count = ins_count;
|
|
|
|
|
+ vsir_program_replace_instructions(program, &instructions);
|
|
|
|
|
program->temp_count = alloc.next_temp_idx;
|
|
|
|
|
done:
|
|
|
|
|
ssas_to_temps_block_info_cleanup(block_info, program->block_count);
|
|
|
|
|
@@ -4868,7 +4877,7 @@ done:
|
|
|
|
|
return VKD3D_OK;
|
|
|
|
|
|
|
|
|
|
fail:
|
|
|
|
|
- vkd3d_free(instructions);
|
|
|
|
|
+ shader_instruction_array_destroy(&instructions);
|
|
|
|
|
ssas_to_temps_block_info_cleanup(block_info, program->block_count);
|
|
|
|
|
vkd3d_free(alloc.table);
|
|
|
|
|
|
|
|
|
|
@@ -4929,7 +4938,7 @@ struct vsir_block
|
|
|
|
|
* LABEL that introduces the block. `end' points to the terminator
|
|
|
|
|
* instruction (either BRANCH or RET). They can coincide, meaning
|
|
|
|
|
* that the block is empty. */
|
|
|
|
|
- struct vkd3d_shader_instruction *begin, *end;
|
|
|
|
|
+ struct vsir_program_iterator begin, end;
|
|
|
|
|
struct vsir_block_list predecessors, successors;
|
|
|
|
|
uint32_t *dominates;
|
|
|
|
|
};
|
|
|
|
|
@@ -5112,8 +5121,8 @@ static void vsir_cfg_structure_cleanup(struct vsir_cfg_structure *structure)
|
|
|
|
|
|
|
|
|
|
struct vsir_cfg_emit_target
|
|
|
|
|
{
|
|
|
|
|
- struct vkd3d_shader_instruction *instructions;
|
|
|
|
|
- size_t ins_capacity, ins_count;
|
|
|
|
|
+ struct vkd3d_shader_instruction_array instructions;
|
|
|
|
|
+
|
|
|
|
|
unsigned int jump_target_temp_idx;
|
|
|
|
|
unsigned int temp_count;
|
|
|
|
|
};
|
|
|
|
|
@@ -5248,19 +5257,21 @@ static void vsir_cfg_dump_dot(struct vsir_cfg *cfg)
|
|
|
|
|
for (i = 0; i < cfg->block_count; ++i)
|
|
|
|
|
{
|
|
|
|
|
struct vsir_block *block = &cfg->blocks[i];
|
|
|
|
|
+ struct vkd3d_shader_instruction *end;
|
|
|
|
|
const char *shape;
|
|
|
|
|
|
|
|
|
|
if (block->label == 0)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
- switch (block->end->opcode)
|
|
|
|
|
+ end = vsir_program_iterator_current(&block->end);
|
|
|
|
|
+ switch (end->opcode)
|
|
|
|
|
{
|
|
|
|
|
case VSIR_OP_RET:
|
|
|
|
|
shape = "trapezium";
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case VSIR_OP_BRANCH:
|
|
|
|
|
- shape = vsir_register_is_label(&block->end->src[0].reg) ? "ellipse" : "box";
|
|
|
|
|
+ shape = vsir_register_is_label(&end->src[0].reg) ? "ellipse" : "box";
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
@@ -5412,8 +5423,8 @@ static enum vkd3d_result vsir_cfg_init(struct vsir_cfg *cfg, struct vsir_program
|
|
|
|
|
VKD3D_ASSERT(current_block->label == 0);
|
|
|
|
|
if ((ret = vsir_block_init(current_block, label, program->block_count)) < 0)
|
|
|
|
|
goto fail;
|
|
|
|
|
- current_block->begin = vsir_program_iterator_next(it);
|
|
|
|
|
- vsir_program_iterator_prev(it);
|
|
|
|
|
+ current_block->begin = *it;
|
|
|
|
|
+ vsir_program_iterator_next(¤t_block->begin);
|
|
|
|
|
if (!cfg->entry)
|
|
|
|
|
cfg->entry = current_block;
|
|
|
|
|
break;
|
|
|
|
|
@@ -5422,7 +5433,7 @@ static enum vkd3d_result vsir_cfg_init(struct vsir_cfg *cfg, struct vsir_program
|
|
|
|
|
case VSIR_OP_BRANCH:
|
|
|
|
|
case VSIR_OP_RET:
|
|
|
|
|
VKD3D_ASSERT(current_block);
|
|
|
|
|
- current_block->end = ins;
|
|
|
|
|
+ current_block->end = *it;
|
|
|
|
|
current_block = NULL;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
@@ -5446,27 +5457,29 @@ static enum vkd3d_result vsir_cfg_init(struct vsir_cfg *cfg, struct vsir_program
|
|
|
|
|
for (i = 0; i < cfg->block_count; ++i)
|
|
|
|
|
{
|
|
|
|
|
struct vsir_block *block = &cfg->blocks[i];
|
|
|
|
|
+ struct vkd3d_shader_instruction *end;
|
|
|
|
|
|
|
|
|
|
if (block->label == 0)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
- switch (block->end->opcode)
|
|
|
|
|
+ end = vsir_program_iterator_current(&block->end);
|
|
|
|
|
+ switch (end->opcode)
|
|
|
|
|
{
|
|
|
|
|
case VSIR_OP_RET:
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case VSIR_OP_BRANCH:
|
|
|
|
|
- if (vsir_register_is_label(&block->end->src[0].reg))
|
|
|
|
|
+ if (vsir_register_is_label(&end->src[0].reg))
|
|
|
|
|
{
|
|
|
|
|
- if ((ret = vsir_cfg_add_edge(cfg, block, &block->end->src[0])) < 0)
|
|
|
|
|
+ if ((ret = vsir_cfg_add_edge(cfg, block, &end->src[0])) < 0)
|
|
|
|
|
goto fail;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
- if ((ret = vsir_cfg_add_edge(cfg, block, &block->end->src[1])) < 0)
|
|
|
|
|
+ if ((ret = vsir_cfg_add_edge(cfg, block, &end->src[1])) < 0)
|
|
|
|
|
goto fail;
|
|
|
|
|
|
|
|
|
|
- if ((ret = vsir_cfg_add_edge(cfg, block, &block->end->src[2])) < 0)
|
|
|
|
|
+ if ((ret = vsir_cfg_add_edge(cfg, block, &end->src[2])) < 0)
|
|
|
|
|
goto fail;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
@@ -5650,8 +5663,10 @@ static enum vkd3d_result vsir_cfg_compute_loops(struct vsir_cfg *cfg)
|
|
|
|
|
|
|
|
|
|
if (cfg->loops_by_header[header->label - 1] != SIZE_MAX)
|
|
|
|
|
{
|
|
|
|
|
+ struct vkd3d_shader_instruction *begin = vsir_program_iterator_current(&header->begin);
|
|
|
|
|
+
|
|
|
|
|
FIXME("Block %u is header to more than one loop, this is not implemented.\n", header->label);
|
|
|
|
|
- vkd3d_shader_error(cfg->message_context, &header->begin->location, VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED,
|
|
|
|
|
+ vkd3d_shader_error(cfg->message_context, &begin->location, VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED,
|
|
|
|
|
"Block %u is header to more than one loop, this is not implemented.", header->label);
|
|
|
|
|
return VKD3D_ERROR_NOT_IMPLEMENTED;
|
|
|
|
|
}
|
|
|
|
|
@@ -5733,8 +5748,10 @@ static enum vkd3d_result vsir_cfg_sort_nodes(struct vsir_cfg *cfg)
|
|
|
|
|
|
|
|
|
|
if (in_degrees[i] == 0 && block != cfg->entry)
|
|
|
|
|
{
|
|
|
|
|
+ struct vkd3d_shader_instruction *begin = vsir_program_iterator_current(&block->begin);
|
|
|
|
|
+
|
|
|
|
|
WARN("Unexpected entry point %u.\n", block->label);
|
|
|
|
|
- vkd3d_shader_error(cfg->message_context, &block->begin->location, VKD3D_SHADER_ERROR_VSIR_INVALID_CONTROL_FLOW,
|
|
|
|
|
+ vkd3d_shader_error(cfg->message_context, &begin->location, VKD3D_SHADER_ERROR_VSIR_INVALID_CONTROL_FLOW,
|
|
|
|
|
"Block %u is unreachable from the entry point.", block->label);
|
|
|
|
|
ret = VKD3D_ERROR_INVALID_SHADER;
|
|
|
|
|
goto fail;
|
|
|
|
|
@@ -5743,8 +5760,10 @@ static enum vkd3d_result vsir_cfg_sort_nodes(struct vsir_cfg *cfg)
|
|
|
|
|
|
|
|
|
|
if (in_degrees[cfg->entry->label - 1] != 0)
|
|
|
|
|
{
|
|
|
|
|
+ struct vkd3d_shader_instruction *begin = vsir_program_iterator_current(&cfg->entry->begin);
|
|
|
|
|
+
|
|
|
|
|
WARN("Entry point has %u incoming forward edges.\n", in_degrees[cfg->entry->label - 1]);
|
|
|
|
|
- vkd3d_shader_error(cfg->message_context, &cfg->entry->begin->location, VKD3D_SHADER_ERROR_VSIR_INVALID_CONTROL_FLOW,
|
|
|
|
|
+ vkd3d_shader_error(cfg->message_context, &begin->location, VKD3D_SHADER_ERROR_VSIR_INVALID_CONTROL_FLOW,
|
|
|
|
|
"The entry point block has %u incoming forward edges.", in_degrees[cfg->entry->label - 1]);
|
|
|
|
|
ret = VKD3D_ERROR_INVALID_SHADER;
|
|
|
|
|
goto fail;
|
|
|
|
|
@@ -5846,9 +5865,11 @@ static enum vkd3d_result vsir_cfg_sort_nodes(struct vsir_cfg *cfg)
|
|
|
|
|
|
|
|
|
|
if (cfg->order.count != cfg->block_count)
|
|
|
|
|
{
|
|
|
|
|
+ struct vkd3d_shader_instruction *begin = vsir_program_iterator_current(&cfg->entry->begin);
|
|
|
|
|
+
|
|
|
|
|
/* There is a cycle of forward edges. */
|
|
|
|
|
WARN("The control flow graph is not reducible.\n");
|
|
|
|
|
- vkd3d_shader_error(cfg->message_context, &cfg->entry->begin->location, VKD3D_SHADER_ERROR_VSIR_INVALID_CONTROL_FLOW,
|
|
|
|
|
+ vkd3d_shader_error(cfg->message_context, &begin->location, VKD3D_SHADER_ERROR_VSIR_INVALID_CONTROL_FLOW,
|
|
|
|
|
"The control flow graph is not reducible.");
|
|
|
|
|
ret = VKD3D_ERROR_INVALID_SHADER;
|
|
|
|
|
goto fail;
|
|
|
|
|
@@ -6107,6 +6128,7 @@ static enum vkd3d_result vsir_cfg_build_structured_program(struct vsir_cfg *cfg)
|
|
|
|
|
{
|
|
|
|
|
struct vsir_block *block = cfg->order.blocks[i];
|
|
|
|
|
struct vsir_cfg_structure *structure;
|
|
|
|
|
+ struct vkd3d_shader_instruction *end;
|
|
|
|
|
|
|
|
|
|
VKD3D_ASSERT(stack_depth > 0);
|
|
|
|
|
|
|
|
|
|
@@ -6132,16 +6154,17 @@ static enum vkd3d_result vsir_cfg_build_structured_program(struct vsir_cfg *cfg)
|
|
|
|
|
structure->u.block = block;
|
|
|
|
|
|
|
|
|
|
/* Generate between zero and two jump instructions. */
|
|
|
|
|
- switch (block->end->opcode)
|
|
|
|
|
+ end = vsir_program_iterator_current(&block->end);
|
|
|
|
|
+ switch (end->opcode)
|
|
|
|
|
{
|
|
|
|
|
case VSIR_OP_BRANCH:
|
|
|
|
|
{
|
|
|
|
|
struct vsir_cfg_edge_action action_true, action_false;
|
|
|
|
|
bool invert_condition = false;
|
|
|
|
|
|
|
|
|
|
- if (vsir_register_is_label(&block->end->src[0].reg))
|
|
|
|
|
+ if (vsir_register_is_label(&end->src[0].reg))
|
|
|
|
|
{
|
|
|
|
|
- unsigned int target = label_from_src_param(&block->end->src[0]);
|
|
|
|
|
+ unsigned int target = label_from_src_param(&end->src[0]);
|
|
|
|
|
struct vsir_block *successor = &cfg->blocks[target - 1];
|
|
|
|
|
|
|
|
|
|
vsir_cfg_compute_edge_action(cfg, block, successor, &action_true);
|
|
|
|
|
@@ -6149,12 +6172,12 @@ static enum vkd3d_result vsir_cfg_build_structured_program(struct vsir_cfg *cfg)
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
- unsigned int target = label_from_src_param(&block->end->src[1]);
|
|
|
|
|
+ unsigned int target = label_from_src_param(&end->src[1]);
|
|
|
|
|
struct vsir_block *successor = &cfg->blocks[target - 1];
|
|
|
|
|
|
|
|
|
|
vsir_cfg_compute_edge_action(cfg, block, successor, &action_true);
|
|
|
|
|
|
|
|
|
|
- target = label_from_src_param(&block->end->src[2]);
|
|
|
|
|
+ target = label_from_src_param(&end->src[2]);
|
|
|
|
|
successor = &cfg->blocks[target - 1];
|
|
|
|
|
|
|
|
|
|
vsir_cfg_compute_edge_action(cfg, block, successor, &action_false);
|
|
|
|
|
@@ -6206,7 +6229,7 @@ static enum vkd3d_result vsir_cfg_build_structured_program(struct vsir_cfg *cfg)
|
|
|
|
|
goto fail;
|
|
|
|
|
structure->u.jump.type = action_true.jump_type;
|
|
|
|
|
structure->u.jump.target = action_true.target;
|
|
|
|
|
- structure->u.jump.condition = &block->end->src[0];
|
|
|
|
|
+ structure->u.jump.condition = &vsir_program_iterator_current(&block->end)->src[0];
|
|
|
|
|
structure->u.jump.invert_condition = invert_condition;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -6691,15 +6714,28 @@ static enum vkd3d_result vsir_cfg_structure_list_emit_block(struct vsir_cfg *cfg
|
|
|
|
|
struct vsir_block *block)
|
|
|
|
|
{
|
|
|
|
|
struct vsir_cfg_emit_target *target = cfg->target;
|
|
|
|
|
+ struct vkd3d_shader_instruction *ins, *end, *dst;
|
|
|
|
|
+ struct vsir_program_iterator it;
|
|
|
|
|
+ size_t ins_count = 0;
|
|
|
|
|
|
|
|
|
|
- if (!reserve_instructions(&target->instructions, &target->ins_capacity,
|
|
|
|
|
- target->ins_count + (block->end - block->begin)))
|
|
|
|
|
- return VKD3D_ERROR_OUT_OF_MEMORY;
|
|
|
|
|
+ it = block->begin;
|
|
|
|
|
+ end = vsir_program_iterator_current(&block->end);
|
|
|
|
|
+
|
|
|
|
|
+ for (ins = vsir_program_iterator_current(&it); ins != end; ins = vsir_program_iterator_next(&it))
|
|
|
|
|
+ {
|
|
|
|
|
+ ++ins_count;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
|
|
- memcpy(&target->instructions[target->ins_count], block->begin,
|
|
|
|
|
- (char *)block->end - (char *)block->begin);
|
|
|
|
|
+ if (!shader_instruction_array_reserve(&target->instructions, target->instructions.count + ins_count))
|
|
|
|
|
+ return VKD3D_ERROR_OUT_OF_MEMORY;
|
|
|
|
|
|
|
|
|
|
- target->ins_count += block->end - block->begin;
|
|
|
|
|
+ it = block->begin;
|
|
|
|
|
+ for (ins = vsir_program_iterator_current(&it); ins != end; ins = vsir_program_iterator_next(&it))
|
|
|
|
|
+ {
|
|
|
|
|
+ dst = shader_instruction_array_append(&target->instructions);
|
|
|
|
|
+ VKD3D_ASSERT(dst);
|
|
|
|
|
+ *dst = *ins;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
|
|
return VKD3D_OK;
|
|
|
|
|
}
|
|
|
|
|
@@ -6709,20 +6745,22 @@ static enum vkd3d_result vsir_cfg_structure_list_emit_loop(struct vsir_cfg *cfg,
|
|
|
|
|
{
|
|
|
|
|
struct vsir_cfg_emit_target *target = cfg->target;
|
|
|
|
|
const struct vkd3d_shader_location no_loc = {0};
|
|
|
|
|
+ struct vkd3d_shader_instruction *ins;
|
|
|
|
|
enum vkd3d_result ret;
|
|
|
|
|
|
|
|
|
|
- if (!reserve_instructions(&target->instructions, &target->ins_capacity, target->ins_count + 1))
|
|
|
|
|
+ if (!(ins = shader_instruction_array_append(&target->instructions)))
|
|
|
|
|
return VKD3D_ERROR_OUT_OF_MEMORY;
|
|
|
|
|
|
|
|
|
|
- vsir_instruction_init(&target->instructions[target->ins_count++], &no_loc, VSIR_OP_LOOP);
|
|
|
|
|
+ vsir_instruction_init(ins, &no_loc, VSIR_OP_LOOP);
|
|
|
|
|
|
|
|
|
|
if ((ret = vsir_cfg_structure_list_emit(cfg, &loop->body, loop->idx)) < 0)
|
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
|
|
- if (!reserve_instructions(&target->instructions, &target->ins_capacity, target->ins_count + 5))
|
|
|
|
|
+ if (!shader_instruction_array_reserve(&target->instructions, target->instructions.count + 5))
|
|
|
|
|
return VKD3D_ERROR_OUT_OF_MEMORY;
|
|
|
|
|
|
|
|
|
|
- vsir_instruction_init(&target->instructions[target->ins_count++], &no_loc, VSIR_OP_ENDLOOP);
|
|
|
|
|
+ ins = shader_instruction_array_append(&target->instructions);
|
|
|
|
|
+ vsir_instruction_init(ins, &no_loc, VSIR_OP_ENDLOOP);
|
|
|
|
|
|
|
|
|
|
/* Add a trampoline to implement multilevel jumping depending on the stored
|
|
|
|
|
* jump_target value. */
|
|
|
|
|
@@ -6736,44 +6774,50 @@ static enum vkd3d_result vsir_cfg_structure_list_emit_loop(struct vsir_cfg *cfg,
|
|
|
|
|
* we have to reach an outer loop, so we keep breaking. */
|
|
|
|
|
const unsigned int inner_break_target = loop->idx << 1;
|
|
|
|
|
|
|
|
|
|
- if (!vsir_instruction_init_with_params(cfg->program, &target->instructions[target->ins_count],
|
|
|
|
|
- &no_loc, VSIR_OP_IEQ, 1, 2))
|
|
|
|
|
+ ins = shader_instruction_array_append(&target->instructions);
|
|
|
|
|
+ if (!vsir_instruction_init_with_params(cfg->program, ins, &no_loc, VSIR_OP_IEQ, 1, 2))
|
|
|
|
|
+ {
|
|
|
|
|
+ vkd3d_shader_instruction_make_nop(ins);
|
|
|
|
|
return VKD3D_ERROR_OUT_OF_MEMORY;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
|
|
- dst_param_init_temp_bool(&target->instructions[target->ins_count].dst[0], target->temp_count);
|
|
|
|
|
- src_param_init_temp_uint(&target->instructions[target->ins_count].src[0], target->jump_target_temp_idx);
|
|
|
|
|
- src_param_init_const_uint(&target->instructions[target->ins_count].src[1], outer_continue_target);
|
|
|
|
|
+ ++target->temp_count;
|
|
|
|
|
|
|
|
|
|
- ++target->ins_count;
|
|
|
|
|
+ dst_param_init_temp_bool(&ins->dst[0], target->temp_count - 1);
|
|
|
|
|
+ src_param_init_temp_uint(&ins->src[0], target->jump_target_temp_idx);
|
|
|
|
|
+ src_param_init_const_uint(&ins->src[1], outer_continue_target);
|
|
|
|
|
|
|
|
|
|
- if (!vsir_instruction_init_with_params(cfg->program, &target->instructions[target->ins_count],
|
|
|
|
|
- &no_loc, VSIR_OP_CONTINUEP, 0, 1))
|
|
|
|
|
+ ins = shader_instruction_array_append(&target->instructions);
|
|
|
|
|
+ if (!vsir_instruction_init_with_params(cfg->program, ins, &no_loc, VSIR_OP_CONTINUEP, 0, 1))
|
|
|
|
|
+ {
|
|
|
|
|
+ vkd3d_shader_instruction_make_nop(ins);
|
|
|
|
|
return VKD3D_ERROR_OUT_OF_MEMORY;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
|
|
- src_param_init_temp_bool(&target->instructions[target->ins_count].src[0], target->temp_count);
|
|
|
|
|
-
|
|
|
|
|
- ++target->ins_count;
|
|
|
|
|
- ++target->temp_count;
|
|
|
|
|
+ src_param_init_temp_bool(&ins->src[0], target->temp_count - 1);
|
|
|
|
|
|
|
|
|
|
- if (!vsir_instruction_init_with_params(cfg->program, &target->instructions[target->ins_count],
|
|
|
|
|
- &no_loc, VSIR_OP_IEQ, 1, 2))
|
|
|
|
|
+ ins = shader_instruction_array_append(&target->instructions);
|
|
|
|
|
+ if (!vsir_instruction_init_with_params(cfg->program, ins, &no_loc, VSIR_OP_IEQ, 1, 2))
|
|
|
|
|
+ {
|
|
|
|
|
+ vkd3d_shader_instruction_make_nop(ins);
|
|
|
|
|
return VKD3D_ERROR_OUT_OF_MEMORY;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
|
|
- dst_param_init_temp_bool(&target->instructions[target->ins_count].dst[0], target->temp_count);
|
|
|
|
|
- src_param_init_temp_uint(&target->instructions[target->ins_count].src[0], target->jump_target_temp_idx);
|
|
|
|
|
- src_param_init_const_uint(&target->instructions[target->ins_count].src[1], inner_break_target);
|
|
|
|
|
+ ++target->temp_count;
|
|
|
|
|
|
|
|
|
|
- ++target->ins_count;
|
|
|
|
|
+ dst_param_init_temp_bool(&ins->dst[0], target->temp_count - 1);
|
|
|
|
|
+ src_param_init_temp_uint(&ins->src[0], target->jump_target_temp_idx);
|
|
|
|
|
+ src_param_init_const_uint(&ins->src[1], inner_break_target);
|
|
|
|
|
|
|
|
|
|
- if (!vsir_instruction_init_with_params(cfg->program, &target->instructions[target->ins_count],
|
|
|
|
|
- &no_loc, VSIR_OP_BREAKP, 0, 1))
|
|
|
|
|
+ ins = shader_instruction_array_append(&target->instructions);
|
|
|
|
|
+ if (!vsir_instruction_init_with_params(cfg->program, ins, &no_loc, VSIR_OP_BREAKP, 0, 1))
|
|
|
|
|
+ {
|
|
|
|
|
+ vkd3d_shader_instruction_make_nop(ins);
|
|
|
|
|
return VKD3D_ERROR_OUT_OF_MEMORY;
|
|
|
|
|
- target->instructions[target->ins_count].flags |= VKD3D_SHADER_CONDITIONAL_OP_Z;
|
|
|
|
|
-
|
|
|
|
|
- src_param_init_temp_bool(&target->instructions[target->ins_count].src[0], target->temp_count);
|
|
|
|
|
+ }
|
|
|
|
|
+ ins->flags |= VKD3D_SHADER_CONDITIONAL_OP_Z;
|
|
|
|
|
|
|
|
|
|
- ++target->ins_count;
|
|
|
|
|
- ++target->temp_count;
|
|
|
|
|
+ src_param_init_temp_bool(&ins->src[0], target->temp_count - 1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return VKD3D_OK;
|
|
|
|
|
@@ -6784,40 +6828,40 @@ static enum vkd3d_result vsir_cfg_structure_list_emit_selection(struct vsir_cfg
|
|
|
|
|
{
|
|
|
|
|
struct vsir_cfg_emit_target *target = cfg->target;
|
|
|
|
|
const struct vkd3d_shader_location no_loc = {0};
|
|
|
|
|
+ struct vkd3d_shader_instruction *ins;
|
|
|
|
|
enum vkd3d_result ret;
|
|
|
|
|
|
|
|
|
|
- if (!reserve_instructions(&target->instructions, &target->ins_capacity, target->ins_count + 1))
|
|
|
|
|
+ if (!(ins = shader_instruction_array_append(&target->instructions)))
|
|
|
|
|
return VKD3D_ERROR_OUT_OF_MEMORY;
|
|
|
|
|
|
|
|
|
|
- if (!vsir_instruction_init_with_params(cfg->program, &target->instructions[target->ins_count],
|
|
|
|
|
- &no_loc, VSIR_OP_IF, 0, 1))
|
|
|
|
|
+ if (!vsir_instruction_init_with_params(cfg->program, ins, &no_loc, VSIR_OP_IF, 0, 1))
|
|
|
|
|
+ {
|
|
|
|
|
+ vkd3d_shader_instruction_make_nop(ins);
|
|
|
|
|
return VKD3D_ERROR_OUT_OF_MEMORY;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
|
|
- target->instructions[target->ins_count].src[0] = *selection->condition;
|
|
|
|
|
+ ins->src[0] = *selection->condition;
|
|
|
|
|
|
|
|
|
|
if (selection->invert_condition)
|
|
|
|
|
- target->instructions[target->ins_count].flags |= VKD3D_SHADER_CONDITIONAL_OP_Z;
|
|
|
|
|
-
|
|
|
|
|
- ++target->ins_count;
|
|
|
|
|
+ ins->flags |= VKD3D_SHADER_CONDITIONAL_OP_Z;
|
|
|
|
|
|
|
|
|
|
if ((ret = vsir_cfg_structure_list_emit(cfg, &selection->if_body, loop_idx)) < 0)
|
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
|
|
if (selection->else_body.count != 0)
|
|
|
|
|
{
|
|
|
|
|
- if (!reserve_instructions(&target->instructions, &target->ins_capacity, target->ins_count + 1))
|
|
|
|
|
+ if (!(ins = shader_instruction_array_append(&target->instructions)))
|
|
|
|
|
return VKD3D_ERROR_OUT_OF_MEMORY;
|
|
|
|
|
|
|
|
|
|
- vsir_instruction_init(&target->instructions[target->ins_count++], &no_loc, VSIR_OP_ELSE);
|
|
|
|
|
+ vsir_instruction_init(ins, &no_loc, VSIR_OP_ELSE);
|
|
|
|
|
|
|
|
|
|
if ((ret = vsir_cfg_structure_list_emit(cfg, &selection->else_body, loop_idx)) < 0)
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- if (!reserve_instructions(&target->instructions, &target->ins_capacity, target->ins_count + 1))
|
|
|
|
|
+ if (!(ins = shader_instruction_array_append(&target->instructions)))
|
|
|
|
|
return VKD3D_ERROR_OUT_OF_MEMORY;
|
|
|
|
|
-
|
|
|
|
|
- vsir_instruction_init(&target->instructions[target->ins_count++], &no_loc, VSIR_OP_ENDIF);
|
|
|
|
|
+ vsir_instruction_init(ins, &no_loc, VSIR_OP_ENDIF);
|
|
|
|
|
|
|
|
|
|
return VKD3D_OK;
|
|
|
|
|
}
|
|
|
|
|
@@ -6830,6 +6874,7 @@ static enum vkd3d_result vsir_cfg_structure_list_emit_jump(struct vsir_cfg *cfg,
|
|
|
|
|
/* Encode the jump target as the loop index plus a bit to remember whether
|
|
|
|
|
* we're breaking or continue-ing. */
|
|
|
|
|
unsigned int jump_target = jump->target << 1;
|
|
|
|
|
+ struct vkd3d_shader_instruction *ins;
|
|
|
|
|
enum vkd3d_shader_opcode opcode;
|
|
|
|
|
|
|
|
|
|
switch (jump->type)
|
|
|
|
|
@@ -6860,32 +6905,34 @@ static enum vkd3d_result vsir_cfg_structure_list_emit_jump(struct vsir_cfg *cfg,
|
|
|
|
|
vkd3d_unreachable();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- if (!reserve_instructions(&target->instructions, &target->ins_capacity, target->ins_count + 2))
|
|
|
|
|
+ if (!shader_instruction_array_reserve(&target->instructions, target->instructions.count + 2))
|
|
|
|
|
return VKD3D_ERROR_OUT_OF_MEMORY;
|
|
|
|
|
|
|
|
|
|
if (jump->needs_launcher)
|
|
|
|
|
{
|
|
|
|
|
- if (!vsir_instruction_init_with_params(cfg->program, &target->instructions[target->ins_count],
|
|
|
|
|
- &no_loc, VSIR_OP_MOV, 1, 1))
|
|
|
|
|
+ ins = shader_instruction_array_append(&target->instructions);
|
|
|
|
|
+ if (!vsir_instruction_init_with_params(cfg->program, ins, &no_loc, VSIR_OP_MOV, 1, 1))
|
|
|
|
|
+ {
|
|
|
|
|
+ vkd3d_shader_instruction_make_nop(ins);
|
|
|
|
|
return VKD3D_ERROR_OUT_OF_MEMORY;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
|
|
- dst_param_init_temp_uint(&target->instructions[target->ins_count].dst[0], target->jump_target_temp_idx);
|
|
|
|
|
- src_param_init_const_uint(&target->instructions[target->ins_count].src[0], jump_target);
|
|
|
|
|
-
|
|
|
|
|
- ++target->ins_count;
|
|
|
|
|
+ dst_param_init_temp_uint(&ins->dst[0], target->jump_target_temp_idx);
|
|
|
|
|
+ src_param_init_const_uint(&ins->src[0], jump_target);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- if (!vsir_instruction_init_with_params(cfg->program, &target->instructions[target->ins_count],
|
|
|
|
|
- &no_loc, opcode, 0, !!jump->condition))
|
|
|
|
|
+ ins = shader_instruction_array_append(&target->instructions);
|
|
|
|
|
+ if (!vsir_instruction_init_with_params(cfg->program, ins, &no_loc, opcode, 0, !!jump->condition))
|
|
|
|
|
+ {
|
|
|
|
|
+ vkd3d_shader_instruction_make_nop(ins);
|
|
|
|
|
return VKD3D_ERROR_OUT_OF_MEMORY;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
|
|
if (jump->invert_condition)
|
|
|
|
|
- target->instructions[target->ins_count].flags |= VKD3D_SHADER_CONDITIONAL_OP_Z;
|
|
|
|
|
+ ins->flags |= VKD3D_SHADER_CONDITIONAL_OP_Z;
|
|
|
|
|
|
|
|
|
|
if (jump->condition)
|
|
|
|
|
- target->instructions[target->ins_count].src[0] = *jump->condition;
|
|
|
|
|
-
|
|
|
|
|
- ++target->ins_count;
|
|
|
|
|
+ ins->src[0] = *jump->condition;
|
|
|
|
|
|
|
|
|
|
return VKD3D_OK;
|
|
|
|
|
}
|
|
|
|
|
@@ -6977,8 +7024,8 @@ static enum vkd3d_result vsir_program_structurize(struct vsir_program *program,
|
|
|
|
|
{
|
|
|
|
|
struct vsir_program_iterator it = vsir_program_iterator(&program->instructions);
|
|
|
|
|
struct vkd3d_shader_message_context *message_context = ctx->message_context;
|
|
|
|
|
+ struct vkd3d_shader_instruction *ins, *dst;
|
|
|
|
|
struct vsir_cfg_emit_target target = {0};
|
|
|
|
|
- struct vkd3d_shader_instruction *ins;
|
|
|
|
|
enum vkd3d_result ret;
|
|
|
|
|
|
|
|
|
|
VKD3D_ASSERT(program->cf_type == VSIR_CF_BLOCKS);
|
|
|
|
|
@@ -6986,7 +7033,7 @@ static enum vkd3d_result vsir_program_structurize(struct vsir_program *program,
|
|
|
|
|
target.jump_target_temp_idx = program->temp_count;
|
|
|
|
|
target.temp_count = program->temp_count + 1;
|
|
|
|
|
|
|
|
|
|
- if (!reserve_instructions(&target.instructions, &target.ins_capacity, program->instructions.count))
|
|
|
|
|
+ if (!shader_instruction_array_reserve(&target.instructions, target.instructions.count))
|
|
|
|
|
return VKD3D_ERROR_OUT_OF_MEMORY;
|
|
|
|
|
|
|
|
|
|
for (ins = vsir_program_iterator_head(&it); ins;)
|
|
|
|
|
@@ -7007,7 +7054,10 @@ static enum vkd3d_result vsir_program_structurize(struct vsir_program *program,
|
|
|
|
|
case VSIR_OP_HS_JOIN_PHASE:
|
|
|
|
|
VKD3D_ASSERT(program->shader_version.type == VKD3D_SHADER_TYPE_HULL);
|
|
|
|
|
TRACE("Structurizing phase %u of a hull shader.\n", ins->opcode);
|
|
|
|
|
- target.instructions[target.ins_count++] = *ins;
|
|
|
|
|
+
|
|
|
|
|
+ dst = shader_instruction_array_append(&target.instructions);
|
|
|
|
|
+ *dst = *ins;
|
|
|
|
|
+
|
|
|
|
|
vsir_program_iterator_next(&it);
|
|
|
|
|
if ((ret = vsir_program_structurize_function(program, message_context, &target, &it)) < 0)
|
|
|
|
|
goto fail;
|
|
|
|
|
@@ -7015,25 +7065,22 @@ static enum vkd3d_result vsir_program_structurize(struct vsir_program *program,
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
- if (!reserve_instructions(&target.instructions, &target.ins_capacity, target.ins_count + 1))
|
|
|
|
|
+ if (!(dst = shader_instruction_array_append(&target.instructions)))
|
|
|
|
|
return VKD3D_ERROR_OUT_OF_MEMORY;
|
|
|
|
|
- target.instructions[target.ins_count++] = *ins;
|
|
|
|
|
+ *dst = *ins;
|
|
|
|
|
ins = vsir_program_iterator_next(&it);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- vkd3d_free(program->instructions.elements);
|
|
|
|
|
- program->instructions.elements = target.instructions;
|
|
|
|
|
- program->instructions.capacity = target.ins_capacity;
|
|
|
|
|
- program->instructions.count = target.ins_count;
|
|
|
|
|
+ vsir_program_replace_instructions(program, &target.instructions);
|
|
|
|
|
program->temp_count = target.temp_count;
|
|
|
|
|
program->cf_type = VSIR_CF_STRUCTURED;
|
|
|
|
|
|
|
|
|
|
return VKD3D_OK;
|
|
|
|
|
|
|
|
|
|
fail:
|
|
|
|
|
- vkd3d_free(target.instructions);
|
|
|
|
|
+ shader_instruction_array_destroy(&target.instructions);
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
@@ -7088,7 +7135,9 @@ static enum vkd3d_result vsir_cfg_materialize_undominated_ssas_to_temps(struct v
|
|
|
|
|
if (block->label == 0)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
- for (ins = block->begin; ins <= block->end; ++ins)
|
|
|
|
|
+ it = block->begin;
|
|
|
|
|
+ end = vsir_program_iterator_current(&block->end);
|
|
|
|
|
+ for (ins = vsir_program_iterator_current(&it); ins != end; ins = vsir_program_iterator_next(&it))
|
|
|
|
|
{
|
|
|
|
|
for (j = 0; j < ins->dst_count; ++j)
|
|
|
|
|
{
|
|
|
|
|
@@ -7105,7 +7154,9 @@ static enum vkd3d_result vsir_cfg_materialize_undominated_ssas_to_temps(struct v
|
|
|
|
|
if (block->label == 0)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
- for (ins = block->begin; ins <= block->end; ++ins)
|
|
|
|
|
+ it = block->begin;
|
|
|
|
|
+ end = vsir_program_iterator_current(&block->end);
|
|
|
|
|
+ for (ins = vsir_program_iterator_current(&it); ins != end; ins = vsir_program_iterator_next(&it))
|
|
|
|
|
{
|
|
|
|
|
for (j = 0; j < ins->src_count; ++j)
|
|
|
|
|
register_map_undominated_use(&ins->src[j].reg, &alloc, block, origin_blocks);
|
|
|
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/msl.c b/libs/vkd3d/libs/vkd3d-shader/msl.c
|
|
|
|
|
index 2005e842201..2acb31ed6d6 100644
|
|
|
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/msl.c
|
|
|
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/msl.c
|
|
|
|
|
@@ -1472,6 +1472,9 @@ static void msl_handle_instruction(struct msl_generator *gen, const struct vkd3d
|
|
|
|
|
case VSIR_OP_CONTINUE:
|
|
|
|
|
msl_continue(gen);
|
|
|
|
|
break;
|
|
|
|
|
+ case VSIR_OP_COS:
|
|
|
|
|
+ msl_intrinsic(gen, ins, "cos");
|
|
|
|
|
+ break;
|
|
|
|
|
case VSIR_OP_DCL_INDEXABLE_TEMP:
|
|
|
|
|
msl_dcl_indexable_temp(gen, ins);
|
|
|
|
|
break;
|
|
|
|
|
@@ -1549,6 +1552,12 @@ static void msl_handle_instruction(struct msl_generator *gen, const struct vkd3d
|
|
|
|
|
case VSIR_OP_UGE:
|
|
|
|
|
msl_relop(gen, ins, ">=");
|
|
|
|
|
break;
|
|
|
|
|
+ case VSIR_OP_HCOS:
|
|
|
|
|
+ msl_intrinsic(gen, ins, "cosh");
|
|
|
|
|
+ break;
|
|
|
|
|
+ case VSIR_OP_HSIN:
|
|
|
|
|
+ msl_intrinsic(gen, ins, "sinh");
|
|
|
|
|
+ break;
|
|
|
|
|
case VSIR_OP_IF:
|
|
|
|
|
msl_if(gen, ins);
|
|
|
|
|
break;
|
|
|
|
|
@@ -1633,6 +1642,9 @@ static void msl_handle_instruction(struct msl_generator *gen, const struct vkd3d
|
|
|
|
|
case VSIR_OP_RSQ:
|
|
|
|
|
msl_intrinsic(gen, ins, "rsqrt");
|
|
|
|
|
break;
|
|
|
|
|
+ case VSIR_OP_SIN:
|
|
|
|
|
+ msl_intrinsic(gen, ins, "sin");
|
|
|
|
|
+ break;
|
|
|
|
|
case VSIR_OP_SQRT:
|
|
|
|
|
msl_intrinsic(gen, ins, "sqrt");
|
|
|
|
|
break;
|
|
|
|
|
@@ -1642,6 +1654,9 @@ static void msl_handle_instruction(struct msl_generator *gen, const struct vkd3d
|
|
|
|
|
case VSIR_OP_SWITCH:
|
|
|
|
|
msl_switch(gen, ins);
|
|
|
|
|
break;
|
|
|
|
|
+ case VSIR_OP_TAN:
|
|
|
|
|
+ msl_intrinsic(gen, ins, "tan");
|
|
|
|
|
+ break;
|
|
|
|
|
case VSIR_OP_XOR:
|
|
|
|
|
msl_binop(gen, ins, "^");
|
|
|
|
|
break;
|
|
|
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/spirv.c b/libs/vkd3d/libs/vkd3d-shader/spirv.c
|
|
|
|
|
index 434be05e786..41ab6114ffc 100644
|
|
|
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/spirv.c
|
|
|
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/spirv.c
|
|
|
|
|
@@ -9529,7 +9529,7 @@ static void spirv_compiler_emit_store_tgsm(struct spirv_compiler *compiler,
|
|
|
|
|
if (!spirv_compiler_get_register_info(compiler, &dst->reg, ®_info))
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
- type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_UINT, 1);
|
|
|
|
|
+ type_id = spirv_get_type_id(builder, VSIR_DATA_U32, 1);
|
|
|
|
|
ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, reg_info.storage_class, type_id);
|
|
|
|
|
base_coordinate_id = spirv_compiler_emit_raw_structured_addressing(compiler,
|
|
|
|
|
type_id, reg_info.structure_stride, &src[0], VKD3DSP_WRITEMASK_0, &src[1], VKD3DSP_WRITEMASK_0);
|
|
|
|
|
@@ -9675,7 +9675,7 @@ static void spirv_compiler_emit_uav_counter_instruction(struct spirv_compiler *c
|
|
|
|
|
counter_id = resource_symbol->info.resource.uav_counter_id;
|
|
|
|
|
VKD3D_ASSERT(counter_id);
|
|
|
|
|
|
|
|
|
|
- type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_UINT, 1);
|
|
|
|
|
+ type_id = spirv_get_type_id(builder, VSIR_DATA_U32, 1);
|
|
|
|
|
|
|
|
|
|
if (resource_symbol->info.resource.uav_counter_array)
|
|
|
|
|
{
|
|
|
|
|
@@ -9924,7 +9924,7 @@ static void spirv_compiler_emit_bufinfo(struct spirv_compiler *compiler,
|
|
|
|
|
{
|
|
|
|
|
resource_symbol = spirv_compiler_find_resource(compiler, &src->reg);
|
|
|
|
|
|
|
|
|
|
- type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_UINT, 1);
|
|
|
|
|
+ type_id = spirv_get_type_id(builder, VSIR_DATA_U32, 1);
|
|
|
|
|
val_id = vkd3d_spirv_build_op_array_length(builder, type_id, resource_symbol->id, 0);
|
|
|
|
|
write_mask = VKD3DSP_WRITEMASK_0;
|
|
|
|
|
}
|
|
|
|
|
@@ -9934,7 +9934,7 @@ static void spirv_compiler_emit_bufinfo(struct spirv_compiler *compiler,
|
|
|
|
|
|
|
|
|
|
spirv_compiler_prepare_image(compiler, &image, &src->reg, NULL, VKD3D_IMAGE_FLAG_NONE);
|
|
|
|
|
|
|
|
|
|
- type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_UINT, 1);
|
|
|
|
|
+ type_id = spirv_get_type_id(builder, VSIR_DATA_U32, 1);
|
|
|
|
|
val_id = vkd3d_spirv_build_op_image_query_size(builder, type_id, image.image_id);
|
|
|
|
|
write_mask = VKD3DSP_WRITEMASK_0;
|
|
|
|
|
}
|
|
|
|
|
@@ -9944,7 +9944,7 @@ static void spirv_compiler_emit_bufinfo(struct spirv_compiler *compiler,
|
|
|
|
|
stride_id = spirv_compiler_get_constant_uint(compiler, image.structure_stride);
|
|
|
|
|
constituents[0] = vkd3d_spirv_build_op_udiv(builder, type_id, val_id, stride_id);
|
|
|
|
|
constituents[1] = stride_id;
|
|
|
|
|
- type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_UINT, ARRAY_SIZE(constituents));
|
|
|
|
|
+ type_id = spirv_get_type_id(builder, VSIR_DATA_U32, ARRAY_SIZE(constituents));
|
|
|
|
|
val_id = vkd3d_spirv_build_op_composite_construct(builder,
|
|
|
|
|
type_id, constituents, ARRAY_SIZE(constituents));
|
|
|
|
|
write_mask |= VKD3DSP_WRITEMASK_1;
|
|
|
|
|
@@ -9983,14 +9983,14 @@ static void spirv_compiler_emit_resinfo(struct spirv_compiler *compiler,
|
|
|
|
|
size_component_count = image.resource_type_info->coordinate_component_count;
|
|
|
|
|
if (image.resource_type_info->dim == SpvDimCube)
|
|
|
|
|
--size_component_count;
|
|
|
|
|
- type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_UINT, size_component_count);
|
|
|
|
|
+ type_id = spirv_get_type_id(builder, VSIR_DATA_U32, size_component_count);
|
|
|
|
|
|
|
|
|
|
supports_mipmaps = src[1].reg.type != VKD3DSPR_UAV && !image.resource_type_info->ms;
|
|
|
|
|
if (supports_mipmaps)
|
|
|
|
|
{
|
|
|
|
|
lod_id = spirv_compiler_emit_load_src(compiler, &src[0], VKD3DSP_WRITEMASK_0);
|
|
|
|
|
val_id = vkd3d_spirv_build_op_image_query_size_lod(builder, type_id, image.image_id, lod_id);
|
|
|
|
|
- type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_UINT, 1);
|
|
|
|
|
+ type_id = spirv_get_type_id(builder, VSIR_DATA_U32, 1);
|
|
|
|
|
miplevel_count_id = vkd3d_spirv_build_op_image_query_levels(builder, type_id, image.image_id);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
@@ -10004,14 +10004,13 @@ static void spirv_compiler_emit_resinfo(struct spirv_compiler *compiler,
|
|
|
|
|
for (i = 0; i < 3 - size_component_count; ++i)
|
|
|
|
|
constituents[i + 1] = spirv_compiler_get_constant_uint(compiler, 0);
|
|
|
|
|
constituents[i + 1] = miplevel_count_id;
|
|
|
|
|
- type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_UINT, VKD3D_VEC4_SIZE);
|
|
|
|
|
- val_id = vkd3d_spirv_build_op_composite_construct(builder,
|
|
|
|
|
- type_id, constituents, i + 2);
|
|
|
|
|
+ type_id = spirv_get_type_id(builder, VSIR_DATA_U32, VKD3D_VEC4_SIZE);
|
|
|
|
|
+ val_id = vkd3d_spirv_build_op_composite_construct(builder, type_id, constituents, i + 2);
|
|
|
|
|
|
|
|
|
|
if (!(instruction->flags & VKD3DSI_RESINFO_UINT))
|
|
|
|
|
{
|
|
|
|
|
component_type = VKD3D_SHADER_COMPONENT_FLOAT;
|
|
|
|
|
- type_id = spirv_get_type_id_for_component_type(builder, component_type, VKD3D_VEC4_SIZE);
|
|
|
|
|
+ type_id = spirv_get_type_id(builder, VSIR_DATA_F32, VKD3D_VEC4_SIZE);
|
|
|
|
|
val_id = vkd3d_spirv_build_op_convert_utof(builder, type_id, val_id);
|
|
|
|
|
if (instruction->flags & VKD3DSI_PRECISE_XYZW)
|
|
|
|
|
vkd3d_spirv_build_op_decorate(builder, val_id, SpvDecorationNoContraction, NULL, 0);
|
|
|
|
|
@@ -10039,7 +10038,7 @@ static uint32_t spirv_compiler_emit_query_sample_count(struct spirv_compiler *co
|
|
|
|
|
vkd3d_spirv_enable_capability(builder, SpvCapabilityImageQuery);
|
|
|
|
|
|
|
|
|
|
spirv_compiler_prepare_image(compiler, &image, &src->reg, NULL, VKD3D_IMAGE_FLAG_NONE);
|
|
|
|
|
- type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_UINT, 1);
|
|
|
|
|
+ type_id = spirv_get_type_id(builder, VSIR_DATA_U32, 1);
|
|
|
|
|
val_id = vkd3d_spirv_build_op_image_query_samples(builder, type_id, image.image_id);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -10065,14 +10064,16 @@ static void spirv_compiler_emit_sample_info(struct spirv_compiler *compiler,
|
|
|
|
|
|
|
|
|
|
constituents[0] = val_id;
|
|
|
|
|
for (i = 1; i < VKD3D_VEC4_SIZE; ++i)
|
|
|
|
|
+ {
|
|
|
|
|
constituents[i] = spirv_compiler_get_constant_uint(compiler, 0);
|
|
|
|
|
- type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_UINT, VKD3D_VEC4_SIZE);
|
|
|
|
|
+ }
|
|
|
|
|
+ type_id = spirv_get_type_id(builder, VSIR_DATA_U32, VKD3D_VEC4_SIZE);
|
|
|
|
|
val_id = vkd3d_spirv_build_op_composite_construct(builder, type_id, constituents, VKD3D_VEC4_SIZE);
|
|
|
|
|
|
|
|
|
|
if (!(instruction->flags & VKD3DSI_SAMPLE_INFO_UINT))
|
|
|
|
|
{
|
|
|
|
|
component_type = VKD3D_SHADER_COMPONENT_FLOAT;
|
|
|
|
|
- type_id = spirv_get_type_id_for_component_type(builder, component_type, VKD3D_VEC4_SIZE);
|
|
|
|
|
+ type_id = spirv_get_type_id(builder, VSIR_DATA_F32, VKD3D_VEC4_SIZE);
|
|
|
|
|
val_id = vkd3d_spirv_build_op_convert_utof(builder, type_id, val_id);
|
|
|
|
|
if (instruction->flags & VKD3DSI_PRECISE_XYZW)
|
|
|
|
|
vkd3d_spirv_build_op_decorate(builder, val_id, SpvDecorationNoContraction, NULL, 0);
|
|
|
|
|
@@ -10138,13 +10139,12 @@ static void spirv_compiler_emit_sample_position(struct spirv_compiler *compiler,
|
|
|
|
|
sample_count_id = spirv_compiler_emit_query_sample_count(compiler, &instruction->src[0]);
|
|
|
|
|
sample_index_id = spirv_compiler_emit_load_src(compiler, &instruction->src[1], VKD3DSP_WRITEMASK_0);
|
|
|
|
|
|
|
|
|
|
- type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_UINT, 1);
|
|
|
|
|
+ type_id = spirv_get_type_id(builder, VSIR_DATA_U32, 1);
|
|
|
|
|
index_id = vkd3d_spirv_build_op_iadd(builder, type_id, sample_count_id, sample_index_id);
|
|
|
|
|
- index_id = vkd3d_spirv_build_op_isub(builder,
|
|
|
|
|
- type_id, index_id, spirv_compiler_get_constant_uint(compiler, 1));
|
|
|
|
|
+ index_id = vkd3d_spirv_build_op_isub(builder, type_id, index_id, spirv_compiler_get_constant_uint(compiler, 1));
|
|
|
|
|
|
|
|
|
|
/* Validate sample index. */
|
|
|
|
|
- bool_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_BOOL, 1);
|
|
|
|
|
+ bool_id = spirv_get_type_id(builder, VSIR_DATA_BOOL, 1);
|
|
|
|
|
id = vkd3d_spirv_build_op_logical_and(builder, bool_id,
|
|
|
|
|
vkd3d_spirv_build_op_uless_than(builder, bool_id, sample_index_id, sample_count_id),
|
|
|
|
|
vkd3d_spirv_build_op_uless_than_equal(builder,
|
|
|
|
|
@@ -10152,7 +10152,7 @@ static void spirv_compiler_emit_sample_position(struct spirv_compiler *compiler,
|
|
|
|
|
index_id = vkd3d_spirv_build_op_select(builder, type_id,
|
|
|
|
|
id, index_id, spirv_compiler_get_constant_uint(compiler, 0));
|
|
|
|
|
|
|
|
|
|
- type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_FLOAT, 2);
|
|
|
|
|
+ type_id = spirv_get_type_id(builder, VSIR_DATA_F32, 2);
|
|
|
|
|
if (!(id = compiler->sample_positions_id))
|
|
|
|
|
{
|
|
|
|
|
length_id = spirv_compiler_get_constant_uint(compiler, ARRAY_SIZE(standard_sample_positions));
|
|
|
|
|
@@ -10216,7 +10216,7 @@ static void spirv_compiler_emit_eval_attrib(struct spirv_compiler *compiler,
|
|
|
|
|
src_ids[src_count++] = spirv_compiler_emit_load_src(compiler, &src[1], VKD3DSP_WRITEMASK_0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_FLOAT,
|
|
|
|
|
+ type_id = spirv_get_type_id(builder, VSIR_DATA_F32,
|
|
|
|
|
vsir_write_mask_component_count(register_info.write_mask));
|
|
|
|
|
|
|
|
|
|
instr_set_id = vkd3d_spirv_get_glsl_std450_instr_set(builder);
|
|
|
|
|
@@ -10425,7 +10425,7 @@ static uint32_t spirv_compiler_emit_group_nonuniform_ballot(struct spirv_compile
|
|
|
|
|
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
|
|
|
|
|
uint32_t type_id, val_id;
|
|
|
|
|
|
|
|
|
|
- type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_UINT, VKD3D_VEC4_SIZE);
|
|
|
|
|
+ type_id = spirv_get_type_id(builder, VSIR_DATA_U32, VKD3D_VEC4_SIZE);
|
|
|
|
|
val_id = spirv_compiler_emit_load_src(compiler, src, VKD3DSP_WRITEMASK_0);
|
|
|
|
|
val_id = vkd3d_spirv_build_op_group_nonuniform_ballot(builder, type_id, val_id);
|
|
|
|
|
|
|
|
|
|
@@ -10508,7 +10508,7 @@ static void spirv_compiler_emit_wave_bit_count(struct spirv_compiler *compiler,
|
|
|
|
|
: SpvGroupOperationReduce;
|
|
|
|
|
|
|
|
|
|
val_id = spirv_compiler_emit_group_nonuniform_ballot(compiler, instruction->src);
|
|
|
|
|
- type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_UINT, 1);
|
|
|
|
|
+ type_id = spirv_get_type_id(builder, VSIR_DATA_U32, 1);
|
|
|
|
|
val_id = vkd3d_spirv_build_op_group_nonuniform_ballot_bit_count(builder, type_id, group_op, val_id);
|
|
|
|
|
|
|
|
|
|
spirv_compiler_emit_store_dst(compiler, dst, val_id);
|
|
|
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h
|
|
|
|
|
index 6037f7179e7..896c97a7a64 100644
|
|
|
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h
|
|
|
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h
|
|
|
|
|
@@ -1428,9 +1428,9 @@ struct vkd3d_shader_instruction_array
|
|
|
|
|
size_t count;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
+struct vkd3d_shader_instruction *shader_instruction_array_append(struct vkd3d_shader_instruction_array *array);
|
|
|
|
|
+bool shader_instruction_array_insert_at(struct vkd3d_shader_instruction_array *instructions, size_t idx, size_t count);
|
|
|
|
|
bool shader_instruction_array_reserve(struct vkd3d_shader_instruction_array *instructions, size_t reserve);
|
|
|
|
|
-bool shader_instruction_array_insert_at(struct vkd3d_shader_instruction_array *instructions,
|
|
|
|
|
- size_t idx, size_t count);
|
|
|
|
|
|
|
|
|
|
struct vsir_program_iterator
|
|
|
|
|
{
|
|
|
|
|
@@ -1486,8 +1486,9 @@ static inline struct vkd3d_shader_instruction *vsir_program_iterator_prev(
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* When insertion takes place, argument `it' is updated to point to the same
|
|
|
|
|
- * instruction as before the insertion, but all other iterators and pointers
|
|
|
|
|
- * to the same container are invalidated and cannot be used any more. */
|
|
|
|
|
+ * instruction as before the insertion, but all existing pointers to the same
|
|
|
|
|
+ * container, as well as any iterators pointing to instructions after the
|
|
|
|
|
+ * insertion point should be considered invalid. */
|
|
|
|
|
static inline bool vsir_program_iterator_insert_after(struct vsir_program_iterator *it, size_t count)
|
|
|
|
|
{
|
|
|
|
|
return shader_instruction_array_insert_at(it->array, it->idx + 1, count);
|
|
|
|
|
@@ -1651,12 +1652,7 @@ bool vsir_instruction_init_with_params(struct vsir_program *program,
|
|
|
|
|
|
|
|
|
|
static inline struct vkd3d_shader_instruction *vsir_program_append(struct vsir_program *program)
|
|
|
|
|
{
|
|
|
|
|
- struct vkd3d_shader_instruction_array *array = &program->instructions;
|
|
|
|
|
-
|
|
|
|
|
- if (!shader_instruction_array_insert_at(array, array->count, 1))
|
|
|
|
|
- return NULL;
|
|
|
|
|
-
|
|
|
|
|
- return &array->elements[array->count - 1];
|
|
|
|
|
+ return shader_instruction_array_append(&program->instructions);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline struct vkd3d_shader_dst_param *vsir_program_get_dst_params(
|
|
|
|
|
--
|
|
|
|
|
2.51.0
|
|
|
|
|
|