summaryrefslogtreecommitdiffstats
path: root/src/mesa
diff options
context:
space:
mode:
authorIan Romanick <[email protected]>2012-08-13 13:14:25 -0700
committerIan Romanick <[email protected]>2012-08-14 14:39:33 -0700
commit07e12c49175e0bf23dbd8bdc3afd7aa79ccc7140 (patch)
tree2f829ad01711cdd5d3adb5366d285af57c70ab7e /src/mesa
parentf241ffd48c2063557461f5b7bb2dea0b744b8bef (diff)
mesa: Add skeleton implementations of glInvalidateTex{Sub,}Image
These are part of GL_ARB_invalidate_subdata (but not OpenGL ES 3.0). v2: Add comment explaining why minimum dimensions are set to 1 for some texture targets. Add default case to switch statement to silence compiler warnings and detect new texture targets. Both changes suggested by Brian. Also use _mesa_is_desktop_gl as suggested by Ken. Signed-off-by: Ian Romanick <[email protected]> Reviewed-by: Brian Paul <[email protected]> Reviewed-by: Kenneth Graunke <[email protected]>
Diffstat (limited to 'src/mesa')
-rw-r--r--src/mesa/main/api_exec.c6
-rw-r--r--src/mesa/main/texobj.c211
-rw-r--r--src/mesa/main/texobj.h8
3 files changed, 225 insertions, 0 deletions
diff --git a/src/mesa/main/api_exec.c b/src/mesa/main/api_exec.c
index bb5d17131ca..6b1499f4f06 100644
--- a/src/mesa/main/api_exec.c
+++ b/src/mesa/main/api_exec.c
@@ -827,10 +827,16 @@ _mesa_create_exec_table(struct gl_context *ctx)
_mesa_init_sampler_object_dispatch(exec);
#endif
+ if (_mesa_is_desktop_gl(ctx)) {
+ SET_InvalidateTexSubImage(exec, _mesa_InvalidateTexSubImage);
+ SET_InvalidateTexImage(exec, _mesa_InvalidateTexImage);
+ }
+
if (_mesa_is_desktop_gl(ctx) || _mesa_is_gles3(ctx)) {
SET_InvalidateSubFramebuffer(exec, _mesa_InvalidateSubFramebuffer);
SET_InvalidateFramebuffer(exec, _mesa_InvalidateFramebuffer);
}
+
return exec;
}
diff --git a/src/mesa/main/texobj.c b/src/mesa/main/texobj.c
index 02e37bebc5e..1d905b608c4 100644
--- a/src/mesa/main/texobj.c
+++ b/src/mesa/main/texobj.c
@@ -877,7 +877,58 @@ _mesa_total_texture_memory(struct gl_context *ctx)
return total;
}
+static struct gl_texture_object *
+invalidate_tex_image_error_check(struct gl_context *ctx, GLuint texture,
+ GLint level, const char *name)
+{
+ /* The GL_ARB_invalidate_subdata spec says:
+ *
+ * "If <texture> is zero or is not the name of a texture, the error
+ * INVALID_VALUE is generated."
+ *
+ * This performs the error check in a different order than listed in the
+ * spec. We have to get the texture object before we can validate the
+ * other parameters against values in the texture object.
+ */
+ struct gl_texture_object *const t = _mesa_lookup_texture(ctx, texture);
+ if (texture == 0 || t == NULL) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "%s(texture)", name);
+ return NULL;
+ }
+ /* The GL_ARB_invalidate_subdata spec says:
+ *
+ * "If <level> is less than zero or greater than the base 2 logarithm
+ * of the maximum texture width, height, or depth, the error
+ * INVALID_VALUE is generated."
+ */
+ if (level < 0 || level > t->MaxLevel) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "%s(level)", name);
+ return NULL;
+ }
+
+ /* The GL_ARB_invalidate_subdata spec says:
+ *
+ * "If the target of <texture> is TEXTURE_RECTANGLE, TEXTURE_BUFFER,
+ * TEXTURE_2D_MULTISAMPLE, or TEXTURE_2D_MULTISAMPLE_ARRAY, and <level>
+ * is not zero, the error INVALID_VALUE is generated."
+ */
+ if (level != 0) {
+ switch (t->Target) {
+ case GL_TEXTURE_RECTANGLE:
+ case GL_TEXTURE_BUFFER:
+ case GL_TEXTURE_2D_MULTISAMPLE:
+ case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
+ _mesa_error(ctx, GL_INVALID_VALUE, "%s(level)", name);
+ return NULL;
+
+ default:
+ break;
+ }
+ }
+
+ return t;
+}
/*@}*/
@@ -1346,4 +1397,164 @@ _mesa_unlock_context_textures( struct gl_context *ctx )
_glthread_UNLOCK_MUTEX(ctx->Shared->TexMutex);
}
+void GLAPIENTRY
+_mesa_InvalidateTexSubImage(GLuint texture, GLint level, GLint xoffset,
+ GLint yoffset, GLint zoffset, GLsizei width,
+ GLsizei height, GLsizei depth)
+{
+ struct gl_texture_object *t;
+ struct gl_texture_image *image;
+ GET_CURRENT_CONTEXT(ctx);
+
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ t = invalidate_tex_image_error_check(ctx, texture, level,
+ "glInvalidateTexSubImage");
+
+ /* The GL_ARB_invalidate_subdata spec says:
+ *
+ * "...the specified subregion must be between -<b> and <dim>+<b> where
+ * <dim> is the size of the dimension of the texture image, and <b> is
+ * the size of the border of that texture image, otherwise
+ * INVALID_VALUE is generated (border is not applied to dimensions that
+ * don't exist in a given texture target)."
+ */
+ image = t->Image[0][level];
+ if (image) {
+ int xBorder;
+ int yBorder;
+ int zBorder;
+ int imageWidth;
+ int imageHeight;
+ int imageDepth;
+
+ /* The GL_ARB_invalidate_subdata spec says:
+ *
+ * "For texture targets that don't have certain dimensions, this
+ * command treats those dimensions as having a size of 1. For
+ * example, to invalidate a portion of a two-dimensional texture,
+ * the application would use <zoffset> equal to zero and <depth>
+ * equal to one."
+ */
+ switch (t->Target) {
+ case GL_TEXTURE_BUFFER:
+ xBorder = 0;
+ yBorder = 0;
+ zBorder = 0;
+ imageWidth = 1;
+ imageHeight = 1;
+ imageDepth = 1;
+ break;
+ case GL_TEXTURE_1D:
+ xBorder = image->Border;
+ yBorder = 0;
+ zBorder = 0;
+ imageWidth = image->Width;
+ imageHeight = 1;
+ imageDepth = 1;
+ break;
+ case GL_TEXTURE_1D_ARRAY:
+ xBorder = image->Border;
+ yBorder = 0;
+ zBorder = 0;
+ imageWidth = image->Width;
+ imageHeight = image->Height;
+ imageDepth = 1;
+ break;
+ case GL_TEXTURE_2D:
+ case GL_TEXTURE_CUBE_MAP:
+ case GL_TEXTURE_RECTANGLE:
+ case GL_TEXTURE_2D_MULTISAMPLE:
+ xBorder = image->Border;
+ yBorder = image->Border;
+ zBorder = 0;
+ imageWidth = image->Width;
+ imageHeight = image->Height;
+ imageDepth = 1;
+ break;
+ case GL_TEXTURE_2D_ARRAY:
+ case GL_TEXTURE_CUBE_MAP_ARRAY:
+ xBorder = image->Border;
+ yBorder = image->Border;
+ zBorder = 0;
+ imageWidth = image->Width;
+ imageHeight = image->Height;
+ imageDepth = image->Depth;
+ break;
+ case GL_TEXTURE_3D:
+ xBorder = image->Border;
+ yBorder = image->Border;
+ zBorder = image->Border;
+ imageWidth = image->Width;
+ imageHeight = image->Height;
+ imageDepth = image->Depth;
+ break;
+ default:
+ assert(!"Should not get here.");
+ xBorder = 0;
+ yBorder = 0;
+ zBorder = 0;
+ imageWidth = 0;
+ imageHeight = 0;
+ imageDepth = 0;
+ break;
+ }
+
+ if (xoffset < -xBorder) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glInvalidateSubTexImage(xoffset)");
+ return;
+ }
+
+ if (xoffset + width > imageWidth + xBorder) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glInvalidateSubTexImage(xoffset+width)");
+ return;
+ }
+
+ if (yoffset < -yBorder) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glInvalidateSubTexImage(yoffset)");
+ return;
+ }
+
+ if (yoffset + height > imageHeight + yBorder) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glInvalidateSubTexImage(yoffset+height)");
+ return;
+ }
+
+ if (zoffset < -zBorder) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glInvalidateSubTexImage(zoffset)");
+ return;
+ }
+
+ if (zoffset + depth > imageDepth + zBorder) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glInvalidateSubTexImage(zoffset+depth)");
+ return;
+ }
+ }
+
+ /* We don't actually do anything for this yet. Just return after
+ * validating the parameters and generating the required errors.
+ */
+ return;
+}
+
+void GLAPIENTRY
+_mesa_InvalidateTexImage(GLuint texture, GLint level)
+{
+ GET_CURRENT_CONTEXT(ctx);
+
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ invalidate_tex_image_error_check(ctx, texture, level,
+ "glInvalidateTexImage");
+
+ /* We don't actually do anything for this yet. Just return after
+ * validating the parameters and generating the required errors.
+ */
+ return;
+}
+
/*@}*/
diff --git a/src/mesa/main/texobj.h b/src/mesa/main/texobj.h
index 23e1ade090c..93e0d77382e 100644
--- a/src/mesa/main/texobj.h
+++ b/src/mesa/main/texobj.h
@@ -152,6 +152,14 @@ _mesa_AreTexturesResident( GLsizei n, const GLuint *textures,
extern GLboolean GLAPIENTRY
_mesa_IsTexture( GLuint texture );
+extern void GLAPIENTRY
+_mesa_InvalidateTexSubImage(GLuint texture, GLint level, GLint xoffset,
+ GLint yoffset, GLint zoffset, GLsizei width,
+ GLsizei height, GLsizei depth);
+
+extern void GLAPIENTRY
+_mesa_InvalidateTexImage(GLuint texture, GLint level);
+
/*@}*/