[Mesa-dev] [PATCH 4/8] glsl: Add new builtins required by GL_ARB_sample_shading
Anuj Phogat
anuj.phogat at gmail.com
Thu Oct 17 01:33:49 CEST 2013
On Wed, Oct 16, 2013 at 3:49 PM, Ian Romanick <idr at freedesktop.org> wrote:
> 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.
>
I'll try these tests on AMD and NVIDIA hadware.
> 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