[Mesa-dev] [PATCH v2 01/24] linker: fix varying linking if SSO program has only gs and fs

Tapani Pälli tapani.palli at intel.com
Mon Apr 13 04:15:58 PDT 2015



On 04/13/2015 11:18 AM, Martin Peres wrote:
>
>
> On 13/04/15 11:08, Martin Peres wrote:
>>
>> On 02/04/15 13:27, Tapani Pälli wrote:
>>>
>>>
>>> On 04/02/2015 12:36 PM, Martin Peres wrote:
>>>>
>>>>
>>>> On 01/04/15 15:14, Tapani Pälli wrote:
>>>>> Previously linker did not take in to account case where one would
>>>>> have only gs and fs (with SSO), patch adds the case by refactoring
>>>>> code around assign_varying_locations. This makes sure locations for
>>>>> gs get populated correctly.
>>>>>
>>>>> This was found with some of the SSO subtests of Martin's upcoming
>>>>> GetProgramInterfaceiv Piglit test which passes with the patch, no
>>>>> Piglit regressions.
>>>>>
>>>>> Signed-off-by: Tapani Pälli <tapani.palli at intel.com>
>>>>> ---
>>>>>   src/glsl/linker.cpp | 32 +++++++++++++++++++-------------
>>>>>   1 file changed, 19 insertions(+), 13 deletions(-)
>>>>>
>>>>> diff --git a/src/glsl/linker.cpp b/src/glsl/linker.cpp
>>>>> index 85830e6..73432b2 100644
>>>>> --- a/src/glsl/linker.cpp
>>>>> +++ b/src/glsl/linker.cpp
>>>>> @@ -2726,10 +2726,19 @@ link_shaders(struct gl_context *ctx, struct
>>>>> gl_shader_program *prog)
>>>>>         goto done;
>>>>>      }
>>>>> -   unsigned first;
>>>>> -   for (first = 0; first <= MESA_SHADER_FRAGMENT; first++) {
>>>>> -      if (prog->_LinkedShaders[first] != NULL)
>>>>> -     break;
>>>>> +   unsigned first, last;
>>>>> +
>>>>> +   first = MESA_SHADER_STAGES;
>>>>> +   last = 0;
>>>>> +
>>>>> +   /* Determine first and last stage. */
>>>>> +   for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
>>>>> +      struct gl_shader *sh = prog->_LinkedShaders[i];
>>>> Why create this variable?
>>>
>>> True, it is not really needed, even in the place from where this loop
>>> was copypasted from, see patch 3 in the series :)
>>
>> Ok, please get rid of it then, to eliminate the possible confusion
>> with another local variable later on.
>>
>>>
>>>>> +      if (!sh)
>>>>> +         continue;
>>>>> +      if (first == MESA_SHADER_STAGES)
>>>>> +         first = i;
>>>>> +      last = i;
>>>>>      }
>>>>>      if (num_tfeedback_decls != 0) {
>>>>> @@ -2758,13 +2767,9 @@ link_shaders(struct gl_context *ctx, struct
>>>>> gl_shader_program *prog)
>>>>>       * ensures that inter-shader outputs written to in an earlier
>>>>> stage are
>>>>>       * eliminated if they are (transitively) not used in a later
>>>>> stage.
>>>>>       */
>>>>> -   int last, next;
>>>>> -   for (last = MESA_SHADER_FRAGMENT; last >= 0; last--) {
>>>>> -      if (prog->_LinkedShaders[last] != NULL)
>>>>> -         break;
>>>>> -   }
>>>>> +   int next;
>>>>
>>>> So, the above is a cleanup for finding the first and last shader stage.
>>>> It is however not necessary.
>>>
>>> Yes, it is only cleanup to make 2 for loops as just one, can be dropped.
>>
>> Let's keep it.
>>
>>>
>>>>> -   if (last >= 0 && last < MESA_SHADER_FRAGMENT) {
>>>>> +   if (first < MESA_SHADER_FRAGMENT) {
>>>>>         gl_shader *const sh = prog->_LinkedShaders[last];
>>>>>         if (first == MESA_SHADER_GEOMETRY) {
>>>>> @@ -2776,13 +2781,14 @@ link_shaders(struct gl_context *ctx, struct
>>>>> gl_shader_program *prog)
>>>>>             * MESA_SHADER_GEOMETRY.
>>>>>             */
>>>>>            if (!assign_varying_locations(ctx, mem_ctx, prog,
>>>>> -                                       NULL, sh,
>>>>> +                                       NULL,
>>>>> prog->_LinkedShaders[first],
>>>> The above change should not change anything because first == last ==
>>>> MESA_SHADER_GEOMETRY. Please get rid of it if I am right.
>>>
>>> You are not right. Here last can be either GS or FS. The point of
>>> this locations assignment call is that we do not have VS but still
>>> want to assign locations to GS. Then only in the very last loop in
>>> this function, varyings between GS->FS are checked.
>>
>> ACK.
>>
>>>
>>>>> num_tfeedback_decls,
>>>>> tfeedback_decls,
>>>>> prog->Geom.VerticesIn))
>>>>>               goto done;
>>>>>         }
>>>>> -      if (num_tfeedback_decls != 0 || prog->SeparateShader) {
>>>>> +      if (last != MESA_SHADER_FRAGMENT &&
>>>>> +         (num_tfeedback_decls != 0 || prog->SeparateShader)) {
>>>>>            /* There was no fragment shader, but we still have to
>>>>> assign varying
>>>>>             * locations for use by transform feedback.
>>>>>             */
>>>>> @@ -2804,7 +2810,7 @@ link_shaders(struct gl_context *ctx, struct
>>>>> gl_shader_program *prog)
>>>>>         while (do_dead_code(sh->ir, false))
>>>>>            ;
>>>>>      }
>>>>> -   else if (first == MESA_SHADER_FRAGMENT) {
>>>>> +   else if (first == MESA_SHADER_FRAGMENT && first == last) {
>>>> How could first != last since fragment is the last stage anyway? Why
>>>> did
>>>> you add this test?
>>>
>>> This can be removed, I added only to emphasize that we really do only
>>> have one but the comment below is enough. Will remove this.
>>
>> Yes, please remove it.
>
> Actually, the last stage is not FS, it is CS. So first == last does not
> have to be true when compute shaders become available. You should keep
> the condition.

I'm OK with both keeping or removing it. For me it looks like this 
function might need quite a bit of changes here and there with CS.

>> With this, the patch is Reviewed-by: Martin Peres
>> <martin.peres at linux.intel.com>
>>>
>>>>>         /* If the program only contains a fragment shader...
>>>>>          */
>>>>>         gl_shader *const sh = prog->_LinkedShaders[first];
>>>>
>>
>> _______________________________________________
>> mesa-dev mailing list
>> mesa-dev at lists.freedesktop.org
>> http://lists.freedesktop.org/mailman/listinfo/mesa-dev
>


More information about the mesa-dev mailing list