e47a30e807
We'll need to force a temporary and mark it as precise. MSL is a little weird here, but we can piggyback on top of the invariant float math option here to force fma() operations everywhere.
93 lines
2.0 KiB
GLSL
93 lines
2.0 KiB
GLSL
#pragma clang diagnostic ignored "-Wmissing-prototypes"
|
|
|
|
#include <metal_stdlib>
|
|
#include <simd/simd.h>
|
|
|
|
using namespace metal;
|
|
|
|
struct main0_out
|
|
{
|
|
float4 gl_Position [[position]];
|
|
};
|
|
|
|
struct main0_in
|
|
{
|
|
float4 vA [[attribute(0)]];
|
|
float4 vB [[attribute(1)]];
|
|
float4 vC [[attribute(2)]];
|
|
};
|
|
|
|
template<typename T>
|
|
T spvFMul(T l, T r)
|
|
{
|
|
return fma(l, r, T(0));
|
|
}
|
|
|
|
template<typename T, int Cols, int Rows>
|
|
vec<T, Cols> spvFMulVectorMatrix(vec<T, Rows> v, matrix<T, Cols, Rows> m)
|
|
{
|
|
vec<T, Cols> res = vec<T, Cols>(0);
|
|
for (uint i = Rows; i > 0; --i)
|
|
{
|
|
vec<T, Cols> tmp(0);
|
|
for (uint j = 0; j < Cols; ++j)
|
|
{
|
|
tmp[j] = m[j][i - 1];
|
|
}
|
|
res = fma(tmp, vec<T, Cols>(v[i - 1]), res);
|
|
}
|
|
return res;
|
|
}
|
|
|
|
template<typename T, int Cols, int Rows>
|
|
vec<T, Rows> spvFMulMatrixVector(matrix<T, Cols, Rows> m, vec<T, Cols> v)
|
|
{
|
|
vec<T, Rows> res = vec<T, Rows>(0);
|
|
for (uint i = Cols; i > 0; --i)
|
|
{
|
|
res = fma(m[i - 1], vec<T, Rows>(v[i - 1]), res);
|
|
}
|
|
return res;
|
|
}
|
|
|
|
template<typename T, int LCols, int LRows, int RCols, int RRows>
|
|
matrix<T, RCols, LRows> spvFMulMatrixMatrix(matrix<T, LCols, LRows> l, matrix<T, RCols, RRows> r)
|
|
{
|
|
matrix<T, RCols, LRows> res;
|
|
for (uint i = 0; i < RCols; i++)
|
|
{
|
|
vec<T, RCols> tmp(0);
|
|
for (uint j = 0; j < LCols; j++)
|
|
{
|
|
tmp = fma(vec<T, RCols>(r[i][j]), l[j], tmp);
|
|
}
|
|
res[i] = tmp;
|
|
}
|
|
return res;
|
|
}
|
|
|
|
template<typename T>
|
|
T spvFAdd(T l, T r)
|
|
{
|
|
return fma(T(1), l, r);
|
|
}
|
|
|
|
template<typename T>
|
|
T spvFSub(T l, T r)
|
|
{
|
|
return fma(T(-1), r, l);
|
|
}
|
|
|
|
vertex main0_out main0(main0_in in [[stage_in]])
|
|
{
|
|
main0_out out = {};
|
|
float4 mul = spvFMul(in.vA, in.vB);
|
|
float4 add = spvFAdd(in.vA, in.vB);
|
|
float4 sub = spvFSub(in.vA, in.vB);
|
|
float4 mad = spvFAdd(spvFMul(in.vA, in.vB), in.vC);
|
|
float4 summed = spvFAdd(spvFAdd(spvFAdd(mul, add), sub), mad);
|
|
out.gl_Position = summed;
|
|
return out;
|
|
}
|
|
|