<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>