diff options
author | Ian Romanick <[email protected]> | 2012-08-13 13:14:25 -0700 |
---|---|---|
committer | Ian Romanick <[email protected]> | 2012-08-14 14:39:33 -0700 |
commit | 07e12c49175e0bf23dbd8bdc3afd7aa79ccc7140 (patch) | |
tree | 2f829ad01711cdd5d3adb5366d285af57c70ab7e /src | |
parent | f241ffd48c2063557461f5b7bb2dea0b744b8bef (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')
-rw-r--r-- | src/mesa/main/api_exec.c | 6 | ||||
-rw-r--r-- | src/mesa/main/texobj.c | 211 | ||||
-rw-r--r-- | src/mesa/main/texobj.h | 8 |
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); + /*@}*/ |