diff options
author | Ian Romanick <[email protected]> | 2010-10-07 17:21:22 -0700 |
---|---|---|
committer | Ian Romanick <[email protected]> | 2010-10-08 14:21:23 -0700 |
commit | 68a4fc9d5a9dd3b61472451d659275531253b67d (patch) | |
tree | 2458cf332f819c61cbdc589e637cc0f171328892 /src/glsl/linker.cpp | |
parent | eee68d3631813580a14fa51fda6f0c959279256c (diff) |
glsl: Add linker support for explicit attribute locations
Diffstat (limited to 'src/glsl/linker.cpp')
-rw-r--r-- | src/glsl/linker.cpp | 33 |
1 files changed, 32 insertions, 1 deletions
diff --git a/src/glsl/linker.cpp b/src/glsl/linker.cpp index bddf8788b47..c612fe54663 100644 --- a/src/glsl/linker.cpp +++ b/src/glsl/linker.cpp @@ -191,7 +191,7 @@ invalidate_variable_locations(gl_shader *sh, enum ir_variable_mode mode, /* Only assign locations for generic attributes / varyings / etc. */ - if (var->location >= generic_base) + if ((var->location >= generic_base) && !var->explicit_location) var->location = -1; } } @@ -365,6 +365,19 @@ cross_validate_globals(struct gl_shader_program *prog, } } + if (var->explicit_location) { + if (existing->explicit_location + && (var->location != existing->location)) { + linker_error_printf(prog, "explicit locations for %s " + "`%s' have differing values\n", + mode_string(var), var->name); + return false; + } + + existing->location = var->location; + existing->explicit_location = true; + } + /* FINISHME: Handle non-constant initializers. */ if (var->constant_value != NULL) { @@ -1186,6 +1199,24 @@ assign_attribute_locations(gl_shader_program *prog, unsigned max_attribute_index if ((var == NULL) || (var->mode != ir_var_in)) continue; + if (var->explicit_location) { + const unsigned slots = count_attribute_slots(var->type); + const unsigned use_mask = (1 << slots) - 1; + const int attr = var->location - VERT_ATTRIB_GENERIC0; + + if ((var->location >= (int)(max_attribute_index + VERT_ATTRIB_GENERIC0)) + || (var->location < 0)) { + linker_error_printf(prog, + "invalid explicit location %d specified for " + "`%s'\n", + (var->location < 0) ? var->location : attr, + var->name); + return false; + } else if (var->location >= VERT_ATTRIB_GENERIC0) { + used_locations |= (use_mask << attr); + } + } + /* The location was explicitly assigned, nothing to do here. */ if (var->location != -1) |