Add GLSL workaround for 4x2 diagonal matrix bug.
GLSL now emits 4x2 diagonal matrices as: `(mat4x2(1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0) * n)` instead of `mat4x2(n)`. This works around a long-standing GLSL bug in both Mesa and glslang that affects several drivers: https://github.com/KhronosGroup/glslang/issues/2645 Change-Id: If529d5cd150ce720f436cb3634a2fd3423919278 Bug: skia:12003 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/410137 Auto-Submit: John Stiles <johnstiles@google.com> Commit-Queue: Brian Osman <brianosman@google.com> Reviewed-by: Brian Osman <brianosman@google.com>
This commit is contained in:
parent
a5569ac9c4
commit
3c74a5357a
@ -18,11 +18,10 @@ bool test_float() {
|
||||
0, 5, 0, 0,
|
||||
0, 0, 5, 0));
|
||||
float4x2 m42 = float4x2(6);
|
||||
// Some Intel and Radeon GLSL drivers don't assemble the mat4x2 properly. (skia:12003)
|
||||
// ok = ok && (m42 == float4x2(6, 0,
|
||||
// 0, 6,
|
||||
// 0, 0,
|
||||
// 0, 0));
|
||||
ok = ok && (m42 == float4x2(6, 0,
|
||||
0, 6,
|
||||
0, 0,
|
||||
0, 0));
|
||||
float4x3 m43 = float4x3(7);
|
||||
ok = ok && (m43 == float4x3(7, 0, 0,
|
||||
0, 7, 0,
|
||||
@ -65,11 +64,10 @@ bool test_half() {
|
||||
0, 5, 0, 0,
|
||||
0, 0, 5, 0));
|
||||
half4x2 m42 = half4x2(6);
|
||||
// Some Intel and Radeon GLSL drivers don't assemble the mat4x2 properly. (skia:12003)
|
||||
// ok = ok && (m42 == half4x2(6, 0,
|
||||
// 0, 6,
|
||||
// 0, 0,
|
||||
// 0, 0));
|
||||
ok = ok && (m42 == half4x2(6, 0,
|
||||
0, 6,
|
||||
0, 0,
|
||||
0, 0));
|
||||
half4x3 m43 = half4x3(7);
|
||||
ok = ok && (m43 == half4x3(7, 0, 0,
|
||||
0, 7, 0,
|
||||
|
@ -190,9 +190,12 @@ void GLSLCodeGenerator::writeExpression(const Expression& expr, Precedence paren
|
||||
case Expression::Kind::kBoolLiteral:
|
||||
this->writeBoolLiteral(expr.as<BoolLiteral>());
|
||||
break;
|
||||
case Expression::Kind::kConstructorDiagonalMatrix:
|
||||
this->writeConstructorDiagonalMatrix(expr.as<ConstructorDiagonalMatrix>(),
|
||||
parentPrecedence);
|
||||
break;
|
||||
case Expression::Kind::kConstructorArray:
|
||||
case Expression::Kind::kConstructorCompound:
|
||||
case Expression::Kind::kConstructorDiagonalMatrix:
|
||||
case Expression::Kind::kConstructorMatrixResize:
|
||||
case Expression::Kind::kConstructorSplat:
|
||||
case Expression::Kind::kConstructorStruct:
|
||||
@ -688,6 +691,24 @@ void GLSLCodeGenerator::writeFunctionCall(const FunctionCall& c) {
|
||||
this->write(")");
|
||||
}
|
||||
|
||||
void GLSLCodeGenerator::writeConstructorDiagonalMatrix(const ConstructorDiagonalMatrix& c,
|
||||
Precedence parentPrecedence) {
|
||||
if (c.type().columns() == 4 && c.type().rows() == 2) {
|
||||
// Due to a longstanding bug in glslang and Mesa, several GPU drivers generate diagonal 4x2
|
||||
// matrices incorrectly. (skia:12003, https://github.com/KhronosGroup/glslang/pull/2646)
|
||||
// We can work around this issue by multiplying a scalar by the identity matrix.
|
||||
// In practice, this doesn't come up naturally in real code and we don't know every affected
|
||||
// driver, so we just apply this workaround everywhere.
|
||||
this->write("(");
|
||||
this->writeType(c.type());
|
||||
this->write("(1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0) * ");
|
||||
this->writeExpression(*c.argument(), Precedence::kMultiplicative);
|
||||
this->write(")");
|
||||
return;
|
||||
}
|
||||
this->writeAnyConstructor(c, parentPrecedence);
|
||||
}
|
||||
|
||||
void GLSLCodeGenerator::writeCastConstructor(const AnyConstructor& c, Precedence parentPrecedence) {
|
||||
const auto arguments = c.argumentSpan();
|
||||
SkASSERT(arguments.size() == 1);
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "src/sksl/ir/SkSLBinaryExpression.h"
|
||||
#include "src/sksl/ir/SkSLBoolLiteral.h"
|
||||
#include "src/sksl/ir/SkSLConstructor.h"
|
||||
#include "src/sksl/ir/SkSLConstructorDiagonalMatrix.h"
|
||||
#include "src/sksl/ir/SkSLConstructorScalarCast.h"
|
||||
#include "src/sksl/ir/SkSLDoStatement.h"
|
||||
#include "src/sksl/ir/SkSLExtension.h"
|
||||
@ -135,6 +136,9 @@ protected:
|
||||
|
||||
virtual void writeFunctionCall(const FunctionCall& c);
|
||||
|
||||
void writeConstructorDiagonalMatrix(const ConstructorDiagonalMatrix& c,
|
||||
Precedence parentPrecedence);
|
||||
|
||||
virtual void writeAnyConstructor(const AnyConstructor& c, Precedence parentPrecedence);
|
||||
|
||||
virtual void writeCastConstructor(const AnyConstructor& c, Precedence parentPrecedence);
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -12,6 +12,8 @@ bool test_half_b() {
|
||||
ok = ok && m32 == mat3x2(4.0, 0.0, 0.0, 4.0, 0.0, 0.0);
|
||||
mat3x4 m34 = mat3x4(5.0);
|
||||
ok = ok && m34 == mat3x4(5.0, 0.0, 0.0, 0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 5.0, 0.0);
|
||||
mat4x2 m42 = (mat4x2(1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0) * 6.0);
|
||||
ok = ok && m42 == mat4x2(6.0, 0.0, 0.0, 6.0, 0.0, 0.0, 0.0, 0.0);
|
||||
mat4x3 m43 = mat4x3(7.0);
|
||||
ok = ok && m43 == mat4x3(7.0, 0.0, 0.0, 0.0, 7.0, 0.0, 0.0, 0.0, 7.0, 0.0, 0.0, 0.0);
|
||||
mat2 m22 = m32 * m23;
|
||||
@ -36,6 +38,8 @@ vec4 main() {
|
||||
_0_ok = _0_ok && _3_m32 == mat3x2(4.0, 0.0, 0.0, 4.0, 0.0, 0.0);
|
||||
mat3x4 _4_m34 = mat3x4(5.0);
|
||||
_0_ok = _0_ok && _4_m34 == mat3x4(5.0, 0.0, 0.0, 0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 5.0, 0.0);
|
||||
mat4x2 _5_m42 = (mat4x2(1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0) * 6.0);
|
||||
_0_ok = _0_ok && _5_m42 == mat4x2(6.0, 0.0, 0.0, 6.0, 0.0, 0.0, 0.0, 0.0);
|
||||
mat4x3 _6_m43 = mat4x3(7.0);
|
||||
_0_ok = _0_ok && _6_m43 == mat4x3(7.0, 0.0, 0.0, 0.0, 7.0, 0.0, 0.0, 0.0, 7.0, 0.0, 0.0, 0.0);
|
||||
mat2 _7_m22 = _3_m32 * _1_m23;
|
||||
|
@ -40,6 +40,15 @@ thread bool operator==(const float3x4 left, const float3x4 right) {
|
||||
thread bool operator!=(const float3x4 left, const float3x4 right) {
|
||||
return !(left == right);
|
||||
}
|
||||
thread bool operator==(const float4x2 left, const float4x2 right) {
|
||||
return all(left[0] == right[0]) &&
|
||||
all(left[1] == right[1]) &&
|
||||
all(left[2] == right[2]) &&
|
||||
all(left[3] == right[3]);
|
||||
}
|
||||
thread bool operator!=(const float4x2 left, const float4x2 right) {
|
||||
return !(left == right);
|
||||
}
|
||||
thread bool operator==(const float4x3 left, const float4x3 right) {
|
||||
return all(left[0] == right[0]) &&
|
||||
all(left[1] == right[1]) &&
|
||||
@ -81,6 +90,8 @@ bool test_half_b() {
|
||||
ok = ok && m32 == float3x2(float2(4.0, 0.0), float2(0.0, 4.0), float2(0.0, 0.0));
|
||||
float3x4 m34 = float3x4(5.0);
|
||||
ok = ok && m34 == float3x4(float4(5.0, 0.0, 0.0, 0.0), float4(0.0, 5.0, 0.0, 0.0), float4(0.0, 0.0, 5.0, 0.0));
|
||||
float4x2 m42 = float4x2(6.0);
|
||||
ok = ok && m42 == float4x2(float2(6.0, 0.0), float2(0.0, 6.0), float2(0.0, 0.0), float2(0.0, 0.0));
|
||||
float4x3 m43 = float4x3(7.0);
|
||||
ok = ok && m43 == float4x3(float3(7.0, 0.0, 0.0), float3(0.0, 7.0, 0.0), float3(0.0, 0.0, 7.0), float3(0.0, 0.0, 0.0));
|
||||
float2x2 m22 = m32 * m23;
|
||||
@ -107,6 +118,8 @@ fragment Outputs fragmentMain(Inputs _in [[stage_in]], constant Uniforms& _unifo
|
||||
_0_ok = _0_ok && _3_m32 == float3x2(float2(4.0, 0.0), float2(0.0, 4.0), float2(0.0, 0.0));
|
||||
float3x4 _4_m34 = float3x4(5.0);
|
||||
_0_ok = _0_ok && _4_m34 == float3x4(float4(5.0, 0.0, 0.0, 0.0), float4(0.0, 5.0, 0.0, 0.0), float4(0.0, 0.0, 5.0, 0.0));
|
||||
float4x2 _5_m42 = float4x2(6.0);
|
||||
_0_ok = _0_ok && _5_m42 == float4x2(float2(6.0, 0.0), float2(0.0, 6.0), float2(0.0, 0.0), float2(0.0, 0.0));
|
||||
float4x3 _6_m43 = float4x3(7.0);
|
||||
_0_ok = _0_ok && _6_m43 == float4x3(float3(7.0, 0.0, 0.0), float3(0.0, 7.0, 0.0), float3(0.0, 0.0, 7.0), float3(0.0, 0.0, 0.0));
|
||||
float2x2 _7_m22 = _3_m32 * _1_m23;
|
||||
|
@ -8,11 +8,11 @@ vec4 main() {
|
||||
result += g[0].x;
|
||||
mat3 h = mat3(mat3x2(1.0));
|
||||
result += h[0].x;
|
||||
mat4 i = mat4(mat4x3(mat4x2(1.0)));
|
||||
mat4 i = mat4(mat4x3((mat4x2(1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0) * 1.0)));
|
||||
result += i[0].x;
|
||||
mat4 j = mat4(mat3x4(mat2x4(1.0)));
|
||||
result += j[0].x;
|
||||
mat2x4 k = mat2x4(mat4x2(1.0));
|
||||
mat2x4 k = mat2x4((mat4x2(1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0) * 1.0));
|
||||
result += k[0].x;
|
||||
mat4x2 l = mat4x2(mat2x4(1.0));
|
||||
result += l[0].x;
|
||||
|
Loading…
Reference in New Issue
Block a user