aboutsummaryrefslogtreecommitdiffstats
path: root/src/mesa/main
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/main')
-rw-r--r--src/mesa/main/api_validate.c57
-rw-r--r--src/mesa/main/ff_fragment_shader.cpp6
-rw-r--r--src/mesa/main/mtypes.h2
-rw-r--r--src/mesa/main/pipelineobj.c76
-rw-r--r--src/mesa/main/shader_query.cpp38
-rw-r--r--src/mesa/main/shaderapi.c104
-rw-r--r--src/mesa/main/shaderapi.h9
-rw-r--r--src/mesa/main/state.c50
-rw-r--r--src/mesa/main/texstate.c5
-rw-r--r--src/mesa/main/transformfeedback.c2
-rw-r--r--src/mesa/main/uniform_query.cpp21
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) {