Greetings -
Debugging an issue here with one of the shaders which works fine on other hardware, but fails to compile on my Radeon 7950. Using Catalyst 14.1 Beta driver here (since I wanted to try out Mantle on BF4 ) on this machine, haven't tried other AMD GPUs yet, on different drivers. but this might be a known issue.
The shader fetches texels from a sampler2DArrayShadow, averages them via PCF and that works fine using texture(...)
[Snippet]
uniform sampler2DArrayShadow m_shadowSampler[kMaxShadowSamplers];
... // Compute other stuff, set index by comparing with cascade bounds
vec4 shadowPos = m_entityparameters.m_biasedShadowMvp[lightIndex*kMaxShadowCascades+index] * vec4(shaderInput.m_position, 1.f);
... // Add layer to vec4, bias z etc.
float sum = texture(m_shadowSampler[lightIndex], shadowPos);
Now using a gaussian kernel to smooth the borders, the shader does this:
// Gaussian 3x3 kernel
float sum = texture(m_shadowSampler[lightIndex], shadowPos) * 0.25f;
vec4 samples;
samples.x = textureOffset(m_shadowSampler[lightIndex], shadowPos, ivec2(-1,-1));
samples.y = textureOffset(m_shadowSampler[lightIndex], shadowPos, ivec2(-1,+1));
samples.z = textureOffset(m_shadowSampler[lightIndex], shadowPos, ivec2(+1,-1));
samples.w = textureOffset(m_shadowSampler[lightIndex], shadowPos, ivec2(+1,+1));
sum += dot(vec4(0.0625f), samples);
samples.x = textureOffset(m_shadowSampler[lightIndex], shadowPos, ivec2(-1, 0));
samples.y = textureOffset(m_shadowSampler[lightIndex], shadowPos, ivec2( 0,-1));
samples.z = textureOffset(m_shadowSampler[lightIndex], shadowPos, ivec2( 0,+1));
samples.w = textureOffset(m_shadowSampler[lightIndex], shadowPos, ivec2(+1, 0));
sum += dot(vec4(0.125f), samples);
Compiles fine on Nvidia hardware for example, but shader compiler on 14.1 reports:
Source:Shader Compiler Type:Error ID:2000
Severity:High Message:glCompileShader failed to compile a GLSL shader with the
following shader info log: 'Fragment shader failed to compile with the followin
g errors:
ERROR: 1:110: error(#202) No matching overloaded function found: textureOffset
ERROR: 1:111: error(#202) No matching overloaded function found: textureOffset
ERROR: 1:112: error(#202) No matching overloaded function found: textureOffset
ERROR: 1:113: error(#202) No matching overloaded function found: textureOffset
ERROR: 1:116: error(#202) No matching overloaded function found: textureOffset
ERROR: 1:117: error(#202) No matching overloaded function found: textureOffset
ERROR: 1:118: error(#202) No matching overloaded function found: textureOffset
ERROR: 1:119: error(#202) No matching overloaded function found: textureOffset
ERROR: error(#273) 8 compilation errors. No code generated
The specs says:
textureOffset - OpenGL 4 Shading Language Reference Pages
float textureOffset( | sampler2DArrayShadow sampler, |
vec4 P, | |
vec2 offset) ; |
Noticed the vec2 instead of ivec2 that I'm using, not sure if this is a typo in the spec. Nonetheless, I've tried using vec2 with the same effect.
Any clues?
Thanks
I Think your problem don't come from the offset format but from the texture coordinate format.
OpenGL documentation :
gvec textureOffset(gsampler sampler, vec texCoord, ivec offset[, float bias]);
The texCoord will have its value offset by offset texels before performing the lookup. Cubemap, multisample, and buffer samplers are not allowed as types for gsampler.
The type ivec has the same type, but in integers, as vec. So when accessing a 2D sampler, vec is "vec2" and ivec is "ivec2". When accessing a 1D sampler, vec is "float" and ivec is "int".
You are using a sampler2D texture so there is just 2 dimension for your texture coordinate. Your variable shadowPos must be a vec2
Recently ran into the same issue.
But also wanted to say, that in this case, tomus, you are wrong because he (and me) isn't using a regular sampler2D, but a sampler2DArrayShadow.
A sampler2DArrayShadow requires 4 coordinates: U, V, Layer and Ref value. The layer selects the proper array slice and the ref value does the depth comparison.
nVidia and Intel's implementations handle this just fine.
This is a bug on AMD's side.
So the prototype for textureOffset() for this case is:
float textureOffset (sampler2DShadow sampler, vec3 P, ivec2 offset [, float bias] )
Note that this a non-LOD version of the function, meaning you can't use it in vertex shader stage. I'm assuming this is not the case, right?
Anyway, I would appreciate if you could copy-paste shader code which fails to compile. I'll be happy to have a look and see if I can help.
textureOffset (sampler2DShadow ...
Nope: sampler2DArrayShadow. ARRAY samplers need an extra member in P that specifies the layer.
sampler2DShadow requires U,V,Ref
sampler2DArrayShadow requires U,V,Layer,Ref
If you look at the man pages for 'textureOffset', you'll notice that P is the same exact P used by the regular texture function (as it should). At the man page for 'texture', P is defined as following:
For shadow forms, when compare is present, it is used as Dsub and the array layer is specified in P.w. When compare is not present, the last component of P is used as Dsub and the array layer is specified in the second to last component of P. (The second component of P is unused for 1D shadow lookups.)
L.E. : usage code
I wouldn't really pay that much attention to reference pages. Official specification should always be the reference.
From https://www.opengl.org/registry/doc/GLSLangSpec.4.50.pdf, we have:
gvec4 textureOffset (gsampler2DArray sampler, vec3 P, ivec2 offset [, float bias] )
So yeah, on the surface that shader should work. For reproduction purposes, can I ask you to copy-paste the whole GLSL body of the fragment shader which fails to compile, please? The shader you linked to seems to only hold function implementations. Thanks.
On this (rare) occasion, the man pages actually match up with the official spec.
From the PDF: float textureOffset(sampler2DArrayShadow sampler, vec4 P, ivec2 offset ); (p. 165)
So it should indeed compile. However, with the latest Crimson driver (16.6.1) I get the exact same "ERROR: 1:110: error(#202) No matching overloaded function found: textureOffset" message.
Don't know if a complete GLSL body would help much as I create shaders on the fly from various small files such as the linked one and offline compilation tools usually fall over when analyzing it.
The final fragment shader is about 1000 lines of code with odd spacing for the most basic case (no textures, no skinning, etc). The vertex shader isn't all that short, either.
I linked my nVidia generated code which should use the problematic code (everything else vendor specific is commented out).
I'll see if I can generate something smaller and portable, maybe using some online GLSL tool or something.