[Mesa-dev] [PATCH 09/24] mesa/st: implement memory objects as a backend for texture storage

Timothy Arceri tarceri at itsqueeze.com
Thu Jul 27 13:08:34 UTC 2017


From: Dave Airlie <airlied at 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 <andresx7 at gmail.com>
Reviewed-by: Marek Olšák <marek.olsak at amd.com>
Reviewed-by: Samuel Pitoiset <samuel.pitoiset at 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



More information about the mesa-dev mailing list