From 92d76a169127a6b8b4e2027a95425b592d0ca3db Mon Sep 17 00:00:00 2001 From: =?utf8?q?Mathias=20Fr=C3=B6hlich?= Date: Fri, 2 Feb 2018 21:31:27 +0100 Subject: [PATCH] mesa: Provide an alternative to get_vp_mode() MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit To get equivalent information than get_vp_mode(), track the vertex processing mode in a per context variable at gl_vertex_program_state::_VPMode. This aims to replace get_vp_mode() as seen in the vbo module. But instead of the get_vp_mode() implementation which only gives correct answers past calling _mesa_update_state() this context variable is immediately tracked when the vertex processing state is modified. The correctness of this value is asserted on state validation. With this in place we should be able to untangle the dependency with varying_vp_inputs and state invalidation. Signed-off-by: Mathias Fröhlich Reviewed-by: Brian Paul --- src/mesa/drivers/common/meta.c | 2 ++ src/mesa/main/arbprogram.c | 5 +++++ src/mesa/main/context.c | 3 +++ src/mesa/main/enable.c | 2 ++ src/mesa/main/mtypes.h | 24 ++++++++++++++++++++++++ src/mesa/main/pipelineobj.c | 3 +++ src/mesa/main/shaderapi.c | 5 +++++ src/mesa/main/state.c | 23 +++++++++++++++++++++++ src/mesa/main/state.h | 7 +++++++ src/mesa/program/program.c | 1 + 10 files changed, 75 insertions(+) diff --git a/src/mesa/drivers/common/meta.c b/src/mesa/drivers/common/meta.c index cd898e26f6f..0cb2ef450e0 100644 --- a/src/mesa/drivers/common/meta.c +++ b/src/mesa/drivers/common/meta.c @@ -1012,6 +1012,8 @@ _mesa_meta_end(struct gl_context *ctx) _mesa_reference_pipeline_object(ctx, &save->Pipeline, NULL); } + + _mesa_update_vertex_processing_mode(ctx); } if (state & MESA_META_STENCIL_TEST) { diff --git a/src/mesa/main/arbprogram.c b/src/mesa/main/arbprogram.c index 625dc667f80..b169bce0c57 100644 --- a/src/mesa/main/arbprogram.c +++ b/src/mesa/main/arbprogram.c @@ -37,6 +37,7 @@ #include "main/mtypes.h" #include "main/arbprogram.h" #include "main/shaderapi.h" +#include "main/state.h" #include "program/arbprogparse.h" #include "program/program.h" #include "program/prog_print.h" @@ -133,6 +134,8 @@ _mesa_BindProgramARB(GLenum target, GLuint id) _mesa_reference_program(ctx, &ctx->FragmentProgram.Current, newProg); } + _mesa_update_vertex_processing_mode(ctx); + /* Never null pointers */ assert(ctx->VertexProgram.Current); assert(ctx->FragmentProgram.Current); @@ -369,6 +372,8 @@ _mesa_ProgramStringARB(GLenum target, GLenum format, GLsizei len, } } + _mesa_update_vertex_processing_mode(ctx); + if (ctx->_Shader->Flags & GLSL_DUMP) { const char *shader_type = target == GL_FRAGMENT_PROGRAM_ARB ? "fragment" : "vertex"; diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c index 79d3e39e922..0aa2e3639f0 100644 --- a/src/mesa/main/context.c +++ b/src/mesa/main/context.c @@ -123,6 +123,7 @@ #include "shared.h" #include "shaderobj.h" #include "shaderimage.h" +#include "state.h" #include "util/debug.h" #include "util/disk_cache.h" #include "util/strtod.h" @@ -1579,6 +1580,8 @@ handle_first_current(struct gl_context *ctx) check_context_limits(ctx); + _mesa_update_vertex_processing_mode(ctx); + /* According to GL_MESA_configless_context the default value of * glDrawBuffers depends on the config of the first surface it is bound to. * For GLES it is always GL_BACK which has a magic interpretation. diff --git a/src/mesa/main/enable.c b/src/mesa/main/enable.c index f23673a6cdc..868b73ac68b 100644 --- a/src/mesa/main/enable.c +++ b/src/mesa/main/enable.c @@ -39,6 +39,7 @@ #include "light.h" #include "mtypes.h" #include "enums.h" +#include "state.h" #include "texstate.h" #include "varray.h" @@ -919,6 +920,7 @@ _mesa_set_enable(struct gl_context *ctx, GLenum cap, GLboolean state) return; FLUSH_VERTICES(ctx, _NEW_PROGRAM); ctx->VertexProgram.Enabled = state; + _mesa_update_vertex_processing_mode(ctx); break; case GL_VERTEX_PROGRAM_POINT_SIZE_ARB: /* This was added with ARB_vertex_program, but it is also used with diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index 7da3240da78..41df04d38d4 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -2136,6 +2136,19 @@ typedef enum } gl_register_file; +/** + * Current vertex processing mode: fixed function vs. shader. + * In reality, fixed function is probably implemented by a shader but that's + * not what we care about here. + */ +typedef enum +{ + VP_MODE_FF, /**< legacy / fixed function */ + VP_MODE_SHADER, /**< ARB vertex program or GLSL vertex shader */ + VP_MODE_MAX /**< for sizing arrays */ +} gl_vertex_processing_mode; + + /** * Base class for any kind of program object */ @@ -2362,6 +2375,17 @@ struct gl_vertex_program_state struct gl_program_cache *Cache; GLboolean _Overriden; + + /** + * If we have a vertex program, a TNL program or no program at all. + * Note that this value should be kept up to date all the time, + * nevertheless its correctness is asserted in _mesa_update_state. + * The reason is to avoid calling _mesa_update_state twice we need + * this value on draw *before* actually calling _mesa_update_state. + * Also it should need to get recomputed only on changes to the + * vertex program which are heavyweight already. + */ + gl_vertex_processing_mode _VPMode; }; /** diff --git a/src/mesa/main/pipelineobj.c b/src/mesa/main/pipelineobj.c index d7d99ec22d8..438f75bc74f 100644 --- a/src/mesa/main/pipelineobj.c +++ b/src/mesa/main/pipelineobj.c @@ -41,6 +41,7 @@ #include "main/pipelineobj.h" #include "main/shaderapi.h" #include "main/shaderobj.h" +#include "main/state.h" #include "main/transformfeedback.h" #include "main/uniforms.h" #include "compiler/glsl/glsl_parser_extras.h" @@ -532,6 +533,8 @@ _mesa_bind_pipeline(struct gl_context *ctx, _mesa_program_init_subroutine_defaults(ctx, prog); } } + + _mesa_update_vertex_processing_mode(ctx); } } diff --git a/src/mesa/main/shaderapi.c b/src/mesa/main/shaderapi.c index d0d2ef9a0f0..d8a3031a386 100644 --- a/src/mesa/main/shaderapi.c +++ b/src/mesa/main/shaderapi.c @@ -50,6 +50,7 @@ #include "main/program_binary.h" #include "main/shaderapi.h" #include "main/shaderobj.h" +#include "main/state.h" #include "main/transformfeedback.h" #include "main/uniforms.h" #include "compiler/glsl/glsl_parser_extras.h" @@ -1258,6 +1259,8 @@ link_program(struct gl_context *ctx, struct gl_shader_program *shProg, shProg->Name, shProg->data->InfoLog); } + _mesa_update_vertex_processing_mode(ctx); + /* debug code */ if (0) { GLuint i; @@ -2432,6 +2435,8 @@ _mesa_use_program(struct gl_context *ctx, gl_shader_stage stage, &shTarget->ReferencedPrograms[stage], shProg); _mesa_reference_program(ctx, target, prog); + if (stage == MESA_SHADER_VERTEX) + _mesa_update_vertex_processing_mode(ctx); return; } diff --git a/src/mesa/main/state.c b/src/mesa/main/state.c index df694d09092..2fd4fb9d323 100644 --- a/src/mesa/main/state.c +++ b/src/mesa/main/state.c @@ -177,15 +177,18 @@ update_program(struct gl_context *ctx) */ if (vsProg) { /* Use GLSL vertex shader */ + assert(VP_MODE_SHADER == ctx->VertexProgram._VPMode); _mesa_reference_program(ctx, &ctx->VertexProgram._Current, vsProg); } else if (_mesa_arb_vertex_program_enabled(ctx)) { /* Use user-defined vertex program */ + assert(VP_MODE_SHADER == ctx->VertexProgram._VPMode); _mesa_reference_program(ctx, &ctx->VertexProgram._Current, ctx->VertexProgram.Current); } else if (ctx->VertexProgram._MaintainTnlProgram) { /* Use vertex program generated from fixed-function state */ + assert(VP_MODE_FF == ctx->VertexProgram._VPMode); _mesa_reference_program(ctx, &ctx->VertexProgram._Current, _mesa_get_fixed_func_vertex_program(ctx)); _mesa_reference_program(ctx, &ctx->VertexProgram._TnlProgram, @@ -193,6 +196,7 @@ update_program(struct gl_context *ctx) } else { /* no vertex program */ + assert(VP_MODE_FF == ctx->VertexProgram._VPMode); _mesa_reference_program(ctx, &ctx->VertexProgram._Current, NULL); } @@ -456,3 +460,22 @@ _mesa_set_vp_override(struct gl_context *ctx, GLboolean flag) ctx->NewState |= _NEW_PROGRAM; } } + + +/** + * Update ctx->VertexProgram._VPMode. + * This is to distinguish whether we're running + * a vertex program/shader, + * a fixed-function TNL program or + * a fixed function vertex transformation without any program. + */ +void +_mesa_update_vertex_processing_mode(struct gl_context *ctx) +{ + if (ctx->_Shader->CurrentProgram[MESA_SHADER_VERTEX]) + ctx->VertexProgram._VPMode = VP_MODE_SHADER; + else if (_mesa_arb_vertex_program_enabled(ctx)) + ctx->VertexProgram._VPMode = VP_MODE_SHADER; + else + ctx->VertexProgram._VPMode = VP_MODE_FF; +} diff --git a/src/mesa/main/state.h b/src/mesa/main/state.h index 5814c659a31..049166578c2 100644 --- a/src/mesa/main/state.h +++ b/src/mesa/main/state.h @@ -46,6 +46,13 @@ extern void _mesa_set_vp_override(struct gl_context *ctx, GLboolean flag); +/** + * Update ctx->VertexProgram._VertexProgramMode. + */ +extern void +_mesa_update_vertex_processing_mode(struct gl_context *ctx); + + static inline bool _mesa_ati_fragment_shader_enabled(const struct gl_context *ctx) { diff --git a/src/mesa/program/program.c b/src/mesa/program/program.c index 6aba3cb3f10..6ab1bf50177 100644 --- a/src/mesa/program/program.c +++ b/src/mesa/program/program.c @@ -100,6 +100,7 @@ _mesa_init_program(struct gl_context *ctx) ctx->Shared->DefaultFragmentProgram); assert(ctx->FragmentProgram.Current); ctx->FragmentProgram.Cache = _mesa_new_program_cache(); + ctx->VertexProgram._VPMode = VP_MODE_FF; /* XXX probably move this stuff */ ctx->ATIFragmentShader.Enabled = GL_FALSE; -- 2.30.2