From: Dave Airlie <airl...@redhat.com> Instead of allocating memory to back a texture, use the provided memory object.
v2: split off extension exposure logic v3: de-duplicate code with st_AllocTextureStorage Signed-off-by: Andres Rodriguez <andre...@gmail.com> Reviewed-by: Marek Olšák <marek.ol...@amd.com> Reviewed-by: Samuel Pitoiset <samuel.pitoi...@gmail.com> --- src/mesa/state_tracker/st_cb_bufferobjects.c | 2 +- src/mesa/state_tracker/st_cb_texture.c | 116 ++++++++++++++++++++++++--- 2 files changed, 106 insertions(+), 12 deletions(-) diff --git a/src/mesa/state_tracker/st_cb_bufferobjects.c b/src/mesa/state_tracker/st_cb_bufferobjects.c index 68ec250101..1fa9389b32 100644 --- a/src/mesa/state_tracker/st_cb_bufferobjects.c +++ b/src/mesa/state_tracker/st_cb_bufferobjects.c @@ -168,21 +168,21 @@ st_bufferobj_get_subdata(struct gl_context *ctx, * Allocate space for and store data in a buffer object. Any data that was * previously stored in the buffer object is lost. If data is NULL, * memory will be allocated, but no copy will occur. * Called via ctx->Driver.BufferData(). * \return GL_TRUE for success, GL_FALSE if out of memory */ static GLboolean st_bufferobj_data(struct gl_context *ctx, GLenum target, GLsizeiptrARB size, - const void * data, + const void *data, GLenum usage, GLbitfield storageFlags, struct gl_buffer_object *obj) { struct st_context *st = st_context(ctx); struct pipe_context *pipe = st->pipe; struct pipe_screen *screen = pipe->screen; struct st_buffer_object *st_obj = st_buffer_object(obj); unsigned bind, pipe_usage, pipe_flags = 0; diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c index ab0bc208c2..3cc1fa0e6c 100644 --- a/src/mesa/state_tracker/st_cb_texture.c +++ b/src/mesa/state_tracker/st_cb_texture.c @@ -46,20 +46,21 @@ #include "main/texobj.h" #include "main/texstore.h" #include "state_tracker/st_debug.h" #include "state_tracker/st_context.h" #include "state_tracker/st_cb_bitmap.h" #include "state_tracker/st_cb_fbo.h" #include "state_tracker/st_cb_flush.h" #include "state_tracker/st_cb_texture.h" #include "state_tracker/st_cb_bufferobjects.h" +#include "state_tracker/st_cb_memoryobjects.h" #include "state_tracker/st_format.h" #include "state_tracker/st_pbo.h" #include "state_tracker/st_texture.h" #include "state_tracker/st_gen_mipmap.h" #include "state_tracker/st_atom.h" #include "state_tracker/st_sampler_view.h" #include "pipe/p_context.h" #include "pipe/p_defines.h" #include "util/u_inlines.h" @@ -2641,34 +2642,95 @@ st_finalize_texture(struct gl_context *ctx, } stObj->validated_first_level = stObj->base.BaseLevel; stObj->validated_last_level = stObj->lastLevel; stObj->needs_validation = false; return GL_TRUE; } /** + * Allocate a new pipe_resource object + * width0, height0, depth0 are the dimensions of the level 0 image + * (the highest resolution). last_level indicates how many mipmap levels + * to allocate storage for. For non-mipmapped textures, this will be zero. + */ +static struct pipe_resource * +st_texture_create_from_memory(struct st_context *st, + struct st_memory_object *memObj, + GLuint64 offset, + enum pipe_texture_target target, + enum pipe_format format, + GLuint last_level, + GLuint width0, + GLuint height0, + GLuint depth0, + GLuint layers, + GLuint nr_samples, + GLuint bind ) +{ + struct pipe_resource pt, *newtex; + struct pipe_screen *screen = st->pipe->screen; + + assert(target < PIPE_MAX_TEXTURE_TYPES); + assert(width0 > 0); + assert(height0 > 0); + assert(depth0 > 0); + if (target == PIPE_TEXTURE_CUBE) + assert(layers == 6); + + DBG("%s target %d format %s last_level %d\n", __func__, + (int) target, util_format_name(format), last_level); + + assert(format); + assert(screen->is_format_supported(screen, format, target, 0, + PIPE_BIND_SAMPLER_VIEW)); + + memset(&pt, 0, sizeof(pt)); + pt.target = target; + pt.format = format; + pt.last_level = last_level; + pt.width0 = width0; + pt.height0 = height0; + pt.depth0 = depth0; + pt.array_size = layers; + pt.usage = PIPE_USAGE_DEFAULT; + pt.bind = bind; + /* only set this for OpenGL textures, not renderbuffers */ + pt.flags = PIPE_RESOURCE_FLAG_TEXTURING_MORE_LIKELY; + pt.nr_samples = nr_samples; + + newtex = screen->resource_from_memobj(screen, &pt, memObj->memory, offset); + + assert(!newtex || pipe_is_referenced(&newtex->reference)); + + return newtex; +} + +/** * Allocate texture memory for a whole mipmap stack. * Note: for multisample textures if the requested sample count is not * supported, we search for the next higher supported sample count. */ static GLboolean st_texture_storage(struct gl_context *ctx, struct gl_texture_object *texObj, GLsizei levels, GLsizei width, - GLsizei height, GLsizei depth) + GLsizei height, GLsizei depth, + struct gl_memory_object *memObj, + GLuint64 offset) { const GLuint numFaces = _mesa_num_tex_faces(texObj->Target); struct gl_texture_image *texImage = texObj->Image[0][0]; struct st_context *st = st_context(ctx); struct st_texture_object *stObj = st_texture_object(texObj); + struct st_memory_object *smObj = st_memory_object(memObj); struct pipe_screen *screen = st->pipe->screen; unsigned ptWidth, bindings; uint16_t ptHeight, ptDepth, ptLayers; enum pipe_format fmt; GLint level; GLuint num_samples = texImage->NumSamples; assert(levels > 0); stObj->lastLevel = levels - 1; @@ -2695,29 +2757,45 @@ st_texture_storage(struct gl_context *ctx, if (!found) { return GL_FALSE; } } st_gl_texture_dims_to_pipe_dims(texObj->Target, width, height, depth, &ptWidth, &ptHeight, &ptDepth, &ptLayers); - stObj->pt = st_texture_create(st, - gl_target_to_pipe(texObj->Target), - fmt, - levels - 1, - ptWidth, - ptHeight, - ptDepth, - ptLayers, num_samples, - bindings); + if (smObj) { + stObj->pt = st_texture_create_from_memory(st, + smObj, + offset, + gl_target_to_pipe(texObj->Target), + fmt, + levels - 1, + ptWidth, + ptHeight, + ptDepth, + ptLayers, num_samples, + bindings); + } + else { + stObj->pt = st_texture_create(st, + gl_target_to_pipe(texObj->Target), + fmt, + levels - 1, + ptWidth, + ptHeight, + ptDepth, + ptLayers, num_samples, + bindings); + } + if (!stObj->pt) return GL_FALSE; /* Set image resource pointers */ for (level = 0; level < levels; level++) { GLuint face; for (face = 0; face < numFaces; face++) { struct st_texture_image *stImage = st_texture_image(texObj->Image[face][level]); pipe_resource_reference(&stImage->pt, stObj->pt); @@ -2738,21 +2816,22 @@ st_texture_storage(struct gl_context *ctx, * Called via ctx->Driver.AllocTextureStorage() to allocate texture memory * for a whole mipmap stack. */ static GLboolean st_AllocTextureStorage(struct gl_context *ctx, struct gl_texture_object *texObj, GLsizei levels, GLsizei width, GLsizei height, GLsizei depth) { return st_texture_storage(ctx, texObj, levels, - width, height, depth); + width, height, depth, + NULL, 0); } static GLboolean st_TestProxyTexImage(struct gl_context *ctx, GLenum target, GLuint numLevels, GLint level, mesa_format format, GLuint numSamples, GLint width, GLint height, GLint depth) { struct st_context *st = st_context(ctx); @@ -2962,20 +3041,32 @@ st_TexParameter(struct gl_context *ctx, /* changing any of these texture parameters means we must create * new sampler views. */ st_texture_release_all_sampler_views(st, stObj); break; default: ; /* nothing */ } } +static GLboolean +st_SetTextureStorageForMemoryObject(struct gl_context *ctx, + struct gl_texture_object *texObj, + struct gl_memory_object *memObj, + GLsizei levels, GLsizei width, + GLsizei height, GLsizei depth, + GLuint64 offset) +{ + return st_texture_storage(ctx, texObj, levels, + width, height, depth, + memObj, offset); +} static GLuint64 st_NewTextureHandle(struct gl_context *ctx, struct gl_texture_object *texObj, struct gl_sampler_object *sampObj) { struct st_context *st = st_context(ctx); struct st_texture_object *stObj = st_texture_object(texObj); struct pipe_context *pipe = st->pipe; struct pipe_sampler_view *view; struct pipe_sampler_state sampler = {0}; @@ -3084,11 +3175,14 @@ st_init_texture_functions(struct dd_function_table *functions) functions->TexParameter = st_TexParameter; /* bindless functions */ functions->NewTextureHandle = st_NewTextureHandle; functions->DeleteTextureHandle = st_DeleteTextureHandle; functions->MakeTextureHandleResident = st_MakeTextureHandleResident; functions->NewImageHandle = st_NewImageHandle; functions->DeleteImageHandle = st_DeleteImageHandle; functions->MakeImageHandleResident = st_MakeImageHandleResident; + + /* external object functions */ + functions->SetTextureStorageForMemoryObject = st_SetTextureStorageForMemoryObject; } -- 2.13.3 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev