[Mesa-dev] [PATCH 4/8] mesa: Add skeleton implementations of glInvalidate{Sub, }Framebuffer

Kenneth Graunke kenneth at whitecape.org
Tue Aug 14 12:46:48 PDT 2012


On 08/13/2012 06:23 PM, Ian Romanick wrote:
> From: Ian Romanick <ian.d.romanick at intel.com>
> 
> These are part of GL_ARB_invalidate_subdata and 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/fbobject.c |  141 ++++++++++++++++++++++++++++++++++++++++++++++
>  src/mesa/main/fbobject.h |    9 +++
>  3 files changed, 155 insertions(+), 0 deletions(-)
> 
> diff --git a/src/mesa/main/api_exec.c b/src/mesa/main/api_exec.c
> index f366f5f..51fb520 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
> +       || (ctx->API == API_OPENGLES2 && ctx->Version >= 30)) {

You can use _mesa_is_desktop_gl(ctx) here.  It might be nice to add a
_mesa_is_gles3 inline function as well.  Then this could be:

if (_mesa_is_desktop_gl(ctx) || _mesa_is_gles3(ctx)) {

...which is easier to read/write.

> +      SET_InvalidateSubFramebuffer(exec, _mesa_InvalidateSubFramebuffer);
> +      SET_InvalidateFramebuffer(exec, _mesa_InvalidateFramebuffer);
> +   }
>     return exec;
>  }
>  
> diff --git a/src/mesa/main/fbobject.c b/src/mesa/main/fbobject.c
> index d558d7f..4dbc349 100644
> --- a/src/mesa/main/fbobject.c
> +++ b/src/mesa/main/fbobject.c
> @@ -3006,3 +3006,144 @@ _mesa_FramebufferTextureFaceARB(GLenum target, GLenum attachment,
>                 "not implemented!");
>  }
>  #endif /* FEATURE_ARB_geometry_shader4 */
> +
> +static void
> +invalidate_framebuffer_storage(GLenum target, GLsizei numAttachments,
> +                               const GLenum *attachments, GLint x, GLint y,
> +                               GLsizei width, GLsizei height, const char *name)
> +{
> +   int i;
> +   struct gl_framebuffer *fb;
> +   GET_CURRENT_CONTEXT(ctx);
> +
> +   ASSERT_OUTSIDE_BEGIN_END(ctx);
> +
> +   fb = get_framebuffer_target(ctx, target);
> +   if (!fb) {
> +      _mesa_error(ctx, GL_INVALID_ENUM, "%s(target)", name);
> +      return;
> +   }
> +
> +   if (numAttachments < 0) {
> +      _mesa_error(ctx, GL_INVALID_VALUE,
> +                  "%s(numAttachments < 0)", name);
> +      return;
> +   }
> +
> +   /* The GL_ARB_invalidate_subdata spec says:
> +    *
> +    *     "If an attachment is specified that does not exist in the
> +    *     framebuffer bound to <target>, it is ignored."
> +    *
> +    * It also says:
> +    *
> +    *     "If <attachments> contains COLOR_ATTACHMENTm and m is greater than
> +    *     or equal to the value of MAX_COLOR_ATTACHMENTS, then the error
> +    *     INVALID_OPERATION is generated."
> +    *
> +    * No mention is made of GL_AUXi being out of range.  Therefore, we allow
> +    * any enum that can be allowed by the API (OpenGL ES 3.0 has a different
> +    * set of retrictions).
> +    */
> +   for (i = 0; i < numAttachments; i++) {
> +      if (_mesa_is_winsys_fbo(fb)) {
> +         switch (attachments[i]) {
> +         case GL_ACCUM:
> +            /* Accumulation buffers were removed in OpenGL 3.1, and they never
> +             * exited in OpenGL ES.

"existed" (typo)

> +             */
> +            if (ctx->API != API_OPENGL)
> +               goto invalid_enum;
> +            break;
> +         case GL_COLOR:
> +         case GL_DEPTH:
> +         case GL_STENCIL:
> +            break;
> +         case GL_AUX0:
> +         case GL_AUX1:
> +         case GL_AUX2:
> +         case GL_AUX3:

AUX buffers are gone in core, so they should be treated like accum
buffers above.

> +         case GL_BACK_LEFT:
> +         case GL_BACK_RIGHT:
> +         case GL_FRONT_LEFT:
> +         case GL_FRONT_RIGHT:
> +            if (ctx->API != API_OPENGL && ctx->API != API_OPENGL_CORE)

if (_mesa_is_desktop_gl(ctx))

Otherwise,
Reviewed-by: Kenneth Graunke <kenneth at whitecape.org>

> +               goto invalid_enum;
> +            break;
> +         default:
> +            goto invalid_enum;
> +         }
> +      } else {
> +         switch (attachments[i]) {
> +         case GL_DEPTH_ATTACHMENT:
> +         case GL_STENCIL_ATTACHMENT:
> +            break;
> +         case GL_COLOR_ATTACHMENT0:
> +         case GL_COLOR_ATTACHMENT1:
> +         case GL_COLOR_ATTACHMENT2:
> +         case GL_COLOR_ATTACHMENT3:
> +         case GL_COLOR_ATTACHMENT4:
> +         case GL_COLOR_ATTACHMENT5:
> +         case GL_COLOR_ATTACHMENT6:
> +         case GL_COLOR_ATTACHMENT7:
> +         case GL_COLOR_ATTACHMENT8:
> +         case GL_COLOR_ATTACHMENT9:
> +         case GL_COLOR_ATTACHMENT10:
> +         case GL_COLOR_ATTACHMENT11:
> +         case GL_COLOR_ATTACHMENT12:
> +         case GL_COLOR_ATTACHMENT13:
> +         case GL_COLOR_ATTACHMENT14:
> +         case GL_COLOR_ATTACHMENT15: {
> +            const int k = attachments[i] - GL_COLOR_ATTACHMENT0;
> +            if (k >= ctx->Const.MaxColorAttachments) {
> +               _mesa_error(ctx, GL_INVALID_OPERATION,
> +                           "%s(attachment >= max. color attachments)", name);
> +               return;
> +            }
> +         }
> +         default:
> +            goto invalid_enum;
> +         }
> +      }
> +   }
> +
> +   /* We don't actually do anything for this yet.  Just return after
> +    * validating the parameters and generating the required errors.
> +    */
> +   return;
> +
> +invalid_enum:
> +   _mesa_error(ctx, GL_INVALID_ENUM, "%s(attachment)", name);
> +   return;
> +}
> +
> +void GLAPIENTRY
> +_mesa_InvalidateSubFramebuffer(GLenum target, GLsizei numAttachments,
> +                               const GLenum *attachments, GLint x, GLint y,
> +                               GLsizei width, GLsizei height)
> +{
> +   invalidate_framebuffer_storage(target, numAttachments, attachments,
> +                                  x, y, width, height,
> +                                  "glInvalidateSubFramebuffer");
> +}
> +
> +void GLAPIENTRY
> +_mesa_InvalidateFramebuffer(GLenum target, GLsizei numAttachments,
> +                            const GLenum *attachments)
> +{
> +   /* The GL_ARB_invalidate_subdata spec says:
> +    *
> +    *     "The command
> +    *
> +    *        void InvalidateFramebuffer(enum target,
> +    *                                   sizei numAttachments,
> +    *                                   const enum *attachments);
> +    *
> +    *     is equivalent to the command InvalidateSubFramebuffer with <x>, <y>,
> +    *     <width>, <height> equal to 0, 0, <MAX_VIEWPORT_DIMS[0]>,
> +    *     <MAX_VIEWPORT_DIMS[1]> respectively."
> +    */
> +   invalidate_framebuffer_storage(target, numAttachments, attachments,
> +                                  0, 0, MAX_VIEWPORT_WIDTH, MAX_VIEWPORT_HEIGHT,
> +                                  "glInvalidateFramebuffer");
> +}
> diff --git a/src/mesa/main/fbobject.h b/src/mesa/main/fbobject.h
> index 3aee842..9cded3c 100644
> --- a/src/mesa/main/fbobject.h
> +++ b/src/mesa/main/fbobject.h
> @@ -214,4 +214,13 @@ _mesa_FramebufferTextureFaceARB(GLenum target, GLenum attachment,
>                                  GLuint texture, GLint level, GLenum face);
>  
>  
> +extern void GLAPIENTRY
> +_mesa_InvalidateSubFramebuffer(GLenum target, GLsizei numAttachments,
> +                               const GLenum *attachments, GLint x, GLint y,
> +                               GLsizei width, GLsizei height);
> +
> +extern void GLAPIENTRY
> +_mesa_InvalidateFramebuffer(GLenum target, GLsizei numAttachments,
> +                            const GLenum *attachments);
> +
>  #endif /* FBOBJECT_H */
> 



More information about the mesa-dev mailing list