[Mesa-dev] [PATCH 06/24] mesa: hook up memoryobject tex(ture)storage api

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


From: Andres Rodriguez <andresx7 at gmail.com>

V2 (Timothy Arceri):
 - formating fixes

Signed-off-by: Andres Rodriguez <andresx7 at gmail.com>
Reviewed-by: Timothy Arceri <tarceri at itsqueeze.com>
---
 src/mesa/main/dd.h              |  10 ++++
 src/mesa/main/externalobjects.c | 129 ++++++++++++++++++++++++++++++++++++----
 src/mesa/main/texstorage.c      |  77 +++++++++++++++++-------
 src/mesa/main/texstorage.h      |   9 +++
 4 files changed, 193 insertions(+), 32 deletions(-)

diff --git a/src/mesa/main/dd.h b/src/mesa/main/dd.h
index e06899d04f..9cdc4a945e 100644
--- a/src/mesa/main/dd.h
+++ b/src/mesa/main/dd.h
@@ -1080,20 +1080,30 @@ struct dd_function_table {
     * allocate/return a subclass of gl_memory_object.
     */
    struct gl_memory_object * (*NewMemoryObject)(struct gl_context *ctx,
                                                 GLuint name);
    /**
     * Called to delete/free a memory object.  Drivers should free the
     * object and any image data it contains.
     */
    void (*DeleteMemoryObject)(struct gl_context *ctx,
                               struct gl_memory_object *memObj);
+
+   /**
+    * Set the given memory object as the texture's storage.
+    */
+   GLboolean (*SetTextureStorageForMemoryObject)(struct gl_context *ctx,
+                                                 struct gl_texture_object *tex_obj,
+                                                 struct gl_memory_object *mem_obj,
+                                                 GLsizei levels, GLsizei width,
+                                                 GLsizei height, GLsizei depth,
+                                                 GLuint64 offset);
    /*@}*/
 
    /**
     * \name GL_EXT_external_objects_fd interface
     */
    /*@{*/
    /**
     * Called to import a memory object. The caller relinquishes ownership
     * of fd after the call returns.
     *
diff --git a/src/mesa/main/externalobjects.c b/src/mesa/main/externalobjects.c
index c3ee0d8115..25ed176aaa 100644
--- a/src/mesa/main/externalobjects.c
+++ b/src/mesa/main/externalobjects.c
@@ -17,20 +17,24 @@
  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  * DEALINGS IN THE SOFTWARE.
  */
 
 #include "macros.h"
 #include "mtypes.h"
 #include "externalobjects.h"
+#include "teximage.h"
+#include "texobj.h"
+#include "glformats.h"
+#include "texstorage.h"
 
 /**
  * Allocate and initialize a new memory object.  But don't put it into the
  * memory object hash table.
  *
  * Called via ctx->Driver.NewMemoryObject, unless overridden by a device
  * driver.
  *
  * \return pointer to new memory object.
  */
@@ -220,144 +224,249 @@ _mesa_GetMemoryObjectParameterivEXT(GLuint memoryObject,
       default:
          goto invalid_pname;
    }
    return;
 
 invalid_pname:
    _mesa_error(ctx, GL_INVALID_ENUM,
                "glGetMemoryObjectParameterivEXT(pname=0x%x)", pname);
 }
 
+static GLboolean
+texstorage_validate(struct gl_context *ctx,
+                    struct gl_memory_object *memObj,
+                    const char *func)
+{
+   if (memObj->Name == 0) {
+      _mesa_error(ctx, GL_INVALID_VALUE, "%s(memory=0)", func);
+      return GL_TRUE;
+   }
+
+   if (!memObj->Immutable) {
+      _mesa_error(ctx, GL_INVALID_OPERATION, "%s(no associated memory)", func);
+      return GL_TRUE;
+   }
+
+   return GL_FALSE;
+}
+/**
+ * Helper used by _mesa_TexStorageMem1/2/3DEXT().
+ */
+static void
+texstorage_memory(GLuint dims, GLenum target, GLsizei levels,
+                  GLenum internalFormat, GLsizei width, GLsizei height,
+                  GLsizei depth, GLuint memory, GLuint64 offset,
+                  const char *func)
+{
+   struct gl_texture_object *texObj;
+   struct gl_memory_object *memObj;
+
+   GET_CURRENT_CONTEXT(ctx);
+
+   texObj = _mesa_get_current_tex_object(ctx, target);
+   if (!texObj)
+      return;
+
+   memObj = _mesa_lookup_memory_object(ctx, memory);
+   if (!memObj)
+      return;
+
+   if (texstorage_validate(ctx, memObj, func))
+      return;
+
+   _mesa_texture_storage_memory(ctx, dims, texObj, memObj, target,
+                                levels, internalFormat,
+                                width, height, depth, offset, false);
+}
+
+static void
+texstorage_memory_ms(GLuint dims, GLenum target, GLsizei samples,
+                     GLenum internalFormat, GLsizei width, GLsizei height,
+                     GLsizei depth, GLboolean fixedSampleLocations,
+                     GLuint memory, GLuint64 offset)
+{
+
+}
+
+/**
+ * Helper used by _mesa_TextureStorageMem1/2/3DEXT().
+ */
+static void
+texturestorage_memory(GLuint dims, GLuint texture, GLsizei levels,
+                      GLenum internalFormat, GLsizei width, GLsizei height,
+                      GLsizei depth, GLuint memory, GLuint64 offset,
+                      const char *func)
+{
+   struct gl_texture_object *texObj;
+   struct gl_memory_object *memObj;
+
+   GET_CURRENT_CONTEXT(ctx);
+
+   texObj = _mesa_lookup_texture(ctx, texture);
+   if (!texObj)
+      return;
+
+   memObj = _mesa_lookup_memory_object(ctx, memory);
+   if (!memObj)
+      return;
+
+   if (texstorage_validate(ctx, memObj, func))
+      return;
+
+   _mesa_texture_storage_memory(ctx, dims, texObj, memObj, texObj->Target,
+                                levels, internalFormat,
+                                width, height, depth, offset, true);
+}
+
+static void
+texturestorage_memory_ms(GLuint dims, GLuint texture, GLsizei samples,
+                         GLenum internalFormat, GLsizei width, GLsizei height,
+                         GLsizei depth, GLboolean fixedSampleLocations,
+                         GLuint memory, GLuint64 offset)
+{
+
+}
+
 void GLAPIENTRY
 _mesa_TexStorageMem2DEXT(GLenum target,
                          GLsizei levels,
                          GLenum internalFormat,
                          GLsizei width,
                          GLsizei height,
                          GLuint memory,
                          GLuint64 offset)
 {
-
+   texstorage_memory(2, target, levels, internalFormat, width, height, 1,
+                     memory, offset, "glTexStorageMem2DEXT");
 }
 
 void GLAPIENTRY
 _mesa_TexStorageMem2DMultisampleEXT(GLenum target,
                                     GLsizei samples,
                                     GLenum internalFormat,
                                     GLsizei width,
                                     GLsizei height,
                                     GLboolean fixedSampleLocations,
                                     GLuint memory,
                                     GLuint64 offset)
 {
-
+   texstorage_memory_ms(2, target, samples, internalFormat, width, height, 1,
+                        fixedSampleLocations, memory, offset);
 }
 
 void GLAPIENTRY
 _mesa_TexStorageMem3DEXT(GLenum target,
                          GLsizei levels,
                          GLenum internalFormat,
                          GLsizei width,
                          GLsizei height,
                          GLsizei depth,
                          GLuint memory,
                          GLuint64 offset)
 {
-
+   texstorage_memory(3, target, levels, internalFormat, width, height, depth,
+                     memory, offset, "glTexStorageMem3DEXT");
 }
 
 void GLAPIENTRY
 _mesa_TexStorageMem3DMultisampleEXT(GLenum target,
                                     GLsizei samples,
                                     GLenum internalFormat,
                                     GLsizei width,
                                     GLsizei height,
                                     GLsizei depth,
                                     GLboolean fixedSampleLocations,
                                     GLuint memory,
                                     GLuint64 offset)
 {
-
+   texstorage_memory_ms(3, target, samples, internalFormat, width, height,
+                        depth, fixedSampleLocations, memory, offset);
 }
 
 void GLAPIENTRY
 _mesa_TextureStorageMem2DEXT(GLuint texture,
                              GLsizei levels,
                              GLenum internalFormat,
                              GLsizei width,
                              GLsizei height,
                              GLuint memory,
                              GLuint64 offset)
 {
-
+   texturestorage_memory(2, texture, levels, internalFormat, width, height, 1,
+                         memory, offset, "glTexureStorageMem2DEXT");
 }
 
 void GLAPIENTRY
 _mesa_TextureStorageMem2DMultisampleEXT(GLuint texture,
                                         GLsizei samples,
                                         GLenum internalFormat,
                                         GLsizei width,
                                         GLsizei height,
                                         GLboolean fixedSampleLocations,
                                         GLuint memory,
                                         GLuint64 offset)
 {
-
+   texturestorage_memory_ms(2, texture, samples, internalFormat, width, height,
+                            1, fixedSampleLocations, memory, offset);
 }
 
 void GLAPIENTRY
 _mesa_TextureStorageMem3DEXT(GLuint texture,
                              GLsizei levels,
                              GLenum internalFormat,
                              GLsizei width,
                              GLsizei height,
                              GLsizei depth,
                              GLuint memory,
                              GLuint64 offset)
 {
-
+   texturestorage_memory(3, texture, levels, internalFormat, width, height,
+                         depth, memory, offset, "glTextureStorageMem3DEXT");
 }
 
 void GLAPIENTRY
 _mesa_TextureStorageMem3DMultisampleEXT(GLuint texture,
                                         GLsizei samples,
                                         GLenum internalFormat,
                                         GLsizei width,
                                         GLsizei height,
                                         GLsizei depth,
                                         GLboolean fixedSampleLocations,
                                         GLuint memory,
                                         GLuint64 offset)
 {
-
+   texturestorage_memory_ms(3, texture, samples, internalFormat, width, height,
+                            depth, fixedSampleLocations, memory, offset);
 }
 
 void GLAPIENTRY
 _mesa_TexStorageMem1DEXT(GLenum target,
                          GLsizei levels,
                          GLenum internalFormat,
                          GLsizei width,
                          GLuint memory,
                          GLuint64 offset)
 {
-
+   texstorage_memory(1, target, levels, internalFormat, width, 1, 1, memory,
+                     offset, "glTexStorageMem1DEXT");
 }
 
 void GLAPIENTRY
 _mesa_TextureStorageMem1DEXT(GLuint texture,
                              GLsizei levels,
                              GLenum internalFormat,
                              GLsizei width,
                              GLuint memory,
                              GLuint64 offset)
 {
-
+   texturestorage_memory(1, texture, levels, internalFormat, width, 1, 1,
+                         memory, offset, "glTextureStorageMem1DEXT");
 }
 
 void GLAPIENTRY
 _mesa_GenSemaphoresEXT(GLsizei n, GLuint *semaphores)
 {
 
 }
 
 void GLAPIENTRY
 _mesa_DeleteSemaphoresEXT(GLsizei n, const GLuint *semaphores)
diff --git a/src/mesa/main/texstorage.c b/src/mesa/main/texstorage.c
index ef4fe58f5e..c61c5bcb86 100644
--- a/src/mesa/main/texstorage.c
+++ b/src/mesa/main/texstorage.c
@@ -297,26 +297,28 @@ _mesa_AllocTextureStorage_sw(struct gl_context *ctx,
 
 /**
  * Do error checking for calls to glTexStorage1/2/3D().
  * If an error is found, record it with _mesa_error(), unless the target
  * is a proxy texture.
  * \return GL_TRUE if any error, GL_FALSE otherwise.
  */
 static GLboolean
 tex_storage_error_check(struct gl_context *ctx,
                         struct gl_texture_object *texObj,
+                        struct gl_memory_object *memObj,
                         GLuint dims, GLenum target,
                         GLsizei levels, GLenum internalformat,
                         GLsizei width, GLsizei height, GLsizei depth,
                         bool dsa)
 {
-   const char* suffix = dsa ? "ture" : "";
+   const char* suffix = dsa ? (memObj ? "tureMem" : "ture") :
+                              (memObj ? "Mem" : "");
 
    /* Legal format checking has been moved to texstorage and texturestorage in
     * order to allow meta functions to use legacy formats. */
 
    /* size check */
    if (!_mesa_valid_tex_storage_dim(width, height, depth)) {
       _mesa_error(ctx, GL_INVALID_VALUE,
                   "glTex%sStorage%uD(width, height or depth < 1)",
                   suffix, dims);
       return GL_TRUE;
@@ -382,31 +384,32 @@ tex_storage_error_check(struct gl_context *ctx,
 }
 
 
 /**
  * Helper that does the storage allocation for _mesa_TexStorage1/2/3D()
  * and _mesa_TextureStorage1/2/3D().
  */
 static void
 texture_storage(struct gl_context *ctx, GLuint dims,
                 struct gl_texture_object *texObj,
-                GLenum target, GLsizei levels,
-                GLenum internalformat, GLsizei width,
-                GLsizei height, GLsizei depth, bool dsa)
+                struct gl_memory_object *memObj, GLenum target, GLsizei levels,
+                GLenum internalformat, GLsizei width, GLsizei height,
+                GLsizei depth, GLuint64 offset, bool dsa)
 {
    GLboolean sizeOK, dimensionsOK;
    mesa_format texFormat;
-   const char* suffix = dsa ? "ture" : "";
+   const char* suffix = dsa ? (memObj ? "tureMem" : "ture") :
+                              (memObj ? "Mem" : "");
 
    assert(texObj);
 
-   if (tex_storage_error_check(ctx, texObj, dims, target, levels,
+   if (tex_storage_error_check(ctx, texObj, memObj, dims, target, levels,
                                internalformat, width, height, depth, dsa)) {
       return; /* error was recorded */
    }
 
    texFormat = _mesa_choose_texture_format(ctx, texObj, target, 0,
                                            internalformat, GL_NONE, GL_NONE);
 
    /* check that width, height, depth are legal for the mipmap level */
    dimensionsOK = _mesa_legal_texture_dimensions(ctx, target, 0,
                                                   width, height, depth, 0);
@@ -441,32 +444,44 @@ texture_storage(struct gl_context *ctx, GLuint dims,
       assert(levels > 0);
       assert(width > 0);
       assert(height > 0);
       assert(depth > 0);
 
       if (!initialize_texture_fields(ctx, texObj, levels, width, height, depth,
                                      internalformat, texFormat)) {
          return;
       }
 
-      /* Do actual texture memory allocation */
-      if (!ctx->Driver.AllocTextureStorage(ctx, texObj, levels,
-                                           width, height, depth)) {
-         /* Reset the texture images' info to zeros.
-          * Strictly speaking, we probably don't have to do this since
-          * generating GL_OUT_OF_MEMORY can leave things in an undefined
-          * state but this puts things in a consistent state.
-          */
-         clear_texture_fields(ctx, texObj);
-         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTex%sStorage%uD",
-                     suffix, dims);
-         return;
+      /* Setup the backing memory */
+      if (memObj) {
+         if (!ctx->Driver.SetTextureStorageForMemoryObject(ctx, texObj, memObj,
+                                                           levels,
+                                                           width, height, depth,
+                                                           offset)) {
+
+            clear_texture_fields(ctx, texObj);
+            return;
+         }
+      }
+      else {
+         if (!ctx->Driver.AllocTextureStorage(ctx, texObj, levels,
+                                              width, height, depth)) {
+            /* Reset the texture images' info to zeros.
+             * Strictly speaking, we probably don't have to do this since
+             * generating GL_OUT_OF_MEMORY can leave things in an undefined
+             * state but this puts things in a consistent state.
+             */
+            clear_texture_fields(ctx, texObj);
+            _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTex%sStorage%uD",
+                        suffix, dims);
+            return;
+         }
       }
 
       _mesa_set_texture_view_state(ctx, texObj, target, levels);
 
       update_fbo_texture(ctx, texObj);
    }
 }
 
 
 /**
@@ -500,22 +515,23 @@ texstorage(GLuint dims, GLenum target, GLsizei levels, GLenum internalformat,
       _mesa_error(ctx, GL_INVALID_ENUM,
                   "%s(internalformat = %s)", caller,
                   _mesa_enum_to_string(internalformat));
       return;
    }
 
    texObj = _mesa_get_current_tex_object(ctx, target);
    if (!texObj)
       return;
 
-   texture_storage(ctx, dims, texObj, target, levels,
-                   internalformat, width, height, depth, false);
+   texture_storage(ctx, dims, texObj, NULL, target, levels,
+                   internalformat, width, height, depth,
+                   0, false);
 }
 
 
 /**
  * Helper used by _mesa_TextureStorage1/2/3D().
  */
 static void
 texturestorage(GLuint dims, GLuint texture, GLsizei levels,
                GLenum internalformat, GLsizei width, GLsizei height,
                GLsizei depth, const char *caller)
@@ -544,22 +560,23 @@ texturestorage(GLuint dims, GLuint texture, GLsizei levels,
    /* Check target.  This is done here so that texture_storage
     * can receive unsized formats.
     */
    if (!legal_texobj_target(ctx, dims, texObj->Target)) {
       _mesa_error(ctx, GL_INVALID_ENUM,
                   "%s(illegal target=%s)", caller,
                   _mesa_enum_to_string(texObj->Target));
       return;
    }
 
-   texture_storage(ctx, dims, texObj, texObj->Target,
-                   levels, internalformat, width, height, depth, true);
+   texture_storage(ctx, dims, texObj, NULL, texObj->Target,
+                   levels, internalformat, width, height, depth,
+                   0, true);
 }
 
 
 void GLAPIENTRY
 _mesa_TexStorage1D(GLenum target, GLsizei levels, GLenum internalformat,
                    GLsizei width)
 {
    texstorage(1, target, levels, internalformat, width, 1, 1,
               "glTexStorage1D");
 }
@@ -667,10 +684,26 @@ _mesa_TextureStorage3DEXT(GLuint texture, GLenum target, GLsizei levels,
    (void) target;
    (void) levels;
    (void) internalformat;
    (void) width;
    (void) height;
    (void) depth;
 
    _mesa_error(ctx, GL_INVALID_OPERATION,
                "glTextureStorage3DEXT not supported");
 }
+
+
+void
+_mesa_texture_storage_memory(struct gl_context *ctx, GLuint dims,
+                             struct gl_texture_object *texObj,
+                             struct gl_memory_object *memObj,
+                             GLenum target, GLsizei levels,
+                             GLenum internalformat, GLsizei width,
+                             GLsizei height, GLsizei depth,
+                             GLuint64 offset, bool dsa)
+{
+   assert(memObj);
+
+   texture_storage(ctx, dims, texObj, memObj, target, levels, internalformat,
+                   width, height, depth, offset, dsa);
+}
diff --git a/src/mesa/main/texstorage.h b/src/mesa/main/texstorage.h
index 526c61e851..47685116f3 100644
--- a/src/mesa/main/texstorage.h
+++ b/src/mesa/main/texstorage.h
@@ -106,11 +106,20 @@ _mesa_TextureStorage3DEXT(GLuint texture, GLenum target, GLsizei levels,
 extern GLboolean
 _mesa_is_legal_tex_storage_format(const struct gl_context *ctx,
                                   GLenum internalformat);
 
 extern GLboolean
 _mesa_AllocTextureStorage_sw(struct gl_context *ctx,
                              struct gl_texture_object *texObj,
                              GLsizei levels, GLsizei width,
                              GLsizei height, GLsizei depth);
 
+extern void
+_mesa_texture_storage_memory(struct gl_context *ctx, GLuint dims,
+                             struct gl_texture_object *texObj,
+                             struct gl_memory_object *memObj,
+                             GLenum target, GLsizei levels,
+                             GLenum internalformat, GLsizei width,
+                             GLsizei height, GLsizei depth,
+                             GLuint64 offset, bool dsa);
+
 #endif /* TEXSTORAGE_H */
-- 
2.13.3



More information about the mesa-dev mailing list