mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-25 00:00:11 +01:00
pvr: Validate instruction repeat and src/dst sizes
Signed-off-by: Simon Perretta <simon.perretta@imgtec.com> Acked-by: Frank Binns <frank.binns@imgtec.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/20430>
This commit is contained in:
parent
8ac16c97cf
commit
1bd84f4753
3 changed files with 247 additions and 67 deletions
|
|
@ -37,17 +37,12 @@
|
|||
/* TODO NEXT: Make things const that can be. */
|
||||
|
||||
/* TODO NEXT: Use debug message functions in u_debug.h */
|
||||
/* TODO NEXT: for validating `repeat` values, add to rogue instr info which
|
||||
* srcs/dsts will be affected and will need to be checked */
|
||||
|
||||
/* TODO NEXT: Reg/src/dst things are often just simple comparisons; write
|
||||
* per-instr-type comparison function that also checks things like modifiers. */
|
||||
|
||||
/* TODO NEXT: In "unreachable"s, replace "invalid" with "unsupported". */
|
||||
|
||||
/* TODO NEXT: go through things that return bool and ensure they return 1 or 0,
|
||||
* not a mask (whose first bit may be non-zero)! */
|
||||
|
||||
#include "compiler/nir/nir.h"
|
||||
#include "compiler/shader_enums.h"
|
||||
#include "compiler/spirv/nir_spirv.h"
|
||||
|
|
@ -756,8 +751,7 @@ static inline enum rogue_reg_class rogue_ref_get_reg_class(const rogue_ref *ref)
|
|||
return ref->regarray->regs[0]->class;
|
||||
else if (rogue_ref_is_reg(ref))
|
||||
return ref->reg->class;
|
||||
else
|
||||
unreachable("Ref is not a reg/regarray.");
|
||||
unreachable("Ref is not a reg/regarray.");
|
||||
}
|
||||
|
||||
static inline unsigned rogue_ref_get_reg_index(const rogue_ref *ref)
|
||||
|
|
@ -766,8 +760,14 @@ static inline unsigned rogue_ref_get_reg_index(const rogue_ref *ref)
|
|||
return ref->regarray->regs[0]->index;
|
||||
else if (rogue_ref_is_reg(ref))
|
||||
return ref->reg->index;
|
||||
else
|
||||
unreachable("Ref is not a reg/regarray.");
|
||||
unreachable("Ref is not a reg/regarray.");
|
||||
}
|
||||
|
||||
static inline unsigned rogue_ref_get_regarray_size(const rogue_ref *ref)
|
||||
{
|
||||
if (rogue_ref_is_regarray(ref))
|
||||
return ref->regarray->size;
|
||||
unreachable("Ref is not a regarray.");
|
||||
}
|
||||
|
||||
#define ROGUE_INTERNAL0_OFFSET 36
|
||||
|
|
@ -1046,6 +1046,9 @@ typedef struct rogue_ctrl_op_mod_info {
|
|||
extern const rogue_ctrl_op_mod_info
|
||||
rogue_ctrl_op_mod_infos[ROGUE_CTRL_OP_MOD_COUNT];
|
||||
|
||||
#define ROGUE_CTRL_OP_MAX_SRCS 7
|
||||
#define ROGUE_CTRL_OP_MAX_DSTS 2
|
||||
|
||||
typedef struct rogue_ctrl_op_info {
|
||||
const char *str;
|
||||
|
||||
|
|
@ -1058,6 +1061,17 @@ typedef struct rogue_ctrl_op_info {
|
|||
unsigned num_srcs;
|
||||
|
||||
uint64_t supported_op_mods;
|
||||
uint64_t supported_dst_mods[ROGUE_CTRL_OP_MAX_DSTS];
|
||||
uint64_t supported_src_mods[ROGUE_CTRL_OP_MAX_SRCS];
|
||||
|
||||
uint64_t supported_dst_types[ROGUE_CTRL_OP_MAX_DSTS];
|
||||
uint64_t supported_src_types[ROGUE_CTRL_OP_MAX_SRCS];
|
||||
|
||||
unsigned dst_stride[ROGUE_CTRL_OP_MAX_DSTS];
|
||||
unsigned src_stride[ROGUE_CTRL_OP_MAX_SRCS];
|
||||
|
||||
uint64_t dst_repeat_mask;
|
||||
uint64_t src_repeat_mask;
|
||||
} rogue_ctrl_op_info;
|
||||
|
||||
extern const rogue_ctrl_op_info rogue_ctrl_op_infos[ROGUE_CTRL_OP_COUNT];
|
||||
|
|
@ -1097,9 +1111,14 @@ typedef struct rogue_alu_op_info {
|
|||
uint64_t supported_dst_mods[ROGUE_ALU_OP_MAX_DSTS];
|
||||
uint64_t supported_src_mods[ROGUE_ALU_OP_MAX_SRCS];
|
||||
|
||||
/* TODO NEXT: Do the same for other instruction types. */
|
||||
uint64_t supported_dst_types[ROGUE_ALU_OP_MAX_DSTS];
|
||||
uint64_t supported_src_types[ROGUE_ALU_OP_MAX_SRCS];
|
||||
|
||||
unsigned dst_stride[ROGUE_CTRL_OP_MAX_DSTS];
|
||||
unsigned src_stride[ROGUE_CTRL_OP_MAX_SRCS];
|
||||
|
||||
uint64_t dst_repeat_mask;
|
||||
uint64_t src_repeat_mask;
|
||||
} rogue_alu_op_info;
|
||||
|
||||
extern const rogue_alu_op_info rogue_alu_op_infos[ROGUE_ALU_OP_COUNT];
|
||||
|
|
@ -1270,6 +1289,17 @@ typedef struct rogue_backend_op_info {
|
|||
rogue_backend_io_info phase_io;
|
||||
|
||||
uint64_t supported_op_mods;
|
||||
uint64_t supported_dst_mods[ROGUE_BACKEND_OP_MAX_DSTS];
|
||||
uint64_t supported_src_mods[ROGUE_BACKEND_OP_MAX_SRCS];
|
||||
|
||||
uint64_t supported_dst_types[ROGUE_BACKEND_OP_MAX_DSTS];
|
||||
uint64_t supported_src_types[ROGUE_BACKEND_OP_MAX_SRCS];
|
||||
|
||||
unsigned dst_stride[ROGUE_CTRL_OP_MAX_DSTS];
|
||||
unsigned src_stride[ROGUE_CTRL_OP_MAX_SRCS];
|
||||
|
||||
uint64_t dst_repeat_mask;
|
||||
uint64_t src_repeat_mask;
|
||||
} rogue_backend_op_info;
|
||||
|
||||
extern const rogue_backend_op_info
|
||||
|
|
@ -1321,9 +1351,6 @@ rogue_backend_op_mod_is_set(const rogue_backend_instr *backend,
|
|||
rogue_backend_instr *rogue_backend_instr_create(rogue_block *block,
|
||||
enum rogue_backend_op op);
|
||||
|
||||
#define ROGUE_CTRL_OP_MAX_SRCS 7
|
||||
#define ROGUE_CTRL_OP_MAX_DSTS 2
|
||||
|
||||
typedef struct rogue_ctrl_instr {
|
||||
rogue_instr instr;
|
||||
|
||||
|
|
@ -1378,21 +1405,32 @@ enum rogue_bitwise_op {
|
|||
ROGUE_BITWISE_OP_COUNT,
|
||||
};
|
||||
|
||||
#define ROGUE_BITWISE_OP_MAX_SRCS 7
|
||||
#define ROGUE_BITWISE_OP_MAX_DSTS 2
|
||||
|
||||
typedef struct rogue_bitwise_op_info {
|
||||
const char *str;
|
||||
|
||||
unsigned num_dsts;
|
||||
unsigned num_srcs;
|
||||
|
||||
/* uint64_t supported_op_mods; */
|
||||
uint64_t supported_op_mods;
|
||||
uint64_t supported_dst_mods[ROGUE_BITWISE_OP_MAX_DSTS];
|
||||
uint64_t supported_src_mods[ROGUE_BITWISE_OP_MAX_SRCS];
|
||||
|
||||
uint64_t supported_dst_types[ROGUE_BITWISE_OP_MAX_DSTS];
|
||||
uint64_t supported_src_types[ROGUE_BITWISE_OP_MAX_SRCS];
|
||||
|
||||
unsigned dst_stride[ROGUE_CTRL_OP_MAX_DSTS];
|
||||
unsigned src_stride[ROGUE_CTRL_OP_MAX_SRCS];
|
||||
|
||||
uint64_t dst_repeat_mask;
|
||||
uint64_t src_repeat_mask;
|
||||
} rogue_bitwise_op_info;
|
||||
|
||||
extern const rogue_bitwise_op_info
|
||||
rogue_bitwise_op_infos[ROGUE_BITWISE_OP_COUNT];
|
||||
|
||||
#define ROGUE_BITWISE_OP_MAX_SRCS 7
|
||||
#define ROGUE_BITWISE_OP_MAX_DSTS 2
|
||||
|
||||
typedef struct rogue_bitwise_dst {
|
||||
rogue_ref ref;
|
||||
unsigned index;
|
||||
|
|
|
|||
|
|
@ -221,6 +221,7 @@ const rogue_ctrl_op_mod_info rogue_ctrl_op_mod_infos[ROGUE_CTRL_OP_MOD_COUNT] =
|
|||
};
|
||||
|
||||
#define OM(op_mod) BITFIELD64_BIT(ROGUE_CTRL_OP_MOD_##op_mod)
|
||||
#define T(type) BITFIELD64_BIT(ROGUE_REF_TYPE_##type - 1)
|
||||
const rogue_ctrl_op_info rogue_ctrl_op_infos[ROGUE_CTRL_OP_COUNT] = {
|
||||
[ROGUE_CTRL_OP_INVALID] = { .str = "!INVALID!", },
|
||||
[ROGUE_CTRL_OP_END] = { .str = "end", .ends_block = true, },
|
||||
|
|
@ -228,16 +229,23 @@ const rogue_ctrl_op_info rogue_ctrl_op_infos[ROGUE_CTRL_OP_COUNT] = {
|
|||
.supported_op_mods = OM(END),
|
||||
},
|
||||
[ROGUE_CTRL_OP_BA] = { .str = "ba", .has_target = true, .ends_block = true, },
|
||||
[ROGUE_CTRL_OP_WDF] = { .str = "wdf", .num_srcs = 1, },
|
||||
[ROGUE_CTRL_OP_WDF] = { .str = "wdf", .num_srcs = 1,
|
||||
.supported_src_types = { [0] = T(DRC), },
|
||||
},
|
||||
};
|
||||
#undef T
|
||||
#undef OM
|
||||
|
||||
#define IO(io) ROGUE_IO_##io
|
||||
#define OM(op_mod) BITFIELD64_BIT(ROGUE_BACKEND_OP_MOD_##op_mod)
|
||||
#define T(type) BITFIELD64_BIT(ROGUE_REF_TYPE_##type - 1)
|
||||
#define B(n) BITFIELD64_BIT(n)
|
||||
const rogue_backend_op_info rogue_backend_op_infos[ROGUE_BACKEND_OP_COUNT] = {
|
||||
[ROGUE_BACKEND_OP_INVALID] = { .str = "!INVALID!", },
|
||||
[ROGUE_BACKEND_OP_UVSW_WRITE] = { .str = "uvsw.write", .num_dsts = 1, .num_srcs = 1,
|
||||
.phase_io = { .src[0] = IO(W0), },
|
||||
.supported_dst_types = { [0] = T(REG), },
|
||||
.supported_src_types = { [0] = T(REG), },
|
||||
},
|
||||
[ROGUE_BACKEND_OP_UVSW_EMIT] = { .str = "uvsw.emit", },
|
||||
[ROGUE_BACKEND_OP_UVSW_ENDTASK] = { .str = "uvsw.endtask", },
|
||||
|
|
@ -245,12 +253,27 @@ const rogue_backend_op_info rogue_backend_op_infos[ROGUE_BACKEND_OP_COUNT] = {
|
|||
[ROGUE_BACKEND_OP_UVSW_EMITTHENENDTASK] = { .str = "uvsw.emitthenendtask", },
|
||||
[ROGUE_BACKEND_OP_UVSW_WRITETHENEMITTHENENDTASK] = { .str = "uvsw.writethenemitthenendtask", .num_dsts = 1, .num_srcs = 1,
|
||||
.phase_io = { .src[0] = IO(W0), },
|
||||
.supported_dst_types = { [0] = T(REG), },
|
||||
.supported_src_types = { [0] = T(REG), },
|
||||
},
|
||||
[ROGUE_BACKEND_OP_FITRP_PIXEL] = { .str = "fitrp.pixel", .num_dsts = 1, .num_srcs = 4,
|
||||
.phase_io = { .dst[0] = IO(S3), .src[1] = IO(S0), .src[2] = IO(S2), },
|
||||
.supported_op_mods = OM(SAT),
|
||||
.supported_dst_types = { [0] = T(REG), },
|
||||
.supported_src_types = {
|
||||
[0] = T(DRC),
|
||||
[1] = T(REGARRAY),
|
||||
[2] = T(REGARRAY),
|
||||
[3] = T(VAL),
|
||||
},
|
||||
.src_stride = {
|
||||
[1] = 3,
|
||||
[2] = 3,
|
||||
},
|
||||
},
|
||||
};
|
||||
#undef B
|
||||
#undef T
|
||||
#undef OM
|
||||
#undef IO
|
||||
|
||||
|
|
@ -298,6 +321,7 @@ const rogue_io_info rogue_io_infos[ROGUE_IO_COUNT] = {
|
|||
#define PH(type) ROGUE_INSTR_PHASE_##type
|
||||
#define IO(io) ROGUE_IO_##io
|
||||
#define T(type) BITFIELD64_BIT(ROGUE_REF_TYPE_##type - 1)
|
||||
#define B(n) BITFIELD64_BIT(n)
|
||||
const rogue_alu_op_info rogue_alu_op_infos[ROGUE_ALU_OP_COUNT] = {
|
||||
[ROGUE_ALU_OP_INVALID] = { .str = "!INVALID!", },
|
||||
[ROGUE_ALU_OP_MBYP] = { .str = "mbyp", .num_dsts = 1, .num_srcs = 1,
|
||||
|
|
@ -360,6 +384,7 @@ const rogue_alu_op_info rogue_alu_op_infos[ROGUE_ALU_OP_COUNT] = {
|
|||
.supported_src_types = {
|
||||
[0] = T(REGARRAY),
|
||||
},
|
||||
.src_repeat_mask = B(0),
|
||||
},
|
||||
/* This mov is "fake" since it can be lowered to a MBYP, make a new instruction for real mov (call it MOVD?). */
|
||||
[ROGUE_ALU_OP_MOV] = { .str = "mov", .num_dsts = 1, .num_srcs = 1,
|
||||
|
|
@ -376,6 +401,7 @@ const rogue_alu_op_info rogue_alu_op_infos[ROGUE_ALU_OP_COUNT] = {
|
|||
[ROGUE_ALU_OP_FMIN] = { .str = "fmin", .num_dsts = 1, .num_srcs = 2, }, /* TODO */
|
||||
[ROGUE_ALU_OP_SEL] = { .str = "sel", .num_dsts = 1, .num_srcs = 3, }, /* TODO */
|
||||
};
|
||||
#undef B
|
||||
#undef T
|
||||
#undef IO
|
||||
#undef PH
|
||||
|
|
|
|||
|
|
@ -41,9 +41,6 @@
|
|||
* through ISR and add any other restrictions). */
|
||||
/* TODO: Remember that some instructions have the DESTINATION as a source
|
||||
* (register pointers), e.g. fitrp using S3 */
|
||||
/* TODO NEXT: Add field to instr_info that specifies which source/destination
|
||||
* should be affected by instruction repeating. */
|
||||
/* TODO NEXT: Validate backend and control sources/dests. */
|
||||
/* TODO: Go through and make sure that validation state is being properly
|
||||
* updated as so to allow for validation_log to print enough info. */
|
||||
|
||||
|
|
@ -54,10 +51,14 @@ typedef struct rogue_validation_state {
|
|||
const rogue_shader *shader; /** The shader being validated. */
|
||||
const char *when; /** Description of the validation being done. */
|
||||
bool nonfatal; /** Don't stop at the first error.*/
|
||||
const rogue_instr *instr; /** Current instruction being validated. */
|
||||
const rogue_instr_group *group; /** Current instruction group being
|
||||
validated. */
|
||||
const rogue_ref *ref; /** Current reference being validated. */
|
||||
struct {
|
||||
const rogue_instr *instr; /** Current instruction being validated. */
|
||||
const rogue_instr_group *group; /** Current instruction group being
|
||||
validated. */
|
||||
const rogue_ref *ref; /** Current reference being validated. */
|
||||
bool src; /** Current reference type (src/dst). */
|
||||
unsigned param; /** Current reference src/dst index. */
|
||||
} ctx;
|
||||
struct util_dynarray *error_msgs; /** Error message list. */
|
||||
} rogue_validation_state;
|
||||
|
||||
|
|
@ -73,7 +74,6 @@ static bool validate_print_errors(rogue_validation_state *state)
|
|||
|
||||
fputs("\n", stderr);
|
||||
|
||||
/* TODO: Figure out if/when to print this. */
|
||||
rogue_print_shader(stderr, state->shader);
|
||||
fputs("\n", stderr);
|
||||
|
||||
|
|
@ -86,12 +86,15 @@ static void PRINTFLIKE(2, 3)
|
|||
char *msg = ralloc_asprintf(state->error_msgs, "Validation error");
|
||||
|
||||
/* Add info about the item that was being validated. */
|
||||
if (state->instr) {
|
||||
ralloc_asprintf_append(&msg, " instr %u", state->instr->index);
|
||||
if (state->ctx.instr) {
|
||||
ralloc_asprintf_append(&msg, " instr %u", state->ctx.instr->index);
|
||||
}
|
||||
|
||||
if (state->ref) {
|
||||
/* TODO: Find a way to get an index. */
|
||||
if (state->ctx.ref) {
|
||||
ralloc_asprintf_append(&msg,
|
||||
" %s %u",
|
||||
state->ctx.src ? "src" : "dst",
|
||||
state->ctx.param);
|
||||
}
|
||||
|
||||
ralloc_asprintf_append(&msg, ": ");
|
||||
|
|
@ -143,37 +146,80 @@ static void validate_regarray(rogue_validation_state *state,
|
|||
}
|
||||
}
|
||||
|
||||
static void validate_alu_dst(rogue_validation_state *state,
|
||||
const rogue_instr_dst *dst,
|
||||
uint64_t supported_dst_types)
|
||||
static void validate_dst(rogue_validation_state *state,
|
||||
const rogue_instr_dst *dst,
|
||||
uint64_t supported_dst_types,
|
||||
unsigned i,
|
||||
unsigned stride,
|
||||
unsigned repeat,
|
||||
uint64_t repeat_mask)
|
||||
{
|
||||
state->ref = &dst->ref;
|
||||
state->ctx.ref = &dst->ref;
|
||||
state->ctx.src = false;
|
||||
state->ctx.param = i;
|
||||
|
||||
if (rogue_ref_is_null(&dst->ref))
|
||||
validate_log(state, "ALU destination has not been set.");
|
||||
|
||||
if (!state->shader->is_grouped)
|
||||
if (!rogue_ref_type_supported(dst->ref.type, supported_dst_types))
|
||||
validate_log(state, "Unsupported ALU destination type.");
|
||||
|
||||
state->ref = NULL;
|
||||
}
|
||||
|
||||
static void validate_alu_src(rogue_validation_state *state,
|
||||
const rogue_instr_src *src,
|
||||
uint64_t supported_src_types)
|
||||
{
|
||||
state->ref = &src->ref;
|
||||
|
||||
if (rogue_ref_is_null(&src->ref))
|
||||
validate_log(state, "ALU source has not been set.");
|
||||
validate_log(state, "Destination has not been set.");
|
||||
|
||||
if (!state->shader->is_grouped) {
|
||||
if (!rogue_ref_type_supported(src->ref.type, supported_src_types))
|
||||
validate_log(state, "Unsupported ALU source type.");
|
||||
unsigned dst_size = stride + 1;
|
||||
if (repeat_mask & (1 << i))
|
||||
dst_size *= repeat;
|
||||
|
||||
if (rogue_ref_is_regarray(&dst->ref)) {
|
||||
if (rogue_ref_get_regarray_size(&dst->ref) != dst_size) {
|
||||
validate_log(state,
|
||||
"Expected regarray size %u, got %u.",
|
||||
dst_size,
|
||||
rogue_ref_get_regarray_size(&dst->ref));
|
||||
}
|
||||
} else if (dst_size > 1) {
|
||||
validate_log(state, "Expected regarray type for destination.");
|
||||
}
|
||||
|
||||
if (!rogue_ref_type_supported(dst->ref.type, supported_dst_types))
|
||||
validate_log(state, "Unsupported destination type.");
|
||||
}
|
||||
|
||||
state->ref = NULL;
|
||||
state->ctx.ref = NULL;
|
||||
}
|
||||
|
||||
static void validate_src(rogue_validation_state *state,
|
||||
const rogue_instr_src *src,
|
||||
uint64_t supported_src_types,
|
||||
unsigned i,
|
||||
unsigned stride,
|
||||
unsigned repeat,
|
||||
uint64_t repeat_mask)
|
||||
{
|
||||
state->ctx.ref = &src->ref;
|
||||
state->ctx.src = true;
|
||||
state->ctx.param = i;
|
||||
|
||||
if (rogue_ref_is_null(&src->ref))
|
||||
validate_log(state, "Source has not been set.");
|
||||
|
||||
if (!state->shader->is_grouped) {
|
||||
unsigned src_size = stride + 1;
|
||||
if (repeat_mask & (1 << i))
|
||||
src_size *= repeat;
|
||||
|
||||
if (rogue_ref_is_regarray(&src->ref)) {
|
||||
if (rogue_ref_get_regarray_size(&src->ref) != src_size) {
|
||||
validate_log(state,
|
||||
"Expected regarray size %u, got %u.",
|
||||
src_size,
|
||||
rogue_ref_get_regarray_size(&src->ref));
|
||||
}
|
||||
} else if (src_size > 1) {
|
||||
validate_log(state, "Expected regarray type for source.");
|
||||
}
|
||||
|
||||
if (!rogue_ref_type_supported(src->ref.type, supported_src_types))
|
||||
validate_log(state, "Unsupported source type.");
|
||||
}
|
||||
|
||||
state->ctx.ref = NULL;
|
||||
}
|
||||
|
||||
static void validate_alu_instr(rogue_validation_state *state,
|
||||
|
|
@ -194,12 +240,32 @@ static void validate_alu_instr(rogue_validation_state *state,
|
|||
if (!rogue_mods_supported(alu->mod, info->supported_op_mods))
|
||||
validate_log(state, "Unsupported ALU op modifiers.");
|
||||
|
||||
/* Validate destinations and sources. */
|
||||
for (unsigned i = 0; i < info->num_dsts; ++i)
|
||||
validate_alu_dst(state, &alu->dst[i], info->supported_dst_types[i]);
|
||||
/* Instruction repeat checks. */
|
||||
if (alu->instr.repeat > 1 && !info->dst_repeat_mask &&
|
||||
!info->src_repeat_mask) {
|
||||
validate_log(state, "Repeat set for ALU op without repeat support.");
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i < info->num_srcs; ++i)
|
||||
validate_alu_src(state, &alu->src[i], info->supported_src_types[i]);
|
||||
/* Validate destinations and sources. */
|
||||
for (unsigned i = 0; i < info->num_dsts; ++i) {
|
||||
validate_dst(state,
|
||||
&alu->dst[i],
|
||||
info->supported_dst_types[i],
|
||||
i,
|
||||
info->dst_stride[i],
|
||||
alu->instr.repeat,
|
||||
info->dst_repeat_mask);
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i < info->num_srcs; ++i) {
|
||||
validate_src(state,
|
||||
&alu->src[i],
|
||||
info->supported_src_types[i],
|
||||
i,
|
||||
info->src_stride[i],
|
||||
alu->instr.repeat,
|
||||
info->src_repeat_mask);
|
||||
}
|
||||
|
||||
/* TODO: Check that the src_use and dst_write fields are correct? */
|
||||
}
|
||||
|
|
@ -217,7 +283,33 @@ static void validate_backend_instr(rogue_validation_state *state,
|
|||
if (!rogue_mods_supported(backend->mod, info->supported_op_mods))
|
||||
validate_log(state, "Unsupported backend op modifiers.");
|
||||
|
||||
/* TODO: Validate dests and srcs? */
|
||||
/* Instruction repeat checks. */
|
||||
if (backend->instr.repeat > 1 && !info->dst_repeat_mask &&
|
||||
!info->src_repeat_mask) {
|
||||
validate_log(state, "Repeat set for backend op without repeat support.");
|
||||
}
|
||||
|
||||
/* Validate destinations and sources. */
|
||||
for (unsigned i = 0; i < info->num_dsts; ++i) {
|
||||
validate_dst(state,
|
||||
&backend->dst[i],
|
||||
info->supported_dst_types[i],
|
||||
i,
|
||||
info->dst_stride[i],
|
||||
backend->instr.repeat,
|
||||
info->dst_repeat_mask);
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i < info->num_srcs; ++i) {
|
||||
validate_src(state,
|
||||
&backend->src[i],
|
||||
info->supported_src_types[i],
|
||||
i,
|
||||
info->src_stride[i],
|
||||
backend->instr.repeat,
|
||||
info->src_repeat_mask);
|
||||
}
|
||||
|
||||
/* TODO: Check that the src_use and dst_write fields are correct? */
|
||||
}
|
||||
|
||||
|
|
@ -241,7 +333,33 @@ static bool validate_ctrl_instr(rogue_validation_state *state,
|
|||
if (!rogue_mods_supported(ctrl->mod, info->supported_op_mods))
|
||||
validate_log(state, "Unsupported CTRL op modifiers.");
|
||||
|
||||
/* TODO: Validate dests and srcs? */
|
||||
/* Instruction repeat checks. */
|
||||
if (ctrl->instr.repeat > 1 && !info->dst_repeat_mask &&
|
||||
!info->src_repeat_mask) {
|
||||
validate_log(state, "Repeat set for CTRL op without repeat support.");
|
||||
}
|
||||
|
||||
/* Validate destinations and sources. */
|
||||
for (unsigned i = 0; i < info->num_dsts; ++i) {
|
||||
validate_dst(state,
|
||||
&ctrl->dst[i],
|
||||
info->supported_dst_types[i],
|
||||
i,
|
||||
info->dst_stride[i],
|
||||
ctrl->instr.repeat,
|
||||
info->dst_repeat_mask);
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i < info->num_srcs; ++i) {
|
||||
validate_src(state,
|
||||
&ctrl->src[i],
|
||||
info->supported_src_types[i],
|
||||
i,
|
||||
info->src_stride[i],
|
||||
ctrl->instr.repeat,
|
||||
info->src_repeat_mask);
|
||||
}
|
||||
|
||||
/* TODO: Check that the src_use and dst_write fields are correct? */
|
||||
|
||||
/* nop.end counts as a end-of-block instruction. */
|
||||
|
|
@ -259,7 +377,7 @@ static bool validate_ctrl_instr(rogue_validation_state *state,
|
|||
static bool validate_instr(rogue_validation_state *state,
|
||||
const rogue_instr *instr)
|
||||
{
|
||||
state->instr = instr;
|
||||
state->ctx.instr = instr;
|
||||
|
||||
bool ends_block = false;
|
||||
|
||||
|
|
@ -287,7 +405,7 @@ static bool validate_instr(rogue_validation_state *state,
|
|||
if (!ends_block)
|
||||
ends_block = instr->end;
|
||||
|
||||
state->instr = NULL;
|
||||
state->ctx.instr = NULL;
|
||||
|
||||
return ends_block;
|
||||
}
|
||||
|
|
@ -296,7 +414,7 @@ static bool validate_instr(rogue_validation_state *state,
|
|||
static bool validate_instr_group(rogue_validation_state *state,
|
||||
const rogue_instr_group *group)
|
||||
{
|
||||
state->group = group;
|
||||
state->ctx.group = group;
|
||||
/* TODO: Validate group properties. */
|
||||
/* TODO: Check for pseudo-instructions. */
|
||||
|
||||
|
|
@ -315,7 +433,7 @@ static bool validate_instr_group(rogue_validation_state *state,
|
|||
ends_block = validate_instr(state, instr);
|
||||
}
|
||||
|
||||
state->group = NULL;
|
||||
state->ctx.group = NULL;
|
||||
|
||||
if (group->header.alu != ROGUE_ALU_CONTROL)
|
||||
return group->header.end;
|
||||
|
|
@ -485,8 +603,6 @@ static void validate_reg_state(rogue_validation_state *state,
|
|||
}
|
||||
}
|
||||
|
||||
/* TODO: To properly test this and see what needs validating, try and write some
|
||||
* failing tests and then filling them from there. */
|
||||
PUBLIC
|
||||
bool rogue_validate_shader(rogue_shader *shader, const char *when)
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue