_mesa_reference_pipeline_object(ctx, &save->Pipeline, NULL);
}
+
+ _mesa_update_vertex_processing_mode(ctx);
}
if (state & MESA_META_STENCIL_TEST) {
#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"
_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);
}
}
+ _mesa_update_vertex_processing_mode(ctx);
+
if (ctx->_Shader->Flags & GLSL_DUMP) {
const char *shader_type =
target == GL_FRAGMENT_PROGRAM_ARB ? "fragment" : "vertex";
#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"
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.
#include "light.h"
#include "mtypes.h"
#include "enums.h"
+#include "state.h"
#include "texstate.h"
#include "varray.h"
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
} 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
*/
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;
};
/**
#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"
_mesa_program_init_subroutine_defaults(ctx, prog);
}
}
+
+ _mesa_update_vertex_processing_mode(ctx);
}
}
#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"
shProg->Name, shProg->data->InfoLog);
}
+ _mesa_update_vertex_processing_mode(ctx);
+
/* debug code */
if (0) {
GLuint i;
&shTarget->ReferencedPrograms[stage],
shProg);
_mesa_reference_program(ctx, target, prog);
+ if (stage == MESA_SHADER_VERTEX)
+ _mesa_update_vertex_processing_mode(ctx);
return;
}
*/
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,
}
else {
/* no vertex program */
+ assert(VP_MODE_FF == ctx->VertexProgram._VPMode);
_mesa_reference_program(ctx, &ctx->VertexProgram._Current, NULL);
}
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;
+}
_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)
{
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;