vc4: fix memory leak
[mesa.git] / src / gallium / drivers / vc4 / vc4_context.c
index 630f8e688967abfbc27b4aa6b71515cb759e514b..eeadea0b1db3db03396e4805fbfd2e0b115dff99 100644 (file)
@@ -61,12 +61,20 @@ vc4_flush(struct pipe_context *pctx)
          * FLUSH completes.
          */
         cl_ensure_space(&vc4->bcl, 8);
-        cl_u8(&vc4->bcl, VC4_PACKET_INCREMENT_SEMAPHORE);
+        struct vc4_cl_out *bcl = cl_start(&vc4->bcl);
+        cl_u8(&bcl, VC4_PACKET_INCREMENT_SEMAPHORE);
         /* The FLUSH caps all of our bin lists with a VC4_PACKET_RETURN. */
-        cl_u8(&vc4->bcl, VC4_PACKET_FLUSH);
+        cl_u8(&bcl, VC4_PACKET_FLUSH);
+        cl_end(&vc4->bcl, bcl);
 
         if (cbuf && (vc4->resolve & PIPE_CLEAR_COLOR0)) {
-                pipe_surface_reference(&vc4->color_write, cbuf);
+                pipe_surface_reference(&vc4->color_write,
+                                       cbuf->texture->nr_samples > 1 ?
+                                       NULL : cbuf);
+                pipe_surface_reference(&vc4->msaa_color_write,
+                                       cbuf->texture->nr_samples > 1 ?
+                                       cbuf : NULL);
+
                 if (!(vc4->cleared & PIPE_CLEAR_COLOR0)) {
                         pipe_surface_reference(&vc4->color_read, cbuf);
                 } else {
@@ -76,11 +84,18 @@ vc4_flush(struct pipe_context *pctx)
         } else {
                 pipe_surface_reference(&vc4->color_write, NULL);
                 pipe_surface_reference(&vc4->color_read, NULL);
+                pipe_surface_reference(&vc4->msaa_color_write, NULL);
         }
 
         if (vc4->framebuffer.zsbuf &&
             (vc4->resolve & (PIPE_CLEAR_DEPTH | PIPE_CLEAR_STENCIL))) {
-                pipe_surface_reference(&vc4->zs_write, zsbuf);
+                pipe_surface_reference(&vc4->zs_write,
+                                       zsbuf->texture->nr_samples > 1 ?
+                                       NULL : zsbuf);
+                pipe_surface_reference(&vc4->msaa_zs_write,
+                                       zsbuf->texture->nr_samples > 1 ?
+                                       zsbuf : NULL);
+
                 if (!(vc4->cleared & (PIPE_CLEAR_DEPTH | PIPE_CLEAR_STENCIL))) {
                         pipe_surface_reference(&vc4->zs_read, zsbuf);
                 } else {
@@ -89,6 +104,7 @@ vc4_flush(struct pipe_context *pctx)
         } else {
                 pipe_surface_reference(&vc4->zs_write, NULL);
                 pipe_surface_reference(&vc4->zs_read, NULL);
+                pipe_surface_reference(&vc4->msaa_zs_write, NULL);
         }
 
         vc4_job_submit(vc4);
@@ -103,8 +119,10 @@ vc4_pipe_flush(struct pipe_context *pctx, struct pipe_fence_handle **fence,
         vc4_flush(pctx);
 
         if (fence) {
+                struct pipe_screen *screen = pctx->screen;
                 struct vc4_fence *f = vc4_fence_create(vc4->screen,
                                                        vc4->last_emit_seqno);
+                screen->fence_reference(screen, fence, NULL);
                 *fence = (struct pipe_fence_handle *)f;
         }
 }
@@ -115,7 +133,8 @@ vc4_pipe_flush(struct pipe_context *pctx, struct pipe_fence_handle **fence,
  * This helps avoid flushing the command buffers when unnecessary.
  */
 bool
-vc4_cl_references_bo(struct pipe_context *pctx, struct vc4_bo *bo)
+vc4_cl_references_bo(struct pipe_context *pctx, struct vc4_bo *bo,
+                     bool include_reads)
 {
         struct vc4_context *vc4 = vc4_context(pctx);
 
@@ -125,11 +144,12 @@ vc4_cl_references_bo(struct pipe_context *pctx, struct vc4_bo *bo)
         /* Walk all the referenced BOs in the drawing command list to see if
          * they match.
          */
-        struct vc4_bo **referenced_bos = vc4->bo_pointers.base;
-        for (int i = 0; i < (vc4->bo_handles.next -
-                             vc4->bo_handles.base) / 4; i++) {
-                if (referenced_bos[i] == bo) {
-                        return true;
+        if (include_reads) {
+                struct vc4_bo **referenced_bos = vc4->bo_pointers.base;
+                for (int i = 0; i < cl_offset(&vc4->bo_handles) / 4; i++) {
+                        if (referenced_bos[i] == bo) {
+                                return true;
+                        }
                 }
         }
 
@@ -185,13 +205,16 @@ vc4_context_destroy(struct pipe_context *pctx)
         pipe_surface_reference(&vc4->framebuffer.cbufs[0], NULL);
         pipe_surface_reference(&vc4->framebuffer.zsbuf, NULL);
 
+        pipe_surface_reference(&vc4->color_write, NULL);
+        pipe_surface_reference(&vc4->color_read, NULL);
+
         vc4_program_fini(pctx);
 
         ralloc_free(vc4);
 }
 
 struct pipe_context *
-vc4_context_create(struct pipe_screen *pscreen, void *priv)
+vc4_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags)
 {
         struct vc4_screen *screen = vc4_screen(pscreen);
         struct vc4_context *vc4;
@@ -201,7 +224,7 @@ vc4_context_create(struct pipe_screen *pscreen, void *priv)
         vc4_debug &= ~VC4_DEBUG_SHADERDB;
 
         vc4 = rzalloc(NULL, struct vc4_context);
-        if (vc4 == NULL)
+        if (!vc4)
                 return NULL;
         struct pipe_context *pctx = &vc4->base;
 
@@ -234,11 +257,14 @@ vc4_context_create(struct pipe_screen *pscreen, void *priv)
         if (!vc4->primconvert)
                 goto fail;
 
-        vc4->uploader = u_upload_create(pctx, 16 * 1024, 4,
-                                        PIPE_BIND_INDEX_BUFFER);
+        vc4->uploader = u_upload_create(pctx, 16 * 1024,
+                                        PIPE_BIND_INDEX_BUFFER,
+                                        PIPE_USAGE_STREAM);
 
         vc4_debug |= saved_shaderdb_flag;
 
+        vc4->sample_mask = (1 << VC4_MAX_SAMPLES) - 1;
+
         return &vc4->base;
 
 fail: