freedreno: add gmem_lock
[mesa.git] / src / gallium / drivers / freedreno / freedreno_context.c
index ad03ac30fb849ed0dfae5d550df3745a2b747ab3..47b7a27ad1f6e847f332dbeb5bb87b68a490b3b2 100644 (file)
@@ -49,11 +49,19 @@ fd_context_flush(struct pipe_context *pctx, struct pipe_fence_handle **fencep,
 
        DBG("%p: flush: flags=%x\n", ctx->batch, flags);
 
+       /* In some sequence of events, we can end up with a last_fence that is
+        * not an "fd" fence, which results in eglDupNativeFenceFDANDROID()
+        * errors.
+        *
+        */
+       if (flags & PIPE_FLUSH_FENCE_FD)
+               fd_fence_ref(&ctx->last_fence, NULL);
+
        /* if no rendering since last flush, ie. app just decided it needed
         * a fence, re-use the last one:
         */
        if (ctx->last_fence) {
-               fd_fence_ref(pctx->screen, &fence, ctx->last_fence);
+               fd_fence_ref(&fence, ctx->last_fence);
                goto out;
        }
 
@@ -61,12 +69,10 @@ fd_context_flush(struct pipe_context *pctx, struct pipe_fence_handle **fencep,
                return;
 
        /* Take a ref to the batch's fence (batch can be unref'd when flushed: */
-       fd_fence_ref(pctx->screen, &fence, batch->fence);
+       fd_fence_ref(&fence, batch->fence);
 
-       /* TODO is it worth trying to figure out if app is using fence-fd's, to
-        * avoid requesting one every batch?
-        */
-       batch->needs_out_fence_fd = true;
+       if (flags & PIPE_FLUSH_FENCE_FD)
+               batch->needs_out_fence_fd = true;
 
        if (!ctx->screen->reorder) {
                fd_batch_flush(batch, true);
@@ -78,11 +84,11 @@ fd_context_flush(struct pipe_context *pctx, struct pipe_fence_handle **fencep,
 
 out:
        if (fencep)
-               fd_fence_ref(pctx->screen, fencep, fence);
+               fd_fence_ref(fencep, fence);
 
-       fd_fence_ref(pctx->screen, &ctx->last_fence, fence);
+       fd_fence_ref(&ctx->last_fence, fence);
 
-       fd_fence_ref(pctx->screen, &fence, NULL);
+       fd_fence_ref(&fence, NULL);
 }
 
 static void
@@ -162,7 +168,7 @@ fd_context_destroy(struct pipe_context *pctx)
 
        DBG("");
 
-       fd_fence_ref(pctx->screen, &ctx->last_fence, NULL);
+       fd_fence_ref(&ctx->last_fence, NULL);
 
        if (ctx->screen->reorder && util_queue_is_initialized(&ctx->flush_queue))
                util_queue_destroy(&ctx->flush_queue);
@@ -187,16 +193,17 @@ fd_context_destroy(struct pipe_context *pctx)
 
        slab_destroy_child(&ctx->transfer_pool);
 
-       for (i = 0; i < ARRAY_SIZE(ctx->vsc_pipe); i++) {
-               struct fd_vsc_pipe *pipe = &ctx->vsc_pipe[i];
-               if (!pipe->bo)
+       for (i = 0; i < ARRAY_SIZE(ctx->vsc_pipe_bo); i++) {
+               if (!ctx->vsc_pipe_bo[i])
                        break;
-               fd_bo_del(pipe->bo);
+               fd_bo_del(ctx->vsc_pipe_bo[i]);
        }
 
        fd_device_del(ctx->dev);
        fd_pipe_del(ctx->pipe);
 
+       mtx_destroy(&ctx->gmem_lock);
+
        if (fd_mesa_debug & (FD_DBG_BSTAT | FD_DBG_MSGS)) {
                printf("batch_total=%u, batch_sysmem=%u, batch_gmem=%u, batch_nondraw=%u, batch_restore=%u\n",
                        (uint32_t)ctx->stats.batch_total, (uint32_t)ctx->stats.batch_sysmem,
@@ -357,6 +364,8 @@ fd_context_init(struct fd_context *ctx, struct pipe_screen *pscreen,
                if (primtypes[i])
                        ctx->primtype_mask |= (1 << i);
 
+       (void) mtx_init(&ctx->gmem_lock, mtx_plain);
+
        /* need some sane default in case state tracker doesn't
         * set some state:
         */