[Mesa-dev] [PATCH 2/2] mesa: add hard limits for the number of varyings and uniforms for the linker

Jose Fonseca jfonseca at vmware.com
Tue Nov 22 07:05:40 PST 2011


Marek,

I think we should take one of two approaches here:
- aim for a short-term workaround, without gallium interface changes:
  - e.g., provide to GLSL compiler infinite/huge limits, while advertising to the app the pipe driver ones
  - or detect the wine process and advertise bigger limits in the r300 driver
- aim for accurately describing the pipe driver compiling abilities
  - e.g., allow the state tracker to create shaders that exceed abilities, and force a trial generation and compilation of the TGSI shaders when the GLSL shader is first linked

But the hard limit caps interface change you propose below doesn't quite align to neither approach: it is an interface change which doesn't truly help describing the pipe driver compiler abilities any better (the actual maximum constants/inputs depends on the shader and is not a global constant), so it merely provides a short term relief.

Jose


----- Original Message -----
> These are different from hardware limits, because some drivers can
> correctly
> handle higher values than they report in most cases, either due
> to driver-specific compiler optimizations, or due to just how the
> hardware
> works internally.
> 
> The problem with the linker is that it artifically reduces driver
> capabilities
> by failing to link shaders which would otherwise run correctly.
> 
> This is a regression fix.
> 
> Another solution would be to just disable the broken checks in the
> linker,
> but some people obviously want to preserve the new broken behavior.
> 
> NOTE: Of course, the Gallium drivers will be modified such that
> MAX_xxx == MAX_xxx_HARD_LIMIT.
> ---
>  src/gallium/include/pipe/p_defines.h     |    4 +++-
>  src/glsl/linker.cpp                      |   12 ++++++------
>  src/glsl/standalone_scaffolding.cpp      |    3 +++
>  src/mesa/drivers/dri/i915/i915_context.c |    2 +-
>  src/mesa/main/context.c                  |    5 ++++-
>  src/mesa/main/mtypes.h                   |    6 ++++++
>  src/mesa/state_tracker/st_extensions.c   |    8 ++++++++
>  7 files changed, 31 insertions(+), 9 deletions(-)
> 
> diff --git a/src/gallium/include/pipe/p_defines.h
> b/src/gallium/include/pipe/p_defines.h
> index 6d6faab..108830c 100644
> --- a/src/gallium/include/pipe/p_defines.h
> +++ b/src/gallium/include/pipe/p_defines.h
> @@ -502,7 +502,9 @@ enum pipe_shader_cap
>     PIPE_SHADER_CAP_SUBROUTINES = 16, /* BGNSUB, ENDSUB, CAL, RET */
>     PIPE_SHADER_CAP_INTEGERS = 17,
>     PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS = 18,
> -   PIPE_SHADER_CAP_OUTPUT_READ = 19
> +   PIPE_SHADER_CAP_OUTPUT_READ = 19,
> +   PIPE_SHADER_CAP_MAX_INPUTS_HARD_LIMIT = 20,
> +   PIPE_SHADER_CAP_MAX_CONSTS_HARD_LIMIT = 21
>  };
>  
>  
> diff --git a/src/glsl/linker.cpp b/src/glsl/linker.cpp
> index 3527088..77b50d8 100644
> --- a/src/glsl/linker.cpp
> +++ b/src/glsl/linker.cpp
> @@ -1814,18 +1814,18 @@ assign_varying_locations(struct gl_context
> *ctx,
>     }
>  
>     if (ctx->API == API_OPENGLES2 || prog->Version == 100) {
> -      if (varying_vectors > ctx->Const.MaxVarying) {
> +      if (varying_vectors > ctx->Const.MaxVaryingHardLimit) {
>  	 linker_error(prog, "shader uses too many varying vectors "
>  		      "(%u > %u)\n",
> -		      varying_vectors, ctx->Const.MaxVarying);
> +		      varying_vectors, ctx->Const.MaxVaryingHardLimit);
>  	 return false;
>        }
>     } else {
>        const unsigned float_components = varying_vectors * 4;
> -      if (float_components > ctx->Const.MaxVarying * 4) {
> +      if (float_components > ctx->Const.MaxVaryingHardLimit * 4) {
>  	 linker_error(prog, "shader uses too many varying components "
>  		      "(%u > %u)\n",
> -		      float_components, ctx->Const.MaxVarying * 4);
> +		      float_components, ctx->Const.MaxVaryingHardLimit * 4);
>  	 return false;
>        }
>     }
> @@ -1943,8 +1943,8 @@ check_resources(struct gl_context *ctx, struct
> gl_shader_program *prog)
>     };
>  
>     const unsigned max_uniform_components[MESA_SHADER_TYPES] = {
> -      ctx->Const.VertexProgram.MaxUniformComponents,
> -      ctx->Const.FragmentProgram.MaxUniformComponents,
> +      ctx->Const.VertexProgram.MaxUniformComponentsHardLimit,
> +      ctx->Const.FragmentProgram.MaxUniformComponentsHardLimit,
>        0          /* FINISHME: Geometry shaders. */
>     };
>  
> diff --git a/src/glsl/standalone_scaffolding.cpp
> b/src/glsl/standalone_scaffolding.cpp
> index 24cc64a..7d51c55 100644
> --- a/src/glsl/standalone_scaffolding.cpp
> +++ b/src/glsl/standalone_scaffolding.cpp
> @@ -83,11 +83,14 @@ void initialize_context_to_defaults(struct
> gl_context *ctx, gl_api api)
>     ctx->Const.MaxTextureCoordUnits = 2;
>     ctx->Const.VertexProgram.MaxAttribs = 16;
>  
> +   ctx->Const.VertexProgram.MaxUniformComponentsHardLimit =
>     ctx->Const.VertexProgram.MaxUniformComponents = 512;
> +   ctx->Const.MaxVaryingHardLimit =
>     ctx->Const.MaxVarying = 8; /* == gl_MaxVaryingFloats / 4 */
>     ctx->Const.MaxVertexTextureImageUnits = 0;
>     ctx->Const.MaxCombinedTextureImageUnits = 2;
>     ctx->Const.MaxTextureImageUnits = 2;
> +   ctx->Const.FragmentProgram.MaxUniformComponentsHardLimit =
>     ctx->Const.FragmentProgram.MaxUniformComponents = 64;
>  
>     ctx->Const.MaxDrawBuffers = 1;
> diff --git a/src/mesa/drivers/dri/i915/i915_context.c
> b/src/mesa/drivers/dri/i915/i915_context.c
> index ca03ad0..0fab9d2 100644
> --- a/src/mesa/drivers/dri/i915/i915_context.c
> +++ b/src/mesa/drivers/dri/i915/i915_context.c
> @@ -131,7 +131,7 @@ i915CreateContext(int api,
>     ctx->Const.MaxTextureUnits = I915_TEX_UNITS;
>     ctx->Const.MaxTextureImageUnits = I915_TEX_UNITS;
>     ctx->Const.MaxTextureCoordUnits = I915_TEX_UNITS;
> -   ctx->Const.MaxVarying = I915_TEX_UNITS;
> +   ctx->Const.MaxVaryingHardLimit = ctx->Const.MaxVarying =
> I915_TEX_UNITS;
>     ctx->Const.MaxCombinedTextureImageUnits =
>        ctx->Const.MaxVertexTextureImageUnits +
>        ctx->Const.MaxTextureImageUnits;
> diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c
> index e0af6ee..75b3441 100644
> --- a/src/mesa/main/context.c
> +++ b/src/mesa/main/context.c
> @@ -494,18 +494,21 @@ init_program_limits(GLenum type, struct
> gl_program_constants *prog)
>        prog->MaxParameters = MAX_VERTEX_PROGRAM_PARAMS;
>        prog->MaxAttribs = MAX_NV_VERTEX_PROGRAM_INPUTS;
>        prog->MaxAddressRegs = MAX_VERTEX_PROGRAM_ADDRESS_REGS;
> +      prog->MaxUniformComponentsHardLimit =
>        prog->MaxUniformComponents = 4 * MAX_UNIFORMS;
>        break;
>     case GL_FRAGMENT_PROGRAM_ARB:
>        prog->MaxParameters = MAX_NV_FRAGMENT_PROGRAM_PARAMS;
>        prog->MaxAttribs = MAX_NV_FRAGMENT_PROGRAM_INPUTS;
>        prog->MaxAddressRegs = MAX_FRAGMENT_PROGRAM_ADDRESS_REGS;
> +      prog->MaxUniformComponentsHardLimit =
>        prog->MaxUniformComponents = 4 * MAX_UNIFORMS;
>        break;
>     case MESA_GEOMETRY_PROGRAM:
>        prog->MaxParameters = MAX_NV_VERTEX_PROGRAM_PARAMS;
>        prog->MaxAttribs = MAX_NV_VERTEX_PROGRAM_INPUTS;
>        prog->MaxAddressRegs = MAX_VERTEX_PROGRAM_ADDRESS_REGS;
> +      prog->MaxUniformComponentsHardLimit =
>        prog->MaxUniformComponents = MAX_GEOMETRY_UNIFORM_COMPONENTS;
>        break;
>     default:
> @@ -614,7 +617,7 @@ _mesa_init_constants(struct gl_context *ctx)
>  #if FEATURE_ARB_vertex_shader
>     ctx->Const.MaxVertexTextureImageUnits =
>     MAX_VERTEX_TEXTURE_IMAGE_UNITS;
>     ctx->Const.MaxCombinedTextureImageUnits =
>     MAX_COMBINED_TEXTURE_IMAGE_UNITS;
> -   ctx->Const.MaxVarying = MAX_VARYING;
> +   ctx->Const.MaxVaryingHardLimit = ctx->Const.MaxVarying =
> MAX_VARYING;
>  #endif
>  #if FEATURE_ARB_geometry_shader4
>     ctx->Const.MaxGeometryTextureImageUnits =
>     MAX_GEOMETRY_TEXTURE_IMAGE_UNITS;
> diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
> index b3427da..7365598 100644
> --- a/src/mesa/main/mtypes.h
> +++ b/src/mesa/main/mtypes.h
> @@ -2699,6 +2699,9 @@ struct gl_program_constants
>     GLuint MaxNativeParameters;
>     /* For shaders */
>     GLuint MaxUniformComponents;  /**< Usually == MaxParameters * 4
>     */
> +   /* How many uniform components a driver can deal with on its own
> and not
> +    * fail, can be greater than MaxUniformComponents. */
> +   GLuint MaxUniformComponentsHardLimit;
>     /* ES 2.0 and GL_ARB_ES2_compatibility */
>     struct gl_precision LowFloat, MediumFloat, HighFloat;
>     struct gl_precision LowInt, MediumInt, HighInt;
> @@ -2764,6 +2767,9 @@ struct gl_constants
>  
>     /** Number of varying vectors between vertex and fragment shaders
>     */
>     GLuint MaxVarying;
> +   /* How many varyings a driver can deal with on its own and not
> fail,
> +    * can be greater than MaxVarying. */
> +   GLuint MaxVaryingHardLimit;
>     GLuint MaxVertexVaryingComponents;   /**< Between vert and geom
>     shader */
>     GLuint MaxGeometryVaryingComponents; /**< Between geom and frag
>     shader */
>  
> diff --git a/src/mesa/state_tracker/st_extensions.c
> b/src/mesa/state_tracker/st_extensions.c
> index 240497a..af2ed50 100644
> --- a/src/mesa/state_tracker/st_extensions.c
> +++ b/src/mesa/state_tracker/st_extensions.c
> @@ -173,6 +173,10 @@ void st_init_limits(struct st_context *st)
>        pc->MaxNativeAddressRegs     =
>        screen->get_shader_param(screen, sh,
>        PIPE_SHADER_CAP_MAX_ADDRS);
>        pc->MaxNativeParameters      =
>        screen->get_shader_param(screen, sh,
>        PIPE_SHADER_CAP_MAX_CONSTS);
>        pc->MaxUniformComponents     = 4 *
>        MIN2(pc->MaxNativeParameters, MAX_UNIFORMS);
> +      pc->MaxUniformComponentsHardLimit =
> screen->get_shader_param(screen, sh,
> +
>                                       PIPE_SHADER_CAP_MAX_CONSTS_HARD_LIMIT);
> +      pc->MaxUniformComponentsHardLimit =
> +            4 * MIN2(pc->MaxUniformComponentsHardLimit,
> MAX_UNIFORMS);
>        /* raise MaxParameters if native support is higher */
>        pc->MaxParameters            = MAX2(pc->MaxParameters,
>        pc->MaxNativeParameters);
>  
> @@ -210,6 +214,10 @@ void st_init_limits(struct st_context *st)
>     c->MaxVarying = screen->get_shader_param(screen,
>     PIPE_SHADER_FRAGMENT,
>                                              PIPE_SHADER_CAP_MAX_INPUTS);
>     c->MaxVarying = MIN2(c->MaxVarying, MAX_VARYING);
> +   c->MaxVaryingHardLimit =
> +      screen->get_shader_param(screen, PIPE_SHADER_FRAGMENT,
> +
>                               PIPE_SHADER_CAP_MAX_INPUTS_HARD_LIMIT);
> +   c->MaxVaryingHardLimit = MIN2(c->MaxVaryingHardLimit,
> MAX_VARYING);
>  
>     /* XXX we'll need a better query here someday */
>     if (screen->get_param(screen, PIPE_CAP_GLSL)) {
> --
> 1.7.5.4
> 
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/mesa-dev
> 


More information about the mesa-dev mailing list