gallium/radeon: reallocate suballocated buffers when exported
authorMarek Olšák <marek.olsak@amd.com>
Tue, 4 Jul 2017 15:29:46 +0000 (17:29 +0200)
committerMarek Olšák <marek.olsak@amd.com>
Mon, 17 Jul 2017 14:50:39 +0000 (10:50 -0400)
This should fix exports of suballocated buffers.

Reviewed-by: Nicolai Hähnle <nicolai.haehnle@amd.com>
src/gallium/drivers/radeon/r600_buffer_common.c
src/gallium/drivers/radeon/r600_texture.c

index 40d763bd9f5a272089e27cc76db5ce1777130a11..dd1c2090fdfbd3206282490c5495fa40cb966610 100644 (file)
@@ -288,13 +288,14 @@ void r600_replace_buffer_storage(struct pipe_context *ctx,
 
        pb_reference(&rdst->buf, rsrc->buf);
        rdst->gpu_address = rsrc->gpu_address;
+       rdst->b.b.bind = rsrc->b.b.bind;
+       rdst->flags = rsrc->flags;
 
        assert(rdst->vram_usage == rsrc->vram_usage);
        assert(rdst->gart_usage == rsrc->gart_usage);
        assert(rdst->bo_size == rsrc->bo_size);
        assert(rdst->bo_alignment == rsrc->bo_alignment);
        assert(rdst->domains == rsrc->domains);
-       assert(rdst->flags == rsrc->flags);
 
        rctx->rebind_buffer(ctx, dst, old_gpu_address);
 }
index f5f7d1030c8d68299db40cc0fa61235fc5bf5045..3aac3c78a987057cfed88ef6f64f4158bfb4af7e 100644 (file)
@@ -618,6 +618,32 @@ static boolean r600_texture_get_handle(struct pipe_screen* screen,
                        slice_size = rtex->surface.u.legacy.level[0].slice_size;
                }
        } else {
+               /* Move a suballocated buffer into a non-suballocated allocation. */
+               if (rscreen->ws->buffer_is_suballocated(res->buf)) {
+                       assert(!res->b.is_shared);
+
+                       /* Allocate a new buffer with PIPE_BIND_SHARED. */
+                       struct pipe_resource templ = res->b.b;
+                       templ.bind |= PIPE_BIND_SHARED;
+
+                       struct pipe_resource *newb =
+                               screen->resource_create(screen, &templ);
+                       if (!newb)
+                               return false;
+
+                       /* Copy the old buffer contents to the new one. */
+                       struct pipe_box box;
+                       u_box_1d(0, newb->width0, &box);
+                       rctx->b.resource_copy_region(&rctx->b, newb, 0, 0, 0, 0,
+                                                    &res->b.b, 0, &box);
+                       /* Move the new buffer storage to the old pipe_resource. */
+                       r600_replace_buffer_storage(&rctx->b, &res->b.b, newb);
+                       pipe_resource_reference(&newb, NULL);
+
+                       assert(res->b.b.bind & PIPE_BIND_SHARED);
+                       assert(res->flags & RADEON_FLAG_NO_SUBALLOC);
+               }
+
                /* Buffers */
                offset = 0;
                stride = 0;