GLSL: Legacy matrix inverse/determinant polyfills, outerProduct()

Also refactors polyfill mechanism in GLSL and fixes transpose() lowering precision.
This commit is contained in:
rdb 2023-01-26 20:21:27 +01:00
parent 86a985f28c
commit 20981666cc
13 changed files with 557 additions and 44 deletions

View File

@ -0,0 +1,85 @@
#version 100
struct Buffer
{
mat2 m2;
mat3 m3;
mat4 m4;
mediump mat2 m2r;
mediump mat3 m3r;
mediump mat4 m4r;
};
uniform Buffer _17;
varying vec3 dets;
varying mat2 o2;
varying mat3 o3;
varying mat4 o4;
varying mat2 o2r;
varying mat3 o3r;
varying mat4 o4r;
float spvDeterminant(highp mat2 m)
{
return m[0][0] * m[1][1] - m[0][1] * m[1][0];
}
float spvDeterminant(highp mat3 m)
{
return dot(m[0], vec3(m[1][1] * m[2][2] - m[1][2] * m[2][1], m[1][2] * m[2][0] - m[1][0] * m[2][2], m[1][0] * m[2][1] - m[1][1] * m[2][0]));
}
float spvDeterminant(highp mat4 m)
{
return dot(m[0], vec4(m[2][1] * m[3][2] * m[1][3] - m[3][1] * m[2][2] * m[1][3] + m[3][1] * m[1][2] * m[2][3] - m[1][1] * m[3][2] * m[2][3] - m[2][1] * m[1][2] * m[3][3] + m[1][1] * m[2][2] * m[3][3], m[3][0] * m[2][2] * m[1][3] - m[2][0] * m[3][2] * m[1][3] - m[3][0] * m[1][2] * m[2][3] + m[1][0] * m[3][2] * m[2][3] + m[2][0] * m[1][2] * m[3][3] - m[1][0] * m[2][2] * m[3][3], m[2][0] * m[3][1] * m[1][3] - m[3][0] * m[2][1] * m[1][3] + m[3][0] * m[1][1] * m[2][3] - m[1][0] * m[3][1] * m[2][3] - m[2][0] * m[1][1] * m[3][3] + m[1][0] * m[2][1] * m[3][3], m[3][0] * m[2][1] * m[1][2] - m[2][0] * m[3][1] * m[1][2] - m[3][0] * m[1][1] * m[2][2] + m[1][0] * m[3][1] * m[2][2] + m[2][0] * m[1][1] * m[3][2] - m[1][0] * m[2][1] * m[3][2]));
}
highp mat2 spvInverse(highp mat2 m)
{
return mat2(m[1][1], -m[0][1], -m[1][0], m[0][0]) * (1.0 / (m[0][0] * m[1][1] - m[1][0] * m[0][1]));
}
highp mat3 spvInverse(highp mat3 m)
{
highp vec3 t = vec3(m[1][1] * m[2][2] - m[1][2] * m[2][1], m[1][2] * m[2][0] - m[1][0] * m[2][2], m[1][0] * m[2][1] - m[1][1] * m[2][0]);
return mat3(t[0], m[0][2] * m[2][1] - m[0][1] * m[2][2], m[0][1] * m[1][2] - m[0][2] * m[1][1], t[1], m[0][0] * m[2][2] - m[0][2] * m[2][0], m[0][2] * m[1][0] - m[0][0] * m[1][2], t[2], m[0][1] * m[2][0] - m[0][0] * m[2][1], m[0][0] * m[1][1] - m[0][1] * m[1][0]) * (1.0 / dot(m[0], t));
}
highp mat4 spvInverse(highp mat4 m)
{
highp vec4 t = vec4(m[2][1] * m[3][2] * m[1][3] - m[3][1] * m[2][2] * m[1][3] + m[3][1] * m[1][2] * m[2][3] - m[1][1] * m[3][2] * m[2][3] - m[2][1] * m[1][2] * m[3][3] + m[1][1] * m[2][2] * m[3][3], m[3][0] * m[2][2] * m[1][3] - m[2][0] * m[3][2] * m[1][3] - m[3][0] * m[1][2] * m[2][3] + m[1][0] * m[3][2] * m[2][3] + m[2][0] * m[1][2] * m[3][3] - m[1][0] * m[2][2] * m[3][3], m[2][0] * m[3][1] * m[1][3] - m[3][0] * m[2][1] * m[1][3] + m[3][0] * m[1][1] * m[2][3] - m[1][0] * m[3][1] * m[2][3] - m[2][0] * m[1][1] * m[3][3] + m[1][0] * m[2][1] * m[3][3], m[3][0] * m[2][1] * m[1][2] - m[2][0] * m[3][1] * m[1][2] - m[3][0] * m[1][1] * m[2][2] + m[1][0] * m[3][1] * m[2][2] + m[2][0] * m[1][1] * m[3][2] - m[1][0] * m[2][1] * m[3][2]);
return mat4(t[0], m[3][1] * m[2][2] * m[0][3] - m[2][1] * m[3][2] * m[0][3] - m[3][1] * m[0][2] * m[2][3] + m[0][1] * m[3][2] * m[2][3] + m[2][1] * m[0][2] * m[3][3] - m[0][1] * m[2][2] * m[3][3], m[1][1] * m[3][2] * m[0][3] - m[3][1] * m[1][2] * m[0][3] + m[3][1] * m[0][2] * m[1][3] - m[0][1] * m[3][2] * m[1][3] - m[1][1] * m[0][2] * m[3][3] + m[0][1] * m[1][2] * m[3][3], m[2][1] * m[1][2] * m[0][3] - m[1][1] * m[2][2] * m[0][3] - m[2][1] * m[0][2] * m[1][3] + m[0][1] * m[2][2] * m[1][3] + m[1][1] * m[0][2] * m[2][3] - m[0][1] * m[1][2] * m[2][3], t[1], m[2][0] * m[3][2] * m[0][3] - m[3][0] * m[2][2] * m[0][3] + m[3][0] * m[0][2] * m[2][3] - m[0][0] * m[3][2] * m[2][3] - m[2][0] * m[0][2] * m[3][3] + m[0][0] * m[2][2] * m[3][3], m[3][0] * m[1][2] * m[0][3] - m[1][0] * m[3][2] * m[0][3] - m[3][0] * m[0][2] * m[1][3] + m[0][0] * m[3][2] * m[1][3] + m[1][0] * m[0][2] * m[3][3] - m[0][0] * m[1][2] * m[3][3], m[1][0] * m[2][2] * m[0][3] - m[2][0] * m[1][2] * m[0][3] + m[2][0] * m[0][2] * m[1][3] - m[0][0] * m[2][2] * m[1][3] - m[1][0] * m[0][2] * m[2][3] + m[0][0] * m[1][2] * m[2][3], t[2], m[3][0] * m[2][1] * m[0][3] - m[2][0] * m[3][1] * m[0][3] - m[3][0] * m[0][1] * m[2][3] + m[0][0] * m[3][1] * m[2][3] + m[2][0] * m[0][1] * m[3][3] - m[0][0] * m[2][1] * m[3][3], m[1][0] * m[3][1] * m[0][3] - m[3][0] * m[1][1] * m[0][3] + m[3][0] * m[0][1] * m[1][3] - m[0][0] * m[3][1] * m[1][3] - m[1][0] * m[0][1] * m[3][3] + m[0][0] * m[1][1] * m[3][3], m[2][0] * m[1][1] * m[0][3] - m[1][0] * m[2][1] * m[0][3] - m[2][0] * m[0][1] * m[1][3] + m[0][0] * m[2][1] * m[1][3] + m[1][0] * m[0][1] * m[2][3] - m[0][0] * m[1][1] * m[2][3], t[3], m[2][0] * m[3][1] * m[0][2] - m[3][0] * m[2][1] * m[0][2] + m[3][0] * m[0][1] * m[2][2] - m[0][0] * m[3][1] * m[2][2] - m[2][0] * m[0][1] * m[3][2] + m[0][0] * m[2][1] * m[3][2], m[3][0] * m[1][1] * m[0][2] - m[1][0] * m[3][1] * m[0][2] - m[3][0] * m[0][1] * m[1][2] + m[0][0] * m[3][1] * m[1][2] + m[1][0] * m[0][1] * m[3][2] - m[0][0] * m[1][1] * m[3][2], m[1][0] * m[2][1] * m[0][2] - m[2][0] * m[1][1] * m[0][2] + m[2][0] * m[0][1] * m[1][2] - m[0][0] * m[2][1] * m[1][2] - m[1][0] * m[0][1] * m[2][2] + m[0][0] * m[1][1] * m[2][2]) * (1.0 / dot(m[0], t));
}
mediump mat2 spvInverseMP(mediump mat2 m)
{
return mat2(m[1][1], -m[0][1], -m[1][0], m[0][0]) * (1.0 / (m[0][0] * m[1][1] - m[1][0] * m[0][1]));
}
mediump mat3 spvInverseMP(mediump mat3 m)
{
mediump vec3 t = vec3(m[1][1] * m[2][2] - m[1][2] * m[2][1], m[1][2] * m[2][0] - m[1][0] * m[2][2], m[1][0] * m[2][1] - m[1][1] * m[2][0]);
return mat3(t[0], m[0][2] * m[2][1] - m[0][1] * m[2][2], m[0][1] * m[1][2] - m[0][2] * m[1][1], t[1], m[0][0] * m[2][2] - m[0][2] * m[2][0], m[0][2] * m[1][0] - m[0][0] * m[1][2], t[2], m[0][1] * m[2][0] - m[0][0] * m[2][1], m[0][0] * m[1][1] - m[0][1] * m[1][0]) * (1.0 / dot(m[0], t));
}
mediump mat4 spvInverseMP(mediump mat4 m)
{
mediump vec4 t = vec4(m[2][1] * m[3][2] * m[1][3] - m[3][1] * m[2][2] * m[1][3] + m[3][1] * m[1][2] * m[2][3] - m[1][1] * m[3][2] * m[2][3] - m[2][1] * m[1][2] * m[3][3] + m[1][1] * m[2][2] * m[3][3], m[3][0] * m[2][2] * m[1][3] - m[2][0] * m[3][2] * m[1][3] - m[3][0] * m[1][2] * m[2][3] + m[1][0] * m[3][2] * m[2][3] + m[2][0] * m[1][2] * m[3][3] - m[1][0] * m[2][2] * m[3][3], m[2][0] * m[3][1] * m[1][3] - m[3][0] * m[2][1] * m[1][3] + m[3][0] * m[1][1] * m[2][3] - m[1][0] * m[3][1] * m[2][3] - m[2][0] * m[1][1] * m[3][3] + m[1][0] * m[2][1] * m[3][3], m[3][0] * m[2][1] * m[1][2] - m[2][0] * m[3][1] * m[1][2] - m[3][0] * m[1][1] * m[2][2] + m[1][0] * m[3][1] * m[2][2] + m[2][0] * m[1][1] * m[3][2] - m[1][0] * m[2][1] * m[3][2]);
return mat4(t[0], m[3][1] * m[2][2] * m[0][3] - m[2][1] * m[3][2] * m[0][3] - m[3][1] * m[0][2] * m[2][3] + m[0][1] * m[3][2] * m[2][3] + m[2][1] * m[0][2] * m[3][3] - m[0][1] * m[2][2] * m[3][3], m[1][1] * m[3][2] * m[0][3] - m[3][1] * m[1][2] * m[0][3] + m[3][1] * m[0][2] * m[1][3] - m[0][1] * m[3][2] * m[1][3] - m[1][1] * m[0][2] * m[3][3] + m[0][1] * m[1][2] * m[3][3], m[2][1] * m[1][2] * m[0][3] - m[1][1] * m[2][2] * m[0][3] - m[2][1] * m[0][2] * m[1][3] + m[0][1] * m[2][2] * m[1][3] + m[1][1] * m[0][2] * m[2][3] - m[0][1] * m[1][2] * m[2][3], t[1], m[2][0] * m[3][2] * m[0][3] - m[3][0] * m[2][2] * m[0][3] + m[3][0] * m[0][2] * m[2][3] - m[0][0] * m[3][2] * m[2][3] - m[2][0] * m[0][2] * m[3][3] + m[0][0] * m[2][2] * m[3][3], m[3][0] * m[1][2] * m[0][3] - m[1][0] * m[3][2] * m[0][3] - m[3][0] * m[0][2] * m[1][3] + m[0][0] * m[3][2] * m[1][3] + m[1][0] * m[0][2] * m[3][3] - m[0][0] * m[1][2] * m[3][3], m[1][0] * m[2][2] * m[0][3] - m[2][0] * m[1][2] * m[0][3] + m[2][0] * m[0][2] * m[1][3] - m[0][0] * m[2][2] * m[1][3] - m[1][0] * m[0][2] * m[2][3] + m[0][0] * m[1][2] * m[2][3], t[2], m[3][0] * m[2][1] * m[0][3] - m[2][0] * m[3][1] * m[0][3] - m[3][0] * m[0][1] * m[2][3] + m[0][0] * m[3][1] * m[2][3] + m[2][0] * m[0][1] * m[3][3] - m[0][0] * m[2][1] * m[3][3], m[1][0] * m[3][1] * m[0][3] - m[3][0] * m[1][1] * m[0][3] + m[3][0] * m[0][1] * m[1][3] - m[0][0] * m[3][1] * m[1][3] - m[1][0] * m[0][1] * m[3][3] + m[0][0] * m[1][1] * m[3][3], m[2][0] * m[1][1] * m[0][3] - m[1][0] * m[2][1] * m[0][3] - m[2][0] * m[0][1] * m[1][3] + m[0][0] * m[2][1] * m[1][3] + m[1][0] * m[0][1] * m[2][3] - m[0][0] * m[1][1] * m[2][3], t[3], m[2][0] * m[3][1] * m[0][2] - m[3][0] * m[2][1] * m[0][2] + m[3][0] * m[0][1] * m[2][2] - m[0][0] * m[3][1] * m[2][2] - m[2][0] * m[0][1] * m[3][2] + m[0][0] * m[2][1] * m[3][2], m[3][0] * m[1][1] * m[0][2] - m[1][0] * m[3][1] * m[0][2] - m[3][0] * m[0][1] * m[1][2] + m[0][0] * m[3][1] * m[1][2] + m[1][0] * m[0][1] * m[3][2] - m[0][0] * m[1][1] * m[3][2], m[1][0] * m[2][1] * m[0][2] - m[2][0] * m[1][1] * m[0][2] + m[2][0] * m[0][1] * m[1][2] - m[0][0] * m[2][1] * m[1][2] - m[1][0] * m[0][1] * m[2][2] + m[0][0] * m[1][1] * m[2][2]) * (1.0 / dot(m[0], t));
}
void main()
{
dets.x = spvDeterminant(_17.m2);
dets.y = spvDeterminant(_17.m3);
dets.z = spvDeterminant(_17.m4);
o2 = spvInverse(_17.m2);
o3 = spvInverse(_17.m3);
o4 = spvInverse(_17.m4);
o2r = spvInverseMP(_17.m2r);
o3r = spvInverseMP(_17.m3r);
o4r = spvInverseMP(_17.m4r);
gl_Position = vec4(0.0);
}

View File

@ -0,0 +1,19 @@
#version 100
varying mat2 m22;
attribute vec2 v2a;
attribute vec2 v2b;
varying mat3 m33;
attribute vec3 v3a;
attribute vec3 v3b;
varying mat4 m44;
attribute vec4 v4a;
attribute vec4 v4b;
void main()
{
m22 = mat2(v2a * v2b.x, v2a * v2b.y);
m33 = mat3(v3a * v3b.x, v3a * v3b.y, v3a * v3b.z);
m44 = mat4(v4a * v4b.x, v4a * v4b.y, v4a * v4b.z, v4a * v4b.w);
}

View File

@ -5,6 +5,7 @@ struct Buffer
mat4 MVPRowMajor;
mat4 MVPColMajor;
mat4 M;
mediump mat4 MRelaxed;
};
uniform Buffer _13;
@ -14,11 +15,20 @@ varying mat4 OutputMat1;
varying mat4 OutputMat2;
varying mat4 OutputMat3;
varying mat4 OutputMat4;
varying mat4 OutputMat5;
varying mat4 OutputMat6;
varying mediump mat4 OutputMat7;
varying mediump mat4 OutputMat8;
highp mat4 spvWorkaroundRowMajor(highp mat4 wrap) { return wrap; }
mediump mat4 spvWorkaroundRowMajorMP(mediump mat4 wrap) { return wrap; }
mat4 spvTranspose(mat4 m)
highp mat4 spvTranspose(highp mat4 m)
{
return mat4(m[0][0], m[1][0], m[2][0], m[3][0], m[0][1], m[1][1], m[2][1], m[3][1], m[0][2], m[1][2], m[2][2], m[3][2], m[0][3], m[1][3], m[2][3], m[3][3]);
}
mediump mat4 spvTransposeMP(mediump mat4 m)
{
return mat4(m[0][0], m[1][0], m[2][0], m[3][0], m[0][1], m[1][1], m[2][1], m[3][1], m[0][2], m[1][2], m[2][2], m[3][2], m[0][3], m[1][3], m[2][3], m[3][3]);
}
@ -33,6 +43,12 @@ void main()
OutputMat2 = spvWorkaroundRowMajor(_13.MVPColMajor);
OutputMat3 = _55;
OutputMat4 = spvTranspose(_61);
mat4 _121 = spvWorkaroundRowMajor(_13.M);
OutputMat5 = spvTranspose(_121);
mediump mat4 _126 = spvWorkaroundRowMajor(_13.MRelaxed);
OutputMat6 = spvTransposeMP(_126);
OutputMat7 = spvTranspose(_121);
OutputMat8 = spvTransposeMP(_126);
gl_Position = (((((((((((spvWorkaroundRowMajor(_13.M) * (Position * _13.MVPRowMajor)) + (spvWorkaroundRowMajor(_13.M) * (spvWorkaroundRowMajor(_13.MVPColMajor) * Position))) + (spvWorkaroundRowMajor(_13.M) * (_13.MVPRowMajor * Position))) + (spvWorkaroundRowMajor(_13.M) * (Position * spvWorkaroundRowMajor(_13.MVPColMajor)))) + (_55 * Position)) + (Position * _61)) + (Position * _55)) + (_61 * Position)) + (Position * _80)) + (Position * _87)) + (_80 * Position)) + (_87 * Position);
}

View File

@ -0,0 +1,85 @@
#version 100
struct Buffer
{
mat2 m2;
mat3 m3;
mat4 m4;
mediump mat2 m2r;
mediump mat3 m3r;
mediump mat4 m4r;
};
uniform Buffer _17;
varying vec3 dets;
varying mat2 o2;
varying mat3 o3;
varying mat4 o4;
varying mat2 o2r;
varying mat3 o3r;
varying mat4 o4r;
float spvDeterminant(highp mat2 m)
{
return m[0][0] * m[1][1] - m[0][1] * m[1][0];
}
float spvDeterminant(highp mat3 m)
{
return dot(m[0], vec3(m[1][1] * m[2][2] - m[1][2] * m[2][1], m[1][2] * m[2][0] - m[1][0] * m[2][2], m[1][0] * m[2][1] - m[1][1] * m[2][0]));
}
float spvDeterminant(highp mat4 m)
{
return dot(m[0], vec4(m[2][1] * m[3][2] * m[1][3] - m[3][1] * m[2][2] * m[1][3] + m[3][1] * m[1][2] * m[2][3] - m[1][1] * m[3][2] * m[2][3] - m[2][1] * m[1][2] * m[3][3] + m[1][1] * m[2][2] * m[3][3], m[3][0] * m[2][2] * m[1][3] - m[2][0] * m[3][2] * m[1][3] - m[3][0] * m[1][2] * m[2][3] + m[1][0] * m[3][2] * m[2][3] + m[2][0] * m[1][2] * m[3][3] - m[1][0] * m[2][2] * m[3][3], m[2][0] * m[3][1] * m[1][3] - m[3][0] * m[2][1] * m[1][3] + m[3][0] * m[1][1] * m[2][3] - m[1][0] * m[3][1] * m[2][3] - m[2][0] * m[1][1] * m[3][3] + m[1][0] * m[2][1] * m[3][3], m[3][0] * m[2][1] * m[1][2] - m[2][0] * m[3][1] * m[1][2] - m[3][0] * m[1][1] * m[2][2] + m[1][0] * m[3][1] * m[2][2] + m[2][0] * m[1][1] * m[3][2] - m[1][0] * m[2][1] * m[3][2]));
}
highp mat2 spvInverse(highp mat2 m)
{
return mat2(m[1][1], -m[0][1], -m[1][0], m[0][0]) * (1.0 / (m[0][0] * m[1][1] - m[1][0] * m[0][1]));
}
highp mat3 spvInverse(highp mat3 m)
{
highp vec3 t = vec3(m[1][1] * m[2][2] - m[1][2] * m[2][1], m[1][2] * m[2][0] - m[1][0] * m[2][2], m[1][0] * m[2][1] - m[1][1] * m[2][0]);
return mat3(t[0], m[0][2] * m[2][1] - m[0][1] * m[2][2], m[0][1] * m[1][2] - m[0][2] * m[1][1], t[1], m[0][0] * m[2][2] - m[0][2] * m[2][0], m[0][2] * m[1][0] - m[0][0] * m[1][2], t[2], m[0][1] * m[2][0] - m[0][0] * m[2][1], m[0][0] * m[1][1] - m[0][1] * m[1][0]) * (1.0 / dot(m[0], t));
}
highp mat4 spvInverse(highp mat4 m)
{
highp vec4 t = vec4(m[2][1] * m[3][2] * m[1][3] - m[3][1] * m[2][2] * m[1][3] + m[3][1] * m[1][2] * m[2][3] - m[1][1] * m[3][2] * m[2][3] - m[2][1] * m[1][2] * m[3][3] + m[1][1] * m[2][2] * m[3][3], m[3][0] * m[2][2] * m[1][3] - m[2][0] * m[3][2] * m[1][3] - m[3][0] * m[1][2] * m[2][3] + m[1][0] * m[3][2] * m[2][3] + m[2][0] * m[1][2] * m[3][3] - m[1][0] * m[2][2] * m[3][3], m[2][0] * m[3][1] * m[1][3] - m[3][0] * m[2][1] * m[1][3] + m[3][0] * m[1][1] * m[2][3] - m[1][0] * m[3][1] * m[2][3] - m[2][0] * m[1][1] * m[3][3] + m[1][0] * m[2][1] * m[3][3], m[3][0] * m[2][1] * m[1][2] - m[2][0] * m[3][1] * m[1][2] - m[3][0] * m[1][1] * m[2][2] + m[1][0] * m[3][1] * m[2][2] + m[2][0] * m[1][1] * m[3][2] - m[1][0] * m[2][1] * m[3][2]);
return mat4(t[0], m[3][1] * m[2][2] * m[0][3] - m[2][1] * m[3][2] * m[0][3] - m[3][1] * m[0][2] * m[2][3] + m[0][1] * m[3][2] * m[2][3] + m[2][1] * m[0][2] * m[3][3] - m[0][1] * m[2][2] * m[3][3], m[1][1] * m[3][2] * m[0][3] - m[3][1] * m[1][2] * m[0][3] + m[3][1] * m[0][2] * m[1][3] - m[0][1] * m[3][2] * m[1][3] - m[1][1] * m[0][2] * m[3][3] + m[0][1] * m[1][2] * m[3][3], m[2][1] * m[1][2] * m[0][3] - m[1][1] * m[2][2] * m[0][3] - m[2][1] * m[0][2] * m[1][3] + m[0][1] * m[2][2] * m[1][3] + m[1][1] * m[0][2] * m[2][3] - m[0][1] * m[1][2] * m[2][3], t[1], m[2][0] * m[3][2] * m[0][3] - m[3][0] * m[2][2] * m[0][3] + m[3][0] * m[0][2] * m[2][3] - m[0][0] * m[3][2] * m[2][3] - m[2][0] * m[0][2] * m[3][3] + m[0][0] * m[2][2] * m[3][3], m[3][0] * m[1][2] * m[0][3] - m[1][0] * m[3][2] * m[0][3] - m[3][0] * m[0][2] * m[1][3] + m[0][0] * m[3][2] * m[1][3] + m[1][0] * m[0][2] * m[3][3] - m[0][0] * m[1][2] * m[3][3], m[1][0] * m[2][2] * m[0][3] - m[2][0] * m[1][2] * m[0][3] + m[2][0] * m[0][2] * m[1][3] - m[0][0] * m[2][2] * m[1][3] - m[1][0] * m[0][2] * m[2][3] + m[0][0] * m[1][2] * m[2][3], t[2], m[3][0] * m[2][1] * m[0][3] - m[2][0] * m[3][1] * m[0][3] - m[3][0] * m[0][1] * m[2][3] + m[0][0] * m[3][1] * m[2][3] + m[2][0] * m[0][1] * m[3][3] - m[0][0] * m[2][1] * m[3][3], m[1][0] * m[3][1] * m[0][3] - m[3][0] * m[1][1] * m[0][3] + m[3][0] * m[0][1] * m[1][3] - m[0][0] * m[3][1] * m[1][3] - m[1][0] * m[0][1] * m[3][3] + m[0][0] * m[1][1] * m[3][3], m[2][0] * m[1][1] * m[0][3] - m[1][0] * m[2][1] * m[0][3] - m[2][0] * m[0][1] * m[1][3] + m[0][0] * m[2][1] * m[1][3] + m[1][0] * m[0][1] * m[2][3] - m[0][0] * m[1][1] * m[2][3], t[3], m[2][0] * m[3][1] * m[0][2] - m[3][0] * m[2][1] * m[0][2] + m[3][0] * m[0][1] * m[2][2] - m[0][0] * m[3][1] * m[2][2] - m[2][0] * m[0][1] * m[3][2] + m[0][0] * m[2][1] * m[3][2], m[3][0] * m[1][1] * m[0][2] - m[1][0] * m[3][1] * m[0][2] - m[3][0] * m[0][1] * m[1][2] + m[0][0] * m[3][1] * m[1][2] + m[1][0] * m[0][1] * m[3][2] - m[0][0] * m[1][1] * m[3][2], m[1][0] * m[2][1] * m[0][2] - m[2][0] * m[1][1] * m[0][2] + m[2][0] * m[0][1] * m[1][2] - m[0][0] * m[2][1] * m[1][2] - m[1][0] * m[0][1] * m[2][2] + m[0][0] * m[1][1] * m[2][2]) * (1.0 / dot(m[0], t));
}
mediump mat2 spvInverseMP(mediump mat2 m)
{
return mat2(m[1][1], -m[0][1], -m[1][0], m[0][0]) * (1.0 / (m[0][0] * m[1][1] - m[1][0] * m[0][1]));
}
mediump mat3 spvInverseMP(mediump mat3 m)
{
mediump vec3 t = vec3(m[1][1] * m[2][2] - m[1][2] * m[2][1], m[1][2] * m[2][0] - m[1][0] * m[2][2], m[1][0] * m[2][1] - m[1][1] * m[2][0]);
return mat3(t[0], m[0][2] * m[2][1] - m[0][1] * m[2][2], m[0][1] * m[1][2] - m[0][2] * m[1][1], t[1], m[0][0] * m[2][2] - m[0][2] * m[2][0], m[0][2] * m[1][0] - m[0][0] * m[1][2], t[2], m[0][1] * m[2][0] - m[0][0] * m[2][1], m[0][0] * m[1][1] - m[0][1] * m[1][0]) * (1.0 / dot(m[0], t));
}
mediump mat4 spvInverseMP(mediump mat4 m)
{
mediump vec4 t = vec4(m[2][1] * m[3][2] * m[1][3] - m[3][1] * m[2][2] * m[1][3] + m[3][1] * m[1][2] * m[2][3] - m[1][1] * m[3][2] * m[2][3] - m[2][1] * m[1][2] * m[3][3] + m[1][1] * m[2][2] * m[3][3], m[3][0] * m[2][2] * m[1][3] - m[2][0] * m[3][2] * m[1][3] - m[3][0] * m[1][2] * m[2][3] + m[1][0] * m[3][2] * m[2][3] + m[2][0] * m[1][2] * m[3][3] - m[1][0] * m[2][2] * m[3][3], m[2][0] * m[3][1] * m[1][3] - m[3][0] * m[2][1] * m[1][3] + m[3][0] * m[1][1] * m[2][3] - m[1][0] * m[3][1] * m[2][3] - m[2][0] * m[1][1] * m[3][3] + m[1][0] * m[2][1] * m[3][3], m[3][0] * m[2][1] * m[1][2] - m[2][0] * m[3][1] * m[1][2] - m[3][0] * m[1][1] * m[2][2] + m[1][0] * m[3][1] * m[2][2] + m[2][0] * m[1][1] * m[3][2] - m[1][0] * m[2][1] * m[3][2]);
return mat4(t[0], m[3][1] * m[2][2] * m[0][3] - m[2][1] * m[3][2] * m[0][3] - m[3][1] * m[0][2] * m[2][3] + m[0][1] * m[3][2] * m[2][3] + m[2][1] * m[0][2] * m[3][3] - m[0][1] * m[2][2] * m[3][3], m[1][1] * m[3][2] * m[0][3] - m[3][1] * m[1][2] * m[0][3] + m[3][1] * m[0][2] * m[1][3] - m[0][1] * m[3][2] * m[1][3] - m[1][1] * m[0][2] * m[3][3] + m[0][1] * m[1][2] * m[3][3], m[2][1] * m[1][2] * m[0][3] - m[1][1] * m[2][2] * m[0][3] - m[2][1] * m[0][2] * m[1][3] + m[0][1] * m[2][2] * m[1][3] + m[1][1] * m[0][2] * m[2][3] - m[0][1] * m[1][2] * m[2][3], t[1], m[2][0] * m[3][2] * m[0][3] - m[3][0] * m[2][2] * m[0][3] + m[3][0] * m[0][2] * m[2][3] - m[0][0] * m[3][2] * m[2][3] - m[2][0] * m[0][2] * m[3][3] + m[0][0] * m[2][2] * m[3][3], m[3][0] * m[1][2] * m[0][3] - m[1][0] * m[3][2] * m[0][3] - m[3][0] * m[0][2] * m[1][3] + m[0][0] * m[3][2] * m[1][3] + m[1][0] * m[0][2] * m[3][3] - m[0][0] * m[1][2] * m[3][3], m[1][0] * m[2][2] * m[0][3] - m[2][0] * m[1][2] * m[0][3] + m[2][0] * m[0][2] * m[1][3] - m[0][0] * m[2][2] * m[1][3] - m[1][0] * m[0][2] * m[2][3] + m[0][0] * m[1][2] * m[2][3], t[2], m[3][0] * m[2][1] * m[0][3] - m[2][0] * m[3][1] * m[0][3] - m[3][0] * m[0][1] * m[2][3] + m[0][0] * m[3][1] * m[2][3] + m[2][0] * m[0][1] * m[3][3] - m[0][0] * m[2][1] * m[3][3], m[1][0] * m[3][1] * m[0][3] - m[3][0] * m[1][1] * m[0][3] + m[3][0] * m[0][1] * m[1][3] - m[0][0] * m[3][1] * m[1][3] - m[1][0] * m[0][1] * m[3][3] + m[0][0] * m[1][1] * m[3][3], m[2][0] * m[1][1] * m[0][3] - m[1][0] * m[2][1] * m[0][3] - m[2][0] * m[0][1] * m[1][3] + m[0][0] * m[2][1] * m[1][3] + m[1][0] * m[0][1] * m[2][3] - m[0][0] * m[1][1] * m[2][3], t[3], m[2][0] * m[3][1] * m[0][2] - m[3][0] * m[2][1] * m[0][2] + m[3][0] * m[0][1] * m[2][2] - m[0][0] * m[3][1] * m[2][2] - m[2][0] * m[0][1] * m[3][2] + m[0][0] * m[2][1] * m[3][2], m[3][0] * m[1][1] * m[0][2] - m[1][0] * m[3][1] * m[0][2] - m[3][0] * m[0][1] * m[1][2] + m[0][0] * m[3][1] * m[1][2] + m[1][0] * m[0][1] * m[3][2] - m[0][0] * m[1][1] * m[3][2], m[1][0] * m[2][1] * m[0][2] - m[2][0] * m[1][1] * m[0][2] + m[2][0] * m[0][1] * m[1][2] - m[0][0] * m[2][1] * m[1][2] - m[1][0] * m[0][1] * m[2][2] + m[0][0] * m[1][1] * m[2][2]) * (1.0 / dot(m[0], t));
}
void main()
{
dets.x = spvDeterminant(_17.m2);
dets.y = spvDeterminant(_17.m3);
dets.z = spvDeterminant(_17.m4);
o2 = spvInverse(_17.m2);
o3 = spvInverse(_17.m3);
o4 = spvInverse(_17.m4);
o2r = spvInverseMP(_17.m2r);
o3r = spvInverseMP(_17.m3r);
o4r = spvInverseMP(_17.m4r);
gl_Position = vec4(0.0);
}

View File

@ -0,0 +1,19 @@
#version 100
varying mat2 m22;
attribute vec2 v2a;
attribute vec2 v2b;
varying mat3 m33;
attribute vec3 v3a;
attribute vec3 v3b;
varying mat4 m44;
attribute vec4 v4a;
attribute vec4 v4b;
void main()
{
m22 = mat2(v2a * v2b.x, v2a * v2b.y);
m33 = mat3(v3a * v3b.x, v3a * v3b.y, v3a * v3b.z);
m44 = mat4(v4a * v4b.x, v4a * v4b.y, v4a * v4b.z, v4a * v4b.w);
}

View File

@ -5,6 +5,7 @@ struct Buffer
mat4 MVPRowMajor;
mat4 MVPColMajor;
mat4 M;
mediump mat4 MRelaxed;
};
uniform Buffer _13;
@ -14,11 +15,20 @@ varying mat4 OutputMat1;
varying mat4 OutputMat2;
varying mat4 OutputMat3;
varying mat4 OutputMat4;
varying mat4 OutputMat5;
varying mat4 OutputMat6;
varying mediump mat4 OutputMat7;
varying mediump mat4 OutputMat8;
highp mat4 spvWorkaroundRowMajor(highp mat4 wrap) { return wrap; }
mediump mat4 spvWorkaroundRowMajorMP(mediump mat4 wrap) { return wrap; }
mat4 spvTranspose(mat4 m)
highp mat4 spvTranspose(highp mat4 m)
{
return mat4(m[0][0], m[1][0], m[2][0], m[3][0], m[0][1], m[1][1], m[2][1], m[3][1], m[0][2], m[1][2], m[2][2], m[3][2], m[0][3], m[1][3], m[2][3], m[3][3]);
}
mediump mat4 spvTransposeMP(mediump mat4 m)
{
return mat4(m[0][0], m[1][0], m[2][0], m[3][0], m[0][1], m[1][1], m[2][1], m[3][1], m[0][2], m[1][2], m[2][2], m[3][2], m[0][3], m[1][3], m[2][3], m[3][3]);
}
@ -41,6 +51,10 @@ void main()
OutputMat2 = spvWorkaroundRowMajor(_13.MVPColMajor);
OutputMat3 = _13.MVPRowMajor;
OutputMat4 = spvTranspose(spvWorkaroundRowMajor(_13.MVPColMajor));
OutputMat5 = spvTranspose(spvWorkaroundRowMajor(_13.M));
OutputMat6 = spvTransposeMP(spvWorkaroundRowMajor(_13.MRelaxed));
OutputMat7 = spvTranspose(spvWorkaroundRowMajor(_13.M));
OutputMat8 = spvTransposeMP(spvWorkaroundRowMajor(_13.MRelaxed));
gl_Position = ((((((((((c0 + c1) + c2) + c3) + c4) + c5) + c6) + c7) + c8) + c9) + c10) + c11;
}

View File

@ -0,0 +1,39 @@
#version 310 es
uniform Buffer
{
mat2 m2;
mat3 m3;
mat4 m4;
mediump mat2 m2r;
mediump mat3 m3r;
mediump mat4 m4r;
};
layout(location = 0) in vec4 Position;
layout(location = 0) out vec3 dets;
layout(location = 1) out mat2 o2;
layout(location = 3) out mat3 o3;
layout(location = 6) out mat4 o4;
layout(location = 10) out mat2 o2r;
layout(location = 12) out mat3 o3r;
layout(location = 15) out mat4 o4r;
void main()
{
dets.x = determinant(m2);
dets.y = determinant(m3);
dets.z = determinant(m4);
o2 = inverse(m2);
o3 = inverse(m3);
o4 = inverse(m4);
o2r = inverse(m2r);
o3r = inverse(m3r);
o4r = inverse(m4r);
gl_Position = vec4(0.0);
}

View File

@ -0,0 +1,19 @@
#version 450
layout(location = 0) in vec2 v2a;
layout(location = 1) in vec2 v2b;
layout(location = 2) in vec3 v3a;
layout(location = 3) in vec3 v3b;
layout(location = 4) in vec4 v4a;
layout(location = 5) in vec4 v4b;
layout(location = 0) out mat2 m22;
layout(location = 2) out mat3 m33;
layout(location = 5) out mat4 m44;
void main()
{
m22 = outerProduct(v2a, v2b);
m33 = outerProduct(v3a, v3b);
m44 = outerProduct(v4a, v4b);
}

View File

@ -5,6 +5,7 @@ uniform Buffer
layout(row_major) mat4 MVPRowMajor;
layout(column_major) mat4 MVPColMajor;
mat4 M;
mediump mat4 MRelaxed;
};
layout(location = 0) in vec4 Position;
@ -13,6 +14,10 @@ layout(location = 1) out mat4 OutputMat1;
layout(location = 5) out mat4 OutputMat2;
layout(location = 9) out mat4 OutputMat3;
layout(location = 13) out mat4 OutputMat4;
layout(location = 17) out highp mat4 OutputMat5;
layout(location = 21) out highp mat4 OutputMat6;
layout(location = 25) out mediump mat4 OutputMat7;
layout(location = 29) out mediump mat4 OutputMat8;
void main()
{
@ -38,6 +43,12 @@ void main()
OutputMat3 = transpose(MVPRowMajor);
OutputMat4 = transpose(MVPColMajor);
// Preserve precision of input, ignore precision of output
OutputMat5 = transpose(M);
OutputMat6 = transpose(MRelaxed);
OutputMat7 = transpose(M);
OutputMat8 = transpose(MRelaxed);
gl_Position = c0 + c1 + c2 + c3 + c4 + c5 + c6 + c7 + c8 + c9 + c10 + c11;
}

View File

@ -636,6 +636,17 @@ void CompilerGLSL::find_static_extensions()
barycentric_is_nv = true;
}
void CompilerGLSL::require_polyfill(Polyfill polyfill, bool relaxed)
{
uint32_t &polyfills = (relaxed && options.es) ? required_polyfills_relaxed : required_polyfills;
if ((polyfills & polyfill) == 0)
{
polyfills |= polyfill;
force_recompile();
}
}
void CompilerGLSL::ray_tracing_khr_fixup_locations()
{
uint32_t location = 0;
@ -701,6 +712,11 @@ string CompilerGLSL::compile()
emit_resources();
emit_extension_workarounds(get_execution_model());
if (required_polyfills != 0)
emit_polyfills(required_polyfills, false);
if (options.es && required_polyfills_relaxed != 0)
emit_polyfills(required_polyfills_relaxed, true);
emit_function(get<SPIRFunction>(ir.default_entry_point), Bitset());
pass_count++;
@ -4401,34 +4417,135 @@ void CompilerGLSL::emit_extension_workarounds(spv::ExecutionModel model)
}
statement("");
}
}
if (requires_transpose_2x2)
void CompilerGLSL::emit_polyfills(uint32_t polyfills, bool relaxed)
{
const char *qual = "";
const char *suffix = (options.es && relaxed) ? "MP" : "";
if (options.es)
qual = relaxed ? "mediump " : "highp ";
if (polyfills & PolyfillTranspose2x2)
{
statement("mat2 spvTranspose(mat2 m)");
statement(qual, "mat2 spvTranspose", suffix, "(", qual, "mat2 m)");
begin_scope();
statement("return mat2(m[0][0], m[1][0], m[0][1], m[1][1]);");
end_scope();
statement("");
}
if (requires_transpose_3x3)
if (polyfills & PolyfillTranspose3x3)
{
statement("mat3 spvTranspose(mat3 m)");
statement(qual, "mat3 spvTranspose", suffix, "(", qual, "mat3 m)");
begin_scope();
statement("return mat3(m[0][0], m[1][0], m[2][0], m[0][1], m[1][1], m[2][1], m[0][2], m[1][2], m[2][2]);");
end_scope();
statement("");
}
if (requires_transpose_4x4)
if (polyfills & PolyfillTranspose4x4)
{
statement("mat4 spvTranspose(mat4 m)");
statement(qual, "mat4 spvTranspose", suffix, "(", qual, "mat4 m)");
begin_scope();
statement("return mat4(m[0][0], m[1][0], m[2][0], m[3][0], m[0][1], m[1][1], m[2][1], m[3][1], m[0][2], "
"m[1][2], m[2][2], m[3][2], m[0][3], m[1][3], m[2][3], m[3][3]);");
end_scope();
statement("");
}
if (polyfills & PolyfillDeterminant2x2)
{
statement("float spvDeterminant", suffix, "(", qual, "mat2 m)");
begin_scope();
statement("return m[0][0] * m[1][1] - m[0][1] * m[1][0];");
end_scope();
statement("");
}
if (polyfills & PolyfillDeterminant3x3)
{
statement("float spvDeterminant", suffix, "(", qual, "mat3 m)");
begin_scope();
statement("return dot(m[0], vec3(m[1][1] * m[2][2] - m[1][2] * m[2][1], "
"m[1][2] * m[2][0] - m[1][0] * m[2][2], "
"m[1][0] * m[2][1] - m[1][1] * m[2][0]));");
end_scope();
statement("");
}
if (polyfills & PolyfillDeterminant4x4)
{
statement("float spvDeterminant", suffix, "(", qual, "mat4 m)");
begin_scope();
statement("return dot(m[0], vec4("
"m[2][1] * m[3][2] * m[1][3] - m[3][1] * m[2][2] * m[1][3] + m[3][1] * m[1][2] * m[2][3] - m[1][1] * m[3][2] * m[2][3] - m[2][1] * m[1][2] * m[3][3] + m[1][1] * m[2][2] * m[3][3], "
"m[3][0] * m[2][2] * m[1][3] - m[2][0] * m[3][2] * m[1][3] - m[3][0] * m[1][2] * m[2][3] + m[1][0] * m[3][2] * m[2][3] + m[2][0] * m[1][2] * m[3][3] - m[1][0] * m[2][2] * m[3][3], "
"m[2][0] * m[3][1] * m[1][3] - m[3][0] * m[2][1] * m[1][3] + m[3][0] * m[1][1] * m[2][3] - m[1][0] * m[3][1] * m[2][3] - m[2][0] * m[1][1] * m[3][3] + m[1][0] * m[2][1] * m[3][3], "
"m[3][0] * m[2][1] * m[1][2] - m[2][0] * m[3][1] * m[1][2] - m[3][0] * m[1][1] * m[2][2] + m[1][0] * m[3][1] * m[2][2] + m[2][0] * m[1][1] * m[3][2] - m[1][0] * m[2][1] * m[3][2]));");
end_scope();
statement("");
}
if (polyfills & PolyfillMatrixInverse2x2)
{
statement(qual, "mat2 spvInverse", suffix, "(", qual, "mat2 m)");
begin_scope();
statement("return mat2(m[1][1], -m[0][1], -m[1][0], m[0][0]) "
"* (1.0 / (m[0][0] * m[1][1] - m[1][0] * m[0][1]));");
end_scope();
statement("");
}
if (polyfills & PolyfillMatrixInverse3x3)
{
statement(qual, "mat3 spvInverse", suffix, "(", qual, "mat3 m)");
begin_scope();
statement(qual, "vec3 t = vec3(m[1][1] * m[2][2] - m[1][2] * m[2][1], m[1][2] * m[2][0] - m[1][0] * m[2][2], m[1][0] * m[2][1] - m[1][1] * m[2][0]);");
statement("return mat3(t[0], "
"m[0][2] * m[2][1] - m[0][1] * m[2][2], "
"m[0][1] * m[1][2] - m[0][2] * m[1][1], "
"t[1], "
"m[0][0] * m[2][2] - m[0][2] * m[2][0], "
"m[0][2] * m[1][0] - m[0][0] * m[1][2], "
"t[2], "
"m[0][1] * m[2][0] - m[0][0] * m[2][1], "
"m[0][0] * m[1][1] - m[0][1] * m[1][0]) "
"* (1.0 / dot(m[0], t));");
end_scope();
statement("");
}
if (polyfills & PolyfillMatrixInverse4x4)
{
statement(qual, "mat4 spvInverse", suffix, "(", qual, "mat4 m)");
begin_scope();
statement(qual, "vec4 t = vec4("
"m[2][1] * m[3][2] * m[1][3] - m[3][1] * m[2][2] * m[1][3] + m[3][1] * m[1][2] * m[2][3] - m[1][1] * m[3][2] * m[2][3] - m[2][1] * m[1][2] * m[3][3] + m[1][1] * m[2][2] * m[3][3], "
"m[3][0] * m[2][2] * m[1][3] - m[2][0] * m[3][2] * m[1][3] - m[3][0] * m[1][2] * m[2][3] + m[1][0] * m[3][2] * m[2][3] + m[2][0] * m[1][2] * m[3][3] - m[1][0] * m[2][2] * m[3][3], "
"m[2][0] * m[3][1] * m[1][3] - m[3][0] * m[2][1] * m[1][3] + m[3][0] * m[1][1] * m[2][3] - m[1][0] * m[3][1] * m[2][3] - m[2][0] * m[1][1] * m[3][3] + m[1][0] * m[2][1] * m[3][3], "
"m[3][0] * m[2][1] * m[1][2] - m[2][0] * m[3][1] * m[1][2] - m[3][0] * m[1][1] * m[2][2] + m[1][0] * m[3][1] * m[2][2] + m[2][0] * m[1][1] * m[3][2] - m[1][0] * m[2][1] * m[3][2]);");
statement("return mat4("
"t[0], "
"m[3][1] * m[2][2] * m[0][3] - m[2][1] * m[3][2] * m[0][3] - m[3][1] * m[0][2] * m[2][3] + m[0][1] * m[3][2] * m[2][3] + m[2][1] * m[0][2] * m[3][3] - m[0][1] * m[2][2] * m[3][3], "
"m[1][1] * m[3][2] * m[0][3] - m[3][1] * m[1][2] * m[0][3] + m[3][1] * m[0][2] * m[1][3] - m[0][1] * m[3][2] * m[1][3] - m[1][1] * m[0][2] * m[3][3] + m[0][1] * m[1][2] * m[3][3], "
"m[2][1] * m[1][2] * m[0][3] - m[1][1] * m[2][2] * m[0][3] - m[2][1] * m[0][2] * m[1][3] + m[0][1] * m[2][2] * m[1][3] + m[1][1] * m[0][2] * m[2][3] - m[0][1] * m[1][2] * m[2][3], "
"t[1], "
"m[2][0] * m[3][2] * m[0][3] - m[3][0] * m[2][2] * m[0][3] + m[3][0] * m[0][2] * m[2][3] - m[0][0] * m[3][2] * m[2][3] - m[2][0] * m[0][2] * m[3][3] + m[0][0] * m[2][2] * m[3][3], "
"m[3][0] * m[1][2] * m[0][3] - m[1][0] * m[3][2] * m[0][3] - m[3][0] * m[0][2] * m[1][3] + m[0][0] * m[3][2] * m[1][3] + m[1][0] * m[0][2] * m[3][3] - m[0][0] * m[1][2] * m[3][3], "
"m[1][0] * m[2][2] * m[0][3] - m[2][0] * m[1][2] * m[0][3] + m[2][0] * m[0][2] * m[1][3] - m[0][0] * m[2][2] * m[1][3] - m[1][0] * m[0][2] * m[2][3] + m[0][0] * m[1][2] * m[2][3], "
"t[2], "
"m[3][0] * m[2][1] * m[0][3] - m[2][0] * m[3][1] * m[0][3] - m[3][0] * m[0][1] * m[2][3] + m[0][0] * m[3][1] * m[2][3] + m[2][0] * m[0][1] * m[3][3] - m[0][0] * m[2][1] * m[3][3], "
"m[1][0] * m[3][1] * m[0][3] - m[3][0] * m[1][1] * m[0][3] + m[3][0] * m[0][1] * m[1][3] - m[0][0] * m[3][1] * m[1][3] - m[1][0] * m[0][1] * m[3][3] + m[0][0] * m[1][1] * m[3][3], "
"m[2][0] * m[1][1] * m[0][3] - m[1][0] * m[2][1] * m[0][3] - m[2][0] * m[0][1] * m[1][3] + m[0][0] * m[2][1] * m[1][3] + m[1][0] * m[0][1] * m[2][3] - m[0][0] * m[1][1] * m[2][3], "
"t[3], "
"m[2][0] * m[3][1] * m[0][2] - m[3][0] * m[2][1] * m[0][2] + m[3][0] * m[0][1] * m[2][2] - m[0][0] * m[3][1] * m[2][2] - m[2][0] * m[0][1] * m[3][2] + m[0][0] * m[2][1] * m[3][2], "
"m[3][0] * m[1][1] * m[0][2] - m[1][0] * m[3][1] * m[0][2] - m[3][0] * m[0][1] * m[1][2] + m[0][0] * m[3][1] * m[1][2] + m[1][0] * m[0][1] * m[3][2] - m[0][0] * m[1][1] * m[3][2], "
"m[1][0] * m[2][1] * m[0][2] - m[2][0] * m[1][1] * m[0][2] + m[2][0] * m[0][1] * m[1][2] - m[0][0] * m[2][1] * m[1][2] - m[1][0] * m[0][1] * m[2][2] + m[0][0] * m[1][1] * m[2][2]) "
"* (1.0 / dot(m[0], t));");
end_scope();
statement("");
}
}
// Returns a string representation of the ID, usable as a function arg.
@ -4864,8 +4981,9 @@ string CompilerGLSL::to_expression(uint32_t id, bool register_expression_read)
// when consuming an access chain expression.
uint32_t physical_type_id = get_extended_decoration(id, SPIRVCrossDecorationPhysicalTypeID);
bool is_packed = has_extended_decoration(id, SPIRVCrossDecorationPhysicalTypePacked);
bool relaxed = has_decoration(id, DecorationRelaxedPrecision);
return convert_row_major_matrix(e.expression, get<SPIRType>(e.expression_type), physical_type_id,
is_packed);
is_packed, relaxed);
}
else if (flattened_structs.count(id))
{
@ -8122,11 +8240,74 @@ void CompilerGLSL::emit_glsl_op(uint32_t result_type, uint32_t id, uint32_t eop,
// Matrix math
case GLSLstd450Determinant:
emit_unary_func_op(result_type, id, args[0], "determinant");
{
// No need to transpose - it doesn't affect the determinant
auto *e = maybe_get<SPIRExpression>(args[0]);
bool old_transpose = e && e->need_transpose;
if (old_transpose)
e->need_transpose = false;
if (options.version < 150) // also matches ES 100
{
auto &type = expression_type(args[0]);
assert(type.vecsize >= 2 && type.vecsize <= 4);
assert(type.vecsize == type.columns);
// ARB_gpu_shader_fp64 needs GLSL 150, other types are not valid
if (type.basetype != SPIRType::Float)
SPIRV_CROSS_THROW("Unsupported type for matrix determinant");
bool relaxed = has_decoration(id, DecorationRelaxedPrecision);
require_polyfill(static_cast<Polyfill>(PolyfillDeterminant2x2 << (type.vecsize - 2)),
relaxed);
emit_unary_func_op(result_type, id, args[0],
(options.es && relaxed) ? "spvDeterminantMP" : "spvDeterminant");
}
else
emit_unary_func_op(result_type, id, args[0], "determinant");
if (old_transpose)
e->need_transpose = true;
break;
}
case GLSLstd450MatrixInverse:
emit_unary_func_op(result_type, id, args[0], "inverse");
{
// The inverse of the transpose is the same as the transpose of
// the inverse, so we can just flip need_transpose of the result.
auto *a = maybe_get<SPIRExpression>(args[0]);
bool old_transpose = a && a->need_transpose;
if (old_transpose)
a->need_transpose = false;
const char *func = "inverse";
if (options.version < 140) // also matches ES 100
{
auto &type = get<SPIRType>(result_type);
assert(type.vecsize >= 2 && type.vecsize <= 4);
assert(type.vecsize == type.columns);
// ARB_gpu_shader_fp64 needs GLSL 150, other types are invalid
if (type.basetype != SPIRType::Float)
SPIRV_CROSS_THROW("Unsupported type for matrix inverse");
bool relaxed = has_decoration(id, DecorationRelaxedPrecision);
require_polyfill(static_cast<Polyfill>(PolyfillMatrixInverse2x2 << (type.vecsize - 2)),
relaxed);
func = (options.es && relaxed) ? "spvInverseMP" : "spvInverse";
}
bool forward = should_forward(args[0]);
auto &e = emit_op(result_type, id, join(func, "(", to_unpacked_expression(args[0]), ")"), forward);
inherit_expression_dependencies(id, args[0]);
if (old_transpose)
{
e.need_transpose = true;
a->need_transpose = true;
}
break;
}
// Lerping
case GLSLstd450FMix:
@ -9954,10 +10135,13 @@ std::string CompilerGLSL::flattened_access_chain_struct(uint32_t base, const uin
// The access chain terminates at the struct, so we need to find matrix strides and row-major information
// ahead of time.
bool need_transpose = false;
bool relaxed = false;
uint32_t matrix_stride = 0;
if (member_type.columns > 1)
{
need_transpose = combined_decoration_for_member(target_type, i).get(DecorationRowMajor);
auto decorations = combined_decoration_for_member(target_type, i);
need_transpose = decorations.get(DecorationRowMajor);
relaxed = decorations.get(DecorationRelaxedPrecision);
matrix_stride = type_struct_member_matrix_stride(target_type, i);
}
@ -9966,7 +10150,7 @@ std::string CompilerGLSL::flattened_access_chain_struct(uint32_t base, const uin
// Cannot forward transpositions, so resolve them here.
if (need_transpose)
expr += convert_row_major_matrix(tmp, member_type, 0, false);
expr += convert_row_major_matrix(tmp, member_type, 0, false, relaxed);
else
expr += tmp;
}
@ -12163,7 +12347,31 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction)
break;
case OpOuterProduct:
GLSL_BFOP(outerProduct);
if (options.version < 120) // Matches GLSL 1.10 / ESSL 1.00
{
uint32_t result_type = ops[0];
uint32_t id = ops[1];
uint32_t a = ops[2];
uint32_t b = ops[3];
auto &type = get<SPIRType>(result_type);
string expr = type_to_glsl_constructor(type);
expr += "(";
for (uint32_t col = 0; col < type.columns; col++)
{
expr += to_enclosed_expression(a);
expr += " * ";
expr += to_extract_component_expression(b, col);
if (col + 1 < type.columns)
expr += ", ";
}
expr += ")";
emit_op(result_type, id, expr, should_forward(a) && should_forward(b));
inherit_expression_dependencies(id, a);
inherit_expression_dependencies(id, b);
}
else
GLSL_BFOP(outerProduct);
break;
case OpDot:
@ -14273,7 +14481,7 @@ bool CompilerGLSL::member_is_packed_physical_type(const SPIRType &type, uint32_t
// Base implementation uses the standard library transpose() function.
// Subclasses may override to use a different function.
string CompilerGLSL::convert_row_major_matrix(string exp_str, const SPIRType &exp_type, uint32_t /* physical_type_id */,
bool /*is_packed*/)
bool /*is_packed*/, bool relaxed)
{
strip_enclosed_expression(exp_str);
if (!is_matrix(exp_type))
@ -14303,32 +14511,14 @@ string CompilerGLSL::convert_row_major_matrix(string exp_str, const SPIRType &ex
// GLSL 110, ES 100 do not have transpose(), so emulate it. Note that
// these GLSL versions do not support non-square matrices.
if (exp_type.vecsize == 2 && exp_type.columns == 2)
{
if (!requires_transpose_2x2)
{
requires_transpose_2x2 = true;
force_recompile();
}
}
require_polyfill(PolyfillTranspose2x2, relaxed);
else if (exp_type.vecsize == 3 && exp_type.columns == 3)
{
if (!requires_transpose_3x3)
{
requires_transpose_3x3 = true;
force_recompile();
}
}
require_polyfill(PolyfillTranspose3x3, relaxed);
else if (exp_type.vecsize == 4 && exp_type.columns == 4)
{
if (!requires_transpose_4x4)
{
requires_transpose_4x4 = true;
force_recompile();
}
}
require_polyfill(PolyfillTranspose4x4, relaxed);
else
SPIRV_CROSS_THROW("Non-square matrices are not supported in legacy GLSL, cannot transpose.");
return join("spvTranspose(", exp_str, ")");
return join("spvTranspose", (options.es && relaxed) ? "MP" : "", "(", exp_str, ")");
}
else
return join("transpose(", exp_str, ")");

View File

@ -552,7 +552,8 @@ protected:
bool member_is_remapped_physical_type(const SPIRType &type, uint32_t index) const;
bool member_is_packed_physical_type(const SPIRType &type, uint32_t index) const;
virtual std::string convert_row_major_matrix(std::string exp_str, const SPIRType &exp_type,
uint32_t physical_type_id, bool is_packed);
uint32_t physical_type_id, bool is_packed,
bool relaxed = false);
std::unordered_set<std::string> local_variable_names;
std::unordered_set<std::string> resource_names;
@ -626,6 +627,7 @@ protected:
void emit_struct(SPIRType &type);
void emit_resources();
void emit_extension_workarounds(spv::ExecutionModel model);
void emit_polyfills(uint32_t polyfills, bool relaxed);
void emit_buffer_block_native(const SPIRVariable &var);
void emit_buffer_reference_block(uint32_t type_id, bool forward_declaration);
void emit_buffer_block_legacy(const SPIRVariable &var);
@ -884,9 +886,23 @@ protected:
return !options.es && options.version < 130;
}
bool requires_transpose_2x2 = false;
bool requires_transpose_3x3 = false;
bool requires_transpose_4x4 = false;
enum Polyfill : uint32_t
{
PolyfillTranspose2x2 = 1 << 0,
PolyfillTranspose3x3 = 1 << 1,
PolyfillTranspose4x4 = 1 << 2,
PolyfillDeterminant2x2 = 1 << 3,
PolyfillDeterminant3x3 = 1 << 4,
PolyfillDeterminant4x4 = 1 << 5,
PolyfillMatrixInverse2x2 = 1 << 6,
PolyfillMatrixInverse3x3 = 1 << 7,
PolyfillMatrixInverse4x4 = 1 << 8,
};
uint32_t required_polyfills = 0;
uint32_t required_polyfills_relaxed = 0;
void require_polyfill(Polyfill polyfill, bool relaxed);
bool ray_tracing_is_khr = false;
bool barycentric_is_nv = false;
void ray_tracing_khr_fixup_locations();

View File

@ -11487,11 +11487,11 @@ bool CompilerMSL::member_is_non_native_row_major_matrix(const SPIRType &type, ui
}
string CompilerMSL::convert_row_major_matrix(string exp_str, const SPIRType &exp_type, uint32_t physical_type_id,
bool is_packed)
bool is_packed, bool relaxed)
{
if (!is_matrix(exp_type))
{
return CompilerGLSL::convert_row_major_matrix(std::move(exp_str), exp_type, physical_type_id, is_packed);
return CompilerGLSL::convert_row_major_matrix(std::move(exp_str), exp_type, physical_type_id, is_packed, relaxed);
}
else
{

View File

@ -864,7 +864,7 @@ protected:
bool is_non_native_row_major_matrix(uint32_t id) override;
bool member_is_non_native_row_major_matrix(const SPIRType &type, uint32_t index) override;
std::string convert_row_major_matrix(std::string exp_str, const SPIRType &exp_type, uint32_t physical_type_id,
bool is_packed) override;
bool is_packed, bool relaxed) override;
bool is_tesc_shader() const;
bool is_tese_shader() const;