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.
This commit is contained in:
parent
75c6f47288
commit
84eba3ef71
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 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.CurrentGeometryProgram) {
|
||||
geom_from_glsl_shader = true;
|
||||
|
||||
if (!ctx->Shader.CurrentGeometryProgram->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.CurrentGeometryProgram,
|
||||
errMsg)) {
|
||||
_mesa_warning(ctx, "Shader program %u is invalid: %s",
|
||||
ctx->Shader.CurrentGeometryProgram->Name, errMsg);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (ctx->Shader.CurrentFragmentProgram) {
|
||||
frag_from_glsl_shader = true;
|
||||
|
||||
if (!ctx->Shader.CurrentFragmentProgram->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.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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
|
@ -926,6 +933,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.
|
||||
*/
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -496,22 +496,27 @@ 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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue