diff options
Diffstat (limited to 'src/gallium/drivers/freedreno/freedreno_gmem.c')
-rw-r--r-- | src/gallium/drivers/freedreno/freedreno_gmem.c | 328 |
1 files changed, 11 insertions, 317 deletions
diff --git a/src/gallium/drivers/freedreno/freedreno_gmem.c b/src/gallium/drivers/freedreno/freedreno_gmem.c index 83e5ea664b7..856e441337c 100644 --- a/src/gallium/drivers/freedreno/freedreno_gmem.c +++ b/src/gallium/drivers/freedreno/freedreno_gmem.c @@ -30,14 +30,11 @@ #include "util/u_string.h" #include "util/u_memory.h" #include "util/u_inlines.h" -#include "util/u_pack_color.h" +#include "util/u_format.h" #include "freedreno_gmem.h" #include "freedreno_context.h" -#include "freedreno_state.h" -#include "freedreno_program.h" #include "freedreno_resource.h" -#include "freedreno_zsa.h" #include "freedreno_util.h" /* @@ -69,277 +66,6 @@ * resolve. */ -static uint32_t fmt2swap(enum pipe_format format) -{ - switch (format) { - case PIPE_FORMAT_B8G8R8A8_UNORM: - /* TODO probably some more.. */ - return 1; - default: - return 0; - } -} - -/* transfer from gmem to system memory (ie. normal RAM) */ - -static void -emit_gmem2mem_surf(struct fd_ringbuffer *ring, uint32_t base, - struct pipe_surface *psurf) -{ - struct fd_resource *rsc = fd_resource(psurf->texture); - uint32_t swap = fmt2swap(psurf->format); - - OUT_PKT3(ring, CP_SET_CONSTANT, 2); - OUT_RING(ring, CP_REG(REG_A2XX_RB_COLOR_INFO)); - OUT_RING(ring, A2XX_RB_COLOR_INFO_SWAP(swap) | - A2XX_RB_COLOR_INFO_BASE(base / 1024) | - A2XX_RB_COLOR_INFO_FORMAT(fd_pipe2color(psurf->format))); - - OUT_PKT3(ring, CP_SET_CONSTANT, 5); - OUT_RING(ring, CP_REG(REG_A2XX_RB_COPY_CONTROL)); - OUT_RING(ring, 0x00000000); /* RB_COPY_CONTROL */ - OUT_RELOC(ring, rsc->bo, 0, 0); /* RB_COPY_DEST_BASE */ - OUT_RING(ring, rsc->pitch >> 5); /* RB_COPY_DEST_PITCH */ - OUT_RING(ring, /* RB_COPY_DEST_INFO */ - A2XX_RB_COPY_DEST_INFO_FORMAT(fd_pipe2color(psurf->format)) | - A2XX_RB_COPY_DEST_INFO_LINEAR | - A2XX_RB_COPY_DEST_INFO_SWAP(swap) | - A2XX_RB_COPY_DEST_INFO_WRITE_RED | - A2XX_RB_COPY_DEST_INFO_WRITE_GREEN | - A2XX_RB_COPY_DEST_INFO_WRITE_BLUE | - A2XX_RB_COPY_DEST_INFO_WRITE_ALPHA); - - OUT_PKT3(ring, CP_WAIT_FOR_IDLE, 1); - OUT_RING(ring, 0x0000000); - - OUT_PKT3(ring, CP_DRAW_INDX, 3); - OUT_RING(ring, 0x00000000); - OUT_RING(ring, DRAW(DI_PT_RECTLIST, DI_SRC_SEL_AUTO_INDEX, - INDEX_SIZE_IGN, IGNORE_VISIBILITY)); - OUT_RING(ring, 3); /* NumIndices */ -} - -static void -emit_gmem2mem(struct fd_context *ctx, struct fd_ringbuffer *ring, - uint32_t xoff, uint32_t yoff, uint32_t bin_w, uint32_t bin_h) -{ - struct pipe_framebuffer_state *pfb = &ctx->framebuffer; - - fd_emit_vertex_bufs(ring, 0x9c, (struct fd_vertex_buf[]) { - { .prsc = ctx->solid_vertexbuf, .size = 48 }, - }, 1); - - OUT_PKT3(ring, CP_SET_CONSTANT, 2); - OUT_RING(ring, CP_REG(REG_A2XX_VGT_INDX_OFFSET)); - OUT_RING(ring, 0); - - OUT_PKT3(ring, CP_SET_CONSTANT, 2); - OUT_RING(ring, CP_REG(REG_A2XX_VGT_VERTEX_REUSE_BLOCK_CNTL)); - OUT_RING(ring, 0x0000028f); - - fd_program_emit(ring, &ctx->solid_prog); - - OUT_PKT3(ring, CP_SET_CONSTANT, 2); - OUT_RING(ring, CP_REG(REG_A2XX_PA_SC_AA_MASK)); - OUT_RING(ring, 0x0000ffff); - - OUT_PKT3(ring, CP_SET_CONSTANT, 2); - OUT_RING(ring, CP_REG(REG_A2XX_RB_DEPTHCONTROL)); - OUT_RING(ring, A2XX_RB_DEPTHCONTROL_EARLY_Z_ENABLE); - - OUT_PKT3(ring, CP_SET_CONSTANT, 2); - OUT_RING(ring, CP_REG(REG_A2XX_PA_SU_SC_MODE_CNTL)); - OUT_RING(ring, A2XX_PA_SU_SC_MODE_CNTL_PROVOKING_VTX_LAST | /* PA_SU_SC_MODE_CNTL */ - A2XX_PA_SU_SC_MODE_CNTL_FRONT_PTYPE(PC_DRAW_TRIANGLES) | - A2XX_PA_SU_SC_MODE_CNTL_BACK_PTYPE(PC_DRAW_TRIANGLES)); - - OUT_PKT3(ring, CP_SET_CONSTANT, 3); - OUT_RING(ring, CP_REG(REG_A2XX_PA_SC_WINDOW_SCISSOR_TL)); - OUT_RING(ring, xy2d(0, 0)); /* PA_SC_WINDOW_SCISSOR_TL */ - OUT_RING(ring, xy2d(pfb->width, pfb->height)); /* PA_SC_WINDOW_SCISSOR_BR */ - - OUT_PKT3(ring, CP_SET_CONSTANT, 2); - OUT_RING(ring, CP_REG(REG_A2XX_PA_CL_VTE_CNTL)); - OUT_RING(ring, A2XX_PA_CL_VTE_CNTL_VTX_W0_FMT | - A2XX_PA_CL_VTE_CNTL_VPORT_X_SCALE_ENA | - A2XX_PA_CL_VTE_CNTL_VPORT_X_OFFSET_ENA | - A2XX_PA_CL_VTE_CNTL_VPORT_Y_SCALE_ENA | - A2XX_PA_CL_VTE_CNTL_VPORT_Y_OFFSET_ENA); - - OUT_PKT3(ring, CP_SET_CONSTANT, 2); - OUT_RING(ring, CP_REG(REG_A2XX_PA_CL_CLIP_CNTL)); - OUT_RING(ring, 0x00000000); - - OUT_PKT3(ring, CP_SET_CONSTANT, 2); - OUT_RING(ring, CP_REG(REG_A2XX_RB_MODECONTROL)); - OUT_RING(ring, A2XX_RB_MODECONTROL_EDRAM_MODE(EDRAM_COPY)); - - OUT_PKT3(ring, CP_SET_CONSTANT, 2); - OUT_RING(ring, CP_REG(REG_A2XX_RB_COPY_DEST_OFFSET)); - OUT_RING(ring, A2XX_RB_COPY_DEST_OFFSET_X(xoff) | - A2XX_RB_COPY_DEST_OFFSET_Y(yoff)); - - if (ctx->resolve & (FD_BUFFER_DEPTH | FD_BUFFER_STENCIL)) - emit_gmem2mem_surf(ring, bin_w * bin_h, pfb->zsbuf); - - if (ctx->resolve & FD_BUFFER_COLOR) - emit_gmem2mem_surf(ring, 0, pfb->cbufs[0]); - - OUT_PKT3(ring, CP_SET_CONSTANT, 2); - OUT_RING(ring, CP_REG(REG_A2XX_RB_MODECONTROL)); - OUT_RING(ring, A2XX_RB_MODECONTROL_EDRAM_MODE(COLOR_DEPTH)); -} - -/* transfer from system memory to gmem */ - -static void -emit_mem2gmem_surf(struct fd_ringbuffer *ring, uint32_t base, - struct pipe_surface *psurf) -{ - struct fd_resource *rsc = fd_resource(psurf->texture); - uint32_t swiz; - - OUT_PKT3(ring, CP_SET_CONSTANT, 2); - OUT_RING(ring, CP_REG(REG_A2XX_RB_COLOR_INFO)); - OUT_RING(ring, A2XX_RB_COLOR_INFO_SWAP(fmt2swap(psurf->format)) | - A2XX_RB_COLOR_INFO_BASE(base) | - A2XX_RB_COLOR_INFO_FORMAT(fd_pipe2color(psurf->format))); - - swiz = fd_tex_swiz(psurf->format, PIPE_SWIZZLE_RED, PIPE_SWIZZLE_GREEN, - PIPE_SWIZZLE_BLUE, PIPE_SWIZZLE_ALPHA); - - /* emit fb as a texture: */ - OUT_PKT3(ring, CP_SET_CONSTANT, 7); - OUT_RING(ring, 0x00010000); - OUT_RING(ring, A2XX_SQ_TEX_0_CLAMP_X(SQ_TEX_WRAP) | - A2XX_SQ_TEX_0_CLAMP_Y(SQ_TEX_WRAP) | - A2XX_SQ_TEX_0_CLAMP_Z(SQ_TEX_WRAP) | - A2XX_SQ_TEX_0_PITCH(rsc->pitch)); - OUT_RELOC(ring, rsc->bo, 0, - fd_pipe2surface(psurf->format) | 0x800); - OUT_RING(ring, A2XX_SQ_TEX_2_WIDTH(psurf->width - 1) | - A2XX_SQ_TEX_2_HEIGHT(psurf->height - 1)); - OUT_RING(ring, 0x01000000 | // XXX - swiz | - A2XX_SQ_TEX_3_XY_MAG_FILTER(SQ_TEX_FILTER_POINT) | - A2XX_SQ_TEX_3_XY_MIN_FILTER(SQ_TEX_FILTER_POINT)); - OUT_RING(ring, 0x00000000); - OUT_RING(ring, 0x00000200); - - OUT_PKT3(ring, CP_DRAW_INDX, 3); - OUT_RING(ring, 0x00000000); - OUT_RING(ring, DRAW(DI_PT_RECTLIST, DI_SRC_SEL_AUTO_INDEX, - INDEX_SIZE_IGN, IGNORE_VISIBILITY)); - OUT_RING(ring, 3); /* NumIndices */ -} - -static void -emit_mem2gmem(struct fd_context *ctx, struct fd_ringbuffer *ring, - uint32_t xoff, uint32_t yoff, uint32_t bin_w, uint32_t bin_h) -{ - struct pipe_framebuffer_state *pfb = &ctx->framebuffer; - float x0, y0, x1, y1; - - fd_emit_vertex_bufs(ring, 0x9c, (struct fd_vertex_buf[]) { - { .prsc = ctx->solid_vertexbuf, .size = 48, .offset = 0x30 }, - { .prsc = ctx->solid_vertexbuf, .size = 32, .offset = 0x60 }, - }, 2); - - /* write texture coordinates to vertexbuf: */ - x0 = ((float)xoff) / ((float)pfb->width); - x1 = ((float)xoff + bin_w) / ((float)pfb->width); - y0 = ((float)yoff) / ((float)pfb->height); - y1 = ((float)yoff + bin_h) / ((float)pfb->height); - OUT_PKT3(ring, CP_MEM_WRITE, 9); - OUT_RELOC(ring, fd_resource(ctx->solid_vertexbuf)->bo, 0x60, 0); - OUT_RING(ring, fui(x0)); - OUT_RING(ring, fui(y0)); - OUT_RING(ring, fui(x1)); - OUT_RING(ring, fui(y0)); - OUT_RING(ring, fui(x0)); - OUT_RING(ring, fui(y1)); - OUT_RING(ring, fui(x1)); - OUT_RING(ring, fui(y1)); - - OUT_PKT3(ring, CP_SET_CONSTANT, 2); - OUT_RING(ring, CP_REG(REG_A2XX_VGT_INDX_OFFSET)); - OUT_RING(ring, 0); - - OUT_PKT3(ring, CP_SET_CONSTANT, 2); - OUT_RING(ring, CP_REG(REG_A2XX_VGT_VERTEX_REUSE_BLOCK_CNTL)); - OUT_RING(ring, 0x0000003b); - - fd_program_emit(ring, &ctx->blit_prog); - - OUT_PKT0(ring, REG_A2XX_TC_CNTL_STATUS, 1); - OUT_RING(ring, A2XX_TC_CNTL_STATUS_L2_INVALIDATE); - - OUT_PKT3(ring, CP_SET_CONSTANT, 2); - OUT_RING(ring, CP_REG(REG_A2XX_RB_DEPTHCONTROL)); - OUT_RING(ring, A2XX_RB_DEPTHCONTROL_EARLY_Z_ENABLE); - - OUT_PKT3(ring, CP_SET_CONSTANT, 2); - OUT_RING(ring, CP_REG(REG_A2XX_PA_SU_SC_MODE_CNTL)); - OUT_RING(ring, A2XX_PA_SU_SC_MODE_CNTL_PROVOKING_VTX_LAST | - A2XX_PA_SU_SC_MODE_CNTL_FRONT_PTYPE(PC_DRAW_TRIANGLES) | - A2XX_PA_SU_SC_MODE_CNTL_BACK_PTYPE(PC_DRAW_TRIANGLES)); - - OUT_PKT3(ring, CP_SET_CONSTANT, 2); - OUT_RING(ring, CP_REG(REG_A2XX_PA_SC_AA_MASK)); - OUT_RING(ring, 0x0000ffff); - - OUT_PKT3(ring, CP_SET_CONSTANT, 2); - OUT_RING(ring, CP_REG(REG_A2XX_RB_COLORCONTROL)); - OUT_RING(ring, A2XX_RB_COLORCONTROL_ALPHA_FUNC(PIPE_FUNC_ALWAYS) | - A2XX_RB_COLORCONTROL_BLEND_DISABLE | - A2XX_RB_COLORCONTROL_ROP_CODE(12) | - A2XX_RB_COLORCONTROL_DITHER_MODE(DITHER_DISABLE) | - A2XX_RB_COLORCONTROL_DITHER_TYPE(DITHER_PIXEL)); - - OUT_PKT3(ring, CP_SET_CONSTANT, 2); - OUT_RING(ring, CP_REG(REG_A2XX_RB_BLEND_CONTROL)); - OUT_RING(ring, A2XX_RB_BLEND_CONTROL_COLOR_SRCBLEND(FACTOR_ONE) | - A2XX_RB_BLEND_CONTROL_COLOR_COMB_FCN(BLEND_DST_PLUS_SRC) | - A2XX_RB_BLEND_CONTROL_COLOR_DESTBLEND(FACTOR_ZERO) | - A2XX_RB_BLEND_CONTROL_ALPHA_SRCBLEND(FACTOR_ONE) | - A2XX_RB_BLEND_CONTROL_ALPHA_COMB_FCN(BLEND_DST_PLUS_SRC) | - A2XX_RB_BLEND_CONTROL_ALPHA_DESTBLEND(FACTOR_ZERO)); - - OUT_PKT3(ring, CP_SET_CONSTANT, 3); - OUT_RING(ring, CP_REG(REG_A2XX_PA_SC_WINDOW_SCISSOR_TL)); - OUT_RING(ring, A2XX_PA_SC_WINDOW_OFFSET_DISABLE | - xy2d(0,0)); /* PA_SC_WINDOW_SCISSOR_TL */ - OUT_RING(ring, xy2d(bin_w, bin_h)); /* PA_SC_WINDOW_SCISSOR_BR */ - - OUT_PKT3(ring, CP_SET_CONSTANT, 5); - OUT_RING(ring, CP_REG(REG_A2XX_PA_CL_VPORT_XSCALE)); - OUT_RING(ring, fui((float)bin_w/2.0)); /* PA_CL_VPORT_XSCALE */ - OUT_RING(ring, fui((float)bin_w/2.0)); /* PA_CL_VPORT_XOFFSET */ - OUT_RING(ring, fui(-(float)bin_h/2.0)); /* PA_CL_VPORT_YSCALE */ - OUT_RING(ring, fui((float)bin_h/2.0)); /* PA_CL_VPORT_YOFFSET */ - - OUT_PKT3(ring, CP_SET_CONSTANT, 2); - OUT_RING(ring, CP_REG(REG_A2XX_PA_CL_VTE_CNTL)); - OUT_RING(ring, A2XX_PA_CL_VTE_CNTL_VTX_XY_FMT | - A2XX_PA_CL_VTE_CNTL_VTX_Z_FMT | // XXX check this??? - A2XX_PA_CL_VTE_CNTL_VPORT_X_SCALE_ENA | - A2XX_PA_CL_VTE_CNTL_VPORT_X_OFFSET_ENA | - A2XX_PA_CL_VTE_CNTL_VPORT_Y_SCALE_ENA | - A2XX_PA_CL_VTE_CNTL_VPORT_Y_OFFSET_ENA); - - OUT_PKT3(ring, CP_SET_CONSTANT, 2); - OUT_RING(ring, CP_REG(REG_A2XX_PA_CL_CLIP_CNTL)); - OUT_RING(ring, 0x00000000); - - if (ctx->restore & (FD_BUFFER_DEPTH | FD_BUFFER_STENCIL)) - emit_mem2gmem_surf(ring, bin_w * bin_h, pfb->zsbuf); - - if (ctx->restore & FD_BUFFER_COLOR) - emit_mem2gmem_surf(ring, 0, pfb->cbufs[0]); - - /* TODO blob driver seems to toss in a CACHE_FLUSH after each DRAW_INDX.. */ -} - static void calculate_tiles(struct fd_context *ctx) { @@ -402,16 +128,14 @@ calculate_tiles(struct fd_context *ctx) gmem->height = height; } + void fd_gmem_render_tiles(struct pipe_context *pctx) { struct fd_context *ctx = fd_context(pctx); struct pipe_framebuffer_state *pfb = &ctx->framebuffer; struct fd_gmem_stateobj *gmem = &ctx->gmem; - struct fd_ringbuffer *ring = ctx->ring; - enum a2xx_colorformatx colorformatx = fd_pipe2color(pfb->cbufs[0]->format); uint32_t i, timestamp, yoff = 0; - uint32_t reg; calculate_tiles(ctx); @@ -422,21 +146,10 @@ fd_gmem_render_tiles(struct pipe_context *pctx) /* mark the end of the clear/draw cmds before emitting per-tile cmds: */ fd_ringmarker_mark(ctx->draw_end); - /* RB_SURFACE_INFO / RB_DEPTH_INFO can be emitted once per tile pass, - * but RB_COLOR_INFO gets overwritten by gmem2mem and mem2gmem and so - * needs to be emitted for each tile: - */ - OUT_PKT3(ring, CP_SET_CONSTANT, 4); - OUT_RING(ring, CP_REG(REG_A2XX_RB_SURFACE_INFO)); - OUT_RING(ring, gmem->bin_w); /* RB_SURFACE_INFO */ - OUT_RING(ring, A2XX_RB_COLOR_INFO_SWAP(1) | /* RB_COLOR_INFO */ - A2XX_RB_COLOR_INFO_FORMAT(colorformatx)); - reg = A2XX_RB_DEPTH_INFO_DEPTH_BASE(align(gmem->bin_w * gmem->bin_h, 4)); - if (pfb->zsbuf) - reg |= A2XX_RB_DEPTH_INFO_DEPTH_FORMAT(fd_pipe2depth(pfb->zsbuf->format)); - OUT_RING(ring, reg); /* RB_DEPTH_INFO */ - yoff= gmem->miny; + + ctx->emit_tile_init(ctx); + for (i = 0; i < gmem->nbins_y; i++) { uint32_t j, xoff = gmem->minx; uint32_t bh = gmem->bin_h; @@ -453,37 +166,18 @@ fd_gmem_render_tiles(struct pipe_context *pctx) DBG("bin_h=%d, yoff=%d, bin_w=%d, xoff=%d", bh, yoff, bw, xoff); - /* setup screen scissor for current tile (same for mem2gmem): */ - OUT_PKT3(ring, CP_SET_CONSTANT, 3); - OUT_RING(ring, CP_REG(REG_A2XX_PA_SC_SCREEN_SCISSOR_TL)); - OUT_RING(ring, xy2d(0,0)); /* PA_SC_SCREEN_SCISSOR_TL */ - OUT_RING(ring, xy2d(bw, bh)); /* PA_SC_SCREEN_SCISSOR_BR */ + ctx->emit_tile_prep(ctx, xoff, yoff, bw, bh); if (ctx->restore) - emit_mem2gmem(ctx, ring, xoff, yoff, bw, bh); - - OUT_PKT3(ring, CP_SET_CONSTANT, 2); - OUT_RING(ring, CP_REG(REG_A2XX_RB_COLOR_INFO)); - OUT_RING(ring, A2XX_RB_COLOR_INFO_SWAP(1) | /* RB_COLOR_INFO */ - A2XX_RB_COLOR_INFO_FORMAT(colorformatx)); + ctx->emit_tile_mem2gmem(ctx, xoff, yoff, bw, bh); - /* setup window scissor and offset for current tile (different - * from mem2gmem): - */ - OUT_PKT3(ring, CP_SET_CONSTANT, 2); - OUT_RING(ring, CP_REG(REG_A2XX_PA_SC_WINDOW_OFFSET)); - OUT_RING(ring, A2XX_PA_SC_WINDOW_OFFSET_X(-xoff) | - A2XX_PA_SC_WINDOW_OFFSET_Y(-yoff));/* PA_SC_WINDOW_OFFSET */ + ctx->emit_tile_renderprep(ctx, xoff, yoff, bw, bh); /* emit IB to drawcmds: */ - OUT_IB (ring, ctx->draw_start, ctx->draw_end); - - OUT_PKT3(ring, CP_SET_CONSTANT, 2); - OUT_RING(ring, CP_REG(REG_A2XX_PA_SC_WINDOW_OFFSET)); - OUT_RING(ring, 0x00000000); /* PA_SC_WINDOW_OFFSET */ + OUT_IB(ctx->ring, ctx->draw_start, ctx->draw_end); /* emit gmem2mem to transfer tile back to system memory: */ - emit_gmem2mem(ctx, ring, xoff, yoff, bw, bh); + ctx->emit_tile_gmem2mem(ctx, xoff, yoff, bw, bh); xoff += bw; } @@ -498,7 +192,7 @@ fd_gmem_render_tiles(struct pipe_context *pctx) fd_ringmarker_mark(ctx->draw_start); /* update timestamps on render targets: */ - fd_pipe_timestamp(ctx->screen->pipe, ×tamp); + timestamp = fd_ringbuffer_timestamp(ctx->ring); fd_resource(pfb->cbufs[0]->texture)->timestamp = timestamp; if (pfb->zsbuf) fd_resource(pfb->zsbuf->texture)->timestamp = timestamp; |