<div dir="ltr"><div><div><div>This happens almost everywhere.  I prefer to call _mesa_error(ctx, "glTex%sStorage".... rather than _mesa_error(ctx, "%s" .... because it's more obvious when reading the code which API function you're in (texture storage rather than copy texture sub image, etc).  Would this work better?<br><br></div>const char *suffix = dsa ? "ture" : "";<br><br></div>_mesa_error(ctx, "glTex%sStorage", suffix....<br>_mesa_error(ctx, "glTex%sStorage", suffix....<br><br></div>Thanks.<br><br>Laura<br></div><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Dec 16, 2014 at 7:46 AM, Brian Paul <span dir="ltr"><<a href="mailto:brianp@vmware.com" target="_blank">brianp@vmware.com</a>></span> wrote:<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="HOEnZb"><div class="h5">On 12/15/2014 06:22 PM, Laura Ekstrand wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
---<br>
  src/mapi/glapi/gen/ARB_direct_<u></u>state_access.xml |  24 +++<br>
  src/mesa/main/texstorage.c                     | 205 +++++++++++++++++++------<br>
  src/mesa/main/texstorage.h                     |  31 ++++<br>
  3 files changed, 209 insertions(+), 51 deletions(-)<br>
<br>
diff --git a/src/mapi/glapi/gen/ARB_<u></u>direct_state_access.xml b/src/mapi/glapi/gen/ARB_<u></u>direct_state_access.xml<br>
index 9f2eacb..37aac7e 100644<br>
--- a/src/mapi/glapi/gen/ARB_<u></u>direct_state_access.xml<br>
+++ b/src/mapi/glapi/gen/ARB_<u></u>direct_state_access.xml<br>
@@ -15,5 +15,29 @@<br>
        <param name="textures" type="GLuint *" /><br>
     </function><br>
<br>
+   <function name="TextureStorage1D" offset="assign"><br>
+      <param name="texture" type="GLuint" /><br>
+      <param name="levels" type="GLsizei" /><br>
+      <param name="internalformat" type="GLenum" /><br>
+      <param name="width" type="GLsizei" /><br>
+   </function><br>
+<br>
+   <function name="TextureStorage2D" offset="assign"><br>
+      <param name="texture" type="GLuint" /><br>
+      <param name="levels" type="GLsizei" /><br>
+      <param name="internalformat" type="GLenum" /><br>
+      <param name="width" type="GLsizei" /><br>
+      <param name="height" type="GLsizei" /><br>
+   </function><br>
+<br>
+   <function name="TextureStorage3D" offset="assign"><br>
+      <param name="texture" type="GLuint" /><br>
+      <param name="levels" type="GLsizei" /><br>
+      <param name="internalformat" type="GLenum" /><br>
+      <param name="width" type="GLsizei" /><br>
+      <param name="height" type="GLsizei" /><br>
+      <param name="depth" type="GLsizei" /><br>
+   </function><br>
+<br>
  </category><br>
  </OpenGLAPI><br>
diff --git a/src/mesa/main/texstorage.c b/src/mesa/main/texstorage.c<br>
index f41076a..7565a43 100644<br>
--- a/src/mesa/main/texstorage.c<br>
+++ b/src/mesa/main/texstorage.c<br>
@@ -42,7 +42,7 @@<br>
  #include "textureview.h"<br>
  #include "mtypes.h"<br>
  #include "glformats.h"<br>
-<br>
+#include "hash.h"<br>
<br>
<br>
  /**<br>
@@ -274,34 +274,25 @@ _mesa_AllocTextureStorage_sw(<u></u>struct gl_context *ctx,<br>
   * \return GL_TRUE if any error, GL_FALSE otherwise.<br>
   */<br>
  static GLboolean<br>
-tex_storage_error_check(<u></u>struct gl_context *ctx, GLuint dims, GLenum target,<br>
+tex_storage_error_check(<u></u>struct gl_context *ctx,<br>
+                        struct gl_texture_object *texObj,<br>
+                        GLuint dims, GLenum target,<br>
                          GLsizei levels, GLenum internalformat,<br>
-                        GLsizei width, GLsizei height, GLsizei depth)<br>
+                        GLsizei width, GLsizei height, GLsizei depth,<br>
+                        bool dsa)<br>
  {<br>
-   struct gl_texture_object *texObj;<br>
<br>
-   if (!_mesa_is_legal_tex_storage_<u></u>format(ctx, internalformat)) {<br>
-      _mesa_error(ctx, GL_INVALID_ENUM,<br>
-                  "glTexStorage%uD(<u></u>internalformat = %s)", dims,<br>
-                  _mesa_lookup_enum_by_nr(<u></u>internalformat));<br>
-      return GL_TRUE;<br>
-   }<br>
+   /* Legal format checking has been moved to texstorage and texturestorage in<br>
+    * order to allow meta functions to use legacy formats. */<br>
<br>
     /* size check */<br>
     if (width < 1 || height < 1 || depth < 1) {<br>
        _mesa_error(ctx, GL_INVALID_VALUE,<br>
-                  "glTexStorage%uD(width, height or depth < 1)", dims);<br>
+                  "glTex%sStorage%uD(width, height or depth < 1)",<br>
+                  dsa ? "ture" : "", dims);<br>
</blockquote>
<br></div></div>
This kind of string replacement seems clunky, and often repeated in this patch and at least 12/41.<br>
<br>
How about declaring a local var:<br>
<br>
const char *func = dsa ? "glTextureStorage" : "glTexStorage";<br>
<br>
and using 'func' in the _mesa_error() calls?<div class="HOEnZb"><div class="h5"><br>
<br>
<br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
        return GL_TRUE;<br>
     }<br>
<br>
-   /* target check */<br>
-   if (!legal_texobj_target(ctx, dims, target)) {<br>
-      _mesa_error(ctx, GL_INVALID_ENUM,<br>
-                  "glTexStorage%uD(illegal target=%s)",<br>
-                  dims, _mesa_lookup_enum_by_nr(<u></u>target));<br>
-      return GL_TRUE;<br>
-   }<br>
-<br>
     /* From section 3.8.6, page 146 of OpenGL ES 3.0 spec:<br>
      *<br>
      *    "The ETC2/EAC texture compression algorithm supports only<br>
@@ -315,50 +306,55 @@ tex_storage_error_check(struct gl_context *ctx, GLuint dims, GLenum target,<br>
         && !_mesa_target_can_be_<u></u>compressed(ctx, target, internalformat)) {<br>
        _mesa_error(ctx, _mesa_is_desktop_gl(ctx)?<br>
                    GL_INVALID_ENUM : GL_INVALID_OPERATION,<br>
-                  "glTexStorage3D(internalformat = %s)",<br>
+                  "glTex%sStorage%dD(<u></u>internalformat = %s)",<br>
+                  dsa ? "ture" : "", dims,<br>
                    _mesa_lookup_enum_by_nr(<u></u>internalformat));<br>
     }<br>
<br>
     /* levels check */<br>
     if (levels < 1) {<br>
-      _mesa_error(ctx, GL_INVALID_VALUE, "glTexStorage%uD(levels < 1)",<br>
-                  dims);<br>
+      _mesa_error(ctx, GL_INVALID_VALUE, "glTex%sStorage%uD(levels < 1)",<br>
+                  dsa ? "ture" : "", dims);<br>
        return GL_TRUE;<br>
     }<br>
<br>
     /* check levels against maximum (note different error than above) */<br>
     if (levels > (GLint) _mesa_max_texture_levels(ctx, target)) {<br>
        _mesa_error(ctx, GL_INVALID_OPERATION,<br>
-                  "glTexStorage%uD(levels too large)", dims);<br>
+                  "glTex%sStorage%uD(levels too large)",<br>
+                  dsa ? "ture" : "", dims);<br>
        return GL_TRUE;<br>
     }<br>
<br>
     /* check levels against width/height/depth */<br>
     if (levels > _mesa_get_tex_max_num_levels(<u></u>target, width, height, depth)) {<br>
        _mesa_error(ctx, GL_INVALID_OPERATION,<br>
-                  "glTexStorage%uD(too many levels for max texture dimension)",<br>
-                  dims);<br>
+                  "glTex%sStorage%uD(too many levels"<br>
+                  " for max texture dimension)",<br>
+                  dsa ? "ture" : "", dims);<br>
        return GL_TRUE;<br>
     }<br>
<br>
     /* non-default texture object check */<br>
-   texObj = _mesa_get_current_tex_object(<u></u>ctx, target);<br>
     if (!_mesa_is_proxy_texture(<u></u>target) && (!texObj || (texObj->Name == 0))) {<br>
        _mesa_error(ctx, GL_INVALID_OPERATION,<br>
-                  "glTexStorage%uD(texture object 0)", dims);<br>
+                  "glTex%sStorage%uD(texture object 0)",<br>
+                  dsa ? "ture" : "", dims);<br>
        return GL_TRUE;<br>
     }<br>
<br>
     /* Check if texObj->Immutable is set */<br>
     if (!_mesa_is_proxy_texture(<u></u>target) && texObj->Immutable) {<br>
-      _mesa_error(ctx, GL_INVALID_OPERATION, "glTexStorage%uD(immutable)",<br>
-                  dims);<br>
+      _mesa_error(ctx, GL_INVALID_OPERATION, "glTex%sStorage%uD(immutable)"<u></u>,<br>
+                  dsa ? "ture" : "", dims);<br>
        return GL_TRUE;<br>
     }<br>
<br>
     /* additional checks for depth textures */<br>
     if (!_mesa_legal_texture_base_<u></u>format_for_target(ctx, target, internalformat,<br>
-                                                   dims, "glTexStorage"))<br>
+                                                   dims, dsa ?<br>
+                                                   "glTextureStorage" :<br>
+                                                   "glTexStorage"))<br>
        return GL_TRUE;<br>
<br>
     return GL_FALSE;<br>
@@ -366,32 +362,26 @@ tex_storage_error_check(struct gl_context *ctx, GLuint dims, GLenum target,<br>
<br>
<br>
  /**<br>
- * Helper used by _mesa_TexStorage1/2/3D().<br>
+ * Helper that does the storage allocation for _mesa_TexStorage1/2/3D()<br>
+ * and _mesa_TextureStorage1/2/3D().<br>
   */<br>
-static void<br>
-texstorage(GLuint dims, GLenum target, GLsizei levels, GLenum internalformat,<br>
-           GLsizei width, GLsizei height, GLsizei depth)<br>
+void<br>
+_mesa_texture_storage(struct gl_context *ctx, GLuint dims,<br>
+                      struct gl_texture_object *texObj,<br>
+                      GLenum target, GLsizei levels,<br>
+                      GLenum internalformat, GLsizei width,<br>
+                      GLsizei height, GLsizei depth, bool dsa)<br>
  {<br>
-   struct gl_texture_object *texObj;<br>
     GLboolean sizeOK, dimensionsOK;<br>
     mesa_format texFormat;<br>
<br>
-   GET_CURRENT_CONTEXT(ctx);<br>
-<br>
-   if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))<br>
-      _mesa_debug(ctx, "glTexStorage%uD %s %d %s %d %d %d\n",<br>
-                  dims,<br>
-                  _mesa_lookup_enum_by_nr(<u></u>target), levels,<br>
-                  _mesa_lookup_enum_by_nr(<u></u>internalformat),<br>
-                  width, height, depth);<br>
+   assert(texObj);<br>
<br>
-   if (tex_storage_error_check(ctx, dims, target, levels,<br>
-                               internalformat, width, height, depth)) {<br>
+   if (tex_storage_error_check(ctx, texObj, dims, target, levels,<br>
+                               internalformat, width, height, depth, dsa)) {<br>
        return; /* error was recorded */<br>
     }<br>
<br>
-   texObj = _mesa_get_current_tex_object(<u></u>ctx, target);<br>
-   assert(texObj);<br>
<br>
     texFormat = _mesa_choose_texture_format(<u></u>ctx, texObj, target, 0,<br>
                                             internalformat, GL_NONE, GL_NONE);<br>
@@ -404,7 +394,7 @@ texstorage(GLuint dims, GLenum target, GLsizei levels, GLenum internalformat,<br>
     sizeOK = ctx->Driver.TestProxyTexImage(<u></u>ctx, target, 0, texFormat,<br>
                                            width, height, depth, 0);<br>
<br>
-   if (_mesa_is_proxy_texture(<u></u>texObj->Target)) {<br>
+   if (_mesa_is_proxy_texture(<u></u>target)) {<br>
        if (dimensionsOK && sizeOK) {<br>
           initialize_texture_fields(ctx, texObj, levels, width, height, depth,<br>
                                     internalformat, texFormat);<br>
@@ -417,13 +407,15 @@ texstorage(GLuint dims, GLenum target, GLsizei levels, GLenum internalformat,<br>
     else {<br>
        if (!dimensionsOK) {<br>
           _mesa_error(ctx, GL_INVALID_VALUE,<br>
-                     "glTexStorage%uD(invalid width, height or depth)", dims);<br>
+                     "glTex%sStorage%uD(invalid width, height or depth)",<br>
+                     dsa ? "ture" : "", dims);<br>
           return;<br>
        }<br>
<br>
        if (!sizeOK) {<br>
           _mesa_error(ctx, GL_OUT_OF_MEMORY,<br>
-                     "glTexStorage%uD(texture too large)", dims);<br>
+                     "glTex%sStorage%uD(texture too large)",<br>
+                     dsa ? "ture" : "", dims);<br>
        }<br>
<br>
        assert(levels > 0);<br>
@@ -445,7 +437,8 @@ texstorage(GLuint dims, GLenum target, GLsizei levels, GLenum internalformat,<br>
            * state but this puts things in a consistent state.<br>
            */<br>
           clear_texture_fields(ctx, texObj);<br>
-         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexStorage%uD", dims);<br>
+         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTex%sStorage%uD",<br>
+                     dsa ? "ture" : "", dims);<br>
           return;<br>
        }<br>
<br>
@@ -454,6 +447,94 @@ texstorage(GLuint dims, GLenum target, GLsizei levels, GLenum internalformat,<br>
     }<br>
  }<br>
<br>
+/**<br>
+ * Helper used by _mesa_TexStorage1/2/3D().<br>
+ */<br>
+static void<br>
+texstorage(GLuint dims, GLenum target, GLsizei levels, GLenum internalformat,<br>
+           GLsizei width, GLsizei height, GLsizei depth)<br>
+{<br>
+   struct gl_texture_object *texObj;<br>
+   GET_CURRENT_CONTEXT(ctx);<br>
+<br>
+   /* target check */<br>
+   /* This is done here so that _mesa_texture_storage can receive unsized<br>
+    * formats. */<br>
+   if (!legal_texobj_target(ctx, dims, target)) {<br>
+      _mesa_error(ctx, GL_INVALID_ENUM,<br>
+                  "glTexStorage%uD(illegal target=%s)",<br>
+                  dims, _mesa_lookup_enum_by_nr(<u></u>target));<br>
+      return;<br>
+   }<br>
+<br>
+   if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))<br>
+      _mesa_debug(ctx, "glTexStorage%uD %s %d %s %d %d %d\n",<br>
+                  dims,<br>
+                  _mesa_lookup_enum_by_nr(<u></u>target), levels,<br>
+                  _mesa_lookup_enum_by_nr(<u></u>internalformat),<br>
+                  width, height, depth);<br>
+   /* Check the format to make sure it is sized. */<br>
+   if (!_mesa_is_legal_tex_storage_<u></u>format(ctx, internalformat)) {<br>
+      _mesa_error(ctx, GL_INVALID_ENUM,<br>
+                  "glTexStorage%uD(<u></u>internalformat = %s)", dims,<br>
+                  _mesa_lookup_enum_by_nr(<u></u>internalformat));<br>
+      return;<br>
+   }<br>
+<br>
+   texObj = _mesa_get_current_tex_object(<u></u>ctx, target);<br>
+   if (!texObj)<br>
+      return;<br>
+<br>
+   _mesa_texture_storage(ctx, dims, texObj, target, levels,<br>
+                         internalformat, width, height, depth, false);<br>
+}<br>
+<br>
+/**<br>
+ * Helper used by _mesa_TextureStorage1/2/3D().<br>
+ */<br>
+static void<br>
+texturestorage(GLuint dims, GLuint texture, GLsizei levels,<br>
+               GLenum internalformat, GLsizei width, GLsizei height,<br>
+               GLsizei depth)<br>
+{<br>
+   struct gl_texture_object *texObj;<br>
+   GET_CURRENT_CONTEXT(ctx);<br>
+<br>
+   if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))<br>
+      _mesa_debug(ctx, "glTextureStorage%uD %s %d %s %d %d %d\n",<br>
+                  dims,<br>
+                  _mesa_lookup_enum_by_nr(<u></u>texObj->Target), levels,<br>
+                  _mesa_lookup_enum_by_nr(<u></u>internalformat),<br>
+                  width, height, depth);<br>
+   /* Check the format to make sure it is sized. */<br>
+   if (!_mesa_is_legal_tex_storage_<u></u>format(ctx, internalformat)) {<br>
+      _mesa_error(ctx, GL_INVALID_ENUM,<br>
+                  "glTextureStorage%uD(<u></u>internalformat = %s)", dims,<br>
+                  _mesa_lookup_enum_by_nr(<u></u>internalformat));<br>
+      return;<br>
+   }<br>
+<br>
+   /* Get the texture object by Name. */<br>
+   texObj = _mesa_lookup_texture(ctx, texture);<br>
+   if (!texObj) {<br>
+      _mesa_error(ctx, GL_INVALID_OPERATION,<br>
+                  "glTextureStorage%uD(texture = %d)", dims, texture);<br>
+      return;<br>
+   }<br>
+<br>
+   /* target check */<br>
+   /* This is done here so that _mesa_texture_storage can receive unsized<br>
+    * formats. */<br>
+   if (!legal_texobj_target(ctx, dims, texObj->Target)) {<br>
+      _mesa_error(ctx, GL_INVALID_ENUM,<br>
+                  "glTextureStorage%uD(illegal target=%s)",<br>
+                  dims, _mesa_lookup_enum_by_nr(<u></u>texObj->Target));<br>
+      return;<br>
+   }<br>
+<br>
+   _mesa_texture_storage(ctx, dims, texObj, texObj->Target,<br>
+                         levels, internalformat, width, height, depth, true);<br>
+}<br>
<br>
  void GLAPIENTRY<br>
  _mesa_TexStorage1D(GLenum target, GLsizei levels, GLenum internalformat,<br>
@@ -478,6 +559,28 @@ _mesa_TexStorage3D(GLenum target, GLsizei levels, GLenum internalformat,<br>
     texstorage(3, target, levels, internalformat, width, height, depth);<br>
  }<br>
<br>
+void GLAPIENTRY<br>
+_mesa_TextureStorage1D(GLuint texture, GLsizei levels, GLenum internalformat,<br>
+                       GLsizei width)<br>
+{<br>
+   texturestorage(1, texture, levels, internalformat, width, 1, 1);<br>
+}<br>
+<br>
+<br>
+void GLAPIENTRY<br>
+_mesa_TextureStorage2D(GLuint texture, GLsizei levels,<br>
+                       GLenum internalformat,<br>
+                       GLsizei width, GLsizei height)<br>
+{<br>
+   texturestorage(2, texture, levels, internalformat, width, height, 1);<br>
+}<br>
+<br>
+void GLAPIENTRY<br>
+_mesa_TextureStorage3D(GLuint texture, GLsizei levels, GLenum internalformat,<br>
+                       GLsizei width, GLsizei height, GLsizei depth)<br>
+{<br>
+   texturestorage(3, texture, levels, internalformat, width, height, depth);<br>
+}<br>
<br>
<br>
  /*<br>
diff --git a/src/mesa/main/texstorage.h b/src/mesa/main/texstorage.h<br>
index 79f228c..7de8080 100644<br>
--- a/src/mesa/main/texstorage.h<br>
+++ b/src/mesa/main/texstorage.h<br>
@@ -26,6 +26,24 @@<br>
  #ifndef TEXSTORAGE_H<br>
  #define TEXSTORAGE_H<br>
<br>
+/**<br>
+ * \name Internal functions<br>
+ */<br>
+/*@{*/<br>
+<br>
+extern void<br>
+_mesa_texture_storage( struct gl_context *ctx, GLuint dims,<br>
+                       struct gl_texture_object *texObj,<br>
+                       GLenum target, GLsizei levels,<br>
+                       GLenum internalformat, GLsizei width,<br>
+                       GLsizei height, GLsizei depth, bool dsa );<br>
+<br>
+/*@}*/<br>
+<br>
+/**<br>
+ * \name API functions<br>
+ */<br>
+/*@{*/<br>
<br>
  extern void GLAPIENTRY<br>
  _mesa_TexStorage1D(GLenum target, GLsizei levels, GLenum internalformat,<br>
@@ -41,6 +59,19 @@ extern void GLAPIENTRY<br>
  _mesa_TexStorage3D(GLenum target, GLsizei levels, GLenum internalformat,<br>
                     GLsizei width, GLsizei height, GLsizei depth);<br>
<br>
+extern void GLAPIENTRY<br>
+_mesa_TextureStorage1D(GLuint texture, GLsizei levels, GLenum internalformat,<br>
+                       GLsizei width);<br>
+<br>
+<br>
+extern void GLAPIENTRY<br>
+_mesa_TextureStorage2D(GLuint texture, GLsizei levels, GLenum internalformat,<br>
+                       GLsizei width, GLsizei height);<br>
+<br>
+<br>
+extern void GLAPIENTRY<br>
+_mesa_TextureStorage3D(GLuint texture, GLsizei levels, GLenum internalformat,<br>
+                       GLsizei width, GLsizei height, GLsizei depth);<br>
<br>
<br>
  extern void GLAPIENTRY<br>
<br>
</blockquote>
<br>
</div></div></blockquote></div></div>