summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gallium/drivers/r600/r600_pipe.c2
-rw-r--r--src/gallium/drivers/radeon/r600_buffer_common.c22
-rw-r--r--src/gallium/drivers/radeon/r600_pipe_common.c13
-rw-r--r--src/gallium/drivers/radeon/r600_pipe_common.h7
-rw-r--r--src/gallium/drivers/radeonsi/si_pipe.c2
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)