vkd3d-shader/dxil: Parse the shader into a vsir program in vkd3d_shader_sm6_parser_create().

This commit is contained in:
Henri Verbeet 2024-05-16 11:42:29 +02:00 committed by Alexandre Julliard
parent 6474e8cc7b
commit ce6f8a6a30
Notes: Alexandre Julliard 2024-05-16 23:13:19 +02: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/869
5 changed files with 61 additions and 126 deletions

View File

@ -880,10 +880,6 @@ static void shader_sm1_skip_opcode(const struct vkd3d_shader_sm1_parser *sm1, co
*ptr += (opcode_info->dst_count + opcode_info->src_count); *ptr += (opcode_info->dst_count + opcode_info->src_count);
} }
static void shader_sm1_destroy(struct vkd3d_shader_parser *parser)
{
}
static void shader_sm1_read_src_param(struct vkd3d_shader_sm1_parser *sm1, const uint32_t **ptr, static void shader_sm1_read_src_param(struct vkd3d_shader_sm1_parser *sm1, const uint32_t **ptr,
struct vkd3d_shader_src_param *src_param) struct vkd3d_shader_src_param *src_param)
{ {
@ -1220,11 +1216,6 @@ static bool shader_sm1_is_end(struct vkd3d_shader_sm1_parser *sm1)
return false; return false;
} }
const struct vkd3d_shader_parser_ops shader_sm1_parser_ops =
{
.parser_destroy = shader_sm1_destroy,
};
static enum vkd3d_result shader_sm1_init(struct vkd3d_shader_sm1_parser *sm1, struct vsir_program *program, static enum vkd3d_result shader_sm1_init(struct vkd3d_shader_sm1_parser *sm1, struct vsir_program *program,
const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_message_context *message_context) const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_message_context *message_context)
{ {
@ -1283,7 +1274,7 @@ static enum vkd3d_result shader_sm1_init(struct vkd3d_shader_sm1_parser *sm1, st
if (!vsir_program_init(program, &version, code_size != ~(size_t)0 ? token_count / 4u + 4 : 16)) if (!vsir_program_init(program, &version, code_size != ~(size_t)0 ? token_count / 4u + 4 : 16))
return VKD3D_ERROR_OUT_OF_MEMORY; return VKD3D_ERROR_OUT_OF_MEMORY;
vkd3d_shader_parser_init(&sm1->p, program, message_context, compile_info->source_name, &shader_sm1_parser_ops); vkd3d_shader_parser_init(&sm1->p, program, message_context, compile_info->source_name);
sm1->ptr = sm1->start; sm1->ptr = sm1->start;
return VKD3D_OK; return VKD3D_OK;

View File

@ -909,11 +909,6 @@ static size_t size_add_with_overflow_check(size_t a, size_t b)
return (i < a) ? SIZE_MAX : i; return (i < a) ? SIZE_MAX : i;
} }
static struct sm6_parser *sm6_parser(struct vkd3d_shader_parser *parser)
{
return CONTAINING_RECORD(parser, struct sm6_parser, p);
}
static bool sm6_parser_is_end(struct sm6_parser *sm6) static bool sm6_parser_is_end(struct sm6_parser *sm6)
{ {
return sm6->ptr == sm6->end; return sm6->ptr == sm6->end;
@ -10124,28 +10119,18 @@ static void sm6_functions_cleanup(struct sm6_function *functions, size_t count)
vkd3d_free(functions); vkd3d_free(functions);
} }
static void sm6_parser_destroy(struct vkd3d_shader_parser *parser) static void sm6_parser_cleanup(struct sm6_parser *sm6)
{ {
struct sm6_parser *sm6 = sm6_parser(parser);
dxil_block_destroy(&sm6->root_block); dxil_block_destroy(&sm6->root_block);
dxil_global_abbrevs_cleanup(sm6->abbrevs, sm6->abbrev_count); dxil_global_abbrevs_cleanup(sm6->abbrevs, sm6->abbrev_count);
vsir_program_cleanup(parser->program);
vkd3d_free(parser->program);
sm6_type_table_cleanup(sm6->types, sm6->type_count); sm6_type_table_cleanup(sm6->types, sm6->type_count);
sm6_symtab_cleanup(sm6->global_symbols, sm6->global_symbol_count); sm6_symtab_cleanup(sm6->global_symbols, sm6->global_symbol_count);
sm6_functions_cleanup(sm6->functions, sm6->function_count); sm6_functions_cleanup(sm6->functions, sm6->function_count);
sm6_parser_metadata_cleanup(sm6); sm6_parser_metadata_cleanup(sm6);
vkd3d_free(sm6->descriptors); vkd3d_free(sm6->descriptors);
vkd3d_free(sm6->values); vkd3d_free(sm6->values);
vkd3d_free(sm6);
} }
static const struct vkd3d_shader_parser_ops sm6_parser_ops =
{
.parser_destroy = sm6_parser_destroy,
};
static struct sm6_function *sm6_parser_get_function(const struct sm6_parser *sm6, const char *name) static struct sm6_function *sm6_parser_get_function(const struct sm6_parser *sm6, const char *name)
{ {
size_t i; size_t i;
@ -10155,7 +10140,7 @@ static struct sm6_function *sm6_parser_get_function(const struct sm6_parser *sm6
return NULL; return NULL;
} }
static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, const char *source_name, static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, struct vsir_program *program, const char *source_name,
struct vkd3d_shader_message_context *message_context, struct dxbc_shader_desc *dxbc_desc) struct vkd3d_shader_message_context *message_context, struct dxbc_shader_desc *dxbc_desc)
{ {
size_t count, length, function_count, expected_function_count, byte_code_size = dxbc_desc->byte_code_size; size_t count, length, function_count, expected_function_count, byte_code_size = dxbc_desc->byte_code_size;
@ -10166,7 +10151,6 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, const char *sou
unsigned int chunk_offset, chunk_size; unsigned int chunk_offset, chunk_size;
enum bitcode_block_abbreviation abbr; enum bitcode_block_abbreviation abbr;
struct vkd3d_shader_version version; struct vkd3d_shader_version version;
struct vsir_program *program;
struct dxil_block *block; struct dxil_block *block;
struct sm6_function *fn; struct sm6_function *fn;
enum vkd3d_result ret; enum vkd3d_result ret;
@ -10250,16 +10234,11 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, const char *sou
return VKD3D_ERROR_INVALID_SHADER; return VKD3D_ERROR_INVALID_SHADER;
} }
if (!(program = vkd3d_malloc(sizeof(*program))))
return VKD3D_ERROR_OUT_OF_MEMORY;
/* Estimate instruction count to avoid reallocation in most shaders. */ /* Estimate instruction count to avoid reallocation in most shaders. */
count = max(token_count, 400) - 400; count = max(token_count, 400) - 400;
if (!vsir_program_init(program, &version, (count + (count >> 2)) / 2u + 10)) if (!vsir_program_init(program, &version, (count + (count >> 2)) / 2u + 10))
{
vkd3d_free(program);
return VKD3D_ERROR_OUT_OF_MEMORY; return VKD3D_ERROR_OUT_OF_MEMORY;
} vkd3d_shader_parser_init(&sm6->p, program, message_context, source_name);
vkd3d_shader_parser_init(&sm6->p, program, message_context, source_name, &sm6_parser_ops);
sm6->ptr = &sm6->start[1]; sm6->ptr = &sm6->start[1];
sm6->bitpos = 2; sm6->bitpos = 2;
@ -10282,7 +10261,7 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, const char *sou
"DXIL bitcode chunk has invalid bitcode."); "DXIL bitcode chunk has invalid bitcode.");
else else
vkd3d_unreachable(); vkd3d_unreachable();
return ret; goto fail;
} }
dxil_global_abbrevs_cleanup(sm6->abbrevs, sm6->abbrev_count); dxil_global_abbrevs_cleanup(sm6->abbrevs, sm6->abbrev_count);
@ -10315,7 +10294,7 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, const char *sou
"DXIL type table is invalid."); "DXIL type table is invalid.");
else else
vkd3d_unreachable(); vkd3d_unreachable();
return ret; goto fail;
} }
if ((ret = sm6_parser_symtab_init(sm6)) < 0) if ((ret = sm6_parser_symtab_init(sm6)) < 0)
@ -10328,7 +10307,7 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, const char *sou
"DXIL value symbol table is invalid."); "DXIL value symbol table is invalid.");
else else
vkd3d_unreachable(); vkd3d_unreachable();
return ret; goto fail;
} }
if (!(sm6->output_params = vsir_program_get_dst_params(program, output_signature->element_count)) if (!(sm6->output_params = vsir_program_get_dst_params(program, output_signature->element_count))
@ -10339,7 +10318,8 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, const char *sou
ERR("Failed to allocate input/output parameters.\n"); ERR("Failed to allocate input/output parameters.\n");
vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY, vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY,
"Out of memory allocating input/output parameters."); "Out of memory allocating input/output parameters.");
return VKD3D_ERROR_OUT_OF_MEMORY; ret = VKD3D_ERROR_OUT_OF_MEMORY;
goto fail;
} }
function_count = dxil_block_compute_function_count(&sm6->root_block); function_count = dxil_block_compute_function_count(&sm6->root_block);
@ -10348,7 +10328,8 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, const char *sou
ERR("Failed to allocate function array.\n"); ERR("Failed to allocate function array.\n");
vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY, vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY,
"Out of memory allocating DXIL function array."); "Out of memory allocating DXIL function array.");
return VKD3D_ERROR_OUT_OF_MEMORY; ret = VKD3D_ERROR_OUT_OF_MEMORY;
goto fail;
} }
if (sm6_parser_compute_max_value_count(sm6, &sm6->root_block, 0) == SIZE_MAX) if (sm6_parser_compute_max_value_count(sm6, &sm6->root_block, 0) == SIZE_MAX)
@ -10356,14 +10337,16 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, const char *sou
WARN("Value array count overflowed.\n"); WARN("Value array count overflowed.\n");
vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_MODULE, vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_MODULE,
"Overflow occurred in the DXIL module value count."); "Overflow occurred in the DXIL module value count.");
return VKD3D_ERROR_INVALID_SHADER; ret = VKD3D_ERROR_INVALID_SHADER;
goto fail;
} }
if (!(sm6->values = vkd3d_calloc(sm6->value_capacity, sizeof(*sm6->values)))) if (!(sm6->values = vkd3d_calloc(sm6->value_capacity, sizeof(*sm6->values))))
{ {
ERR("Failed to allocate value array.\n"); ERR("Failed to allocate value array.\n");
vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY, vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY,
"Out of memory allocating DXIL value array."); "Out of memory allocating DXIL value array.");
return VKD3D_ERROR_OUT_OF_MEMORY; ret = VKD3D_ERROR_OUT_OF_MEMORY;
goto fail;
} }
sm6->function_count = 0; sm6->function_count = 0;
sm6->ssa_next_id = 1; sm6->ssa_next_id = 1;
@ -10371,13 +10354,14 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, const char *sou
if ((ret = sm6_parser_globals_init(sm6)) < 0) if ((ret = sm6_parser_globals_init(sm6)) < 0)
{ {
WARN("Failed to load global declarations.\n"); WARN("Failed to load global declarations.\n");
return ret; goto fail;
} }
if (!sm6_parser_allocate_named_metadata(sm6)) if (!sm6_parser_allocate_named_metadata(sm6))
{ {
ERR("Failed to allocate named metadata array.\n"); ERR("Failed to allocate named metadata array.\n");
return VKD3D_ERROR_OUT_OF_MEMORY; ret = VKD3D_ERROR_OUT_OF_MEMORY;
goto fail;
} }
for (i = 0, j = 0; i < sm6->root_block.child_block_count; ++i) for (i = 0, j = 0; i < sm6->root_block.child_block_count; ++i)
@ -10391,18 +10375,19 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, const char *sou
FIXME("Too many metadata tables.\n"); FIXME("Too many metadata tables.\n");
vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_METADATA, vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_METADATA,
"A metadata table count greater than %zu is unsupported.", ARRAY_SIZE(sm6->metadata_tables)); "A metadata table count greater than %zu is unsupported.", ARRAY_SIZE(sm6->metadata_tables));
return VKD3D_ERROR_INVALID_SHADER; ret = VKD3D_ERROR_INVALID_SHADER;
goto fail;
} }
if ((ret = sm6_parser_metadata_init(sm6, block, &sm6->metadata_tables[j++])) < 0) if ((ret = sm6_parser_metadata_init(sm6, block, &sm6->metadata_tables[j++])) < 0)
return ret; goto fail;
} }
if ((ret = sm6_parser_entry_point_init(sm6)) < 0) if ((ret = sm6_parser_entry_point_init(sm6)) < 0)
return ret; goto fail;
if ((ret = sm6_parser_resources_init(sm6)) < 0) if ((ret = sm6_parser_resources_init(sm6)) < 0)
return ret; goto fail;
if ((ret = sm6_parser_module_init(sm6, &sm6->root_block, 0)) < 0) if ((ret = sm6_parser_module_init(sm6, &sm6->root_block, 0)) < 0)
{ {
@ -10412,7 +10397,7 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, const char *sou
else if (ret == VKD3D_ERROR_INVALID_SHADER) else if (ret == VKD3D_ERROR_INVALID_SHADER)
vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_MODULE, vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_MODULE,
"DXIL module is invalid."); "DXIL module is invalid.");
return ret; goto fail;
} }
if (!sm6_parser_require_space(sm6, output_signature->element_count + input_signature->element_count if (!sm6_parser_require_space(sm6, output_signature->element_count + input_signature->element_count
@ -10420,7 +10405,8 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, const char *sou
{ {
vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY, vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY,
"Out of memory emitting shader signature declarations."); "Out of memory emitting shader signature declarations.");
return VKD3D_ERROR_OUT_OF_MEMORY; ret = VKD3D_ERROR_OUT_OF_MEMORY;
goto fail;
} }
program->ssa_count = sm6->ssa_next_id; program->ssa_count = sm6->ssa_next_id;
@ -10430,7 +10416,8 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, const char *sou
WARN("Failed to find entry point %s.\n", sm6->entry_point); WARN("Failed to find entry point %s.\n", sm6->entry_point);
vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_ENTRY_POINT, vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_ENTRY_POINT,
"The definition of the entry point function '%s' was not found.", sm6->entry_point); "The definition of the entry point function '%s' was not found.", sm6->entry_point);
return VKD3D_ERROR_INVALID_SHADER; ret = VKD3D_ERROR_INVALID_SHADER;
goto fail;
} }
if (version.type == VKD3D_SHADER_TYPE_HULL) if (version.type == VKD3D_SHADER_TYPE_HULL)
@ -10438,7 +10425,7 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, const char *sou
sm6_parser_add_instruction(sm6, VKD3DSIH_HS_CONTROL_POINT_PHASE); sm6_parser_add_instruction(sm6, VKD3DSIH_HS_CONTROL_POINT_PHASE);
if ((ret = sm6_function_emit_blocks(fn, sm6)) < 0) if ((ret = sm6_function_emit_blocks(fn, sm6)) < 0)
return ret; goto fail;
if (!(fn = sm6_parser_get_function(sm6, sm6->patch_constant_function))) if (!(fn = sm6_parser_get_function(sm6, sm6->patch_constant_function)))
{ {
@ -10446,19 +10433,20 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, const char *sou
vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_MODULE, vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_MODULE,
"Failed to find the patch constant function '%s' for a hull shader.", "Failed to find the patch constant function '%s' for a hull shader.",
sm6->patch_constant_function); sm6->patch_constant_function);
return VKD3D_ERROR_INVALID_SHADER; ret = VKD3D_ERROR_INVALID_SHADER;
goto fail;
} }
sm6_parser_add_instruction(sm6, VKD3DSIH_HS_FORK_PHASE); sm6_parser_add_instruction(sm6, VKD3DSIH_HS_FORK_PHASE);
if ((ret = sm6_function_emit_blocks(fn, sm6)) < 0) if ((ret = sm6_function_emit_blocks(fn, sm6)) < 0)
return ret; goto fail;
expected_function_count = 2; expected_function_count = 2;
} }
else else
{ {
if ((ret = sm6_function_emit_blocks(fn, sm6)) < 0) if ((ret = sm6_function_emit_blocks(fn, sm6)) < 0)
return ret; goto fail;
expected_function_count = 1; expected_function_count = 1;
} }
@ -10472,30 +10460,27 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, const char *sou
dxil_block_destroy(&sm6->root_block); dxil_block_destroy(&sm6->root_block);
return VKD3D_OK; return VKD3D_OK;
fail:
vsir_program_cleanup(program);
return ret;
} }
int vkd3d_shader_sm6_parser_create(const struct vkd3d_shader_compile_info *compile_info, uint64_t config_flags, int dxil_parse(const struct vkd3d_shader_compile_info *compile_info, uint64_t config_flags,
struct vkd3d_shader_message_context *message_context, struct vkd3d_shader_parser **parser) struct vkd3d_shader_message_context *message_context, struct vsir_program *program)
{ {
struct dxbc_shader_desc dxbc_desc = {0}; struct dxbc_shader_desc dxbc_desc = {0};
struct sm6_parser sm6 = {0};
uint32_t *byte_code = NULL; uint32_t *byte_code = NULL;
struct sm6_parser *sm6;
int ret; int ret;
ERR("Creating a DXIL parser. This is unsupported; you get to keep all the pieces if it breaks.\n"); ERR("Creating a DXIL parser. This is unsupported; you get to keep all the pieces if it breaks.\n");
if (!(sm6 = vkd3d_calloc(1, sizeof(*sm6))))
{
ERR("Failed to allocate parser.\n");
return VKD3D_ERROR_OUT_OF_MEMORY;
}
dxbc_desc.is_dxil = true; dxbc_desc.is_dxil = true;
if ((ret = shader_extract_from_dxbc(&compile_info->source, message_context, compile_info->source_name, if ((ret = shader_extract_from_dxbc(&compile_info->source, message_context, compile_info->source_name,
&dxbc_desc)) < 0) &dxbc_desc)) < 0)
{ {
WARN("Failed to extract shader, vkd3d result %d.\n", ret); WARN("Failed to extract shader, vkd3d result %d.\n", ret);
vkd3d_free(sm6);
return ret; return ret;
} }
@ -10507,7 +10492,6 @@ int vkd3d_shader_sm6_parser_create(const struct vkd3d_shader_compile_info *compi
{ {
ERR("Failed to allocate aligned chunk.\n"); ERR("Failed to allocate aligned chunk.\n");
free_dxbc_shader_desc(&dxbc_desc); free_dxbc_shader_desc(&dxbc_desc);
vkd3d_free(sm6);
return VKD3D_ERROR_OUT_OF_MEMORY; return VKD3D_ERROR_OUT_OF_MEMORY;
} }
@ -10515,24 +10499,22 @@ int vkd3d_shader_sm6_parser_create(const struct vkd3d_shader_compile_info *compi
dxbc_desc.byte_code = byte_code; dxbc_desc.byte_code = byte_code;
} }
ret = sm6_parser_init(sm6, compile_info->source_name, message_context, &dxbc_desc); ret = sm6_parser_init(&sm6, program, compile_info->source_name, message_context, &dxbc_desc);
free_dxbc_shader_desc(&dxbc_desc); free_dxbc_shader_desc(&dxbc_desc);
vkd3d_free(byte_code); vkd3d_free(byte_code);
if (!sm6->p.failed && ret >= 0) if (!sm6.p.failed && ret >= 0)
ret = vkd3d_shader_parser_validate(&sm6->p, config_flags); ret = vkd3d_shader_parser_validate(&sm6.p, config_flags);
if (sm6->p.failed && ret >= 0) if (sm6.p.failed && ret >= 0)
ret = VKD3D_ERROR_INVALID_SHADER; ret = VKD3D_ERROR_INVALID_SHADER;
sm6_parser_cleanup(&sm6);
if (ret < 0) if (ret < 0)
{ {
WARN("Failed to initialise shader parser.\n"); WARN("Failed to parse shader.\n");
sm6_parser_destroy(&sm6->p);
return ret; return ret;
} }
*parser = &sm6->p;
return ret; return ret;
} }

View File

@ -1746,10 +1746,6 @@ static enum vkd3d_data_type map_data_type(char t)
} }
} }
static void shader_sm4_destroy(struct vkd3d_shader_parser *parser)
{
}
static bool shader_sm4_read_reg_idx(struct vkd3d_shader_sm4_parser *priv, const uint32_t **ptr, static bool shader_sm4_read_reg_idx(struct vkd3d_shader_sm4_parser *priv, const uint32_t **ptr,
const uint32_t *end, uint32_t addressing, struct vkd3d_shader_register_index *reg_idx) const uint32_t *end, uint32_t addressing, struct vkd3d_shader_register_index *reg_idx)
{ {
@ -2496,11 +2492,6 @@ fail:
return; return;
} }
static const struct vkd3d_shader_parser_ops shader_sm4_parser_ops =
{
.parser_destroy = shader_sm4_destroy,
};
static bool shader_sm4_init(struct vkd3d_shader_sm4_parser *sm4, struct vsir_program *program, static bool shader_sm4_init(struct vkd3d_shader_sm4_parser *sm4, struct vsir_program *program,
const uint32_t *byte_code, size_t byte_code_size, const char *source_name, const uint32_t *byte_code, size_t byte_code_size, const char *source_name,
struct vkd3d_shader_message_context *message_context) struct vkd3d_shader_message_context *message_context)
@ -2563,7 +2554,7 @@ static bool shader_sm4_init(struct vkd3d_shader_sm4_parser *sm4, struct vsir_pro
/* Estimate instruction count to avoid reallocation in most shaders. */ /* Estimate instruction count to avoid reallocation in most shaders. */
if (!vsir_program_init(program, &version, token_count / 7u + 20)) if (!vsir_program_init(program, &version, token_count / 7u + 20))
return false; return false;
vkd3d_shader_parser_init(&sm4->p, program, message_context, source_name, &shader_sm4_parser_ops); vkd3d_shader_parser_init(&sm4->p, program, message_context, source_name);
sm4->ptr = sm4->start; sm4->ptr = sm4->start;
init_sm4_lookup_tables(&sm4->lookup); init_sm4_lookup_tables(&sm4->lookup);

View File

@ -555,14 +555,12 @@ uint64_t vkd3d_shader_init_config_flags(void)
} }
void vkd3d_shader_parser_init(struct vkd3d_shader_parser *parser, struct vsir_program *program, void vkd3d_shader_parser_init(struct vkd3d_shader_parser *parser, struct vsir_program *program,
struct vkd3d_shader_message_context *message_context, const char *source_name, struct vkd3d_shader_message_context *message_context, const char *source_name)
const struct vkd3d_shader_parser_ops *ops)
{ {
parser->message_context = message_context; parser->message_context = message_context;
parser->location.source_name = source_name; parser->location.source_name = source_name;
parser->location.line = 1; parser->location.line = 1;
parser->location.column = 0; parser->location.column = 0;
parser->ops = ops;
parser->program = program; parser->program = program;
} }
@ -1515,24 +1513,20 @@ int vkd3d_shader_scan(const struct vkd3d_shader_compile_info *compile_info, char
else else
{ {
uint64_t config_flags = vkd3d_shader_init_config_flags(); uint64_t config_flags = vkd3d_shader_init_config_flags();
struct vkd3d_shader_parser *parser; struct vsir_program program;
struct vsir_program program, *p;
switch (compile_info->source_type) switch (compile_info->source_type)
{ {
case VKD3D_SHADER_SOURCE_D3D_BYTECODE: case VKD3D_SHADER_SOURCE_D3D_BYTECODE:
ret = d3dbc_parse(compile_info, config_flags, &message_context, &program); ret = d3dbc_parse(compile_info, config_flags, &message_context, &program);
p = &program;
break; break;
case VKD3D_SHADER_SOURCE_DXBC_TPF: case VKD3D_SHADER_SOURCE_DXBC_TPF:
ret = tpf_parse(compile_info, config_flags, &message_context, &program); ret = tpf_parse(compile_info, config_flags, &message_context, &program);
p = &program;
break; break;
case VKD3D_SHADER_SOURCE_DXBC_DXIL: case VKD3D_SHADER_SOURCE_DXBC_DXIL:
if ((ret = vkd3d_shader_sm6_parser_create(compile_info, config_flags, &message_context, &parser)) >= 0) ret = dxil_parse(compile_info, config_flags, &message_context, &program);
p = parser->program;
break; break;
default: default:
@ -1543,15 +1537,12 @@ int vkd3d_shader_scan(const struct vkd3d_shader_compile_info *compile_info, char
if (ret < 0) if (ret < 0)
{ {
WARN("Failed to create shader parser.\n"); WARN("Failed to parse shader.\n");
} }
else else
{ {
ret = vsir_program_scan(p, compile_info, &message_context, NULL); ret = vsir_program_scan(&program, compile_info, &message_context, NULL);
if (p == &program)
vsir_program_cleanup(&program); vsir_program_cleanup(&program);
else
vkd3d_shader_parser_destroy(parser);
} }
} }
@ -1644,24 +1635,20 @@ int vkd3d_shader_compile(const struct vkd3d_shader_compile_info *compile_info,
else else
{ {
uint64_t config_flags = vkd3d_shader_init_config_flags(); uint64_t config_flags = vkd3d_shader_init_config_flags();
struct vkd3d_shader_parser *parser; struct vsir_program program;
struct vsir_program program, *p;
switch (compile_info->source_type) switch (compile_info->source_type)
{ {
case VKD3D_SHADER_SOURCE_D3D_BYTECODE: case VKD3D_SHADER_SOURCE_D3D_BYTECODE:
ret = d3dbc_parse(compile_info, config_flags, &message_context, &program); ret = d3dbc_parse(compile_info, config_flags, &message_context, &program);
p = &program;
break; break;
case VKD3D_SHADER_SOURCE_DXBC_TPF: case VKD3D_SHADER_SOURCE_DXBC_TPF:
ret = tpf_parse(compile_info, config_flags, &message_context, &program); ret = tpf_parse(compile_info, config_flags, &message_context, &program);
p = &program;
break; break;
case VKD3D_SHADER_SOURCE_DXBC_DXIL: case VKD3D_SHADER_SOURCE_DXBC_DXIL:
if ((ret = vkd3d_shader_sm6_parser_create(compile_info, config_flags, &message_context, &parser)) >= 0) ret = dxil_parse(compile_info, config_flags, &message_context, &program);
p = parser->program;
break; break;
default: default:
@ -1672,15 +1659,12 @@ int vkd3d_shader_compile(const struct vkd3d_shader_compile_info *compile_info,
if (ret < 0) if (ret < 0)
{ {
WARN("Failed to create shader parser.\n"); WARN("Failed to parse shader.\n");
} }
else else
{ {
ret = vsir_program_compile(p, config_flags, compile_info, out, &message_context); ret = vsir_program_compile(&program, config_flags, compile_info, out, &message_context);
if (p == &program)
vsir_program_cleanup(&program); vsir_program_cleanup(&program);
else
vkd3d_shader_parser_destroy(parser);
} }
} }

View File

@ -1394,28 +1394,15 @@ struct vkd3d_shader_parser
struct vkd3d_shader_location location; struct vkd3d_shader_location location;
struct vsir_program *program; struct vsir_program *program;
bool failed; bool failed;
const struct vkd3d_shader_parser_ops *ops;
};
struct vkd3d_shader_parser_ops
{
void (*parser_destroy)(struct vkd3d_shader_parser *parser);
}; };
void vkd3d_shader_parser_error(struct vkd3d_shader_parser *parser, void vkd3d_shader_parser_error(struct vkd3d_shader_parser *parser,
enum vkd3d_shader_error error, const char *format, ...) VKD3D_PRINTF_FUNC(3, 4); enum vkd3d_shader_error error, const char *format, ...) VKD3D_PRINTF_FUNC(3, 4);
void vkd3d_shader_parser_init(struct vkd3d_shader_parser *parser, struct vsir_program *program, void vkd3d_shader_parser_init(struct vkd3d_shader_parser *parser, struct vsir_program *program,
struct vkd3d_shader_message_context *message_context, const char *source_name, struct vkd3d_shader_message_context *message_context, const char *source_name);
const struct vkd3d_shader_parser_ops *ops);
void vkd3d_shader_parser_warning(struct vkd3d_shader_parser *parser, void vkd3d_shader_parser_warning(struct vkd3d_shader_parser *parser,
enum vkd3d_shader_error error, const char *format, ...) VKD3D_PRINTF_FUNC(3, 4); enum vkd3d_shader_error error, const char *format, ...) VKD3D_PRINTF_FUNC(3, 4);
static inline void vkd3d_shader_parser_destroy(struct vkd3d_shader_parser *parser)
{
parser->ops->parser_destroy(parser);
}
static inline enum vkd3d_result vkd3d_shader_parser_validate(struct vkd3d_shader_parser *parser, uint64_t config_flags) static inline enum vkd3d_result vkd3d_shader_parser_validate(struct vkd3d_shader_parser *parser, uint64_t config_flags)
{ {
return vsir_program_validate(parser->program, config_flags, return vsir_program_validate(parser->program, config_flags,
@ -1556,10 +1543,10 @@ void vkd3d_shader_trace_text_(const char *text, size_t size, const char *functio
int d3dbc_parse(const struct vkd3d_shader_compile_info *compile_info, uint64_t config_flags, int d3dbc_parse(const struct vkd3d_shader_compile_info *compile_info, uint64_t config_flags,
struct vkd3d_shader_message_context *message_context, struct vsir_program *program); struct vkd3d_shader_message_context *message_context, struct vsir_program *program);
int dxil_parse(const struct vkd3d_shader_compile_info *compile_info, uint64_t config_flags,
struct vkd3d_shader_message_context *message_context, struct vsir_program *program);
int tpf_parse(const struct vkd3d_shader_compile_info *compile_info, uint64_t config_flags, int tpf_parse(const struct vkd3d_shader_compile_info *compile_info, uint64_t config_flags,
struct vkd3d_shader_message_context *message_context, struct vsir_program *program); struct vkd3d_shader_message_context *message_context, struct vsir_program *program);
int vkd3d_shader_sm6_parser_create(const struct vkd3d_shader_compile_info *compile_info, uint64_t config_flags,
struct vkd3d_shader_message_context *message_context, struct vkd3d_shader_parser **parser);
void free_dxbc_shader_desc(struct dxbc_shader_desc *desc); void free_dxbc_shader_desc(struct dxbc_shader_desc *desc);