summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/freedreno/a3xx
diff options
context:
space:
mode:
authorRob Clark <[email protected]>2013-12-20 20:48:18 -0500
committerRob Clark <[email protected]>2013-12-26 12:06:29 -0500
commitbe01d7a905d827c3c0c222cab2430c6d4575429a (patch)
treefc714be776c88076f061280b60137c1322af103b /src/gallium/drivers/freedreno/a3xx
parent64fe0670664bc6f2c75cc1630aa07cef1898b8b5 (diff)
freedreno: prepare for hw binning
Actually assign VSC_PIPE's properly, which will be needed for tiling. And introduce fd_tile for per-tile state (including the assignment of tile to VSC_PIPE). This gives us the proper pipe setup that we'll need for hw binning pass, and also cleans things up a bit by not having to pass so many parameters around. And will also make it easier to introduce different tiling patterns (since we may no longer render tiles in a simple left-to-right top-to-bottom pattern). Signed-off-by: Rob Clark <[email protected]>
Diffstat (limited to 'src/gallium/drivers/freedreno/a3xx')
-rw-r--r--src/gallium/drivers/freedreno/a3xx/fd3_context.c4
-rw-r--r--src/gallium/drivers/freedreno/a3xx/fd3_context.h7
-rw-r--r--src/gallium/drivers/freedreno/a3xx/fd3_gmem.c73
-rw-r--r--src/gallium/drivers/freedreno/a3xx/fd3_program.c27
4 files changed, 34 insertions, 77 deletions
diff --git a/src/gallium/drivers/freedreno/a3xx/fd3_context.c b/src/gallium/drivers/freedreno/a3xx/fd3_context.c
index 13f91e9de0c..23467193d43 100644
--- a/src/gallium/drivers/freedreno/a3xx/fd3_context.c
+++ b/src/gallium/drivers/freedreno/a3xx/fd3_context.c
@@ -47,7 +47,6 @@ fd3_context_destroy(struct pipe_context *pctx)
fd_bo_del(fd3_ctx->vs_pvt_mem);
fd_bo_del(fd3_ctx->fs_pvt_mem);
fd_bo_del(fd3_ctx->vsc_size_mem);
- fd_bo_del(fd3_ctx->vsc_pipe_mem);
pipe_resource_reference(&fd3_ctx->solid_vbuf, NULL);
pipe_resource_reference(&fd3_ctx->blit_texcoord_vbuf, NULL);
@@ -129,9 +128,6 @@ fd3_context_create(struct pipe_screen *pscreen, void *priv)
fd3_ctx->vsc_size_mem = fd_bo_new(screen->dev, 0x1000,
DRM_FREEDRENO_GEM_TYPE_KMEM);
- fd3_ctx->vsc_pipe_mem = fd_bo_new(screen->dev, 0x40000,
- DRM_FREEDRENO_GEM_TYPE_KMEM);
-
fd3_ctx->solid_vbuf = create_solid_vertexbuf(pctx);
fd3_ctx->blit_texcoord_vbuf = create_blit_texcoord_vertexbuf(pctx);
diff --git a/src/gallium/drivers/freedreno/a3xx/fd3_context.h b/src/gallium/drivers/freedreno/a3xx/fd3_context.h
index 3829ab52675..3599fe1bb08 100644
--- a/src/gallium/drivers/freedreno/a3xx/fd3_context.h
+++ b/src/gallium/drivers/freedreno/a3xx/fd3_context.h
@@ -38,14 +38,11 @@ struct fd3_context {
struct fd_bo *vs_pvt_mem, *fs_pvt_mem;
- /* not sure how big this actually needs to be.. the blob driver
- * combines it w/ the solid_vertexbuf, we could probably do the
- * same to save an extra bo allocation..
+ /* This only needs to be 4 * num_of_pipes bytes (ie. 32 bytes). We
+ * could combine it with another allocation.
*/
struct fd_bo *vsc_size_mem;
- struct fd_bo *vsc_pipe_mem;
-
/* vertex buf used for clear/gmem->mem vertices, and mem->gmem
* vertices:
*/
diff --git a/src/gallium/drivers/freedreno/a3xx/fd3_gmem.c b/src/gallium/drivers/freedreno/a3xx/fd3_gmem.c
index 7be0b6881ce..4a5a241bac9 100644
--- a/src/gallium/drivers/freedreno/a3xx/fd3_gmem.c
+++ b/src/gallium/drivers/freedreno/a3xx/fd3_gmem.c
@@ -134,8 +134,7 @@ emit_gmem2mem_surf(struct fd_context *ctx,
}
static void
-fd3_emit_tile_gmem2mem(struct fd_context *ctx, uint32_t xoff, uint32_t yoff,
- uint32_t bin_w, uint32_t bin_h)
+fd3_emit_tile_gmem2mem(struct fd_context *ctx, struct fd_tile *tile)
{
struct fd3_context *fd3_ctx = fd3_context(ctx);
struct fd_ringbuffer *ring = ctx->ring;
@@ -256,21 +255,22 @@ emit_mem2gmem_surf(struct fd_context *ctx, uint32_t base,
}
static void
-fd3_emit_tile_mem2gmem(struct fd_context *ctx, uint32_t xoff, uint32_t yoff,
- uint32_t bin_w, uint32_t bin_h)
+fd3_emit_tile_mem2gmem(struct fd_context *ctx, struct fd_tile *tile)
{
struct fd3_context *fd3_ctx = fd3_context(ctx);
struct fd_gmem_stateobj *gmem = &ctx->gmem;
struct fd_ringbuffer *ring = ctx->ring;
struct pipe_framebuffer_state *pfb = &ctx->framebuffer;
float x0, y0, x1, y1;
+ unsigned bin_w = tile->bin_w;
+ unsigned bin_h = tile->bin_h;
unsigned i;
/* 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);
+ x0 = ((float)tile->xoff) / ((float)pfb->width);
+ x1 = ((float)tile->xoff + bin_w) / ((float)pfb->width);
+ y0 = ((float)tile->yoff) / ((float)pfb->height);
+ y1 = ((float)tile->yoff + bin_h) / ((float)pfb->height);
OUT_PKT3(ring, CP_MEM_WRITE, 5);
OUT_RELOC(ring, fd_resource(fd3_ctx->blit_texcoord_vbuf)->bo, 0, 0, 0);
@@ -384,29 +384,23 @@ static void
update_vsc_pipe(struct fd_context *ctx)
{
struct fd_ringbuffer *ring = ctx->ring;
- struct fd_gmem_stateobj *gmem = &ctx->gmem;
- struct fd_bo *bo = fd3_context(ctx)->vsc_pipe_mem;
int i;
- /* since we aren't using binning, just try to assign all bins
- * to same pipe for now:
- */
- OUT_PKT0(ring, REG_A3XX_VSC_PIPE(0), 3);
- OUT_RING(ring, A3XX_VSC_PIPE_CONFIG_X(0) |
- A3XX_VSC_PIPE_CONFIG_Y(0) |
- A3XX_VSC_PIPE_CONFIG_W(gmem->nbins_x) |
- A3XX_VSC_PIPE_CONFIG_H(gmem->nbins_y));
- OUT_RELOC(ring, bo, 0, 0, 0); /* VSC_PIPE[0].DATA_ADDRESS */
- OUT_RING(ring, fd_bo_size(bo) - 32); /* VSC_PIPE[0].DATA_LENGTH */
-
- for (i = 1; i < 8; i++) {
- OUT_PKT0(ring, REG_A3XX_VSC_PIPE(i), 3);
- OUT_RING(ring, A3XX_VSC_PIPE_CONFIG_X(0) |
- A3XX_VSC_PIPE_CONFIG_Y(0) |
- A3XX_VSC_PIPE_CONFIG_W(0) |
- A3XX_VSC_PIPE_CONFIG_H(0));
- OUT_RING(ring, 0x00000000); /* VSC_PIPE[i].DATA_ADDRESS */
- OUT_RING(ring, 0x00000000); /* VSC_PIPE[i].DATA_LENGTH */
+ for (i = 0; i < 8; i++) {
+ struct fd_vsc_pipe *pipe = &ctx->pipe[i];
+
+ if (!pipe->bo) {
+ pipe->bo = fd_bo_new(ctx->screen->dev, 0x40000,
+ DRM_FREEDRENO_GEM_TYPE_KMEM);
+ }
+
+ OUT_PKT0(ring, REG_A3XX_VSC_PIPE(0), 3);
+ OUT_RING(ring, A3XX_VSC_PIPE_CONFIG_X(pipe->x) |
+ A3XX_VSC_PIPE_CONFIG_Y(pipe->y) |
+ A3XX_VSC_PIPE_CONFIG_W(pipe->w) |
+ A3XX_VSC_PIPE_CONFIG_H(pipe->h));
+ OUT_RELOC(ring, pipe->bo, 0, 0, 0); /* VSC_PIPE[i].DATA_ADDRESS */
+ OUT_RING(ring, fd_bo_size(pipe->bo) - 32); /* VSC_PIPE[i].DATA_LENGTH */
}
}
@@ -465,16 +459,12 @@ fd3_emit_tile_init(struct fd_context *ctx)
OUT_RING(ring, A3XX_VSC_BIN_SIZE_WIDTH(gmem->bin_w) |
A3XX_VSC_BIN_SIZE_HEIGHT(gmem->bin_h));
- /* TODO we only need to do this if gmem stateobj changes.. or in
- * particular if the # of bins changes..
- */
update_vsc_pipe(ctx);
}
/* before mem2gmem */
static void
-fd3_emit_tile_prep(struct fd_context *ctx, uint32_t xoff, uint32_t yoff,
- uint32_t bin_w, uint32_t bin_h)
+fd3_emit_tile_prep(struct fd_context *ctx, struct fd_tile *tile)
{
struct fd_ringbuffer *ring = ctx->ring;
struct pipe_framebuffer_state *pfb = &ctx->framebuffer;
@@ -506,17 +496,16 @@ fd3_emit_tile_prep(struct fd_context *ctx, uint32_t xoff, uint32_t yoff,
/* before IB to rendering cmds: */
static void
-fd3_emit_tile_renderprep(struct fd_context *ctx, uint32_t xoff, uint32_t yoff,
- uint32_t bin_w, uint32_t bin_h)
+fd3_emit_tile_renderprep(struct fd_context *ctx, struct fd_tile *tile)
{
struct fd_ringbuffer *ring = ctx->ring;
struct fd_gmem_stateobj *gmem = &ctx->gmem;
struct pipe_framebuffer_state *pfb = &ctx->framebuffer;
- uint32_t x1 = xoff;
- uint32_t y1 = yoff;
- uint32_t x2 = xoff + bin_w - 1;
- uint32_t y2 = yoff + bin_h - 1;
+ uint32_t x1 = tile->xoff;
+ uint32_t y1 = tile->yoff;
+ uint32_t x2 = tile->xoff + tile->bin_w - 1;
+ uint32_t y2 = tile->yoff + tile->bin_h - 1;
OUT_PKT3(ring, CP_SET_BIN, 3);
OUT_RING(ring, 0x00000000);
@@ -531,8 +520,8 @@ fd3_emit_tile_renderprep(struct fd_context *ctx, uint32_t xoff, uint32_t yoff,
/* setup scissor/offset for current tile: */
OUT_PKT0(ring, REG_A3XX_RB_WINDOW_OFFSET, 1);
- OUT_RING(ring, A3XX_RB_WINDOW_OFFSET_X(xoff) |
- A3XX_RB_WINDOW_OFFSET_Y(yoff));
+ OUT_RING(ring, A3XX_RB_WINDOW_OFFSET_X(tile->xoff) |
+ A3XX_RB_WINDOW_OFFSET_Y(tile->yoff));
OUT_PKT0(ring, REG_A3XX_GRAS_SC_SCREEN_SCISSOR_TL, 2);
OUT_RING(ring, A3XX_GRAS_SC_SCREEN_SCISSOR_TL_X(x1) |
diff --git a/src/gallium/drivers/freedreno/a3xx/fd3_program.c b/src/gallium/drivers/freedreno/a3xx/fd3_program.c
index 17659af373f..c02b14cba39 100644
--- a/src/gallium/drivers/freedreno/a3xx/fd3_program.c
+++ b/src/gallium/drivers/freedreno/a3xx/fd3_program.c
@@ -266,17 +266,6 @@ fd3_program_emit(struct fd_ringbuffer *ring,
// XXX sometimes 0, sometimes 1:
A3XX_SP_SP_CTRL_REG_LOMODE(1));
- /* emit unknown sequence of perfcounter disables that the blob
- * emits as part of the program state..
- */
- for (i = 0; i < 6; i++) {
- OUT_PKT0(ring, REG_A3XX_SP_PERFCOUNTER0_SELECT, 1);
- OUT_RING(ring, 0x00000000); /* SP_PERFCOUNTER0_SELECT */
-
- OUT_PKT0(ring, REG_A3XX_SP_PERFCOUNTER4_SELECT, 1);
- OUT_RING(ring, 0x00000000); /* SP_PERFCOUNTER4_SELECT */
- }
-
OUT_PKT0(ring, REG_A3XX_SP_VS_LENGTH_REG, 1);
OUT_RING(ring, A3XX_SP_VS_LENGTH_REG_SHADERLENGTH(vp->instrlen));
@@ -329,22 +318,10 @@ fd3_program_emit(struct fd_ringbuffer *ring,
OUT_RING(ring, reg);
}
-#if 0
- /* for some reason, when I write SP_{VS,FS}_OBJ_START_REG I get:
-[ 666.663665] kgsl kgsl-3d0: |a3xx_err_callback| RBBM | AHB bus error | READ | addr=201 | ports=1:3
-[ 666.664001] kgsl kgsl-3d0: |a3xx_err_callback| ringbuffer AHB error interrupt
-[ 670.680909] kgsl kgsl-3d0: |adreno_idle| spun too long waiting for RB to idle
-[ 670.681062] kgsl kgsl-3d0: |kgsl-3d0| Dump Started
-[ 670.681123] kgsl kgsl-3d0: POWER: FLAGS = 00000007 | ACTIVE POWERLEVEL = 00000001
-[ 670.681214] kgsl kgsl-3d0: POWER: INTERVAL TIMEOUT = 0000000A
-[ 670.681367] kgsl kgsl-3d0: GRP_CLK = 325000000
-[ 670.681489] kgsl kgsl-3d0: BUS CLK = 0
- */
OUT_PKT0(ring, REG_A3XX_SP_VS_OBJ_OFFSET_REG, 2);
OUT_RING(ring, A3XX_SP_VS_OBJ_OFFSET_REG_CONSTOBJECTOFFSET(0) |
A3XX_SP_VS_OBJ_OFFSET_REG_SHADEROBJOFFSET(0));
OUT_RELOC(ring, vp->bo, 0, 0, 0); /* SP_VS_OBJ_START_REG */
-#endif
OUT_PKT0(ring, REG_A3XX_SP_FS_LENGTH_REG, 1);
OUT_RING(ring, A3XX_SP_FS_LENGTH_REG_SHADERLENGTH(fp->instrlen));
@@ -364,12 +341,10 @@ fd3_program_emit(struct fd_ringbuffer *ring,
A3XX_SP_FS_CTRL_REG1_CONSTFOOTPRINT(MAX2(fsi->max_const, 0)) |
A3XX_SP_FS_CTRL_REG1_HALFPRECVAROFFSET(63));
-#if 0
OUT_PKT0(ring, REG_A3XX_SP_FS_OBJ_OFFSET_REG, 2);
OUT_RING(ring, A3XX_SP_FS_OBJ_OFFSET_REG_CONSTOBJECTOFFSET(128) |
- A3XX_SP_FS_OBJ_OFFSET_REG_SHADEROBJOFFSET(128 - fp->instrlen));
+ A3XX_SP_FS_OBJ_OFFSET_REG_SHADEROBJOFFSET(0));
OUT_RELOC(ring, fp->bo, 0, 0, 0); /* SP_FS_OBJ_START_REG */
-#endif
OUT_PKT0(ring, REG_A3XX_SP_FS_FLAT_SHAD_MODE_REG_0, 2);
OUT_RING(ring, 0x00000000); /* SP_FS_FLAT_SHAD_MODE_REG_0 */