mesa: Provide an alternative to get_vp_mode()
authorMathias Fröhlich <mathias.froehlich@web.de>
Fri, 2 Feb 2018 20:31:27 +0000 (21:31 +0100)
committerMathias Fröhlich <mathias.froehlich@web.de>
Fri, 23 Feb 2018 04:33:30 +0000 (05:33 +0100)
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 <Mathias.Froehlich@web.de>
Reviewed-by: Brian Paul <brianp@vmware.com>
src/mesa/drivers/common/meta.c
src/mesa/main/arbprogram.c
src/mesa/main/context.c
src/mesa/main/enable.c
src/mesa/main/mtypes.h
src/mesa/main/pipelineobj.c
src/mesa/main/shaderapi.c
src/mesa/main/state.c
src/mesa/main/state.h
src/mesa/program/program.c

index cd898e26f6fbf98a63d0707aaf9b7be0efa5b14b..0cb2ef450e08812706f127d056d85c7e6be1a46e 100644 (file)
@@ -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) {
index 625dc667f809f624a0a9370ae8403d5b57fb1696..b169bce0c576ff93993e5f028be049d3bf336de3 100644 (file)
@@ -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";
index 79d3e39e92246d7e343d3269e0fb9142e4c329bb..0aa2e3639f0846f948eb9ef57939895f9b524f2c 100644 (file)
 #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.
index f23673a6cdc23eeb4d5bf68a42b8434542c425b0..868b73ac68b83f40f419a6e6db6938183db43dcd 100644 (file)
@@ -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
index 7da3240da78428f4bc96c0e2a9cbb2d5e8e977d0..41df04d38d42075e6f370f238ef241320ff3d7e1 100644 (file)
@@ -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;
 };
 
 /**
index d7d99ec22d8369c78b0e102eab9ea5434aa16ddd..438f75bc74fd106251d0942567b5add2d49e9bd5 100644 (file)
@@ -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);
    }
 }
 
index d0d2ef9a0f0088cfb35bfe55b4903213f351188c..d8a3031a386e8178a0754fdcc41b8d8717219017 100644 (file)
@@ -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;
    }
 
index df694d090927a70fd24a41a8a8b2b5838c702dee..2fd4fb9d3238d999547b10277a5a267e0869962c 100644 (file)
@@ -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;
+}
index 5814c659a31e6f2242358a4c35d183baf68fdf77..049166578c2be549c0cbe863730026c29c8e845f 100644 (file)
@@ -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)
 {
index 6aba3cb3f10a900652e13445ce9787afd71f8b4f..6ab1bf50177b9919035740d622ac347cdc9fb381 100644 (file)
@@ -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;