freedreno/a5xx: work around SWAP vs TILE_MODE constraint
[mesa.git] / src / gallium / drivers / freedreno / freedreno_gmem.c
index 310a0266c93646960c0dfe4fb5c71b76673ec02b..37a2f33365daae527cb56fe5bf709f3e2a59527e 100644 (file)
@@ -112,6 +112,7 @@ calculate_tiles(struct fd_batch *batch)
        struct pipe_framebuffer_state *pfb = &batch->framebuffer;
        const uint32_t gmem_alignw = ctx->screen->gmem_alignw;
        const uint32_t gmem_alignh = ctx->screen->gmem_alignh;
+       const unsigned npipes = ctx->screen->num_vsc_pipes;
        const uint32_t gmem_size = ctx->screen->gmemsize_bytes;
        uint32_t minx, miny, width, height;
        uint32_t nbins_x = 1, nbins_y = 1;
@@ -121,7 +122,7 @@ calculate_tiles(struct fd_batch *batch)
        uint32_t i, j, t, xoff, yoff;
        uint32_t tpp_x, tpp_y;
        bool has_zs = !!(batch->resolve & (FD_BUFFER_DEPTH | FD_BUFFER_STENCIL));
-       int tile_n[ARRAY_SIZE(ctx->pipe)];
+       int tile_n[npipes];
 
        if (has_zs) {
                struct fd_resource *rsc = fd_resource(pfb->zsbuf->texture);
@@ -224,8 +225,8 @@ calculate_tiles(struct fd_batch *batch)
 
        /* configure pipes: */
        xoff = yoff = 0;
-       for (i = 0; i < ARRAY_SIZE(ctx->pipe); i++) {
-               struct fd_vsc_pipe *pipe = &ctx->pipe[i];
+       for (i = 0; i < npipes; i++) {
+               struct fd_vsc_pipe *pipe = &ctx->vsc_pipe[i];
 
                if (xoff >= nbins_x) {
                        xoff = 0;
@@ -244,8 +245,8 @@ calculate_tiles(struct fd_batch *batch)
                xoff += tpp_x;
        }
 
-       for (; i < ARRAY_SIZE(ctx->pipe); i++) {
-               struct fd_vsc_pipe *pipe = &ctx->pipe[i];
+       for (; i < npipes; i++) {
+               struct fd_vsc_pipe *pipe = &ctx->vsc_pipe[i];
                pipe->x = pipe->y = pipe->w = pipe->h = 0;
        }
 
@@ -371,15 +372,16 @@ render_sysmem(struct fd_batch *batch)
 static void
 flush_ring(struct fd_batch *batch)
 {
-       struct fd_context *ctx = batch->ctx;
+       /* for compute/blit batch, there is no batch->gmem, only batch->draw: */
+       struct fd_ringbuffer *ring = batch->nondraw ? batch->draw : batch->gmem;
+       uint32_t timestamp;
        int out_fence_fd = -1;
 
-       fd_ringbuffer_flush2(batch->gmem, batch->in_fence_fd,
+       fd_ringbuffer_flush2(ring, batch->in_fence_fd,
                        batch->needs_out_fence_fd ? &out_fence_fd : NULL);
 
-       fd_fence_ref(&ctx->screen->base, &ctx->last_fence, NULL);
-       ctx->last_fence = fd_fence_create(ctx,
-                       fd_ringbuffer_timestamp(batch->gmem), out_fence_fd);
+       timestamp = fd_ringbuffer_timestamp(ring);
+       fd_fence_populate(batch->fence, timestamp, out_fence_fd);
 }
 
 void
@@ -389,23 +391,29 @@ fd_gmem_render_tiles(struct fd_batch *batch)
        struct pipe_framebuffer_state *pfb = &batch->framebuffer;
        bool sysmem = false;
 
-       if (ctx->emit_sysmem_prep) {
-               if (batch->num_draws == 0) {
-                       sysmem = true;
-               } else if (batch->cleared || batch->gmem_reason || (batch->num_draws > 5)) {
-                       // TODO maybe consider # of draws w/ blend enabled, etc?
+       if (ctx->emit_sysmem_prep && !batch->nondraw) {
+               if (batch->cleared || batch->gmem_reason ||
+                               ((batch->num_draws > 5) && !batch->blit)) {
                        DBG("GMEM: cleared=%x, gmem_reason=%x, num_draws=%u",
                                batch->cleared, batch->gmem_reason, batch->num_draws);
                } else if (!(fd_mesa_debug & FD_DBG_NOBYPASS)) {
                        sysmem = true;
                }
+
+               /* For ARB_framebuffer_no_attachments: */
+               if ((pfb->nr_cbufs == 0) && !pfb->zsbuf) {
+                       sysmem = true;
+               }
        }
 
        fd_reset_wfi(batch);
 
        ctx->stats.batch_total++;
 
-       if (sysmem) {
+       if (batch->nondraw) {
+               DBG("%p: rendering non-draw", batch);
+               ctx->stats.batch_nondraw++;
+       } else if (sysmem) {
                DBG("%p: rendering sysmem %ux%u (%s/%s)",
                        batch, pfb->width, pfb->height,
                        util_format_short_name(pipe_surface_format(pfb->cbufs[0])),
@@ -445,13 +453,6 @@ fd_gmem_render_noop(struct fd_batch *batch)
        flush_ring(batch);
 }
 
-void
-fd_gmem_flush_compute(struct fd_batch *batch)
-{
-       render_sysmem(batch);
-       flush_ring(batch);
-}
-
 /* tile needs restore if it isn't completely contained within the
  * cleared scissor:
  */