freedreno/a6xx: fix VSC bug with larger # of tiles
authorRob Clark <robdclark@gmail.com>
Tue, 30 Oct 2018 12:41:58 +0000 (08:41 -0400)
committerRob Clark <robdclark@gmail.com>
Tue, 6 Nov 2018 13:56:21 +0000 (08:56 -0500)
At higher resolutions with the addition of MSAA, the number of tiles
can increase to the point where we use more than one VSC pipe per
tile.  Which would cause us to calculate an out-of-bounds offset for
VSC_SIZE_ADDRESS.  So don't try to be clever, just always put it at
a fixed offset assuming the max 32 VSC pipes in use.

Signed-off-by: Rob Clark <robdclark@gmail.com>
src/gallium/drivers/freedreno/a6xx/fd6_gmem.c

index 94991dfcfc6cacec841c728e3ab7656c2e69a15b..8278e48d5bde44feb0cfca35b2b94782f72c9f91 100644 (file)
@@ -292,14 +292,13 @@ update_vsc_pipe(struct fd_batch *batch)
        struct fd6_context *fd6_ctx = fd6_context(ctx);
        struct fd_gmem_stateobj *gmem = &ctx->gmem;
        struct fd_ringbuffer *ring = batch->gmem;
-       unsigned n = gmem->nbins_x * gmem->nbins_y;
        int i;
 
        OUT_PKT4(ring, REG_A6XX_VSC_BIN_SIZE, 3);
        OUT_RING(ring, A6XX_VSC_BIN_SIZE_WIDTH(gmem->bin_w) |
                        A6XX_VSC_BIN_SIZE_HEIGHT(gmem->bin_h));
        OUT_RELOCW(ring, fd6_ctx->vsc_data,
-                       n * A6XX_VSC_DATA_PITCH, 0, 0); /* VSC_SIZE_ADDRESS_LO/HI */
+                       32 * A6XX_VSC_DATA_PITCH, 0, 0); /* VSC_SIZE_ADDRESS_LO/HI */
 
        OUT_PKT4(ring, REG_A6XX_VSC_BIN_COUNT, 1);
        OUT_RING(ring, A6XX_VSC_BIN_COUNT_NX(gmem->nbins_x) |
@@ -552,9 +551,7 @@ fd6_emit_tile_prep(struct fd_batch *batch, struct fd_tile *tile)
        OUT_RING(ring, A6XX_VPC_SO_OVERRIDE_SO_DISABLE);
 
        if (use_hw_binning(batch)) {
-               struct fd_gmem_stateobj *gmem = &ctx->gmem;
                struct fd_vsc_pipe *pipe = &ctx->vsc_pipe[tile->p];
-               unsigned n = gmem->nbins_x * gmem->nbins_y;
 
                OUT_PKT7(ring, CP_WAIT_FOR_ME, 0);
 
@@ -570,7 +567,7 @@ fd6_emit_tile_prep(struct fd_batch *batch, struct fd_tile *tile)
                OUT_RELOC(ring, fd6_ctx->vsc_data,       /* VSC_PIPE[p].DATA_ADDRESS */
                                (tile->p * A6XX_VSC_DATA_PITCH), 0, 0);
                OUT_RELOC(ring, fd6_ctx->vsc_data,       /* VSC_SIZE_ADDRESS + (p * 4) */
-                               (tile->p * 4) + (n * A6XX_VSC_DATA_PITCH), 0, 0);
+                               (tile->p * 4) + (32 * A6XX_VSC_DATA_PITCH), 0, 0);
                OUT_RELOC(ring, fd6_ctx->vsc_data2,
                                (tile->p * A6XX_VSC_DATA2_PITCH), 0, 0);
        } else {