[Mesa-dev] [PATCH 4/8] glsl: Add new builtins required by GL_ARB_sample_shading
Ian Romanick
idr at freedesktop.org
Thu Oct 17 00:49:17 CEST 2013
On 10/16/2013 11:29 AM, Kenneth Graunke wrote:
> On 10/16/2013 10:40 AM, Ian Romanick wrote:
>> On 10/15/2013 07:50 PM, Kenneth Graunke wrote:
> [snip]
>>> Right, but gl_SampleMask is not an unsized array. It's statically sized
>>> based on your implementation's maximum supported number of color samples
>>> (ceil(samples/32)), and this is totally known at compile time...
>>
>> That doesn't match what the spec says. At least the GLSL 4.00 spec:
>>
>> "In the fragment language, built-in variables are intrinsically
>> declared as:
>>
>> in vec4 gl_FragCoord;
>> in bool gl_FrontFacing;
>> in float gl_ClipDistance[];
>> in vec2 gl_PointCoord;
>> in int gl_PrimitiveID;
>> in int gl_SampleID;
>> in vec2 gl_SamplePosition;
>> out vec4 gl_FragColor;
>> out vec4 gl_FragData[gl_MaxDrawBuffers];
>> out float gl_FragDepth;
>> out int gl_SampleMask[];"
>>
>> Note that both gl_ClipDistance and gl_SampleMask are unsized, and both
>> have a maximum size based on implementation limits. Later the GLSL 4.00
>> spec says:
>>
>> "This array must be sized in the fragment shader either implicitly
>> or explicitly to be the same size as the implementation-dependent
>> maximum sample-mask (as an array of 32bit elements), determined by
>> the maximum number of samples."
>>
>> The maximum size of the array is ceil(max_samples/32), but initially it
>> is unsized.
>
> You've got to be kidding me. This is utter and complete garbage.
> "We know exactly how big the array is, at compile time, but we're going
> to make you, the technical artist, tell us anyway. By the way, you have
> to guess the exact number we're thinking."
>
> So, about that "explicitly the same size" text...what if my shader sets
> it to some /other/ size? What happens?
>
> * Larger than ceil(float(gl_NumSamples)/32.0):
>
> A compile error? Truncated to the right size? Probably the same
> behavior as ClipDistance. That doesn't seem well specified either.
>
> * Smaller than ceil(float(gl_NumSamples)/32.0):
>
> From the GLSL 4.40 specification,
> "If the fragment shader statically assigns a value to gl_SampleMask,
> the sample mask will be undefined for any array elements of any
> fragment shader invocations that fail to assign a value."
>
> The hardware is expecting a certain number of samples, so ultimately,
> the fact that you don't have them means they're undefined. Just like
> the above case of forgetting to assign them. Do we pretend the array is
> the right size, ignoring their request and treating any unwritten
> elements as unsized? Or do we reject it as a compile error?
>
> ...
>
> Also, considering that the Radeon 8970 (arguably AMD's best card today)
> only does 24x MSAA, and it looks like nVidia's GTX Titan doesn't do more
> than 32x (though it's harder to tell), this array will always be exactly
> size 1 for every implementation in existence.
Looking that revision history, it was a fairly late change to make
gl_SampleMask an array at all. It was just a scalar int.
> <sarcasm>
> I'm sure applications are fully on board to explicitly declare this and
> cope with the consequences of it not being a single integer.
> </sarcasm>
Maybe. I doubt there are very many applications that use gl_SampleMask.
Of the ones that do, they probably also use gl_SampleMaskIn and do
something like:
gl_SampleMask = gl_SampleMaskIn; // of course this fails. duh
or
for (...)
gl_SampleMask[i] = gl_SampleMaskIn[i];
Note that the spec says "implicitly or explicitly". The latter form
implicitly sizes gl_SampleMask to be the same size as gl_SampleMaskIn.
In ARB_gpu_shader5, gl_SampleMaskIn has somewhat more sensible language:
in int gl_SampleMaskIn[];
The variable gl_SampleMaskIn is an array of integers, each holding a
bitfield indicating the set of samples covered by the primitive
generating the fragment during multisample rasterization. The
array has ceil(<s>/32) elements, where <s> is the maximum number of
color samples supported by the implementation. Bit <n> or word <w>
in the bitfield is set if and only if the sample numbered
<w>*32+<n> is considered covered for this fragment shader
invocation.
> That said, at this point, it's about 4 years too late to change the
> idiocy of the spec, so we're kind of stuck. We probably ought to
> investigate what other vendors do.
You are completely correct here. We should check what other vendors do.
I think 5 tests will tell us everything we need to know (then we'll
probably submit some spec bugs). I don't have any non-Intel hardware
that supports either extension, so I can't actually try any of these.
1. Does this compile, link, and run:
#version 130
#extension GL_ARB_sample_shading: require
out vec4 color;
void main() {
color = vec4(gl_SampleMask.length());
gl_SampleMask[0] = ~0;
}
2. Does this compile and link:
#version 130
#extension GL_ARB_sample_shading: require
out vec4 color;
void main() {
color = vec4(1);
gl_SampleMask[0] = ~0;
gl_SampleMask[1] = ~0;
}
3. Does this compile and link:
#version 130
#extension GL_ARB_sample_shading: require
#extension GL_ARB_gpu_shader5: require
out vec4 color;
void main() {
color = vec4(1);
gl_SampleMask = gl_SampleMaskIn;
}
4. Does this compile and link:
#version 130
#extension GL_ARB_sample_shading: require
out vec4 color;
in int gl_SampleMask[1];
void main() {
color = vec4(1);
gl_SampleMask[0] = ~0;
}
5. Does this compile and link:
#version 130
#extension GL_ARB_sample_shading: require
out vec4 color;
in int gl_SampleMask[2];
void main() {
color = vec4(1);
gl_SampleMask[0] = ~0;
gl_SampleMask[1] = ~0;
}
> --Ken
More information about the mesa-dev
mailing list