From e9fd5d6b1bb0a2726517e462555432828b13706c Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Tue, 7 Feb 2017 14:39:36 -0800 Subject: [PATCH] Work around driver bugs on Apple Radeon GPUs --- resources/shaders/draw.tcs.glsl | 14 +++++++++++--- resources/shaders/draw.tes.glsl | 16 ++++++++++++---- 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/resources/shaders/draw.tcs.glsl b/resources/shaders/draw.tcs.glsl index 8db463e2..1ddf1023 100644 --- a/resources/shaders/draw.tcs.glsl +++ b/resources/shaders/draw.tcs.glsl @@ -24,8 +24,16 @@ patch out vec2 vpP0; patch out vec2 vpP1; // The endpoint of this segment. patch out vec2 vpP2; -// 1.0 if this segment runs left to right; -1.0 otherwise. -patch out float vpDirection; +// x: 1.0 if this segment runs left to right; -1.0 otherwise. +// y: The tessellation level. +// +// This is packed together into a single vec2 to work around an Apple Intel driver bug whereby +// patch outputs beyond the first 4 are forced to 0. +// +// And in case you're wondering why the tessellation level is passed along in a patch out instead +// of having the TES read it directly, that's another Apple bug workaround, this time in the Radeon +// driver. +patch out vec2 vpDirectionTessLevel; void main() { vec2 p0 = gl_in[0].gl_Position.xy; @@ -111,6 +119,6 @@ void main() { vpP0 = p0; vpP1 = p1; vpP2 = p2; - vpDirection = direction; + vpDirectionTessLevel = vec2(direction, tessLevel); } diff --git a/resources/shaders/draw.tes.glsl b/resources/shaders/draw.tes.glsl index b6e6481a..8bef98f7 100644 --- a/resources/shaders/draw.tes.glsl +++ b/resources/shaders/draw.tes.glsl @@ -21,8 +21,16 @@ patch in vec2 vpP0; patch in vec2 vpP1; // The endpoint of this segment. patch in vec2 vpP2; -// 1.0 if this segment runs left to right; -1.0 otherwise. -patch in float vpDirection; +// x: 1.0 if this segment runs left to right; -1.0 otherwise. +// y: The tessellation level. +// +// This is packed together into a single vec2 to work around an Apple Intel driver bug whereby +// patch outputs beyond the first 4 are forced to 0. +// +// And in case you're wondering why the tessellation level is passed along in a patch out instead +// of having the TES read it directly, that's another Apple bug workaround, this time in the Radeon +// driver. +patch in vec2 vpDirectionTessLevel; // The starting point of the segment. flat out vec2 vP0; @@ -38,7 +46,7 @@ flat out vec2 vYMinMax; void main() { // Work out how many lines made up this segment, which line we're working on, and which // endpoint of that line we're looking at. - uint tessPointCount = uint(gl_TessLevelInner[0] + 1.0f); + uint tessPointCount = uint(vpDirectionTessLevel.y + 1.0f); uint tessIndex = uint(round(gl_TessCoord.x * float(tessPointCount - 1))); uint lineCount = tessPointCount / 2, lineIndex = tessIndex / 2, endpoint = tessIndex % 2; @@ -59,7 +67,7 @@ void main() { vSlope = (vP1.y - vP0.y) / (vP1.x - vP0.x); // Forward direction onto the fragment shader. - vDirection = vpDirection; + vDirection = vpDirectionTessLevel.x; // Compute our final position in atlas space, rounded out to the next pixel. float x = endpoint == 0 ? floor(vP0.x) : ceil(vP1.x);