Module: Mesa Branch: main Commit: b1064e91f17c7af8478d9d7f1eb34ec3aa7e1871 URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=b1064e91f17c7af8478d9d7f1eb34ec3aa7e1871
Author: Simon Perretta <[email protected]> Date: Wed Feb 15 22:26:29 2023 +0000 pvr: Add support for ST Signed-off-by: Simon Perretta <[email protected]> Acked-by: Frank Binns <[email protected]> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/21474> --- .../rogue/passes/rogue_schedule_instr_groups.c | 41 +++++-- src/imagination/rogue/rogue.h | 3 + src/imagination/rogue/rogue_encode.c | 126 +++++++++++++++------ src/imagination/rogue/rogue_info.c | 19 ++++ src/imagination/rogue/rogue_isa.h | 51 +++++++++ 5 files changed, 192 insertions(+), 48 deletions(-) diff --git a/src/imagination/rogue/passes/rogue_schedule_instr_groups.c b/src/imagination/rogue/passes/rogue_schedule_instr_groups.c index af234289758..8775b019ad4 100644 --- a/src/imagination/rogue/passes/rogue_schedule_instr_groups.c +++ b/src/imagination/rogue/passes/rogue_schedule_instr_groups.c @@ -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)) || diff --git a/src/imagination/rogue/rogue.h b/src/imagination/rogue/rogue.h index 04c1d61eb28..e70c15e3f11 100644 --- a/src/imagination/rogue/rogue.h +++ b/src/imagination/rogue/rogue.h @@ -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. diff --git a/src/imagination/rogue/rogue_encode.c b/src/imagination/rogue/rogue_encode.c index 7e52739ab37..e9ce7829e56 100644 --- a/src/imagination/rogue/rogue_encode.c +++ b/src/imagination/rogue/rogue_encode.c @@ -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) { diff --git a/src/imagination/rogue/rogue_info.c b/src/imagination/rogue/rogue_info.c index c90f3bc595b..bdcb8fad87c 100644 --- a/src/imagination/rogue/rogue_info.c +++ b/src/imagination/rogue/rogue_info.c @@ -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) }, diff --git a/src/imagination/rogue/rogue_isa.h b/src/imagination/rogue/rogue_isa.h index a3b210e0007..7634ba46eef 100644 --- a/src/imagination/rogue/rogue_isa.h +++ b/src/imagination/rogue/rogue_isa.h @@ -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,
