To simplify SM 6 support, insert a control point id relative address where needed, and declare control point phase inputs where missing.
-- v4: vkd3d-shader/ir: Insert hull shader control point input declarations if no control point phase is defined. vkd3d-shader/ir: Normalise control point phase output registers to include the control point id.
From: Conor McCarthy cmccarthy@codeweavers.com
In SPIR-V the address must include the invocation id, but in TPF it is implicit. Move the register index up one slot and insert an OUTPOINTID relative address. --- libs/vkd3d-shader/ir.c | 101 +++++++++++++++++++++++ libs/vkd3d-shader/spirv.c | 32 ++----- libs/vkd3d-shader/vkd3d_shader_private.h | 3 + 3 files changed, 111 insertions(+), 25 deletions(-)
diff --git a/libs/vkd3d-shader/ir.c b/libs/vkd3d-shader/ir.c index a077a05d..8b976a26 100644 --- a/libs/vkd3d-shader/ir.c +++ b/libs/vkd3d-shader/ir.c @@ -84,6 +84,11 @@ static void shader_instruction_eliminate_phase_instance_id(struct vkd3d_shader_i shader_register_eliminate_phase_addressing((struct vkd3d_shader_register *)&ins->dst[i].reg, instance_id); }
+static bool normaliser_is_in_control_point_phase(const struct vkd3d_shader_normaliser *normaliser) +{ + return normaliser->phase == VKD3DSIH_HS_CONTROL_POINT_PHASE; +} + static bool normaliser_is_in_fork_or_join_phase(const struct vkd3d_shader_normaliser *normaliser) { return normaliser->phase == VKD3DSIH_HS_FORK_PHASE || normaliser->phase == VKD3DSIH_HS_JOIN_PHASE; @@ -217,6 +222,22 @@ static enum vkd3d_result shader_normaliser_flatten_phases(struct vkd3d_shader_no return VKD3D_OK; }
+static void shader_register_init(struct vkd3d_shader_register *reg, + enum vkd3d_shader_register_type reg_type, enum vkd3d_data_type data_type) +{ + reg->type = reg_type; + reg->precision = VKD3D_SHADER_REGISTER_PRECISION_DEFAULT; + reg->non_uniform = false; + reg->data_type = data_type; + reg->idx[0].offset = ~0u; + reg->idx[0].rel_addr = NULL; + reg->idx[1].offset = ~0u; + reg->idx[1].rel_addr = NULL; + reg->idx[2].offset = ~0u; + reg->idx[2].rel_addr = NULL; + reg->immconst_type = VKD3D_IMMCONST_SCALAR; +} + static void shader_instruction_init(struct vkd3d_shader_instruction *ins, enum vkd3d_shader_opcode handler_idx) { memset(ins, 0, sizeof(*ins)); @@ -258,6 +279,86 @@ enum vkd3d_result shader_normaliser_flatten_hull_shader_phases(struct vkd3d_shad return result; }
+static struct vkd3d_shader_src_param *shader_normaliser_create_outpointid_param(struct vkd3d_shader_normaliser *normaliser) +{ + struct vkd3d_shader_src_param *rel_addr; + + if (!(rel_addr = shader_src_param_allocator_get(&normaliser->instructions.src_params, 1))) + return NULL; + + shader_register_init(&rel_addr->reg, VKD3DSPR_OUTPOINTID, VKD3D_DATA_UINT); + rel_addr->swizzle = 0; + rel_addr->modifiers = 0; + + return rel_addr; +} + +static bool shader_dst_param_normalise_outpointid(struct vkd3d_shader_dst_param *dst_param, + struct vkd3d_shader_normaliser *normaliser) +{ + struct vkd3d_shader_register *reg = &dst_param->reg; + + if (normaliser_is_in_control_point_phase(normaliser) && reg->type == VKD3DSPR_OUTPUT) + { + if (reg->idx[2].offset != ~0u) + { + FIXME("Cannot insert phase id.\n"); + return false; + } + if (reg->idx[1].offset != ~0u) + { + WARN("Unexpected address at index 1.\n"); + reg->idx[2] = reg->idx[1]; + } + reg->idx[1] = reg->idx[0]; + /* The control point id param is implicit here. Avoid later complications by inserting it. */ + reg->idx[0].offset = 0; + reg->idx[0].rel_addr = normaliser->outpointid_param; + } + + return true; +} + +enum vkd3d_result shader_normaliser_normalise_hull_shader_control_point_io(struct vkd3d_shader_normaliser *normaliser) +{ + struct vkd3d_shader_instruction_array *instructions = &normaliser->instructions; + struct vkd3d_shader_instruction *ins; + unsigned int i, j; + + if (!(normaliser->outpointid_param = shader_normaliser_create_outpointid_param(normaliser))) + { + ERR("Failed to allocate src param.\n"); + return VKD3D_ERROR_OUT_OF_MEMORY; + } + + normaliser->phase = VKD3DSIH_INVALID; + for (i = 0; i < normaliser->instructions.count; ++i) + { + ins = &instructions->elements[i]; + + switch (ins->handler_idx) + { + case VKD3DSIH_HS_CONTROL_POINT_PHASE: + case VKD3DSIH_HS_FORK_PHASE: + case VKD3DSIH_HS_JOIN_PHASE: + normaliser->phase = ins->handler_idx; + break; + default: + if (shader_instruction_is_dcl(ins)) + break; + for (j = 0; j < ins->dst_count; ++j) + { + if (!shader_dst_param_normalise_outpointid((struct vkd3d_shader_dst_param *)&ins->dst[j], + normaliser)) + return VKD3D_ERROR_INVALID_ARGUMENT; + } + break; + } + } + + return VKD3D_OK; +} + void shader_normaliser_destroy(struct vkd3d_shader_normaliser *normaliser) { shader_instruction_array_destroy(&normaliser->instructions); diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c index 9504b955..e3708db4 100644 --- a/libs/vkd3d-shader/spirv.c +++ b/libs/vkd3d-shader/spirv.c @@ -1971,7 +1971,6 @@ struct vkd3d_symbol_register_data unsigned int structure_stride; unsigned int binding_base_idx; bool is_aggregate; /* An aggregate, i.e. a structure or an array. */ - bool is_dynamically_indexed; /* If member_idx is a variable ID instead of a constant. */ };
struct vkd3d_symbol_resource_data @@ -2064,7 +2063,7 @@ static void vkd3d_symbol_make_register(struct vkd3d_symbol *symbol, symbol->type = VKD3D_SYMBOL_REGISTER; memset(&symbol->key, 0, sizeof(symbol->key)); symbol->key.reg.type = reg->type; - if (vkd3d_shader_register_is_input(reg) && reg->idx[1].offset != ~0u) + if ((vkd3d_shader_register_is_input(reg) || vkd3d_shader_register_is_output(reg)) && reg->idx[1].offset != ~0u) symbol->key.reg.idx = reg->idx[1].offset; else if (reg->type != VKD3DSPR_IMMCONSTBUFFER) symbol->key.reg.idx = reg->idx[0].offset; @@ -2084,7 +2083,6 @@ static void vkd3d_symbol_set_register_info(struct vkd3d_symbol *symbol, symbol->info.reg.structure_stride = 0; symbol->info.reg.binding_base_idx = 0; symbol->info.reg.is_aggregate = false; - symbol->info.reg.is_dynamically_indexed = false; }
static void vkd3d_symbol_make_resource(struct vkd3d_symbol *symbol, @@ -3191,7 +3189,6 @@ struct vkd3d_shader_register_info unsigned int structure_stride; unsigned int binding_base_idx; bool is_aggregate; - bool is_dynamically_indexed; };
static bool spirv_compiler_get_register_info(const struct spirv_compiler *compiler, @@ -3214,7 +3211,6 @@ static bool spirv_compiler_get_register_info(const struct spirv_compiler *compil register_info->structure_stride = 0; register_info->binding_base_idx = 0; register_info->is_aggregate = false; - register_info->is_dynamically_indexed = false; return true; }
@@ -3236,7 +3232,6 @@ static bool spirv_compiler_get_register_info(const struct spirv_compiler *compil register_info->structure_stride = symbol->info.reg.structure_stride; register_info->binding_base_idx = symbol->info.reg.binding_base_idx; register_info->is_aggregate = symbol->info.reg.is_aggregate; - register_info->is_dynamically_indexed = symbol->info.reg.is_dynamically_indexed;
return true; } @@ -3381,17 +3376,8 @@ static void spirv_compiler_emit_dereference_register(struct spirv_compiler *comp if (reg->idx[1].rel_addr) FIXME("Relative addressing not implemented.\n");
- if (register_info->is_dynamically_indexed) - { - indexes[index_count++] = vkd3d_spirv_build_op_load(builder, - vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_INT, 1), - register_info->member_idx, SpvMemoryAccessMaskNone); - } - else - { - reg_idx.offset = register_info->member_idx; - indexes[index_count++] = spirv_compiler_emit_register_addressing(compiler, ®_idx); - } + reg_idx.offset = register_info->member_idx; + indexes[index_count++] = spirv_compiler_emit_register_addressing(compiler, ®_idx); } } else @@ -5110,12 +5096,7 @@ static void spirv_compiler_emit_output(struct spirv_compiler *compiler, use_private_variable ? VKD3D_SHADER_COMPONENT_FLOAT : component_type, use_private_variable ? VKD3DSP_WRITEMASK_ALL : write_mask); reg_symbol.info.reg.is_aggregate = use_private_variable ? is_patch_constant : array_size; - if (!use_private_variable && is_in_control_point_phase(compiler)) - { - reg_symbol.info.reg.member_idx = spirv_compiler_get_invocation_id(compiler); - reg_symbol.info.reg.is_dynamically_indexed = true; - } - else if (is_patch_constant) + if (is_patch_constant) { reg_symbol.info.reg.member_idx = reg->idx[0].offset; } @@ -6487,7 +6468,6 @@ static void spirv_compiler_leave_shader_phase(struct spirv_compiler *compiler) }
memset(®, 0, sizeof(reg)); - reg.idx[1].offset = ~0u;
/* Fork and join phases share output registers (patch constants). * Control point phase has separate output registers. */ @@ -6502,6 +6482,7 @@ static void spirv_compiler_leave_shader_phase(struct spirv_compiler *compiler)
reg.type = VKD3DSPR_OUTPUT; reg.idx[0].offset = e->register_index; + reg.idx[1].offset = ~0u; vkd3d_symbol_make_register(®_symbol, ®); if ((entry = rb_get(&compiler->symbol_table, ®_symbol))) { @@ -9861,7 +9842,8 @@ static int spirv_compiler_generate_spirv(struct spirv_compiler *compiler, if (compiler->shader_type == VKD3D_SHADER_TYPE_HULL) { shader_normaliser_init(&normaliser, instructions); - result = shader_normaliser_flatten_hull_shader_phases(&normaliser); + if ((result = shader_normaliser_flatten_hull_shader_phases(&normaliser)) >= 0) + result = shader_normaliser_normalise_hull_shader_control_point_io(&normaliser); instructions = &normaliser.instructions;
if (result >= 0 && TRACE_ON()) diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h index 7e111c42..37231446 100644 --- a/libs/vkd3d-shader/vkd3d_shader_private.h +++ b/libs/vkd3d-shader/vkd3d_shader_private.h @@ -1333,11 +1333,14 @@ struct vkd3d_shader_normaliser unsigned int instance_count; unsigned int phase_body_idx; enum vkd3d_shader_opcode phase; + + struct vkd3d_shader_src_param *outpointid_param; };
void shader_normaliser_init(struct vkd3d_shader_normaliser *normaliser, struct vkd3d_shader_instruction_array *instructions); enum vkd3d_result shader_normaliser_flatten_hull_shader_phases(struct vkd3d_shader_normaliser *normaliser); +enum vkd3d_result shader_normaliser_normalise_hull_shader_control_point_io(struct vkd3d_shader_normaliser *normaliser); void shader_normaliser_destroy(struct vkd3d_shader_normaliser *normaliser);
#endif /* __VKD3D_SHADER_PRIVATE_H */
From: Conor McCarthy cmccarthy@codeweavers.com
The SPIR-V backend will emit a default control point phase. Inserting inputs into the IR allows handling of declarations via the usual path instead of an ad hoc implementation which may not match later changes to input handling. --- libs/vkd3d-shader/ir.c | 101 ++++++++++++- libs/vkd3d-shader/spirv.c | 178 +++-------------------- libs/vkd3d-shader/vkd3d_shader_private.h | 11 +- 3 files changed, 127 insertions(+), 163 deletions(-)
diff --git a/libs/vkd3d-shader/ir.c b/libs/vkd3d-shader/ir.c index 8b976a26..274c6ff9 100644 --- a/libs/vkd3d-shader/ir.c +++ b/libs/vkd3d-shader/ir.c @@ -29,6 +29,11 @@ static bool shader_instruction_is_dcl(const struct vkd3d_shader_instruction *ins || ins->handler_idx == VKD3DSIH_HS_DECLS; }
+static bool shader_instruction_is_fork_or_join_phase(const struct vkd3d_shader_instruction *ins) +{ + return ins->handler_idx == VKD3DSIH_HS_FORK_PHASE || ins->handler_idx == VKD3DSIH_HS_JOIN_PHASE; +} + static void vkd3d_shader_instruction_make_nop(struct vkd3d_shader_instruction *ins) { ins->handler_idx = VKD3DSIH_NOP; @@ -319,10 +324,73 @@ static bool shader_dst_param_normalise_outpointid(struct vkd3d_shader_dst_param return true; }
-enum vkd3d_result shader_normaliser_normalise_hull_shader_control_point_io(struct vkd3d_shader_normaliser *normaliser) +static void shader_dst_param_io_init(struct vkd3d_shader_dst_param *param, + const struct vkd3d_shader_signature_element *e, enum vkd3d_shader_register_type reg_type) +{ + param->write_mask = e->mask; + param->modifiers = 0; + param->shift = 0; + shader_register_init(¶m->reg, reg_type, vkd3d_data_type_from_component_type(e->component_type)); +} + +static enum vkd3d_result shader_normaliser_emit_hs_input(struct vkd3d_shader_normaliser *normaliser, + const struct vkd3d_shader_signature *s, unsigned int input_control_point_count, unsigned int dst) +{ + const struct vkd3d_shader_signature_element *e; + struct vkd3d_shader_instruction *ins; + struct vkd3d_shader_dst_param *param; + unsigned int i, count; + + for (i = 0, count = 1; i < s->element_count; ++i) + count += !!s->elements[i].used_mask; + + if (!shader_instruction_array_reserve(&normaliser->instructions, normaliser->instructions.count + count)) + return VKD3D_ERROR_OUT_OF_MEMORY; + + memmove(&normaliser->instructions.elements[dst + count], &normaliser->instructions.elements[dst], + (normaliser->instructions.count - dst) * sizeof(*normaliser->instructions.elements)); + normaliser->instructions.count += count; + + ins = &normaliser->instructions.elements[dst]; + shader_instruction_init(ins, VKD3DSIH_HS_CONTROL_POINT_PHASE); + ins->flags = 1; + ++ins; + + for (i = 0; i < s->element_count; ++i) + { + e = &s->elements[i]; + if (!e->used_mask) + continue; + + if (e->sysval_semantic != VKD3D_SHADER_SV_NONE) + { + shader_instruction_init(ins, VKD3DSIH_DCL_INPUT_SIV); + param = &ins->declaration.register_semantic.reg; + ins->declaration.register_semantic.sysval_semantic = vkd3d_siv_from_sysval(e->sysval_semantic); + } + else + { + shader_instruction_init(ins, VKD3DSIH_DCL_INPUT); + param = &ins->declaration.dst; + } + + shader_dst_param_io_init(param, e, VKD3DSPR_INPUT); + param->reg.idx[0].offset = input_control_point_count; + param->reg.idx[1].offset = i; + + ++ins; + } + + return VKD3D_OK; +} + +enum vkd3d_result shader_normaliser_normalise_hull_shader_control_point_io(struct vkd3d_shader_normaliser *normaliser, + const struct vkd3d_shader_signature *input_signature) { struct vkd3d_shader_instruction_array *instructions = &normaliser->instructions; + unsigned int input_control_point_count; struct vkd3d_shader_instruction *ins; + bool has_control_point_phase; unsigned int i, j;
if (!(normaliser->outpointid_param = shader_normaliser_create_outpointid_param(normaliser))) @@ -356,6 +424,37 @@ enum vkd3d_result shader_normaliser_normalise_hull_shader_control_point_io(struc } }
+ normaliser->phase = VKD3DSIH_INVALID; + input_control_point_count = 1; + has_control_point_phase = false; + + for (i = 0; i < instructions->count; ++i) + { + ins = &instructions->elements[i]; + + if (shader_instruction_is_fork_or_join_phase(ins) && !has_control_point_phase + && !normaliser_is_in_fork_or_join_phase(normaliser)) + { + return shader_normaliser_emit_hs_input(normaliser, input_signature, input_control_point_count, i); + } + + switch (ins->handler_idx) + { + case VKD3DSIH_DCL_INPUT_CONTROL_POINT_COUNT: + input_control_point_count = ins->declaration.count; + break; + case VKD3DSIH_HS_CONTROL_POINT_PHASE: + has_control_point_phase = true; + break; + case VKD3DSIH_HS_FORK_PHASE: + case VKD3DSIH_HS_JOIN_PHASE: + normaliser->phase = ins->handler_idx; + break; + default: + break; + } + } + return VKD3D_OK; }
diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c index e3708db4..73510f8b 100644 --- a/libs/vkd3d-shader/spirv.c +++ b/libs/vkd3d-shader/spirv.c @@ -168,7 +168,7 @@ static void vkd3d_spirv_validate(const struct vkd3d_shader_code *spirv,
#endif /* HAVE_SPIRV_TOOLS */
-static enum vkd3d_shader_input_sysval_semantic vkd3d_siv_from_sysval_indexed(enum vkd3d_shader_sysval_semantic sysval, +enum vkd3d_shader_input_sysval_semantic vkd3d_siv_from_sysval_indexed(enum vkd3d_shader_sysval_semantic sysval, unsigned int index) { switch (sysval) @@ -199,11 +199,6 @@ static enum vkd3d_shader_input_sysval_semantic vkd3d_siv_from_sysval_indexed(enu } }
-static enum vkd3d_shader_input_sysval_semantic vkd3d_siv_from_sysval(enum vkd3d_shader_sysval_semantic sysval) -{ - return vkd3d_siv_from_sysval_indexed(sysval, 0); -} - #define VKD3D_SPIRV_VERSION 0x00010000 #define VKD3D_SPIRV_GENERATOR_ID 18 #define VKD3D_SPIRV_GENERATOR_VERSION 7 @@ -2271,6 +2266,7 @@ struct spirv_compiler bool use_vocp;
enum vkd3d_shader_opcode phase; + bool emit_default_control_point_phase; struct vkd3d_shader_phase control_point_phase; struct vkd3d_shader_phase patch_constant_phase;
@@ -6440,6 +6436,8 @@ static void spirv_compiler_emit_dcl_thread_group(struct spirv_compiler *compiler SpvExecutionModeLocalSize, local_size, ARRAY_SIZE(local_size)); }
+static void spirv_compiler_emit_default_control_point_phase(struct spirv_compiler *compiler); + static void spirv_compiler_leave_shader_phase(struct spirv_compiler *compiler) { const struct vkd3d_shader_signature *signature = compiler->output_signature; @@ -6449,6 +6447,9 @@ static void spirv_compiler_leave_shader_phase(struct spirv_compiler *compiler) struct rb_entry *entry; unsigned int i;
+ if (is_in_control_point_phase(compiler) && compiler->emit_default_control_point_phase) + spirv_compiler_emit_default_control_point_phase(compiler); + vkd3d_spirv_build_op_function_end(builder);
compiler->temp_id = 0; @@ -6534,6 +6535,9 @@ static void spirv_compiler_enter_shader_phase(struct spirv_compiler *compiler, ? &compiler->control_point_phase : &compiler->patch_constant_phase; phase->function_id = function_id; phase->function_location = vkd3d_spirv_stream_current_location(&builder->function_stream); + + if (instruction->handler_idx == VKD3DSIH_HS_CONTROL_POINT_PHASE) + compiler->emit_default_control_point_phase = instruction->flags; }
static void spirv_compiler_emit_default_control_point_phase(struct spirv_compiler *compiler) @@ -6542,10 +6546,10 @@ static void spirv_compiler_emit_default_control_point_phase(struct spirv_compile const struct vkd3d_shader_signature *input_signature = compiler->input_signature; struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; enum vkd3d_shader_component_type component_type; - uint32_t input_id, output_id, dst_id, src_id; struct vkd3d_shader_src_param invocation; struct vkd3d_shader_register input_reg; uint32_t type_id, output_ptr_type_id; + uint32_t input_id, output_id, dst_id; unsigned int component_count; uint32_t invocation_id; unsigned int i; @@ -6578,8 +6582,6 @@ static void spirv_compiler_emit_default_control_point_phase(struct spirv_compile
input_reg.idx[1].offset = input->register_index; input_id = spirv_compiler_get_register_id(compiler, &input_reg); - type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_FLOAT, 4); - src_id = vkd3d_spirv_build_op_load(builder, type_id, input_id, SpvMemoryAccessMaskNone);
component_type = output->component_type; component_count = vkd3d_write_mask_component_count(output->mask); @@ -6593,9 +6595,10 @@ static void spirv_compiler_emit_default_control_point_phase(struct spirv_compile output_ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassOutput, type_id); dst_id = vkd3d_spirv_build_op_access_chain1(builder, output_ptr_type_id, output_id, invocation_id);
- spirv_compiler_emit_store(compiler, dst_id, output->mask, - component_type, SpvStorageClassOutput, VKD3DSP_WRITEMASK_ALL, src_id); + vkd3d_spirv_build_op_copy_memory(builder, dst_id, input_id, SpvMemoryAccessMaskNone); } + + vkd3d_spirv_build_op_return(builder); }
static void spirv_compiler_emit_barrier(struct spirv_compiler *compiler, @@ -6624,95 +6627,6 @@ static void spirv_compiler_emit_hull_shader_barrier(struct spirv_compiler *compi SpvScopeWorkgroup, SpvScopeInvocation, SpvMemorySemanticsMaskNone); }
-static void spirv_compiler_emit_hull_shader_input_initialisation(struct spirv_compiler *compiler) -{ - uint32_t type_id, length_id, register_index_id, src_array_id, dst_array_id, vicp_id, tmp_id; - const struct vkd3d_shader_signature *signature = compiler->input_signature; - uint32_t src_type_id, dst_type_id, src_id, dst_id, point_index_id; - struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; - const struct vkd3d_shader_signature_element *element; - enum vkd3d_shader_input_sysval_semantic sysval; - const struct vkd3d_spirv_builtin *builtin; - struct vkd3d_symbol *symbol, symbol_key; - unsigned int register_count, i, j; - struct vkd3d_shader_register r; - struct rb_entry *entry; - uint32_t indices[2]; - - for (i = 0, register_count = 0; i < signature->element_count; ++i) - { - register_count = max(register_count, signature->elements[i].register_index + 1); - } - - type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_FLOAT, 4); - length_id = spirv_compiler_get_constant_uint(compiler, compiler->input_control_point_count); - type_id = vkd3d_spirv_get_op_type_array(builder, type_id, length_id); - type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassPrivate, type_id); - - memset(&r, 0, sizeof(r)); - r.type = VKD3DSPR_INPUT; - r.idx[0].offset = 0; - r.idx[1].offset = ~0u; - vkd3d_symbol_make_register(&symbol_key, &r); - - for (i = 0; i < signature->element_count; ++i) - { - element = &signature->elements[i]; - - symbol_key.key.reg.idx = element->register_index; - entry = rb_get(&compiler->symbol_table, &symbol_key); - symbol = RB_ENTRY_VALUE(entry, struct vkd3d_symbol, entry); - - vicp_id = symbol->id; - register_index_id = spirv_compiler_get_constant_uint(compiler, element->register_index); - dst_array_id = vkd3d_spirv_build_op_in_bounds_access_chain1(builder, type_id, vicp_id, register_index_id); - - if (element->sysval_semantic) - { - sysval = vkd3d_siv_from_sysval(element->sysval_semantic); - builtin = get_spirv_builtin_for_sysval(compiler, sysval); - src_array_id = spirv_compiler_emit_builtin_variable(compiler, builtin, - SpvStorageClassInput, compiler->input_control_point_count); - - if (builtin->component_count == 4) - { - vkd3d_spirv_build_op_copy_memory(builder, dst_array_id, src_array_id, SpvMemoryAccessMaskNone); - } - else - { - tmp_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_FLOAT, builtin->component_count); - src_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassInput, tmp_id); - dst_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassPrivate, tmp_id); - - for (j = 0; j < compiler->input_control_point_count; ++j) - { - point_index_id = spirv_compiler_get_constant_uint(compiler, j); - src_id = vkd3d_spirv_build_op_in_bounds_access_chain1(builder, - src_type_id, src_array_id, point_index_id); - - indices[0] = point_index_id; - indices[1] = spirv_compiler_get_constant_uint(compiler, 0); - dst_id = vkd3d_spirv_build_op_in_bounds_access_chain(builder, - dst_type_id, dst_array_id, indices, 2); - - vkd3d_spirv_build_op_copy_memory(builder, dst_id, src_id, SpvMemoryAccessMaskNone); - } - } - } - else - { - src_array_id = spirv_compiler_emit_array_variable(compiler, &builder->global_stream, - SpvStorageClassInput, VKD3D_SHADER_COMPONENT_FLOAT, 4, compiler->input_control_point_count); - vkd3d_spirv_add_iface_variable(builder, src_array_id); - vkd3d_spirv_build_op_decorate1(builder, src_array_id, SpvDecorationLocation, element->register_index); - vkd3d_spirv_build_op_name(builder, src_array_id, "v%u", element->register_index); - - vkd3d_spirv_build_op_copy_memory(builder, dst_array_id, src_array_id, SpvMemoryAccessMaskNone); - } - symbol->info.reg.dcl_mask |= element->mask; - } -} - static void spirv_compiler_emit_shader_epilogue_invocation(struct spirv_compiler *compiler) { struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; @@ -6759,14 +6673,9 @@ static void spirv_compiler_emit_hull_shader_main(struct spirv_compiler *compiler
vkd3d_spirv_builder_begin_main_function(builder);
- spirv_compiler_emit_hull_shader_input_initialisation(compiler); - void_id = vkd3d_spirv_get_op_type_void(builder);
- if (compiler->control_point_phase.function_id) - vkd3d_spirv_build_op_function_call(builder, void_id, compiler->control_point_phase.function_id, NULL, 0); - else - spirv_compiler_emit_default_control_point_phase(compiler); + vkd3d_spirv_build_op_function_call(builder, void_id, compiler->control_point_phase.function_id, NULL, 0);
if (compiler->use_vocp) spirv_compiler_emit_hull_shader_barrier(compiler); @@ -9402,58 +9311,6 @@ static void spirv_compiler_emit_cut_stream(struct spirv_compiler *compiler, vkd3d_spirv_build_op_end_primitive(builder); }
-static void spirv_compiler_emit_hull_shader_inputs(struct spirv_compiler *compiler) -{ - const struct vkd3d_shader_signature *signature = compiler->input_signature; - struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; - uint32_t type_id, length_id, vicp_id, vicp_type_id; - unsigned int register_count, register_idx, i; - struct vkd3d_shader_register r; - struct vkd3d_symbol symbol; - struct rb_entry *entry; - - for (i = 0, register_count = 0; i < signature->element_count; ++i) - { - register_count = max(register_count, signature->elements[i].register_index + 1); - } - - type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_FLOAT, 4); - length_id = spirv_compiler_get_constant_uint(compiler, compiler->input_control_point_count); - type_id = vkd3d_spirv_get_op_type_array(builder, type_id, length_id); - length_id = spirv_compiler_get_constant_uint(compiler, register_count); - type_id = vkd3d_spirv_get_op_type_array(builder, type_id, length_id); - vicp_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassPrivate, type_id); - - vicp_id = vkd3d_spirv_build_op_variable(builder, - &builder->global_stream, vicp_type_id, SpvStorageClassPrivate, 0); - vkd3d_spirv_build_op_name(builder, vicp_id, "vicp"); - - memset(&r, 0, sizeof(r)); - r.type = VKD3DSPR_INPUT; - r.idx[0].offset = 0; - r.idx[1].offset = ~0u; - vkd3d_symbol_make_register(&symbol, &r); - - for (i = 0; i < signature->element_count; ++i) - { - register_idx = signature->elements[i].register_index; - - symbol.key.reg.idx = register_idx; - if ((entry = rb_get(&compiler->symbol_table, &symbol))) - { - struct vkd3d_symbol *s = RB_ENTRY_VALUE(entry, struct vkd3d_symbol, entry); - s->info.reg.dcl_mask |= signature->elements[i].mask; - continue; - } - - vkd3d_symbol_set_register_info(&symbol, vicp_id, SpvStorageClassPrivate, - VKD3D_SHADER_COMPONENT_FLOAT, VKD3DSP_WRITEMASK_ALL); - symbol.info.reg.dcl_mask = signature->elements[i].mask; - symbol.info.reg.is_aggregate = true; - spirv_compiler_put_symbol(compiler, &symbol); - } -} - /* This function is called after declarations are processed. */ static void spirv_compiler_emit_main_prolog(struct spirv_compiler *compiler) { @@ -9462,8 +9319,6 @@ static void spirv_compiler_emit_main_prolog(struct spirv_compiler *compiler) if (compiler->xfb_info && compiler->xfb_info->element_count && compiler->shader_type != VKD3D_SHADER_TYPE_GEOMETRY) spirv_compiler_emit_point_size(compiler); - if (compiler->shader_type == VKD3D_SHADER_TYPE_HULL) - spirv_compiler_emit_hull_shader_inputs(compiler); }
static bool is_dcl_instruction(enum vkd3d_shader_opcode handler_idx) @@ -9843,7 +9698,8 @@ static int spirv_compiler_generate_spirv(struct spirv_compiler *compiler, { shader_normaliser_init(&normaliser, instructions); if ((result = shader_normaliser_flatten_hull_shader_phases(&normaliser)) >= 0) - result = shader_normaliser_normalise_hull_shader_control_point_io(&normaliser); + result = shader_normaliser_normalise_hull_shader_control_point_io(&normaliser, + &parser->shader_desc.input_signature); instructions = &normaliser.instructions;
if (result >= 0 && TRACE_ON()) diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h index 37231446..3cd586e5 100644 --- a/libs/vkd3d-shader/vkd3d_shader_private.h +++ b/libs/vkd3d-shader/vkd3d_shader_private.h @@ -1202,6 +1202,14 @@ static inline enum vkd3d_data_type vkd3d_data_type_from_component_type( } }
+enum vkd3d_shader_input_sysval_semantic vkd3d_siv_from_sysval_indexed(enum vkd3d_shader_sysval_semantic sysval, + unsigned int index); + +static inline enum vkd3d_shader_input_sysval_semantic vkd3d_siv_from_sysval(enum vkd3d_shader_sysval_semantic sysval) +{ + return vkd3d_siv_from_sysval_indexed(sysval, 0); +} + static inline unsigned int vkd3d_write_mask_get_component_idx(DWORD write_mask) { unsigned int i; @@ -1340,7 +1348,8 @@ struct vkd3d_shader_normaliser void shader_normaliser_init(struct vkd3d_shader_normaliser *normaliser, struct vkd3d_shader_instruction_array *instructions); enum vkd3d_result shader_normaliser_flatten_hull_shader_phases(struct vkd3d_shader_normaliser *normaliser); -enum vkd3d_result shader_normaliser_normalise_hull_shader_control_point_io(struct vkd3d_shader_normaliser *normaliser); +enum vkd3d_result shader_normaliser_normalise_hull_shader_control_point_io(struct vkd3d_shader_normaliser *normaliser, + const struct vkd3d_shader_signature *input_signature); void shader_normaliser_destroy(struct vkd3d_shader_normaliser *normaliser);
#endif /* __VKD3D_SHADER_PRIVATE_H */