Bug 1505871. Work around a suspected shader miscompilation on Windows. r=gw
authorTimothy Nikkel <tnikkel@gmail.com>
Tue, 26 Feb 2019 00:16:37 -0600
changeset 461132 55ba29bf61f031b82f94a76e18f2f769ac0b264e
parent 461131 1562b43107f242b18e342c8b7c9c76b9aa9fcf96
child 461133 30f9e207c3d4dd83247792c3806668e09273cf36
push id35618
push usershindli@mozilla.com
push dateTue, 26 Feb 2019 16:54:44 +0000
treeherdermozilla-central@d326a9d5f77b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgw
bugs1505871
milestone67.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1505871. Work around a suspected shader miscompilation on Windows. r=gw On Windows the vFuncs array is always 0 in the fragment shader. If we move the computation of the vFuncs array outside of the switch (so that it is computed for every type of shader, even when it is not needed) then it works.
gfx/wr/webrender/res/brush_blend.glsl
--- a/gfx/wr/webrender/res/brush_blend.glsl
+++ b/gfx/wr/webrender/res/brush_blend.glsl
@@ -61,16 +61,26 @@ void brush_vs(
     float oneMinusLumB = 1.0 - lumB;
 
     float amount = float(user_data.z) / 65536.0;
     float invAmount = 1.0 - amount;
 
     vOp = user_data.y & 0xffff;
     vAmount = amount;
 
+    // This assignment is only used for component transfer filters but this
+    // assignment has to be done here and not in the component transfer case
+    // below because it doesn't get executed on Windows because of a suspected
+    // miscompile of this shader on Windows. See
+    // https://github.com/servo/webrender/wiki/Driver-issues#bug-1505871---assignment-to-varying-flat-arrays-inside-switch-statement-of-vertex-shader-suspected-miscompile-on-windows
+    vFuncs[0] = (user_data.y >> 28) & 0xf; // R
+    vFuncs[1] = (user_data.y >> 24) & 0xf; // G
+    vFuncs[2] = (user_data.y >> 20) & 0xf; // B
+    vFuncs[3] = (user_data.y >> 16) & 0xf; // A
+
     switch (vOp) {
         case 2: {
             // Grayscale
             vColorMat = mat3(
                 vec3(lumR + oneMinusLumR * invAmount, lumR - lumR * invAmount, lumR - lumR * invAmount),
                 vec3(lumG - lumG * invAmount, lumG + oneMinusLumG * invAmount, lumG - lumG * invAmount),
                 vec3(lumB - lumB * invAmount, lumB - lumB * invAmount, lumB + oneMinusLumB * invAmount)
             );
@@ -115,20 +125,16 @@ void brush_vs(
             vec4 offset_data = fetch_from_gpu_cache_1(user_data.z + 4);
             vColorMat = mat3(mat_data[0].xyz, mat_data[1].xyz, mat_data[2].xyz);
             vColorOffset = offset_data.rgb;
             break;
         }
         case 13: {
             // Component Transfer
             vTableAddress = user_data.z;
-            vFuncs[0] = (user_data.y >> 28) & 0xf; // R
-            vFuncs[1] = (user_data.y >> 24) & 0xf; // G
-            vFuncs[2] = (user_data.y >> 20) & 0xf; // B
-            vFuncs[3] = (user_data.y >> 16) & 0xf; // A
             break;
         }
         default: break;
     }
 }
 #endif
 
 #ifdef WR_FRAGMENT_SHADER