소스 검색

linker: Use gl_shader_program::AttributeBindings for attrib locations

Signed-off-by: Ian Romanick <ian.d.romanick@intel.com>
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
tags/mesa-8.0-rc1
Ian Romanick 14 년 전
부모
커밋
523b611646
1개의 변경된 파일64개의 추가작업 그리고 74개의 파일을 삭제
  1. 64
    74
      src/glsl/linker.cpp

+ 64
- 74
src/glsl/linker.cpp 파일 보기

@@ -1298,71 +1298,6 @@ assign_attribute_or_color_locations(gl_shader_program *prog,

invalidate_variable_locations(sh, direction, generic_base);

if ((target_index == MESA_SHADER_VERTEX) && (prog->Attributes != NULL)) {
for (unsigned i = 0; i < prog->Attributes->NumParameters; i++) {
ir_variable *const var =
sh->symbols->get_variable(prog->Attributes->Parameters[i].Name);

/* Note: attributes that occupy multiple slots, such as arrays or
* matrices, may appear in the attrib array multiple times.
*/
if ((var == NULL) || (var->location != -1))
continue;

/* From page 61 of the OpenGL 4.0 spec:
*
* "LinkProgram will fail if the attribute bindings assigned by
* BindAttribLocation do not leave not enough space to assign a
* location for an active matrix attribute or an active attribute
* array, both of which require multiple contiguous generic
* attributes."
*
* Previous versions of the spec contain similar language but omit the
* bit about attribute arrays.
*
* Page 61 of the OpenGL 4.0 spec also says:
*
* "It is possible for an application to bind more than one
* attribute name to the same location. This is referred to as
* aliasing. This will only work if only one of the aliased
* attributes is active in the executable program, or if no path
* through the shader consumes more than one attribute of a set
* of attributes aliased to the same location. A link error can
* occur if the linker determines that every path through the
* shader consumes multiple aliased attributes, but
* implementations are not required to generate an error in this
* case."
*
* These two paragraphs are either somewhat contradictory, or I don't
* fully understand one or both of them.
*/
/* FINISHME: The code as currently written does not support attribute
* FINISHME: location aliasing (see comment above).
*/
const int attr = prog->Attributes->Parameters[i].StateIndexes[0];
const unsigned slots = count_attribute_slots(var->type);

/* Mask representing the contiguous slots that will be used by this
* attribute.
*/
const unsigned use_mask = (1 << slots) - 1;

/* Generate a link error if the set of bits requested for this
* attribute overlaps any previously allocated bits.
*/
if ((~(use_mask << attr) & used_locations) != used_locations) {
linker_error(prog,
"insufficient contiguous attribute locations "
"available for vertex shader input `%s'",
var->name);
return false;
}

var->location = VERT_ATTRIB_GENERIC0 + attr;
used_locations |= (use_mask << attr);
}
}

/* Temporary storage for the set of attributes that need locations assigned.
*/
struct temp_attr {
@@ -1389,28 +1324,83 @@ assign_attribute_or_color_locations(gl_shader_program *prog,
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 - generic_base;

if ((var->location >= (int)(max_index + generic_base))
|| (var->location < 0)) {
linker_error(prog,
"invalid explicit location %d specified for `%s'\n",
(var->location < 0) ? var->location : attr,
(var->location < 0)
? var->location : var->location - generic_base,
var->name);
return false;
} else if (var->location >= generic_base) {
used_locations |= (use_mask << attr);
}
} else if (target_index == MESA_SHADER_VERTEX) {
unsigned binding;

if (prog->AttributeBindings->get(binding, var->name)) {
assert(binding >= VERT_ATTRIB_GENERIC0);
var->location = binding;
}
}

/* The location was explicitly assigned, nothing to do here.
*/
if (var->location != -1)
const unsigned slots = count_attribute_slots(var->type);
if (var->location != -1) {
if (var->location >= generic_base) {
/* From page 61 of the OpenGL 4.0 spec:
*
* "LinkProgram will fail if the attribute bindings assigned
* by BindAttribLocation do not leave not enough space to
* assign a location for an active matrix attribute or an
* active attribute array, both of which require multiple
* contiguous generic attributes."
*
* Previous versions of the spec contain similar language but omit
* the bit about attribute arrays.
*
* Page 61 of the OpenGL 4.0 spec also says:
*
* "It is possible for an application to bind more than one
* attribute name to the same location. This is referred to as
* aliasing. This will only work if only one of the aliased
* attributes is active in the executable program, or if no
* path through the shader consumes more than one attribute of
* a set of attributes aliased to the same location. A link
* error can occur if the linker determines that every path
* through the shader consumes multiple aliased attributes,
* but implementations are not required to generate an error
* in this case."
*
* These two paragraphs are either somewhat contradictory, or I
* don't fully understand one or both of them.
*/
/* FINISHME: The code as currently written does not support
* FINISHME: attribute location aliasing (see comment above).
*/
/* Mask representing the contiguous slots that will be used by
* this attribute.
*/
const unsigned attr = var->location - generic_base;
const unsigned use_mask = (1 << slots) - 1;

/* Generate a link error if the set of bits requested for this
* attribute overlaps any previously allocated bits.
*/
if ((~(use_mask << attr) & used_locations) != used_locations) {
linker_error(prog,
"insufficient contiguous attribute locations "
"available for vertex shader input `%s'",
var->name);
return false;
}

used_locations |= (use_mask << attr);
}

continue;
}

to_assign[num_attr].slots = count_attribute_slots(var->type);
to_assign[num_attr].slots = slots;
to_assign[num_attr].var = var;
num_attr++;
}

Loading…
취소
저장