Some compat fixes for MSL and Half.

This commit is contained in:
Hans-Kristian Arntzen 2018-03-06 17:07:59 +01:00
parent 547278da12
commit d9da2db442
3 changed files with 27 additions and 9 deletions

View File

@ -2592,16 +2592,16 @@ string CompilerGLSL::convert_half_to_string(const SPIRConstant &c, uint32_t col,
{
// There is no uintBitsToFloat for 16-bit, so have to rely on legacy fallback here.
if (float_value == numeric_limits<float>::infinity())
res = "(1.0hf / 0.0hf)";
res = join("(1.0", backend.half_literal_suffix, " / 0.0", backend.half_literal_suffix, ")");
else if (float_value == -numeric_limits<float>::infinity())
res = "(-1.0hf / 0.0hf)";
res = join("(-1.0", backend.half_literal_suffix, " / 0.0", backend.half_literal_suffix, ")");
else if (std::isnan(float_value))
res = "(0.0hf / 0.0hf)";
res = join("(0.0", backend.half_literal_suffix, " / 0.0", backend.half_literal_suffix, ")");
else
SPIRV_CROSS_THROW("Cannot represent non-finite floating point constant.");
}
else
res = convert_to_string(float_value) + "hf";
res = convert_to_string(float_value) + backend.half_literal_suffix;
return res;
}

View File

@ -319,6 +319,7 @@ protected:
bool long_long_literal_suffix = false;
const char *basic_int_type = "int";
const char *basic_uint_type = "uint";
const char *half_literal_suffix = "hf";
bool swizzle_is_function = false;
bool shared_is_implied = false;
bool flexible_member_array_supported = true;

View File

@ -25,7 +25,12 @@ using namespace spv;
using namespace spirv_cross;
using namespace std;
static const uint32_t k_unknown_location = ~0;
static const uint32_t k_unknown_location = ~0u;
static bool type_is_floating_point(const SPIRType &type)
{
return type.basetype == SPIRType::Half || type.basetype == SPIRType::Float || type.basetype == SPIRType::Double;
}
CompilerMSL::CompilerMSL(vector<uint32_t> spirv_, vector<MSLVertexAttr> *p_vtx_attrs,
vector<MSLResourceBinding> *p_res_bindings)
@ -114,6 +119,7 @@ string CompilerMSL::compile()
CompilerGLSL::options.es = false;
CompilerGLSL::options.version = 450;
backend.float_literal_suffix = false;
backend.half_literal_suffix = "h";
backend.uint32_t_literal_suffix = true;
backend.basic_int_type = "int";
backend.basic_uint_type = "uint";
@ -597,7 +603,7 @@ uint32_t CompilerMSL::add_interface_block(StorageClass storage)
else if (type.basetype == SPIRType::Boolean || type.basetype == SPIRType::Char ||
type.basetype == SPIRType::Int || type.basetype == SPIRType::UInt ||
type.basetype == SPIRType::Int64 || type.basetype == SPIRType::UInt64 ||
type.basetype == SPIRType::Float || type.basetype == SPIRType::Double ||
type_is_floating_point(type) ||
type.basetype == SPIRType::Boolean)
{
bool is_builtin = is_builtin_variable(*p_var);
@ -1472,6 +1478,12 @@ void CompilerMSL::emit_instruction(const Instruction &instruction)
UFOP(dfdy);
break;
case OpFwidth:
case OpFwidthCoarse:
case OpFwidthFine:
UFOP(fwidth);
break;
// Bitfield
case OpBitFieldInsert:
QFOP(insert_bits);
@ -2257,7 +2269,7 @@ string CompilerMSL::to_function_args(uint32_t img, const SPIRType &imgtype, bool
bool forward = should_forward(coord);
auto coord_expr = to_enclosed_expression(coord);
auto &coord_type = expression_type(coord);
bool coord_is_fp = (coord_type.basetype == SPIRType::Float) || (coord_type.basetype == SPIRType::Double);
bool coord_is_fp = type_is_floating_point(coord_type);
bool is_cube_fetch = false;
string tex_coords = coord_expr;
@ -3311,8 +3323,11 @@ string CompilerMSL::type_to_glsl(const SPIRType &type, uint32_t id)
case SPIRType::UInt64:
type_name = "size_t";
break;
case SPIRType::Half:
type_name = "half";
break;
case SPIRType::Float:
type_name = (type.width == 16 ? "half" : "float");
type_name = "float";
break;
case SPIRType::Double:
type_name = "double"; // Currently unsupported
@ -3449,7 +3464,9 @@ string CompilerMSL::bitcast_glsl_op(const SPIRType &out_type, const SPIRType &in
(out_type.basetype == SPIRType::Int64 && in_type.basetype == SPIRType::Double) ||
(out_type.basetype == SPIRType::UInt64 && in_type.basetype == SPIRType::Double) ||
(out_type.basetype == SPIRType::Double && in_type.basetype == SPIRType::Int64) ||
(out_type.basetype == SPIRType::Double && in_type.basetype == SPIRType::UInt64))
(out_type.basetype == SPIRType::Double && in_type.basetype == SPIRType::UInt64) ||
(out_type.basetype == SPIRType::Half && in_type.basetype == SPIRType::UInt) ||
(out_type.basetype == SPIRType::UInt && in_type.basetype == SPIRType::Half))
return "as_type<" + type_to_glsl(out_type) + ">";
return "";