summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNicolai Hähnle <[email protected]>2016-01-12 09:29:18 -0500
committerNicolai Hähnle <[email protected]>2016-01-14 09:41:24 -0500
commite976860638c6fb9f69b9cf3a82acaba55c08e274 (patch)
treef8a11602169358e460a607781b7c843606fbe7a8
parent321140d563730b210e6390c5b73c09fdcf9649af (diff)
gallium/radeon: do not reallocate user memory buffers
The whole point of AMD_pinned_memory is that applications don't have to map buffers via OpenGL - but they're still allowed to, so make sure we don't break the link between buffer object and user memory unless explicitly instructed to. Reviewed-by: Marek Olšák <[email protected]>
-rw-r--r--src/gallium/drivers/radeon/r600_buffer_common.c31
-rw-r--r--src/gallium/drivers/radeon/radeon_winsys.h8
-rw-r--r--src/gallium/winsys/amdgpu/drm/amdgpu_bo.c6
-rw-r--r--src/gallium/winsys/radeon/drm/radeon_drm_bo.c6
4 files changed, 43 insertions, 8 deletions
diff --git a/src/gallium/drivers/radeon/r600_buffer_common.c b/src/gallium/drivers/radeon/r600_buffer_common.c
index 09755e04b58..6592c5bdeca 100644
--- a/src/gallium/drivers/radeon/r600_buffer_common.c
+++ b/src/gallium/drivers/radeon/r600_buffer_common.c
@@ -209,11 +209,15 @@ static void r600_buffer_destroy(struct pipe_screen *screen,
FREE(rbuffer);
}
-void r600_invalidate_resource(struct pipe_context *ctx,
- struct pipe_resource *resource)
+static bool
+r600_do_invalidate_resource(struct r600_common_context *rctx,
+ struct r600_resource *rbuffer)
{
- struct r600_common_context *rctx = (struct r600_common_context*)ctx;
- struct r600_resource *rbuffer = r600_resource(resource);
+ /* In AMD_pinned_memory, the user pointer association only gets
+ * broken when the buffer is explicitly re-allocated.
+ */
+ if (rctx->ws->buffer_is_user_ptr(rbuffer->buf))
+ return false;
/* Check if mapping this buffer would cause waiting for the GPU. */
if (r600_rings_is_buffer_referenced(rctx, rbuffer->buf, RADEON_USAGE_READWRITE) ||
@@ -222,6 +226,17 @@ void r600_invalidate_resource(struct pipe_context *ctx,
} else {
util_range_set_empty(&rbuffer->valid_buffer_range);
}
+
+ return true;
+}
+
+void r600_invalidate_resource(struct pipe_context *ctx,
+ struct pipe_resource *resource)
+{
+ struct r600_common_context *rctx = (struct r600_common_context*)ctx;
+ struct r600_resource *rbuffer = r600_resource(resource);
+
+ (void)r600_do_invalidate_resource(rctx, rbuffer);
}
static void *r600_buffer_get_transfer(struct pipe_context *ctx,
@@ -291,10 +306,10 @@ static void *r600_buffer_transfer_map(struct pipe_context *ctx,
!(usage & PIPE_TRANSFER_UNSYNCHRONIZED)) {
assert(usage & PIPE_TRANSFER_WRITE);
- r600_invalidate_resource(ctx, resource);
-
- /* At this point, the buffer is always idle. */
- usage |= PIPE_TRANSFER_UNSYNCHRONIZED;
+ if (r600_do_invalidate_resource(rctx, rbuffer)) {
+ /* At this point, the buffer is always idle. */
+ usage |= PIPE_TRANSFER_UNSYNCHRONIZED;
+ }
}
else if ((usage & PIPE_TRANSFER_DISCARD_RANGE) &&
!(usage & PIPE_TRANSFER_UNSYNCHRONIZED) &&
diff --git a/src/gallium/drivers/radeon/radeon_winsys.h b/src/gallium/drivers/radeon/radeon_winsys.h
index 4af6a1877bf..ad304747eab 100644
--- a/src/gallium/drivers/radeon/radeon_winsys.h
+++ b/src/gallium/drivers/radeon/radeon_winsys.h
@@ -530,6 +530,14 @@ struct radeon_winsys {
void *pointer, unsigned size);
/**
+ * Whether the buffer was created from a user pointer.
+ *
+ * \param buf A winsys buffer object
+ * \return whether \p buf was created via buffer_from_ptr
+ */
+ bool (*buffer_is_user_ptr)(struct pb_buffer *buf);
+
+ /**
* Get a winsys handle from a winsys buffer. The internal structure
* of the handle is platform-specific and only a winsys should access it.
*
diff --git a/src/gallium/winsys/amdgpu/drm/amdgpu_bo.c b/src/gallium/winsys/amdgpu/drm/amdgpu_bo.c
index a8447731dc9..82c803b564d 100644
--- a/src/gallium/winsys/amdgpu/drm/amdgpu_bo.c
+++ b/src/gallium/winsys/amdgpu/drm/amdgpu_bo.c
@@ -686,6 +686,11 @@ error:
return NULL;
}
+static bool amdgpu_bo_is_user_ptr(struct pb_buffer *buf)
+{
+ return ((struct amdgpu_winsys_bo*)buf)->user_ptr != NULL;
+}
+
static uint64_t amdgpu_bo_get_va(struct pb_buffer *buf)
{
return ((struct amdgpu_winsys_bo*)buf)->va;
@@ -701,6 +706,7 @@ void amdgpu_bo_init_functions(struct amdgpu_winsys *ws)
ws->base.buffer_create = amdgpu_bo_create;
ws->base.buffer_from_handle = amdgpu_bo_from_handle;
ws->base.buffer_from_ptr = amdgpu_bo_from_ptr;
+ ws->base.buffer_is_user_ptr = amdgpu_bo_is_user_ptr;
ws->base.buffer_get_handle = amdgpu_bo_get_handle;
ws->base.buffer_get_virtual_address = amdgpu_bo_get_va;
ws->base.buffer_get_initial_domain = amdgpu_bo_get_initial_domain;
diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_bo.c b/src/gallium/winsys/radeon/drm/radeon_drm_bo.c
index e35d2804390..3ec6a065c7d 100644
--- a/src/gallium/winsys/radeon/drm/radeon_drm_bo.c
+++ b/src/gallium/winsys/radeon/drm/radeon_drm_bo.c
@@ -1052,6 +1052,11 @@ static boolean radeon_winsys_bo_get_handle(struct pb_buffer *buffer,
return TRUE;
}
+static bool radeon_winsys_bo_is_user_ptr(struct pb_buffer *buf)
+{
+ return ((struct radeon_bo*)buf)->user_ptr != NULL;
+}
+
static uint64_t radeon_winsys_bo_va(struct pb_buffer *buf)
{
return ((struct radeon_bo*)buf)->va;
@@ -1067,6 +1072,7 @@ void radeon_drm_bo_init_functions(struct radeon_drm_winsys *ws)
ws->base.buffer_create = radeon_winsys_bo_create;
ws->base.buffer_from_handle = radeon_winsys_bo_from_handle;
ws->base.buffer_from_ptr = radeon_winsys_bo_from_ptr;
+ ws->base.buffer_is_user_ptr = radeon_winsys_bo_is_user_ptr;
ws->base.buffer_get_handle = radeon_winsys_bo_get_handle;
ws->base.buffer_get_virtual_address = radeon_winsys_bo_va;
ws->base.buffer_get_initial_domain = radeon_bo_get_initial_domain;