On Sat, Oct 22, 2011 at 2:14 AM, Dan McCabe <zen3d.li...@gmail.com> wrote: > Modify the linker to assign additional slots for varying > variables used by transform feedback. This is done after other > varyings are already assigned slots. > > Since this is done after previous varying slot assignments, > the code needs to know how many varyings are already assigned > slots. A new function "max_varying()" is introduced to examine a > previously processed shader to find the largest varying already > assigned a slot. All new varyings will be assigned slots after > this one. If varyings are found, -1 is returned. > --- > src/glsl/linker.cpp | 84 > +++++++++++++++++++++++++++++++++++++++++++++++++++ > 1 files changed, 84 insertions(+), 0 deletions(-) > > diff --git a/src/glsl/linker.cpp b/src/glsl/linker.cpp > index a7c38a3..81f2658 100644 > --- a/src/glsl/linker.cpp > +++ b/src/glsl/linker.cpp > @@ -207,6 +207,25 @@ invalidate_variable_locations(gl_shader *sh, enum > ir_variable_mode mode, > } > } > > + > +int > +max_varying(gl_shader *sh, enum ir_variable_mode mode) > +{ > + int max_varying = -1; > + > + foreach_list(node, sh->ir) { > + ir_variable *const var = ((ir_instruction *) node)->as_variable(); > + > + if ((var == NULL) || (var->mode != (unsigned) mode)) > + continue; > + > + if (var->location > max_varying) > + max_varying = var->location; > + } > + > + return max_varying; > +} > + > > /** > * Determine the number of attribute slots required for a particular type > @@ -1597,6 +1616,69 @@ assign_varying_locations(struct gl_context *ctx, > > > void > +assign_transform_feedback_varying_locations(struct gl_context *ctx, > + struct gl_shader_program *prog) > +{ > + struct gl_shader *vs = prog->_LinkedShaders[MESA_SHADER_VERTEX]; > + > + if (vs == NULL) > + return; > + > + char **names = prog->TransformFeedback.VaryingNames; > + int num_names = prog->TransformFeedback.NumVarying; > + > + if (num_names <= 0) > + return; > + > + int num_varying = max_varying(vs, ir_var_out) + 1; > + unsigned output_index = > + (num_varying > VERT_RESULT_VAR0) > + ? num_varying > + : VERT_RESULT_VAR0; > + > + foreach_list(node, vs->ir) { > + ir_variable *const output_var = ((ir_instruction *) > node)->as_variable(); > + > + if (output_var == NULL > + || output_var->mode != ir_var_out > + || output_var->location != -1) > + continue; > + > + /* Find a transform feedback varying variable that has > + * the same name as the shader variable. > + */ > + int varying_index = -1; > + for (int num_name = 0; num_name < num_names; num_name++) { > + char *name = *names++;
Hi Dan, Sorry for the very late reply and thank you very much for the work. I have just a few remarks. 1) *names++ doesn't seem correct and causes a segfault. You probably wanted *(names++). I fixed this in my code by using names[num_name], which is more readable. 2) I am not sure whether your code will work with varying arrays. With "varying vec4 array[2];", "array[0]" and "array[1]" are possible names for transform feedback varyings. 3) If a transform feedback varying is undeclared, linker_error should be called and the linker should back off. Other than that, transform feedback varying locations seem to be assigned correctly. Best regards, Marek _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev