pvr: Add support for ST

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/21474>
This commit is contained in:
Simon Perretta 2023-02-15 22:26:29 +00:00 committed by Marge Bot
parent c4b7128d84
commit b1064e91f1
5 changed files with 192 additions and 48 deletions

View file

@ -561,6 +561,21 @@ static void rogue_calc_alu_instrs_size(rogue_instr_group *group,
#undef DM
#undef SM
#define OM(op_mod) BITFIELD64_BIT(ROGUE_BACKEND_OP_MOD_##op_mod)
static bool rogue_backend_cachemode_is_set(const rogue_backend_instr *backend)
{
return !!(backend->mod & (OM(BYPASS) | OM(FORCELINEFILL) | OM(WRITETHROUGH) |
OM(WRITEBACK) | OM(LAZYWRITEBACK)));
}
static bool
rogue_backend_slccachemode_is_set(const rogue_backend_instr *backend)
{
return !!(backend->mod & (OM(SLCBYPASS) | OM(SLCWRITEBACK) |
OM(SLCWRITETHROUGH) | OM(SLCNOALLOC)));
}
#undef OM
#define OM(op_mod) ROGUE_BACKEND_OP_MOD_##op_mod
static void rogue_calc_backend_instrs_size(rogue_instr_group *group,
rogue_backend_instr *backend,
@ -586,9 +601,20 @@ static void rogue_calc_backend_instrs_size(rogue_instr_group *group,
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))
if (rogue_ref_is_val(&backend->src[1].ref) ||
rogue_backend_slccachemode_is_set(backend)) {
group->size.instrs[phase] = 3;
}
break;
case ROGUE_BACKEND_OP_ST:
group->size.instrs[phase] = 3;
if (rogue_backend_op_mod_is_set(backend, OM(TILED)) ||
rogue_backend_slccachemode_is_set(backend) ||
!rogue_ref_is_io_none(&backend->src[5].ref)) {
group->size.instrs[phase] = 4;
}
break;
case ROGUE_BACKEND_OP_SMP1D:
@ -599,17 +625,10 @@ static void rogue_calc_backend_instrs_size(rogue_instr_group *group,
if (rogue_backend_op_mod_is_set(backend, OM(ARRAY))) {
group->size.instrs[phase] = 5;
} else if (rogue_backend_op_mod_is_set(backend, OM(WRT)) ||
rogue_backend_op_mod_is_set(backend, OM(BYPASS)) ||
rogue_backend_op_mod_is_set(backend, OM(FORCELINEFILL)) ||
rogue_backend_op_mod_is_set(backend, OM(WRITETHROUGH)) ||
rogue_backend_op_mod_is_set(backend, OM(WRITEBACK)) ||
rogue_backend_op_mod_is_set(backend, OM(LAZYWRITEBACK)) ||
rogue_backend_op_mod_is_set(backend, OM(SCHEDSWAP)) ||
rogue_backend_op_mod_is_set(backend, OM(F16)) ||
rogue_backend_op_mod_is_set(backend, OM(SLCBYPASS)) ||
rogue_backend_op_mod_is_set(backend, OM(SLCWRITEBACK)) ||
rogue_backend_op_mod_is_set(backend, OM(SLCWRITETHROUGH)) ||
rogue_backend_op_mod_is_set(backend, OM(SLCNOALLOC))) {
rogue_backend_cachemode_is_set(backend) ||
rogue_backend_slccachemode_is_set(backend)) {
group->size.instrs[phase] = 4;
} else if (rogue_backend_op_mod_is_set(backend, OM(TAO)) ||
rogue_backend_op_mod_is_set(backend, OM(SOO)) ||

View file

@ -1348,6 +1348,7 @@ enum rogue_backend_op {
ROGUE_BACKEND_OP_EMITPIX,
ROGUE_BACKEND_OP_LD,
ROGUE_BACKEND_OP_ST,
ROGUE_BACKEND_OP_FITR_PIXEL,
/* ROGUE_BACKEND_OP_SAMPLE, */
@ -1417,6 +1418,8 @@ enum rogue_backend_op_mod {
ROGUE_BACKEND_OP_MOD_INFO, /* Sample bypass mode: info. */
ROGUE_BACKEND_OP_MOD_BOTH, /* Sample bypass mode: both. */
ROGUE_BACKEND_OP_MOD_TILED, /* Tiled LD/ST. */
ROGUE_BACKEND_OP_MOD_BYPASS, /* MCU cache mode (read): bypass. */
ROGUE_BACKEND_OP_MOD_FORCELINEFILL, /* MCU cache mode (read): force line
* fill.

View file

@ -294,6 +294,39 @@ static void rogue_encode_alu_instr(const rogue_alu_instr *alu,
#undef SM
#define OM(op_mod) ROGUE_BACKEND_OP_MOD_##op_mod
static unsigned rogue_backend_get_cachemode(const rogue_backend_instr *backend)
{
if (rogue_backend_op_mod_is_set(backend, OM(BYPASS)))
return CACHEMODE_LD_BYPASS;
else if (rogue_backend_op_mod_is_set(backend, OM(FORCELINEFILL)))
return CACHEMODE_LD_FORCE_LINE_FILL;
else if (rogue_backend_op_mod_is_set(backend, OM(WRITETHROUGH)))
return CACHEMODE_ST_WRITE_THROUGH;
else if (rogue_backend_op_mod_is_set(backend, OM(WRITEBACK)))
return CACHEMODE_ST_WRITE_BACK;
else if (rogue_backend_op_mod_is_set(backend, OM(LAZYWRITEBACK)))
return CACHEMODE_ST_WRITE_BACK_LAZY;
/* Default cache mode. */
return CACHEMODE_LD_NORMAL; /* == CACHEMODE_ST_WRITE_THROUGH */
}
static unsigned
rogue_backend_get_slccachemode(const rogue_backend_instr *backend)
{
if (rogue_backend_op_mod_is_set(backend, OM(SLCBYPASS)))
return SLCCACHEMODE_BYPASS;
else if (rogue_backend_op_mod_is_set(backend, OM(SLCWRITEBACK)))
return SLCCACHEMODE_WRITE_BACK;
else if (rogue_backend_op_mod_is_set(backend, OM(SLCWRITETHROUGH)))
return SLCCACHEMODE_WRITE_THROUGH;
else if (rogue_backend_op_mod_is_set(backend, OM(SLCNOALLOC)))
return SLCCACHEMODE_CACHED_READS;
/* Default SLC cache mode. */
return SLCCACHEMODE_BYPASS;
}
static void rogue_encode_backend_instr(const rogue_backend_instr *backend,
unsigned instr_size,
rogue_instr_encoding *instr_encoding)
@ -359,13 +392,10 @@ static void rogue_encode_backend_instr(const rogue_backend_instr *backend,
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);
instr_encoding->backend.dma.ld.cachemode =
rogue_backend_get_cachemode(backend);
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
@ -378,13 +408,60 @@ static void rogue_encode_backend_instr(const rogue_backend_instr *backend,
rogue_ref_get_io_src_index(&backend->src[1].ref);
}
instr_encoding->backend.dma.ld.srcseladd =
rogue_ref_get_io_src_index(&backend->src[2].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;
instr_encoding->backend.dma.ld.slccachemode =
rogue_backend_get_slccachemode(backend);
instr_encoding->backend.dma.ld.notimmbl = !imm_burstlen;
}
break;
}
case ROGUE_BACKEND_OP_ST: {
instr_encoding->backend.op = BACKENDOP_DMA;
instr_encoding->backend.dma.dmaop = DMAOP_ST;
instr_encoding->backend.dma.st.drc =
rogue_ref_get_drc_index(&backend->src[1].ref);
bool imm_burstlen = rogue_ref_is_val(&backend->src[3].ref);
instr_encoding->backend.dma.st.immbl = imm_burstlen;
if (imm_burstlen) {
rogue_burstlen burstlen = { ._ = rogue_ref_get_val(
&backend->src[3].ref) };
instr_encoding->backend.dma.st.burstlen_2_0 = burstlen._2_0;
instr_encoding->backend.dma.st.burstlen_3 = burstlen._3;
} else {
instr_encoding->backend.dma.st.srcselbl =
rogue_ref_get_io_src_index(&backend->src[3].ref);
}
instr_encoding->backend.dma.st.cachemode =
rogue_backend_get_cachemode(backend);
instr_encoding->backend.dma.st.srcseladd =
rogue_ref_get_io_src_index(&backend->src[4].ref);
instr_encoding->backend.dma.st.dsize =
rogue_ref_get_val(&backend->src[1].ref);
instr_encoding->backend.dma.st.srcseldata =
rogue_ref_get_io_src_index(&backend->src[0].ref);
if (instr_size == 4) {
instr_encoding->backend.dma.st.ext = 1;
instr_encoding->backend.dma.st.srcmask =
rogue_ref_get_io_src_index(&backend->src[5].ref);
instr_encoding->backend.dma.st.slccachemode =
rogue_backend_get_slccachemode(backend);
instr_encoding->backend.dma.st.nottiled =
!rogue_backend_op_mod_is_set(backend, OM(TILED));
}
break;
@ -481,41 +558,16 @@ static void rogue_encode_backend_instr(const rogue_backend_instr *backend,
instr_encoding->backend.dma.smp.w =
rogue_backend_op_mod_is_set(backend, OM(WRT));
if (rogue_backend_op_mod_is_set(backend, OM(BYPASS))) {
instr_encoding->backend.dma.smp.cachemode = CACHEMODE_LD_BYPASS;
} else if (rogue_backend_op_mod_is_set(backend, OM(FORCELINEFILL))) {
instr_encoding->backend.dma.smp.cachemode =
CACHEMODE_LD_FORCE_LINE_FILL;
} else if (rogue_backend_op_mod_is_set(backend, OM(WRITETHROUGH))) {
instr_encoding->backend.dma.smp.cachemode =
CACHEMODE_ST_WRITE_THROUGH;
} else if (rogue_backend_op_mod_is_set(backend, OM(WRITEBACK))) {
instr_encoding->backend.dma.smp.cachemode = CACHEMODE_ST_WRITE_BACK;
} else if (rogue_backend_op_mod_is_set(backend, OM(LAZYWRITEBACK))) {
instr_encoding->backend.dma.smp.cachemode =
CACHEMODE_ST_WRITE_BACK_LAZY;
} else {
instr_encoding->backend.dma.smp.cachemode =
CACHEMODE_LD_NORMAL; /* == CACHEMODE_ST_WRITE_THROUGH */
}
instr_encoding->backend.dma.smp.cachemode =
rogue_backend_get_cachemode(backend);
instr_encoding->backend.dma.smp.swap =
rogue_backend_op_mod_is_set(backend, OM(SCHEDSWAP));
instr_encoding->backend.dma.smp.f16 =
rogue_backend_op_mod_is_set(backend, OM(F16));
if (rogue_backend_op_mod_is_set(backend, OM(SLCWRITEBACK))) {
instr_encoding->backend.dma.smp.slccachemode =
SLCCACHEMODE_WRITE_BACK;
} else if (rogue_backend_op_mod_is_set(backend, OM(SLCWRITETHROUGH))) {
instr_encoding->backend.dma.smp.slccachemode =
SLCCACHEMODE_WRITE_THROUGH;
} else if (rogue_backend_op_mod_is_set(backend, OM(SLCNOALLOC))) {
instr_encoding->backend.dma.smp.slccachemode =
SLCCACHEMODE_CACHED_READS;
} else {
instr_encoding->backend.dma.smp.slccachemode = SLCCACHEMODE_BYPASS;
}
instr_encoding->backend.dma.smp.slccachemode =
rogue_backend_get_slccachemode(backend);
}
if (instr_size > 4) {

View file

@ -272,6 +272,7 @@ const rogue_backend_op_info rogue_backend_op_infos[ROGUE_BACKEND_OP_COUNT] = {
/* .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_op_mods = OM(BYPASS) | OM(FORCELINEFILL) | OM(SLCBYPASS) | OM(SLCNOALLOC),
.supported_dst_types = { [0] = T(REG) | T(REGARRAY), },
.supported_src_types = {
[0] = T(DRC),
@ -284,6 +285,23 @@ const rogue_backend_op_info rogue_backend_op_infos[ROGUE_BACKEND_OP_COUNT] = {
.src_stride = {
[2] = 1,
},
},
/* .src[0] and .src[3] can actually be S0-5. */
[ROGUE_BACKEND_OP_ST] = { .str = "st", .num_srcs = 6,
.phase_io = { .src[0] = IO(S3), .src[3] = IO(S0), },
.supported_op_mods = OM(TILED) | OM(WRITETHROUGH) | OM(WRITEBACK) | OM(LAZYWRITEBACK) |
OM(SLCBYPASS) | OM(SLCWRITEBACK) | OM(SLCWRITETHROUGH) | OM(SLCNOALLOC),
.supported_src_types = {
[0] = T(REG) | T(REGARRAY),
[1] = T(VAL),
[2] = T(DRC),
[3] = T(VAL),
[4] = T(REGARRAY),
[5] = T(IO),
},
.src_stride = {
[4] = 1,
},
},
[ROGUE_BACKEND_OP_FITR_PIXEL] = { .str = "fitr.pixel", .num_dsts = 1, .num_srcs = 3,
.phase_io = { .dst[0] = IO(S3), .src[1] = IO(S0), },
@ -419,6 +437,7 @@ const rogue_backend_op_mod_info rogue_backend_op_mod_infos[ROGUE_BACKEND_OP_MOD_
[ROGUE_BACKEND_OP_MOD_DATA] = { .str = "data", .exclude = OM(INFO) | OM(BOTH) },
[ROGUE_BACKEND_OP_MOD_INFO] = { .str = "info", .exclude = OM(DATA) | OM(BOTH) },
[ROGUE_BACKEND_OP_MOD_BOTH] = { .str = "both", .exclude = OM(DATA) | OM(INFO) },
[ROGUE_BACKEND_OP_MOD_TILED] = { .str = "tiled", },
[ROGUE_BACKEND_OP_MOD_BYPASS] = { .str = "bypass", .exclude = OM(FORCELINEFILL) | OM(WRITETHROUGH) | OM(WRITEBACK) | OM(LAZYWRITEBACK) },
[ROGUE_BACKEND_OP_MOD_FORCELINEFILL] = { .str = "forcelinefill", .exclude = OM(BYPASS) | OM(WRITETHROUGH) | OM(WRITEBACK) | OM(LAZYWRITEBACK) },
[ROGUE_BACKEND_OP_MOD_WRITETHROUGH] = { .str = "writethrough", .exclude = OM(BYPASS) | OM(FORCELINEFILL) | OM(WRITEBACK) | OM(LAZYWRITEBACK) },

View file

@ -832,6 +832,56 @@ enum cachemode_ld {
CACHEMODE_LD_FORCE_LINE_FILL = 0b10,
};
typedef struct rogue_backend_dma_st_encoding {
/* Byte 0 */
struct {
unsigned : 3;
unsigned drc : 1;
unsigned immbl : 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 : 1;
unsigned dsize : 2;
unsigned srcseldata : 3;
unsigned ext : 1;
} PACKED;
/* Byte 3 */
struct {
unsigned srcmask : 3;
unsigned slccachemode : 2;
unsigned nottiled : 1; /* N.B. default is 1 if ext = 0. */
unsigned : 2;
} PACKED;
} PACKED rogue_backend_dma_st_encoding;
static_assert(sizeof(rogue_backend_dma_st_encoding) == 4,
"sizeof(rogue_backend_dma_st_encoding) != 4");
enum dsize {
DSIZE_8 = 0b00,
DSIZE_16 = 0b01,
DSIZE_BURSTLEN = 0b10,
};
enum cachemode_st {
CACHEMODE_ST_WRITE_THROUGH = 0b00,
CACHEMODE_ST_WRITE_BACK = 0b01,
@ -953,6 +1003,7 @@ typedef struct rogue_backend_dma_encoding {
rogue_backend_dma_smp_encoding smp;
rogue_backend_dma_idf_encoding idf;
rogue_backend_dma_ld_encoding ld;
rogue_backend_dma_st_encoding st;
} PACKED;
} PACKED rogue_backend_dma_encoding;
static_assert(sizeof(rogue_backend_dma_encoding) == 5,