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