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

Brian Paul brianp at vmware.com
Fri Sep 30 21:21:48 UTC 2016


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



More information about the mesa-dev mailing list