Add an option to SPIRV-Cross to enforce invariant floating point math to prevent different depth calculation between prepass & basepass when running on Metal 2.0 and earlier.
This commit is contained in:
parent
e4c6388571
commit
69b703f1da
@ -977,7 +977,30 @@ void CompilerMSL::preprocess_op_codes()
|
|||||||
/* UE Change Begin: Allow Metal to use the array<T> template to make arrays a value type */
|
/* UE Change Begin: Allow Metal to use the array<T> template to make arrays a value type */
|
||||||
// UnsafeArray
|
// UnsafeArray
|
||||||
{
|
{
|
||||||
add_header_line(" ");
|
if (msl_options.invariant_float_math)
|
||||||
|
{
|
||||||
|
add_header_line("template <typename T> T fmul(T l, T r) { return metal::fma(l, r, T(0)); }");
|
||||||
|
add_header_line("template <typename T> T fadd(T l, T r) { return metal::fma(T(1), l, r); }");
|
||||||
|
|
||||||
|
add_header_line("template <typename T, int Cols, int Rows> metal::vec<T, Rows> fmul_mv(metal::matrix<T, Cols, Rows> m, metal::vec<T, Cols> v) { metal::vec<T, Rows> res = metal::vec<T, Rows>(0); for(uint i = Cols; i > 0; --i) { res = metal::fma(m[i-1], metal::vec<T, Rows>(v[i-1]), res); } return res; }");
|
||||||
|
|
||||||
|
add_header_line("template <typename T, int LCols, int LRows, int RCols, int RRows>");
|
||||||
|
add_header_line("metal::matrix<T, RCols, LRows> fmul_mat(metal::matrix<T, LCols, LRows> l, metal::matrix<T, RCols, RRows> r)");
|
||||||
|
add_header_line("{");
|
||||||
|
add_header_line(" metal::matrix<T, RCols, LRows> res;");
|
||||||
|
add_header_line(" for(uint i = 0; i < RCols; i++)");
|
||||||
|
add_header_line(" {");
|
||||||
|
add_header_line(" metal::vec<T, RCols> tmp(0);");
|
||||||
|
add_header_line(" for(uint j = 0; j < LCols; j++)");
|
||||||
|
add_header_line(" {");
|
||||||
|
add_header_line(" tmp = metal::fma(metal::vec<T, RCols>(r[i][j]),l[j],tmp);");
|
||||||
|
add_header_line(" }");
|
||||||
|
add_header_line(" res[i] = tmp;");
|
||||||
|
add_header_line(" }");
|
||||||
|
add_header_line(" return res;");
|
||||||
|
add_header_line("}");
|
||||||
|
}
|
||||||
|
|
||||||
add_header_line("template <typename T, size_t Num>");
|
add_header_line("template <typename T, size_t Num>");
|
||||||
add_header_line("struct unsafe_array");
|
add_header_line("struct unsafe_array");
|
||||||
add_header_line("{");
|
add_header_line("{");
|
||||||
@ -5360,6 +5383,20 @@ void CompilerMSL::emit_instruction(const Instruction &instruction)
|
|||||||
MSL_BFOP(fmod);
|
MSL_BFOP(fmod);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case OpFMul:
|
||||||
|
if (msl_options.invariant_float_math)
|
||||||
|
MSL_BFOP(fmul);
|
||||||
|
else
|
||||||
|
MSL_BOP(*);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OpFAdd:
|
||||||
|
if (msl_options.invariant_float_math)
|
||||||
|
MSL_BFOP(fadd);
|
||||||
|
else
|
||||||
|
MSL_BOP(+);
|
||||||
|
break;
|
||||||
|
|
||||||
// Atomics
|
// Atomics
|
||||||
case OpAtomicExchange:
|
case OpAtomicExchange:
|
||||||
{
|
{
|
||||||
@ -5782,14 +5819,31 @@ void CompilerMSL::emit_instruction(const Instruction &instruction)
|
|||||||
uint32_t a = ops[2];
|
uint32_t a = ops[2];
|
||||||
uint32_t b = ops[3];
|
uint32_t b = ops[3];
|
||||||
|
|
||||||
|
auto *type_a = maybe_get<SPIRType>(a);
|
||||||
|
auto *type_b = maybe_get<SPIRType>(b);
|
||||||
|
|
||||||
auto &type = get<SPIRType>(result_type);
|
auto &type = get<SPIRType>(result_type);
|
||||||
string expr = type_to_glsl_constructor(type);
|
string expr = type_to_glsl_constructor(type);
|
||||||
expr += "(";
|
expr += "(";
|
||||||
for (uint32_t col = 0; col < type.columns; col++)
|
for (uint32_t col = 0; col < type.columns; col++)
|
||||||
|
{
|
||||||
|
if (msl_options.invariant_float_math && type_a && type_b &&
|
||||||
|
( (is_matrix(*type_a) && is_matrix(*type_b)) ||
|
||||||
|
(is_matrix(*type_a) && is_vector(*type_b)) ||
|
||||||
|
(is_vector(*type_a) && is_matrix(*type_b)) ) )
|
||||||
|
{
|
||||||
|
expr += "fmul_mat(";
|
||||||
|
expr += to_enclosed_expression(a);
|
||||||
|
expr += ", ";
|
||||||
|
expr += to_extract_component_expression(b, col);
|
||||||
|
expr += ")";
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
expr += to_enclosed_expression(a);
|
expr += to_enclosed_expression(a);
|
||||||
expr += " * ";
|
expr += " * ";
|
||||||
expr += to_extract_component_expression(b, col);
|
expr += to_extract_component_expression(b, col);
|
||||||
|
}
|
||||||
if (col + 1 < type.columns)
|
if (col + 1 < type.columns)
|
||||||
expr += ", ";
|
expr += ", ";
|
||||||
}
|
}
|
||||||
|
@ -299,6 +299,8 @@ public:
|
|||||||
bool enforce_storge_buffer_bounds = false;
|
bool enforce_storge_buffer_bounds = false;
|
||||||
/* UE Change End: Storage buffer robustness - clamps access to SSBOs to the size of the buffer */
|
/* UE Change End: Storage buffer robustness - clamps access to SSBOs to the size of the buffer */
|
||||||
|
|
||||||
|
bool invariant_float_math = false;
|
||||||
|
|
||||||
// Requires MSL 2.1, use the native support for texel buffers.
|
// Requires MSL 2.1, use the native support for texel buffers.
|
||||||
bool texture_buffer_native = false;
|
bool texture_buffer_native = false;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user