Bug 214948 - REGRESSION: [ ios14 ] webgl/1.0.3/conformance/glsl/functions/glsl-function-sign.html and webgl/1.0.3/conformance/glsl/misc/glsl-function-nodes.html are failing consistently.
Summary: REGRESSION: [ ios14 ] webgl/1.0.3/conformance/glsl/functions/glsl-function-si...
Status: ASSIGNED
Alias: None
Product: WebKit
Classification: Unclassified
Component: WebGL (show other bugs)
Version: WebKit Nightly Build
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Kimmo Kinnunen
URL:
Keywords: InRadar
Depends on: 222964
Blocks:
  Show dependency treegraph
 
Reported: 2020-07-29 16:26 PDT by Dean Jackson
Modified: 2022-08-11 03:22 PDT (History)
5 users (show)

See Also:


Attachments
result (5.58 KB, image/png)
2020-07-29 17:49 PDT, Dean Jackson
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Dean Jackson 2020-07-29 16:26:50 PDT
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
Comment 1 Dean Jackson 2020-07-29 16:27:13 PDT
rdar://64701357
Comment 2 Dean Jackson 2020-07-29 16:27:52 PDT
The tests work ok on device. This is specific to the simulator.
Comment 3 Dean Jackson 2020-07-29 17:31:01 PDT
The rendered images are definitely different.
Comment 4 Dean Jackson 2020-07-29 17:35:48 PDT
The vertex shader tests are failing.
Comment 5 Dean Jackson 2020-07-29 17:37:35 PDT
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);
}
]]]
Comment 6 Dean Jackson 2020-07-29 17:40:32 PDT
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)
Comment 7 Dean Jackson 2020-07-29 17:48:48 PDT
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.
Comment 8 Dean Jackson 2020-07-29 17:49:04 PDT
Created attachment 405533 [details]
result
Comment 9 Dean Jackson 2020-07-29 17:51:32 PDT
Those endpoints come out ok! There must be intermediate points in the drawn element.
Comment 10 Dean Jackson 2020-07-29 17:52:52 PDT
Yeah, 4x4 grid.
Comment 11 Dean Jackson 2020-07-29 18:09:03 PDT
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]
Comment 12 Dean Jackson 2020-07-29 18:11:35 PDT
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.
Comment 13 Dean Jackson 2020-07-29 18:14:43 PDT
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.
Comment 14 Kenneth Russell 2020-07-29 19:41:47 PDT
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.
Comment 15 Kimmo Kinnunen 2021-03-17 03:28:26 PDT
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