This was originally intended to be part 2/2, but the final patch in the original series has some conflicts with other MRs.
From: Henri Verbeet hverbeet@codeweavers.com
--- libs/vkd3d-shader/ir.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/libs/vkd3d-shader/ir.c b/libs/vkd3d-shader/ir.c index 0dd31af91..7fd98a5ef 100644 --- a/libs/vkd3d-shader/ir.c +++ b/libs/vkd3d-shader/ir.c @@ -1386,10 +1386,9 @@ static void shader_instruction_normalise_io_params(struct vkd3d_shader_instructi } }
-static enum vkd3d_result shader_normalise_io_registers(struct vkd3d_shader_parser *parser) +static enum vkd3d_result vsir_program_normalise_io_registers(struct vsir_program *program) { - struct io_normaliser normaliser = {parser->program.instructions}; - struct vsir_program *program = &parser->program; + struct io_normaliser normaliser = {program->instructions}; struct vkd3d_shader_instruction *ins; bool has_control_point_phase; unsigned int i, j; @@ -3987,7 +3986,7 @@ enum vkd3d_result vkd3d_shader_normalise(struct vkd3d_shader_parser *parser, return result; }
- if ((result = shader_normalise_io_registers(parser)) < 0) + if ((result = vsir_program_normalise_io_registers(program)) < 0) return result;
if ((result = instruction_array_normalise_flat_constants(program)) < 0)
From: Henri Verbeet hverbeet@codeweavers.com
--- libs/vkd3d-shader/ir.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-)
diff --git a/libs/vkd3d-shader/ir.c b/libs/vkd3d-shader/ir.c index 7fd98a5ef..fc2412134 100644 --- a/libs/vkd3d-shader/ir.c +++ b/libs/vkd3d-shader/ir.c @@ -1670,19 +1670,20 @@ static void remove_dead_code(struct vsir_program *program) } }
-static enum vkd3d_result normalise_combined_samplers(struct vkd3d_shader_parser *parser) +static enum vkd3d_result vsir_program_normalise_combined_samplers(struct vsir_program *program, + struct vkd3d_shader_message_context *message_context) { unsigned int i;
- for (i = 0; i < parser->program.instructions.count; ++i) + for (i = 0; i < program->instructions.count; ++i) { - struct vkd3d_shader_instruction *ins = &parser->program.instructions.elements[i]; + struct vkd3d_shader_instruction *ins = &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->program.instructions.src_params, 3))) + if (!(srcs = shader_src_param_allocator_get(&program->instructions.src_params, 3))) return VKD3D_ERROR_OUT_OF_MEMORY; memset(srcs, 0, sizeof(*srcs) * 3);
@@ -1725,7 +1726,7 @@ static enum vkd3d_result normalise_combined_samplers(struct vkd3d_shader_parser case VKD3DSIH_TEXREG2AR: case VKD3DSIH_TEXREG2GB: case VKD3DSIH_TEXREG2RGB: - vkd3d_shader_parser_error(parser, VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED, + vkd3d_shader_error(message_context, &ins->location, VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED, "Aborting due to not yet implemented feature: " "Combined sampler instruction %#x.", ins->handler_idx); return VKD3D_ERROR_NOT_IMPLEMENTED; @@ -3994,7 +3995,7 @@ enum vkd3d_result vkd3d_shader_normalise(struct vkd3d_shader_parser *parser,
remove_dead_code(program);
- if ((result = normalise_combined_samplers(parser)) < 0) + if ((result = vsir_program_normalise_combined_samplers(program, message_context)) < 0) return result; }
From: Henri Verbeet hverbeet@codeweavers.com
--- libs/vkd3d-shader/ir.c | 55 ++++++++++++++++++++++++------------------ 1 file changed, 31 insertions(+), 24 deletions(-)
diff --git a/libs/vkd3d-shader/ir.c b/libs/vkd3d-shader/ir.c index fc2412134..1ead6879f 100644 --- a/libs/vkd3d-shader/ir.c +++ b/libs/vkd3d-shader/ir.c @@ -1792,10 +1792,10 @@ struct cf_flattener_info
struct cf_flattener { - struct vkd3d_shader_parser *parser; + struct vsir_program *program;
struct vkd3d_shader_location location; - bool allocation_failed; + enum vkd3d_result status;
struct vkd3d_shader_instruction *instructions; size_t instruction_capacity; @@ -1815,13 +1815,20 @@ struct cf_flattener size_t control_flow_info_size; };
+static void cf_flattener_set_error(struct cf_flattener *flattener, enum vkd3d_result error) +{ + if (flattener->status != VKD3D_OK) + return; + 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"); - flattener->allocation_failed = true; + cf_flattener_set_error(flattener, VKD3D_ERROR_OUT_OF_MEMORY); return NULL; } return &flattener->instructions[flattener->instruction_count]; @@ -1853,9 +1860,9 @@ static struct vkd3d_shader_src_param *instruction_src_params_alloc(struct vkd3d_ { struct vkd3d_shader_src_param *params;
- if (!(params = vsir_program_get_src_params(&flattener->parser->program, count))) + if (!(params = vsir_program_get_src_params(flattener->program, count))) { - flattener->allocation_failed = true; + cf_flattener_set_error(flattener, VKD3D_ERROR_OUT_OF_MEMORY); return NULL; } ins->src = params; @@ -1869,10 +1876,10 @@ static void cf_flattener_emit_label(struct cf_flattener *flattener, unsigned int
if (!(ins = cf_flattener_require_space(flattener, 1))) return; - if (vsir_instruction_init_label(ins, &flattener->location, label_id, &flattener->parser->program)) + if (vsir_instruction_init_label(ins, &flattener->location, label_id, flattener->program)) ++flattener->instruction_count; else - flattener->allocation_failed = true; + cf_flattener_set_error(flattener, VKD3D_ERROR_OUT_OF_MEMORY); }
/* For conditional branches, this returns the false target branch parameter. */ @@ -1950,7 +1957,7 @@ static struct cf_flattener_info *cf_flattener_push_control_flow_level(struct cf_ flattener->control_flow_depth + 1, sizeof(*flattener->control_flow_info))) { ERR("Failed to allocate control flow info structure.\n"); - flattener->allocation_failed = true; + cf_flattener_set_error(flattener, VKD3D_ERROR_OUT_OF_MEMORY); return NULL; }
@@ -2017,12 +2024,12 @@ static void VKD3D_PRINTF_FUNC(3, 4) cf_flattener_create_block_name(struct cf_fla flattener->block_names[block_id] = buffer.buffer; }
-static enum vkd3d_result cf_flattener_iterate_instruction_array(struct cf_flattener *flattener) +static enum vkd3d_result cf_flattener_iterate_instruction_array(struct cf_flattener *flattener, + struct vkd3d_shader_message_context *message_context) { bool main_block_open, is_hull_shader, after_declarations_section; - struct vkd3d_shader_parser *parser = flattener->parser; struct vkd3d_shader_instruction_array *instructions; - struct vsir_program *program = &parser->program; + struct vsir_program *program = flattener->program; struct vkd3d_shader_instruction *dst_ins; size_t i;
@@ -2074,7 +2081,8 @@ static enum vkd3d_result cf_flattener_iterate_instruction_array(struct cf_flatte break;
case VKD3DSIH_LABEL: - vkd3d_shader_parser_error(parser, VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED, + vkd3d_shader_error(message_context, &instruction->location, + VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED, "Aborting due to not yet implemented feature: Label instruction."); return VKD3D_ERROR_NOT_IMPLEMENTED;
@@ -2239,8 +2247,10 @@ static enum vkd3d_result cf_flattener_iterate_instruction_array(struct cf_flatte if (src->swizzle != VKD3D_SHADER_SWIZZLE(X, X, X, X)) { WARN("Unexpected src swizzle %#x.\n", src->swizzle); - vkd3d_shader_parser_error(parser, VKD3D_SHADER_ERROR_VSIR_INVALID_SWIZZLE, + vkd3d_shader_error(message_context, &instruction->location, + VKD3D_SHADER_ERROR_VSIR_INVALID_SWIZZLE, "The swizzle for a switch case value is not scalar X."); + cf_flattener_set_error(flattener, VKD3D_ERROR_INVALID_SHADER); } value = *src->reg.u.immconst_u32;
@@ -2368,21 +2378,18 @@ static enum vkd3d_result cf_flattener_iterate_instruction_array(struct cf_flatte ++flattener->instruction_count; }
- return flattener->allocation_failed ? VKD3D_ERROR_OUT_OF_MEMORY : VKD3D_OK; + return flattener->status; }
-static enum vkd3d_result flatten_control_flow_constructs(struct vkd3d_shader_parser *parser) +static enum vkd3d_result vsir_program_flatten_control_flow_constructs(struct vsir_program *program, + struct vkd3d_shader_message_context *message_context) { - struct vsir_program *program = &parser->program; - struct cf_flattener flattener = {0}; + struct cf_flattener flattener = {.program = program}; enum vkd3d_result result;
- flattener.parser = parser; - result = cf_flattener_iterate_instruction_array(&flattener); - - if (result >= 0) + if ((result = cf_flattener_iterate_instruction_array(&flattener, message_context)) >= 0) { - vkd3d_free(parser->program.instructions.elements); + vkd3d_free(program->instructions.elements); program->instructions.elements = flattener.instructions; program->instructions.capacity = flattener.instruction_capacity; program->instructions.count = flattener.instruction_count; @@ -3999,13 +4006,13 @@ enum vkd3d_result vkd3d_shader_normalise(struct vkd3d_shader_parser *parser, return result; }
- if ((result = flatten_control_flow_constructs(parser)) < 0) + if ((result = vsir_program_flatten_control_flow_constructs(program, message_context)) < 0) return result;
if (TRACE_ON()) vkd3d_shader_trace(program);
- if (!parser->failed && (result = vsir_validate(parser)) < 0) + if ((result = vsir_validate(parser)) < 0) return result;
if (parser->failed)
From: Henri Verbeet hverbeet@codeweavers.com
--- libs/vkd3d-shader/d3dbc.c | 2 +- libs/vkd3d-shader/dxil.c | 2 +- libs/vkd3d-shader/ir.c | 43 ++++++++++++++---------- libs/vkd3d-shader/tpf.c | 2 +- libs/vkd3d-shader/vkd3d_shader_private.h | 12 +++++-- 5 files changed, 38 insertions(+), 23 deletions(-)
diff --git a/libs/vkd3d-shader/d3dbc.c b/libs/vkd3d-shader/d3dbc.c index 57dd0258a..101c46d6e 100644 --- a/libs/vkd3d-shader/d3dbc.c +++ b/libs/vkd3d-shader/d3dbc.c @@ -1358,7 +1358,7 @@ int vkd3d_shader_sm1_parser_create(const struct vkd3d_shader_compile_info *compi sm1->p.shader_desc.flat_constant_count[i].external = get_external_constant_count(sm1, i);
if (!sm1->p.failed) - ret = vsir_validate(&sm1->p); + ret = vkd3d_shader_parser_validate(&sm1->p);
if (sm1->p.failed && ret >= 0) ret = VKD3D_ERROR_INVALID_SHADER; diff --git a/libs/vkd3d-shader/dxil.c b/libs/vkd3d-shader/dxil.c index de51588b5..df9519b6c 100644 --- a/libs/vkd3d-shader/dxil.c +++ b/libs/vkd3d-shader/dxil.c @@ -8481,7 +8481,7 @@ int vkd3d_shader_sm6_parser_create(const struct vkd3d_shader_compile_info *compi vkd3d_free(byte_code);
if (!sm6->p.failed && ret >= 0) - ret = vsir_validate(&sm6->p); + ret = vkd3d_shader_parser_validate(&sm6->p);
if (sm6->p.failed && ret >= 0) ret = VKD3D_ERROR_INVALID_SHADER; diff --git a/libs/vkd3d-shader/ir.c b/libs/vkd3d-shader/ir.c index 1ead6879f..2c256f903 100644 --- a/libs/vkd3d-shader/ir.c +++ b/libs/vkd3d-shader/ir.c @@ -4012,21 +4012,21 @@ enum vkd3d_result vkd3d_shader_normalise(struct vkd3d_shader_parser *parser, if (TRACE_ON()) vkd3d_shader_trace(program);
- if ((result = vsir_validate(parser)) < 0) + if ((result = vsir_program_validate(program, parser->config_flags, + compile_info->source_name, message_context)) < 0) return result;
- if (parser->failed) - result = VKD3D_ERROR_INVALID_SHADER; - return result; }
struct validation_context { - struct vkd3d_shader_parser *parser; + struct vkd3d_shader_message_context *message_context; const struct vsir_program *program; size_t instruction_idx; + struct vkd3d_shader_location null_location; bool invalid_instruction_idx; + enum vkd3d_result status; bool dcl_temps_found; enum vkd3d_shader_opcode phase; enum cf_type @@ -4072,16 +4072,21 @@ static void VKD3D_PRINTF_FUNC(3, 4) validator_error(struct validation_context *c
if (ctx->invalid_instruction_idx) { - vkd3d_shader_parser_error(ctx->parser, error, "%s", buf.buffer); + vkd3d_shader_error(ctx->message_context, &ctx->null_location, error, "%s", buf.buffer); ERR("VSIR validation error: %s\n", buf.buffer); } else { - vkd3d_shader_parser_error(ctx->parser, error, "instruction %zu: %s", ctx->instruction_idx + 1, buf.buffer); + const struct vkd3d_shader_instruction *ins = &ctx->program->instructions.elements[ctx->instruction_idx]; + vkd3d_shader_error(ctx->message_context, &ins->location, error, + "instruction %zu: %s", ctx->instruction_idx + 1, buf.buffer); ERR("VSIR validation error: instruction %zu: %s\n", ctx->instruction_idx + 1, buf.buffer); }
vkd3d_string_buffer_cleanup(&buf); + + if (!ctx->status) + ctx->status = VKD3D_ERROR_INVALID_SHADER; }
static void vsir_validate_src_param(struct validation_context *ctx, @@ -4135,10 +4140,10 @@ static void vsir_validate_register(struct validation_context *ctx, if (reg->idx[0].rel_addr) validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_INDEX, "Non-NULL relative address for a TEMP register.");
- if (reg->idx[0].offset >= ctx->parser->program.temp_count) + if (reg->idx[0].offset >= ctx->program->temp_count) { validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_INDEX, "TEMP register index %u exceeds the maximum count %u.", - reg->idx[0].offset, ctx->parser->program.temp_count); + reg->idx[0].offset, ctx->program->temp_count); break; }
@@ -4328,7 +4333,7 @@ static void vsir_validate_dst_param(struct validation_context *ctx, switch (dst->reg.type) { case VKD3DSPR_SSA: - if (dst->reg.idx[0].offset < ctx->parser->program.ssa_count) + if (dst->reg.idx[0].offset < ctx->program->ssa_count) { struct validation_context_ssa_data *data = &ctx->ssas[dst->reg.idx[0].offset];
@@ -4381,7 +4386,7 @@ static void vsir_validate_src_param(struct validation_context *ctx, switch (src->reg.type) { case VKD3DSPR_SSA: - if (src->reg.idx[0].offset < ctx->parser->program.ssa_count) + if (src->reg.idx[0].offset < ctx->program->ssa_count) { struct validation_context_ssa_data *data = &ctx->ssas[src->reg.idx[0].offset]; unsigned int i; @@ -4472,7 +4477,6 @@ static void vsir_validate_instruction(struct validation_context *ctx) size_t i;
instruction = &ctx->program->instructions.elements[ctx->instruction_idx]; - ctx->parser->location = instruction->location;
for (i = 0; i < instruction->dst_count; ++i) vsir_validate_dst_param(ctx, &instruction->dst[i]); @@ -4823,17 +4827,20 @@ static void vsir_validate_instruction(struct validation_context *ctx) } }
-enum vkd3d_result vsir_validate(struct vkd3d_shader_parser *parser) +enum vkd3d_result vsir_program_validate(struct vsir_program *program, uint64_t config_flags, + const char *source_name, struct vkd3d_shader_message_context *message_context) { struct validation_context ctx = { - .parser = parser, - .program = &parser->program, + .message_context = message_context, + .program = program, + .null_location = {.source_name = source_name}, + .status = VKD3D_OK, .phase = VKD3DSIH_INVALID, }; unsigned int i;
- if (!(parser->config_flags & VKD3D_SHADER_CONFIG_FLAG_FORCE_VALIDATION)) + if (!(config_flags & VKD3D_SHADER_CONFIG_FLAG_FORCE_VALIDATION)) return VKD3D_OK;
if (!(ctx.temps = vkd3d_calloc(ctx.program->temp_count, sizeof(*ctx.temps)))) @@ -4842,7 +4849,7 @@ enum vkd3d_result vsir_validate(struct vkd3d_shader_parser *parser) if (!(ctx.ssas = vkd3d_calloc(ctx.program->ssa_count, sizeof(*ctx.ssas)))) goto fail;
- for (ctx.instruction_idx = 0; ctx.instruction_idx < parser->program.instructions.count; ++ctx.instruction_idx) + for (ctx.instruction_idx = 0; ctx.instruction_idx < program->instructions.count; ++ctx.instruction_idx) vsir_validate_instruction(&ctx);
ctx.invalid_instruction_idx = true; @@ -4867,7 +4874,7 @@ enum vkd3d_result vsir_validate(struct vkd3d_shader_parser *parser) vkd3d_free(ctx.temps); vkd3d_free(ctx.ssas);
- return VKD3D_OK; + return ctx.status;
fail: vkd3d_free(ctx.blocks); diff --git a/libs/vkd3d-shader/tpf.c b/libs/vkd3d-shader/tpf.c index bd558693b..072aa94e0 100644 --- a/libs/vkd3d-shader/tpf.c +++ b/libs/vkd3d-shader/tpf.c @@ -2724,7 +2724,7 @@ int vkd3d_shader_sm4_parser_create(const struct vkd3d_shader_compile_info *compi shader_sm4_validate_default_phase_index_ranges(sm4);
if (!sm4->p.failed) - vsir_validate(&sm4->p); + vkd3d_shader_parser_validate(&sm4->p);
if (sm4->p.failed) { diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h index ba018070f..c35f78593 100644 --- a/libs/vkd3d-shader/vkd3d_shader_private.h +++ b/libs/vkd3d-shader/vkd3d_shader_private.h @@ -814,6 +814,8 @@ enum vkd3d_shader_type VKD3D_SHADER_TYPE_COUNT, };
+struct vkd3d_shader_message_context; + struct vkd3d_shader_version { enum vkd3d_shader_type type; @@ -1315,6 +1317,8 @@ struct vsir_program
bool vsir_program_init(struct vsir_program *program, const struct vkd3d_shader_version *version, unsigned int reserve); void vsir_program_cleanup(struct vsir_program *program); +enum vkd3d_result vsir_program_validate(struct vsir_program *program, uint64_t config_flags, + const char *source_name, struct vkd3d_shader_message_context *message_context);
static inline struct vkd3d_shader_dst_param *vsir_program_get_dst_params( struct vsir_program *program, unsigned int count) @@ -1360,6 +1364,12 @@ static inline void vkd3d_shader_parser_destroy(struct vkd3d_shader_parser *parse parser->ops->parser_destroy(parser); }
+static inline enum vkd3d_result vkd3d_shader_parser_validate(struct vkd3d_shader_parser *parser) +{ + return vsir_program_validate(&parser->program, parser->config_flags, + parser->location.source_name, parser->message_context); +} + struct vkd3d_shader_descriptor_info1 { enum vkd3d_shader_descriptor_type type; @@ -1522,8 +1532,6 @@ int preproc_lexer_parse(const struct vkd3d_shader_compile_info *compile_info, int hlsl_compile_shader(const struct vkd3d_shader_code *hlsl, const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_code *out, struct vkd3d_shader_message_context *message_context);
-enum vkd3d_result vsir_validate(struct vkd3d_shader_parser *parser); - static inline enum vkd3d_shader_component_type vkd3d_component_type_from_data_type( enum vkd3d_data_type data_type) {
This merge request was approved by Giovanni Mascellani.