[Mesa-dev] [PATCH] mesa: move _mesa_valid_to_render() to api_validate.c

Anuj Phogat anuj.phogat at gmail.com
Fri Sep 30 21:46:11 UTC 2016


On Fri, Sep 30, 2016 at 2:21 PM, Brian Paul <brianp at vmware.com> wrote:

> Almost all of the other drawing validation code is in api_validate.c
> so put this function there as well.
> ---
>  src/mesa/main/api_validate.c | 191 ++++++++++++++++++++++++++++++
> ++++++++++++-
>  src/mesa/main/api_validate.h |   3 +
>  src/mesa/main/context.c      | 188 +-----------------------------
> ------------
>  src/mesa/main/context.h      |   3 -
>  src/mesa/main/drawpix.c      |   1 +
>  5 files changed, 195 insertions(+), 191 deletions(-)
>
> diff --git a/src/mesa/main/api_validate.c b/src/mesa/main/api_validate.c
> index 6cb626a..05691d2 100644
> --- a/src/mesa/main/api_validate.c
> +++ b/src/mesa/main/api_validate.c
> @@ -30,9 +30,198 @@
>  #include "context.h"
>  #include "imports.h"
>  #include "mtypes.h"
> +#include "pipelineobj.h"
>  #include "enums.h"
> -#include "vbo/vbo.h"
> +#include "state.h"
>  #include "transformfeedback.h"
> +#include "uniforms.h"
> +#include "vbo/vbo.h"
> +#include "program/prog_print.h"
> +
> +
> +static bool
> +check_blend_func_error(struct gl_context *ctx)
> +{
> +   /* The ARB_blend_func_extended spec's ERRORS section says:
> +    *
> +    *    "The error INVALID_OPERATION is generated by Begin or any
> procedure
> +    *     that implicitly calls Begin if any draw buffer has a blend
> function
> +    *     requiring the second color input (SRC1_COLOR,
> ONE_MINUS_SRC1_COLOR,
> +    *     SRC1_ALPHA or ONE_MINUS_SRC1_ALPHA), and a framebuffer is bound
> that
> +    *     has more than the value of MAX_DUAL_SOURCE_DRAW_BUFFERS-1 active
> +    *     color attachements."
> +    */
> +   for (unsigned i = ctx->Const.MaxDualSourceDrawBuffers;
> +       i < ctx->DrawBuffer->_NumColorDrawBuffers;
> +       i++) {
> +      if (ctx->Color.Blend[i]._UsesDualSrc) {
> +        _mesa_error(ctx, GL_INVALID_OPERATION,
> +                    "dual source blend on illegal attachment");
> +        return false;
> +      }
> +   }
> +
> +   if (ctx->Color.BlendEnabled && ctx->Color._AdvancedBlendMode) {
> +      /* The KHR_blend_equation_advanced spec says:
> +       *
> +       *    "If any non-NONE draw buffer uses a blend equation found in
> table
> +       *     X.1 or X.2, the error INVALID_OPERATION is generated by
> Begin or
> +       *     any operation that implicitly calls Begin (such as
> DrawElements)
> +       *     if:
> +       *
> +       *       * the draw buffer for color output zero selects multiple
> color
> +       *         buffers (e.g., FRONT_AND_BACK in the default
> framebuffer); or
> +       *
> +       *       * the draw buffer for any other color output is not NONE."
> +       */
> +      if (ctx->DrawBuffer->ColorDrawBuffer[0] == GL_FRONT_AND_BACK) {
> +         _mesa_error(ctx, GL_INVALID_OPERATION,
> +                     "advanced blending is active and draw buffer for
> color "
> +                     "output zero selects multiple color buffers");
> +         return false;
> +      }
> +
> +      for (unsigned i = 1; i < ctx->DrawBuffer->_NumColorDrawBuffers;
> i++) {
> +         if (ctx->DrawBuffer->ColorDrawBuffer[i] != GL_NONE) {
> +            _mesa_error(ctx, GL_INVALID_OPERATION,
> +                        "advanced blending is active with multiple color "
> +                        "draw buffers");
> +            return false;
> +         }
> +      }
> +
> +      /* The KHR_blend_equation_advanced spec says:
> +       *
> +       *    "Advanced blending equations require the use of a fragment
> shader
> +       *     with a matching "blend_support" layout qualifier.  If the
> current
> +       *     blend equation is found in table X.1 or X.2, and the active
> +       *     fragment shader does not include the layout qualifier
> matching
> +       *     the blend equation or "blend_support_all_equations", the
> error
> +       *     INVALID_OPERATION is generated [...]"
> +       */
> +      const struct gl_shader_program *sh_prog =
> +         ctx->_Shader->_CurrentFragmentProgram;
> +      const GLbitfield blend_support = !sh_prog ? 0 :
> +         sh_prog->_LinkedShaders[MESA_SHADER_FRAGMENT]->info.
> BlendSupport;
> +
> +      if ((blend_support & ctx->Color._AdvancedBlendMode) == 0) {
> +         _mesa_error(ctx, GL_INVALID_OPERATION,
> +                     "fragment shader does not allow advanced blending
> mode "
> +                     "(%s)",
> +                      _mesa_enum_to_string(ctx->
> Color.Blend[0].EquationRGB));
> +      }
> +   }
> +
> +   return true;
> +}
> +
> +
> +/**
> + * Prior to drawing anything with glBegin, glDrawArrays, etc. this
> function
> + * is called to see if it's valid to render.  This involves checking that
> + * the current shader is valid and the framebuffer is complete.
> + * It also check the current pipeline object is valid if any.
> + * If an error is detected it'll be recorded here.
> + * \return GL_TRUE if OK to render, GL_FALSE if not
> + */
> +GLboolean
> +_mesa_valid_to_render(struct gl_context *ctx, const char *where)
> +{
> +   /* This depends on having up to date derived state (shaders) */
> +   if (ctx->NewState)
> +      _mesa_update_state(ctx);
> +
> +   if (ctx->API == API_OPENGL_COMPAT) {
> +      /* Any shader stages that are not supplied by the GLSL shader and
> have
> +       * assembly shaders enabled must now be validated.
> +       */
> +      if (!ctx->_Shader->CurrentProgram[MESA_SHADER_VERTEX]
> +          && ctx->VertexProgram.Enabled && !ctx->VertexProgram._Enabled) {
> +         _mesa_error(ctx, GL_INVALID_OPERATION,
> +                     "%s(vertex program not valid)", where);
> +         return GL_FALSE;
> +      }
> +
> +      if (!ctx->_Shader->CurrentProgram[MESA_SHADER_FRAGMENT]) {
> +         if (ctx->FragmentProgram.Enabled && !ctx->FragmentProgram._Enabled)
> {
> +            _mesa_error(ctx, GL_INVALID_OPERATION,
> +                        "%s(fragment program not valid)", where);
> +            return GL_FALSE;
> +         }
> +
> +         /* If drawing to integer-valued color buffers, there must be an
> +          * active fragment shader (GL_EXT_texture_integer).
> +          */
> +         if (ctx->DrawBuffer && ctx->DrawBuffer->_IntegerColor) {
> +            _mesa_error(ctx, GL_INVALID_OPERATION,
> +                        "%s(integer format but no fragment shader)",
> where);
> +            return GL_FALSE;
> +         }
> +      }
> +   }
> +
> +   /* A pipeline object is bound */
> +   if (ctx->_Shader->Name && !ctx->_Shader->Validated) {
> +      if (!_mesa_validate_program_pipeline(ctx, ctx->_Shader)) {
> +         _mesa_error(ctx, GL_INVALID_OPERATION,
> +                     "glValidateProgramPipeline failed to validate the "
> +                     "pipeline");
> +         return GL_FALSE;
> +      }
> +   }
> +
> +   /* If a program is active and SSO not in use, check if validation of
> +    * samplers succeeded for the active program. */
> +   if (ctx->_Shader->ActiveProgram && ctx->_Shader !=
> ctx->Pipeline.Current) {
> +      char errMsg[100];
> +      if (!_mesa_sampler_uniforms_are_valid(ctx->_Shader->ActiveProgram,
> +                                            errMsg, 100)) {
> +         _mesa_error(ctx, GL_INVALID_OPERATION, "%s", errMsg);
> +         return GL_FALSE;
> +      }
> +   }
> +
> +   if (ctx->DrawBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
> +      _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT,
> +                  "%s(incomplete framebuffer)", where);
> +      return GL_FALSE;
> +   }
> +
> +   if (!check_blend_func_error(ctx)) {
> +      return GL_FALSE;
> +   }
> +
> +#ifdef DEBUG
> +   if (ctx->_Shader->Flags & GLSL_LOG) {
> +      struct gl_shader_program **shProg = ctx->_Shader->CurrentProgram;
> +      gl_shader_stage i;
> +
> +      for (i = 0; i < MESA_SHADER_STAGES; i++) {
> +        if (shProg[i] == NULL || shProg[i]->_Used
> +            || shProg[i]->_LinkedShaders[i] == NULL)
> +           continue;
> +
> +        /* This is the first time this shader is being used.
> +         * Append shader's constants/uniforms to log file.
> +         *
> +         * Only log data for the program target that matches the shader
> +         * target.  It's possible to have a program bound to the vertex
> +         * shader target that also supplied a fragment shader.  If that
> +         * program isn't also bound to the fragment shader target we don't
> +         * want to log its fragment data.
> +         */
> +        _mesa_append_uniforms_to_file(shProg[i]->_LinkedShaders[i]);
> +      }
> +
> +      for (i = 0; i < MESA_SHADER_STAGES; i++) {
> +        if (shProg[i] != NULL)
> +           shProg[i]->_Used = GL_TRUE;
> +      }
> +   }
> +#endif
> +
> +   return GL_TRUE;
> +}
>
>
>  /**
> diff --git a/src/mesa/main/api_validate.h b/src/mesa/main/api_validate.h
> index 5b321e3..2eba834 100644
> --- a/src/mesa/main/api_validate.h
> +++ b/src/mesa/main/api_validate.h
> @@ -35,6 +35,9 @@ struct gl_context;
>  struct gl_transform_feedback_object;
>
>
> +extern GLboolean
> +_mesa_valid_to_render(struct gl_context *ctx, const char *where);
> +
>  extern bool
>  _mesa_is_valid_prim_mode(struct gl_context *ctx, GLenum mode);
>
> diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c
> index f550b0c..697b518 100644
> --- a/src/mesa/main/context.c
> +++ b/src/mesa/main/context.c
> @@ -122,7 +122,6 @@
>  #include "shaderobj.h"
>  #include "shaderimage.h"
>  #include "util/strtod.h"
> -#include "state.h"
>  #include "stencil.h"
>  #include "texcompress_s3tc.h"
>  #include "texstate.h"
> @@ -131,18 +130,16 @@
>  #include "varray.h"
>  #include "version.h"
>  #include "viewport.h"
> -#include "vtxfmt.h"
>  #include "program/program.h"
> -#include "program/prog_print.h"
>  #include "math/m_matrix.h"
>  #include "main/dispatch.h" /* for _gloffset_COUNT */
> -#include "uniforms.h"
>  #include "macros.h"
>
>  #ifdef USE_SPARC_ASM
>  #include "sparc/sparc.h"
>  #endif
>
> +#include "compiler/glsl_types.h"
>  #include "compiler/glsl/glsl_parser_extras.h"
>  #include <stdbool.h>
>
> @@ -1857,189 +1854,6 @@ _mesa_Flush(void)
>  }
>
>
> -static bool
> -check_blend_func_error(struct gl_context *ctx)
> -{
> -   /* The ARB_blend_func_extended spec's ERRORS section says:
> -    *
> -    *    "The error INVALID_OPERATION is generated by Begin or any
> procedure
> -    *     that implicitly calls Begin if any draw buffer has a blend
> function
> -    *     requiring the second color input (SRC1_COLOR,
> ONE_MINUS_SRC1_COLOR,
> -    *     SRC1_ALPHA or ONE_MINUS_SRC1_ALPHA), and a framebuffer is bound
> that
> -    *     has more than the value of MAX_DUAL_SOURCE_DRAW_BUFFERS-1 active
> -    *     color attachements."
> -    */
> -   for (unsigned i = ctx->Const.MaxDualSourceDrawBuffers;
> -       i < ctx->DrawBuffer->_NumColorDrawBuffers;
> -       i++) {
> -      if (ctx->Color.Blend[i]._UsesDualSrc) {
> -        _mesa_error(ctx, GL_INVALID_OPERATION,
> -                    "dual source blend on illegal attachment");
> -        return false;
> -      }
> -   }
> -
> -   if (ctx->Color.BlendEnabled && ctx->Color._AdvancedBlendMode) {
> -      /* The KHR_blend_equation_advanced spec says:
> -       *
> -       *    "If any non-NONE draw buffer uses a blend equation found in
> table
> -       *     X.1 or X.2, the error INVALID_OPERATION is generated by
> Begin or
> -       *     any operation that implicitly calls Begin (such as
> DrawElements)
> -       *     if:
> -       *
> -       *       * the draw buffer for color output zero selects multiple
> color
> -       *         buffers (e.g., FRONT_AND_BACK in the default
> framebuffer); or
> -       *
> -       *       * the draw buffer for any other color output is not NONE."
> -       */
> -      if (ctx->DrawBuffer->ColorDrawBuffer[0] == GL_FRONT_AND_BACK) {
> -         _mesa_error(ctx, GL_INVALID_OPERATION,
> -                     "advanced blending is active and draw buffer for
> color "
> -                     "output zero selects multiple color buffers");
> -         return false;
> -      }
> -
> -      for (unsigned i = 1; i < ctx->DrawBuffer->_NumColorDrawBuffers;
> i++) {
> -         if (ctx->DrawBuffer->ColorDrawBuffer[i] != GL_NONE) {
> -            _mesa_error(ctx, GL_INVALID_OPERATION,
> -                        "advanced blending is active with multiple color "
> -                        "draw buffers");
> -            return false;
> -         }
> -      }
> -
> -      /* The KHR_blend_equation_advanced spec says:
> -       *
> -       *    "Advanced blending equations require the use of a fragment
> shader
> -       *     with a matching "blend_support" layout qualifier.  If the
> current
> -       *     blend equation is found in table X.1 or X.2, and the active
> -       *     fragment shader does not include the layout qualifier
> matching
> -       *     the blend equation or "blend_support_all_equations", the
> error
> -       *     INVALID_OPERATION is generated [...]"
> -       */
> -      const struct gl_shader_program *sh_prog =
> -         ctx->_Shader->_CurrentFragmentProgram;
> -      const GLbitfield blend_support = !sh_prog ? 0 :
> -         sh_prog->_LinkedShaders[MESA_SHADER_FRAGMENT]->info.
> BlendSupport;
> -
> -      if ((blend_support & ctx->Color._AdvancedBlendMode) == 0) {
> -         _mesa_error(ctx, GL_INVALID_OPERATION,
> -                     "fragment shader does not allow advanced blending
> mode "
> -                     "(%s)",
> -                      _mesa_enum_to_string(ctx->
> Color.Blend[0].EquationRGB));
> -      }
> -   }
> -
> -   return true;
> -}
> -
> -
> -/**
> - * Prior to drawing anything with glBegin, glDrawArrays, etc. this
> function
> - * is called to see if it's valid to render.  This involves checking that
> - * the current shader is valid and the framebuffer is complete.
> - * It also check the current pipeline object is valid if any.
> - * If an error is detected it'll be recorded here.
> - * \return GL_TRUE if OK to render, GL_FALSE if not
> - */
> -GLboolean
> -_mesa_valid_to_render(struct gl_context *ctx, const char *where)
> -{
> -   /* This depends on having up to date derived state (shaders) */
> -   if (ctx->NewState)
> -      _mesa_update_state(ctx);
> -
> -   if (ctx->API == API_OPENGL_COMPAT) {
> -      /* Any shader stages that are not supplied by the GLSL shader and
> have
> -       * assembly shaders enabled must now be validated.
> -       */
> -      if (!ctx->_Shader->CurrentProgram[MESA_SHADER_VERTEX]
> -          && ctx->VertexProgram.Enabled && !ctx->VertexProgram._Enabled) {
> -         _mesa_error(ctx, GL_INVALID_OPERATION,
> -                     "%s(vertex program not valid)", where);
> -         return GL_FALSE;
> -      }
> -
> -      if (!ctx->_Shader->CurrentProgram[MESA_SHADER_FRAGMENT]) {
> -         if (ctx->FragmentProgram.Enabled && !ctx->FragmentProgram._Enabled)
> {
> -            _mesa_error(ctx, GL_INVALID_OPERATION,
> -                        "%s(fragment program not valid)", where);
> -            return GL_FALSE;
> -         }
> -
> -         /* If drawing to integer-valued color buffers, there must be an
> -          * active fragment shader (GL_EXT_texture_integer).
> -          */
> -         if (ctx->DrawBuffer && ctx->DrawBuffer->_IntegerColor) {
> -            _mesa_error(ctx, GL_INVALID_OPERATION,
> -                        "%s(integer format but no fragment shader)",
> where);
> -            return GL_FALSE;
> -         }
> -      }
> -   }
> -
> -   /* A pipeline object is bound */
> -   if (ctx->_Shader->Name && !ctx->_Shader->Validated) {
> -      if (!_mesa_validate_program_pipeline(ctx, ctx->_Shader)) {
> -         _mesa_error(ctx, GL_INVALID_OPERATION,
> -                     "glValidateProgramPipeline failed to validate the "
> -                     "pipeline");
> -         return GL_FALSE;
> -      }
> -   }
> -
> -   /* If a program is active and SSO not in use, check if validation of
> -    * samplers succeeded for the active program. */
> -   if (ctx->_Shader->ActiveProgram && ctx->_Shader !=
> ctx->Pipeline.Current) {
> -      char errMsg[100];
> -      if (!_mesa_sampler_uniforms_are_valid(ctx->_Shader->ActiveProgram,
> -                                            errMsg, 100)) {
> -         _mesa_error(ctx, GL_INVALID_OPERATION, "%s", errMsg);
> -         return GL_FALSE;
> -      }
> -   }
> -
> -   if (ctx->DrawBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
> -      _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT,
> -                  "%s(incomplete framebuffer)", where);
> -      return GL_FALSE;
> -   }
> -
> -   if (!check_blend_func_error(ctx)) {
> -      return GL_FALSE;
> -   }
> -
> -#ifdef DEBUG
> -   if (ctx->_Shader->Flags & GLSL_LOG) {
> -      struct gl_shader_program **shProg = ctx->_Shader->CurrentProgram;
> -      gl_shader_stage i;
> -
> -      for (i = 0; i < MESA_SHADER_STAGES; i++) {
> -        if (shProg[i] == NULL || shProg[i]->_Used
> -            || shProg[i]->_LinkedShaders[i] == NULL)
> -           continue;
> -
> -        /* This is the first time this shader is being used.
> -         * Append shader's constants/uniforms to log file.
> -         *
> -         * Only log data for the program target that matches the shader
> -         * target.  It's possible to have a program bound to the vertex
> -         * shader target that also supplied a fragment shader.  If that
> -         * program isn't also bound to the fragment shader target we don't
> -         * want to log its fragment data.
> -         */
> -        _mesa_append_uniforms_to_file(shProg[i]->_LinkedShaders[i]);
> -      }
> -
> -      for (i = 0; i < MESA_SHADER_STAGES; i++) {
> -        if (shProg[i] != NULL)
> -           shProg[i]->_Used = GL_TRUE;
> -      }
> -   }
> -#endif
> -
> -   return GL_TRUE;
> -}
>
>
>  /*@}*/
> diff --git a/src/mesa/main/context.h b/src/mesa/main/context.h
> index 520b3bb..9704a96 100644
> --- a/src/mesa/main/context.h
> +++ b/src/mesa/main/context.h
> @@ -152,9 +152,6 @@ _mesa_get_dispatch(struct gl_context *ctx);
>  extern void
>  _mesa_set_context_lost_dispatch(struct gl_context *ctx);
>
> -extern GLboolean
> -_mesa_valid_to_render(struct gl_context *ctx, const char *where);
> -
>
>
>  /** \name Miscellaneous */
> diff --git a/src/mesa/main/drawpix.c b/src/mesa/main/drawpix.c
> index 720a082..ec1d261 100644
> --- a/src/mesa/main/drawpix.c
> +++ b/src/mesa/main/drawpix.c
> @@ -24,6 +24,7 @@
>
>  #include "glheader.h"
>  #include "imports.h"
> +#include "api_validate.h"
>  #include "bufferobj.h"
>  #include "context.h"
>  #include "drawpix.h"
> --
> 1.9.1
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/mesa-dev
>

Reviewed-by: Anuj Phogat <anuj.phogat at gmail.com>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.freedesktop.org/archives/mesa-dev/attachments/20160930/4f9dda1e/attachment-0001.html>


More information about the mesa-dev mailing list