summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Romanick <ian.d.romanick@intel.com>2010-10-13 13:58:44 -0700
committerIan Romanick <ian.d.romanick@intel.com>2010-10-27 13:35:53 -0700
commit84eba3ef71dfa822e5ff0463032cdd2e3515b888 (patch)
treedc737eed47f4e7ec35581a1ec9daf598765cb978
parent75c6f472880706dcbb9d1e20727fa8f71db8b11c (diff)
Track separate programs for each stage
The assumption is that all stages are the same program or that varyings are passed between stages using built-in varyings.
-rw-r--r--src/mesa/drivers/common/meta.c30
-rw-r--r--src/mesa/drivers/dri/i965/brw_fs.cpp6
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm_state.c4
-rw-r--r--src/mesa/main/context.c150
-rw-r--r--src/mesa/main/mtypes.h10
-rw-r--r--src/mesa/main/shaderapi.c89
-rw-r--r--src/mesa/main/state.c16
-rw-r--r--src/mesa/main/texenvprogram.c9
-rw-r--r--src/mesa/main/texstate.c33
-rw-r--r--src/mesa/state_tracker/st_atom_rasterizer.c5
-rw-r--r--src/mesa/state_tracker/st_draw.c20
-rw-r--r--src/mesa/state_tracker/st_program.c38
-rw-r--r--src/mesa/swrast/s_fragprog.c2
13 files changed, 297 insertions, 115 deletions
diff --git a/src/mesa/drivers/common/meta.c b/src/mesa/drivers/common/meta.c
index 9946bf1990..1bfd76a665 100644
--- a/src/mesa/drivers/common/meta.c
+++ b/src/mesa/drivers/common/meta.c
@@ -143,7 +143,10 @@ struct save_state
struct gl_vertex_program *VertexProgram;
GLboolean FragmentProgramEnabled;
struct gl_fragment_program *FragmentProgram;
- GLuint Shader;
+ GLuint VertexShader;
+ GLuint GeometryShader;
+ GLuint FragmentShader;
+ GLuint ActiveShader;
/** META_STENCIL_TEST */
struct gl_stencil_attrib Stencil;
@@ -433,8 +436,15 @@ _mesa_meta_begin(struct gl_context *ctx, GLbitfield state)
}
if (ctx->Extensions.ARB_shader_objects) {
- save->Shader = ctx->Shader.CurrentProgram ?
- ctx->Shader.CurrentProgram->Name : 0;
+ save->VertexShader = ctx->Shader.CurrentVertexProgram ?
+ ctx->Shader.CurrentVertexProgram->Name : 0;
+ save->GeometryShader = ctx->Shader.CurrentGeometryProgram ?
+ ctx->Shader.CurrentGeometryProgram->Name : 0;
+ save->FragmentShader = ctx->Shader.CurrentFragmentProgram ?
+ ctx->Shader.CurrentFragmentProgram->Name : 0;
+ save->ActiveShader = ctx->Shader.ActiveProgram ?
+ ctx->Shader.ActiveProgram->Name : 0;
+
_mesa_UseProgramObjectARB(0);
}
}
@@ -664,9 +674,17 @@ _mesa_meta_end(struct gl_context *ctx)
_mesa_reference_fragprog(ctx, &save->FragmentProgram, NULL);
}
- if (ctx->Extensions.ARB_shader_objects) {
- _mesa_UseProgramObjectARB(save->Shader);
- }
+ if (ctx->Extensions.ARB_vertex_shader)
+ _mesa_UseShaderProgramEXT(GL_VERTEX_SHADER, save->VertexShader);
+
+ if (ctx->Extensions.ARB_geometry_shader4)
+ _mesa_UseShaderProgramEXT(GL_GEOMETRY_SHADER_ARB,
+ save->GeometryShader);
+
+ if (ctx->Extensions.ARB_fragment_shader)
+ _mesa_UseShaderProgramEXT(GL_FRAGMENT_SHADER, save->FragmentShader);
+
+ _mesa_ActiveProgramEXT(save->ActiveShader);
}
if (state & META_STENCIL_TEST) {
diff --git a/src/mesa/drivers/dri/i965/brw_fs.cpp b/src/mesa/drivers/dri/i965/brw_fs.cpp
index 4919394bc8..5f6deb841c 100644
--- a/src/mesa/drivers/dri/i965/brw_fs.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs.cpp
@@ -1186,7 +1186,7 @@ fs_visitor::visit(ir_texture *ir)
assert(!ir->projector);
sampler = _mesa_get_sampler_uniform_value(ir->sampler,
- ctx->Shader.CurrentProgram,
+ ctx->Shader.CurrentFragmentProgram,
&brw->fragment_program->Base);
sampler = c->fp->program.Base.SamplerUnits[sampler];
@@ -3093,7 +3093,7 @@ fs_visitor::generate_code()
if (INTEL_DEBUG & DEBUG_WM) {
printf("Native code for fragment shader %d:\n",
- ctx->Shader.CurrentProgram->Name);
+ ctx->Shader.CurrentFragmentProgram->Name);
}
if_depth_in_loop[loop_stack_depth] = 0;
@@ -3320,7 +3320,7 @@ brw_wm_fs_emit(struct brw_context *brw, struct brw_wm_compile *c)
{
struct intel_context *intel = &brw->intel;
struct gl_context *ctx = &intel->ctx;
- struct gl_shader_program *prog = ctx->Shader.CurrentProgram;
+ struct gl_shader_program *prog = ctx->Shader.CurrentFragmentProgram;
if (!prog)
return GL_FALSE;
diff --git a/src/mesa/drivers/dri/i965/brw_wm_state.c b/src/mesa/drivers/dri/i965/brw_wm_state.c
index 433ccc66f0..9a27b93710 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_state.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_state.c
@@ -137,9 +137,9 @@ wm_unit_populate_key(struct brw_context *brw, struct brw_wm_unit_key *key)
/* If using the fragment shader backend, the program is always
* 8-wide.
*/
- if (ctx->Shader.CurrentProgram) {
+ if (ctx->Shader.CurrentFragmentProgram) {
struct brw_shader *shader = (struct brw_shader *)
- ctx->Shader.CurrentProgram->_LinkedShaders[MESA_SHADER_FRAGMENT];
+ ctx->Shader.CurrentFragmentProgram->_LinkedShaders[MESA_SHADER_FRAGMENT];
if (shader != NULL && shader->ir != NULL) {
key->is_glsl = GL_TRUE;
diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c
index 3e265fb308..3ebe54926f 100644
--- a/src/mesa/main/context.c
+++ b/src/mesa/main/context.c
@@ -1697,11 +1697,10 @@ _mesa_valid_to_render(struct gl_context *ctx, const char *where)
if (ctx->NewState)
_mesa_update_state(ctx);
- if (ctx->Shader.CurrentProgram) {
- struct gl_shader_program *const prog = ctx->Shader.CurrentProgram;
+ if (ctx->Shader.CurrentVertexProgram) {
+ vert_from_glsl_shader = true;
- /* The current shader program must be successfully linked */
- if (!prog->LinkStatus) {
+ if (!ctx->Shader.CurrentVertexProgram->LinkStatus) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"%s(shader not linked)", where);
return GL_FALSE;
@@ -1709,34 +1708,56 @@ _mesa_valid_to_render(struct gl_context *ctx, const char *where)
#if 0 /* not normally enabled */
{
char errMsg[100];
- if (!_mesa_validate_shader_program(ctx, prog, errMsg)) {
+ if (!_mesa_validate_shader_program(ctx,
+ ctx->Shader.CurrentVertexProgram,
+ errMsg)) {
_mesa_warning(ctx, "Shader program %u is invalid: %s",
- prog->Name, errMsg);
+ ctx->Shader.CurrentVertexProgram->Name, errMsg);
}
}
#endif
+ }
- /* Figure out which shader stages are provided by the GLSL program. For
- * any stages that are not provided, the corresponding assembly shader
- * target will be validated below.
- */
- vert_from_glsl_shader =
- prog->_LinkedShaders[MESA_SHADER_VERTEX] != NULL;
- geom_from_glsl_shader =
- prog->_LinkedShaders[MESA_SHADER_GEOMETRY] != NULL;
- frag_from_glsl_shader =
- prog->_LinkedShaders[MESA_SHADER_FRAGMENT] != NULL;
+ if (ctx->Shader.CurrentGeometryProgram) {
+ geom_from_glsl_shader = true;
+
+ if (!ctx->Shader.CurrentGeometryProgram->LinkStatus) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "%s(shader not linked)", where);
+ return GL_FALSE;
+ }
+#if 0 /* not normally enabled */
+ {
+ char errMsg[100];
+ if (!_mesa_validate_shader_program(ctx,
+ ctx->Shader.CurrentGeometryProgram,
+ errMsg)) {
+ _mesa_warning(ctx, "Shader program %u is invalid: %s",
+ ctx->Shader.CurrentGeometryProgram->Name, errMsg);
+ }
+ }
+#endif
}
- /* If drawing to integer-valued color buffers, there must be an
- * active fragment shader (GL_EXT_texture_integer).
- */
- if (ctx->DrawBuffer && ctx->DrawBuffer->_IntegerColor) {
- if (!frag_from_glsl_shader) {
+ if (ctx->Shader.CurrentFragmentProgram) {
+ frag_from_glsl_shader = true;
+
+ if (!ctx->Shader.CurrentFragmentProgram->LinkStatus) {
_mesa_error(ctx, GL_INVALID_OPERATION,
- "%s(integer format but no fragment shader)", where);
+ "%s(shader not linked)", where);
return GL_FALSE;
}
+#if 0 /* not normally enabled */
+ {
+ char errMsg[100];
+ if (!_mesa_validate_shader_program(ctx,
+ ctx->Shader.CurrentFragmentProgram,
+ errMsg)) {
+ _mesa_warning(ctx, "Shader program %u is invalid: %s",
+ ctx->Shader.CurrentFragmentProgram->Name, errMsg);
+ }
+ }
+#endif
}
/* Any shader stages that are not supplied by the GLSL shader and have
@@ -1754,11 +1775,21 @@ _mesa_valid_to_render(struct gl_context *ctx, const char *where)
*/
(void) geom_from_glsl_shader;
- if (!frag_from_glsl_shader
- && ctx->FragmentProgram.Enabled && !ctx->FragmentProgram._Enabled) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "%s(fragment program not valid)", where);
- return GL_FALSE;
+ if (!frag_from_glsl_shader) {
+ 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;
+ }
}
if (ctx->DrawBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
@@ -1769,26 +1800,51 @@ _mesa_valid_to_render(struct gl_context *ctx, const char *where)
#ifdef DEBUG
if (ctx->Shader.Flags & GLSL_LOG) {
- struct gl_shader_program *shProg = ctx->Shader.CurrentProgram;
- if (shProg) {
- if (!shProg->_Used) {
- /* This is the first time this shader is being used.
- * Append shader's constants/uniforms to log file.
- */
- GLuint i;
- for (i = 0; i < shProg->NumShaders; i++) {
- struct gl_shader *sh = shProg->Shaders[i];
- if (sh->Type == GL_VERTEX_SHADER) {
- _mesa_append_uniforms_to_file(sh,
- &shProg->VertexProgram->Base);
- }
- else if (sh->Type == GL_FRAGMENT_SHADER) {
- _mesa_append_uniforms_to_file(sh,
- &shProg->FragmentProgram->Base);
- }
- }
- shProg->_Used = GL_TRUE;
- }
+ struct gl_shader_program *shProg[MESA_SHADER_TYPES];
+ unsigned i;
+
+ shProg[MESA_SHADER_VERTEX] = ctx->Shader.CurrentVertexProgram;
+ shProg[MESA_SHADER_GEOMETRY] = ctx->Shader.CurrentGeometryProgram;
+ shProg[MESA_SHADER_FRAGMENT] = ctx->Shader.CurrentFragmentProgram;
+
+ for (i = 0; i < MESA_SHADER_TYPES; i++) {
+ struct gl_shader *sh;
+
+ 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.
+ *
+ * The logic is a little odd here. We only want to log data for each
+ * shader target that will actually be used, and we only want to log
+ * it once. 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.
+ */
+ sh = shProg[i]->_LinkedShaders[i];
+ switch (sh->Type) {
+ case GL_VERTEX_SHADER:
+ _mesa_append_uniforms_to_file(sh, &shProg[i]->VertexProgram->Base);
+ break;
+
+ case GL_GEOMETRY_SHADER_ARB:
+ _mesa_append_uniforms_to_file(sh,
+ &shProg[i]->GeometryProgram->Base);
+ break;
+
+ case GL_FRAGMENT_SHADER:
+ _mesa_append_uniforms_to_file(sh,
+ &shProg[i]->FragmentProgram->Base);
+ break;
+ }
+ }
+
+ for (i = 0; i < MESA_SHADER_TYPES; i++) {
+ if (shProg[i] != NULL)
+ shProg[i]->_Used = GL_TRUE;
}
}
#endif
diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
index 7863ef382d..1b8a80416c 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -2142,9 +2142,15 @@ struct gl_shader_program
struct gl_shader_state
{
/**
- * Program used for rendering.
+ * Programs used for rendering
+ *
+ * There is a separate program set for each shader stage. If
+ * GL_EXT_separate_shader_objects is not supported, each of these must point
+ * to \c NULL or to the same program.
*/
- struct gl_shader_program *CurrentProgram;
+ struct gl_shader_program *CurrentVertexProgram;
+ struct gl_shader_program *CurrentGeometryProgram;
+ struct gl_shader_program *CurrentFragmentProgram;
/**
* Program used by glUniform calls.
diff --git a/src/mesa/main/shaderapi.c b/src/mesa/main/shaderapi.c
index 26c9a181aa..e6c7f7aa3f 100644
--- a/src/mesa/main/shaderapi.c
+++ b/src/mesa/main/shaderapi.c
@@ -116,7 +116,11 @@ _mesa_init_shader_state(struct gl_context *ctx)
void
_mesa_free_shader_state(struct gl_context *ctx)
{
- _mesa_reference_shader_program(ctx, &ctx->Shader.CurrentProgram, NULL);
+ _mesa_reference_shader_program(ctx, &ctx->Shader.CurrentVertexProgram, NULL);
+ _mesa_reference_shader_program(ctx, &ctx->Shader.CurrentGeometryProgram,
+ NULL);
+ _mesa_reference_shader_program(ctx, &ctx->Shader.CurrentFragmentProgram,
+ NULL);
_mesa_reference_shader_program(ctx, &ctx->Shader.ActiveProgram, NULL);
}
@@ -846,7 +850,10 @@ link_program(struct gl_context *ctx, GLuint program)
if (!shProg)
return;
- if (obj->Active && shProg == ctx->Shader.CurrentProgram) {
+ if (obj->Active
+ && (shProg == ctx->Shader.CurrentVertexProgram
+ || shProg == ctx->Shader.CurrentGeometryProgram
+ || shProg == ctx->Shader.CurrentFragmentProgram)) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"glLinkProgram(transform feedback active");
return;
@@ -927,6 +934,54 @@ active_program(struct gl_context *ctx, struct gl_shader_program *shProg,
}
/**
+ */
+static bool
+use_shader_program(struct gl_context *ctx, GLenum type,
+ struct gl_shader_program *shProg)
+{
+ struct gl_shader_program **target;
+
+ switch (type) {
+#if FEATURE_ARB_vertex_shader
+ case GL_VERTEX_SHADER:
+ target = &ctx->Shader.CurrentVertexProgram;
+ if ((shProg == NULL)
+ || (shProg->_LinkedShaders[MESA_SHADER_VERTEX] == NULL)) {
+ shProg = NULL;
+ }
+ break;
+#endif
+#if FEATURE_ARB_geometry_shader4
+ case GL_GEOMETRY_SHADER_ARB:
+ target = &ctx->Shader.CurrentGeometryProgram;
+ if ((shProg == NULL)
+ || (shProg->_LinkedShaders[MESA_SHADER_GEOMETRY] == NULL)) {
+ shProg = NULL;
+ }
+ break;
+#endif
+#if FEATURE_ARB_fragment_shader
+ case GL_FRAGMENT_SHADER:
+ target = &ctx->Shader.CurrentFragmentProgram;
+ if ((shProg == NULL)
+ || (shProg->_LinkedShaders[MESA_SHADER_FRAGMENT] == NULL)) {
+ shProg = NULL;
+ }
+ break;
+#endif
+ default:
+ return false;
+ }
+
+ if (*target != shProg) {
+ _mesa_reference_shader_program(ctx, target, shProg);
+ return true;
+ }
+
+ return false;
+}
+
+/**
* Use the named shader program for subsequent rendering.
*/
void
@@ -935,6 +990,7 @@ _mesa_use_program(struct gl_context *ctx, GLuint program)
struct gl_shader_program *shProg;
struct gl_transform_feedback_object *obj =
ctx->TransformFeedback.CurrentObject;
+ bool changed = false;
if (obj->Active) {
_mesa_error(ctx, GL_INVALID_OPERATION,
@@ -942,12 +998,6 @@ _mesa_use_program(struct gl_context *ctx, GLuint program)
return;
}
- if (ctx->Shader.CurrentProgram &&
- ctx->Shader.CurrentProgram->Name == program) {
- /* no-op */
- return;
- }
-
if (program) {
shProg = _mesa_lookup_shader_program_err(ctx, program, "glUseProgram");
if (!shProg) {
@@ -959,8 +1009,6 @@ _mesa_use_program(struct gl_context *ctx, GLuint program)
return;
}
- active_program(ctx, shProg, "glUseProgram");
-
/* debug code */
if (ctx->Shader.Flags & GLSL_USE_PROG) {
print_shader_info(shProg);
@@ -970,9 +1018,15 @@ _mesa_use_program(struct gl_context *ctx, GLuint program)
shProg = NULL;
}
- if (ctx->Shader.CurrentProgram != shProg) {
+ changed = use_shader_program(ctx, GL_VERTEX_SHADER, shProg);
+ changed = use_shader_program(ctx, GL_GEOMETRY_SHADER_ARB, shProg)
+ || changed;
+ changed = use_shader_program(ctx, GL_FRAGMENT_SHADER, shProg)
+ || changed;
+ active_program(ctx, shProg, "glUseProgram");
+
+ if (changed) {
FLUSH_VERTICES(ctx, _NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS);
- _mesa_reference_shader_program(ctx, &ctx->Shader.CurrentProgram, shProg);
}
if (ctx->Driver.UseProgram)
@@ -1643,7 +1697,8 @@ void GLAPIENTRY
_mesa_UseShaderProgramEXT(GLenum type, GLuint program)
{
GET_CURRENT_CONTEXT(ctx);
- struct gl_shader_program *shProg;
+ struct gl_shader_program *shProg = NULL;
+ bool changed = false;
if (!validate_shader_target(ctx, type)) {
_mesa_error(ctx, GL_INVALID_ENUM, "glUseShaderProgramEXT(type)");
@@ -1669,8 +1724,12 @@ _mesa_UseShaderProgramEXT(GLenum type, GLuint program)
}
}
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glUseShaderProgramEXT(NOT YET IMPLEMENTED)");
+ changed = use_shader_program(ctx, type, shProg);
+ if (changed)
+ FLUSH_VERTICES(ctx, _NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS);
+
+ if (ctx->Driver.UseProgram)
+ ctx->Driver.UseProgram(ctx, shProg);
return;
}
diff --git a/src/mesa/main/state.c b/src/mesa/main/state.c
index 5529732de0..05f4165c44 100644
--- a/src/mesa/main/state.c
+++ b/src/mesa/main/state.c
@@ -247,7 +247,9 @@ update_program_enables(struct gl_context *ctx)
static GLbitfield
update_program(struct gl_context *ctx)
{
- const struct gl_shader_program *shProg = ctx->Shader.CurrentProgram;
+ const struct gl_shader_program *vsProg = ctx->Shader.CurrentVertexProgram;
+ const struct gl_shader_program *gsProg = ctx->Shader.CurrentGeometryProgram;
+ const struct gl_shader_program *fsProg = ctx->Shader.CurrentFragmentProgram;
const struct gl_vertex_program *prevVP = ctx->VertexProgram._Current;
const struct gl_fragment_program *prevFP = ctx->FragmentProgram._Current;
const struct gl_geometry_program *prevGP = ctx->GeometryProgram._Current;
@@ -269,10 +271,10 @@ update_program(struct gl_context *ctx)
* come up, or matter.
*/
- if (shProg && shProg->LinkStatus && shProg->FragmentProgram) {
+ if (fsProg && fsProg->LinkStatus && fsProg->FragmentProgram) {
/* Use shader programs */
_mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current,
- shProg->FragmentProgram);
+ fsProg->FragmentProgram);
}
else if (ctx->FragmentProgram._Enabled) {
/* use user-defined vertex program */
@@ -292,10 +294,10 @@ update_program(struct gl_context *ctx)
_mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current, NULL);
}
- if (shProg && shProg->LinkStatus && shProg->GeometryProgram) {
+ if (gsProg && gsProg->LinkStatus && gsProg->GeometryProgram) {
/* Use shader programs */
_mesa_reference_geomprog(ctx, &ctx->GeometryProgram._Current,
- shProg->GeometryProgram);
+ gsProg->GeometryProgram);
} else {
/* no fragment program */
_mesa_reference_geomprog(ctx, &ctx->GeometryProgram._Current, NULL);
@@ -305,10 +307,10 @@ update_program(struct gl_context *ctx)
* _mesa_get_fixed_func_vertex_program() needs to know active
* fragprog inputs.
*/
- if (shProg && shProg->LinkStatus && shProg->VertexProgram) {
+ if (vsProg && vsProg->LinkStatus && vsProg->VertexProgram) {
/* Use shader programs */
_mesa_reference_vertprog(ctx, &ctx->VertexProgram._Current,
- shProg->VertexProgram);
+ vsProg->VertexProgram);
}
else if (ctx->VertexProgram._Enabled) {
/* use user-defined vertex program */
diff --git a/src/mesa/main/texenvprogram.c b/src/mesa/main/texenvprogram.c
index 4647a9c440..a8bffe416d 100644
--- a/src/mesa/main/texenvprogram.c
+++ b/src/mesa/main/texenvprogram.c
@@ -310,9 +310,10 @@ static GLuint translate_tex_src_bit( GLbitfield bit )
static GLbitfield get_fp_input_mask( struct gl_context *ctx )
{
/* _NEW_PROGRAM */
- const GLboolean vertexShader = (ctx->Shader.CurrentProgram &&
- ctx->Shader.CurrentProgram->LinkStatus &&
- ctx->Shader.CurrentProgram->VertexProgram);
+ const GLboolean vertexShader =
+ (ctx->Shader.CurrentVertexProgram &&
+ ctx->Shader.CurrentVertexProgram->LinkStatus &&
+ ctx->Shader.CurrentVertexProgram->VertexProgram);
const GLboolean vertexProgram = ctx->VertexProgram._Enabled;
GLbitfield fp_inputs = 0x0;
@@ -377,7 +378,7 @@ static GLbitfield get_fp_input_mask( struct gl_context *ctx )
* validation (see additional comments in state.c).
*/
if (vertexShader)
- vprog = ctx->Shader.CurrentProgram->VertexProgram;
+ vprog = ctx->Shader.CurrentVertexProgram->VertexProgram;
else
vprog = ctx->VertexProgram.Current;
diff --git a/src/mesa/main/texstate.c b/src/mesa/main/texstate.c
index 1b0d760fae..f4d77189f2 100644
--- a/src/mesa/main/texstate.c
+++ b/src/mesa/main/texstate.c
@@ -496,23 +496,28 @@ update_texture_state( struct gl_context *ctx )
struct gl_vertex_program *vprog = NULL;
GLbitfield enabledFragUnits = 0x0;
- if (ctx->Shader.CurrentProgram &&
- ctx->Shader.CurrentProgram->LinkStatus) {
- fprog = ctx->Shader.CurrentProgram->FragmentProgram;
- vprog = ctx->Shader.CurrentProgram->VertexProgram;
+ if (ctx->Shader.CurrentVertexProgram &&
+ ctx->Shader.CurrentVertexProgram->LinkStatus) {
+ vprog = ctx->Shader.CurrentVertexProgram->VertexProgram;
+ } else if (ctx->VertexProgram._Enabled) {
+ /* XXX enable this if/when non-shader vertex programs get
+ * texture fetches:
+ vprog = ctx->VertexProgram.Current;
+ */
}
- else {
- if (ctx->FragmentProgram._Enabled) {
- fprog = ctx->FragmentProgram.Current;
- }
- if (ctx->VertexProgram._Enabled) {
- /* XXX enable this if/when non-shader vertex programs get
- * texture fetches:
- vprog = ctx->VertexProgram.Current;
- */
- }
+
+ if (ctx->Shader.CurrentFragmentProgram &&
+ ctx->Shader.CurrentFragmentProgram->LinkStatus) {
+ fprog = ctx->Shader.CurrentFragmentProgram->FragmentProgram;
+ }
+ else if (ctx->FragmentProgram._Enabled) {
+ fprog = ctx->FragmentProgram.Current;
}
+ /* FINISHME: Geometry shader texture accesses should also be considered
+ * FINISHME: here.
+ */
+
/* TODO: only set this if there are actual changes */
ctx->NewState |= _NEW_TEXTURE;
diff --git a/src/mesa/state_tracker/st_atom_rasterizer.c b/src/mesa/state_tracker/st_atom_rasterizer.c
index 451299cef0..f92ca13d5e 100644
--- a/src/mesa/state_tracker/st_atom_rasterizer.c
+++ b/src/mesa/state_tracker/st_atom_rasterizer.c
@@ -96,9 +96,8 @@ static void update_raster_state( struct st_context *st )
*/
if (ctx->VertexProgram._Current) {
if (ctx->VertexProgram._Enabled ||
- (ctx->Shader.CurrentProgram &&
- ctx->Shader.CurrentProgram->VertexProgram &&
- ctx->Shader.CurrentProgram->LinkStatus)) {
+ (ctx->Shader.CurrentVertexProgram &&
+ ctx->Shader.CurrentVertexProgram->LinkStatus)) {
/* user-defined vertex program or shader */
raster->light_twoside = ctx->VertexProgram.TwoSideEnabled;
}
diff --git a/src/mesa/state_tracker/st_draw.c b/src/mesa/state_tracker/st_draw.c
index 5387499eb9..61a0e1b087 100644
--- a/src/mesa/state_tracker/st_draw.c
+++ b/src/mesa/state_tracker/st_draw.c
@@ -547,11 +547,21 @@ setup_index_buffer(struct gl_context *ctx,
static void
check_uniforms(struct gl_context *ctx)
{
- const struct gl_shader_program *shProg = ctx->Shader.CurrentProgram;
- if (shProg && shProg->LinkStatus) {
- GLuint i;
- for (i = 0; i < shProg->Uniforms->NumUniforms; i++) {
- const struct gl_uniform *u = &shProg->Uniforms->Uniforms[i];
+ struct gl_shader_program *shProg[3] = {
+ ctx->Shader.CurrentVertexProgram,
+ ctx->Shader.CurrentGeometryProgram,
+ ctx->Shader.CurrentFragmentProgram,
+ };
+ unsigned j;
+
+ for (j = 0; j < 3; j++) {
+ unsigned i;
+
+ if (shProg[j] == NULL || !shProg[j]->LinkStatus)
+ continue;
+
+ for (i = 0; i < shProg[j]->Uniforms->NumUniforms; i++) {
+ const struct gl_uniform *u = &shProg[j]->Uniforms->Uniforms[i];
if (!u->Initialized) {
_mesa_warning(ctx,
"Using shader with uninitialized uniform: %s",
diff --git a/src/mesa/state_tracker/st_program.c b/src/mesa/state_tracker/st_program.c
index 95e6bd7dac..6a5d741b61 100644
--- a/src/mesa/state_tracker/st_program.c
+++ b/src/mesa/state_tracker/st_program.c
@@ -718,12 +718,38 @@ st_translate_geometry_program(struct st_context *st,
void
st_print_shaders(struct gl_context *ctx)
{
- struct gl_shader_program *shProg = ctx->Shader.CurrentProgram;
- if (shProg) {
- GLuint i;
- for (i = 0; i < shProg->NumShaders; i++) {
- printf("GLSL shader %u of %u:\n", i, shProg->NumShaders);
- printf("%s\n", shProg->Shaders[i]->Source);
+ struct gl_shader_program *shProg[3] = {
+ ctx->Shader.CurrentVertexProgram,
+ ctx->Shader.CurrentGeometryProgram,
+ ctx->Shader.CurrentFragmentProgram,
+ };
+ unsigned j;
+
+ for (j = 0; j < 3; j++) {
+ unsigned i;
+
+ if (shProg[j] == NULL)
+ continue;
+
+ for (i = 0; i < shProg[j]->NumShaders; i++) {
+ struct gl_shader *sh;
+
+ switch (shProg[j]->Shaders[i]->Type) {
+ case GL_VERTEX_SHADER:
+ sh = (i != 0) ? NULL : shProg[j]->Shaders[i];
+ break;
+ case GL_GEOMETRY_SHADER_ARB:
+ sh = (i != 1) ? NULL : shProg[j]->Shaders[i];
+ break;
+ case GL_FRAGMENT_SHADER:
+ sh = (i != 2) ? NULL : shProg[j]->Shaders[i];
+ break;
+ }
+
+ if (sh != NULL) {
+ printf("GLSL shader %u of %u:\n", i, shProg[j]->NumShaders);
+ printf("%s\n", sh->Source);
+ }
}
}
}
diff --git a/src/mesa/swrast/s_fragprog.c b/src/mesa/swrast/s_fragprog.c
index e421d218d7..e391043f4d 100644
--- a/src/mesa/swrast/s_fragprog.c
+++ b/src/mesa/swrast/s_fragprog.c
@@ -169,7 +169,7 @@ init_machine(struct gl_context *ctx, struct gl_program_machine *machine,
machine->Samplers = program->Base.SamplerUnits;
/* if running a GLSL program (not ARB_fragment_program) */
- if (ctx->Shader.CurrentProgram) {
+ if (ctx->Shader.CurrentFragmentProgram) {
/* Store front/back facing value */
machine->Attribs[FRAG_ATTRIB_FACE][col][0] = 1.0F - span->facing;
}