summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarek Olšák <marek.olsak@amd.com>2015-02-10 01:39:41 +0100
committerMarek Olšák <marek.olsak@amd.com>2015-02-17 17:31:48 +0100
commit11ebb03c26a7af4e975f5611303f6caf98f8a315 (patch)
tree43cea246789fbc9237b7e8a2c3ea5deada4cb21e
parent4fa61b1a23ab0128d3791541403ee020fbef3d4c (diff)
mesa: implement GL_AMD_pinned_memory
It's not possible to query the current buffer binding, because the extension doesn't define GL_..._BUFFER__BINDING_AMD. Drivers should check the target parameter of Drivers.BufferData. If it's equal to GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD, the memory should be pinned. That's all there is to it. A piglit test is on the piglit mailing list. Reviewed-by: Ian Romanick <ian.d.romanick@intel.com> Reviewed-by: Christian König <christian.koenig@amd.com>
-rw-r--r--src/mapi/glapi/gen/gl_API.xml4
-rw-r--r--src/mesa/main/bufferobj.c33
-rw-r--r--src/mesa/main/extensions.c1
-rw-r--r--src/mesa/main/mtypes.h7
4 files changed, 43 insertions, 2 deletions
diff --git a/src/mapi/glapi/gen/gl_API.xml b/src/mapi/glapi/gen/gl_API.xml
index 17bf62a10fa..cc8aaf34e8a 100644
--- a/src/mapi/glapi/gen/gl_API.xml
+++ b/src/mapi/glapi/gen/gl_API.xml
@@ -12856,6 +12856,10 @@
<enum name="SKIP_DECODE_EXT" value="0x8A4A"/>
</category>
+<category name="GL_AMD_pinned_memory" number="411">
+ <enum name="EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD" value="0x9160"/>
+</category>
+
<xi:include href="INTEL_performance_query.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
<category name="GL_EXT_polygon_offset_clamp" number="460">
diff --git a/src/mesa/main/bufferobj.c b/src/mesa/main/bufferobj.c
index 0c23b429e5b..b372c68f21c 100644
--- a/src/mesa/main/bufferobj.c
+++ b/src/mesa/main/bufferobj.c
@@ -117,6 +117,11 @@ get_buffer_target(struct gl_context *ctx, GLenum target)
return &ctx->AtomicBuffer;
}
break;
+ case GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD:
+ if (ctx->Extensions.AMD_pinned_memory) {
+ return &ctx->ExternalVirtualMemoryBuffer;
+ }
+ break;
default:
return NULL;
}
@@ -1242,6 +1247,10 @@ _mesa_DeleteBuffers(GLsizei n, const GLuint *ids)
_mesa_BindBuffer( GL_TEXTURE_BUFFER, 0 );
}
+ if (ctx->ExternalVirtualMemoryBuffer == bufObj) {
+ _mesa_BindBuffer(GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD, 0);
+ }
+
/* The ID is immediately freed for re-use */
_mesa_HashRemove(ctx->Shared->BufferObjects, ids[i]);
/* Make sure we do not run into the classic ABA problem on bind.
@@ -1381,7 +1390,16 @@ _mesa_BufferStorage(GLenum target, GLsizeiptr size, const GLvoid *data,
ASSERT(ctx->Driver.BufferData);
if (!ctx->Driver.BufferData(ctx, target, size, data, GL_DYNAMIC_DRAW,
flags, bufObj)) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBufferStorage()");
+ if (target == GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD) {
+ /* Even though the interaction between AMD_pinned_memory and
+ * glBufferStorage is not described in the spec, Graham Sellers
+ * said that it should behave the same as glBufferData.
+ */
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glBufferStorage()");
+ }
+ else {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBufferStorage()");
+ }
}
}
@@ -1465,7 +1483,18 @@ _mesa_BufferData(GLenum target, GLsizeiptrARB size,
GL_MAP_WRITE_BIT |
GL_DYNAMIC_STORAGE_BIT,
bufObj)) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBufferDataARB()");
+ if (target == GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD) {
+ /* From GL_AMD_pinned_memory:
+ *
+ * INVALID_OPERATION is generated by BufferData if <target> is
+ * EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD, and the store cannot be
+ * mapped to the GPU address space.
+ */
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glBufferData()");
+ }
+ else {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBufferData()");
+ }
}
}
diff --git a/src/mesa/main/extensions.c b/src/mesa/main/extensions.c
index 220b220d668..685236a9194 100644
--- a/src/mesa/main/extensions.c
+++ b/src/mesa/main/extensions.c
@@ -335,6 +335,7 @@ static const struct extension extension_table[] = {
{ "GL_AMD_conservative_depth", o(ARB_conservative_depth), GL, 2009 },
{ "GL_AMD_draw_buffers_blend", o(ARB_draw_buffers_blend), GL, 2009 },
{ "GL_AMD_performance_monitor", o(AMD_performance_monitor), GL, 2007 },
+ { "GL_AMD_pinned_memory", o(AMD_pinned_memory), GL, 2013 },
{ "GL_AMD_seamless_cubemap_per_texture", o(AMD_seamless_cubemap_per_texture), GL, 2009 },
{ "GL_AMD_shader_stencil_export", o(ARB_shader_stencil_export), GL, 2009 },
{ "GL_AMD_shader_trinary_minmax", o(dummy_true), GL, 2012 },
diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
index 1c33ef4605b..08133f1afe0 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -3837,6 +3837,7 @@ struct gl_extensions
GLboolean OES_standard_derivatives;
/* vendor extensions */
GLboolean AMD_performance_monitor;
+ GLboolean AMD_pinned_memory;
GLboolean AMD_seamless_cubemap_per_texture;
GLboolean AMD_vertex_shader_layer;
GLboolean AMD_vertex_shader_viewport_index;
@@ -4378,6 +4379,12 @@ struct gl_context
struct gl_buffer_object *AtomicBuffer;
/**
+ * Object currently associated w/ the GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD
+ * target.
+ */
+ struct gl_buffer_object *ExternalVirtualMemoryBuffer;
+
+ /**
* Array of atomic counter buffer binding points.
*/
struct gl_atomic_buffer_binding