From: Conor McCarthy cmccarthy@codeweavers.com
--- libs/vkd3d-shader/ir.c | 28 +++++++++++++++++++++--- libs/vkd3d-shader/spirv.c | 2 +- libs/vkd3d-shader/vkd3d_shader_private.h | 7 +++++- 3 files changed, 32 insertions(+), 5 deletions(-)
diff --git a/libs/vkd3d-shader/ir.c b/libs/vkd3d-shader/ir.c index 11ba7563..bf2c4442 100644 --- a/libs/vkd3d-shader/ir.c +++ b/libs/vkd3d-shader/ir.c @@ -18,6 +18,16 @@
#include "vkd3d_shader_private.h"
+static void VKD3D_PRINTF_FUNC(3, 4) shader_normaliser_error(struct vkd3d_shader_normaliser *normaliser, + enum vkd3d_shader_error error, const char *format, ...) +{ + va_list args; + + va_start(args, format); + vkd3d_shader_verror(normaliser->message_context, &normaliser->location, error, format, args); + va_end(args); +} + static inline bool shader_register_is_phase_instance_id(const struct vkd3d_shader_register *reg) { return reg->type == VKD3DSPR_FORKINSTID || reg->type == VKD3DSPR_JOININSTID; @@ -205,6 +215,7 @@ static enum vkd3d_result shader_normaliser_flatten_phases(struct vkd3d_shader_no { for (k = 0; k < loc->instruction_count; ++k) { + normaliser->location.line = loc->index + k + 1; if (!shader_instruction_array_clone_instruction(&normaliser->instructions, loc->index + loc->instruction_count * j + k, loc->index + k)) return VKD3D_ERROR_OUT_OF_MEMORY; @@ -214,8 +225,11 @@ static enum vkd3d_result shader_normaliser_flatten_phases(struct vkd3d_shader_no for (j = 0; j < loc->instance_count; ++j) { for (k = 0; k < loc->instruction_count; ++k) - shader_instruction_eliminate_phase_instance_id( - &normaliser->instructions.elements[loc->index + loc->instruction_count * j + k], j); + { + unsigned int ins_idx = loc->index + loc->instruction_count * j + k; + normaliser->location.line = ins_idx + 1; + shader_instruction_eliminate_phase_instance_id(&normaliser->instructions.elements[ins_idx], j); + } } }
@@ -245,11 +259,12 @@ static void shader_instruction_init(struct vkd3d_shader_instruction *ins, enum v }
void shader_normaliser_init(struct vkd3d_shader_normaliser *normaliser, - struct vkd3d_shader_instruction_array *instructions) + struct vkd3d_shader_instruction_array *instructions, struct vkd3d_shader_message_context *message_context) { memset(normaliser, 0, sizeof(*normaliser)); normaliser->phase = VKD3DSIH_INVALID; normaliser->instructions = *instructions; + normaliser->message_context = message_context; memset(instructions, 0, sizeof(*instructions)); }
@@ -261,7 +276,10 @@ enum vkd3d_result shader_normaliser_flatten_hull_shader_phases(struct vkd3d_shad unsigned int i;
for (i = 0, locations.count = 0; i < instructions->count; ++i) + { + normaliser->location.line = i + 1; shader_normaliser_eliminate_phase_related_dcls(normaliser, i, &locations); + }
if ((result = shader_normaliser_flatten_phases(normaliser, &locations)) < 0) return result; @@ -303,6 +321,8 @@ static bool shader_dst_param_normalise_outpointid(struct vkd3d_shader_dst_param if (reg->idx[2].offset != ~0u) { FIXME("Cannot insert phase id.\n"); + shader_normaliser_error(normaliser, VKD3D_SHADER_ERROR_IR_REGISTER_ORDER_TOO_HIGH, + "Highest register order is occupied. Cannot insert phase id.\n"); return false; } if (reg->idx[1].offset != ~0u) @@ -397,6 +417,7 @@ enum vkd3d_result shader_normaliser_normalise_hull_shader_control_point_io(struc for (i = 0; i < normaliser->instructions.count; ++i) { ins = &instructions->elements[i]; + normaliser->location.line = i + 1;
switch (ins->handler_idx) { @@ -424,6 +445,7 @@ enum vkd3d_result shader_normaliser_normalise_hull_shader_control_point_io(struc for (i = 0; i < instructions->count; ++i) { ins = &instructions->elements[i]; + normaliser->location.line = i + 1;
switch (ins->handler_idx) { diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c index 73510f8b..03a713e9 100644 --- a/libs/vkd3d-shader/spirv.c +++ b/libs/vkd3d-shader/spirv.c @@ -9696,7 +9696,7 @@ static int spirv_compiler_generate_spirv(struct spirv_compiler *compiler,
if (compiler->shader_type == VKD3D_SHADER_TYPE_HULL) { - shader_normaliser_init(&normaliser, instructions); + shader_normaliser_init(&normaliser, instructions, compiler->message_context); if ((result = shader_normaliser_flatten_hull_shader_phases(&normaliser)) >= 0) result = shader_normaliser_normalise_hull_shader_control_point_io(&normaliser, &parser->shader_desc.input_signature); diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h index e635a70b..88b79fea 100644 --- a/libs/vkd3d-shader/vkd3d_shader_private.h +++ b/libs/vkd3d-shader/vkd3d_shader_private.h @@ -139,6 +139,8 @@ enum vkd3d_shader_error VKD3D_SHADER_ERROR_D3DBC_OUT_OF_MEMORY = 7004,
VKD3D_SHADER_WARNING_D3DBC_IGNORED_INSTRUCTION_FLAGS= 7300, + + VKD3D_SHADER_ERROR_IR_REGISTER_ORDER_TOO_HIGH = 8000, };
enum vkd3d_shader_opcode @@ -1331,6 +1333,9 @@ int dxbc_writer_write(struct dxbc_writer *dxbc, struct vkd3d_shader_code *code);
struct vkd3d_shader_normaliser { + struct vkd3d_shader_message_context *message_context; + struct vkd3d_shader_location location; + struct vkd3d_shader_instruction_array instructions;
unsigned int max_temp_count; @@ -1344,7 +1349,7 @@ struct vkd3d_shader_normaliser };
void shader_normaliser_init(struct vkd3d_shader_normaliser *normaliser, - struct vkd3d_shader_instruction_array *instructions); + struct vkd3d_shader_instruction_array *instructions, struct vkd3d_shader_message_context *message_context); 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, const struct vkd3d_shader_signature *input_signature);