summaryrefslogtreecommitdiff
path: root/src/glsl/linker.cpp
diff options
context:
space:
mode:
authorIan Romanick <ian.d.romanick@intel.com>2010-10-14 13:28:42 -0700
committerIan Romanick <ian.d.romanick@intel.com>2010-10-14 17:16:59 -0700
commit3322fbaf3b5e305ce00c1d08c26965bb98e0cef0 (patch)
tree30aba427f916748177148fb74e495619c527e8a6 /src/glsl/linker.cpp
parent4b4284c9c9b472f750663352485290c22f8c3921 (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.cpp83
1 files changed, 64 insertions, 19 deletions
diff --git a/src/glsl/linker.cpp b/src/glsl/linker.cpp
index db1b76b371..ffff08b17b 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. */