[Mesa-dev] [PATCH 7/8] mesa: Add skeleton implementations of glInvalidateTex{Sub, }Image
Ian Romanick
idr at freedesktop.org
Tue Aug 14 10:37:26 PDT 2012
On 08/13/2012 08:01 PM, Brian Paul wrote:
> On Mon, Aug 13, 2012 at 7:24 PM, Ian Romanick <idr at freedesktop.org> wrote:
>> From: Ian Romanick <ian.d.romanick at intel.com>
>>
>> These are part of GL_ARB_invalidate_subdata (but not OpenGL ES 3.0).
>>
>> Signed-off-by: Ian Romanick <ian.d.romanick at intel.com>
>> ---
>> src/mesa/main/api_exec.c | 5 +
>> src/mesa/main/texobj.c | 194 ++++++++++++++++++++++++++++++++++++++++++++++
>> src/mesa/main/texobj.h | 8 ++
>> 3 files changed, 207 insertions(+), 0 deletions(-)
>>
>> diff --git a/src/mesa/main/api_exec.c b/src/mesa/main/api_exec.c
>> index 66c4a67..59a9aeb 100644
>> --- a/src/mesa/main/api_exec.c
>> +++ b/src/mesa/main/api_exec.c
>> @@ -827,6 +827,11 @@ _mesa_create_exec_table(struct gl_context *ctx)
>> _mesa_init_sampler_object_dispatch(exec);
>> #endif
>>
>> + if (ctx->API == API_OPENGL || ctx->API == API_OPENGL_CORE) {
>> + SET_InvalidateTexSubImage(exec, _mesa_InvalidateTexSubImage);
>> + SET_InvalidateTexImage(exec, _mesa_InvalidateTexImage);
>> + }
>> +
>> if (ctx->API == API_OPENGL || ctx->API == API_OPENGL_CORE
>> || (ctx->API == API_OPENGLES2 && ctx->Version >= 30)) {
>> SET_InvalidateSubFramebuffer(exec, _mesa_InvalidateSubFramebuffer);
>> diff --git a/src/mesa/main/texobj.c b/src/mesa/main/texobj.c
>> index 02e37be..36ad7c6 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,147 @@ _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;
>> +
>> + switch (t->Target) {
>> + case GL_TEXTURE_BUFFER:
>> + xBorder = 0;
>> + yBorder = 0;
>> + zBorder = 0;
>> + imageWidth = 1;
>> + imageHeight = 1;
>> + imageDepth = 1;
>
> I haven't checked the spec yet, but is imageWidth=1 right? It looks
> peculiar. Maybe add a comment?
I'll add the following comment block before the switch-statement:
/* 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."
*/
>> + 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;
>> + }
>
> I think there should be a default case above, both to catch potential
> oversights when new texture targets are added and because I think some
> compilers will complain about unitialized values for the border and
> size vars.
Good idea.
>> +
>> + 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 23e1ade..93e0d77 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);
>> +
>> /*@}*/
>>
More information about the mesa-dev
mailing list