mirror of
https://gitlab.winehq.org/wine/vkd3d.git
synced 2024-11-21 16:46:41 -08:00
vkd3d-shader/ir: Include an initial label instruction in the first control flow block.
This commit is contained in:
parent
d402804851
commit
559d9d4ee0
Notes:
Alexandre Julliard
2024-01-17 22:42:55 +01:00
Approved-by: Giovanni Mascellani (@giomasce) Approved-by: Henri Verbeet (@hverbeet) Approved-by: Alexandre Julliard (@julliard) Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/450
@ -4869,6 +4869,18 @@ static enum vkd3d_result sm6_parser_module_init(struct sm6_parser *sm6, const st
|
||||
return VKD3D_OK;
|
||||
}
|
||||
|
||||
static void sm6_parser_emit_label(struct sm6_parser *sm6, unsigned int label_id)
|
||||
{
|
||||
struct vkd3d_shader_src_param *src_param;
|
||||
struct vkd3d_shader_instruction *ins;
|
||||
|
||||
ins = sm6_parser_add_instruction(sm6, VKD3DSIH_LABEL);
|
||||
|
||||
if (!(src_param = instruction_src_params_alloc(ins, 1, sm6)))
|
||||
return;
|
||||
vsir_src_param_init_label(src_param, label_id);
|
||||
}
|
||||
|
||||
static bool sm6_parser_allocate_named_metadata(struct sm6_parser *sm6)
|
||||
{
|
||||
struct dxil_block *block;
|
||||
@ -6217,6 +6229,7 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, const uint32_t
|
||||
}
|
||||
|
||||
sm6->p.shader_desc.ssa_count = sm6->ssa_next_id;
|
||||
sm6->p.shader_desc.block_count = 1;
|
||||
|
||||
if (!(fn = sm6_parser_get_function(sm6, sm6->entry_point)))
|
||||
{
|
||||
@ -6227,6 +6240,7 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, const uint32_t
|
||||
}
|
||||
|
||||
assert(sm6->function_count == 1);
|
||||
sm6_parser_emit_label(sm6, 1);
|
||||
if (!sm6_block_emit_instructions(fn->blocks[0], sm6))
|
||||
{
|
||||
vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY,
|
||||
|
@ -320,7 +320,7 @@ static void vsir_src_param_init(struct vkd3d_shader_src_param *param, enum vkd3d
|
||||
param->modifiers = VKD3DSPSM_NONE;
|
||||
}
|
||||
|
||||
static void vsir_src_param_init_label(struct vkd3d_shader_src_param *param, unsigned int label_id)
|
||||
void vsir_src_param_init_label(struct vkd3d_shader_src_param *param, unsigned int label_id)
|
||||
{
|
||||
vsir_src_param_init(param, VKD3DSPR_LABEL, VKD3D_DATA_UINT, 1);
|
||||
param->reg.dimension = VSIR_DIMENSION_NONE;
|
||||
@ -1785,18 +1785,27 @@ static void VKD3D_PRINTF_FUNC(3, 4) cf_flattener_create_block_name(struct cf_fla
|
||||
flattener->block_names[block_id] = buffer.buffer;
|
||||
}
|
||||
|
||||
static bool vsir_instruction_is_dcl(const struct vkd3d_shader_instruction *instruction)
|
||||
{
|
||||
enum vkd3d_shader_opcode handler_idx = instruction->handler_idx;
|
||||
return (VKD3DSIH_DCL <= handler_idx && handler_idx <= VKD3DSIH_DCL_VERTICES_OUT)
|
||||
|| handler_idx == VKD3DSIH_HS_DECLS;
|
||||
}
|
||||
|
||||
static enum vkd3d_result cf_flattener_iterate_instruction_array(struct cf_flattener *flattener)
|
||||
{
|
||||
bool main_block_open, is_hull_shader, after_declarations_section;
|
||||
struct vkd3d_shader_parser *parser = flattener->parser;
|
||||
struct vkd3d_shader_instruction_array *instructions;
|
||||
struct vkd3d_shader_instruction *dst_ins;
|
||||
bool main_block_open;
|
||||
size_t i;
|
||||
|
||||
instructions = &parser->instructions;
|
||||
main_block_open = parser->shader_version.type != VKD3D_SHADER_TYPE_HULL;
|
||||
is_hull_shader = parser->shader_version.type == VKD3D_SHADER_TYPE_HULL;
|
||||
main_block_open = !is_hull_shader;
|
||||
after_declarations_section = is_hull_shader;
|
||||
|
||||
if (!cf_flattener_require_space(flattener, instructions->count))
|
||||
if (!cf_flattener_require_space(flattener, instructions->count + 1))
|
||||
return VKD3D_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
for (i = 0; i < instructions->count; ++i)
|
||||
@ -1808,11 +1817,29 @@ static enum vkd3d_result cf_flattener_iterate_instruction_array(struct cf_flatte
|
||||
|
||||
flattener->location = instruction->location;
|
||||
|
||||
/* Declarations should occur before the first code block, which in hull shaders is marked by the first
|
||||
* phase instruction, and in all other shader types begins with the first label instruction. */
|
||||
if (!after_declarations_section && !vsir_instruction_is_dcl(instruction)
|
||||
&& instruction->handler_idx != VKD3DSIH_NOP)
|
||||
{
|
||||
after_declarations_section = true;
|
||||
cf_flattener_emit_label(flattener, cf_flattener_alloc_block_id(flattener));
|
||||
}
|
||||
|
||||
cf_info = flattener->control_flow_depth
|
||||
? &flattener->control_flow_info[flattener->control_flow_depth - 1] : NULL;
|
||||
|
||||
switch (instruction->handler_idx)
|
||||
{
|
||||
case VKD3DSIH_HS_CONTROL_POINT_PHASE:
|
||||
case VKD3DSIH_HS_FORK_PHASE:
|
||||
case VKD3DSIH_HS_JOIN_PHASE:
|
||||
if (!cf_flattener_copy_instruction(flattener, instruction))
|
||||
return VKD3D_ERROR_OUT_OF_MEMORY;
|
||||
if (instruction->handler_idx != VKD3DSIH_HS_CONTROL_POINT_PHASE || !instruction->flags)
|
||||
after_declarations_section = false;
|
||||
break;
|
||||
|
||||
case VKD3DSIH_LABEL:
|
||||
vkd3d_shader_parser_error(parser, VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED,
|
||||
"Aborting due to not yet implemented feature: Label instruction.");
|
||||
|
@ -1871,8 +1871,6 @@ static void vkd3d_spirv_builder_begin_main_function(struct vkd3d_spirv_builder *
|
||||
|
||||
vkd3d_spirv_build_op_function(builder, void_id,
|
||||
builder->main_function_id, SpvFunctionControlMaskNone, function_type_id);
|
||||
vkd3d_spirv_build_op_label(builder, vkd3d_spirv_alloc_id(builder));
|
||||
builder->main_function_location = vkd3d_spirv_stream_current_location(&builder->function_stream);
|
||||
}
|
||||
|
||||
static void vkd3d_spirv_builder_free(struct vkd3d_spirv_builder *builder)
|
||||
@ -2314,7 +2312,7 @@ struct spirv_compiler
|
||||
struct vkd3d_push_constant_buffer_binding *push_constants;
|
||||
const struct vkd3d_shader_spirv_target_info *spirv_target_info;
|
||||
|
||||
bool after_declarations_section;
|
||||
bool prolog_emitted;
|
||||
struct shader_signature input_signature;
|
||||
struct shader_signature output_signature;
|
||||
struct shader_signature patch_constant_signature;
|
||||
@ -2381,6 +2379,8 @@ static bool is_in_fork_or_join_phase(const struct spirv_compiler *compiler)
|
||||
|
||||
static void spirv_compiler_emit_initial_declarations(struct spirv_compiler *compiler);
|
||||
static size_t spirv_compiler_get_current_function_location(struct spirv_compiler *compiler);
|
||||
static void spirv_compiler_emit_main_prolog(struct spirv_compiler *compiler);
|
||||
static void spirv_compiler_emit_io_declarations(struct spirv_compiler *compiler);
|
||||
|
||||
static const char *spirv_compiler_get_entry_point_name(const struct spirv_compiler *compiler)
|
||||
{
|
||||
@ -6498,20 +6498,45 @@ static void spirv_compiler_enter_shader_phase(struct spirv_compiler *compiler,
|
||||
vkd3d_spirv_build_op_function(builder, void_id, function_id,
|
||||
SpvFunctionControlMaskNone, function_type_id);
|
||||
|
||||
vkd3d_spirv_build_op_label(builder, vkd3d_spirv_alloc_id(builder));
|
||||
|
||||
compiler->phase = instruction->handler_idx;
|
||||
spirv_compiler_emit_shader_phase_name(compiler, function_id, NULL);
|
||||
|
||||
phase = (instruction->handler_idx == VKD3DSIH_HS_CONTROL_POINT_PHASE)
|
||||
? &compiler->control_point_phase : &compiler->patch_constant_phase;
|
||||
phase->function_id = function_id;
|
||||
phase->function_location = vkd3d_spirv_stream_current_location(&builder->function_stream);
|
||||
/* The insertion location must be set after the label is emitted. */
|
||||
phase->function_location = 0;
|
||||
|
||||
if (instruction->handler_idx == VKD3DSIH_HS_CONTROL_POINT_PHASE)
|
||||
compiler->emit_default_control_point_phase = instruction->flags;
|
||||
}
|
||||
|
||||
static void spirv_compiler_initialise_block(struct spirv_compiler *compiler)
|
||||
{
|
||||
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
|
||||
|
||||
/* Insertion locations must point immediately after the function's initial label. */
|
||||
if (compiler->shader_type == VKD3D_SHADER_TYPE_HULL)
|
||||
{
|
||||
struct vkd3d_shader_phase *phase = (compiler->phase == VKD3DSIH_HS_CONTROL_POINT_PHASE)
|
||||
? &compiler->control_point_phase : &compiler->patch_constant_phase;
|
||||
if (!phase->function_location)
|
||||
phase->function_location = vkd3d_spirv_stream_current_location(&builder->function_stream);
|
||||
}
|
||||
else if (!builder->main_function_location)
|
||||
{
|
||||
builder->main_function_location = vkd3d_spirv_stream_current_location(&builder->function_stream);
|
||||
}
|
||||
|
||||
/* I/O declarations can result in emission of fixups, which must occur after the initial label. */
|
||||
if (!compiler->prolog_emitted)
|
||||
{
|
||||
spirv_compiler_emit_main_prolog(compiler);
|
||||
spirv_compiler_emit_io_declarations(compiler);
|
||||
compiler->prolog_emitted = true;
|
||||
}
|
||||
}
|
||||
|
||||
static void spirv_compiler_emit_default_control_point_phase(struct spirv_compiler *compiler)
|
||||
{
|
||||
const struct shader_signature *output_signature = &compiler->output_signature;
|
||||
@ -6524,6 +6549,8 @@ static void spirv_compiler_emit_default_control_point_phase(struct spirv_compile
|
||||
unsigned int component_count;
|
||||
unsigned int i;
|
||||
|
||||
vkd3d_spirv_build_op_label(builder, vkd3d_spirv_alloc_id(builder));
|
||||
spirv_compiler_initialise_block(compiler);
|
||||
invocation_id = spirv_compiler_emit_load_invocation_id(compiler);
|
||||
|
||||
memset(&invocation, 0, sizeof(invocation));
|
||||
@ -6622,6 +6649,7 @@ static void spirv_compiler_emit_hull_shader_main(struct spirv_compiler *compiler
|
||||
memset(compiler->descriptor_offset_ids, 0, compiler->offset_info.descriptor_table_count
|
||||
* sizeof(*compiler->descriptor_offset_ids));
|
||||
vkd3d_spirv_builder_begin_main_function(builder);
|
||||
vkd3d_spirv_build_op_label(builder, vkd3d_spirv_alloc_id(builder));
|
||||
|
||||
void_id = vkd3d_spirv_get_op_type_void(builder);
|
||||
|
||||
@ -7589,6 +7617,8 @@ static void spirv_compiler_emit_label(struct spirv_compiler *compiler,
|
||||
--block_id;
|
||||
if (block_id < compiler->block_name_count && compiler->block_names[block_id])
|
||||
vkd3d_spirv_build_op_name(builder, label_id, compiler->block_names[block_id]);
|
||||
|
||||
spirv_compiler_initialise_block(compiler);
|
||||
}
|
||||
|
||||
static void spirv_compiler_emit_merge(struct spirv_compiler *compiler,
|
||||
@ -9228,23 +9258,11 @@ static void spirv_compiler_emit_main_prolog(struct spirv_compiler *compiler)
|
||||
spirv_compiler_emit_point_size(compiler);
|
||||
}
|
||||
|
||||
static bool is_dcl_instruction(enum vkd3d_shader_opcode handler_idx)
|
||||
{
|
||||
return (VKD3DSIH_DCL <= handler_idx && handler_idx <= VKD3DSIH_DCL_VERTICES_OUT)
|
||||
|| handler_idx == VKD3DSIH_HS_DECLS;
|
||||
}
|
||||
|
||||
static int spirv_compiler_handle_instruction(struct spirv_compiler *compiler,
|
||||
const struct vkd3d_shader_instruction *instruction)
|
||||
{
|
||||
int ret = VKD3D_OK;
|
||||
|
||||
if (!is_dcl_instruction(instruction->handler_idx) && !compiler->after_declarations_section)
|
||||
{
|
||||
compiler->after_declarations_section = true;
|
||||
spirv_compiler_emit_main_prolog(compiler);
|
||||
}
|
||||
|
||||
switch (instruction->handler_idx)
|
||||
{
|
||||
case VKD3DSIH_DCL_GLOBAL_FLAGS:
|
||||
@ -9692,8 +9710,6 @@ static int spirv_compiler_generate_spirv(struct spirv_compiler *compiler,
|
||||
if (compiler->shader_type != VKD3D_SHADER_TYPE_HULL)
|
||||
spirv_compiler_emit_shader_signature_outputs(compiler);
|
||||
|
||||
spirv_compiler_emit_io_declarations(compiler);
|
||||
|
||||
for (i = 0; i < instructions.count && result >= 0; ++i)
|
||||
{
|
||||
compiler->location.line = i + 1;
|
||||
|
@ -1117,8 +1117,7 @@ static void shader_sm4_read_dcl_indexable_temp(struct vkd3d_shader_instruction *
|
||||
ins->declaration.indexable_temp.alignment = 0;
|
||||
ins->declaration.indexable_temp.data_type = VKD3D_DATA_FLOAT;
|
||||
ins->declaration.indexable_temp.component_count = *tokens;
|
||||
/* Indexable temp declarations are global, but except for hull shaders the backend currently emits them within a function. */
|
||||
ins->declaration.indexable_temp.has_function_scope = priv->p.shader_version.type != VKD3D_SHADER_TYPE_HULL;
|
||||
ins->declaration.indexable_temp.has_function_scope = false;
|
||||
}
|
||||
|
||||
static void shader_sm4_read_dcl_global_flags(struct vkd3d_shader_instruction *ins, uint32_t opcode,
|
||||
|
@ -886,6 +886,8 @@ struct vkd3d_shader_src_param
|
||||
enum vkd3d_shader_src_modifier modifiers;
|
||||
};
|
||||
|
||||
void vsir_src_param_init_label(struct vkd3d_shader_src_param *param, unsigned int label_id);
|
||||
|
||||
struct vkd3d_shader_index_range
|
||||
{
|
||||
struct vkd3d_shader_dst_param dst;
|
||||
|
Loading…
Reference in New Issue
Block a user