On iOS 14 simulator, the following two tests are failing: webgl/1.0.3/conformance/glsl/functions/glsl-function-sign.html webgl/1.0.3/conformance/glsl/misc/glsl-function-nodes.html
rdar://64701357
The tests work ok on device. This is specific to the simulator.
The rendered images are definitely different.
The vertex shader tests are failing.
This is quite weird. This is the reference vertex shader: [[[ attribute vec4 aPosition; varying vec4 vColor; float sign_base(float value) { if (value == 0.0) return 0.0; return value > 0.0 ? 1.0 : -1.0; } float sign_emu(float value) { return sign_base(value); } void main() { gl_Position = aPosition; vec2 texcoord = vec2(aPosition.xy * 0.5 + vec2(0.5, 0.5)); vec4 color = vec4( texcoord, texcoord.x * texcoord.y, (1.0 - texcoord.x) * texcoord.y * 0.5 + 0.5); vColor = vec4( sign_emu(color.x * 2.0 - 1.0) * 0.5 + 0.5, 0.5, 0, 1); } ]]] and this is the test vertex shader: [[[ attribute vec4 aPosition; varying vec4 vColor; void main() { gl_Position = aPosition; vec2 texcoord = vec2(aPosition.xy * 0.5 + vec2(0.5, 0.5)); vec4 color = vec4( texcoord, texcoord.x * texcoord.y, (1.0 - texcoord.x) * texcoord.y * 0.5 + 0.5); vColor = vec4( sign(color.x * 2.0 - 1.0) * 0.5 + 0.5, 0.5, 0, 1); } ]]]
So, the built-in "sign" function is not equivalent to the explicit form of float sign(float value) { if (value == 0.0) return 0.0; return value > 0.0 ? 1.0 : -1.0; } (I'm not sure why the test puts it through another function)
Let's try to work out what it is actually returning! texcoord is the normalized vertex position. vec4 color = vec4( texcoord, texcoord.x * texcoord.y, (1.0 - texcoord.x) * texcoord.y * 0.5 + 0.5); So for input texcoords... 0,0 -> color = 0, 0, 0, 0.5 0,1 -> color = 0, 1, 0, 1 1,0 -> color = 1, 0, 0, 1 1,1 -> color = 1, 1, 1, 0.5 Now the varying value vColor = vec4( sign(color.x * 2.0 - 1.0) * 0.5 + 0.5, 0.5, 0, 1); 0,0 [[sign(-1) * 0.5 + 0.5]] -> 0, 0.5, 0, 1 0,1 [[sign(-1) * 0.5 + 0.5]] -> 0, 0.5, 0, 1 1,0 [[sign(1) * 0.5 + 0.5]] -> 1, 0.5, 0, 1 1,1 [[sign(1) * 0.5 + 0.5]] -> 1, 0.5, 0, 1 Attaching the result as a screenshot.
Created attachment 405533 [details] result
Those endpoints come out ok! There must be intermediate points in the drawn element.
Yeah, 4x4 grid.
The problem is that the built-in sign appears to be a no-op. ie. sign(-0.5) returns -0.5. Here's my test case: void main() { gl_Position = aPosition; vec2 texcoord = vec2(aPosition.xy * 0.5 + vec2(0.5, 0.5)); vec4 color = vec4( texcoord, texcoord.x * texcoord.y, (1.0 - texcoord.x) * texcoord.y * 0.5 + 0.5); // New code here. float a = (color.x * 2.0 - 1.0) < 0.0 ? -1.0 : 1.0; float b = sign(color.x * 2.0 - 1.0); if (a != b) { vColor = vec4(1.0, 0.0, 0.0, 1.0); } else { vColor = vec4( sign(color.x * 2.0 - 1.0) * 0.5 + 0.5, 0.5, 0, 1); } } ... which shouldn't produce any red, but it does between about texCoords [0.25,0.75]
Now the question is whether this really is a regression from ANGLE. I can't imagine it would be replacing the built-in sign function with something that doesn't work. Actually, my replaced code isn't right. sign returns 0 when the input is 0.
I was wrong. It's that the built-in is not returning 0 for an input of 0! Still doesn't explain why ANGLE is to blame.
I wonder whether ANGLE's internal shader compiler instance might not be enabling some of the driver bug workarounds that used to be enabled by WebKit's manually constructed instance. Perhaps check the options that were previously being passed into sh::Compile in the ANGLEWebKitBridge, and see if any are missing inside ANGLE when it constructs its compiler instance? See Source/ThirdParty/ANGLE/include/GLSLANG/ShaderLang.h , and for example SH_REWRITE_FLOAT_UNARY_MINUS_OPERATOR.
The original TestExpectation was put to platform/ios/, even though the problem was in ios-simulator. This does not seem to be failing anymore, possibly because of angle update or fixing few workarounds in angle. Blocking weblg2conformance to remove the problematic expectations. once the expectations are removed, this can be closed. Removal targeted in bug 222964