mesa: move _mesa_valid_to_render() to api_validate.c
authorBrian Paul <brianp@vmware.com>
Fri, 30 Sep 2016 16:25:05 +0000 (10:25 -0600)
committerBrian Paul <brianp@vmware.com>
Fri, 30 Sep 2016 22:28:00 +0000 (16:28 -0600)
Almost all of the other drawing validation code is in api_validate.c
so put this function there as well.

Reviewed-by: Anuj Phogat <anuj.phogat@gmail.com>
src/mesa/main/api_validate.c
src/mesa/main/api_validate.h
src/mesa/main/context.c
src/mesa/main/context.h
src/mesa/main/drawpix.c

index 6cb626a5805804952875d6f01f2b8b2ae5cf1b53..05691d25da0d907215a0347ae66a4e9e4f374292 100644 (file)
 #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;
+}
 
 
 /**
index 5b321e3ac99d8be282c78f9d342ce8f0ce1fbbed..2eba834c50daab27f8f7ae3696f3e960ec0a30ad 100644 (file)
@@ -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);
 
index f550b0c556d37f347262d68e6200847177820897..697b5186fb8918865b08ecddf694679e21d48522 100644 (file)
 #include "shaderobj.h"
 #include "shaderimage.h"
 #include "util/strtod.h"
-#include "state.h"
 #include "stencil.h"
 #include "texcompress_s3tc.h"
 #include "texstate.h"
 #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;
-}
 
 
 /*@}*/
index 520b3bbfb9a54d54b8c5c18158fdd463a849d203..9704a96e11f77cd940ba5d845eea428b35f7cbe7 100644 (file)
@@ -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 */
index 720a082ce6d7dac2a4308ab4ccdf64067e7fbd69..ec1d2618cad981fdc0b98d5c74b75d0429ca8aa4 100644 (file)
@@ -24,6 +24,7 @@
 
 #include "glheader.h"
 #include "imports.h"
+#include "api_validate.h"
 #include "bufferobj.h"
 #include "context.h"
 #include "drawpix.h"