diff options
Diffstat (limited to 'src/mesa/main')
-rw-r--r-- | src/mesa/main/api_validate.c | 57 | ||||
-rw-r--r-- | src/mesa/main/ff_fragment_shader.cpp | 6 | ||||
-rw-r--r-- | src/mesa/main/mtypes.h | 2 | ||||
-rw-r--r-- | src/mesa/main/pipelineobj.c | 76 | ||||
-rw-r--r-- | src/mesa/main/shader_query.cpp | 38 | ||||
-rw-r--r-- | src/mesa/main/shaderapi.c | 104 | ||||
-rw-r--r-- | src/mesa/main/shaderapi.h | 9 | ||||
-rw-r--r-- | src/mesa/main/state.c | 50 | ||||
-rw-r--r-- | src/mesa/main/texstate.c | 5 | ||||
-rw-r--r-- | src/mesa/main/transformfeedback.c | 2 | ||||
-rw-r--r-- | src/mesa/main/uniform_query.cpp | 21 |
11 files changed, 160 insertions, 210 deletions
diff --git a/src/mesa/main/api_validate.c b/src/mesa/main/api_validate.c index 5f051dbec6f..6c95701ea0e 100644 --- a/src/mesa/main/api_validate.c +++ b/src/mesa/main/api_validate.c @@ -191,12 +191,10 @@ _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; - gl_shader_stage i; + struct gl_program **prog = ctx->_Shader->CurrentProgram; - for (i = 0; i < MESA_SHADER_STAGES; i++) { - if (shProg[i] == NULL || shProg[i]->_LinkedShaders[i] == NULL || - shProg[i]->_LinkedShaders[i]->Program->_Used) + for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) { + if (prog[i] == NULL || prog[i]->_Used) continue; /* This is the first time this shader is being used. @@ -208,12 +206,12 @@ _mesa_valid_to_render(struct gl_context *ctx, const char *where) * program isn't also bound to the fragment shader target we don't * want to log its fragment data. */ - _mesa_append_uniforms_to_file(shProg[i]->_LinkedShaders[i]->Program); + _mesa_append_uniforms_to_file(prog[i]); } - for (i = 0; i < MESA_SHADER_STAGES; i++) { - if (shProg[i] != NULL && shProg[i]->_LinkedShaders[i] != NULL) - shProg[i]->_LinkedShaders[i]->Program->_Used = GL_TRUE; + for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) { + if (prog[i] != NULL) + prog[i]->_Used = GL_TRUE; } } #endif @@ -394,17 +392,15 @@ _mesa_valid_prim_mode(struct gl_context *ctx, GLenum mode, const char *name) if (ctx->_Shader->CurrentProgram[MESA_SHADER_GEOMETRY]) { const GLenum geom_mode = ctx->_Shader->CurrentProgram[MESA_SHADER_GEOMETRY]-> - _LinkedShaders[MESA_SHADER_GEOMETRY]->info.Geom.InputType; - struct gl_shader_program *tes = + info.gs.input_primitive; + struct gl_program *tes = ctx->_Shader->CurrentProgram[MESA_SHADER_TESS_EVAL]; GLenum mode_before_gs = mode; if (tes) { - struct gl_linked_shader *tes_sh = - tes->_LinkedShaders[MESA_SHADER_TESS_EVAL]; - if (tes_sh->info.TessEval.PointMode) + if (tes->info.tess.point_mode) mode_before_gs = GL_POINTS; - else if (tes_sh->info.TessEval.PrimitiveMode == GL_ISOLINES) + else if (tes->info.tess.primitive_mode == GL_ISOLINES) mode_before_gs = GL_LINES; else /* the GL_QUADS mode generates triangles too */ @@ -501,8 +497,7 @@ _mesa_valid_prim_mode(struct gl_context *ctx, GLenum mode, const char *name) if(ctx->_Shader->CurrentProgram[MESA_SHADER_GEOMETRY]) { switch (ctx->_Shader->CurrentProgram[MESA_SHADER_GEOMETRY]-> - _LinkedShaders[MESA_SHADER_GEOMETRY]-> - info.Geom.OutputType) { + info.gs.output_primitive) { case GL_POINTS: pass = ctx->TransformFeedback.Mode == GL_POINTS; break; @@ -517,13 +512,11 @@ _mesa_valid_prim_mode(struct gl_context *ctx, GLenum mode, const char *name) } } else if (ctx->_Shader->CurrentProgram[MESA_SHADER_TESS_EVAL]) { - struct gl_shader_program *tes = + struct gl_program *tes = ctx->_Shader->CurrentProgram[MESA_SHADER_TESS_EVAL]; - struct gl_linked_shader *tes_sh = - tes->_LinkedShaders[MESA_SHADER_TESS_EVAL]; - if (tes_sh->info.TessEval.PointMode) + if (tes->info.tess.point_mode) pass = ctx->TransformFeedback.Mode == GL_POINTS; - else if (tes_sh->info.TessEval.PrimitiveMode == GL_ISOLINES) + else if (tes->info.tess.primitive_mode == GL_ISOLINES) pass = ctx->TransformFeedback.Mode == GL_LINES; else pass = ctx->TransformFeedback.Mode == GL_TRIANGLES; @@ -1296,8 +1289,6 @@ _mesa_validate_MultiDrawElementsIndirectCount(struct gl_context *ctx, static bool check_valid_to_compute(struct gl_context *ctx, const char *function) { - struct gl_shader_program *prog; - if (!_mesa_has_compute_shaders(ctx)) { _mesa_error(ctx, GL_INVALID_OPERATION, "unsupported function (%s) called", @@ -1310,8 +1301,7 @@ check_valid_to_compute(struct gl_context *ctx, const char *function) * "An INVALID_OPERATION error is generated if there is no active program * for the compute shader stage." */ - prog = ctx->_Shader->CurrentProgram[MESA_SHADER_COMPUTE]; - if (prog == NULL || prog->_LinkedShaders[MESA_SHADER_COMPUTE] == NULL) { + if (ctx->_Shader->CurrentProgram[MESA_SHADER_COMPUTE] == NULL) { _mesa_error(ctx, GL_INVALID_OPERATION, "%s(no active compute shader)", function); @@ -1325,7 +1315,6 @@ GLboolean _mesa_validate_DispatchCompute(struct gl_context *ctx, const GLuint *num_groups) { - struct gl_shader_program *prog; int i; FLUSH_CURRENT(ctx, 0); @@ -1363,8 +1352,8 @@ _mesa_validate_DispatchCompute(struct gl_context *ctx, * "An INVALID_OPERATION error is generated by DispatchCompute if the active * program for the compute shader stage has a variable work group size." */ - prog = ctx->_Shader->CurrentProgram[MESA_SHADER_COMPUTE]; - if (prog->Comp.LocalSizeVariable) { + struct gl_program *prog = ctx->_Shader->CurrentProgram[MESA_SHADER_COMPUTE]; + if (prog->info.cs.local_size_variable) { _mesa_error(ctx, GL_INVALID_OPERATION, "glDispatchCompute(variable work group size forbidden)"); return GL_FALSE; @@ -1378,7 +1367,6 @@ _mesa_validate_DispatchComputeGroupSizeARB(struct gl_context *ctx, const GLuint *num_groups, const GLuint *group_size) { - struct gl_shader_program *prog; GLuint total_invocations = 1; int i; @@ -1393,8 +1381,8 @@ _mesa_validate_DispatchComputeGroupSizeARB(struct gl_context *ctx, * DispatchComputeGroupSizeARB if the active program for the compute * shader stage has a fixed work group size." */ - prog = ctx->_Shader->CurrentProgram[MESA_SHADER_COMPUTE]; - if (!prog->Comp.LocalSizeVariable) { + struct gl_program *prog = ctx->_Shader->CurrentProgram[MESA_SHADER_COMPUTE]; + if (!prog->info.cs.local_size_variable) { _mesa_error(ctx, GL_INVALID_OPERATION, "glDispatchComputeGroupSizeARB(fixed work group size " "forbidden)"); @@ -1462,7 +1450,6 @@ valid_dispatch_indirect(struct gl_context *ctx, GLsizei size, const char *name) { const uint64_t end = (uint64_t) indirect + size; - struct gl_shader_program *prog; if (!check_valid_to_compute(ctx, name)) return GL_FALSE; @@ -1513,8 +1500,8 @@ valid_dispatch_indirect(struct gl_context *ctx, * "An INVALID_OPERATION error is generated if the active program for the * compute shader stage has a variable work group size." */ - prog = ctx->_Shader->CurrentProgram[MESA_SHADER_COMPUTE]; - if (prog->Comp.LocalSizeVariable) { + struct gl_program *prog = ctx->_Shader->CurrentProgram[MESA_SHADER_COMPUTE]; + if (prog->info.cs.local_size_variable) { _mesa_error(ctx, GL_INVALID_OPERATION, "%s(variable work group size forbidden)", name); return GL_FALSE; diff --git a/src/mesa/main/ff_fragment_shader.cpp b/src/mesa/main/ff_fragment_shader.cpp index 6261b9cacc5..b2942f1aada 100644 --- a/src/mesa/main/ff_fragment_shader.cpp +++ b/src/mesa/main/ff_fragment_shader.cpp @@ -300,9 +300,7 @@ static GLbitfield get_fp_input_mask( struct gl_context *ctx ) { /* _NEW_PROGRAM */ const GLboolean vertexShader = - (ctx->_Shader->CurrentProgram[MESA_SHADER_VERTEX] && - ctx->_Shader->CurrentProgram[MESA_SHADER_VERTEX]->data->LinkStatus && - ctx->_Shader->CurrentProgram[MESA_SHADER_VERTEX]->_LinkedShaders[MESA_SHADER_VERTEX]); + ctx->_Shader->CurrentProgram[MESA_SHADER_VERTEX] != NULL; const GLboolean vertexProgram = ctx->VertexProgram._Enabled; GLbitfield fp_inputs = 0x0; @@ -366,7 +364,7 @@ static GLbitfield get_fp_input_mask( struct gl_context *ctx ) * validation (see additional comments in state.c). */ if (vertexShader) - vprog = ctx->_Shader->CurrentProgram[MESA_SHADER_VERTEX]->_LinkedShaders[MESA_SHADER_VERTEX]->Program; + vprog = ctx->_Shader->CurrentProgram[MESA_SHADER_VERTEX]; else vprog = ctx->VertexProgram.Current; diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index 7784d2548d2..c733911c476 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -2907,7 +2907,7 @@ struct gl_pipeline_object * * There is a separate program set for each shader stage. */ - struct gl_shader_program *CurrentProgram[MESA_SHADER_STAGES]; + struct gl_program *CurrentProgram[MESA_SHADER_STAGES]; struct gl_program *_CurrentFragmentProgram; diff --git a/src/mesa/main/pipelineobj.c b/src/mesa/main/pipelineobj.c index e777f991589..ec5df896c09 100644 --- a/src/mesa/main/pipelineobj.c +++ b/src/mesa/main/pipelineobj.c @@ -61,7 +61,7 @@ _mesa_delete_pipeline_object(struct gl_context *ctx, _mesa_reference_program(ctx, &obj->_CurrentFragmentProgram, NULL); for (i = 0; i < MESA_SHADER_STAGES; i++) - _mesa_reference_shader_program(ctx, &obj->CurrentProgram[i], NULL); + _mesa_reference_program(ctx, &obj->CurrentProgram[i], NULL); _mesa_reference_shader_program(ctx, &obj->ActiveProgram, NULL); mtx_destroy(&obj->Mutex); @@ -218,6 +218,18 @@ _mesa_reference_pipeline_object_(struct gl_context *ctx, } } +static void +use_program_stage(struct gl_context *ctx, GLenum type, + struct gl_shader_program *shProg, + struct gl_pipeline_object *pipe) { + gl_shader_stage stage = _mesa_shader_enum_to_shader_stage(type); + struct gl_program *prog = NULL; + if (shProg && shProg->_LinkedShaders[stage]) + prog = shProg->_LinkedShaders[stage]->Program; + + _mesa_use_program(ctx, stage, prog, pipe); +} + /** * Bound program to severals stages of the pipeline */ @@ -325,22 +337,22 @@ _mesa_UseProgramStages(GLuint pipeline, GLbitfield stages, GLuint program) * configured for the indicated shader stages." */ if ((stages & GL_VERTEX_SHADER_BIT) != 0) - _mesa_use_shader_program(ctx, GL_VERTEX_SHADER, shProg, pipe); + use_program_stage(ctx, GL_VERTEX_SHADER, shProg, pipe); if ((stages & GL_FRAGMENT_SHADER_BIT) != 0) - _mesa_use_shader_program(ctx, GL_FRAGMENT_SHADER, shProg, pipe); + use_program_stage(ctx, GL_FRAGMENT_SHADER, shProg, pipe); if ((stages & GL_GEOMETRY_SHADER_BIT) != 0) - _mesa_use_shader_program(ctx, GL_GEOMETRY_SHADER, shProg, pipe); + use_program_stage(ctx, GL_GEOMETRY_SHADER, shProg, pipe); if ((stages & GL_TESS_CONTROL_SHADER_BIT) != 0) - _mesa_use_shader_program(ctx, GL_TESS_CONTROL_SHADER, shProg, pipe); + use_program_stage(ctx, GL_TESS_CONTROL_SHADER, shProg, pipe); if ((stages & GL_TESS_EVALUATION_SHADER_BIT) != 0) - _mesa_use_shader_program(ctx, GL_TESS_EVALUATION_SHADER, shProg, pipe); + use_program_stage(ctx, GL_TESS_EVALUATION_SHADER, shProg, pipe); if ((stages & GL_COMPUTE_SHADER_BIT) != 0) - _mesa_use_shader_program(ctx, GL_COMPUTE_SHADER, shProg, pipe); + use_program_stage(ctx, GL_COMPUTE_SHADER, shProg, pipe); pipe->Validated = false; } @@ -469,11 +481,9 @@ _mesa_bind_pipeline(struct gl_context *ctx, FLUSH_VERTICES(ctx, _NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS); for (i = 0; i < MESA_SHADER_STAGES; i++) { - if (ctx->_Shader->CurrentProgram[i]) { - struct gl_linked_shader *sh = - ctx->_Shader->CurrentProgram[i]->_LinkedShaders[i]; - if (sh) - _mesa_program_init_subroutine_defaults(ctx, sh->Program); + struct gl_program *prog = ctx->_Shader->CurrentProgram[i]; + if (prog) { + _mesa_program_init_subroutine_defaults(ctx, prog); } } } @@ -659,35 +669,35 @@ _mesa_GetProgramPipelineiv(GLuint pipeline, GLenum pname, GLint *params) return; case GL_VERTEX_SHADER: *params = pipe->CurrentProgram[MESA_SHADER_VERTEX] - ? pipe->CurrentProgram[MESA_SHADER_VERTEX]->Name : 0; + ? pipe->CurrentProgram[MESA_SHADER_VERTEX]->Id : 0; return; case GL_TESS_EVALUATION_SHADER: if (!has_tess) break; *params = pipe->CurrentProgram[MESA_SHADER_TESS_EVAL] - ? pipe->CurrentProgram[MESA_SHADER_TESS_EVAL]->Name : 0; + ? pipe->CurrentProgram[MESA_SHADER_TESS_EVAL]->Id : 0; return; case GL_TESS_CONTROL_SHADER: if (!has_tess) break; *params = pipe->CurrentProgram[MESA_SHADER_TESS_CTRL] - ? pipe->CurrentProgram[MESA_SHADER_TESS_CTRL]->Name : 0; + ? pipe->CurrentProgram[MESA_SHADER_TESS_CTRL]->Id : 0; return; case GL_GEOMETRY_SHADER: if (!has_gs) break; *params = pipe->CurrentProgram[MESA_SHADER_GEOMETRY] - ? pipe->CurrentProgram[MESA_SHADER_GEOMETRY]->Name : 0; + ? pipe->CurrentProgram[MESA_SHADER_GEOMETRY]->Id : 0; return; case GL_FRAGMENT_SHADER: *params = pipe->CurrentProgram[MESA_SHADER_FRAGMENT] - ? pipe->CurrentProgram[MESA_SHADER_FRAGMENT]->Name : 0; + ? pipe->CurrentProgram[MESA_SHADER_FRAGMENT]->Id : 0; return; case GL_COMPUTE_SHADER: if (!_mesa_has_compute_shaders(ctx)) break; *params = pipe->CurrentProgram[MESA_SHADER_COMPUTE] - ? pipe->CurrentProgram[MESA_SHADER_COMPUTE]->Name : 0; + ? pipe->CurrentProgram[MESA_SHADER_COMPUTE]->Id : 0; return; default: break; @@ -703,23 +713,22 @@ _mesa_GetProgramPipelineiv(GLuint pipeline, GLenum pname, GLint *params) */ static bool program_stages_all_active(struct gl_pipeline_object *pipe, - const struct gl_shader_program *prog) + const struct gl_program *prog) { - unsigned i; bool status = true; if (!prog) return true; - for (i = 0; i < MESA_SHADER_STAGES; i++) { - if (prog->_LinkedShaders[i]) { - if (pipe->CurrentProgram[i]) { - if (prog->Name != pipe->CurrentProgram[i]->Name) { - status = false; - } - } else { + unsigned mask = prog->sh.data->linked_stages; + while (mask) { + const int i = u_bit_scan(&mask); + if (pipe->CurrentProgram[i]) { + if (prog->Id != pipe->CurrentProgram[i]->Id) { status = false; } + } else { + status = false; } } @@ -727,7 +736,7 @@ program_stages_all_active(struct gl_pipeline_object *pipe, pipe->InfoLog = ralloc_asprintf(pipe, "Program %d is not active for all " "shaders that was linked", - prog->Name); + prog->Id); } return status; @@ -742,7 +751,7 @@ program_stages_interleaved_illegally(const struct gl_pipeline_object *pipe) * sequence of unrelated programs or empty stages. */ for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) { - struct gl_shader_program *cur = pipe->CurrentProgram[i]; + struct gl_program *cur = pipe->CurrentProgram[i]; /* Empty stages anywhere in the pipe are OK. Also we can be confident * that if the linked_stages mask matches we are looking at the same @@ -751,7 +760,7 @@ program_stages_interleaved_illegally(const struct gl_pipeline_object *pipe) * programs with the sames stages linked are not active for all linked * stages. */ - if (!cur || cur->data->linked_stages == prev_linked_stages) + if (!cur || cur->sh.data->linked_stages == prev_linked_stages) continue; if (prev_linked_stages) { @@ -762,7 +771,7 @@ program_stages_interleaved_illegally(const struct gl_pipeline_object *pipe) return true; } - prev_linked_stages = cur->data->linked_stages; + prev_linked_stages = cur->sh.data->linked_stages; } return false; @@ -861,11 +870,12 @@ _mesa_validate_program_pipeline(struct gl_context* ctx, * PROGRAM_SEPARABLE parameter set to FALSE. */ for (i = 0; i < MESA_SHADER_STAGES; i++) { - if (pipe->CurrentProgram[i] && !pipe->CurrentProgram[i]->SeparateShader) { + if (pipe->CurrentProgram[i] && + !pipe->CurrentProgram[i]->info.separate_shader) { pipe->InfoLog = ralloc_asprintf(pipe, "Program %d was relinked without " "PROGRAM_SEPARABLE state", - pipe->CurrentProgram[i]->Name); + pipe->CurrentProgram[i]->Id); return GL_FALSE; } } diff --git a/src/mesa/main/shader_query.cpp b/src/mesa/main/shader_query.cpp index 40107373b80..f465b3959e5 100644 --- a/src/mesa/main/shader_query.cpp +++ b/src/mesa/main/shader_query.cpp @@ -1373,24 +1373,21 @@ _mesa_get_program_resourceiv(struct gl_shader_program *shProg, } static bool -validate_io(struct gl_shader_program *producer, - struct gl_shader_program *consumer, - gl_shader_stage producer_stage, - gl_shader_stage consumer_stage) +validate_io(struct gl_program *producer, struct gl_program *consumer) { - if (producer == consumer) + if (producer->sh.data->linked_stages == consumer->sh.data->linked_stages) return true; const bool nonarray_stage_to_array_stage = - producer_stage != MESA_SHADER_TESS_CTRL && - (consumer_stage == MESA_SHADER_GEOMETRY || - consumer_stage == MESA_SHADER_TESS_CTRL || - consumer_stage == MESA_SHADER_TESS_EVAL); + producer->info.stage != MESA_SHADER_TESS_CTRL && + (consumer->info.stage == MESA_SHADER_GEOMETRY || + consumer->info.stage == MESA_SHADER_TESS_CTRL || + consumer->info.stage == MESA_SHADER_TESS_EVAL); bool valid = true; gl_shader_variable const **outputs = - (gl_shader_variable const **) calloc(producer->data->NumProgramResourceList, + (gl_shader_variable const **) calloc(producer->sh.data->NumProgramResourceList, sizeof(gl_shader_variable *)); if (outputs == NULL) return false; @@ -1413,9 +1410,9 @@ validate_io(struct gl_shader_program *producer, * some output that did not have an input. */ unsigned num_outputs = 0; - for (unsigned i = 0; i < producer->data->NumProgramResourceList; i++) { + for (unsigned i = 0; i < producer->sh.data->NumProgramResourceList; i++) { struct gl_program_resource *res = - &producer->data->ProgramResourceList[i]; + &producer->sh.data->ProgramResourceList[i]; if (res->Type != GL_PROGRAM_OUTPUT) continue; @@ -1434,9 +1431,9 @@ validate_io(struct gl_shader_program *producer, } unsigned match_index = 0; - for (unsigned i = 0; i < consumer->data->NumProgramResourceList; i++) { + for (unsigned i = 0; i < consumer->sh.data->NumProgramResourceList; i++) { struct gl_program_resource *res = - &consumer->data->ProgramResourceList[i]; + &consumer->sh.data->ProgramResourceList[i]; if (res->Type != GL_PROGRAM_INPUT) continue; @@ -1592,30 +1589,27 @@ validate_io(struct gl_shader_program *producer, extern "C" bool _mesa_validate_pipeline_io(struct gl_pipeline_object *pipeline) { - struct gl_shader_program **shProg = - (struct gl_shader_program **) pipeline->CurrentProgram; + struct gl_program **prog = (struct gl_program **) pipeline->CurrentProgram; /* Find first active stage in pipeline. */ unsigned idx, prev = 0; for (idx = 0; idx < ARRAY_SIZE(pipeline->CurrentProgram); idx++) { - if (shProg[idx]) { + if (prog[idx]) { prev = idx; break; } } for (idx = prev + 1; idx < ARRAY_SIZE(pipeline->CurrentProgram); idx++) { - if (shProg[idx]) { + if (prog[idx]) { /* Pipeline might include both non-compute and a compute program, do * not attempt to validate varyings between non-compute and compute * stage. */ - if (shProg[idx]->_LinkedShaders[idx]->Stage == MESA_SHADER_COMPUTE) + if (prog[idx]->info.stage == MESA_SHADER_COMPUTE) break; - if (!validate_io(shProg[prev], shProg[idx], - shProg[prev]->_LinkedShaders[prev]->Stage, - shProg[idx]->_LinkedShaders[idx]->Stage)) + if (!validate_io(prog[prev], prog[idx])) return false; prev = idx; diff --git a/src/mesa/main/shaderapi.c b/src/mesa/main/shaderapi.c index c87ba0946ca..8ad4e36a309 100644 --- a/src/mesa/main/shaderapi.c +++ b/src/mesa/main/shaderapi.c @@ -156,10 +156,8 @@ _mesa_init_shader_state(struct gl_context *ctx) void _mesa_free_shader_state(struct gl_context *ctx) { - int i; - for (i = 0; i < MESA_SHADER_STAGES; i++) { - _mesa_reference_shader_program(ctx, &ctx->Shader.CurrentProgram[i], - NULL); + for (int i = 0; i < MESA_SHADER_STAGES; i++) { + _mesa_reference_program(ctx, &ctx->Shader.CurrentProgram[i], NULL); } _mesa_reference_program(ctx, &ctx->Shader._CurrentFragmentProgram, NULL); _mesa_reference_shader_program(ctx, &ctx->Shader.ActiveProgram, NULL); @@ -1100,7 +1098,8 @@ _mesa_link_program(struct gl_context *ctx, struct gl_shader_program *shProg) unsigned programs_in_use = 0; if (ctx->_Shader) for (unsigned stage = 0; stage < MESA_SHADER_STAGES; stage++) { - if (ctx->_Shader->CurrentProgram[stage] == shProg) { + if (ctx->_Shader->CurrentProgram[stage] && + ctx->_Shader->CurrentProgram[stage]->Id == shProg->Name) { programs_in_use |= 1 << stage; } } @@ -1119,7 +1118,15 @@ _mesa_link_program(struct gl_context *ctx, struct gl_shader_program *shProg) * is attached." */ if (shProg->data->LinkStatus && programs_in_use) { - ctx->NewState |= _NEW_PROGRAM; + while (programs_in_use) { + const int stage = u_bit_scan(&programs_in_use); + + struct gl_program *prog = NULL; + if (shProg->_LinkedShaders[stage]) + prog = shProg->_LinkedShaders[stage]->Program; + + _mesa_use_program(ctx, stage, prog, ctx->_Shader); + } } /* Capture .shader_test files. */ @@ -1232,27 +1239,17 @@ _mesa_active_program(struct gl_context *ctx, struct gl_shader_program *shProg, static void -use_shader_program(struct gl_context *ctx, gl_shader_stage stage, - struct gl_shader_program *shProg, - struct gl_pipeline_object *shTarget) +use_program(struct gl_context *ctx, gl_shader_stage stage, + struct gl_program *new_prog, struct gl_pipeline_object *shTarget) { - struct gl_shader_program **target; + struct gl_program **target; target = &shTarget->CurrentProgram[stage]; - if ((shProg != NULL) && (shProg->_LinkedShaders[stage] == NULL)) - shProg = NULL; - - if (shProg) { - for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) { - struct gl_linked_shader *sh = shProg->_LinkedShaders[i]; - if (!sh) - continue; - - _mesa_program_init_subroutine_defaults(ctx, sh->Program); - } + if (new_prog) { + _mesa_program_init_subroutine_defaults(ctx, new_prog); } - if (*target != shProg) { + if (*target != new_prog) { /* Program is current, flush it */ if (shTarget == ctx->_Shader) { FLUSH_VERTICES(ctx, _NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS); @@ -1271,10 +1268,7 @@ use_shader_program(struct gl_context *ctx, gl_shader_stage stage, /* Empty for now. */ break; case MESA_SHADER_FRAGMENT: - if (*target != NULL && - ((*target)->_LinkedShaders[MESA_SHADER_FRAGMENT] && - (*target)->_LinkedShaders[MESA_SHADER_FRAGMENT]->Program == - ctx->_Shader->_CurrentFragmentProgram)) { + if (*target == ctx->_Shader->_CurrentFragmentProgram) { _mesa_reference_program(ctx, &ctx->_Shader->_CurrentFragmentProgram, NULL); @@ -1282,7 +1276,7 @@ use_shader_program(struct gl_context *ctx, gl_shader_stage stage, break; } - _mesa_reference_shader_program(ctx, target, shProg); + _mesa_reference_program(ctx, target, new_prog); return; } } @@ -1292,11 +1286,15 @@ use_shader_program(struct gl_context *ctx, gl_shader_stage stage, * Use the named shader program for subsequent rendering. */ void -_mesa_use_program(struct gl_context *ctx, struct gl_shader_program *shProg) +_mesa_use_shader_program(struct gl_context *ctx, + struct gl_shader_program *shProg) { - int i; - for (i = 0; i < MESA_SHADER_STAGES; i++) - use_shader_program(ctx, i, shProg, &ctx->Shader); + for (int i = 0; i < MESA_SHADER_STAGES; i++) { + struct gl_program *new_prog = NULL; + if (shProg && shProg->_LinkedShaders[i]) + new_prog = shProg->_LinkedShaders[i]->Program; + use_program(ctx, i, new_prog, &ctx->Shader); + } _mesa_active_program(ctx, shProg, "glUseProgram"); } @@ -1893,10 +1891,10 @@ _mesa_UseProgram(GLuint program) /* Attach shader state to the binding point */ _mesa_reference_pipeline_object(ctx, &ctx->_Shader, &ctx->Shader); /* Update the program */ - _mesa_use_program(ctx, shProg); + _mesa_use_shader_program(ctx, shProg); } else { /* Must be done first: detach the progam */ - _mesa_use_program(ctx, shProg); + _mesa_use_shader_program(ctx, shProg); /* Unattach shader_state binding point */ _mesa_reference_pipeline_object(ctx, &ctx->_Shader, ctx->Pipeline.Default); /* If a pipeline was bound, rebind it */ @@ -2178,12 +2176,11 @@ invalid_value: void -_mesa_use_shader_program(struct gl_context *ctx, GLenum type, - struct gl_shader_program *shProg, - struct gl_pipeline_object *shTarget) +_mesa_use_program(struct gl_context *ctx, gl_shader_stage stage, + struct gl_program *prog, + struct gl_pipeline_object *shTarget) { - gl_shader_stage stage = _mesa_shader_enum_to_shader_stage(type); - use_shader_program(ctx, stage, shProg, shTarget); + use_program(ctx, stage, prog, shTarget); } @@ -2612,8 +2609,6 @@ _mesa_UniformSubroutinesuiv(GLenum shadertype, GLsizei count, { GET_CURRENT_CONTEXT(ctx); const char *api_name = "glUniformSubroutinesuiv"; - struct gl_shader_program *shProg; - struct gl_linked_shader *sh; gl_shader_stage stage; int i; @@ -2628,19 +2623,12 @@ _mesa_UniformSubroutinesuiv(GLenum shadertype, GLsizei count, } stage = _mesa_shader_enum_to_shader_stage(shadertype); - shProg = ctx->_Shader->CurrentProgram[stage]; - if (!shProg) { - _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name); - return; - } - - sh = shProg->_LinkedShaders[stage]; - if (!sh) { + struct gl_program *p = ctx->_Shader->CurrentProgram[stage]; + if (!p) { _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name); return; } - struct gl_program *p = shProg->_LinkedShaders[stage]->Program; if (count != p->sh.NumSubroutineUniformRemapTable) { _mesa_error(ctx, GL_INVALID_VALUE, "%s", api_name); return; @@ -2697,8 +2685,6 @@ _mesa_GetUniformSubroutineuiv(GLenum shadertype, GLint location, { GET_CURRENT_CONTEXT(ctx); const char *api_name = "glGetUniformSubroutineuiv"; - struct gl_shader_program *shProg; - struct gl_linked_shader *sh; gl_shader_stage stage; if (!_mesa_has_ARB_shader_subroutine(ctx)) { @@ -2712,19 +2698,12 @@ _mesa_GetUniformSubroutineuiv(GLenum shadertype, GLint location, } stage = _mesa_shader_enum_to_shader_stage(shadertype); - shProg = ctx->_Shader->CurrentProgram[stage]; - if (!shProg) { - _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name); - return; - } - - sh = shProg->_LinkedShaders[stage]; - if (!sh) { + struct gl_program *p = ctx->_Shader->CurrentProgram[stage]; + if (!p) { _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name); return; } - struct gl_program *p = sh->Program; if (location >= p->sh.NumSubroutineUniformRemapTable) { _mesa_error(ctx, GL_INVALID_VALUE, "%s", api_name); return; @@ -2890,10 +2869,9 @@ void _mesa_shader_write_subroutine_indices(struct gl_context *ctx, gl_shader_stage stage) { - if (ctx->_Shader->CurrentProgram[stage] && - ctx->_Shader->CurrentProgram[stage]->_LinkedShaders[stage]) + if (ctx->_Shader->CurrentProgram[stage]) _mesa_shader_write_subroutine_index(ctx, - ctx->_Shader->CurrentProgram[stage]->_LinkedShaders[stage]->Program); + ctx->_Shader->CurrentProgram[stage]); } void diff --git a/src/mesa/main/shaderapi.h b/src/mesa/main/shaderapi.h index 06de11ff766..a89dbfb564c 100644 --- a/src/mesa/main/shaderapi.h +++ b/src/mesa/main/shaderapi.h @@ -51,7 +51,8 @@ _mesa_copy_string(GLchar *dst, GLsizei maxLength, GLsizei *length, const GLchar *src); extern void -_mesa_use_program(struct gl_context *ctx, struct gl_shader_program *shProg); +_mesa_use_shader_program(struct gl_context *ctx, + struct gl_shader_program *shProg); extern void _mesa_active_program(struct gl_context *ctx, struct gl_shader_program *shProg, @@ -213,9 +214,9 @@ extern void GLAPIENTRY _mesa_ProgramParameteri(GLuint program, GLenum pname, GLint value); void -_mesa_use_shader_program(struct gl_context *ctx, GLenum type, - struct gl_shader_program *shProg, - struct gl_pipeline_object *shTarget); +_mesa_use_program(struct gl_context *ctx, gl_shader_stage stage, + struct gl_program *prog, + struct gl_pipeline_object *shTarget); extern void _mesa_copy_linked_program_data(const struct gl_shader_program *src, diff --git a/src/mesa/main/state.c b/src/mesa/main/state.c index 2a926a182b9..5cb58a469bb 100644 --- a/src/mesa/main/state.c +++ b/src/mesa/main/state.c @@ -95,17 +95,17 @@ update_program_enables(struct gl_context *ctx) static GLbitfield update_program(struct gl_context *ctx) { - const struct gl_shader_program *vsProg = + struct gl_program *vsProg = ctx->_Shader->CurrentProgram[MESA_SHADER_VERTEX]; - const struct gl_shader_program *tcsProg = + struct gl_program *tcsProg = ctx->_Shader->CurrentProgram[MESA_SHADER_TESS_CTRL]; - const struct gl_shader_program *tesProg = + struct gl_program *tesProg = ctx->_Shader->CurrentProgram[MESA_SHADER_TESS_EVAL]; - const struct gl_shader_program *gsProg = + struct gl_program *gsProg = ctx->_Shader->CurrentProgram[MESA_SHADER_GEOMETRY]; - struct gl_shader_program *fsProg = + struct gl_program *fsProg = ctx->_Shader->CurrentProgram[MESA_SHADER_FRAGMENT]; - const struct gl_shader_program *csProg = + struct gl_program *csProg = ctx->_Shader->CurrentProgram[MESA_SHADER_COMPUTE]; const struct gl_program *prevVP = ctx->VertexProgram._Current; const struct gl_program *prevFP = ctx->FragmentProgram._Current; @@ -132,13 +132,11 @@ update_program(struct gl_context *ctx) * come up, or matter. */ - if (fsProg && fsProg->data->LinkStatus - && fsProg->_LinkedShaders[MESA_SHADER_FRAGMENT]) { + if (fsProg) { /* Use GLSL fragment shader */ _mesa_reference_program(ctx, &ctx->_Shader->_CurrentFragmentProgram, - fsProg->_LinkedShaders[MESA_SHADER_FRAGMENT]->Program); - _mesa_reference_program(ctx, &ctx->FragmentProgram._Current, - fsProg->_LinkedShaders[MESA_SHADER_FRAGMENT]->Program); + fsProg); + _mesa_reference_program(ctx, &ctx->FragmentProgram._Current, fsProg); _mesa_reference_program(ctx, &ctx->FragmentProgram._TexEnvProgram, NULL); } @@ -179,32 +177,26 @@ update_program(struct gl_context *ctx) NULL); } - if (gsProg && gsProg->data->LinkStatus - && gsProg->_LinkedShaders[MESA_SHADER_GEOMETRY]) { + if (gsProg) { /* Use GLSL geometry shader */ - _mesa_reference_program(ctx, &ctx->GeometryProgram._Current, - gsProg->_LinkedShaders[MESA_SHADER_GEOMETRY]->Program); + _mesa_reference_program(ctx, &ctx->GeometryProgram._Current, gsProg); } else { /* No geometry program */ _mesa_reference_program(ctx, &ctx->GeometryProgram._Current, NULL); } - if (tesProg && tesProg->data->LinkStatus - && tesProg->_LinkedShaders[MESA_SHADER_TESS_EVAL]) { + if (tesProg) { /* Use GLSL tessellation evaluation shader */ - _mesa_reference_program(ctx, &ctx->TessEvalProgram._Current, - tesProg->_LinkedShaders[MESA_SHADER_TESS_EVAL]->Program); + _mesa_reference_program(ctx, &ctx->TessEvalProgram._Current, tesProg); } else { /* No tessellation evaluation program */ _mesa_reference_program(ctx, &ctx->TessEvalProgram._Current, NULL); } - if (tcsProg && tcsProg->data->LinkStatus - && tcsProg->_LinkedShaders[MESA_SHADER_TESS_CTRL]) { + if (tcsProg) { /* Use GLSL tessellation control shader */ - _mesa_reference_program(ctx, &ctx->TessCtrlProgram._Current, - tcsProg->_LinkedShaders[MESA_SHADER_TESS_CTRL]->Program); + _mesa_reference_program(ctx, &ctx->TessCtrlProgram._Current, tcsProg); } else { /* No tessellation control program */ @@ -215,11 +207,9 @@ update_program(struct gl_context *ctx) * _mesa_get_fixed_func_vertex_program() needs to know active * fragprog inputs. */ - if (vsProg && vsProg->data->LinkStatus - && vsProg->_LinkedShaders[MESA_SHADER_VERTEX]) { + if (vsProg) { /* Use GLSL vertex shader */ - _mesa_reference_program(ctx, &ctx->VertexProgram._Current, - vsProg->_LinkedShaders[MESA_SHADER_VERTEX]->Program); + _mesa_reference_program(ctx, &ctx->VertexProgram._Current, vsProg); } else if (ctx->VertexProgram._Enabled) { /* Use user-defined vertex program */ @@ -238,11 +228,9 @@ update_program(struct gl_context *ctx) _mesa_reference_program(ctx, &ctx->VertexProgram._Current, NULL); } - if (csProg && csProg->data->LinkStatus - && csProg->_LinkedShaders[MESA_SHADER_COMPUTE]) { + if (csProg) { /* Use GLSL compute shader */ - _mesa_reference_program(ctx, &ctx->ComputeProgram._Current, - csProg->_LinkedShaders[MESA_SHADER_COMPUTE]->Program); + _mesa_reference_program(ctx, &ctx->ComputeProgram._Current, csProg); } else { /* no compute program */ _mesa_reference_program(ctx, &ctx->ComputeProgram._Current, NULL); diff --git a/src/mesa/main/texstate.c b/src/mesa/main/texstate.c index 4676d4aa0d9..be73fc33db6 100644 --- a/src/mesa/main/texstate.c +++ b/src/mesa/main/texstate.c @@ -700,9 +700,8 @@ update_texture_state( struct gl_context *ctx ) BITSET_DECLARE(enabled_texture_units, MAX_COMBINED_TEXTURE_IMAGE_UNITS); for (i = 0; i < MESA_SHADER_STAGES; i++) { - if (ctx->_Shader->CurrentProgram[i] && - ctx->_Shader->CurrentProgram[i]->data->LinkStatus) { - prog[i] = ctx->_Shader->CurrentProgram[i]->_LinkedShaders[i]->Program; + if (ctx->_Shader->CurrentProgram[i]) { + prog[i] = ctx->_Shader->CurrentProgram[i]; } else { if (i == MESA_SHADER_FRAGMENT && ctx->FragmentProgram._Enabled) prog[i] = ctx->FragmentProgram.Current; diff --git a/src/mesa/main/transformfeedback.c b/src/mesa/main/transformfeedback.c index 771223aff99..06fa56ab993 100644 --- a/src/mesa/main/transformfeedback.c +++ b/src/mesa/main/transformfeedback.c @@ -390,7 +390,7 @@ get_xfb_source(struct gl_context *ctx) int i; for (i = MESA_SHADER_GEOMETRY; i >= MESA_SHADER_VERTEX; i--) { if (ctx->_Shader->CurrentProgram[i] != NULL) - return ctx->_Shader->CurrentProgram[i]->_LinkedShaders[i]->Program; + return ctx->_Shader->CurrentProgram[i]; } return NULL; } diff --git a/src/mesa/main/uniform_query.cpp b/src/mesa/main/uniform_query.cpp index f505986fcfc..d5a2d0f58bc 100644 --- a/src/mesa/main/uniform_query.cpp +++ b/src/mesa/main/uniform_query.cpp @@ -1163,27 +1163,22 @@ _mesa_sampler_uniforms_pipeline_are_valid(struct gl_pipeline_object *pipeline) GLbitfield mask; GLbitfield TexturesUsed[MAX_COMBINED_TEXTURE_IMAGE_UNITS]; - struct gl_linked_shader *shader; unsigned active_samplers = 0; - const struct gl_shader_program **shProg = - (const struct gl_shader_program **) pipeline->CurrentProgram; + const struct gl_program **prog = + (const struct gl_program **) pipeline->CurrentProgram; memset(TexturesUsed, 0, sizeof(TexturesUsed)); for (unsigned idx = 0; idx < ARRAY_SIZE(pipeline->CurrentProgram); idx++) { - if (!shProg[idx]) + if (!prog[idx]) continue; - shader = shProg[idx]->_LinkedShaders[idx]; - if (!shader || !shader->Program) - continue; - - mask = shader->Program->SamplersUsed; + mask = prog[idx]->SamplersUsed; while (mask) { const int s = u_bit_scan(&mask); - GLuint unit = shader->Program->SamplerUnits[s]; - GLuint tgt = shader->Program->sh.SamplerTargets[s]; + GLuint unit = prog[idx]->SamplerUnits[s]; + GLuint tgt = prog[idx]->sh.SamplerTargets[s]; /* FIXME: Samplers are initialized to 0 and Mesa doesn't do a * great job of eliminating unused uniforms currently so for now @@ -1197,14 +1192,14 @@ _mesa_sampler_uniforms_pipeline_are_valid(struct gl_pipeline_object *pipeline) ralloc_asprintf(pipeline, "Program %d: " "Texture unit %d is accessed with 2 different types", - shProg[idx]->Name, unit); + prog[idx]->Id, unit); return false; } TexturesUsed[unit] |= (1 << tgt); } - active_samplers += shader->Program->info.num_textures; + active_samplers += prog[idx]->info.num_textures; } if (active_samplers > MAX_COMBINED_TEXTURE_IMAGE_UNITS) { |