From 700de07771a1b6ce2a63b063fcc196c5b26cffe3 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Sat, 16 Jul 2016 21:52:20 +0200 Subject: [PATCH] radeonsi: implement buffer_subdata without indirect calls MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit There is less noise in CPU profile data now. Reviewed-by: Nicolai Hähnle --- src/gallium/drivers/r600/r600_pipe.c | 2 +- .../drivers/radeon/r600_buffer_common.c | 22 +++++++++++++++++++ src/gallium/drivers/radeon/r600_pipe_common.c | 13 +++++++++-- src/gallium/drivers/radeon/r600_pipe_common.h | 7 +++++- src/gallium/drivers/radeonsi/si_pipe.c | 2 +- 5 files changed, 41 insertions(+), 5 deletions(-) diff --git a/src/gallium/drivers/r600/r600_pipe.c b/src/gallium/drivers/r600/r600_pipe.c index a3b6189309e..39a310abebb 100644 --- a/src/gallium/drivers/r600/r600_pipe.c +++ b/src/gallium/drivers/r600/r600_pipe.c @@ -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; diff --git a/src/gallium/drivers/radeon/r600_buffer_common.c b/src/gallium/drivers/radeon/r600_buffer_common.c index b5c8697ac52..9c7eac57970 100644 --- a/src/gallium/drivers/radeon/r600_buffer_common.c +++ b/src/gallium/drivers/radeon/r600_buffer_common.c @@ -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 */ diff --git a/src/gallium/drivers/radeon/r600_pipe_common.c b/src/gallium/drivers/radeon/r600_pipe_common.c index 4ef58cae282..caf2552bcda 100644 --- a/src/gallium/drivers/radeon/r600_pipe_common.c +++ b/src/gallium/drivers/radeon/r600_pipe_common.c @@ -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 = diff --git a/src/gallium/drivers/radeon/r600_pipe_common.h b/src/gallium/drivers/radeon/r600_pipe_common.h index d8736c61096..7851a8624f9 100644 --- a/src/gallium/drivers/radeon/r600_pipe_common.h +++ b/src/gallium/drivers/radeon/r600_pipe_common.h @@ -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, diff --git a/src/gallium/drivers/radeonsi/si_pipe.c b/src/gallium/drivers/radeonsi/si_pipe.c index 6a496c23015..9304e5c5943 100644 --- a/src/gallium/drivers/radeonsi/si_pipe.c +++ b/src/gallium/drivers/radeonsi/si_pipe.c @@ -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) -- 2.30.2