static void emit_mrt(struct fd_ringbuffer *ring, unsigned nr_bufs, struct pipe_surface **bufs, uint32_t *bases, uint32_t bin_w, bool decode_srgb) { enum a4xx_tile_mode tile_mode; unsigned i; if (bin_w) { tile_mode = 2; } else { tile_mode = TILE4_LINEAR; } for (i = 0; i < A4XX_MAX_RENDER_TARGETS; i++) { enum a4xx_color_fmt format = 0; enum a3xx_color_swap swap = WZYX; bool srgb = false; struct fd_resource *rsc = NULL; struct fd_resource_slice *slice = NULL; uint32_t stride = 0; uint32_t base = 0; uint32_t offset = 0; if ((i < nr_bufs) && bufs[i]) { struct pipe_surface *psurf = bufs[i]; enum pipe_format pformat = psurf->format; rsc = fd_resource(psurf->texture); /* In case we're drawing to Z32F_S8, the "color" actually goes to * the stencil */ if (rsc->stencil) { rsc = rsc->stencil; pformat = rsc->base.b.format; bases++; } slice = fd_resource_slice(rsc, psurf->u.tex.level); format = fd4_pipe2color(pformat); swap = fd4_pipe2swap(pformat); if (decode_srgb) srgb = util_format_is_srgb(pformat); else pformat = util_format_linear(pformat); debug_assert(psurf->u.tex.first_layer == psurf->u.tex.last_layer); offset = fd_resource_offset(rsc, psurf->u.tex.level, psurf->u.tex.first_layer); if (bin_w) { stride = bin_w * rsc->cpp; if (bases) { base = bases[i]; } } else { stride = slice->pitch * rsc->cpp; } } else if ((i < nr_bufs) && bases) { base = bases[i]; } OUT_PKT0(ring, REG_A4XX_RB_MRT_BUF_INFO(i), 3); OUT_RING(ring, A4XX_RB_MRT_BUF_INFO_COLOR_FORMAT(format) | A4XX_RB_MRT_BUF_INFO_COLOR_TILE_MODE(tile_mode) | A4XX_RB_MRT_BUF_INFO_COLOR_BUF_PITCH(stride) | A4XX_RB_MRT_BUF_INFO_COLOR_SWAP(swap) | COND(srgb, A4XX_RB_MRT_BUF_INFO_COLOR_SRGB)); if (bin_w || (i >= nr_bufs) || !bufs[i]) { OUT_RING(ring, base); OUT_RING(ring, A4XX_RB_MRT_CONTROL3_STRIDE(stride)); } else { OUT_RELOCW(ring, rsc->bo, offset, 0, 0); /* RB_MRT[i].CONTROL3.STRIDE not emitted by c2d.. * not sure if we need to skip it for bypass or * not. */ OUT_RING(ring, A4XX_RB_MRT_CONTROL3_STRIDE(0)); } } }
static void emit_mrt(struct fd_ringbuffer *ring, unsigned nr_bufs, struct pipe_surface **bufs, uint32_t *bases, uint32_t bin_w) { enum a4xx_tile_mode tile_mode; unsigned i; if (bin_w) { tile_mode = 2; } else { tile_mode = TILE4_LINEAR; } for (i = 0; i < 8; i++) { enum a4xx_color_fmt format = 0; enum a3xx_color_swap swap = WZYX; struct fd_resource *rsc = NULL; struct fd_resource_slice *slice = NULL; uint32_t stride = 0; uint32_t base = 0; uint32_t offset = 0; if ((i < nr_bufs) && bufs[i]) { struct pipe_surface *psurf = bufs[i]; rsc = fd_resource(psurf->texture); slice = fd_resource_slice(rsc, psurf->u.tex.level); format = fd4_pipe2color(psurf->format); swap = fd4_pipe2swap(psurf->format); debug_assert(psurf->u.tex.first_layer == psurf->u.tex.last_layer); offset = fd_resource_offset(rsc, psurf->u.tex.level, psurf->u.tex.first_layer); if (bin_w) { stride = bin_w * rsc->cpp; if (bases) { base = bases[i]; } } else { stride = slice->pitch * rsc->cpp; } } OUT_PKT0(ring, REG_A4XX_RB_MRT_BUF_INFO(i), 3); OUT_RING(ring, A4XX_RB_MRT_BUF_INFO_COLOR_FORMAT(format) | A4XX_RB_MRT_BUF_INFO_COLOR_TILE_MODE(tile_mode) | A4XX_RB_MRT_BUF_INFO_COLOR_BUF_PITCH(stride) | A4XX_RB_MRT_BUF_INFO_COLOR_SWAP(swap)); if (bin_w || (i >= nr_bufs)) { OUT_RING(ring, base); OUT_RING(ring, A4XX_RB_MRT_CONTROL3_STRIDE(stride)); } else { OUT_RELOCW(ring, rsc->bo, offset, 0, 0); /* RB_MRT[i].CONTROL3.STRIDE not emitted by c2d.. * not sure if we need to skip it for bypass or * not. */ OUT_RING(ring, A4XX_RB_MRT_CONTROL3_STRIDE(0)); } } }