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

Ilia Mirkin imirkin at alum.mit.edu
Tue Feb 5 14:55:23 UTC 2019


Actually Karol had already done this in a way that I think is better
-- by introducing a special PIPE_CAP_MAX_VARYINGS. This patch is
withdrawn, I'm going to go with his approach (tonight).

On Tue, Feb 5, 2019 at 1:06 AM Ilia Mirkin <imirkin at alum.mit.edu> wrote:
>
> NVIDIA hardware is weird. The fragment shader allows 124 varying
> components (i.e. 31 varyings), but a total of 128 input components if
> you could e.g. gl_FragCoord. There's no way to express this currently --
> specifying a max of 32 varyings will cause failures in some tests.
>
> This separates INPUT_COMPONENTS from INPUTS, and links up
> INPUT_COMPONENTS to the proper limit. For all drivers other than nvc0,
> this is set to 4 * INPUTS.
>
> Signed-off-by: Ilia Mirkin <imirkin at alum.mit.edu>
> Cc: 19.0 <mesa-stable at lists.freedesktop.org>
> ---
>
> This is a conformance issue for nouveau, so I'd like to get it into the
> next release. Should have no effect on non-nvc0 drivers.
>
>  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/etnaviv/etnaviv_screen.c     |  4 ++++
>  src/gallium/drivers/freedreno/freedreno_screen.c |  2 ++
>  src/gallium/drivers/i915/i915_screen.c           |  2 ++
>  src/gallium/drivers/nouveau/nv30/nv30_screen.c   |  4 ++++
>  src/gallium/drivers/nouveau/nv50/nv50_screen.c   |  4 ++++
>  src/gallium/drivers/nouveau/nvc0/nvc0_screen.c   |  2 ++
>  src/gallium/drivers/panfrost/pan_screen.c        |  3 +++
>  src/gallium/drivers/r300/r300_screen.c           |  4 ++++
>  src/gallium/drivers/r600/r600_pipe.c             |  2 ++
>  src/gallium/drivers/radeonsi/si_get.c            |  2 ++
>  src/gallium/drivers/svga/svga_screen.c           | 11 +++++++++++
>  src/gallium/drivers/v3d/v3d_screen.c             |  5 +++++
>  src/gallium/drivers/vc4/vc4_screen.c             |  2 ++
>  src/gallium/drivers/virgl/virgl_screen.c         |  5 +++++
>  src/gallium/include/pipe/p_defines.h             |  1 +
>  src/mesa/state_tracker/st_extensions.c           |  2 +-
>  19 files changed, 62 insertions(+), 1 deletion(-)
>
> diff --git a/src/gallium/auxiliary/gallivm/lp_bld_limits.h b/src/gallium/auxiliary/gallivm/lp_bld_limits.h
> index 7b66b758729..c27bdf8e5b8 100644
> --- a/src/gallium/auxiliary/gallivm/lp_bld_limits.h
> +++ b/src/gallium/auxiliary/gallivm/lp_bld_limits.h
> @@ -99,6 +99,8 @@ gallivm_get_shader_param(enum pipe_shader_cap param)
>        return LP_MAX_TGSI_NESTING;
>     case PIPE_SHADER_CAP_MAX_INPUTS:
>        return 32;
> +   case PIPE_SHADER_CAP_MAX_INPUT_COMPONENTS:
> +      return 32 * 4;
>     case PIPE_SHADER_CAP_MAX_OUTPUTS:
>        return 32;
>     case PIPE_SHADER_CAP_MAX_CONST_BUFFER_SIZE:
> diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.h b/src/gallium/auxiliary/tgsi/tgsi_exec.h
> index 6d4ac381421..2f483ee79d4 100644
> --- a/src/gallium/auxiliary/tgsi/tgsi_exec.h
> +++ b/src/gallium/auxiliary/tgsi/tgsi_exec.h
> @@ -500,6 +500,8 @@ tgsi_exec_get_shader_param(enum pipe_shader_cap param)
>        return TGSI_EXEC_MAX_NESTING;
>     case PIPE_SHADER_CAP_MAX_INPUTS:
>        return TGSI_EXEC_MAX_INPUT_ATTRIBS;
> +   case PIPE_SHADER_CAP_MAX_INPUT_COMPONENTS:
> +      return TGSI_EXEC_MAX_INPUT_ATTRIBS * 4;
>     case PIPE_SHADER_CAP_MAX_OUTPUTS:
>        return 32;
>     case PIPE_SHADER_CAP_MAX_CONST_BUFFER_SIZE:
> diff --git a/src/gallium/docs/source/screen.rst b/src/gallium/docs/source/screen.rst
> index eaf492ce8b0..391aa82b233 100644
> --- a/src/gallium/docs/source/screen.rst
> +++ b/src/gallium/docs/source/screen.rst
> @@ -595,6 +595,10 @@ MOV OUT[0], CONST[0][3]  # copy vector 3 of constbuf 0
>  * ``PIPE_SHADER_CAP_MAX_HW_ATOMIC_COUNTER_BUFFERS``: If atomic counters are
>    separate, how many atomic counter buffers are available for this stage.
>  * ``PIPE_SHADER_CAP_SCALAR_ISA``: Whether the ISA is a scalar one.
> +* ``PIPE_SHADER_CAP_MAX_INPUT_COMPONENTS``: The maximum number of
> +  input components, including any system values that require
> +  slots. This value is at least 4 * ``PIPE_SHADER_CAP_MAX_INPUTS``,
> +  but can be more if more components are allowed that aren't varyings.
>
>  .. _pipe_compute_cap:
>
> diff --git a/src/gallium/drivers/etnaviv/etnaviv_screen.c b/src/gallium/drivers/etnaviv/etnaviv_screen.c
> index fd320232528..ffb7abe8ca2 100644
> --- a/src/gallium/drivers/etnaviv/etnaviv_screen.c
> +++ b/src/gallium/drivers/etnaviv/etnaviv_screen.c
> @@ -440,6 +440,10 @@ etna_screen_get_shader_param(struct pipe_screen *pscreen,
>         * of varyings. */
>        return shader == PIPE_SHADER_FRAGMENT ? screen->specs.max_varyings
>                                              : screen->specs.vertex_max_elements;
> +   case PIPE_SHADER_CAP_MAX_INPUT_COMPONENTS:
> +      return (shader == PIPE_SHADER_FRAGMENT ?
> +              screen->specs.max_varyings :
> +              screen->specs.vertex_max_elements) * 4;
>     case PIPE_SHADER_CAP_MAX_OUTPUTS:
>        return 16; /* see VIVS_VS_OUTPUT */
>     case PIPE_SHADER_CAP_MAX_TEMPS:
> diff --git a/src/gallium/drivers/freedreno/freedreno_screen.c b/src/gallium/drivers/freedreno/freedreno_screen.c
> index e596a4e8462..449dc83cd72 100644
> --- a/src/gallium/drivers/freedreno/freedreno_screen.c
> +++ b/src/gallium/drivers/freedreno/freedreno_screen.c
> @@ -452,6 +452,8 @@ fd_screen_get_shader_param(struct pipe_screen *pscreen,
>         case PIPE_SHADER_CAP_MAX_INPUTS:
>         case PIPE_SHADER_CAP_MAX_OUTPUTS:
>                 return 16;
> +       case PIPE_SHADER_CAP_MAX_INPUT_COMPONENTS:
> +               return 16 * 4;
>         case PIPE_SHADER_CAP_MAX_TEMPS:
>                 return 64; /* Max native temporaries. */
>         case PIPE_SHADER_CAP_MAX_CONST_BUFFER_SIZE:
> diff --git a/src/gallium/drivers/i915/i915_screen.c b/src/gallium/drivers/i915/i915_screen.c
> index a7b4a43c015..c545aa257e7 100644
> --- a/src/gallium/drivers/i915/i915_screen.c
> +++ b/src/gallium/drivers/i915/i915_screen.c
> @@ -139,6 +139,8 @@ i915_get_shader_param(struct pipe_screen *screen,
>           return 0;
>        case PIPE_SHADER_CAP_MAX_INPUTS:
>           return 10;
> +      case PIPE_SHADER_CAP_MAX_INPUT_COMPONENTS:
> +         return 10 * 4;
>        case PIPE_SHADER_CAP_MAX_OUTPUTS:
>           return 1;
>        case PIPE_SHADER_CAP_MAX_CONST_BUFFER_SIZE:
> diff --git a/src/gallium/drivers/nouveau/nv30/nv30_screen.c b/src/gallium/drivers/nouveau/nv30/nv30_screen.c
> index 2b69a8f6968..2e4fb4ae097 100644
> --- a/src/gallium/drivers/nouveau/nv30/nv30_screen.c
> +++ b/src/gallium/drivers/nouveau/nv30/nv30_screen.c
> @@ -319,6 +319,8 @@ nv30_screen_get_shader_param(struct pipe_screen *pscreen,
>        case PIPE_SHADER_CAP_MAX_INPUTS:
>        case PIPE_SHADER_CAP_MAX_OUTPUTS:
>           return 16;
> +      case PIPE_SHADER_CAP_MAX_INPUT_COMPONENTS:
> +         return 16 * 4;
>        case PIPE_SHADER_CAP_MAX_CONST_BUFFER_SIZE:
>           return ((eng3d->oclass >= NV40_3D_CLASS) ? (468 - 6): (256 - 6)) * sizeof(float[4]);
>        case PIPE_SHADER_CAP_MAX_CONST_BUFFERS:
> @@ -371,6 +373,8 @@ nv30_screen_get_shader_param(struct pipe_screen *pscreen,
>           return 0;
>        case PIPE_SHADER_CAP_MAX_INPUTS:
>           return 8; /* should be possible to do 10 with nv4x */
> +      case PIPE_SHADER_CAP_MAX_INPUT_COMPONENTS:
> +         return 8 * 4;
>        case PIPE_SHADER_CAP_MAX_OUTPUTS:
>           return 4;
>        case PIPE_SHADER_CAP_MAX_CONST_BUFFER_SIZE:
> diff --git a/src/gallium/drivers/nouveau/nv50/nv50_screen.c b/src/gallium/drivers/nouveau/nv50/nv50_screen.c
> index fb09f557def..b702602ef6b 100644
> --- a/src/gallium/drivers/nouveau/nv50/nv50_screen.c
> +++ b/src/gallium/drivers/nouveau/nv50/nv50_screen.c
> @@ -365,6 +365,10 @@ nv50_screen_get_shader_param(struct pipe_screen *pscreen,
>        if (shader == PIPE_SHADER_VERTEX)
>           return 32;
>        return 15;
> +   case PIPE_SHADER_CAP_MAX_INPUT_COMPONENTS:
> +      if (shader == PIPE_SHADER_VERTEX)
> +         return 32 * 4;
> +      return 15 * 4;
>     case PIPE_SHADER_CAP_MAX_OUTPUTS:
>        return 16;
>     case PIPE_SHADER_CAP_MAX_CONST_BUFFER_SIZE:
> diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c b/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c
> index fad16645610..76f14972b8d 100644
> --- a/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c
> +++ b/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c
> @@ -406,6 +406,8 @@ nvc0_screen_get_shader_param(struct pipe_screen *pscreen,
>         * and excludes 0x60 per-patch inputs.
>         */
>        return 0x200 / 16;
> +   case PIPE_SHADER_CAP_MAX_INPUT_COMPONENTS:
> +      return 128;
>     case PIPE_SHADER_CAP_MAX_OUTPUTS:
>        return 32;
>     case PIPE_SHADER_CAP_MAX_CONST_BUFFER_SIZE:
> diff --git a/src/gallium/drivers/panfrost/pan_screen.c b/src/gallium/drivers/panfrost/pan_screen.c
> index 0e745583940..9e1bda6823c 100644
> --- a/src/gallium/drivers/panfrost/pan_screen.c
> +++ b/src/gallium/drivers/panfrost/pan_screen.c
> @@ -423,6 +423,9 @@ panfrost_get_shader_param(struct pipe_screen *screen,
>          case PIPE_SHADER_CAP_MAX_INPUTS:
>                  return 16;
>
> +        case PIPE_SHADER_CAP_MAX_INPUT_COMPONENTS:
> +                return 16 * 4;
> +
>          case PIPE_SHADER_CAP_MAX_OUTPUTS:
>                  return shader == PIPE_SHADER_FRAGMENT ? 1 : 8;
>
> diff --git a/src/gallium/drivers/r300/r300_screen.c b/src/gallium/drivers/r300/r300_screen.c
> index 19d3a1bae30..36fbccaca4b 100644
> --- a/src/gallium/drivers/r300/r300_screen.c
> +++ b/src/gallium/drivers/r300/r300_screen.c
> @@ -358,6 +358,8 @@ static int r300_get_shader_param(struct pipe_screen *pscreen,
>               * additional texcoords but there is no two-sided color
>               * selection then. However the facing bit can be used instead. */
>              return 10;
> +        case PIPE_SHADER_CAP_MAX_INPUT_COMPONENTS:
> +            return 10 * 4;
>          case PIPE_SHADER_CAP_MAX_OUTPUTS:
>              return 4;
>          case PIPE_SHADER_CAP_MAX_CONST_BUFFER_SIZE:
> @@ -424,6 +426,8 @@ static int r300_get_shader_param(struct pipe_screen *pscreen,
>              return is_r500 ? 4 : 0; /* For loops; not sure about conditionals. */
>          case PIPE_SHADER_CAP_MAX_INPUTS:
>              return 16;
> +        case PIPE_SHADER_CAP_MAX_INPUT_COMPONENTS:
> +            return 16 * 4;
>          case PIPE_SHADER_CAP_MAX_OUTPUTS:
>              return 10;
>          case PIPE_SHADER_CAP_MAX_CONST_BUFFER_SIZE:
> diff --git a/src/gallium/drivers/r600/r600_pipe.c b/src/gallium/drivers/r600/r600_pipe.c
> index ade1a94ab32..d83970c81e8 100644
> --- a/src/gallium/drivers/r600/r600_pipe.c
> +++ b/src/gallium/drivers/r600/r600_pipe.c
> @@ -613,6 +613,8 @@ static int r600_get_shader_param(struct pipe_screen* pscreen,
>                 return 32;
>         case PIPE_SHADER_CAP_MAX_INPUTS:
>                 return shader == PIPE_SHADER_VERTEX ? 16 : 32;
> +        case PIPE_SHADER_CAP_MAX_INPUT_COMPONENTS:
> +               return (shader == PIPE_SHADER_VERTEX ? 16 : 32) * 4;
>         case PIPE_SHADER_CAP_MAX_OUTPUTS:
>                 return shader == PIPE_SHADER_FRAGMENT ? 8 : 32;
>         case PIPE_SHADER_CAP_MAX_TEMPS:
> diff --git a/src/gallium/drivers/radeonsi/si_get.c b/src/gallium/drivers/radeonsi/si_get.c
> index bb2d8c09eb1..28a892708e6 100644
> --- a/src/gallium/drivers/radeonsi/si_get.c
> +++ b/src/gallium/drivers/radeonsi/si_get.c
> @@ -404,6 +404,8 @@ static int si_get_shader_param(struct pipe_screen* pscreen,
>                 return 16384;
>         case PIPE_SHADER_CAP_MAX_INPUTS:
>                 return shader == PIPE_SHADER_VERTEX ? SI_MAX_ATTRIBS : 32;
> +       case PIPE_SHADER_CAP_MAX_INPUT_COMPONENTS:
> +               return (shader == PIPE_SHADER_VERTEX ? SI_MAX_ATTRIBS : 32) * 4;
>         case PIPE_SHADER_CAP_MAX_OUTPUTS:
>                 return shader == PIPE_SHADER_FRAGMENT ? 8 : 32;
>         case PIPE_SHADER_CAP_MAX_TEMPS:
> diff --git a/src/gallium/drivers/svga/svga_screen.c b/src/gallium/drivers/svga/svga_screen.c
> index 95dde8b0897..10c6fb1a9eb 100644
> --- a/src/gallium/drivers/svga/svga_screen.c
> +++ b/src/gallium/drivers/svga/svga_screen.c
> @@ -515,6 +515,8 @@ vgpu9_get_shader_param(struct pipe_screen *screen,
>           return SVGA3D_MAX_NESTING_LEVEL;
>        case PIPE_SHADER_CAP_MAX_INPUTS:
>           return 10;
> +      case PIPE_SHADER_CAP_MAX_INPUT_COMPONENTS:
> +         return 10 * 4;
>        case PIPE_SHADER_CAP_MAX_OUTPUTS:
>           return svgascreen->max_color_buffers;
>        case PIPE_SHADER_CAP_MAX_CONST_BUFFER_SIZE:
> @@ -589,6 +591,8 @@ vgpu9_get_shader_param(struct pipe_screen *screen,
>           return SVGA3D_MAX_NESTING_LEVEL;
>        case PIPE_SHADER_CAP_MAX_INPUTS:
>           return 16;
> +      case PIPE_SHADER_CAP_MAX_INPUT_COMPONENTS:
> +         return 16 * 4;
>        case PIPE_SHADER_CAP_MAX_OUTPUTS:
>           return 10;
>        case PIPE_SHADER_CAP_MAX_CONST_BUFFER_SIZE:
> @@ -693,6 +697,13 @@ vgpu10_get_shader_param(struct pipe_screen *screen,
>           return VGPU10_MAX_GS_INPUTS;
>        else
>           return VGPU10_MAX_VS_INPUTS;
> +   case PIPE_SHADER_CAP_MAX_INPUT_COMPONENTS:
> +      if (shader == PIPE_SHADER_FRAGMENT)
> +         return VGPU10_MAX_FS_INPUTS * 4;
> +      else if (shader == PIPE_SHADER_GEOMETRY)
> +         return VGPU10_MAX_GS_INPUTS * 4;
> +      else
> +         return VGPU10_MAX_VS_INPUTS * 4;
>     case PIPE_SHADER_CAP_MAX_OUTPUTS:
>        if (shader == PIPE_SHADER_FRAGMENT)
>           return VGPU10_MAX_FS_OUTPUTS;
> diff --git a/src/gallium/drivers/v3d/v3d_screen.c b/src/gallium/drivers/v3d/v3d_screen.c
> index bed2c63a64d..351d2ada4de 100644
> --- a/src/gallium/drivers/v3d/v3d_screen.c
> +++ b/src/gallium/drivers/v3d/v3d_screen.c
> @@ -263,6 +263,11 @@ v3d_screen_get_shader_param(struct pipe_screen *pscreen, unsigned shader,
>                          return V3D_MAX_FS_INPUTS / 4;
>                  else
>                          return V3D_MAX_VS_INPUTS / 4;
> +        case PIPE_SHADER_CAP_MAX_INPUT_COMPONENTS:
> +                if (shader == PIPE_SHADER_FRAGMENT)
> +                        return V3D_MAX_FS_INPUTS;
> +                else
> +                        return V3D_MAX_VS_INPUTS;
>          case PIPE_SHADER_CAP_MAX_OUTPUTS:
>                  if (shader == PIPE_SHADER_FRAGMENT)
>                          return 4;
> diff --git a/src/gallium/drivers/vc4/vc4_screen.c b/src/gallium/drivers/vc4/vc4_screen.c
> index e7f7c82c271..147e2e55d0b 100644
> --- a/src/gallium/drivers/vc4/vc4_screen.c
> +++ b/src/gallium/drivers/vc4/vc4_screen.c
> @@ -248,6 +248,8 @@ vc4_screen_get_shader_param(struct pipe_screen *pscreen,
>
>          case PIPE_SHADER_CAP_MAX_INPUTS:
>                  return 8;
> +        case PIPE_SHADER_CAP_MAX_INPUT_COMPONENTS:
> +                return 8 * 4;
>          case PIPE_SHADER_CAP_MAX_OUTPUTS:
>                  return shader == PIPE_SHADER_FRAGMENT ? 1 : 8;
>          case PIPE_SHADER_CAP_MAX_TEMPS:
> diff --git a/src/gallium/drivers/virgl/virgl_screen.c b/src/gallium/drivers/virgl/virgl_screen.c
> index 72afd4d95f0..38305fc7575 100644
> --- a/src/gallium/drivers/virgl/virgl_screen.c
> +++ b/src/gallium/drivers/virgl/virgl_screen.c
> @@ -388,6 +388,11 @@ virgl_get_shader_param(struct pipe_screen *screen,
>              return vscreen->caps.caps.v2.max_vertex_attribs;
>           return (shader == PIPE_SHADER_VERTEX ||
>                   shader == PIPE_SHADER_GEOMETRY) ? vscreen->caps.caps.v2.max_vertex_attribs : 32;
> +      case PIPE_SHADER_CAP_MAX_INPUT_COMPONENTS:
> +         if (vscreen->caps.caps.v1.glsl_level < 150)
> +            return vscreen->caps.caps.v2.max_vertex_attribs * 4;
> +         return (shader == PIPE_SHADER_VERTEX ||
> +                 shader == PIPE_SHADER_GEOMETRY) ? vscreen->caps.caps.v2.max_vertex_attribs * 4 : 32 * 4;
>        case PIPE_SHADER_CAP_MAX_OUTPUTS:
>           if (shader == PIPE_SHADER_FRAGMENT)
>              return vscreen->caps.caps.v1.max_render_targets;
> diff --git a/src/gallium/include/pipe/p_defines.h b/src/gallium/include/pipe/p_defines.h
> index 1f2a3469cc9..e7f70a97a34 100644
> --- a/src/gallium/include/pipe/p_defines.h
> +++ b/src/gallium/include/pipe/p_defines.h
> @@ -941,6 +941,7 @@ enum pipe_shader_cap
>     PIPE_SHADER_CAP_MAX_HW_ATOMIC_COUNTERS,
>     PIPE_SHADER_CAP_MAX_HW_ATOMIC_COUNTER_BUFFERS,
>     PIPE_SHADER_CAP_SCALAR_ISA,
> +   PIPE_SHADER_CAP_MAX_INPUT_COMPONENTS,
>  };
>
>  /**
> diff --git a/src/mesa/state_tracker/st_extensions.c b/src/mesa/state_tracker/st_extensions.c
> index 3449b2a9645..38fe1660e48 100644
> --- a/src/mesa/state_tracker/st_extensions.c
> +++ b/src/mesa/state_tracker/st_extensions.c
> @@ -226,7 +226,7 @@ void st_init_limits(struct pipe_screen *screen,
>        pc->MaxParameters =
>        pc->MaxNativeParameters = pc->MaxUniformComponents / 4;
>        pc->MaxInputComponents =
> -         screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_MAX_INPUTS) * 4;
> +         screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_MAX_INPUT_COMPONENTS);
>        pc->MaxOutputComponents =
>           screen->get_shader_param(screen, sh, PIPE_SHADER_CAP_MAX_OUTPUTS) * 4;
>
> --
> 2.19.2
>


More information about the mesa-dev mailing list