servo / webrender

A GPU-based renderer for the web
https://doc.servo.org/webrender/
Mozilla Public License 2.0
3.14k stars 279 forks source link

Angle (EGL via D3D) shader compilation failed (error X3004) #3661

Open paulrouget opened 5 years ago

paulrouget commented 5 years ago

I'm running Servo on Windows via Angle. Servo crashes after this failure:

ERROR - Failed to link shader program: cs_border_solid
C:\fakepath(126,1-2): error X3004: undeclared identifier 's3'

Warning: D3D shader compilation failed with default flags. (vs_5_0)
 Retrying with skip validation
C:\fakepath(126,1-2): error X3004: undeclared identifier 's3'

Warning: D3D shader compilation failed with skip validation flags. (vs_5_0)
 Retrying with skip optimization
C:\fakepath(126,1-2): error X3004: undeclared identifier 's3'

Warning: D3D shader compilation failed with skip optimization flags. (vs_5_0)

Failed to create D3D shaders.
paulrouget commented 5 years ago

I do not use mozangle, but https://github.com/microsoft/angle.

Here is how I initialize OpenGLES: https://github.com/paulrouget/HLServo/blob/master/OpenGLES.cpp

paulrouget commented 5 years ago

/cc @pcwalton @gw3583

kvark commented 5 years ago

@paulrouget what if you just do cargo test inside the WR folder? That should build all the shaders with mozangle, it would be interesting if this also fails for you.

Extracting the shader code generated by Angle (in case of errors like this) is somewhat painful. We could break here and inspect the state closely.

paulrouget commented 5 years ago

what if you just do cargo test inside the WR folder?

All green.

Extracting the shader code generated by Angle (in case of errors like this) is somewhat painful. We could break here and inspect the state closely.

I guess the equivalent would be this function. If I manage to break here, what should I be looking at?

kvark commented 5 years ago

All green.

Do you see "angle_shader_validation" test running? I wonder if we got the test diverging from what renderer is using, again.

If I manage to break here, what should I be looking at?

Identifier "s3"

jdm commented 5 years ago

I have reproduced this loading google.com in the UWP Servo app, so I'll poke around in the debugger.

jdm commented 5 years ago

Additionally, we get a gl error 1282 (INVALID_OPERATION) after a call to glDrawElementsInstanced.

staktrace commented 5 years ago

Might be related to https://bugzilla.mozilla.org/show_bug.cgi?id=1556763

jdm commented 5 years ago
Failed to link shader program: cs_border_solid
C:\fakepath(606,1-4): error X3004: undeclared identifier 's849'

Failing shader:

``` /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include shared,ellipse #define DONT_MIX 0 #define MIX_AA 1 #define MIX_NO_AA 2 // For edges, the colors are the same. For corners, these // are the colors of each edge making up the corner. flat varying vec4 vColor0; flat varying vec4 vColor1; // A point + tangent defining the line where the edge // transition occurs. Used for corners only. flat varying vec4 vColorLine; // A boolean indicating that we should be mixing between edge colors. flat varying int vMixColors; // xy = Local space position of the clip center. // zw = Scale the rect origin by this to get the outer // corner from the segment rectangle. flat varying vec4 vClipCenter_Sign; // An outer and inner elliptical radii for border // corner clipping. flat varying vec4 vClipRadii; // Position, scale, and radii of horizontally and vertically adjacent corner clips. flat varying vec4 vHorizontalClipCenter_Sign; flat varying vec2 vHorizontalClipRadii; flat varying vec4 vVerticalClipCenter_Sign; flat varying vec2 vVerticalClipRadii; // Local space position varying vec2 vPos; #define SEGMENT_TOP_LEFT 0 #define SEGMENT_TOP_RIGHT 1 #define SEGMENT_BOTTOM_RIGHT 2 #define SEGMENT_BOTTOM_LEFT 3 #ifdef WR_VERTEX_SHADER in vec2 aTaskOrigin; in vec4 aRect; in vec4 aColor0; in vec4 aColor1; in int aFlags; in vec2 aWidths; in vec2 aRadii; in vec4 aHorizontallyAdjacentCorner; in vec4 aVerticallyAdjacentCorner; vec2 get_outer_corner_scale(int segment) { vec2 p; switch (segment) { case SEGMENT_TOP_LEFT: p = vec2(0.0, 0.0); break; case SEGMENT_TOP_RIGHT: p = vec2(1.0, 0.0); break; case SEGMENT_BOTTOM_RIGHT: p = vec2(1.0, 1.0); break; case SEGMENT_BOTTOM_LEFT: p = vec2(0.0, 1.0); break; default: // The result is only used for non-default segment cases p = vec2(0.0); break; } return p; } void main(void) { int segment = aFlags & 0xff; bool do_aa = ((aFlags >> 24) & 0xf0) != 0; vec2 outer_scale = get_outer_corner_scale(segment); vec2 outer = outer_scale * aRect.zw; vec2 clip_sign = 1.0 - 2.0 * outer_scale; int mix_colors; switch (segment) { case SEGMENT_TOP_LEFT: case SEGMENT_TOP_RIGHT: case SEGMENT_BOTTOM_RIGHT: case SEGMENT_BOTTOM_LEFT: mix_colors = do_aa ? MIX_AA : MIX_NO_AA; break; default: mix_colors = DONT_MIX; break; } vMixColors = mix_colors; vPos = aRect.zw * aPosition.xy; vColor0 = aColor0; vColor1 = aColor1; vClipCenter_Sign = vec4(outer + clip_sign * aRadii, clip_sign); vClipRadii = vec4(aRadii, max(aRadii - aWidths, 0.0)); vColorLine = vec4(outer, aWidths.y * -clip_sign.y, aWidths.x * clip_sign.x); vec2 horizontal_clip_sign = vec2(-clip_sign.x, clip_sign.y); vHorizontalClipCenter_Sign = vec4(aHorizontallyAdjacentCorner.xy + horizontal_clip_sign * aHorizontallyAdjacentCorner.zw, horizontal_clip_sign); vHorizontalClipRadii = aHorizontallyAdjacentCorner.zw; vec2 vertical_clip_sign = vec2(clip_sign.x, -clip_sign.y); vVerticalClipCenter_Sign = vec4(aVerticallyAdjacentCorner.xy + vertical_clip_sign * aVerticallyAdjacentCorner.zw, vertical_clip_sign); vVerticalClipRadii = aVerticallyAdjacentCorner.zw; gl_Position = uTransform * vec4(aTaskOrigin + aRect.xy + vPos, 0.0, 1.0); } #endif #ifdef WR_FRAGMENT_SHADER void main(void) { float aa_range = compute_aa_range(vPos); bool do_aa = vMixColors != MIX_NO_AA; float mix_factor = 0.0; if (vMixColors != DONT_MIX) { float d_line = distance_to_line(vColorLine.xy, vColorLine.zw, vPos); if (do_aa) { mix_factor = distance_aa(aa_range, -d_line); } else { mix_factor = d_line + EPSILON >= 0. ? 1.0 : 0.0; } } // Check if inside main corner clip-region vec2 clip_relative_pos = vPos - vClipCenter_Sign.xy; bool in_clip_region = all(lessThan(vClipCenter_Sign.zw * clip_relative_pos, vec2(0.0))); float d = -1.0; if (in_clip_region) { float d_radii_a = distance_to_ellipse(clip_relative_pos, vClipRadii.xy, aa_range); float d_radii_b = distance_to_ellipse(clip_relative_pos, vClipRadii.zw, aa_range); d = max(d_radii_a, -d_radii_b); } // And again for horizontally-adjacent corner clip_relative_pos = vPos - vHorizontalClipCenter_Sign.xy; in_clip_region = all(lessThan(vHorizontalClipCenter_Sign.zw * clip_relative_pos, vec2(0.0))); if (in_clip_region) { float d_radii = distance_to_ellipse(clip_relative_pos, vHorizontalClipRadii.xy, aa_range); d = max(d_radii, d); } // And finally for vertically-adjacent corner clip_relative_pos = vPos - vVerticalClipCenter_Sign.xy; in_clip_region = all(lessThan(vVerticalClipCenter_Sign.zw * clip_relative_pos, vec2(0.0))); if (in_clip_region) { float d_radii = distance_to_ellipse(clip_relative_pos, vVerticalClipRadii.xy, aa_range); d = max(d_radii, d); } float alpha = do_aa ? distance_aa(aa_range, d) : 1.0; vec4 color = mix(vColor0, vColor1, mix_factor); oFragColor = color * alpha; } #endif ```

ANGLE output:

``` // GLSL // // #version 300 es // // cs_border_solid // #define WR_VERTEX_SHADER // #define WR_MAX_VERTEX_TEXTURE_WIDTH 1024U // /* This Source Code Form is subject to the terms of the Mozilla Public // * License, v. 2.0. If a copy of the MPL was not distributed with this // * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ // // /* This Source Code Form is subject to the terms of the Mozilla Public // * License, v. 2.0. If a copy of the MPL was not distributed with this // * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ // // #ifdef WR_FEATURE_TEXTURE_EXTERNAL // // Please check https://www.khronos.org/registry/OpenGL/extensions/OES/OES_EGL_image_external_essl3.txt // // for this extension. // #extension GL_OES_EGL_image_external_essl3 : require // #endif // // #ifdef WR_FEATURE_DUAL_SOURCE_BLENDING // #extension GL_ARB_explicit_attrib_location : require // #endif // // /* This Source Code Form is subject to the terms of the Mozilla Public // * License, v. 2.0. If a copy of the MPL was not distributed with this // * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ // // #if defined(GL_ES) // #if GL_ES == 1 // #ifdef GL_FRAGMENT_PRECISION_HIGH // precision highp sampler2DArray; // #else // precision mediump sampler2DArray; // #endif // // // Sampler default precision is lowp on mobile GPUs. // // This causes RGBA32F texture data to be clamped to 16 bit floats on some GPUs (e.g. Mali-T880). // // Define highp precision macro to allow lossless FLOAT texture sampling. // #define HIGHP_SAMPLER_FLOAT highp // // // texelFetchOffset is buggy on some Android GPUs (see issue #1694). // // Fallback to texelFetch on mobile GPUs. // #define TEXEL_FETCH(sampler, position, lod, offset) texelFetch(sampler, position + offset, lod) // #else // #define HIGHP_SAMPLER_FLOAT // #define TEXEL_FETCH(sampler, position, lod, offset) texelFetchOffset(sampler, position, lod, offset) // #endif // #else // #define HIGHP_SAMPLER_FLOAT // #define TEXEL_FETCH(sampler, position, lod, offset) texelFetchOffset(sampler, position, lod, offset) // #endif // // #ifdef WR_VERTEX_SHADER // #define varying out // #endif // // #ifdef WR_FRAGMENT_SHADER // precision highp float; // #define varying in // #endif // // #if defined(WR_FEATURE_TEXTURE_EXTERNAL) || defined(WR_FEATURE_TEXTURE_RECT) || defined(WR_FEATURE_TEXTURE_2D) // #define TEX_SAMPLE(sampler, tex_coord) texture(sampler, tex_coord.xy) // #else // #define TEX_SAMPLE(sampler, tex_coord) texture(sampler, tex_coord) // #endif // // //====================================================================================== // // Vertex shader attributes and uniforms // //====================================================================================== // #ifdef WR_VERTEX_SHADER // // A generic uniform that shaders can optionally use to configure // // an operation mode for this batch. // uniform int uMode; // // // Uniform inputs // uniform mat4 uTransform; // Orthographic projection // // // Attribute inputs // in vec3 aPosition; // // // get_fetch_uv is a macro to work around a macOS Intel driver parsing bug. // // TODO: convert back to a function once the driver issues are resolved, if ever. // // https://github.com/servo/webrender/pull/623 // // https://github.com/servo/servo/issues/13953 // // Do the division with unsigned ints because that's more efficient with D3D // #define get_fetch_uv(i, vpi) ivec2(int(vpi * (uint(i) % (WR_MAX_VERTEX_TEXTURE_WIDTH/vpi))), int(uint(i) / (WR_MAX_VERTEX_TEXTURE_WIDTH/vpi))) // #endif // // //====================================================================================== // // Fragment shader attributes and uniforms // //====================================================================================== // #ifdef WR_FRAGMENT_SHADER // // Uniform inputs // // // Fragment shader outputs // #ifdef WR_FEATURE_DUAL_SOURCE_BLENDING // layout(location = 0, index = 0) out vec4 oFragColor; // layout(location = 0, index = 1) out vec4 oFragBlend; // #else // out vec4 oFragColor; // #endif // // #define EPSILON 0.0001 // // // "Show Overdraw" color. Premultiplied. // #define WR_DEBUG_OVERDRAW_COLOR vec4(0.110, 0.077, 0.027, 0.125) // // float distance_to_line(vec2 p0, vec2 perp_dir, vec2 p) { // vec2 dir_to_p0 = p0 - p; // return dot(normalize(perp_dir), dir_to_p0); // } // // /// Find the appropriate half range to apply the AA approximation over. // /// This range represents a coefficient to go from one CSS pixel to half a device pixel. // float compute_aa_range(vec2 position) { // // The constant factor is chosen to compensate for the fact that length(fw) is equal // // to sqrt(2) times the device pixel ratio in the typical case. 0.5/sqrt(2) = 0.35355. // // // // This coefficient is chosen to ensure that any sample 0.5 pixels or more inside of // // the shape has no anti-aliasing applied to it (since pixels are sampled at their center, // // such a pixel (axis aligned) is fully inside the border). We need this so that antialiased // // curves properly connect with non-antialiased vertical or horizontal lines, among other things. // // // // Lines over a half-pixel away from the pixel center *can* intersect with the pixel square; // // indeed, unless they are horizontal or vertical, they are guaranteed to. However, choosing // // a nonzero area for such pixels causes noticeable artifacts at the junction between an anti- // // aliased corner and a straight edge. // // // // We may want to adjust this constant in specific scenarios (for example keep the principled // // value for straight edges where we want pixel-perfect equivalence with non antialiased lines // // when axis aligned, while selecting a larger and smoother aa range on curves). // return 0.35355 * length(fwidth(position)); // } // // /// Return the blending coefficient for distance antialiasing. // /// // /// 0.0 means inside the shape, 1.0 means outside. // /// // /// This cubic polynomial approximates the area of a 1x1 pixel square under a // /// line, given the signed Euclidean distance from the center of the square to // /// that line. Calculating the *exact* area would require taking into account // /// not only this distance but also the angle of the line. However, in // /// practice, this complexity is not required, as the area is roughly the same // /// regardless of the angle. // /// // /// The coefficients of this polynomial were determined through least-squares // /// regression and are accurate to within 2.16% of the total area of the pixel // /// square 95% of the time, with a maximum error of 3.53%. // /// // /// See the comments in `compute_aa_range()` for more information on the // /// cutoff values of -0.5 and 0.5. // float distance_aa(float aa_range, float signed_distance) { // float dist = 0.5 * signed_distance / aa_range; // if (dist <= -0.5 + EPSILON) // return 1.0; // if (dist >= 0.5 - EPSILON) // return 0.0; // return 0.5 + dist * (0.8431027 * dist * dist - 1.14453603); // } // // /// Component-wise selection. // /// // /// The idea of using this is to ensure both potential branches are executed before // /// selecting the result, to avoid observable timing differences based on the condition. // /// // /// Example usage: color = if_then_else(LessThanEqual(color, vec3(0.5)), vec3(0.0), vec3(1.0)); // /// // /// The above example sets each component to 0.0 or 1.0 independently depending on whether // /// their values are below or above 0.5. // /// // /// This is written as a macro in order to work with vectors of any dimension. // /// // /// Note: Some older android devices don't support mix with bvec. If we ever run into them // /// the only option we have is to polyfill it with a branch per component. // #define if_then_else(cond, then_branch, else_branch) mix(else_branch, then_branch, cond) // #endif // // //====================================================================================== // // Shared shader uniforms // //====================================================================================== // #ifdef WR_FEATURE_TEXTURE_2D // uniform sampler2D sColor0; // uniform sampler2D sColor1; // uniform sampler2D sColor2; // #elif defined WR_FEATURE_TEXTURE_RECT // uniform sampler2DRect sColor0; // uniform sampler2DRect sColor1; // uniform sampler2DRect sColor2; // #elif defined WR_FEATURE_TEXTURE_EXTERNAL // uniform samplerExternalOES sColor0; // uniform samplerExternalOES sColor1; // uniform samplerExternalOES sColor2; // #else // uniform sampler2DArray sColor0; // uniform sampler2DArray sColor1; // uniform sampler2DArray sColor2; // #endif // // #ifdef WR_FEATURE_DITHERING // uniform sampler2D sDither; // #endif // // //====================================================================================== // // Interpolator definitions // //====================================================================================== // // //====================================================================================== // // VS only types and UBOs // //====================================================================================== // // //====================================================================================== // // VS only functions // //====================================================================================== // /* This Source Code Form is subject to the terms of the Mozilla Public // * License, v. 2.0. If a copy of the MPL was not distributed with this // * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ // // #ifdef WR_FRAGMENT_SHADER // // // One iteration of Newton's method on the 2D equation of an ellipse: // // // // E(x, y) = x^2/a^2 + y^2/b^2 - 1 // // // // The Jacobian of this equation is: // // // // J(E(x, y)) = [ 2*x/a^2 2*y/b^2 ] // // // // We approximate the distance with: // // // // E(x, y) / ||J(E(x, y))|| // // // // See G. Taubin, "Distance Approximations for Rasterizing Implicit // // Curves", section 3. // float distance_to_ellipse(vec2 p, vec2 radii, float aa_range) { // float dist; // if (any(lessThanEqual(radii, vec2(0.0)))) { // dist = length(p); // } else { // vec2 invRadiiSq = 1.0 / (radii * radii); // float g = dot(p * p * invRadiiSq, vec2(1.0)) - 1.0; // vec2 dG = 2.0 * p * invRadiiSq; // dist = g * inversesqrt(dot(dG, dG)); // } // return clamp(dist, -aa_range, aa_range); // } // // float clip_against_ellipse_if_needed( // vec2 pos, // float current_distance, // vec4 ellipse_center_radius, // vec2 sign_modifier, // float aa_range // ) { // if (!all(lessThan(sign_modifier * pos, sign_modifier * ellipse_center_radius.xy))) { // return current_distance; // } // // float distance = distance_to_ellipse(pos - ellipse_center_radius.xy, // ellipse_center_radius.zw, // aa_range); // // return max(distance, current_distance); // } // // float rounded_rect(vec2 pos, // vec4 clip_center_radius_tl, // vec4 clip_center_radius_tr, // vec4 clip_center_radius_br, // vec4 clip_center_radius_bl, // float aa_range) { // // Start with a negative value (means "inside") for all fragments that are not // // in a corner. If the fragment is in a corner, one of the clip_against_ellipse_if_needed // // calls below will update it. // float current_distance = -aa_range; // // // Clip against each ellipse. // current_distance = clip_against_ellipse_if_needed(pos, // current_distance, // clip_center_radius_tl, // vec2(1.0), // aa_range); // // current_distance = clip_against_ellipse_if_needed(pos, // current_distance, // clip_center_radius_tr, // vec2(-1.0, 1.0), // aa_range); // // current_distance = clip_against_ellipse_if_needed(pos, // current_distance, // clip_center_radius_br, // vec2(-1.0), // aa_range); // // current_distance = clip_against_ellipse_if_needed(pos, // current_distance, // clip_center_radius_bl, // vec2(1.0, -1.0), // aa_range); // // // Apply AA // // See comment in ps_border_corner about the choice of constants. // // return distance_aa(aa_range, current_distance); // } // #endif // // #define DONT_MIX 0 // #define MIX_AA 1 // #define MIX_NO_AA 2 // // // For edges, the colors are the same. For corners, these // // are the colors of each edge making up the corner. // flat varying vec4 vColor0; // flat varying vec4 vColor1; // // // A point + tangent defining the line where the edge // // transition occurs. Used for corners only. // flat varying vec4 vColorLine; // // // A boolean indicating that we should be mixing between edge colors. // flat varying int vMixColors; // // // xy = Local space position of the clip center. // // zw = Scale the rect origin by this to get the outer // // corner from the segment rectangle. // flat varying vec4 vClipCenter_Sign; // // // An outer and inner elliptical radii for border // // corner clipping. // flat varying vec4 vClipRadii; // // // Position, scale, and radii of horizontally and vertically adjacent corner clips. // flat varying vec4 vHorizontalClipCenter_Sign; // flat varying vec2 vHorizontalClipRadii; // flat varying vec4 vVerticalClipCenter_Sign; // flat varying vec2 vVerticalClipRadii; // // // Local space position // varying vec2 vPos; // // #define SEGMENT_TOP_LEFT 0 // #define SEGMENT_TOP_RIGHT 1 // #define SEGMENT_BOTTOM_RIGHT 2 // #define SEGMENT_BOTTOM_LEFT 3 // // #ifdef WR_VERTEX_SHADER // // in vec2 aTaskOrigin; // in vec4 aRect; // in vec4 aColor0; // in vec4 aColor1; // in int aFlags; // in vec2 aWidths; // in vec2 aRadii; // in vec4 aHorizontallyAdjacentCorner; // in vec4 aVerticallyAdjacentCorner; // // vec2 get_outer_corner_scale(int segment) { // vec2 p; // // switch (segment) { // case SEGMENT_TOP_LEFT: // p = vec2(0.0, 0.0); // break; // case SEGMENT_TOP_RIGHT: // p = vec2(1.0, 0.0); // break; // case SEGMENT_BOTTOM_RIGHT: // p = vec2(1.0, 1.0); // break; // case SEGMENT_BOTTOM_LEFT: // p = vec2(0.0, 1.0); // break; // default: // // The result is only used for non-default segment cases // p = vec2(0.0); // break; // } // // return p; // } // // void main(void) { // int segment = aFlags & 0xff; // bool do_aa = ((aFlags >> 24) & 0xf0) != 0; // // vec2 outer_scale = get_outer_corner_scale(segment); // vec2 outer = outer_scale * aRect.zw; // vec2 clip_sign = 1.0 - 2.0 * outer_scale; // // int mix_colors; // switch (segment) { // case SEGMENT_TOP_LEFT: // case SEGMENT_TOP_RIGHT: // case SEGMENT_BOTTOM_RIGHT: // case SEGMENT_BOTTOM_LEFT: // mix_colors = do_aa ? MIX_AA : MIX_NO_AA; // break; // default: // mix_colors = DONT_MIX; // break; // } // // vMixColors = mix_colors; // vPos = aRect.zw * aPosition.xy; // // vColor0 = aColor0; // vColor1 = aColor1; // vClipCenter_Sign = vec4(outer + clip_sign * aRadii, clip_sign); // vClipRadii = vec4(aRadii, max(aRadii - aWidths, 0.0)); // vColorLine = vec4(outer, aWidths.y * -clip_sign.y, aWidths.x * clip_sign.x); // // vec2 horizontal_clip_sign = vec2(-clip_sign.x, clip_sign.y); // vHorizontalClipCenter_Sign = vec4(aHorizontallyAdjacentCorner.xy + // horizontal_clip_sign * aHorizontallyAdjacentCorner.zw, // horizontal_clip_sign); // vHorizontalClipRadii = aHorizontallyAdjacentCorner.zw; // // vec2 vertical_clip_sign = vec2(clip_sign.x, -clip_sign.y); // vVerticalClipCenter_Sign = vec4(aVerticallyAdjacentCorner.xy + // vertical_clip_sign * aVerticallyAdjacentCorner.zw, // vertical_clip_sign); // vVerticalClipRadii = aVerticallyAdjacentCorner.zw; // // gl_Position = uTransform * vec4(aTaskOrigin + aRect.xy + vPos, 0.0, 1.0); // } // #endif // // #ifdef WR_FRAGMENT_SHADER // void main(void) { // float aa_range = compute_aa_range(vPos); // bool do_aa = vMixColors != MIX_NO_AA; // // float mix_factor = 0.0; // if (vMixColors != DONT_MIX) { // float d_line = distance_to_line(vColorLine.xy, vColorLine.zw, vPos); // if (do_aa) { // mix_factor = distance_aa(aa_range, -d_line); // } else { // mix_factor = d_line + EPSILON >= 0. ? 1.0 : 0.0; // } // } // // // Check if inside main corner clip-region // vec2 clip_relative_pos = vPos - vClipCenter_Sign.xy; // bool in_clip_region = all(lessThan(vClipCenter_Sign.zw * clip_relative_pos, vec2(0.0))); // // float d = -1.0; // if (in_clip_region) { // float d_radii_a = distance_to_ellipse(clip_relative_pos, vClipRadii.xy, aa_range); // float d_radii_b = distance_to_ellipse(clip_relative_pos, vClipRadii.zw, aa_range); // d = max(d_radii_a, -d_radii_b); // } // // // And again for horizontally-adjacent corner // clip_relative_pos = vPos - vHorizontalClipCenter_Sign.xy; // in_clip_region = all(lessThan(vHorizontalClipCenter_Sign.zw * clip_relative_pos, vec2(0.0))); // if (in_clip_region) { // float d_radii = distance_to_ellipse(clip_relative_pos, vHorizontalClipRadii.xy, aa_range); // d = max(d_radii, d); // } // // // And finally for vertically-adjacent corner // clip_relative_pos = vPos - vVerticalClipCenter_Sign.xy; // in_clip_region = all(lessThan(vVerticalClipCenter_Sign.zw * clip_relative_pos, vec2(0.0))); // if (in_clip_region) { // float d_radii = distance_to_ellipse(clip_relative_pos, vVerticalClipRadii.xy, aa_range); // d = max(d_radii, d); // } // // float alpha = do_aa ? distance_aa(aa_range, d) : 1.0; // vec4 color = mix(vColor0, vColor1, mix_factor); // oFragColor = color * alpha; // } // #endif float2 vec2(float x0, float x1) { return float2(x0, x1); } float4 vec4(float2 x0, float x1, float x2) { return float4(x0, x1, x2); } float4 vec4(float2 x0, float2 x1) { return float4(x0, x1); } // Uniforms uniform float4x4 _uTransform : register(c0); #ifdef ANGLE_ENABLE_LOOP_FLATTEN #define LOOP [loop] #define FLATTEN [flatten] #else #define LOOP #define FLATTEN #endif // Attributes static float4 _aColor0 = {0, 0, 0, 0}; static float4 _aColor1 = {0, 0, 0, 0}; static int _aFlags = {0}; static float4 _aHorizontallyAdjacentCorner = {0, 0, 0, 0}; static float3 _aPosition = {0, 0, 0}; static float2 _aRadii = {0, 0}; static float4 _aRect = {0, 0, 0, 0}; static float2 _aTaskOrigin = {0, 0}; static float4 _aVerticallyAdjacentCorner = {0, 0, 0, 0}; static float2 _aWidths = {0, 0}; static float4 gl_Position = float4(0, 0, 0, 0); // Varyings static nointerpolation float4 _vClipCenter_Sign = {0, 0, 0, 0}; static nointerpolation float4 _vClipRadii = {0, 0, 0, 0}; static nointerpolation float4 _vColor0 = {0, 0, 0, 0}; static nointerpolation float4 _vColor1 = {0, 0, 0, 0}; static nointerpolation float4 _vColorLine = {0, 0, 0, 0}; static nointerpolation float4 _vHorizontalClipCenter_Sign = {0, 0, 0, 0}; static nointerpolation float2 _vHorizontalClipRadii = {0, 0}; static nointerpolation int _vMixColors = {0}; static float2 _vPos = {0, 0}; static nointerpolation float4 _vVerticalClipCenter_Sign = {0, 0, 0, 0}; static nointerpolation float2 _vVerticalClipRadii = {0, 0}; cbuffer DriverConstants : register(b1) { float4 dx_ViewAdjust : packoffset(c1); float2 dx_ViewCoords : packoffset(c2); float2 dx_ViewScale : packoffset(c3); }; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; float2 f_get_outer_corner_scale(in int _segment) { float2 _p = {0, 0}; switch (_segment) { case (0): (_p = float2(0.0, 0.0)); break; ; case (1): (_p = float2(1.0, 0.0)); break; ; case (2): (_p = float2(1.0, 1.0)); break; ; case (3): (_p = float2(0.0, 1.0)); break; ; default: (_p = float2(0.0, 0.0)); break; ; } ; return _p; ; } ; void gl_main() { int _segment = (_aFlags & 255); bool _do_aa = (((_aFlags >> 24) & 240) != 0); float2 _outer_scale = f_get_outer_corner_scale(_segment); float2 _outer = (_outer_scale * _aRect.zw); float2 _clip_sign = (1.0 - (2.0 * _outer_scale)); int _mix_colors = {0}; switch (_segment) { case (0): case (1): case (2): case (3): s849; if (_do_aa) { (s849 = 1); } else { (s849 = 2); } (_mix_colors = s849); break; ; default: (_mix_colors = 0); break; ; } ; (_vMixColors = _mix_colors); (_vPos = (_aRect.zw * _aPosition.xy)); (_vColor0 = _aColor0); (_vColor1 = _aColor1); (_vClipCenter_Sign = vec4((_outer + (_clip_sign * _aRadii)), _clip_sign)); (_vClipRadii = vec4(_aRadii, max((_aRadii - _aWidths), 0.0))); (_vColorLine = vec4(_outer, (_aWidths.y * (-_clip_sign.y)), (_aWidths.x * _clip_sign.x))); float2 _horizontal_clip_sign = vec2((-_clip_sign.x), _clip_sign.y); (_vHorizontalClipCenter_Sign = vec4((_aHorizontallyAdjacentCorner.xy + (_horizontal_clip_sign * _aHorizontallyAdjacentCorner.zw)), _horizontal_clip_sign)); (_vHorizontalClipRadii = _aHorizontallyAdjacentCorner.zw); float2 _vertical_clip_sign = vec2(_clip_sign.x, (-_clip_sign.y)); (_vVerticalClipCenter_Sign = vec4((_aVerticallyAdjacentCorner.xy + (_vertical_clip_sign * _aVerticallyAdjacentCorner.zw)), _vertical_clip_sign)); (_vVerticalClipRadii = _aVerticallyAdjacentCorner.zw); (gl_Position = mul(transpose(_uTransform), vec4(((_aTaskOrigin + _aRect.xy) + _vPos), 0.0, 1.0))); } ; struct VS_INPUT { float3 _aPosition : TEXCOORD0; float2 _aTaskOrigin : TEXCOORD1; float4 _aRect : TEXCOORD2; float4 _aColor0 : TEXCOORD3; float4 _aColor1 : TEXCOORD4; int _aFlags : TEXCOORD5; float2 _aWidths : TEXCOORD6; float2 _aRadii : TEXCOORD7; float4 _aHorizontallyAdjacentCorner : TEXCOORD8; float4 _aVerticallyAdjacentCorner : TEXCOORD9; }; void initAttributes(VS_INPUT input) { _aPosition = input._aPosition; _aTaskOrigin = input._aTaskOrigin; _aRect = input._aRect; _aColor0 = input._aColor0; _aColor1 = input._aColor1; _aFlags = input._aFlags; _aWidths = input._aWidths; _aRadii = input._aRadii; _aHorizontallyAdjacentCorner = input._aHorizontallyAdjacentCorner; _aVerticallyAdjacentCorner = input._aVerticallyAdjacentCorner; } struct VS_OUTPUT { float4 dx_Position : SV_Position; float4 gl_Position : TEXCOORD11; nointerpolation float4 v0 : TEXCOORD0; nointerpolation float4 v1 : TEXCOORD1; nointerpolation float4 v2 : TEXCOORD2; nointerpolation float4 v3 : TEXCOORD3; nointerpolation float4 v4 : TEXCOORD4; nointerpolation float4 v5 : TEXCOORD5; nointerpolation float4 v6 : TEXCOORD6; nointerpolation float2 v7 : TEXCOORD7; float2 v8 : TEXCOORD8; nointerpolation float2 v9 : TEXCOORD9; nointerpolation int v10 : TEXCOORD10; }; VS_OUTPUT main(VS_INPUT input) { initAttributes(input); gl_main(); VS_OUTPUT output; output.gl_Position = gl_Position; output.dx_Position.x = gl_Position.x; output.dx_Position.y = - gl_Position.y; output.dx_Position.z = (gl_Position.z + gl_Position.w) * 0.5; output.dx_Position.w = gl_Position.w; output.v0 = _vClipCenter_Sign; output.v1 = _vClipRadii; output.v2 = _vColor0; output.v3 = _vColor1; output.v4 = _vColorLine; output.v5 = _vHorizontalClipCenter_Sign; output.v6 = _vVerticalClipCenter_Sign; output.v7 = _vHorizontalClipRadii; output.v8 = _vPos; output.v9 = _vVerticalClipRadii; output.v10 = _vMixColors; return output; } ```
jdm commented 5 years ago

I fixed the shader problem by avoiding the ? construct and using an explicit if/else instead.

kvark commented 5 years ago

Great find @jdm ! Apparently we already faced this problem before - https://github.com/servo/webrender/wiki/Driver-issues#1285---declarations-in-switch-cases

Too bad we don't have any tooling to check for those cases on CI.