diff options
author | Rob Clark <[email protected]> | 2013-05-26 17:13:27 -0400 |
---|---|---|
committer | Rob Clark <[email protected]> | 2013-06-08 13:15:51 -0400 |
commit | 18c317b21ddc2ec4538544f9dd69dc568dcf821f (patch) | |
tree | 224e3c0464dcedabbf5784e5c3def952473fd8f8 /src/gallium/drivers/freedreno/freedreno_gmem.c | |
parent | 213c207b3ac40ae769afe01b8578f566b5e7840d (diff) |
freedreno: prepare for a3xx
Split the parts that are specific to adreno a2xx series GPUs from the
parts that will be in common with a3xx, so that a3xx support can be
added more cleanly.
Signed-off-by: Rob Clark <[email protected]>
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; |