From 3a8501d76a0f548c4ce65d23ba12b035a6b6b27d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Sat, 7 Feb 2015 13:45:51 +0100 Subject: [PATCH] gallium: add PIPE_SHADER_CAP_MAX_UNROLL_ITERATIONS This is the same as the Mesa core setting. This works around a critical r600g bug. Bugzilla:_https://bugs.freedesktop.org/show_bug.cgi?id=86720 Cc: 10.5 10.4 10.3 --- 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; } -- 2.1.0