[Mesa-dev] [PATCH v2 01/24] linker: fix varying linking if SSO program has only gs and fs
Martin Peres
martin.peres at linux.intel.com
Mon Apr 13 01:08:19 PDT 2015
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.
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];
>>
More information about the mesa-dev
mailing list