radeonsi: implement buffer_subdata without indirect calls
authorMarek Olšák <marek.olsak@amd.com>
Sat, 16 Jul 2016 19:52:20 +0000 (21:52 +0200)
committerMarek Olšák <marek.olsak@amd.com>
Sat, 23 Jul 2016 11:33:42 +0000 (13:33 +0200)
There is less noise in CPU profile data now.

Reviewed-by: Nicolai Hähnle <nicolai.haehnle@amd.com>
src/gallium/drivers/r600/r600_pipe.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/si_pipe.c

index a3b6189309e97c258690ffc30b105f728904e4bd..39a310abebb660cc827a2552d0048bfae284312e 100644 (file)
@@ -129,7 +129,7 @@ static struct pipe_context *r600_create_context(struct pipe_screen *screen,
        rctx->b.b.destroy = r600_destroy_context;
        rctx->b.set_atom_dirty = (void *)r600_set_atom_dirty;
 
-       if (!r600_common_context_init(&rctx->b, &rscreen->b))
+       if (!r600_common_context_init(&rctx->b, &rscreen->b, flags))
                goto fail;
 
        rctx->screen = rscreen;
index b5c8697ac5290aaeea8452703a2bfc2386818773..9c7eac57970e7383be303279606fce11795e9b08 100644 (file)
@@ -449,6 +449,28 @@ static void r600_buffer_transfer_unmap(struct pipe_context *ctx,
        util_slab_free(&rctx->pool_transfers, transfer);
 }
 
+void r600_buffer_subdata(struct pipe_context *ctx,
+                        struct pipe_resource *buffer,
+                        unsigned usage, unsigned offset,
+                        unsigned size, const void *data)
+{
+       struct pipe_transfer *transfer = NULL;
+       struct pipe_box box;
+       uint8_t *map = NULL;
+
+       u_box_1d(offset, size, &box);
+       map = r600_buffer_transfer_map(ctx, buffer, 0,
+                                      PIPE_TRANSFER_WRITE |
+                                      PIPE_TRANSFER_DISCARD_RANGE |
+                                      usage,
+                                      &box, &transfer);
+       if (!map)
+               return;
+
+       memcpy(map, data, size);
+       r600_buffer_transfer_unmap(ctx, transfer);
+}
+
 static const struct u_resource_vtbl r600_buffer_vtbl =
 {
        NULL,                           /* get_handle */
index 4ef58cae282061106fa292b429b597bbdf0e7f24..caf2552bcda447a5ffd8010ed6cd2f2dfb4a8f8d 100644 (file)
@@ -400,7 +400,8 @@ static void r600_set_debug_callback(struct pipe_context *ctx,
 }
 
 bool r600_common_context_init(struct r600_common_context *rctx,
-                             struct r600_common_screen *rscreen)
+                             struct r600_common_screen *rscreen,
+                             unsigned context_flags)
 {
        util_slab_create(&rctx->pool_transfers,
                         sizeof(struct r600_transfer), 64,
@@ -422,12 +423,20 @@ bool r600_common_context_init(struct r600_common_context *rctx,
        rctx->b.transfer_map = u_transfer_map_vtbl;
        rctx->b.transfer_flush_region = u_transfer_flush_region_vtbl;
        rctx->b.transfer_unmap = u_transfer_unmap_vtbl;
-       rctx->b.buffer_subdata = u_default_buffer_subdata;
        rctx->b.texture_subdata = u_default_texture_subdata;
        rctx->b.memory_barrier = r600_memory_barrier;
        rctx->b.flush = r600_flush_from_st;
        rctx->b.set_debug_callback = r600_set_debug_callback;
 
+       /* evergreen_compute.c has a special codepath for global buffers.
+        * Everything else can use the direct path.
+        */
+       if ((rscreen->chip_class == EVERGREEN || rscreen->chip_class == CAYMAN) &&
+           (context_flags & PIPE_CONTEXT_COMPUTE_ONLY))
+               rctx->b.buffer_subdata = u_default_buffer_subdata;
+       else
+               rctx->b.buffer_subdata = r600_buffer_subdata;
+
        if (rscreen->info.drm_major == 2 && rscreen->info.drm_minor >= 43) {
                rctx->b.get_device_reset_status = r600_get_reset_status;
                rctx->gpu_reset_counter =
index d8736c610962c10a837bd88594bf04d7864e58a1..7851a8624f9cd8237dc53f3cbce334cfb7729c0b 100644 (file)
@@ -644,6 +644,10 @@ bool r600_rings_is_buffer_referenced(struct r600_common_context *ctx,
 void *r600_buffer_map_sync_with_rings(struct r600_common_context *ctx,
                                       struct r600_resource *resource,
                                       unsigned usage);
+void r600_buffer_subdata(struct pipe_context *ctx,
+                        struct pipe_resource *buffer,
+                        unsigned usage, unsigned offset,
+                        unsigned size, const void *data);
 bool r600_init_resource(struct r600_common_screen *rscreen,
                        struct r600_resource *res,
                        uint64_t size, unsigned alignment);
@@ -674,7 +678,8 @@ void r600_destroy_common_screen(struct r600_common_screen *rscreen);
 void r600_preflush_suspend_features(struct r600_common_context *ctx);
 void r600_postflush_resume_features(struct r600_common_context *ctx);
 bool r600_common_context_init(struct r600_common_context *rctx,
-                             struct r600_common_screen *rscreen);
+                             struct r600_common_screen *rscreen,
+                             unsigned context_flags);
 void r600_common_context_cleanup(struct r600_common_context *rctx);
 void r600_context_add_resource_size(struct pipe_context *ctx, struct pipe_resource *r);
 bool r600_can_dump_shader(struct r600_common_screen *rscreen,
index 6a496c2301584255ce1612d4371a45ef2e4cc85d..9304e5c594399155272419c051124d627485ea4c 100644 (file)
@@ -165,7 +165,7 @@ static struct pipe_context *si_create_context(struct pipe_screen *screen,
        sctx->screen = sscreen; /* Easy accessing of screen/winsys. */
        sctx->is_debug = (flags & PIPE_CONTEXT_DEBUG) != 0;
 
-       if (!r600_common_context_init(&sctx->b, &sscreen->b))
+       if (!r600_common_context_init(&sctx->b, &sscreen->b, flags))
                goto fail;
 
        if (sscreen->b.info.drm_major == 3)