vkd3d-shader/ir: Introduce struct vsir_program.

This commit is contained in:
Henri Verbeet 2024-01-16 14:47:34 +01:00 committed by Alexandre Julliard
parent 55c7cd5c22
commit fc9043be3c
Notes: Alexandre Julliard 2024-01-22 22:53:09 +01:00
Approved-by: Alexandre Julliard (@julliard)
Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/585
8 changed files with 75 additions and 58 deletions

View File

@ -883,7 +883,7 @@ static void shader_sm1_destroy(struct vkd3d_shader_parser *parser)
{
struct vkd3d_shader_sm1_parser *sm1 = vkd3d_shader_sm1_parser(parser);
shader_instruction_array_destroy(&parser->instructions);
vsir_program_cleanup(&parser->program);
free_shader_desc(&sm1->p.shader_desc);
vkd3d_free(sm1);
}
@ -1334,7 +1334,7 @@ int vkd3d_shader_sm1_parser_create(const struct vkd3d_shader_compile_info *compi
return ret;
}
instructions = &sm1->p.instructions;
instructions = &sm1->p.program.instructions;
while (!shader_sm1_is_end(sm1))
{
if (!shader_instruction_array_reserve(instructions, instructions->count + 1))

View File

@ -2572,7 +2572,7 @@ static enum vkd3d_result value_allocate_constant_array(struct sm6_value *dst, co
"Out of memory allocating an immediate constant buffer of count %u.", count);
return VKD3D_ERROR_OUT_OF_MEMORY;
}
if (!shader_instruction_array_add_icb(&sm6->p.instructions, icb))
if (!shader_instruction_array_add_icb(&sm6->p.program.instructions, icb))
{
ERR("Failed to store icb object.\n");
vkd3d_free(icb);
@ -2768,12 +2768,12 @@ static bool bitcode_parse_alignment(uint64_t encoded_alignment, unsigned int *al
static struct vkd3d_shader_instruction *sm6_parser_require_space(struct sm6_parser *sm6, size_t extra)
{
if (!shader_instruction_array_reserve(&sm6->p.instructions, sm6->p.instructions.count + extra))
if (!shader_instruction_array_reserve(&sm6->p.program.instructions, sm6->p.program.instructions.count + extra))
{
ERR("Failed to allocate instruction.\n");
return NULL;
}
return &sm6->p.instructions.elements[sm6->p.instructions.count];
return &sm6->p.program.instructions.elements[sm6->p.program.instructions.count];
}
/* Space should be reserved before calling this. It is intended to require no checking of the returned pointer. */
@ -2783,7 +2783,7 @@ static struct vkd3d_shader_instruction *sm6_parser_add_instruction(struct sm6_pa
struct vkd3d_shader_instruction *ins = sm6_parser_require_space(sm6, 1);
assert(ins);
vsir_instruction_init(ins, &sm6->p.location, handler_idx);
++sm6->p.instructions.count;
++sm6->p.program.instructions.count;
return ins;
}
@ -3046,9 +3046,9 @@ static enum vkd3d_result sm6_parser_globals_init(struct sm6_parser *sm6)
}
/* Resolve initialiser forward references. */
for (i = 0; i < sm6->p.instructions.count; ++i)
for (i = 0; i < sm6->p.program.instructions.count; ++i)
{
ins = &sm6->p.instructions.elements[i];
ins = &sm6->p.program.instructions.elements[i];
if (ins->handler_idx == VKD3DSIH_DCL_INDEXABLE_TEMP && ins->declaration.indexable_temp.initialiser)
{
ins->declaration.indexable_temp.initialiser = resolve_forward_initialiser(
@ -5505,9 +5505,9 @@ static enum vkd3d_result sm6_function_emit_blocks(const struct sm6_function *fun
sm6_parser_emit_label(sm6, block->id);
sm6_block_emit_phi(block, sm6);
memcpy(&sm6->p.instructions.elements[sm6->p.instructions.count], block->instructions,
memcpy(&sm6->p.program.instructions.elements[sm6->p.program.instructions.count], block->instructions,
block->instruction_count * sizeof(*block->instructions));
sm6->p.instructions.count += block->instruction_count;
sm6->p.program.instructions.count += block->instruction_count;
sm6_block_emit_terminator(block, sm6);
}
@ -6289,7 +6289,7 @@ static enum vkd3d_result sm6_parser_descriptor_type_init(struct sm6_parser *sm6,
}
++sm6->descriptor_count;
++sm6->p.instructions.count;
++sm6->p.program.instructions.count;
}
return VKD3D_OK;
@ -6896,7 +6896,7 @@ static void sm6_parser_destroy(struct vkd3d_shader_parser *parser)
dxil_block_destroy(&sm6->root_block);
dxil_global_abbrevs_cleanup(sm6->abbrevs, sm6->abbrev_count);
shader_instruction_array_destroy(&parser->instructions);
vsir_program_cleanup(&parser->program);
sm6_type_table_cleanup(sm6->types, sm6->type_count);
sm6_symtab_cleanup(sm6->global_symbols, sm6->global_symbol_count);
sm6_functions_cleanup(sm6->functions, sm6->function_count);

View File

@ -91,7 +91,7 @@ static void vkd3d_glsl_handle_instruction(struct vkd3d_glsl_generator *generator
}
int vkd3d_glsl_generator_generate(struct vkd3d_glsl_generator *generator,
struct vkd3d_shader_parser *parser, struct vkd3d_shader_code *out)
struct vsir_program *program, struct vkd3d_shader_code *out)
{
unsigned int i;
void *code;
@ -100,10 +100,10 @@ int vkd3d_glsl_generator_generate(struct vkd3d_glsl_generator *generator,
vkd3d_string_buffer_printf(&generator->buffer, "void main()\n{\n");
generator->location.column = 0;
for (i = 0; i < parser->instructions.count; ++i)
for (i = 0; i < program->instructions.count; ++i)
{
generator->location.line = i + 1;
vkd3d_glsl_handle_instruction(generator, &parser->instructions.elements[i]);
vkd3d_glsl_handle_instruction(generator, &program->instructions.elements[i]);
}
if (generator->failed)

View File

@ -18,6 +18,16 @@
#include "vkd3d_shader_private.h"
bool vsir_program_init(struct vsir_program *program, unsigned int reserve)
{
return shader_instruction_array_init(&program->instructions, reserve);
}
void vsir_program_cleanup(struct vsir_program *program)
{
shader_instruction_array_destroy(&program->instructions);
}
static inline bool shader_register_is_phase_instance_id(const struct vkd3d_shader_register *reg)
{
return reg->type == VKD3DSPR_FORKINSTID || reg->type == VKD3DSPR_JOININSTID;
@ -1229,7 +1239,7 @@ static void shader_instruction_normalise_io_params(struct vkd3d_shader_instructi
static enum vkd3d_result shader_normalise_io_registers(struct vkd3d_shader_parser *parser)
{
struct io_normaliser normaliser = {parser->instructions};
struct io_normaliser normaliser = {parser->program.instructions};
struct vkd3d_shader_instruction *ins;
bool has_control_point_phase;
unsigned int i, j;
@ -1241,9 +1251,9 @@ static enum vkd3d_result shader_normalise_io_registers(struct vkd3d_shader_parse
normaliser.output_signature = &parser->shader_desc.output_signature;
normaliser.patch_constant_signature = &parser->shader_desc.patch_constant_signature;
for (i = 0, has_control_point_phase = false; i < parser->instructions.count; ++i)
for (i = 0, has_control_point_phase = false; i < parser->program.instructions.count; ++i)
{
ins = &parser->instructions.elements[i];
ins = &parser->program.instructions.elements[i];
switch (ins->handler_idx)
{
@ -1286,7 +1296,7 @@ static enum vkd3d_result shader_normalise_io_registers(struct vkd3d_shader_parse
|| !shader_signature_merge(&parser->shader_desc.output_signature, normaliser.output_range_map, false)
|| !shader_signature_merge(&parser->shader_desc.patch_constant_signature, normaliser.pc_range_map, true))
{
parser->instructions = normaliser.instructions;
parser->program.instructions = normaliser.instructions;
return VKD3D_ERROR_OUT_OF_MEMORY;
}
@ -1294,7 +1304,7 @@ static enum vkd3d_result shader_normalise_io_registers(struct vkd3d_shader_parse
for (i = 0; i < normaliser.instructions.count; ++i)
shader_instruction_normalise_io_params(&normaliser.instructions.elements[i], &normaliser);
parser->instructions = normaliser.instructions;
parser->program.instructions = normaliser.instructions;
parser->shader_desc.use_vocp = normaliser.use_vocp;
return VKD3D_OK;
}
@ -1308,7 +1318,6 @@ struct flat_constant_def
struct flat_constants_normaliser
{
struct vkd3d_shader_parser *parser;
struct flat_constant_def *defs;
size_t def_count, defs_capacity;
};
@ -1383,14 +1392,14 @@ static void shader_register_normalise_flat_constants(struct vkd3d_shader_src_par
param->reg.idx_count = 3;
}
static enum vkd3d_result instruction_array_normalise_flat_constants(struct vkd3d_shader_parser *parser)
static enum vkd3d_result instruction_array_normalise_flat_constants(struct vsir_program *program)
{
struct flat_constants_normaliser normaliser = {.parser = parser};
struct flat_constants_normaliser normaliser = {0};
unsigned int i, j;
for (i = 0; i < parser->instructions.count; ++i)
for (i = 0; i < program->instructions.count; ++i)
{
struct vkd3d_shader_instruction *ins = &parser->instructions.elements[i];
struct vkd3d_shader_instruction *ins = &program->instructions.elements[i];
if (ins->handler_idx == VKD3DSIH_DEF || ins->handler_idx == VKD3DSIH_DEFI || ins->handler_idx == VKD3DSIH_DEFB)
{
@ -1422,14 +1431,14 @@ static enum vkd3d_result instruction_array_normalise_flat_constants(struct vkd3d
return VKD3D_OK;
}
static void remove_dead_code(struct vkd3d_shader_parser *parser)
static void remove_dead_code(struct vsir_program *program)
{
size_t i, depth = 0;
bool dead = false;
for (i = 0; i < parser->instructions.count; ++i)
for (i = 0; i < program->instructions.count; ++i)
{
struct vkd3d_shader_instruction *ins = &parser->instructions.elements[i];
struct vkd3d_shader_instruction *ins = &program->instructions.elements[i];
switch (ins->handler_idx)
{
@ -1516,15 +1525,15 @@ static enum vkd3d_result normalise_combined_samplers(struct vkd3d_shader_parser
{
unsigned int i;
for (i = 0; i < parser->instructions.count; ++i)
for (i = 0; i < parser->program.instructions.count; ++i)
{
struct vkd3d_shader_instruction *ins = &parser->instructions.elements[i];
struct vkd3d_shader_instruction *ins = &parser->program.instructions.elements[i];
struct vkd3d_shader_src_param *srcs;
switch (ins->handler_idx)
{
case VKD3DSIH_TEX:
if (!(srcs = shader_src_param_allocator_get(&parser->instructions.src_params, 3)))
if (!(srcs = shader_src_param_allocator_get(&parser->program.instructions.src_params, 3)))
return VKD3D_ERROR_OUT_OF_MEMORY;
memset(srcs, 0, sizeof(*srcs) * 3);
@ -1872,7 +1881,7 @@ static enum vkd3d_result cf_flattener_iterate_instruction_array(struct cf_flatte
struct vkd3d_shader_instruction *dst_ins;
size_t i;
instructions = &parser->instructions;
instructions = &parser->program.instructions;
is_hull_shader = parser->shader_version.type == VKD3D_SHADER_TYPE_HULL;
main_block_open = !is_hull_shader;
after_declarations_section = is_hull_shader;
@ -2220,10 +2229,10 @@ static enum vkd3d_result flatten_control_flow_constructs(struct vkd3d_shader_par
if (result >= 0)
{
vkd3d_free(parser->instructions.elements);
parser->instructions.elements = flattener.instructions;
parser->instructions.capacity = flattener.instruction_capacity;
parser->instructions.count = flattener.instruction_count;
vkd3d_free(parser->program.instructions.elements);
parser->program.instructions.elements = flattener.instructions;
parser->program.instructions.capacity = flattener.instruction_capacity;
parser->program.instructions.count = flattener.instruction_count;
parser->shader_desc.block_count = flattener.block_id;
}
else
@ -2242,7 +2251,7 @@ static enum vkd3d_result flatten_control_flow_constructs(struct vkd3d_shader_par
enum vkd3d_result vkd3d_shader_normalise(struct vkd3d_shader_parser *parser,
const struct vkd3d_shader_compile_info *compile_info)
{
struct vkd3d_shader_instruction_array *instructions = &parser->instructions;
struct vkd3d_shader_instruction_array *instructions = &parser->program.instructions;
enum vkd3d_result result = VKD3D_OK;
if (parser->shader_desc.is_dxil)
@ -2262,10 +2271,10 @@ enum vkd3d_result vkd3d_shader_normalise(struct vkd3d_shader_parser *parser,
result = shader_normalise_io_registers(parser);
if (result >= 0)
result = instruction_array_normalise_flat_constants(parser);
result = instruction_array_normalise_flat_constants(&parser->program);
if (result >= 0)
remove_dead_code(parser);
remove_dead_code(&parser->program);
if (result >= 0)
result = flatten_control_flow_constructs(parser);
@ -2703,9 +2712,10 @@ static void vsir_validate_cf_type(struct validation_context *ctx,
static void vsir_validate_instruction(struct validation_context *ctx)
{
const struct vkd3d_shader_instruction *instruction = &ctx->parser->instructions.elements[ctx->instruction_idx];
const struct vkd3d_shader_instruction *instruction;
size_t i;
instruction = &ctx->parser->program.instructions.elements[ctx->instruction_idx];
ctx->parser->location = instruction->location;
for (i = 0; i < instruction->dst_count; ++i)
@ -2994,7 +3004,7 @@ enum vkd3d_result vsir_validate(struct vkd3d_shader_parser *parser)
if (!(ctx.ssas = vkd3d_calloc(parser->shader_desc.ssa_count, sizeof(*ctx.ssas))))
goto fail;
for (ctx.instruction_idx = 0; ctx.instruction_idx < parser->instructions.count; ++ctx.instruction_idx)
for (ctx.instruction_idx = 0; ctx.instruction_idx < parser->program.instructions.count; ++ctx.instruction_idx)
vsir_validate_instruction(&ctx);
ctx.invalid_instruction_idx = true;

View File

@ -9699,8 +9699,8 @@ static int spirv_compiler_generate_spirv(struct spirv_compiler *compiler,
if (parser->shader_desc.block_count && !spirv_compiler_init_blocks(compiler, parser->shader_desc.block_count))
return VKD3D_ERROR_OUT_OF_MEMORY;
instructions = parser->instructions;
memset(&parser->instructions, 0, sizeof(parser->instructions));
instructions = parser->program.instructions;
memset(&parser->program.instructions, 0, sizeof(parser->program.instructions));
compiler->input_signature = shader_desc->input_signature;
compiler->output_signature = shader_desc->output_signature;

View File

@ -796,7 +796,7 @@ static void shader_sm4_read_shader_data(struct vkd3d_shader_instruction *ins, ui
icb->element_count = icb_size / VKD3D_VEC4_SIZE;
icb->is_null = false;
memcpy(icb->data, tokens, sizeof(*tokens) * icb_size);
shader_instruction_array_add_icb(&priv->p.instructions, icb);
shader_instruction_array_add_icb(&priv->p.program.instructions, icb);
ins->declaration.icb = icb;
}
@ -1732,7 +1732,7 @@ static void shader_sm4_destroy(struct vkd3d_shader_parser *parser)
{
struct vkd3d_shader_sm4_parser *sm4 = vkd3d_shader_sm4_parser(parser);
shader_instruction_array_destroy(&parser->instructions);
vsir_program_cleanup(&parser->program);
free_shader_desc(&parser->shader_desc);
vkd3d_free(sm4);
}
@ -2676,7 +2676,7 @@ int vkd3d_shader_sm4_parser_create(const struct vkd3d_shader_compile_info *compi
return VKD3D_ERROR_INVALID_SHADER;
}
instructions = &sm4->p.instructions;
instructions = &sm4->p.program.instructions;
while (sm4->ptr != sm4->end)
{
if (!shader_instruction_array_reserve(instructions, instructions->count + 1))

View File

@ -542,7 +542,7 @@ bool vkd3d_shader_parser_init(struct vkd3d_shader_parser *parser,
parser->shader_version = *version;
parser->ops = ops;
parser->config_flags = vkd3d_shader_init_config_flags();
return shader_instruction_array_init(&parser->instructions, instruction_reserve);
return vsir_program_init(&parser->program, instruction_reserve);
}
void VKD3D_PRINTF_FUNC(3, 4) vkd3d_shader_parser_error(struct vkd3d_shader_parser *parser,
@ -1406,13 +1406,11 @@ static int scan_with_parser(const struct vkd3d_shader_compile_info *compile_info
descriptor_info1, combined_sampler_info, message_context);
if (TRACE_ON())
{
vkd3d_shader_trace(&parser->instructions, &parser->shader_version);
}
vkd3d_shader_trace(&parser->program.instructions, &parser->shader_version);
for (i = 0; i < parser->instructions.count; ++i)
for (i = 0; i < parser->program.instructions.count; ++i)
{
instruction = &parser->instructions.elements[i];
instruction = &parser->program.instructions.elements[i];
if ((ret = vkd3d_shader_scan_instruction(&context, instruction)) < 0)
break;
}
@ -1585,7 +1583,8 @@ static int vkd3d_shader_parser_compile(struct vkd3d_shader_parser *parser,
switch (compile_info->target_type)
{
case VKD3D_SHADER_TARGET_D3D_ASM:
ret = vkd3d_dxbc_binary_to_text(&parser->instructions, &parser->shader_version, compile_info, out, VSIR_ASM_D3D);
ret = vkd3d_dxbc_binary_to_text(&parser->program.instructions,
&parser->shader_version, compile_info, out, VSIR_ASM_D3D);
break;
case VKD3D_SHADER_TARGET_GLSL:
@ -1599,7 +1598,7 @@ static int vkd3d_shader_parser_compile(struct vkd3d_shader_parser *parser,
return VKD3D_ERROR;
}
ret = vkd3d_glsl_generator_generate(glsl_generator, parser, out);
ret = vkd3d_glsl_generator_generate(glsl_generator, &parser->program, out);
vkd3d_glsl_generator_destroy(glsl_generator);
vkd3d_shader_free_scan_descriptor_info1(&scan_descriptor_info);
break;

View File

@ -1270,6 +1270,14 @@ enum vkd3d_shader_config_flags
VKD3D_SHADER_CONFIG_FLAG_FORCE_VALIDATION = 0x00000001,
};
struct vsir_program
{
struct vkd3d_shader_instruction_array instructions;
};
bool vsir_program_init(struct vsir_program *program, unsigned int reserve);
void vsir_program_cleanup(struct vsir_program *program);
struct vkd3d_shader_parser
{
struct vkd3d_shader_message_context *message_context;
@ -1279,7 +1287,7 @@ struct vkd3d_shader_parser
struct vkd3d_shader_desc shader_desc;
struct vkd3d_shader_version shader_version;
const struct vkd3d_shader_parser_ops *ops;
struct vkd3d_shader_instruction_array instructions;
struct vsir_program program;
uint64_t config_flags;
};
@ -1301,13 +1309,13 @@ void vkd3d_shader_parser_warning(struct vkd3d_shader_parser *parser,
static inline struct vkd3d_shader_dst_param *shader_parser_get_dst_params(
struct vkd3d_shader_parser *parser, unsigned int count)
{
return shader_dst_param_allocator_get(&parser->instructions.dst_params, count);
return shader_dst_param_allocator_get(&parser->program.instructions.dst_params, count);
}
static inline struct vkd3d_shader_src_param *shader_parser_get_src_params(
struct vkd3d_shader_parser *parser, unsigned int count)
{
return shader_src_param_allocator_get(&parser->instructions.src_params, count);
return shader_src_param_allocator_get(&parser->program.instructions.src_params, count);
}
static inline void vkd3d_shader_parser_destroy(struct vkd3d_shader_parser *parser)
@ -1461,7 +1469,7 @@ struct vkd3d_glsl_generator;
struct vkd3d_glsl_generator *vkd3d_glsl_generator_create(const struct vkd3d_shader_version *version,
struct vkd3d_shader_message_context *message_context, const struct vkd3d_shader_location *location);
int vkd3d_glsl_generator_generate(struct vkd3d_glsl_generator *generator,
struct vkd3d_shader_parser *parser, struct vkd3d_shader_code *out);
struct vsir_program *program, struct vkd3d_shader_code *out);
void vkd3d_glsl_generator_destroy(struct vkd3d_glsl_generator *generator);
#define SPIRV_MAX_SRC_COUNT 6