[Mesa-dev] [PATCH] gallium: add PIPE_SHADER_CAP_MAX_UNROLL_ITERATIONS

Marek Olšák maraeo at gmail.com
Wed Feb 11 09:29:57 PST 2015


I completely agree with you. Turning off the R600 optimizing Shader
Backend would also work, but the performance drop would be unpleasant.

Marek

On Wed, Feb 11, 2015 at 4:11 PM, Roland Scheidegger <sroland at vmware.com> wrote:
> I don't think this is a good idea. This pollutes the gallium interface
> (albeit in some rather minor way, but still) to just cover up a driver
> bug. It does not do anything to actually fix the root cause of the bug
> (presumably it would still just lock up if the loop would actually have
> 256 iterations and hence still not get unrolled, and it's a hint only so
> even with less iterations you could still get such loops with other
> state trackers).
> Unless such a hint would be useful in general for drivers to set some
> limit for loop unrolling.
>
> Roland
>
>
> Am 11.02.2015 um 15:23 schrieb Marek Olšák:
>> From: Marek Olšák <marek.olsak at amd.com>
>>
>> This is the same as the Mesa core setting.
>>
>> This avoids a serious r600g bug.
>> Bugzilla:_https://bugs.freedesktop.org/show_bug.cgi?id=86720
>>
>> Cc: 10.5 10.4 10.3 <mesa-stable at lists.freedesktop.org>
>> ---
>>  src/gallium/auxiliary/gallivm/lp_bld_limits.h    | 2 ++
>>  src/gallium/auxiliary/tgsi/tgsi_exec.h           | 2 ++
>>  src/gallium/docs/source/screen.rst               | 4 ++++
>>  src/gallium/drivers/freedreno/freedreno_screen.c | 2 ++
>>  src/gallium/drivers/i915/i915_screen.c           | 2 ++
>>  src/gallium/drivers/ilo/ilo_screen.c             | 2 ++
>>  src/gallium/drivers/nouveau/nv30/nv30_screen.c   | 4 ++++
>>  src/gallium/drivers/nouveau/nv50/nv50_screen.c   | 2 ++
>>  src/gallium/drivers/nouveau/nvc0/nvc0_screen.c   | 2 ++
>>  src/gallium/drivers/r300/r300_screen.c           | 4 ++++
>>  src/gallium/drivers/r600/r600_pipe.c             | 6 ++++++
>>  src/gallium/drivers/radeonsi/si_pipe.c           | 2 ++
>>  src/gallium/drivers/svga/svga_screen.c           | 4 ++++
>>  src/gallium/drivers/vc4/vc4_screen.c             | 2 ++
>>  src/gallium/include/pipe/p_defines.h             | 3 ++-
>>  src/mesa/state_tracker/st_extensions.c           | 3 +++
>>  16 files changed, 45 insertions(+), 1 deletion(-)
>>
>> diff --git a/src/gallium/auxiliary/gallivm/lp_bld_limits.h b/src/gallium/auxiliary/gallivm/lp_bld_limits.h
>> index 8c66f9d..7856006 100644
>> --- a/src/gallium/auxiliary/gallivm/lp_bld_limits.h
>> +++ b/src/gallium/auxiliary/gallivm/lp_bld_limits.h
>> @@ -128,6 +128,8 @@ gallivm_get_shader_param(enum pipe_shader_cap param)
>>        return 1;
>>     case PIPE_SHADER_CAP_DOUBLES:
>>        return 0;
>> +   case PIPE_SHADER_CAP_MAX_UNROLL_ITERATIONS:
>> +      return 32;
>>     }
>>     /* if we get here, we missed a shader cap above (and should have seen
>>      * a compiler warning.)
>> diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.h b/src/gallium/auxiliary/tgsi/tgsi_exec.h
>> index cc5a916..56c8930 100644
>> --- a/src/gallium/auxiliary/tgsi/tgsi_exec.h
>> +++ b/src/gallium/auxiliary/tgsi/tgsi_exec.h
>> @@ -457,6 +457,8 @@ tgsi_exec_get_shader_param(enum pipe_shader_cap param)
>>        return 1;
>>     case PIPE_SHADER_CAP_DOUBLES:
>>        return 0;
>> +   case PIPE_SHADER_CAP_MAX_UNROLL_ITERATIONS:
>> +      return 32;
>>     }
>>     /* if we get here, we missed a shader cap above (and should have seen
>>      * a compiler warning.)
>> diff --git a/src/gallium/docs/source/screen.rst b/src/gallium/docs/source/screen.rst
>> index 5d80908..aa519d2 100644
>> --- a/src/gallium/docs/source/screen.rst
>> +++ b/src/gallium/docs/source/screen.rst
>> @@ -326,6 +326,10 @@ to be 0.
>>    sampler views. Must not be lower than PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS.
>>  * ``PIPE_SHADER_CAP_DOUBLES``: Whether double precision floating-point
>>    operations are supported.
>> +* ``PIPE_SHADER_CAP_MAX_UNROLL_ITERATIONS``: This is the maximum number of
>> +  iterations that loops are allowed to have to be unrolled. It is only
>> +  a hint to state trackers. Whether any loops will be unrolled is not
>> +  guaranteed.
>>
>>
>>  .. _pipe_compute_cap:
>> diff --git a/src/gallium/drivers/freedreno/freedreno_screen.c b/src/gallium/drivers/freedreno/freedreno_screen.c
>> index 1ce96d3..90fd6f8 100644
>> --- a/src/gallium/drivers/freedreno/freedreno_screen.c
>> +++ b/src/gallium/drivers/freedreno/freedreno_screen.c
>> @@ -398,6 +398,8 @@ fd_screen_get_shader_param(struct pipe_screen *pscreen, unsigned shader,
>>               return 16;
>>       case PIPE_SHADER_CAP_PREFERRED_IR:
>>               return PIPE_SHADER_IR_TGSI;
>> +     case PIPE_SHADER_CAP_MAX_UNROLL_ITERATIONS:
>> +             return 32;
>>       }
>>       debug_printf("unknown shader param %d\n", param);
>>       return 0;
>> diff --git a/src/gallium/drivers/i915/i915_screen.c b/src/gallium/drivers/i915/i915_screen.c
>> index 2dcb507..d2199a2 100644
>> --- a/src/gallium/drivers/i915/i915_screen.c
>> +++ b/src/gallium/drivers/i915/i915_screen.c
>> @@ -155,6 +155,8 @@ i915_get_shader_param(struct pipe_screen *screen, unsigned shader, enum pipe_sha
>>        case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS:
>>        case PIPE_SHADER_CAP_MAX_SAMPLER_VIEWS:
>>           return I915_TEX_UNITS;
>> +      case PIPE_SHADER_CAP_MAX_UNROLL_ITERATIONS:
>> +         return 32;
>>        default:
>>           debug_printf("%s: Unknown cap %u.\n", __FUNCTION__, cap);
>>           return 0;
>> diff --git a/src/gallium/drivers/ilo/ilo_screen.c b/src/gallium/drivers/ilo/ilo_screen.c
>> index 04c1283..6e9e723 100644
>> --- a/src/gallium/drivers/ilo/ilo_screen.c
>> +++ b/src/gallium/drivers/ilo/ilo_screen.c
>> @@ -154,6 +154,8 @@ ilo_get_shader_param(struct pipe_screen *screen, unsigned shader,
>>        return PIPE_SHADER_IR_TGSI;
>>     case PIPE_SHADER_CAP_TGSI_SQRT_SUPPORTED:
>>        return 1;
>> +   case PIPE_SHADER_CAP_MAX_UNROLL_ITERATIONS:
>> +      return 32;
>>
>>     default:
>>        return 0;
>> diff --git a/src/gallium/drivers/nouveau/nv30/nv30_screen.c b/src/gallium/drivers/nouveau/nv30/nv30_screen.c
>> index 83cae7a..9c183f2 100644
>> --- a/src/gallium/drivers/nouveau/nv30/nv30_screen.c
>> +++ b/src/gallium/drivers/nouveau/nv30/nv30_screen.c
>> @@ -247,6 +247,8 @@ nv30_screen_get_shader_param(struct pipe_screen *pscreen, unsigned shader,
>>        case PIPE_SHADER_CAP_SUBROUTINES:
>>        case PIPE_SHADER_CAP_INTEGERS:
>>           return 0;
>> +      case PIPE_SHADER_CAP_MAX_UNROLL_ITERATIONS:
>> +         return 32;
>>        default:
>>           debug_printf("unknown vertex shader param %d\n", param);
>>           return 0;
>> @@ -283,6 +285,8 @@ nv30_screen_get_shader_param(struct pipe_screen *pscreen, unsigned shader,
>>        case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR:
>>        case PIPE_SHADER_CAP_SUBROUTINES:
>>           return 0;
>> +      case PIPE_SHADER_CAP_MAX_UNROLL_ITERATIONS:
>> +         return 32;
>>        default:
>>           debug_printf("unknown fragment shader param %d\n", param);
>>           return 0;
>> diff --git a/src/gallium/drivers/nouveau/nv50/nv50_screen.c b/src/gallium/drivers/nouveau/nv50/nv50_screen.c
>> index 222fa65..b79c237 100644
>> --- a/src/gallium/drivers/nouveau/nv50/nv50_screen.c
>> +++ b/src/gallium/drivers/nouveau/nv50/nv50_screen.c
>> @@ -285,6 +285,8 @@ nv50_screen_get_shader_param(struct pipe_screen *pscreen, unsigned shader,
>>        /* The chip could handle more sampler views than samplers */
>>     case PIPE_SHADER_CAP_MAX_SAMPLER_VIEWS:
>>        return MIN2(32, PIPE_MAX_SAMPLERS);
>> +   case PIPE_SHADER_CAP_MAX_UNROLL_ITERATIONS:
>> +      return 32;
>>     default:
>>        NOUVEAU_ERR("unknown PIPE_SHADER_CAP %d\n", param);
>>        return 0;
>> diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c b/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c
>> index 63fbad7..4e53ca4 100644
>> --- a/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c
>> +++ b/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c
>> @@ -293,6 +293,8 @@ nvc0_screen_get_shader_param(struct pipe_screen *pscreen, unsigned shader,
>>        return 16; /* would be 32 in linked (OpenGL-style) mode */
>>     case PIPE_SHADER_CAP_MAX_SAMPLER_VIEWS:
>>        return 16; /* XXX not sure if more are really safe */
>> +   case PIPE_SHADER_CAP_MAX_UNROLL_ITERATIONS:
>> +      return 32;
>>     default:
>>        NOUVEAU_ERR("unknown PIPE_SHADER_CAP %d\n", param);
>>        return 0;
>> diff --git a/src/gallium/drivers/r300/r300_screen.c b/src/gallium/drivers/r300/r300_screen.c
>> index 7794fc2..e6b826d 100644
>> --- a/src/gallium/drivers/r300/r300_screen.c
>> +++ b/src/gallium/drivers/r300/r300_screen.c
>> @@ -285,6 +285,8 @@ static int r300_get_shader_param(struct pipe_screen *pscreen, unsigned shader, e
>>          case PIPE_SHADER_CAP_INTEGERS:
>>          case PIPE_SHADER_CAP_DOUBLES:
>>              return 0;
>> +        case PIPE_SHADER_CAP_MAX_UNROLL_ITERATIONS:
>> +            return 32;
>>          case PIPE_SHADER_CAP_PREFERRED_IR:
>>              return PIPE_SHADER_IR_TGSI;
>>          }
>> @@ -337,6 +339,8 @@ static int r300_get_shader_param(struct pipe_screen *pscreen, unsigned shader, e
>>          case PIPE_SHADER_CAP_MAX_SAMPLER_VIEWS:
>>          case PIPE_SHADER_CAP_DOUBLES:
>>              return 0;
>> +        case PIPE_SHADER_CAP_MAX_UNROLL_ITERATIONS:
>> +            return 32;
>>          case PIPE_SHADER_CAP_PREFERRED_IR:
>>              return PIPE_SHADER_IR_TGSI;
>>          }
>> diff --git a/src/gallium/drivers/r600/r600_pipe.c b/src/gallium/drivers/r600/r600_pipe.c
>> index 60bed0e..e10b224 100644
>> --- a/src/gallium/drivers/r600/r600_pipe.c
>> +++ b/src/gallium/drivers/r600/r600_pipe.c
>> @@ -486,6 +486,12 @@ static int r600_get_shader_param(struct pipe_screen* pscreen, unsigned shader, e
>>               }
>>       case PIPE_SHADER_CAP_DOUBLES:
>>               return 0;
>> +     case PIPE_SHADER_CAP_MAX_UNROLL_ITERATIONS:
>> +             /* due to a bug in the shader compiler, some loops hang
>> +              * if they are not unrolled, see:
>> +              *    https://bugs.freedesktop.org/show_bug.cgi?id=86720
>> +              */
>> +             return 255;
>>       }
>>       return 0;
>>  }
>> diff --git a/src/gallium/drivers/radeonsi/si_pipe.c b/src/gallium/drivers/radeonsi/si_pipe.c
>> index 26182c2..d88ad14 100644
>> --- a/src/gallium/drivers/radeonsi/si_pipe.c
>> +++ b/src/gallium/drivers/radeonsi/si_pipe.c
>> @@ -421,6 +421,8 @@ static int si_get_shader_param(struct pipe_screen* pscreen, unsigned shader, enu
>>               return PIPE_SHADER_IR_TGSI;
>>       case PIPE_SHADER_CAP_DOUBLES:
>>               return 0;
>> +     case PIPE_SHADER_CAP_MAX_UNROLL_ITERATIONS:
>> +             return 32;
>>       }
>>       return 0;
>>  }
>> diff --git a/src/gallium/drivers/svga/svga_screen.c b/src/gallium/drivers/svga/svga_screen.c
>> index e3db4a8..0156001 100644
>> --- a/src/gallium/drivers/svga/svga_screen.c
>> +++ b/src/gallium/drivers/svga/svga_screen.c
>> @@ -373,6 +373,8 @@ static int svga_get_shader_param(struct pipe_screen *screen, unsigned shader, en
>>           return PIPE_SHADER_IR_TGSI;
>>        case PIPE_SHADER_CAP_DOUBLES:
>>           return 0;
>> +      case PIPE_SHADER_CAP_MAX_UNROLL_ITERATIONS:
>> +         return 32;
>>        }
>>        /* If we get here, we failed to handle a cap above */
>>        debug_printf("Unexpected fragment shader query %u\n", param);
>> @@ -427,6 +429,8 @@ static int svga_get_shader_param(struct pipe_screen *screen, unsigned shader, en
>>           return PIPE_SHADER_IR_TGSI;
>>        case PIPE_SHADER_CAP_DOUBLES:
>>           return 0;
>> +      case PIPE_SHADER_CAP_MAX_UNROLL_ITERATIONS:
>> +         return 32;
>>        }
>>        /* If we get here, we failed to handle a cap above */
>>        debug_printf("Unexpected vertex shader query %u\n", param);
>> diff --git a/src/gallium/drivers/vc4/vc4_screen.c b/src/gallium/drivers/vc4/vc4_screen.c
>> index db88eaa..29637fb 100644
>> --- a/src/gallium/drivers/vc4/vc4_screen.c
>> +++ b/src/gallium/drivers/vc4/vc4_screen.c
>> @@ -322,6 +322,8 @@ vc4_screen_get_shader_param(struct pipe_screen *pscreen, unsigned shader,
>>                  return VC4_MAX_TEXTURE_SAMPLERS;
>>          case PIPE_SHADER_CAP_PREFERRED_IR:
>>                  return PIPE_SHADER_IR_TGSI;
>> +     case PIPE_SHADER_CAP_MAX_UNROLL_ITERATIONS:
>> +             return 32;
>>          default:
>>                  fprintf(stderr, "unknown shader param %d\n", param);
>>                  return 0;
>> diff --git a/src/gallium/include/pipe/p_defines.h b/src/gallium/include/pipe/p_defines.h
>> index 7ce25af..192af63 100644
>> --- a/src/gallium/include/pipe/p_defines.h
>> +++ b/src/gallium/include/pipe/p_defines.h
>> @@ -634,7 +634,8 @@ enum pipe_shader_cap
>>     PIPE_SHADER_CAP_PREFERRED_IR,
>>     PIPE_SHADER_CAP_TGSI_SQRT_SUPPORTED,
>>     PIPE_SHADER_CAP_MAX_SAMPLER_VIEWS,
>> -   PIPE_SHADER_CAP_DOUBLES
>> +   PIPE_SHADER_CAP_DOUBLES,
>> +   PIPE_SHADER_CAP_MAX_UNROLL_ITERATIONS
>>  };
>>
>>  /**
>> diff --git a/src/mesa/state_tracker/st_extensions.c b/src/mesa/state_tracker/st_extensions.c
>> index 2b5cde2..240308a 100644
>> --- a/src/mesa/state_tracker/st_extensions.c
>> +++ b/src/mesa/state_tracker/st_extensions.c
>> @@ -241,6 +241,9 @@ void st_init_limits(struct pipe_screen *screen,
>>
>>        if (options->EmitNoLoops)
>>           options->MaxUnrollIterations = MIN2(screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_MAX_INSTRUCTIONS), 65536);
>> +      else
>> +         options->MaxUnrollIterations = screen->get_shader_param(screen, sh,
>> +                                      PIPE_SHADER_CAP_MAX_UNROLL_ITERATIONS);
>>
>>        options->LowerClipDistance = true;
>>     }
>>
>


More information about the mesa-dev mailing list