[Mesa-dev] [PATCH] TransformFeedback: Assign transform feedback varying slots in linker.

Dan McCabe zen3d.linux at gmail.com
Mon Oct 24 14:37:09 PDT 2011


On 10/23/2011 01:19 PM, Marek Olšák wrote:
> On Sat, Oct 22, 2011 at 2:14 AM, Dan McCabe<zen3d.linux at 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.

Agreed on both points. Thanks.

>
> 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.

Possibly not; this hasn't been tested extensively. But I'll check.

>
> 3) If a transform feedback varying is undeclared, linker_error should
> be called and the linker should back off.

Agreed.

>
> Other than that, transform feedback varying locations seem to be
> assigned correctly.
>
> Best regards,
> Marek



More information about the mesa-dev mailing list