On Fri, Sep 30, 2016 at 2:21 PM, Brian Paul <bri...@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@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/mesa-dev > Reviewed-by: Anuj Phogat <anuj.pho...@gmail.com>
_______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev