[Mesa-dev] [PATCH 11/17] mesa: Get GL_MAX_VARYING_FLOATS_ARB from VertexProgram.MaxOutputComponents

Ian Romanick idr at freedesktop.org
Wed Sep 18 13:04:49 PDT 2013


On 09/13/2013 01:45 PM, Paul Berry wrote:
> On 11 September 2013 16:28, Ian Romanick <idr at freedesktop.org
> <mailto:idr at freedesktop.org>> wrote:
> 
>     On 09/11/2013 04:05 PM, Paul Berry wrote:
>     > On 10 September 2013 12:10, Ian Romanick <idr at freedesktop.org
>     <mailto:idr at freedesktop.org>
>     > <mailto:idr at freedesktop.org <mailto:idr at freedesktop.org>>> wrote:
>     >
>     >     From: Ian Romanick <ian.d.romanick at intel.com
>     <mailto:ian.d.romanick at intel.com>
>     >     <mailto:ian.d.romanick at intel.com
>     <mailto:ian.d.romanick at intel.com>>>
>     >
>     >     Signed-off-by: Ian Romanick <ian.d.romanick at intel.com
>     <mailto:ian.d.romanick at intel.com>
>     >     <mailto:ian.d.romanick at intel.com
>     <mailto:ian.d.romanick at intel.com>>>
>     >     ---
>     >      src/mesa/main/get.c              | 4 ----
>     >      src/mesa/main/get_hash_params.py | 2 +-
>     >      2 files changed, 1 insertion(+), 5 deletions(-)
>     >
>     >     diff --git a/src/mesa/main/get.c b/src/mesa/main/get.c
>     >     index 34eb6be..ae45bf8 100644
>     >     --- a/src/mesa/main/get.c
>     >     +++ b/src/mesa/main/get.c
>     >     @@ -718,10 +718,6 @@ find_custom_value(struct gl_context *ctx,
>     const
>     >     struct value_desc *d, union valu
>     >            ASSERT(v->value_int_n.n <=
>     ARRAY_SIZE(v->value_int_n.ints));
>     >            break;
>     >
>     >     -   case GL_MAX_VARYING_FLOATS_ARB:
>     >     -      v->value_int = ctx->Const.MaxVarying * 4;
>     >     -      break;
>     >     -
>     >         /* Various object names */
>     >
>     >         case GL_TEXTURE_BINDING_1D:
>     >     diff --git a/src/mesa/main/get_hash_params.py
>     >     b/src/mesa/main/get_hash_params.py
>     >     index c0dbf45..3d47443 100644
>     >     --- a/src/mesa/main/get_hash_params.py
>     >     +++ b/src/mesa/main/get_hash_params.py
>     >     @@ -365,7 +365,7 @@ descriptor=[
>     >
>     >      # GL_ARB_vertex_shader
>     >        [ "MAX_VERTEX_UNIFORM_COMPONENTS_ARB",
>     >     "CONTEXT_INT(Const.VertexProgram.MaxUniformComponents),
>     >     extra_ARB_vertex_shader" ],
>     >     -  [ "MAX_VARYING_FLOATS_ARB", "LOC_CUSTOM, TYPE_INT, 0,
>     >     extra_ARB_vertex_shader" ],
>     >     +  [ "MAX_VARYING_FLOATS_ARB",
>     >     "CONTEXT_INT(Const.VertexProgram.MaxOutputComponents),
>     >     extra_ARB_vertex_shader" ],
>     >
>     >      # GL_EXT_framebuffer_blit
>     >      # NOTE: GL_DRAW_FRAMEBUFFER_BINDING_EXT ==
>     GL_FRAMEBUFFER_BINDING_EXT
>     >     --
>     >     1.8.1.4
>     >
>     >     _______________________________________________
>     >     mesa-dev mailing list
>     >     mesa-dev at lists.freedesktop.org
>     <mailto:mesa-dev at lists.freedesktop.org>
>     <mailto:mesa-dev at lists.freedesktop.org
>     <mailto:mesa-dev at lists.freedesktop.org>>
>     >     http://lists.freedesktop.org/mailman/listinfo/mesa-dev
>     >
>     > Doesn't MAX_VARYING_FLOATS need to be
>     MIN2(MAX_VERTEX_OUTPUT_COMPONENTS,
>     > MAX_FRAGMENT_INPUT_COMPONENTS)?  I can imagine an implementation where
>     > MAX_FRAGMENT_INPUT_COMPONENTS is the smaller constraint (in fact,
>     ES3's
>     > minimum maximums constitute just such a case).
> 
>     It's all so much more horrible than you think. :)
> 
>     OpenGL 3.2 sets:
> 
>     MAX_VARYING_COMPONENTS: 60
>     MAX_VERTEX_OUTPUT_COMPONENTS: 64
>     MAX_FRAGMENT_INPUT_COMPONENTS: 128
> 
>     OpenGL ES 3.0 sets:
> 
>     MAX_VARYING_COMPONENTS: 60
>     MAX_VARYING_VECTORS: 15
>     MAX_VERTEX_OUTPUT_VECTORS: 16
>     MAX_VERTEX_OUTPUT_COMPONENTS: 64
>     MAX_FRAGMENT_INPUT_VECTORS: 15
>     MAX_FRAGMENT_INPUT_COMPONENTS: 60
> 
> 
> Oddly, I don'tsee MAX_VERTEX_OUTPUT_VECTORS or
> MAX_FRAGMENT_INPUT_VECTORS in the GLES 3 spec; only MAX_VARYING_VECTORS.

Brilliant.  The API spec uses GL_MAX_*_COMPONENTS, but the GLSL built-in
variables are gl_Max*Vectors.

>     BUT the description of MAX_VARYING_COMPONENTS in GLES3 says:
> 
>         "Number of components for output variables."
> 
>     So... OpenGL 3.2 makes no sense, and OpenGL ES 3.0 seems self
>     contradictory.  The core problem seems to be the way that each API (and
>     each driver) counts gl_Position and gl_FragCoord.  Some say it's
>     counted, some say it's not counted, and some say it might be counted.
>     Our existing infrastructure may not be sufficient to handle all
>     combinations of those cases.
> 
> 
> I've spent a while digging through the specs, and I actually don't think
> it's quite as complicated or counterintuitive as it sounded at first.
> 
> First of all, we don't need to worry about the distinction between
> COMPONENTS and VECTORS, because MAX_foo_COMPONENTS always equals
> MAX_foo_VECTORS * 4.  Similarly, there's no need to distinguish between
> MAX_VARYING_COMPONENTS and MAX_VARYING_FLOATS.

Right.  In fact, the differing names have the same enum values.

> As for the question of whether gl_Position and gl_FragCoord count
> against these limits, all GL specs since 2.0, and all GLES specs since
> 2.0 seem to agree that gl_Position is *not* counted for
> MAX_VARYING_COMPONENTS, however MAX_*_OUTPUT_COMPONENTS and
> MAX_*_INPUT_COMPONENTS count *all* inputs and outputs.  I think
> reasonable to infer that the spec writers probably intended for the same
> to apply to gl_FragCoord and gl_FrontFacing (namely, they don't count
> against MAX_VARYING_COMPONENTS, but the do count against
> MAX_FRAGMENT_INPUT_COMPONENTS).

The OpenGL 3.1 spec says:

    "The transformed vertex position (gl_Position) is not a varying
    variable and does not count against [MAX_VARYING_COMPONENTS]."

However, the OpenGL ES 3.0 and OpenGL 3.2 (and later) specs say:
	
    "When a program is linked, all components of any varying and
    special variable written by a vertex shader will count against
    [MAX_VERTEX_OUTPUT_COMPONENTS]."

And

    "This limit is given by the value of the implementation-dependent
    constant MAX_VARYING_COMPONENTS. Each varying or special variable
    component used as either a vertex shader output or fragment
    shader input count against this limit, except for the components
    of gl_Position."

And

    "When a program is linked, all components of any varying and
    special variable read by a fragment shader will count against
    [MAX_FRAGMENT_INPUT_COMPONENTS]."

MAX_VARYING_COMPONENTS was reduced from 64 to 60 in 3.2 because, as I
recall, some vendor (AMD?) had to use varying space for gl_FragCoord.
If gl_FragCoord wasn't read, gl_Position didn't need any space.  I
/think/.  Those discussions were a loooong time ago.

The stage-specific values are 64 on desktop GL because gl_Position and
gl_FragCoord are counted.  I don't know why
MAX_FRAGMENT_INPUT_COMPONENTS is only 60 on ES.  Given the different
counting, 64 seems to be the correct value if MAX_VARYING_COMPONENTS is
64. *shrug*

> Interestingly, ARB_vertex_shader doesn't specifically mention that
> gl_Position is excluded from MAX_VARYING_FLOATS, but it defines
> MAX_VARYING_FLOATS as the number of "interpolators" that are available,
> so I think it's a reasonable interpretation that gl_Position is not
> intended to be counted (especially given that this is the interpretation
> that the GL spec authors chose when promoting the extension into GL 2.0).
> 
> Note that all the specs allow for the possibility that device-dependent
> optimizations may allow for more than the advertised number of
> inputs/outputs/varyings to be supported in some circumstances, so if a
> certain piece of hardware has dedicated input/output locations for
> certain variables, that's not a problem; it simply means that in some
> situations the driver may be able to successfully compile and link a
> shader that isn't strictly guaranteed by the spec to work.
> 
> So it seems to me that there's a single consistent interpretation:
> clients may assume that MAX_VARYING_{FLOATS,COMPONENTS,VECTORS} applies
> just to things that are truly varyings (gl_Position, gl_FragCoord, and
> gl_FrontFacing are exempted), but to be safe, clients must assume that
> MAX_*_OUTPUT_COMPONENTS and MAX_*_INPUT_COMPONENTS apply to all shader
> inputs/outputs.  However, implementations are free to choose not to
> count certain inputs/outputs against these limits, causing them to
> successfully compile and link shaders that would otherwise fail.
> 
> (There is the minor wrinkle that certain implementations have a
> hardware-imposed limit of 64 on the number of vertex output components
> (including gl_Position), so they aren't strictly able to support GL
> 3.0-3.1's requirement that MAX_VARYING_COMPONENTS >= 64.  I'm not sure
> if Mesa supports any of these implementations; but if it does, I think
> we can finesse that issue).
> 
>     In the end, I opted to use VertexProgram.MaxOutputComponents because
>     MAX_VARYING_FLOATS was added by GL_ARB_vertex_shader.
> 
>     I guess I'm not sure what the "right" answer actually is now. :(
> 
> 
> Now that I've spent a day thinking about all this, it seems to me that
> Mesa front end shouldn't ever try to infer MAX_VARYING_COMPONENTS from
> MAX_VERTEX_OUTPUT_COMPONENTS and MAX_FRAGMENT_INPUT_COMPONENTS, because
> the relationship between them depends on exactly what the hardware
> limitations are.  For example, once my 128-varyings patches land, Mesa
> on i965/gen6+ will be able to support:
> 
> MAX_VARYING_COMPONENTS 128
> MAX_VERTEX_OUTPUT_COMPONENTS 128
> MAX_FRAGMENT_INPUT_COMPONENTS 128
> 
> because the hardware has dedicated locations for gl_Position,
> gl_FragCoord, and gl_FrontFacing.  But implementations that don't have
> those dedicated locations might support as little as:
> 
> MAX_VARYING_COMPONENTS 120
> MAX_VERTEX_OUTPUT_COMPONENTS 128
> MAX_FRAGMENT_INPUT_COMPONENTS 128
> 
> So I think the back-end should just specify all three of these values
> independently, and Mesa should expose them to the client without
> applying any further math to them (other than the factor of 4 to convert
> between component and vector counts).

I think, unfortunately, you are correct.  I'm going to push the first 10
patches in the series, and I'll respin the last 7.

> Another question which we haven't really addressed is how Mesa's front
> end linker should check these limits, given the fact that some
> implementations have dedicated locations for certain shader
> inputs/outputs.  I have a few ideas about this, but it's probably
> something that we should save for a future patch series.

Maybe the 39th time will be the charm. :(  The last time this came up
was w.r.t. gl_Color and gl_SecondaryColor.  Most (all?) SM2 hardware
(i915, r300, and probably others) have special slots that can be used
for *clamped* fragment shader inputs.  So, gl_Color can use those slots
if the API setting of CLAMP_VERTEX_COLOR is TRUE.  This control is added
by the GL_ARB_color_buffer_float extension and OpenGL 3.0

I think we need a flag for each special variable that says whether or
not it is counted.  I think Marek implemented something like this for
gl_Color.



More information about the mesa-dev mailing list