From: Giovanni Mascellani gmascellani@codeweavers.com
--- libs/vkd3d-shader/ir.c | 4 ++++ libs/vkd3d-shader/vkd3d_shader_private.h | 3 +++ 2 files changed, 7 insertions(+)
diff --git a/libs/vkd3d-shader/ir.c b/libs/vkd3d-shader/ir.c index 511b0e8fa..9c95d2d9d 100644 --- a/libs/vkd3d-shader/ir.c +++ b/libs/vkd3d-shader/ir.c @@ -1492,6 +1492,10 @@ static void vsir_validate_register(struct validation_context *ctx, if (reg->type >= VKD3DSPR_COUNT) validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_REGISTER_TYPE, "Invalid register type %#x.", reg->type); + + if (reg->precision >= VKD3D_SHADER_REGISTER_PRECISION_COUNT) + validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_PRECISION, "Invalid register precision %#x.", + reg->precision); }
static void vsir_validate_dst_param(struct validation_context *ctx, diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h index c9d2dec8b..1b045436d 100644 --- a/libs/vkd3d-shader/vkd3d_shader_private.h +++ b/libs/vkd3d-shader/vkd3d_shader_private.h @@ -198,6 +198,7 @@ enum vkd3d_shader_error VKD3D_SHADER_ERROR_VSIR_INVALID_MODIFIERS = 9004, VKD3D_SHADER_ERROR_VSIR_INVALID_SHIFT = 9005, VKD3D_SHADER_ERROR_VSIR_INVALID_SWIZZLE = 9006, + VKD3D_SHADER_ERROR_VSIR_INVALID_PRECISION = 9007, };
enum vkd3d_shader_opcode @@ -554,6 +555,8 @@ enum vkd3d_shader_register_precision VKD3D_SHADER_REGISTER_PRECISION_MIN_INT_16, VKD3D_SHADER_REGISTER_PRECISION_MIN_UINT_16,
+ VKD3D_SHADER_REGISTER_PRECISION_COUNT, + VKD3D_SHADER_REGISTER_PRECISION_INVALID = ~0u, };
From: Giovanni Mascellani gmascellani@codeweavers.com
--- libs/vkd3d-shader/ir.c | 4 ++++ libs/vkd3d-shader/vkd3d_shader_private.h | 3 +++ 2 files changed, 7 insertions(+)
diff --git a/libs/vkd3d-shader/ir.c b/libs/vkd3d-shader/ir.c index 9c95d2d9d..f97287e9d 100644 --- a/libs/vkd3d-shader/ir.c +++ b/libs/vkd3d-shader/ir.c @@ -1496,6 +1496,10 @@ static void vsir_validate_register(struct validation_context *ctx, if (reg->precision >= VKD3D_SHADER_REGISTER_PRECISION_COUNT) validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_PRECISION, "Invalid register precision %#x.", reg->precision); + + if (reg->data_type >= VKD3D_DATA_COUNT) + validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, "Invalid register data type %#x.", + reg->data_type); }
static void vsir_validate_dst_param(struct validation_context *ctx, diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h index 1b045436d..5dc2adee8 100644 --- a/libs/vkd3d-shader/vkd3d_shader_private.h +++ b/libs/vkd3d-shader/vkd3d_shader_private.h @@ -199,6 +199,7 @@ enum vkd3d_shader_error VKD3D_SHADER_ERROR_VSIR_INVALID_SHIFT = 9005, VKD3D_SHADER_ERROR_VSIR_INVALID_SWIZZLE = 9006, VKD3D_SHADER_ERROR_VSIR_INVALID_PRECISION = 9007, + VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE = 9008, };
enum vkd3d_shader_opcode @@ -577,6 +578,8 @@ enum vkd3d_data_type VKD3D_DATA_UNUSED, VKD3D_DATA_UINT8, VKD3D_DATA_UINT64, + + VKD3D_DATA_COUNT, };
static inline bool data_type_is_integer(enum vkd3d_data_type data_type)
From: Giovanni Mascellani gmascellani@codeweavers.com
--- libs/vkd3d-shader/ir.c | 4 ++++ libs/vkd3d-shader/tpf.c | 2 ++ libs/vkd3d-shader/vkd3d_shader_private.h | 3 +++ 3 files changed, 9 insertions(+)
diff --git a/libs/vkd3d-shader/ir.c b/libs/vkd3d-shader/ir.c index f97287e9d..f5e4b6a47 100644 --- a/libs/vkd3d-shader/ir.c +++ b/libs/vkd3d-shader/ir.c @@ -1500,6 +1500,10 @@ static void vsir_validate_register(struct validation_context *ctx, if (reg->data_type >= VKD3D_DATA_COUNT) validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, "Invalid register data type %#x.", reg->data_type); + + if (reg->dimension >= VSIR_DIMENSION_COUNT) + validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DIMENSION, "Invalid register dimension %#x.", + reg->dimension); }
static void vsir_validate_dst_param(struct validation_context *ctx, diff --git a/libs/vkd3d-shader/tpf.c b/libs/vkd3d-shader/tpf.c index 0ea5a682f..4a098cf81 100644 --- a/libs/vkd3d-shader/tpf.c +++ b/libs/vkd3d-shader/tpf.c @@ -549,6 +549,8 @@ static enum vkd3d_sm4_dimension sm4_dimension_from_vsir_dimension(enum vsir_dime return VKD3D_SM4_DIMENSION_SCALAR; case VSIR_DIMENSION_VEC4: return VKD3D_SM4_DIMENSION_VEC4; + case VSIR_DIMENSION_COUNT: + vkd3d_unreachable(); } vkd3d_unreachable(); } diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h index 5dc2adee8..09f0f3e52 100644 --- a/libs/vkd3d-shader/vkd3d_shader_private.h +++ b/libs/vkd3d-shader/vkd3d_shader_private.h @@ -200,6 +200,7 @@ enum vkd3d_shader_error VKD3D_SHADER_ERROR_VSIR_INVALID_SWIZZLE = 9006, VKD3D_SHADER_ERROR_VSIR_INVALID_PRECISION = 9007, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE = 9008, + VKD3D_SHADER_ERROR_VSIR_INVALID_DIMENSION = 9009, };
enum vkd3d_shader_opcode @@ -593,6 +594,8 @@ enum vsir_dimension VSIR_DIMENSION_NONE, VSIR_DIMENSION_SCALAR, VSIR_DIMENSION_VEC4, + + VSIR_DIMENSION_COUNT, };
enum vkd3d_shader_src_modifier
From: Giovanni Mascellani gmascellani@codeweavers.com
--- libs/vkd3d-shader/ir.c | 4 ++++ libs/vkd3d-shader/vkd3d_shader_private.h | 1 + 2 files changed, 5 insertions(+)
diff --git a/libs/vkd3d-shader/ir.c b/libs/vkd3d-shader/ir.c index f5e4b6a47..70961718a 100644 --- a/libs/vkd3d-shader/ir.c +++ b/libs/vkd3d-shader/ir.c @@ -1504,6 +1504,10 @@ static void vsir_validate_register(struct validation_context *ctx, if (reg->dimension >= VSIR_DIMENSION_COUNT) validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DIMENSION, "Invalid register dimension %#x.", reg->dimension); + + if (reg->idx_count > ARRAY_SIZE(reg->idx)) + validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_INDEX_COUNT, "Invalid register index count %u.", + reg->idx_count); }
static void vsir_validate_dst_param(struct validation_context *ctx, diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h index 09f0f3e52..630d1ef7a 100644 --- a/libs/vkd3d-shader/vkd3d_shader_private.h +++ b/libs/vkd3d-shader/vkd3d_shader_private.h @@ -201,6 +201,7 @@ enum vkd3d_shader_error VKD3D_SHADER_ERROR_VSIR_INVALID_PRECISION = 9007, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE = 9008, VKD3D_SHADER_ERROR_VSIR_INVALID_DIMENSION = 9009, + VKD3D_SHADER_ERROR_VSIR_INVALID_INDEX_COUNT = 9010, };
enum vkd3d_shader_opcode
From: Giovanni Mascellani gmascellani@codeweavers.com
--- libs/vkd3d-shader/ir.c | 9 +++++++++ libs/vkd3d-shader/vkd3d_shader_private.h | 1 + 2 files changed, 10 insertions(+)
diff --git a/libs/vkd3d-shader/ir.c b/libs/vkd3d-shader/ir.c index 70961718a..8907fe5fc 100644 --- a/libs/vkd3d-shader/ir.c +++ b/libs/vkd3d-shader/ir.c @@ -1489,6 +1489,8 @@ static void VKD3D_PRINTF_FUNC(3, 4) validator_error(struct validation_context *c static void vsir_validate_register(struct validation_context *ctx, const struct vkd3d_shader_register *reg) { + unsigned int i; + if (reg->type >= VKD3DSPR_COUNT) validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_REGISTER_TYPE, "Invalid register type %#x.", reg->type); @@ -1508,6 +1510,13 @@ static void vsir_validate_register(struct validation_context *ctx, if (reg->idx_count > ARRAY_SIZE(reg->idx)) validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_INDEX_COUNT, "Invalid register index count %u.", reg->idx_count); + + for (i = reg->idx_count; i < ARRAY_SIZE(reg->idx); ++i) + { + if (reg->idx[i].offset != ~0u || reg->idx[i].rel_addr != NULL) + validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_INDEX, "Unused index %u has offset %#x and non-NULL relative address.", + i, reg->idx[i].offset); + } }
static void vsir_validate_dst_param(struct validation_context *ctx, diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h index 630d1ef7a..f399f91a3 100644 --- a/libs/vkd3d-shader/vkd3d_shader_private.h +++ b/libs/vkd3d-shader/vkd3d_shader_private.h @@ -202,6 +202,7 @@ enum vkd3d_shader_error VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE = 9008, VKD3D_SHADER_ERROR_VSIR_INVALID_DIMENSION = 9009, VKD3D_SHADER_ERROR_VSIR_INVALID_INDEX_COUNT = 9010, + VKD3D_SHADER_ERROR_VSIR_INVALID_INDEX = 9011, };
enum vkd3d_shader_opcode
From: Giovanni Mascellani gmascellani@codeweavers.com
--- libs/vkd3d-shader/ir.c | 27 ++++++++++++++++++++++++ libs/vkd3d-shader/vkd3d_shader_private.h | 2 ++ 2 files changed, 29 insertions(+)
diff --git a/libs/vkd3d-shader/ir.c b/libs/vkd3d-shader/ir.c index 8907fe5fc..80eb06bdb 100644 --- a/libs/vkd3d-shader/ir.c +++ b/libs/vkd3d-shader/ir.c @@ -1563,6 +1563,22 @@ static void vsir_validate_src_param(struct validation_context *ctx, src->modifiers); }
+static void vsir_validate_dst_count(struct validation_context *ctx, + const struct vkd3d_shader_instruction *instruction, unsigned int count) +{ + if (instruction->dst_count != 0) + validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DEST_COUNT, + "Invalid destination count %u for an instruction of type %#x.", instruction->dst_count, instruction->handler_idx); +} + +static void vsir_validate_src_count(struct validation_context *ctx, + const struct vkd3d_shader_instruction *instruction, unsigned int count) +{ + if (instruction->src_count != 0) + validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_SOURCE_COUNT, + "Invalid source count %u for an instruction of type %#x.", instruction->src_count, instruction->handler_idx); +} + static void vsir_validate_instruction(struct validation_context *ctx) { const struct vkd3d_shader_instruction *instruction = &ctx->parser->instructions.elements[ctx->instruction_idx]; @@ -1581,6 +1597,17 @@ static void vsir_validate_instruction(struct validation_context *ctx) validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_HANDLER, "Invalid instruction handler %#x.", instruction->handler_idx); } + + switch (instruction->handler_idx) + { + case VKD3DSIH_DCL_TEMPS: + vsir_validate_dst_count(ctx, instruction, 0); + vsir_validate_src_count(ctx, instruction, 0); + break; + + default: + break; + } }
void vsir_validate(struct vkd3d_shader_parser *parser) diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h index f399f91a3..e57cb44c5 100644 --- a/libs/vkd3d-shader/vkd3d_shader_private.h +++ b/libs/vkd3d-shader/vkd3d_shader_private.h @@ -203,6 +203,8 @@ enum vkd3d_shader_error VKD3D_SHADER_ERROR_VSIR_INVALID_DIMENSION = 9009, VKD3D_SHADER_ERROR_VSIR_INVALID_INDEX_COUNT = 9010, VKD3D_SHADER_ERROR_VSIR_INVALID_INDEX = 9011, + VKD3D_SHADER_ERROR_VSIR_INVALID_DEST_COUNT = 9012, + VKD3D_SHADER_ERROR_VSIR_INVALID_SOURCE_COUNT = 9013, };
enum vkd3d_shader_opcode
From: Giovanni Mascellani gmascellani@codeweavers.com
--- libs/vkd3d-shader/ir.c | 27 ++++++++++++++++++++++++ libs/vkd3d-shader/vkd3d_shader_private.h | 1 + 2 files changed, 28 insertions(+)
diff --git a/libs/vkd3d-shader/ir.c b/libs/vkd3d-shader/ir.c index 80eb06bdb..49b5ea4a1 100644 --- a/libs/vkd3d-shader/ir.c +++ b/libs/vkd3d-shader/ir.c @@ -1467,6 +1467,8 @@ struct validation_context { struct vkd3d_shader_parser *parser; size_t instruction_idx; + bool dcl_temps_found; + unsigned int temp_count; };
static void VKD3D_PRINTF_FUNC(3, 4) validator_error(struct validation_context *ctx, @@ -1517,6 +1519,25 @@ static void vsir_validate_register(struct validation_context *ctx, validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_INDEX, "Unused index %u has offset %#x and non-NULL relative address.", i, reg->idx[i].offset); } + + switch (reg->type) + { + case VKD3DSPR_TEMP: + if (reg->idx_count != 1) + validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_INDEX_COUNT, "Invalid index count %u for a TEMP register.", + reg->idx_count); + + if (reg->idx_count >= 1 && 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_count >= 1 && reg->idx[0].offset >= ctx->temp_count) + validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_INDEX, "TEMP register index %u exceeds the declared count %u.", + reg->idx[0].offset, ctx->temp_count); + break; + + default: + break; + } }
static void vsir_validate_dst_param(struct validation_context *ctx, @@ -1603,6 +1624,12 @@ static void vsir_validate_instruction(struct validation_context *ctx) case VKD3DSIH_DCL_TEMPS: vsir_validate_dst_count(ctx, instruction, 0); vsir_validate_src_count(ctx, instruction, 0); + /* TODO Check that each phase in a hull shader has a at + * most one occurrence. */ + if (ctx->dcl_temps_found && ctx->parser->shader_version.type != VKD3D_SHADER_TYPE_HULL) + validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_DUPLICATE_DCL_TEMPS, "Duplicate DCL_TEMPS instruction."); + ctx->dcl_temps_found = true; + ctx->temp_count = instruction->declaration.count; break;
default: diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h index e57cb44c5..bfb8edb5b 100644 --- a/libs/vkd3d-shader/vkd3d_shader_private.h +++ b/libs/vkd3d-shader/vkd3d_shader_private.h @@ -205,6 +205,7 @@ enum vkd3d_shader_error VKD3D_SHADER_ERROR_VSIR_INVALID_INDEX = 9011, VKD3D_SHADER_ERROR_VSIR_INVALID_DEST_COUNT = 9012, VKD3D_SHADER_ERROR_VSIR_INVALID_SOURCE_COUNT = 9013, + VKD3D_SHADER_ERROR_VSIR_DUPLICATE_DCL_TEMPS = 9014, };
enum vkd3d_shader_opcode