aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrian Paul <[email protected]>2016-09-30 10:25:05 -0600
committerBrian Paul <[email protected]>2016-09-30 16:28:00 -0600
commit951bf44a56d3236550d4d910741c10d5e0d1311b (patch)
tree2e7bc9081ad49cf29cb215f737a42fae2ef75d76
parente99b9395befe5b8612df3163b4deec2a0c0cb702 (diff)
mesa: move _mesa_valid_to_render() to api_validate.c
Almost all of the other drawing validation code is in api_validate.c so put this function there as well. Reviewed-by: Anuj Phogat <[email protected]>
-rw-r--r--src/mesa/main/api_validate.c191
-rw-r--r--src/mesa/main/api_validate.h3
-rw-r--r--src/mesa/main/context.c188
-rw-r--r--src/mesa/main/context.h3
-rw-r--r--src/mesa/main/drawpix.c1
5 files changed, 195 insertions, 191 deletions
diff --git a/src/mesa/main/api_validate.c b/src/mesa/main/api_validate.c
index 6cb626a5805..05691d25da0 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 5b321e3ac99..2eba834c50d 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 f550b0c556d..697b5186fb8 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 520b3bbfb9a..9704a96e11f 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 720a082ce6d..ec1d2618cad 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"