[Mesa-dev] gallium: add PIPE_SHADER_CAP_MAX_UNROLL_ITERATIONS

Submitted by Marek Olšák on Feb. 11, 2015, 2:23 p.m.

Details

Message ID 1423664624-12276-1-git-send-email-maraeo@gmail.com
State New, archived
Headers show

Not browsing as part of any series.

Commit Message

Marek Olšák Feb. 11, 2015, 2:23 p.m.
From: Marek Olšák <marek.olsak@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@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(-)

Patch hide | download patch | download mbox

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;
    }

Comments

On 02/11/2015 07:23 AM, Marek Olšák wrote:
> From: Marek Olšák <marek.olsak@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@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;
>      }
>

Instead of 32 everywhere, maybe we should #define 
PIPE_SHADER_MAX_UNROLL_ITERATIONS_DEFAULT somewhere in case there's ever 
reason to bump it up or change it.

Either way,
Reviewed-by: Brian Paul <brianp@vmware.com>
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@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@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;
>     }
>
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@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@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@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;
>>     }
>>
>