[Mesa-dev] [PATCH 5/6] i965: Expose AMD_pinned_memory
Chris Wilson
chris at chris-wilson.co.uk
Fri Oct 13 09:34:55 UTC 2017
All GEN GPU can bind to any piece of memory (thanks UMA), and so through
a special ioctl we can map a chunk of page-aligned client memory into
the GPU address space. However, not all GEN are equal. Some have
cache-coherency between the CPU and the GPU, whilst the others are
incoherent and rely on snooping on explicit flushes to push/pull dirty
data. Whereas we can use client buffers as a general replacement for kernel
allocated buffers with LLC (cache coherency), using snooped buffers
behaves differently and so must be used with care.
AMD_pinned_memory supposes that the client memory buffer is suitable
for any general usage (e.g. vertex data, texture data) and so only on
LLC can we offer that extension.
---
src/mesa/drivers/dri/i965/intel_buffer_objects.c | 55 ++++++++++++++++--------
src/mesa/drivers/dri/i965/intel_extensions.c | 11 +++++
2 files changed, 49 insertions(+), 17 deletions(-)
diff --git a/src/mesa/drivers/dri/i965/intel_buffer_objects.c b/src/mesa/drivers/dri/i965/intel_buffer_objects.c
index 49e68bd739..425c5e1372 100644
--- a/src/mesa/drivers/dri/i965/intel_buffer_objects.c
+++ b/src/mesa/drivers/dri/i965/intel_buffer_objects.c
@@ -72,6 +72,23 @@ mark_buffer_invalid(struct intel_buffer_object *intel_obj)
intel_obj->valid_data_end = 0;
}
+/** Allocates a new brw_bo to store the data for the buffer object. */
+static void
+mark_new_state(struct brw_context *brw,
+ struct intel_buffer_object *intel_obj)
+{
+ /* the buffer might be bound as a uniform buffer, need to update it
+ */
+ if (intel_obj->Base.UsageHistory & USAGE_UNIFORM_BUFFER)
+ brw->ctx.NewDriverState |= BRW_NEW_UNIFORM_BUFFER;
+ if (intel_obj->Base.UsageHistory & USAGE_SHADER_STORAGE_BUFFER)
+ brw->ctx.NewDriverState |= BRW_NEW_UNIFORM_BUFFER;
+ if (intel_obj->Base.UsageHistory & USAGE_TEXTURE_BUFFER)
+ brw->ctx.NewDriverState |= BRW_NEW_TEXTURE_BUFFER;
+ if (intel_obj->Base.UsageHistory & USAGE_ATOMIC_COUNTER_BUFFER)
+ brw->ctx.NewDriverState |= BRW_NEW_ATOMIC_BUFFER;
+}
+
/** Allocates a new brw_bo to store the data for the buffer object. */
static void
alloc_buffer_object(struct brw_context *brw,
@@ -98,17 +115,7 @@ alloc_buffer_object(struct brw_context *brw,
}
intel_obj->buffer = brw_bo_alloc(brw->bufmgr, "bufferobj", size, 64);
- /* the buffer might be bound as a uniform buffer, need to update it
- */
- if (intel_obj->Base.UsageHistory & USAGE_UNIFORM_BUFFER)
- brw->ctx.NewDriverState |= BRW_NEW_UNIFORM_BUFFER;
- if (intel_obj->Base.UsageHistory & USAGE_SHADER_STORAGE_BUFFER)
- brw->ctx.NewDriverState |= BRW_NEW_UNIFORM_BUFFER;
- if (intel_obj->Base.UsageHistory & USAGE_TEXTURE_BUFFER)
- brw->ctx.NewDriverState |= BRW_NEW_TEXTURE_BUFFER;
- if (intel_obj->Base.UsageHistory & USAGE_ATOMIC_COUNTER_BUFFER)
- brw->ctx.NewDriverState |= BRW_NEW_ATOMIC_BUFFER;
-
+ mark_new_state(brw, intel_obj);
mark_buffer_inactive(intel_obj);
mark_buffer_invalid(intel_obj);
}
@@ -206,13 +213,27 @@ brw_buffer_data(struct gl_context *ctx,
release_buffer(intel_obj);
if (size != 0) {
- alloc_buffer_object(brw, intel_obj);
- if (!intel_obj->buffer)
- return false;
-
- if (data != NULL) {
- brw_bo_subdata(intel_obj->buffer, 0, size, data);
+ if (target == GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD) {
+ intel_obj->buffer =
+ brw_bo_alloc_userptr(brw->bufmgr, "bufferobj(userptr)",
+ (void *)data, size, 0);
+ if (!intel_obj->buffer)
+ return false;
+
+ mark_new_state(brw, intel_obj);
+ mark_buffer_inactive(intel_obj);
mark_buffer_valid_data(intel_obj, 0, size);
+ } else {
+ alloc_buffer_object(brw, intel_obj);
+ if (!intel_obj->buffer)
+ return false;
+
+ if (data != NULL) {
+ brw_bo_subdata(intel_obj->buffer, 0, size, data);
+ mark_new_state(brw, intel_obj);
+ mark_buffer_inactive(intel_obj);
+ mark_buffer_valid_data(intel_obj, 0, size);
+ }
}
}
diff --git a/src/mesa/drivers/dri/i965/intel_extensions.c b/src/mesa/drivers/dri/i965/intel_extensions.c
index 519d0a56cb..844a2290f4 100644
--- a/src/mesa/drivers/dri/i965/intel_extensions.c
+++ b/src/mesa/drivers/dri/i965/intel_extensions.c
@@ -196,6 +196,17 @@ intelInitExtensions(struct gl_context *ctx)
ctx->Extensions.ARB_timer_query = brw->screen->hw_has_timestamp;
+ /* AMD_pinned_memory assumes the flexibility of using client memory
+ * for any buffer (incl. vertex buffers) which rules out the prospect
+ * of using snooped buffers, as using snooped buffers without
+ * cogniscience is likely to be detrimental to performance and require
+ * extensive checking in the driver for correctness, e.g. to prevent
+ * illegal snoop <-> snoop transfers.
+ */
+ ctx->Extensions.AMD_pinned_memory =
+ brw->screen->kernel_features & KERNEL_ALLOWS_USERPTR &&
+ brw->screen->devinfo.has_llc;
+
/* Only enable this in core profile because other parts of Mesa behave
* slightly differently when the extension is enabled.
*/
--
2.15.0.rc0
More information about the mesa-dev
mailing list