r600g,radeonsi: consolidate buffer code, add handling of DISCARD_RANGE for SI
authorMarek Olšák <marek.olsak@amd.com>
Fri, 29 Nov 2013 16:28:23 +0000 (17:28 +0100)
committerMarek Olšák <marek.olsak@amd.com>
Thu, 12 Dec 2013 17:34:11 +0000 (18:34 +0100)
This adds 2 optimizations for radeonsi:
- handling of DISCARD_RANGE
- mapping an uninitialized buffer range is automatically UNSYNCHRONIZED

Reviewed-by: Michel Dänzer <michel.daenzer@amd.com>
13 files changed:
src/gallium/drivers/r600/Makefile.sources
src/gallium/drivers/r600/r600_buffer.c [deleted file]
src/gallium/drivers/r600/r600_pipe.c
src/gallium/drivers/r600/r600_pipe.h
src/gallium/drivers/r600/r600_state_common.c
src/gallium/drivers/radeon/r600_buffer_common.c
src/gallium/drivers/radeon/r600_pipe_common.c
src/gallium/drivers/radeon/r600_pipe_common.h
src/gallium/drivers/radeonsi/r600_buffer.c
src/gallium/drivers/radeonsi/r600_resource.c
src/gallium/drivers/radeonsi/r600_translate.c
src/gallium/drivers/radeonsi/radeonsi_pipe.c
src/gallium/drivers/radeonsi/radeonsi_pipe.h

index 76fd164b6e6e2a8de8728afc3061a304753e9db3..d96d98bc0a12433a65218bdec778b532653d6cf0 100644 (file)
@@ -1,7 +1,6 @@
 C_SOURCES = \
        r600_asm.c \
        r600_blit.c \
-       r600_buffer.c \
        r600_hw_context.c \
        r600_isa.c \
        r600_pipe.c \
diff --git a/src/gallium/drivers/r600/r600_buffer.c b/src/gallium/drivers/r600/r600_buffer.c
deleted file mode 100644 (file)
index 969803f..0000000
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
- * Copyright 2010 Jerome Glisse <glisse@freedesktop.org>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * on the rights to use, copy, modify, merge, publish, distribute, sub
- * license, and/or sell copies of the Software, and to permit persons to whom
- * the Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
- * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
- * USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- *      Jerome Glisse
- *      Corbin Simpson <MostAwesomeDude@gmail.com>
- */
-#include "r600_pipe.h"
-#include "util/u_upload_mgr.h"
-#include "util/u_memory.h"
-#include "util/u_surface.h"
-
-static void r600_buffer_destroy(struct pipe_screen *screen,
-                               struct pipe_resource *buf)
-{
-       struct r600_resource *rbuffer = r600_resource(buf);
-
-       util_range_destroy(&rbuffer->valid_buffer_range);
-       pb_reference(&rbuffer->buf, NULL);
-       FREE(rbuffer);
-}
-
-static void *r600_buffer_get_transfer(struct pipe_context *ctx,
-                                     struct pipe_resource *resource,
-                                      unsigned level,
-                                      unsigned usage,
-                                      const struct pipe_box *box,
-                                     struct pipe_transfer **ptransfer,
-                                     void *data, struct r600_resource *staging,
-                                     unsigned offset)
-{
-       struct r600_context *rctx = (struct r600_context*)ctx;
-       struct r600_transfer *transfer = util_slab_alloc(&rctx->pool_transfers);
-
-       transfer->transfer.resource = resource;
-       transfer->transfer.level = level;
-       transfer->transfer.usage = usage;
-       transfer->transfer.box = *box;
-       transfer->transfer.stride = 0;
-       transfer->transfer.layer_stride = 0;
-       transfer->offset = offset;
-       transfer->staging = staging;
-       *ptransfer = &transfer->transfer;
-       return data;
-}
-
-static void *r600_buffer_transfer_map(struct pipe_context *ctx,
-                                       struct pipe_resource *resource,
-                                       unsigned level,
-                                       unsigned usage,
-                                       const struct pipe_box *box,
-                                       struct pipe_transfer **ptransfer)
-{
-       struct r600_context *rctx = (struct r600_context*)ctx;
-       struct r600_resource *rbuffer = r600_resource(resource);
-       uint8_t *data;
-
-       assert(box->x + box->width <= resource->width0);
-
-       /* See if the buffer range being mapped has never been initialized,
-        * in which case it can be mapped unsynchronized. */
-       if (!(usage & PIPE_TRANSFER_UNSYNCHRONIZED) &&
-           usage & PIPE_TRANSFER_WRITE &&
-           !util_ranges_intersect(&rbuffer->valid_buffer_range, box->x, box->x + box->width)) {
-               usage |= PIPE_TRANSFER_UNSYNCHRONIZED;
-       }
-
-       if (usage & PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE &&
-           !(usage & PIPE_TRANSFER_UNSYNCHRONIZED)) {
-               assert(usage & PIPE_TRANSFER_WRITE);
-
-               /* Check if mapping this buffer would cause waiting for the GPU. */
-               if (r600_rings_is_buffer_referenced(&rctx->b, rbuffer->cs_buf, RADEON_USAGE_READWRITE) ||
-                   rctx->b.ws->buffer_is_busy(rbuffer->buf, RADEON_USAGE_READWRITE)) {
-                       rctx->b.invalidate_buffer(&rctx->b.b, &rbuffer->b.b);
-               }
-       }
-       else if ((usage & PIPE_TRANSFER_DISCARD_RANGE) &&
-                !(usage & PIPE_TRANSFER_UNSYNCHRONIZED) &&
-                !(rctx->screen->b.debug_flags & DBG_NO_DISCARD_RANGE) &&
-                (rctx->screen->b.has_cp_dma ||
-                 (rctx->screen->b.has_streamout &&
-                  /* The buffer range must be aligned to 4 with streamout. */
-                  box->x % 4 == 0 && box->width % 4 == 0))) {
-               assert(usage & PIPE_TRANSFER_WRITE);
-
-               /* Check if mapping this buffer would cause waiting for the GPU. */
-               if (r600_rings_is_buffer_referenced(&rctx->b, rbuffer->cs_buf, RADEON_USAGE_READWRITE) ||
-                   rctx->b.ws->buffer_is_busy(rbuffer->buf, RADEON_USAGE_READWRITE)) {
-                       /* Do a wait-free write-only transfer using a temporary buffer. */
-                       unsigned offset;
-                       struct r600_resource *staging = NULL;
-
-                       u_upload_alloc(rctx->uploader, 0, box->width + (box->x % R600_MAP_BUFFER_ALIGNMENT),
-                                      &offset, (struct pipe_resource**)&staging, (void**)&data);
-
-                       if (staging) {
-                               data += box->x % R600_MAP_BUFFER_ALIGNMENT;
-                               return r600_buffer_get_transfer(ctx, resource, level, usage, box,
-                                                               ptransfer, data, staging, offset);
-                       }
-               }
-       }
-
-       /* mmap and synchronize with rings */
-       data = r600_buffer_map_sync_with_rings(&rctx->b, rbuffer, usage);
-       if (!data) {
-               return NULL;
-       }
-       data += box->x;
-
-       return r600_buffer_get_transfer(ctx, resource, level, usage, box,
-                                       ptransfer, data, NULL, 0);
-}
-
-static void r600_buffer_transfer_unmap(struct pipe_context *pipe,
-                                       struct pipe_transfer *transfer)
-{
-       struct r600_context *rctx = (struct r600_context*)pipe;
-       struct r600_transfer *rtransfer = (struct r600_transfer*)transfer;
-       struct r600_resource *rbuffer = r600_resource(transfer->resource);
-
-       if (rtransfer->staging) {
-               struct pipe_resource *dst, *src;
-               unsigned soffset, doffset, size;
-               struct pipe_box box;
-
-               dst = transfer->resource;
-               src = &rtransfer->staging->b.b;
-               size = transfer->box.width;
-               doffset = transfer->box.x;
-               soffset = rtransfer->offset + transfer->box.x % R600_MAP_BUFFER_ALIGNMENT;
-
-               u_box_1d(soffset, size, &box);
-
-               /* Copy the staging buffer into the original one. */
-               if (!(size % 4) && !(doffset % 4) && !(soffset % 4) &&
-                   rctx->b.dma_copy(pipe, dst, 0, doffset, 0, 0, src, 0, &box)) {
-                       /* DONE. */
-               } else {
-                       pipe->resource_copy_region(pipe, dst, 0, doffset, 0, 0, src, 0, &box);
-               }
-               pipe_resource_reference((struct pipe_resource**)&rtransfer->staging, NULL);
-       }
-
-       if (transfer->usage & PIPE_TRANSFER_WRITE) {
-               util_range_add(&rbuffer->valid_buffer_range, transfer->box.x,
-                              transfer->box.x + transfer->box.width);
-       }
-       util_slab_free(&rctx->pool_transfers, transfer);
-}
-
-static const struct u_resource_vtbl r600_buffer_vtbl =
-{
-       u_default_resource_get_handle,          /* get_handle */
-       r600_buffer_destroy,                    /* resource_destroy */
-       r600_buffer_transfer_map,               /* transfer_map */
-       NULL,                                   /* transfer_flush_region */
-       r600_buffer_transfer_unmap,             /* transfer_unmap */
-       NULL                                    /* transfer_inline_write */
-};
-
-struct pipe_resource *r600_buffer_create(struct pipe_screen *screen,
-                                        const struct pipe_resource *templ,
-                                        unsigned alignment)
-{
-       struct r600_screen *rscreen = (struct r600_screen*)screen;
-       struct r600_resource *rbuffer;
-
-       rbuffer = MALLOC_STRUCT(r600_resource);
-
-       rbuffer->b.b = *templ;
-       pipe_reference_init(&rbuffer->b.b.reference, 1);
-       rbuffer->b.b.screen = screen;
-       rbuffer->b.vtbl = &r600_buffer_vtbl;
-       util_range_init(&rbuffer->valid_buffer_range);
-
-       if (!r600_init_resource(&rscreen->b, rbuffer, templ->width0, alignment, TRUE, templ->usage)) {
-               FREE(rbuffer);
-               return NULL;
-       }
-       return &rbuffer->b.b;
-}
index 296d4660182d28270dbea32fd0fcc59b6fb4d1e1..4016bbe152090708a2bd7119650f504233521834 100644 (file)
@@ -179,13 +179,9 @@ static void r600_destroy_context(struct pipe_context *context)
        if (rctx->blitter) {
                util_blitter_destroy(rctx->blitter);
        }
-       if (rctx->uploader) {
-               u_upload_destroy(rctx->uploader);
-       }
        if (rctx->allocator_fetch_shader) {
                u_suballocator_destroy(rctx->allocator_fetch_shader);
        }
-       util_slab_destroy(&rctx->pool_transfers);
 
        r600_release_command_buffer(&rctx->start_cs_cmd);
 
@@ -208,10 +204,6 @@ static struct pipe_context *r600_create_context(struct pipe_screen *screen, void
        if (rctx == NULL)
                return NULL;
 
-       util_slab_create(&rctx->pool_transfers,
-                        sizeof(struct r600_transfer), 64,
-                        UTIL_SLAB_SINGLETHREADED);
-
        rctx->b.b.screen = screen;
        rctx->b.b.priv = priv;
        rctx->b.b.destroy = r600_destroy_context;
@@ -295,12 +287,6 @@ static struct pipe_context *r600_create_context(struct pipe_screen *screen, void
                rctx->b.rings.dma.flushing = false;
        }
 
-       rctx->uploader = u_upload_create(&rctx->b.b, 1024 * 1024, 256,
-                                       PIPE_BIND_INDEX_BUFFER |
-                                       PIPE_BIND_CONSTANT_BUFFER);
-       if (!rctx->uploader)
-               goto fail;
-
        rctx->allocator_fetch_shader = u_suballocator_create(&rctx->b.b, 64 * 1024, 256,
                                                             0, PIPE_USAGE_STATIC, FALSE);
        if (!rctx->allocator_fetch_shader)
index 15e89a0e26394241540a4ab34dc69884a0a6c097..735047920ff1b7a0fa7a6e4aedec6019c059d8ae 100644 (file)
@@ -34,7 +34,6 @@
 #include "r600_resource.h"
 
 #include "util/u_blitter.h"
-#include "util/u_slab.h"
 #include "util/u_suballoc.h"
 #include "util/u_double_list.h"
 #include "util/u_transfer.h"
@@ -63,8 +62,6 @@
 #define R600_BIG_ENDIAN 0
 #endif
 
-#define R600_MAP_BUFFER_ALIGNMENT 64
-
 #define R600_QUERY_DRAW_CALLS          (PIPE_QUERY_DRIVER_SPECIFIC + 0)
 #define R600_QUERY_REQUESTED_VRAM      (PIPE_QUERY_DRIVER_SPECIFIC + 1)
 #define R600_QUERY_REQUESTED_GTT       (PIPE_QUERY_DRIVER_SPECIFIC + 2)
@@ -399,9 +396,7 @@ struct r600_context {
        struct r600_common_context      b;
        struct r600_screen              *screen;
        struct blitter_context          *blitter;
-       struct u_upload_mgr             *uploader;
        struct u_suballocator           *allocator_fetch_shader;
-       struct util_slab_mempool        pool_transfers;
        unsigned                        initial_gfx_cs_size;
 
        /* Hardware info. */
@@ -601,11 +596,6 @@ void r600_decompress_depth_textures(struct r600_context *rctx,
 void r600_decompress_color_textures(struct r600_context *rctx,
                                    struct r600_samplerview_state *textures);
 
-/* r600_buffer.c */
-struct pipe_resource *r600_buffer_create(struct pipe_screen *screen,
-                                        const struct pipe_resource *templ,
-                                        unsigned alignment);
-
 /* r600_pipe.c */
 const char * r600_llvm_gpu_string(enum radeon_family family);
 
index 3c7bfe9474513083c3af710b6aa4b5f9d27f5ed6..3dc79910247bb7d6699ad3f93dee581bb8c3fb52 100644 (file)
@@ -953,10 +953,10 @@ static void r600_set_constant_buffer(struct pipe_context *ctx, uint shader, uint
                                tmpPtr[i] = util_bswap32(((uint32_t *)ptr)[i]);
                        }
 
-                       u_upload_data(rctx->uploader, 0, size, tmpPtr, &cb->buffer_offset, &cb->buffer);
+                       u_upload_data(rctx->b.uploader, 0, size, tmpPtr, &cb->buffer_offset, &cb->buffer);
                        free(tmpPtr);
                } else {
-                       u_upload_data(rctx->uploader, 0, input->buffer_size, ptr, &cb->buffer_offset, &cb->buffer);
+                       u_upload_data(rctx->b.uploader, 0, input->buffer_size, ptr, &cb->buffer_offset, &cb->buffer);
                }
                /* account it in gtt */
                rctx->b.gtt += input->buffer_size;
@@ -1257,7 +1257,7 @@ static void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info
                        unsigned out_offset;
                        void *ptr;
 
-                       u_upload_alloc(rctx->uploader, 0, info.count * 2,
+                       u_upload_alloc(rctx->b.uploader, 0, info.count * 2,
                                       &out_offset, &out_buffer, &ptr);
 
                        util_shorten_ubyte_elts_to_userptr(
@@ -1276,7 +1276,7 @@ static void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info
                 * Note: Instanced rendering in combination with immediate indices hangs. */
                if (ib.user_buffer && (R600_BIG_ENDIAN || info.instance_count > 1 ||
                                       info.count*ib.index_size > 20)) {
-                       u_upload_data(rctx->uploader, 0, info.count * ib.index_size,
+                       u_upload_data(rctx->b.uploader, 0, info.count * ib.index_size,
                                      ib.user_buffer, &ib.offset, &ib.buffer);
                        ib.user_buffer = NULL;
                }
@@ -1452,7 +1452,7 @@ void r600_draw_rectangle(struct blitter_context *blitter,
        /* Upload vertices. The hw rectangle has only 3 vertices,
         * I guess the 4th one is derived from the first 3.
         * The vertex specification should match u_blitter's vertex element state. */
-       u_upload_alloc(rctx->uploader, 0, sizeof(float) * 24, &offset, &buf, (void**)&vb);
+       u_upload_alloc(rctx->b.uploader, 0, sizeof(float) * 24, &offset, &buf, (void**)&vb);
        vb[0] = x1;
        vb[1] = y1;
        vb[2] = depth;
index 82b69d8624410c5f32b60f10af5bcc88abe2ca0d..ac5fbcc0dd01345e9ddbab46983fb462f7ff0846 100644 (file)
@@ -25,6 +25,8 @@
  */
 
 #include "r600_cs.h"
+#include "util/u_memory.h"
+#include "util/u_upload_mgr.h"
 #include <inttypes.h>
 
 boolean r600_rings_is_buffer_referenced(struct r600_common_context *ctx,
@@ -146,3 +148,175 @@ bool r600_init_resource(struct r600_common_screen *rscreen,
        }
        return true;
 }
+
+static void r600_buffer_destroy(struct pipe_screen *screen,
+                               struct pipe_resource *buf)
+{
+       struct r600_resource *rbuffer = r600_resource(buf);
+
+       util_range_destroy(&rbuffer->valid_buffer_range);
+       pb_reference(&rbuffer->buf, NULL);
+       FREE(rbuffer);
+}
+
+static void *r600_buffer_get_transfer(struct pipe_context *ctx,
+                                     struct pipe_resource *resource,
+                                      unsigned level,
+                                      unsigned usage,
+                                      const struct pipe_box *box,
+                                     struct pipe_transfer **ptransfer,
+                                     void *data, struct r600_resource *staging,
+                                     unsigned offset)
+{
+       struct r600_common_context *rctx = (struct r600_common_context*)ctx;
+       struct r600_transfer *transfer = util_slab_alloc(&rctx->pool_transfers);
+
+       transfer->transfer.resource = resource;
+       transfer->transfer.level = level;
+       transfer->transfer.usage = usage;
+       transfer->transfer.box = *box;
+       transfer->transfer.stride = 0;
+       transfer->transfer.layer_stride = 0;
+       transfer->offset = offset;
+       transfer->staging = staging;
+       *ptransfer = &transfer->transfer;
+       return data;
+}
+
+static void *r600_buffer_transfer_map(struct pipe_context *ctx,
+                                      struct pipe_resource *resource,
+                                      unsigned level,
+                                      unsigned usage,
+                                      const struct pipe_box *box,
+                                      struct pipe_transfer **ptransfer)
+{
+       struct r600_common_context *rctx = (struct r600_common_context*)ctx;
+       struct r600_common_screen *rscreen = (struct r600_common_screen*)ctx->screen;
+        struct r600_resource *rbuffer = r600_resource(resource);
+        uint8_t *data;
+
+       assert(box->x + box->width <= resource->width0);
+
+       /* See if the buffer range being mapped has never been initialized,
+        * in which case it can be mapped unsynchronized. */
+       if (!(usage & PIPE_TRANSFER_UNSYNCHRONIZED) &&
+           usage & PIPE_TRANSFER_WRITE &&
+           !util_ranges_intersect(&rbuffer->valid_buffer_range, box->x, box->x + box->width)) {
+               usage |= PIPE_TRANSFER_UNSYNCHRONIZED;
+       }
+
+       if (usage & PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE &&
+           !(usage & PIPE_TRANSFER_UNSYNCHRONIZED)) {
+               assert(usage & PIPE_TRANSFER_WRITE);
+
+               /* Check if mapping this buffer would cause waiting for the GPU. */
+               if (r600_rings_is_buffer_referenced(rctx, rbuffer->cs_buf, RADEON_USAGE_READWRITE) ||
+                   rctx->ws->buffer_is_busy(rbuffer->buf, RADEON_USAGE_READWRITE)) {
+                       rctx->invalidate_buffer(&rctx->b, &rbuffer->b.b);
+               }
+       }
+       else if ((usage & PIPE_TRANSFER_DISCARD_RANGE) &&
+                !(usage & PIPE_TRANSFER_UNSYNCHRONIZED) &&
+                !(rscreen->debug_flags & DBG_NO_DISCARD_RANGE) &&
+                (rscreen->has_cp_dma ||
+                 (rscreen->has_streamout &&
+                  /* The buffer range must be aligned to 4 with streamout. */
+                  box->x % 4 == 0 && box->width % 4 == 0))) {
+               assert(usage & PIPE_TRANSFER_WRITE);
+
+               /* Check if mapping this buffer would cause waiting for the GPU. */
+               if (r600_rings_is_buffer_referenced(rctx, rbuffer->cs_buf, RADEON_USAGE_READWRITE) ||
+                   rctx->ws->buffer_is_busy(rbuffer->buf, RADEON_USAGE_READWRITE)) {
+                       /* Do a wait-free write-only transfer using a temporary buffer. */
+                       unsigned offset;
+                       struct r600_resource *staging = NULL;
+
+                       u_upload_alloc(rctx->uploader, 0, box->width + (box->x % R600_MAP_BUFFER_ALIGNMENT),
+                                      &offset, (struct pipe_resource**)&staging, (void**)&data);
+
+                       if (staging) {
+                               data += box->x % R600_MAP_BUFFER_ALIGNMENT;
+                               return r600_buffer_get_transfer(ctx, resource, level, usage, box,
+                                                               ptransfer, data, staging, offset);
+                       }
+               }
+       }
+
+       data = r600_buffer_map_sync_with_rings(rctx, rbuffer, usage);
+       if (!data) {
+               return NULL;
+       }
+       data += box->x;
+
+       return r600_buffer_get_transfer(ctx, resource, level, usage, box,
+                                       ptransfer, data, NULL, 0);
+}
+
+static void r600_buffer_transfer_unmap(struct pipe_context *ctx,
+                                      struct pipe_transfer *transfer)
+{
+       struct r600_common_context *rctx = (struct r600_common_context*)ctx;
+       struct r600_transfer *rtransfer = (struct r600_transfer*)transfer;
+       struct r600_resource *rbuffer = r600_resource(transfer->resource);
+
+       if (rtransfer->staging) {
+               struct pipe_resource *dst, *src;
+               unsigned soffset, doffset, size;
+               struct pipe_box box;
+
+               dst = transfer->resource;
+               src = &rtransfer->staging->b.b;
+               size = transfer->box.width;
+               doffset = transfer->box.x;
+               soffset = rtransfer->offset + transfer->box.x % R600_MAP_BUFFER_ALIGNMENT;
+
+               u_box_1d(soffset, size, &box);
+
+               /* Copy the staging buffer into the original one. */
+               if (!(size % 4) && !(doffset % 4) && !(soffset % 4) &&
+                   rctx->dma_copy(ctx, dst, 0, doffset, 0, 0, src, 0, &box)) {
+                       /* DONE. */
+               } else {
+                       ctx->resource_copy_region(ctx, dst, 0, doffset, 0, 0, src, 0, &box);
+               }
+               pipe_resource_reference((struct pipe_resource**)&rtransfer->staging, NULL);
+       }
+
+       if (transfer->usage & PIPE_TRANSFER_WRITE) {
+               util_range_add(&rbuffer->valid_buffer_range, transfer->box.x,
+                              transfer->box.x + transfer->box.width);
+       }
+       util_slab_free(&rctx->pool_transfers, transfer);
+}
+
+static const struct u_resource_vtbl r600_buffer_vtbl =
+{
+       NULL,                           /* get_handle */
+       r600_buffer_destroy,            /* resource_destroy */
+       r600_buffer_transfer_map,       /* transfer_map */
+       NULL,                           /* transfer_flush_region */
+       r600_buffer_transfer_unmap,     /* transfer_unmap */
+       NULL                            /* transfer_inline_write */
+};
+
+struct pipe_resource *r600_buffer_create(struct pipe_screen *screen,
+                                        const struct pipe_resource *templ,
+                                        unsigned alignment)
+{
+       struct r600_common_screen *rscreen = (struct r600_common_screen*)screen;
+       struct r600_resource *rbuffer;
+
+       rbuffer = MALLOC_STRUCT(r600_resource);
+
+       rbuffer->b.b = *templ;
+       pipe_reference_init(&rbuffer->b.b.reference, 1);
+       rbuffer->b.b.screen = screen;
+       rbuffer->b.vtbl = &r600_buffer_vtbl;
+       util_range_init(&rbuffer->valid_buffer_range);
+
+       if (!r600_init_resource(rscreen, rbuffer, templ->width0, alignment, TRUE, templ->usage)) {
+               FREE(rbuffer);
+               return NULL;
+       }
+       return &rbuffer->b.b;
+}
index 1ad47e1481b98f64f020978ee0af365337972a04..28921beea821b3b68f99cdfb9d39f3c14aa60cf9 100644 (file)
@@ -28,6 +28,7 @@
 #include "r600_cs.h"
 #include "tgsi/tgsi_parse.h"
 #include "util/u_format_s3tc.h"
+#include "util/u_upload_mgr.h"
 #include <inttypes.h>
 
 static const struct debug_named_value common_debug_options[] = {
@@ -223,6 +224,10 @@ void r600_common_screen_cleanup(struct r600_common_screen *rscreen)
 bool r600_common_context_init(struct r600_common_context *rctx,
                              struct r600_common_screen *rscreen)
 {
+       util_slab_create(&rctx->pool_transfers,
+                        sizeof(struct r600_transfer), 64,
+                        UTIL_SLAB_SINGLETHREADED);
+
        rctx->ws = rscreen->ws;
        rctx->family = rscreen->family;
        rctx->chip_class = rscreen->chip_class;
@@ -234,11 +239,23 @@ bool r600_common_context_init(struct r600_common_context *rctx,
        if (!rctx->allocator_so_filled_size)
                return false;
 
+       rctx->uploader = u_upload_create(&rctx->b, 1024 * 1024, 256,
+                                       PIPE_BIND_INDEX_BUFFER |
+                                       PIPE_BIND_CONSTANT_BUFFER);
+       if (!rctx->uploader)
+               return false;
+
        return true;
 }
 
 void r600_common_context_cleanup(struct r600_common_context *rctx)
 {
+       if (rctx->uploader) {
+               u_upload_destroy(rctx->uploader);
+       }
+
+       util_slab_destroy(&rctx->pool_transfers);
+
        if (rctx->allocator_so_filled_size) {
                u_suballocator_destroy(rctx->allocator_so_filled_size);
        }
index 172dd937bbd81db8f9af20fe4ea77f8f0d36f8ee..08144823d6e409caeb18d8432abd71f105075471 100644 (file)
@@ -35,6 +35,7 @@
 #include "../../winsys/radeon/drm/radeon_winsys.h"
 
 #include "util/u_range.h"
+#include "util/u_slab.h"
 #include "util/u_suballoc.h"
 #include "util/u_transfer.h"
 
@@ -77,6 +78,8 @@
 #define DBG_NO_DISCARD_RANGE   (1 << 14)
 /* The maximum allowed bit is 15. */
 
+#define R600_MAP_BUFFER_ALIGNMENT 64
+
 struct r600_common_context;
 
 struct r600_resource {
@@ -225,7 +228,9 @@ struct r600_common_context {
        enum chip_class                 chip_class;
        struct r600_rings               rings;
 
+       struct u_upload_mgr             *uploader;
        struct u_suballocator           *allocator_so_filled_size;
+       struct util_slab_mempool        pool_transfers;
 
        /* Current unaccounted memory usage. */
        uint64_t                        vram;
@@ -273,6 +278,9 @@ bool r600_init_resource(struct r600_common_screen *rscreen,
                        struct r600_resource *res,
                        unsigned size, unsigned alignment,
                        bool use_reusable_pool, unsigned usage);
+struct pipe_resource *r600_buffer_create(struct pipe_screen *screen,
+                                        const struct pipe_resource *templ,
+                                        unsigned alignment);
 
 /* r600_common_pipe.c */
 bool r600_common_screen_init(struct r600_common_screen *rscreen,
index c952fe0084bb2749ce3d1e931b92264327322c13..e64683d382ee5d33af05ae53f21503f60c9571ec 100644 (file)
 #include "r600.h"
 #include "radeonsi_pipe.h"
 
-static void r600_buffer_destroy(struct pipe_screen *screen,
-                               struct pipe_resource *buf)
-{
-       struct r600_resource *rbuffer = r600_resource(buf);
-
-       pb_reference(&rbuffer->buf, NULL);
-       FREE(rbuffer);
-}
-
-static void *r600_buffer_transfer_map(struct pipe_context *ctx,
-                                      struct pipe_resource *resource,
-                                      unsigned level,
-                                      unsigned usage,
-                                      const struct pipe_box *box,
-                                      struct pipe_transfer **ptransfer)
-{
-       struct r600_context *rctx = (struct r600_context*)ctx;
-       struct pipe_transfer *transfer;
-        struct r600_resource *rbuffer = r600_resource(resource);
-        uint8_t *data;
-
-       if (usage & PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE &&
-           !(usage & PIPE_TRANSFER_UNSYNCHRONIZED)) {
-               assert(usage & PIPE_TRANSFER_WRITE);
-
-               /* Check if mapping this buffer would cause waiting for the GPU. */
-               if (r600_rings_is_buffer_referenced(&rctx->b, rbuffer->cs_buf, RADEON_USAGE_READWRITE) ||
-                   rctx->b.ws->buffer_is_busy(rbuffer->buf, RADEON_USAGE_READWRITE)) {
-                       rctx->b.invalidate_buffer(&rctx->b.b, &rbuffer->b.b);
-               }
-       }
-
-       data = rctx->b.ws->buffer_map(rbuffer->cs_buf, rctx->b.rings.gfx.cs, usage);
-        if (!data) {
-               return NULL;
-        }
-
-       transfer = util_slab_alloc(&rctx->pool_transfers);
-       transfer->resource = resource;
-       transfer->level = level;
-       transfer->usage = usage;
-       transfer->box = *box;
-       transfer->stride = 0;
-       transfer->layer_stride = 0;
-        *ptransfer = transfer;
-
-       return (uint8_t*)data + transfer->box.x;
-}
-
-static void r600_buffer_transfer_unmap(struct pipe_context *ctx,
-                                       struct pipe_transfer *transfer)
-{
-       struct r600_context *rctx = (struct r600_context*)ctx;
-       util_slab_free(&rctx->pool_transfers, transfer);
-}
-
-static void r600_buffer_transfer_flush_region(struct pipe_context *pipe,
-                                               struct pipe_transfer *transfer,
-                                               const struct pipe_box *box)
-{
-}
-
-static const struct u_resource_vtbl r600_buffer_vtbl =
-{
-       u_default_resource_get_handle,          /* get_handle */
-       r600_buffer_destroy,                    /* resource_destroy */
-       r600_buffer_transfer_map,               /* transfer_map */
-       r600_buffer_transfer_flush_region,      /* transfer_flush_region */
-       r600_buffer_transfer_unmap,             /* transfer_unmap */
-       NULL    /* transfer_inline_write */
-};
-
-struct pipe_resource *si_buffer_create(struct pipe_screen *screen,
-                                      const struct pipe_resource *templ)
-{
-       struct r600_screen *rscreen = (struct r600_screen*)screen;
-       struct r600_resource *rbuffer;
-       /* XXX We probably want a different alignment for buffers and textures. */
-       unsigned alignment = 4096;
-
-       rbuffer = MALLOC_STRUCT(r600_resource);
-
-       rbuffer->b.b = *templ;
-       pipe_reference_init(&rbuffer->b.b.reference, 1);
-       rbuffer->b.b.screen = screen;
-       rbuffer->b.vtbl = &r600_buffer_vtbl;
-       util_range_init(&rbuffer->valid_buffer_range);
-
-       if (!r600_init_resource(&rscreen->b, rbuffer, templ->width0, alignment, TRUE, templ->usage)) {
-               FREE(rbuffer);
-               return NULL;
-       }
-       return &rbuffer->b.b;
-}
-
 void r600_upload_index_buffer(struct r600_context *rctx,
                              struct pipe_index_buffer *ib, unsigned count)
 {
-       u_upload_data(rctx->uploader, 0, count * ib->index_size,
+       u_upload_data(rctx->b.uploader, 0, count * ib->index_size,
                      ib->user_buffer, &ib->offset, &ib->buffer);
 }
 
@@ -154,12 +59,12 @@ void r600_upload_const_buffer(struct r600_context *rctx, struct r600_resource **
                        tmpPtr[i] = util_bswap32(((uint32_t *)ptr)[i]);
                }
 
-               u_upload_data(rctx->uploader, 0, size, tmpPtr, const_offset,
+               u_upload_data(rctx->b.uploader, 0, size, tmpPtr, const_offset,
                                (struct pipe_resource**)rbuffer);
 
                free(tmpPtr);
        } else {
-               u_upload_data(rctx->uploader, 0, size, ptr, const_offset,
+               u_upload_data(rctx->b.uploader, 0, size, ptr, const_offset,
                                        (struct pipe_resource**)rbuffer);
        }
 }
index 745d3ba88c9c163fdf265b3ac680873fae90c2a0..9a0fde430ff949ec2958f509da8ca430e89910df 100644 (file)
@@ -27,7 +27,7 @@ static struct pipe_resource *r600_resource_create(struct pipe_screen *screen,
                                                const struct pipe_resource *templ)
 {
        if (templ->target == PIPE_BUFFER) {
-               return si_buffer_create(screen, templ);
+               return r600_buffer_create(screen, templ, 4096);
        } else {
                return r600_texture_create(screen, templ);
        }
@@ -55,7 +55,7 @@ void r600_init_screen_resource_functions(struct pipe_screen *screen)
 void r600_init_context_resource_functions(struct r600_context *r600)
 {
        r600->b.b.transfer_map = u_transfer_map_vtbl;
-       r600->b.b.transfer_flush_region = u_transfer_flush_region_vtbl;
+       r600->b.b.transfer_flush_region = u_default_transfer_flush_region;
        r600->b.b.transfer_unmap = u_transfer_unmap_vtbl;
        r600->b.b.transfer_inline_write = u_default_transfer_inline_write;
 }
index ccb72d5fca154740dc9b793f34dc9a3523d31098..177a9dd708473d952beaeb23793223818fc059aa 100644 (file)
@@ -38,7 +38,7 @@ void r600_translate_index_buffer(struct r600_context *r600,
 
        switch (ib->index_size) {
        case 1:
-               u_upload_alloc(r600->uploader, 0, count * 2,
+               u_upload_alloc(r600->b.uploader, 0, count * 2,
                               &out_offset, &out_buffer, &ptr);
 
                util_shorten_ubyte_elts_to_userptr(
index 866cc1af8d84ac83821008ac7b49d8ce7f055b0b..0fec6d56978cdb6ff0081c4461a68bdb665c7fd1 100644 (file)
@@ -119,11 +119,6 @@ static void r600_destroy_context(struct pipe_context *context)
 
        util_blitter_destroy(rctx->blitter);
 
-       if (rctx->uploader) {
-               u_upload_destroy(rctx->uploader);
-       }
-       util_slab_destroy(&rctx->pool_transfers);
-
        r600_common_context_cleanup(&rctx->b);
        FREE(rctx);
 }
@@ -187,16 +182,6 @@ static struct pipe_context *r600_create_context(struct pipe_screen *screen, void
 
        rctx->b.ws->cs_set_flush_callback(rctx->b.rings.gfx.cs, r600_flush_from_winsys, rctx);
 
-       util_slab_create(&rctx->pool_transfers,
-                        sizeof(struct pipe_transfer), 64,
-                        UTIL_SLAB_SINGLETHREADED);
-
-        rctx->uploader = u_upload_create(&rctx->b.b, 1024 * 1024, 256,
-                                         PIPE_BIND_INDEX_BUFFER |
-                                         PIPE_BIND_CONSTANT_BUFFER);
-        if (!rctx->uploader)
-               goto fail;
-
        rctx->blitter = util_blitter_create(&rctx->b.b);
        if (rctx->blitter == NULL)
                goto fail;
index de613e0ed34360e04af84d9c123f65405519ea60..e84088f11dbedcb27fece1b56f659d2a11618078 100644 (file)
@@ -142,9 +142,6 @@ struct r600_context {
        struct r600_resource            *border_color_table;
        unsigned                        border_color_offset;
 
-       struct u_upload_mgr             *uploader;
-       struct util_slab_mempool        pool_transfers;
-
        unsigned default_ps_gprs, default_vs_gprs;
 
        /* Below are variables from the old r600_context.
@@ -186,8 +183,6 @@ void r600_decompress_color_textures(struct r600_context *rctx,
                                    struct r600_textures_info *textures);
 
 /* r600_buffer.c */
-struct pipe_resource *si_buffer_create(struct pipe_screen *screen,
-                                      const struct pipe_resource *templ);
 void r600_upload_index_buffer(struct r600_context *rctx,
                              struct pipe_index_buffer *ib, unsigned count);