GLSL: Legacy matrix inverse/determinant polyfills, outerProduct()
Also refactors polyfill mechanism in GLSL and fixes transpose() lowering precision.
This commit is contained in:
parent
86a985f28c
commit
20981666cc
85
reference/opt/shaders/legacy/vert/inverse.legacy.vert
Normal file
85
reference/opt/shaders/legacy/vert/inverse.legacy.vert
Normal 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);
|
||||
}
|
||||
|
19
reference/opt/shaders/legacy/vert/outer-product.legacy.vert
Normal file
19
reference/opt/shaders/legacy/vert/outer-product.legacy.vert
Normal 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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
85
reference/shaders/legacy/vert/inverse.legacy.vert
Normal file
85
reference/shaders/legacy/vert/inverse.legacy.vert
Normal 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);
|
||||
}
|
||||
|
19
reference/shaders/legacy/vert/outer-product.legacy.vert
Normal file
19
reference/shaders/legacy/vert/outer-product.legacy.vert
Normal 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);
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
39
shaders/legacy/vert/inverse.legacy.vert
Normal file
39
shaders/legacy/vert/inverse.legacy.vert
Normal 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);
|
||||
}
|
||||
|
19
shaders/legacy/vert/outer-product.legacy.vert
Normal file
19
shaders/legacy/vert/outer-product.legacy.vert
Normal 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);
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
|
260
spirv_glsl.cpp
260
spirv_glsl.cpp
@ -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, ")");
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user