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 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev