diff options
author | Ian Romanick <[email protected]> | 2010-10-14 13:28:42 -0700 |
---|---|---|
committer | Ian Romanick <[email protected]> | 2010-10-14 17:16:59 -0700 |
commit | 3322fbaf3b5e305ce00c1d08c26965bb98e0cef0 (patch) | |
tree | 30aba427f916748177148fb74e495619c527e8a6 /src/glsl/linker.cpp | |
parent | 4b4284c9c9b472f750663352485290c22f8c3921 (diff) |
glsl: Slightly change the semantic of _LinkedShaders
Previously _LinkedShaders was a compact array of the linked shaders
for each shader stage. Now it is arranged such that each slot,
indexed by the MESA_SHADER_* defines, refers to a specific shader
stage. As a result, some slots will be NULL. This makes things a
little more complex in the linker, but it simplifies things in other
places.
As a side effect _NumLinkedShaders is removed.
NOTE: This may be a candidate for the 7.9 branch. If there are other
patches that get backported to 7.9 that use _LinkedShader, this patch
should be cherry picked also.
Diffstat (limited to 'src/glsl/linker.cpp')
-rw-r--r-- | src/glsl/linker.cpp | 83 |
1 files changed, 64 insertions, 19 deletions
diff --git a/src/glsl/linker.cpp b/src/glsl/linker.cpp index db1b76b3716..ffff08b17bf 100644 --- a/src/glsl/linker.cpp +++ b/src/glsl/linker.cpp @@ -80,6 +80,10 @@ extern "C" { #include "linker.h" #include "ir_optimization.h" +extern "C" { +#include "main/shaderobj.h" +} + /** * Visitor that determines whether or not a variable is ever written. */ @@ -321,6 +325,9 @@ cross_validate_globals(struct gl_shader_program *prog, */ glsl_symbol_table variables; for (unsigned i = 0; i < num_shaders; i++) { + if (shader_list[i] == NULL) + continue; + foreach_list(node, shader_list[i]->ir) { ir_variable *const var = ((ir_instruction *) node)->as_variable(); @@ -420,7 +427,7 @@ bool cross_validate_uniforms(struct gl_shader_program *prog) { return cross_validate_globals(prog, prog->_LinkedShaders, - prog->_NumLinkedShaders, true); + MESA_SHADER_TYPES, true); } @@ -876,7 +883,10 @@ struct uniform_node { static void update_array_sizes(struct gl_shader_program *prog) { - for (unsigned i = 0; i < prog->_NumLinkedShaders; i++) { + for (unsigned i = 0; i < MESA_SHADER_TYPES; i++) { + if (prog->_LinkedShaders[i] == NULL) + continue; + foreach_list(node, prog->_LinkedShaders[i]->ir) { ir_variable *const var = ((ir_instruction *) node)->as_variable(); @@ -887,7 +897,10 @@ update_array_sizes(struct gl_shader_program *prog) continue; unsigned int size = var->max_array_access; - for (unsigned j = 0; j < prog->_NumLinkedShaders; j++) { + for (unsigned j = 0; j < MESA_SHADER_TYPES; j++) { + if (prog->_LinkedShaders[j] == NULL) + continue; + foreach_list(node2, prog->_LinkedShaders[j]->ir) { ir_variable *other_var = ((ir_instruction *) node2)->as_variable(); if (!other_var) @@ -999,7 +1012,10 @@ assign_uniform_locations(struct gl_shader_program *prog) hash_table_string_compare); void *mem_ctx = talloc_new(NULL); - for (unsigned i = 0; i < prog->_NumLinkedShaders; i++) { + for (unsigned i = 0; i < MESA_SHADER_TYPES; i++) { + if (prog->_LinkedShaders[i] == NULL) + continue; + unsigned next_position = 0; foreach_list(node, prog->_LinkedShaders[i]->ir) { @@ -1449,13 +1465,15 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog) prog->Version = max_version; - for (unsigned int i = 0; i < prog->_NumLinkedShaders; i++) { - ctx->Driver.DeleteShader(ctx, prog->_LinkedShaders[i]); + for (unsigned int i = 0; i < MESA_SHADER_TYPES; i++) { + if (prog->_LinkedShaders[i] != NULL) + ctx->Driver.DeleteShader(ctx, prog->_LinkedShaders[i]); + + prog->_LinkedShaders[i] = NULL; } /* Link all shaders for a particular stage and validate the result. */ - prog->_NumLinkedShaders = 0; if (num_vert_shaders > 0) { gl_shader *const sh = link_intrastage_shaders(ctx, prog, vert_shader_list, num_vert_shaders); @@ -1466,8 +1484,8 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog) if (!validate_vertex_shader_executable(prog, sh)) goto done; - prog->_LinkedShaders[prog->_NumLinkedShaders] = sh; - prog->_NumLinkedShaders++; + _mesa_reference_shader(ctx, &prog->_LinkedShaders[MESA_SHADER_VERTEX], + sh); } if (num_frag_shaders > 0) { @@ -1480,8 +1498,8 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog) if (!validate_fragment_shader_executable(prog, sh)) goto done; - prog->_LinkedShaders[prog->_NumLinkedShaders] = sh; - prog->_NumLinkedShaders++; + _mesa_reference_shader(ctx, &prog->_LinkedShaders[MESA_SHADER_FRAGMENT], + sh); } /* Here begins the inter-stage linking phase. Some initial validation is @@ -1489,14 +1507,26 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog) * varyings. */ if (cross_validate_uniforms(prog)) { + unsigned prev; + + for (prev = 0; prev < MESA_SHADER_TYPES; prev++) { + if (prog->_LinkedShaders[prev] != NULL) + break; + } + /* Validate the inputs of each stage with the output of the preceeding * stage. */ - for (unsigned i = 1; i < prog->_NumLinkedShaders; i++) { + for (unsigned i = prev + 1; i < MESA_SHADER_TYPES; i++) { + if (prog->_LinkedShaders[i] == NULL) + continue; + if (!cross_validate_outputs_to_inputs(prog, - prog->_LinkedShaders[i - 1], + prog->_LinkedShaders[prev], prog->_LinkedShaders[i])) goto done; + + prev = i; } prog->LinkStatus = true; @@ -1506,7 +1536,10 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog) * uniforms, and varyings. Later optimization could possibly make * some of that unused. */ - for (unsigned i = 0; i < prog->_NumLinkedShaders; i++) { + for (unsigned i = 0; i < MESA_SHADER_TYPES; i++) { + if (prog->_LinkedShaders[i] == NULL) + continue; + while (do_common_optimization(prog->_LinkedShaders[i]->ir, true, 32)) ; } @@ -1515,7 +1548,7 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog) assign_uniform_locations(prog); - if (prog->_NumLinkedShaders && prog->_LinkedShaders[0]->Type == GL_VERTEX_SHADER) { + if (prog->_LinkedShaders[MESA_SHADER_VERTEX] != NULL) { /* FINISHME: The value of the max_attribute_index parameter is * FINISHME: implementation dependent based on the value of * FINISHME: GL_MAX_VERTEX_ATTRIBS. GL_MAX_VERTEX_ATTRIBS must be @@ -1526,14 +1559,26 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog) goto done; } - if (prog->_NumLinkedShaders == 1) - demote_unread_shader_outputs(prog->_LinkedShaders[0]); + if ((prog->_LinkedShaders[MESA_SHADER_GEOMETRY] == NULL) + && (prog->_LinkedShaders[MESA_SHADER_FRAGMENT] == NULL)) + demote_unread_shader_outputs(prog->_LinkedShaders[MESA_SHADER_VERTEX]); } - for (unsigned i = 1; i < prog->_NumLinkedShaders; i++) + unsigned prev; + for (prev = 0; prev < MESA_SHADER_TYPES; prev++) { + if (prog->_LinkedShaders[prev] != NULL) + break; + } + + for (unsigned i = prev + 1; i < MESA_SHADER_TYPES; i++) { + if (prog->_LinkedShaders[i] == NULL) + continue; + assign_varying_locations(prog, - prog->_LinkedShaders[i - 1], + prog->_LinkedShaders[prev], prog->_LinkedShaders[i]); + prev = i; + } /* FINISHME: Assign fragment shader output locations. */ |