Added a new 'emulate_cube_array' option to SPIRV-Cross to cope with translating TextureCubeArray into texture2d_array for iOS where this type is not available. (Original Author: Mark Satterthwaite)
This commit is contained in:
parent
9573faa56d
commit
7cf5d4f7a1
@ -980,14 +980,22 @@ 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
|
|
||||||
{
|
{
|
||||||
if (msl_options.invariant_float_math)
|
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 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> 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 Cols, int Rows>");
|
||||||
|
add_header_line("metal::vec<T, Rows> fmul_mv(metal::matrix<T, Cols, Rows> m, metal::vec<T, Cols> v)");
|
||||||
|
add_header_line("{");
|
||||||
|
add_header_line(" metal::vec<T, Rows> res = metal::vec<T, Rows>(0);");
|
||||||
|
add_header_line(" for(uint i = Cols; i > 0; --i)");
|
||||||
|
add_header_line(" {");
|
||||||
|
add_header_line(" res = metal::fma(m[i-1], metal::vec<T, Rows>(v[i-1]), res);");
|
||||||
|
add_header_line(" }");
|
||||||
|
add_header_line(" return res;");
|
||||||
|
add_header_line("}");
|
||||||
|
|
||||||
add_header_line("template <typename T, int LCols, int LRows, int RCols, int RRows>");
|
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("metal::matrix<T, RCols, LRows> fmul_mat(metal::matrix<T, LCols, LRows> l, metal::matrix<T, RCols, RRows> r)");
|
||||||
@ -1006,6 +1014,43 @@ void CompilerMSL::preprocess_op_codes()
|
|||||||
add_header_line("}");
|
add_header_line("}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (msl_options.emulate_cube_array)
|
||||||
|
{
|
||||||
|
add_header_line("static inline __attribute__((always_inline)) float3 spvCubemapTo2DArrayFace(float3 P)");
|
||||||
|
add_header_line("{");
|
||||||
|
add_header_line(" float3 Coords = metal::abs(P.xyz);");
|
||||||
|
add_header_line(" float CubeFace = 0;");
|
||||||
|
add_header_line(" float ProjectionAxis = 0;");
|
||||||
|
add_header_line(" float u = 0;");
|
||||||
|
add_header_line(" float v = 0;");
|
||||||
|
add_header_line(" if(Coords.x >= Coords.y && Coords.x >= Coords.z)");
|
||||||
|
add_header_line(" {");
|
||||||
|
add_header_line(" CubeFace = P.x >= 0 ? 0 : 1;");
|
||||||
|
add_header_line(" ProjectionAxis = Coords.x;");
|
||||||
|
add_header_line(" u = P.x >= 0 ? -P.z : P.z;");
|
||||||
|
add_header_line(" v = -P.y;");
|
||||||
|
add_header_line(" }");
|
||||||
|
add_header_line(" else if(Coords.y >= Coords.x && Coords.y >= Coords.z)");
|
||||||
|
add_header_line(" {");
|
||||||
|
add_header_line(" CubeFace = P.y >= 0 ? 2 : 3;");
|
||||||
|
add_header_line(" ProjectionAxis = Coords.y;");
|
||||||
|
add_header_line(" u = P.x;");
|
||||||
|
add_header_line(" v = P.y >= 0 ? P.z : -P.z;");
|
||||||
|
add_header_line(" }");
|
||||||
|
add_header_line(" else");
|
||||||
|
add_header_line(" {");
|
||||||
|
add_header_line(" CubeFace = P.z >= 0 ? 4 : 5;");
|
||||||
|
add_header_line(" ProjectionAxis = Coords.z;");
|
||||||
|
add_header_line(" u = P.z >= 0 ? P.x : -P.x;");
|
||||||
|
add_header_line(" v = -P.y;");
|
||||||
|
add_header_line(" }");
|
||||||
|
add_header_line(" u = 0.5 * (u/ProjectionAxis + 1);");
|
||||||
|
add_header_line(" v = 0.5 * (v/ProjectionAxis + 1);");
|
||||||
|
add_header_line(" return float3(u, v, CubeFace);");
|
||||||
|
add_header_line("}");
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnsafeArray
|
||||||
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("{");
|
||||||
@ -5673,7 +5718,11 @@ void CompilerMSL::emit_instruction(const Instruction &instruction)
|
|||||||
expr += ", " + img_exp + ".get_depth(" + lod + ")";
|
expr += ", " + img_exp + ".get_depth(" + lod + ")";
|
||||||
|
|
||||||
if (img_is_array)
|
if (img_is_array)
|
||||||
|
{
|
||||||
expr += ", " + img_exp + ".get_array_size()";
|
expr += ", " + img_exp + ".get_array_size()";
|
||||||
|
if (img_dim == DimCube && msl_options.emulate_cube_array)
|
||||||
|
expr += " / 6";
|
||||||
|
}
|
||||||
|
|
||||||
expr += ")";
|
expr += ")";
|
||||||
|
|
||||||
@ -7300,6 +7349,18 @@ string CompilerMSL::to_function_args(uint32_t img, const SPIRType &imgtype, bool
|
|||||||
|
|
||||||
if (!farg_str.empty())
|
if (!farg_str.empty())
|
||||||
farg_str += ", ";
|
farg_str += ", ";
|
||||||
|
|
||||||
|
if (imgtype.image.arrayed && msl_options.emulate_cube_array)
|
||||||
|
{
|
||||||
|
farg_str += "spvCubemapTo2DArrayFace(" + tex_coords + ").xy";
|
||||||
|
|
||||||
|
if (is_cube_fetch)
|
||||||
|
farg_str += ", uint(" + to_extract_component_expression(coord, 2) + ")";
|
||||||
|
else
|
||||||
|
farg_str += ", uint(spvCubemapTo2DArrayFace(" + tex_coords + ").z) + (uint(" + to_extract_component_expression(coord, 2) + ") * 6u)";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
farg_str += tex_coords;
|
farg_str += tex_coords;
|
||||||
|
|
||||||
// If fetch from cube, add face explicitly
|
// If fetch from cube, add face explicitly
|
||||||
@ -7319,9 +7380,8 @@ string CompilerMSL::to_function_args(uint32_t img, const SPIRType &imgtype, bool
|
|||||||
if (imgtype.image.dim == DimCube && is_fetch)
|
if (imgtype.image.dim == DimCube && is_fetch)
|
||||||
farg_str += ", uint(" + to_extract_component_expression(coord, 2) + ") / 6u";
|
farg_str += ", uint(" + to_extract_component_expression(coord, 2) + ") / 6u";
|
||||||
else
|
else
|
||||||
farg_str += ", uint(" +
|
farg_str += ", uint(" + round_fp_tex_coords(to_extract_component_expression(coord, alt_coord_component), coord_is_fp) + ")";
|
||||||
round_fp_tex_coords(to_extract_component_expression(coord, alt_coord_component), coord_is_fp) +
|
}
|
||||||
")";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Depth compare reference value
|
// Depth compare reference value
|
||||||
@ -7426,6 +7486,9 @@ string CompilerMSL::to_function_args(uint32_t img, const SPIRType &imgtype, bool
|
|||||||
grad_opt = "3d";
|
grad_opt = "3d";
|
||||||
break;
|
break;
|
||||||
case DimCube:
|
case DimCube:
|
||||||
|
if (imgtype.image.arrayed && msl_options.emulate_cube_array)
|
||||||
|
grad_opt = "2d";
|
||||||
|
else
|
||||||
grad_opt = "cube";
|
grad_opt = "cube";
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -10366,7 +10429,10 @@ string CompilerMSL::image_type_glsl(const SPIRType &type, uint32_t id)
|
|||||||
img_type_name += "depth3d_unsupported_by_metal";
|
img_type_name += "depth3d_unsupported_by_metal";
|
||||||
break;
|
break;
|
||||||
case DimCube:
|
case DimCube:
|
||||||
|
if (!msl_options.emulate_cube_array)
|
||||||
img_type_name += (img_type.arrayed ? "depthcube_array" : "depthcube");
|
img_type_name += (img_type.arrayed ? "depthcube_array" : "depthcube");
|
||||||
|
else
|
||||||
|
img_type_name += (img_type.arrayed ? "depth2d_array" : "depthcube");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
img_type_name += "unknown_depth_texture_type";
|
img_type_name += "unknown_depth_texture_type";
|
||||||
@ -10416,7 +10482,10 @@ string CompilerMSL::image_type_glsl(const SPIRType &type, uint32_t id)
|
|||||||
img_type_name += "texture3d";
|
img_type_name += "texture3d";
|
||||||
break;
|
break;
|
||||||
case DimCube:
|
case DimCube:
|
||||||
|
if (!msl_options.emulate_cube_array)
|
||||||
img_type_name += (img_type.arrayed ? "texturecube_array" : "texturecube");
|
img_type_name += (img_type.arrayed ? "texturecube_array" : "texturecube");
|
||||||
|
else
|
||||||
|
img_type_name += (img_type.arrayed ? "texture2d_array" : "texturecube");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
img_type_name += "unknown_texture_type";
|
img_type_name += "unknown_texture_type";
|
||||||
|
@ -301,6 +301,10 @@ public:
|
|||||||
|
|
||||||
bool invariant_float_math = false;
|
bool invariant_float_math = false;
|
||||||
|
|
||||||
|
/* UE Change Begin: Emulate texturecube_array with texture2d_array for iOS where this type is not available */
|
||||||
|
bool emulate_cube_array = false;
|
||||||
|
/* UE Change End: Emulate texturecube_array with texture2d_array for iOS where this type is not available */
|
||||||
|
|
||||||
// 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