pvr: Add memory load support

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/21331>
This commit is contained in:
Simon Perretta
2023-02-07 10:53:13 +00:00
committed by Marge Bot
parent 81f86a559c
commit 93fa2f6265
9 changed files with 207 additions and 5 deletions

View File

@@ -546,6 +546,14 @@ static void rogue_calc_backend_instrs_size(rogue_instr_group *group,
group->size.instrs[phase] = 1; group->size.instrs[phase] = 1;
break; break;
case ROGUE_BACKEND_OP_LD:
group->size.instrs[phase] = 2;
/* TODO: or, if slccachemode is being overridden */
if (rogue_ref_is_val(&backend->src[1].ref))
group->size.instrs[phase] = 3;
break;
default: default:
unreachable("Unsupported backend op."); unreachable("Unsupported backend op.");
} }

View File

@@ -807,6 +807,11 @@ static inline bool rogue_ref_is_io_none(const rogue_ref *ref)
return rogue_ref_get_io(ref) == ROGUE_IO_NONE; return rogue_ref_get_io(ref) == ROGUE_IO_NONE;
} }
static inline unsigned rogue_ref_get_io_src_index(const rogue_ref *ref)
{
return rogue_ref_get_io(ref) - ROGUE_IO_S0;
}
static inline unsigned rogue_ref_get_drc_index(const rogue_ref *ref) static inline unsigned rogue_ref_get_drc_index(const rogue_ref *ref)
{ {
assert(rogue_ref_is_drc(ref)); assert(rogue_ref_is_drc(ref));
@@ -1263,6 +1268,8 @@ enum rogue_backend_op {
ROGUE_BACKEND_OP_UVSW_EMITTHENENDTASK, ROGUE_BACKEND_OP_UVSW_EMITTHENENDTASK,
ROGUE_BACKEND_OP_UVSW_WRITETHENEMITTHENENDTASK, ROGUE_BACKEND_OP_UVSW_WRITETHENEMITTHENENDTASK,
ROGUE_BACKEND_OP_LD,
/* ROGUE_BACKEND_OP_FITR, */ /* ROGUE_BACKEND_OP_FITR, */
/* ROGUE_BACKEND_OP_SAMPLE, */ /* ROGUE_BACKEND_OP_SAMPLE, */
/* ROGUE_BACKEND_OP_CENTROID, */ /* ROGUE_BACKEND_OP_CENTROID, */

View File

@@ -41,6 +41,10 @@
#define ROGUE_BUILDER_DEFINE_BACKEND11(...) #define ROGUE_BUILDER_DEFINE_BACKEND11(...)
#endif /* ROGUE_BUILDER_DEFINE_BACKEND11 */ #endif /* ROGUE_BUILDER_DEFINE_BACKEND11 */
#ifndef ROGUE_BUILDER_DEFINE_BACKEND13
#define ROGUE_BUILDER_DEFINE_BACKEND13(...)
#endif /* ROGUE_BUILDER_DEFINE_BACKEND13 */
#ifndef ROGUE_BUILDER_DEFINE_BACKEND14 #ifndef ROGUE_BUILDER_DEFINE_BACKEND14
#define ROGUE_BUILDER_DEFINE_BACKEND14(...) #define ROGUE_BUILDER_DEFINE_BACKEND14(...)
#endif /* ROGUE_BUILDER_DEFINE_BACKEND14 */ #endif /* ROGUE_BUILDER_DEFINE_BACKEND14 */
@@ -52,8 +56,11 @@ ROGUE_BUILDER_DEFINE_BACKEND00(UVSW_EMITTHENENDTASK)
ROGUE_BUILDER_DEFINE_BACKEND11(UVSW_WRITE) ROGUE_BUILDER_DEFINE_BACKEND11(UVSW_WRITE)
ROGUE_BUILDER_DEFINE_BACKEND11(UVSW_WRITETHENEMITTHENENDTASK) ROGUE_BUILDER_DEFINE_BACKEND11(UVSW_WRITETHENEMITTHENENDTASK)
ROGUE_BUILDER_DEFINE_BACKEND13(LD)
ROGUE_BUILDER_DEFINE_BACKEND14(FITRP_PIXEL) ROGUE_BUILDER_DEFINE_BACKEND14(FITRP_PIXEL)
#undef ROGUE_BUILDER_DEFINE_BACKEND14 #undef ROGUE_BUILDER_DEFINE_BACKEND14
#undef ROGUE_BUILDER_DEFINE_BACKEND13
#undef ROGUE_BUILDER_DEFINE_BACKEND11 #undef ROGUE_BUILDER_DEFINE_BACKEND11
#undef ROGUE_BUILDER_DEFINE_BACKEND00 #undef ROGUE_BUILDER_DEFINE_BACKEND00

View File

@@ -250,6 +250,19 @@ rogue_build_backend11(rogue_builder *b,
return rogue_build_backend(b, op, 1, dsts, 1, srcs); return rogue_build_backend(b, op, 1, dsts, 1, srcs);
} }
static inline rogue_backend_instr *
rogue_build_backend13(rogue_builder *b,
enum rogue_backend_op op,
rogue_ref dst0,
rogue_ref src0,
rogue_ref src1,
rogue_ref src2)
{
rogue_ref dsts[] = { dst0 };
rogue_ref srcs[] = { src0, src1, src2 };
return rogue_build_backend(b, op, 1, dsts, 3, srcs);
}
static inline rogue_backend_instr * static inline rogue_backend_instr *
rogue_build_backend14(rogue_builder *b, rogue_build_backend14(rogue_builder *b,
enum rogue_backend_op op, enum rogue_backend_op op,
@@ -284,6 +297,24 @@ rogue_build_backend14(rogue_builder *b,
return rogue_build_backend11(b, ROGUE_BACKEND_OP_##op, dst0, src0); \ return rogue_build_backend11(b, ROGUE_BACKEND_OP_##op, dst0, src0); \
} }
#define ROGUE_BUILDER_DEFINE_BACKEND13(op) \
PUBLIC \
rogue_backend_instr *rogue_##op(rogue_builder *b, \
rogue_ref dst0, \
rogue_ref src0, \
rogue_ref src1, \
rogue_ref src2) \
{ \
assert(rogue_backend_op_infos[ROGUE_BACKEND_OP_##op].num_dsts == 1); \
assert(rogue_backend_op_infos[ROGUE_BACKEND_OP_##op].num_srcs == 3); \
return rogue_build_backend13(b, \
ROGUE_BACKEND_OP_##op, \
dst0, \
src0, \
src1, \
src2); \
}
#define ROGUE_BUILDER_DEFINE_BACKEND14(op) \ #define ROGUE_BUILDER_DEFINE_BACKEND14(op) \
PUBLIC \ PUBLIC \
rogue_backend_instr *rogue_##op(rogue_builder *b, \ rogue_backend_instr *rogue_##op(rogue_builder *b, \

View File

@@ -138,6 +138,13 @@ static inline rogue_block *rogue_push_block(rogue_builder *b)
rogue_ref dst0, \ rogue_ref dst0, \
rogue_ref src0); rogue_ref src0);
#define ROGUE_BUILDER_DEFINE_BACKEND13(op) \
rogue_backend_instr *rogue_##op(rogue_builder *b, \
rogue_ref dst0, \
rogue_ref src0, \
rogue_ref src1, \
rogue_ref src2);
#define ROGUE_BUILDER_DEFINE_BACKEND14(op) \ #define ROGUE_BUILDER_DEFINE_BACKEND14(op) \
rogue_backend_instr *rogue_##op(rogue_builder *b, \ rogue_backend_instr *rogue_##op(rogue_builder *b, \
rogue_ref dst0, \ rogue_ref dst0, \

View File

@@ -337,6 +337,42 @@ static void rogue_encode_backend_instr(const rogue_backend_instr *backend,
rogue_ref_get_reg_index(&backend->dst[0].ref); rogue_ref_get_reg_index(&backend->dst[0].ref);
break; break;
case ROGUE_BACKEND_OP_LD: {
instr_encoding->backend.op = BACKENDOP_DMA;
instr_encoding->backend.dma.dmaop = DMAOP_LD;
instr_encoding->backend.dma.ld.drc =
rogue_ref_get_drc_index(&backend->src[0].ref);
instr_encoding->backend.dma.ld.cachemode = CACHEMODE_LD_NORMAL;
instr_encoding->backend.dma.ld.srcseladd =
rogue_ref_get_io_src_index(&backend->src[2].ref);
bool imm_burstlen = rogue_ref_is_val(&backend->src[1].ref);
/* Only supporting immediate burst lengths for now. */
assert(imm_burstlen);
rogue_burstlen burstlen = {
._ = imm_burstlen ? rogue_ref_get_val(&backend->src[1].ref) : 0
};
if (imm_burstlen) {
instr_encoding->backend.dma.ld.burstlen_2_0 = burstlen._2_0;
} else {
instr_encoding->backend.dma.ld.srcselbl =
rogue_ref_get_io_src_index(&backend->src[1].ref);
}
if (instr_size == 3) {
instr_encoding->backend.dma.ld.ext = 1;
instr_encoding->backend.dma.ld.slccachemode = SLCCACHEMODE_BYPASS;
instr_encoding->backend.dma.ld.notimmbl = !imm_burstlen;
if (imm_burstlen)
instr_encoding->backend.dma.ld.burstlen_3 = burstlen._3;
}
break;
}
default: default:
unreachable("Unsupported backend op."); unreachable("Unsupported backend op.");
} }

View File

@@ -255,6 +255,22 @@ const rogue_backend_op_info rogue_backend_op_infos[ROGUE_BACKEND_OP_COUNT] = {
.phase_io = { .src[0] = IO(W0), }, .phase_io = { .src[0] = IO(W0), },
.supported_dst_types = { [0] = T(REG), }, .supported_dst_types = { [0] = T(REG), },
.supported_src_types = { [0] = T(REG), }, .supported_src_types = { [0] = T(REG), },
},
/* .src[1] and .src[2] can actually be S0-5. */
[ROGUE_BACKEND_OP_LD] = { .str = "ld", .num_dsts = 1, .num_srcs = 3,
.phase_io = { .dst[0] = IO(S3), .src[2] = IO(S0), },
.supported_dst_types = { [0] = T(REG) | T(REGARRAY), },
.supported_src_types = {
[0] = T(DRC),
[1] = T(VAL),
[2] = T(REGARRAY),
},
.dst_stride = {
[0] = ~0U,
},
.src_stride = {
[2] = 1,
},
}, },
[ROGUE_BACKEND_OP_FITRP_PIXEL] = { .str = "fitrp.pixel", .num_dsts = 1, .num_srcs = 4, [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), }, .phase_io = { .dst[0] = IO(S3), .src[1] = IO(S0), .src[2] = IO(S2), },
@@ -268,7 +284,7 @@ const rogue_backend_op_info rogue_backend_op_infos[ROGUE_BACKEND_OP_COUNT] = {
}, },
.src_stride = { .src_stride = {
[1] = 3, [1] = 3,
[2] = 3, [2] = ~0U,
}, },
}, },
}; };

View File

@@ -778,6 +778,95 @@ enum uvsw_writeop {
UVSW_WRITEOP_WRITE_EMIT_END = 0b110, UVSW_WRITEOP_WRITE_EMIT_END = 0b110,
}; };
typedef struct rogue_burstlen {
union {
struct {
unsigned _2_0 : 3;
unsigned _3 : 1;
unsigned : 4;
} PACKED;
uint8_t _;
} PACKED;
} PACKED rogue_burstlen;
static_assert(sizeof(rogue_burstlen) == 1, "sizeof(rogue_burstlen) != 1");
typedef struct rogue_backend_dma_ld_encoding {
/* Byte 0 */
struct {
unsigned : 3;
unsigned drc : 1;
unsigned ext : 1;
unsigned : 3;
} PACKED;
/* Byte 1 */
union {
struct {
unsigned cachemode : 2;
unsigned burstlen_2_0 : 3;
unsigned srcseladd : 3;
} PACKED;
struct {
unsigned : 2;
unsigned srcselbl : 3;
unsigned : 3;
} PACKED;
} PACKED;
/* Byte 2 */
struct {
unsigned burstlen_3 : 1;
unsigned slccachemode : 2;
unsigned notimmbl : 1; /* N.B. default is 1 if ext = 0. */
unsigned : 4;
} PACKED;
} PACKED rogue_backend_dma_ld_encoding;
static_assert(sizeof(rogue_backend_dma_ld_encoding) == 3,
"sizeof(rogue_backend_dma_ld_encoding) != 3");
enum cachemode_ld {
CACHEMODE_LD_NORMAL = 0b00,
CACHEMODE_LD_BYPASS = 0b01,
CACHEMODE_LD_FORCE_LINE_FILL = 0b10,
};
enum cachemode_st {
CACHEMODE_ST_WRITE_THROUGH = 0b00,
CACHEMODE_ST_WRITE_BACK = 0b01,
CACHEMODE_ST_WRITE_BACK_LAZY = 0b10,
};
enum slccachemode {
SLCCACHEMODE_BYPASS = 0b00,
SLCCACHEMODE_WRITE_BACK = 0b01,
SLCCACHEMODE_WRITE_THROUGH = 0b10,
SLCCACHEMODE_CACHED_READS = 0b11,
};
typedef struct rogue_backend_dma_encoding {
union {
/* Byte 0 */
struct {
unsigned dmaop : 3;
unsigned : 5;
} PACKED;
rogue_backend_dma_ld_encoding ld;
} PACKED;
} PACKED rogue_backend_dma_encoding;
static_assert(sizeof(rogue_backend_dma_encoding) == 3,
"sizeof(rogue_backend_dma_encoding) != 3");
enum dmaop {
DMAOP_IDF = 0b000,
DMAOP_LD = 0b001,
DMAOP_ST = 0b010,
DMAOP_SMP = 0b100,
DMAOP_ATOMIC = 0b101,
};
typedef struct rogue_backend_instr_encoding { typedef struct rogue_backend_instr_encoding {
union { union {
/* Byte 0 */ /* Byte 0 */
@@ -789,10 +878,11 @@ typedef struct rogue_backend_instr_encoding {
rogue_backend_uvsw_encoding uvsw; rogue_backend_uvsw_encoding uvsw;
rogue_backend_fitr_encoding fitr; rogue_backend_fitr_encoding fitr;
rogue_backend_emitpix_encoding emitpix; rogue_backend_emitpix_encoding emitpix;
rogue_backend_dma_encoding dma;
} PACKED; } PACKED;
} PACKED rogue_backend_instr_encoding; } PACKED rogue_backend_instr_encoding;
static_assert(sizeof(rogue_backend_instr_encoding) == 2, static_assert(sizeof(rogue_backend_instr_encoding) == 3,
"sizeof(rogue_backend_instr_encoding) != 2"); "sizeof(rogue_backend_instr_encoding) != 3");
enum backendop { enum backendop {
BACKENDOP_UVSW = 0b000, BACKENDOP_UVSW = 0b000,

View File

@@ -163,7 +163,7 @@ static void validate_dst(rogue_validation_state *state,
if (rogue_ref_is_null(&dst->ref)) if (rogue_ref_is_null(&dst->ref))
validate_log(state, "Destination has not been set."); validate_log(state, "Destination has not been set.");
if (!state->shader->is_grouped) { if (!state->shader->is_grouped && stride != ~0U) {
unsigned dst_size = stride + 1; unsigned dst_size = stride + 1;
if (repeat_mask & (1 << i)) if (repeat_mask & (1 << i))
dst_size *= repeat; dst_size *= repeat;
@@ -201,7 +201,7 @@ static void validate_src(rogue_validation_state *state,
if (rogue_ref_is_null(&src->ref)) if (rogue_ref_is_null(&src->ref))
validate_log(state, "Source has not been set."); validate_log(state, "Source has not been set.");
if (!state->shader->is_grouped) { if (!state->shader->is_grouped && stride != ~0U) {
unsigned src_size = stride + 1; unsigned src_size = stride + 1;
if (repeat_mask & (1 << i)) if (repeat_mask & (1 << i))
src_size *= repeat; src_size *= repeat;