From 8b587ee7011aee900fd84f6203467ba899f2ed01 Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Tue, 10 Feb 2015 14:00:57 +0100 Subject: gallium: add interface and state tracker support for GL_AMD_pinned_memory MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit v2: add alignment restrictions to docs, fix indentation in headers Reviewed-by: Christian König --- src/gallium/docs/source/screen.rst | 6 ++++++ src/gallium/drivers/i915/i915_screen.c | 1 + src/gallium/drivers/ilo/ilo_screen.c | 1 + src/gallium/drivers/llvmpipe/lp_screen.c | 1 + src/gallium/drivers/nouveau/nv30/nv30_screen.c | 1 + src/gallium/drivers/nouveau/nv50/nv50_screen.c | 1 + src/gallium/drivers/nouveau/nvc0/nvc0_screen.c | 1 + src/gallium/drivers/r300/r300_screen.c | 1 + src/gallium/drivers/softpipe/sp_screen.c | 1 + src/gallium/drivers/svga/svga_screen.c | 1 + src/gallium/drivers/vc4/vc4_screen.c | 1 + src/gallium/include/pipe/p_defines.h | 1 + src/gallium/include/pipe/p_screen.h | 8 ++++++++ src/mesa/state_tracker/st_cb_bufferobjects.c | 18 +++++++++++++----- src/mesa/state_tracker/st_extensions.c | 1 + 15 files changed, 39 insertions(+), 5 deletions(-) diff --git a/src/gallium/docs/source/screen.rst b/src/gallium/docs/source/screen.rst index 5d80908057..373a2fe25d 100644 --- a/src/gallium/docs/source/screen.rst +++ b/src/gallium/docs/source/screen.rst @@ -246,6 +246,12 @@ The integer capabilities: * ``PIPE_CAP_MULTISAMPLE_Z_RESOLVE``: Whether the driver supports blitting a multisampled depth buffer into a single-sampled texture (or depth buffer). Only the first sampled should be copied. +* ``PIPE_CAP_RESOURCE_FROM_USER_MEMORY``: Whether the driver can create + a pipe_resource where an already-existing piece of (malloc'd) user memory + is used as its backing storage. In other words, whether the driver can map + existing user memory into the device address space for direct device access. + The create function is pipe_screen::resource_from_user_memory. The address + and size must be page-aligned. .. _pipe_capf: diff --git a/src/gallium/drivers/i915/i915_screen.c b/src/gallium/drivers/i915/i915_screen.c index 2dcb507335..5fbbcf5158 100644 --- a/src/gallium/drivers/i915/i915_screen.c +++ b/src/gallium/drivers/i915/i915_screen.c @@ -229,6 +229,7 @@ i915_get_param(struct pipe_screen *screen, enum pipe_cap cap) case PIPE_CAP_VERTEXID_NOBASE: case PIPE_CAP_POLYGON_OFFSET_CLAMP: case PIPE_CAP_MULTISAMPLE_Z_RESOLVE: + case PIPE_CAP_RESOURCE_FROM_USER_MEMORY: return 0; case PIPE_CAP_MAX_DUAL_SOURCE_RENDER_TARGETS: diff --git a/src/gallium/drivers/ilo/ilo_screen.c b/src/gallium/drivers/ilo/ilo_screen.c index cf9f897500..95e34d3e4d 100644 --- a/src/gallium/drivers/ilo/ilo_screen.c +++ b/src/gallium/drivers/ilo/ilo_screen.c @@ -471,6 +471,7 @@ ilo_get_param(struct pipe_screen *screen, enum pipe_cap param) case PIPE_CAP_CONDITIONAL_RENDER_INVERTED: case PIPE_CAP_SAMPLER_VIEW_TARGET: case PIPE_CAP_MULTISAMPLE_Z_RESOLVE: + case PIPE_CAP_RESOURCE_FROM_USER_MEMORY: return 0; case PIPE_CAP_VENDOR_ID: diff --git a/src/gallium/drivers/llvmpipe/lp_screen.c b/src/gallium/drivers/llvmpipe/lp_screen.c index 31c65df022..8b6e66e968 100644 --- a/src/gallium/drivers/llvmpipe/lp_screen.c +++ b/src/gallium/drivers/llvmpipe/lp_screen.c @@ -288,6 +288,7 @@ llvmpipe_get_param(struct pipe_screen *screen, enum pipe_cap param) case PIPE_CAP_POLYGON_OFFSET_CLAMP: return 1; case PIPE_CAP_MULTISAMPLE_Z_RESOLVE: + case PIPE_CAP_RESOURCE_FROM_USER_MEMORY: return 0; } /* should only get here on unhandled cases */ diff --git a/src/gallium/drivers/nouveau/nv30/nv30_screen.c b/src/gallium/drivers/nouveau/nv30/nv30_screen.c index 83cae7a173..a532e5303e 100644 --- a/src/gallium/drivers/nouveau/nv30/nv30_screen.c +++ b/src/gallium/drivers/nouveau/nv30/nv30_screen.c @@ -160,6 +160,7 @@ nv30_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) case PIPE_CAP_VERTEXID_NOBASE: case PIPE_CAP_POLYGON_OFFSET_CLAMP: case PIPE_CAP_MULTISAMPLE_Z_RESOLVE: + case PIPE_CAP_RESOURCE_FROM_USER_MEMORY: return 0; case PIPE_CAP_VENDOR_ID: diff --git a/src/gallium/drivers/nouveau/nv50/nv50_screen.c b/src/gallium/drivers/nouveau/nv50/nv50_screen.c index 222fa65b31..6c1de08ddc 100644 --- a/src/gallium/drivers/nouveau/nv50/nv50_screen.c +++ b/src/gallium/drivers/nouveau/nv50/nv50_screen.c @@ -208,6 +208,7 @@ nv50_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) case PIPE_CAP_DRAW_INDIRECT: case PIPE_CAP_VERTEXID_NOBASE: case PIPE_CAP_MULTISAMPLE_Z_RESOLVE: /* potentially supported on some hw */ + case PIPE_CAP_RESOURCE_FROM_USER_MEMORY: return 0; case PIPE_CAP_VENDOR_ID: diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c b/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c index 63fbad7a09..edea845ecb 100644 --- a/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c +++ b/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c @@ -192,6 +192,7 @@ nvc0_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) case PIPE_CAP_FAKE_SW_MSAA: case PIPE_CAP_TGSI_VS_WINDOW_SPACE_POSITION: case PIPE_CAP_VERTEXID_NOBASE: + case PIPE_CAP_RESOURCE_FROM_USER_MEMORY: return 0; case PIPE_CAP_VENDOR_ID: diff --git a/src/gallium/drivers/r300/r300_screen.c b/src/gallium/drivers/r300/r300_screen.c index 7794fc26cd..36b2996546 100644 --- a/src/gallium/drivers/r300/r300_screen.c +++ b/src/gallium/drivers/r300/r300_screen.c @@ -184,6 +184,7 @@ static int r300_get_param(struct pipe_screen* pscreen, enum pipe_cap param) case PIPE_CAP_VERTEXID_NOBASE: case PIPE_CAP_POLYGON_OFFSET_CLAMP: case PIPE_CAP_MULTISAMPLE_Z_RESOLVE: + case PIPE_CAP_RESOURCE_FROM_USER_MEMORY: return 0; /* SWTCL-only features. */ diff --git a/src/gallium/drivers/softpipe/sp_screen.c b/src/gallium/drivers/softpipe/sp_screen.c index 365fc0a1db..bae136768a 100644 --- a/src/gallium/drivers/softpipe/sp_screen.c +++ b/src/gallium/drivers/softpipe/sp_screen.c @@ -236,6 +236,7 @@ softpipe_get_param(struct pipe_screen *screen, enum pipe_cap param) case PIPE_CAP_POLYGON_OFFSET_CLAMP: return 0; case PIPE_CAP_MULTISAMPLE_Z_RESOLVE: + case PIPE_CAP_RESOURCE_FROM_USER_MEMORY: return 0; } /* should only get here on unhandled cases */ diff --git a/src/gallium/drivers/svga/svga_screen.c b/src/gallium/drivers/svga/svga_screen.c index e3db4a8b44..e468a2f89c 100644 --- a/src/gallium/drivers/svga/svga_screen.c +++ b/src/gallium/drivers/svga/svga_screen.c @@ -307,6 +307,7 @@ svga_get_param(struct pipe_screen *screen, enum pipe_cap param) /* XXX: Query the host ? */ return 1; case PIPE_CAP_UMA: + case PIPE_CAP_RESOURCE_FROM_USER_MEMORY: return 0; } diff --git a/src/gallium/drivers/vc4/vc4_screen.c b/src/gallium/drivers/vc4/vc4_screen.c index db88eaa5bb..74643512b9 100644 --- a/src/gallium/drivers/vc4/vc4_screen.c +++ b/src/gallium/drivers/vc4/vc4_screen.c @@ -172,6 +172,7 @@ vc4_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) case PIPE_CAP_VERTEXID_NOBASE: case PIPE_CAP_POLYGON_OFFSET_CLAMP: case PIPE_CAP_MULTISAMPLE_Z_RESOLVE: + case PIPE_CAP_RESOURCE_FROM_USER_MEMORY: return 0; /* Stream output. */ diff --git a/src/gallium/include/pipe/p_defines.h b/src/gallium/include/pipe/p_defines.h index 7ce25af20c..17850438dc 100644 --- a/src/gallium/include/pipe/p_defines.h +++ b/src/gallium/include/pipe/p_defines.h @@ -575,6 +575,7 @@ enum pipe_cap { PIPE_CAP_VERTEXID_NOBASE = 112, PIPE_CAP_POLYGON_OFFSET_CLAMP = 113, PIPE_CAP_MULTISAMPLE_Z_RESOLVE = 114, + PIPE_CAP_RESOURCE_FROM_USER_MEMORY = 115, }; #define PIPE_QUIRK_TEXTURE_BORDER_COLOR_SWIZZLE_NV50 (1 << 0) diff --git a/src/gallium/include/pipe/p_screen.h b/src/gallium/include/pipe/p_screen.h index cf958d26a0..ac885068aa 100644 --- a/src/gallium/include/pipe/p_screen.h +++ b/src/gallium/include/pipe/p_screen.h @@ -163,6 +163,14 @@ struct pipe_screen { const struct pipe_resource *templat, struct winsys_handle *handle); + /** + * Create a resource from user memory. This maps the user memory into + * the device address space. + */ + struct pipe_resource * (*resource_from_user_memory)(struct pipe_screen *, + const struct pipe_resource *t, + void *user_memory); + /** * Get a winsys_handle from a texture. Some platforms/winsys requires * that the texture is created with a special usage flag like diff --git a/src/mesa/state_tracker/st_cb_bufferobjects.c b/src/mesa/state_tracker/st_cb_bufferobjects.c index 90f786cc1f..f24805cf5d 100644 --- a/src/mesa/state_tracker/st_cb_bufferobjects.c +++ b/src/mesa/state_tracker/st_cb_bufferobjects.c @@ -186,7 +186,8 @@ st_bufferobj_data(struct gl_context *ctx, struct st_buffer_object *st_obj = st_buffer_object(obj); unsigned bind, pipe_usage, pipe_flags = 0; - if (size && data && st_obj->buffer && + if (target != GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD && + size && data && st_obj->buffer && st_obj->Base.Size == size && st_obj->Base.Usage == usage && st_obj->Base.StorageFlags == storageFlags) { @@ -287,6 +288,7 @@ st_bufferobj_data(struct gl_context *ctx, } if (size != 0) { + struct pipe_screen *screen = pipe->screen; struct pipe_resource buffer; memset(&buffer, 0, sizeof buffer); @@ -300,16 +302,22 @@ st_bufferobj_data(struct gl_context *ctx, buffer.depth0 = 1; buffer.array_size = 1; - st_obj->buffer = pipe->screen->resource_create(pipe->screen, &buffer); + if (target == GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD) { + st_obj->buffer = + screen->resource_from_user_memory(screen, &buffer, (void*)data); + } + else { + st_obj->buffer = screen->resource_create(screen, &buffer); + + if (st_obj->buffer && data) + pipe_buffer_write(pipe, st_obj->buffer, 0, size, data); + } if (!st_obj->buffer) { /* out of memory */ st_obj->Base.Size = 0; return GL_FALSE; } - - if (data) - pipe_buffer_write(pipe, st_obj->buffer, 0, size, data); } /* BufferData may change an array or uniform buffer, need to update it */ diff --git a/src/mesa/state_tracker/st_extensions.c b/src/mesa/state_tracker/st_extensions.c index 2b5cde2804..036fac71a0 100644 --- a/src/mesa/state_tracker/st_extensions.c +++ b/src/mesa/state_tracker/st_extensions.c @@ -446,6 +446,7 @@ void st_init_extensions(struct pipe_screen *screen, { o(EXT_texture_swizzle), PIPE_CAP_TEXTURE_SWIZZLE }, { o(EXT_transform_feedback), PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS }, + { o(AMD_pinned_memory), PIPE_CAP_RESOURCE_FROM_USER_MEMORY }, { o(AMD_seamless_cubemap_per_texture), PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE }, { o(ATI_separate_stencil), PIPE_CAP_TWO_SIDED_STENCIL }, { o(ATI_texture_mirror_once), PIPE_CAP_TEXTURE_MIRROR_CLAMP }, -- cgit v1.2.3