summaryrefslogtreecommitdiff
path: root/src
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 /src
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.
Diffstat (limited to 'src')
-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;
}