Support special float constants (NaN/Inf).
This commit is contained in:
Родитель
3f64f56037
Коммит
047ad7df0f
|
@ -0,0 +1,19 @@
|
|||
static float3 FragColor;
|
||||
|
||||
struct SPIRV_Cross_Output
|
||||
{
|
||||
float3 FragColor : SV_Target0;
|
||||
};
|
||||
|
||||
void frag_main()
|
||||
{
|
||||
FragColor = float3(asfloat(0x7f800000u), asfloat(0xff800000u), asfloat(0xffc00000u));
|
||||
}
|
||||
|
||||
SPIRV_Cross_Output main()
|
||||
{
|
||||
frag_main();
|
||||
SPIRV_Cross_Output stage_output;
|
||||
stage_output.FragColor = FragColor;
|
||||
return stage_output;
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
#include <metal_stdlib>
|
||||
#include <simd/simd.h>
|
||||
|
||||
using namespace metal;
|
||||
|
||||
struct main0_out
|
||||
{
|
||||
float3 FragColor [[color(0)]];
|
||||
};
|
||||
|
||||
fragment main0_out main0()
|
||||
{
|
||||
main0_out out = {};
|
||||
out.FragColor = float3(as_type<float>(0x7f800000u), as_type<float>(0xff800000u), as_type<float>(0xffc00000u));
|
||||
return out;
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
#version 450
|
||||
#extension GL_ARB_gpu_shader_int64 : require
|
||||
|
||||
layout(location = 0) out vec3 FragColor;
|
||||
layout(location = 0) flat in double vTmp;
|
||||
|
||||
void main()
|
||||
{
|
||||
FragColor = vec3(dvec3(uint64BitsToDouble(0x7ff0000000000000ul), uint64BitsToDouble(0xfff0000000000000ul), uint64BitsToDouble(0xfff8000000000000ul)) + dvec3(vTmp));
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
#version 310 es
|
||||
precision mediump float;
|
||||
precision highp int;
|
||||
|
||||
layout(location = 0) out highp vec3 FragColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
FragColor = vec3(uintBitsToFloat(0x7f800000u), uintBitsToFloat(0xff800000u), uintBitsToFloat(0xffc00000u));
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
static float3 FragColor;
|
||||
|
||||
struct SPIRV_Cross_Output
|
||||
{
|
||||
float3 FragColor : SV_Target0;
|
||||
};
|
||||
|
||||
void frag_main()
|
||||
{
|
||||
FragColor = float3(asfloat(0x7f800000u), asfloat(0xff800000u), asfloat(0xffc00000u));
|
||||
}
|
||||
|
||||
SPIRV_Cross_Output main()
|
||||
{
|
||||
frag_main();
|
||||
SPIRV_Cross_Output stage_output;
|
||||
stage_output.FragColor = FragColor;
|
||||
return stage_output;
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
#include <metal_stdlib>
|
||||
#include <simd/simd.h>
|
||||
|
||||
using namespace metal;
|
||||
|
||||
struct main0_out
|
||||
{
|
||||
float3 FragColor [[color(0)]];
|
||||
};
|
||||
|
||||
fragment main0_out main0()
|
||||
{
|
||||
main0_out out = {};
|
||||
out.FragColor = float3(as_type<float>(0x7f800000u), as_type<float>(0xff800000u), as_type<float>(0xffc00000u));
|
||||
return out;
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
#version 450
|
||||
#extension GL_ARB_gpu_shader_int64 : require
|
||||
|
||||
layout(location = 0) out vec3 FragColor;
|
||||
layout(location = 0) flat in double vTmp;
|
||||
|
||||
void main()
|
||||
{
|
||||
FragColor = vec3(dvec3(uint64BitsToDouble(0x7ff0000000000000ul), uint64BitsToDouble(0xfff0000000000000ul), uint64BitsToDouble(0xfff8000000000000ul)) + dvec3(vTmp));
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
#version 310 es
|
||||
precision mediump float;
|
||||
precision highp int;
|
||||
|
||||
layout(location = 0) out highp vec3 FragColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
FragColor = vec3(uintBitsToFloat(0x7f800000u), uintBitsToFloat(0xff800000u), uintBitsToFloat(0xffc00000u));
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
#version 310 es
|
||||
precision highp float;
|
||||
|
||||
const float posinf = 1.0 / 0.0;
|
||||
const float neginf = -1.0 / 0.0;
|
||||
const float nan = 0.0 / 0.0;
|
||||
|
||||
layout(location = 0) out vec3 FragColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
FragColor = vec3(posinf, neginf, nan);
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
#version 310 es
|
||||
precision highp float;
|
||||
|
||||
const float posinf = 1.0 / 0.0;
|
||||
const float neginf = -1.0 / 0.0;
|
||||
const float nan = 0.0 / 0.0;
|
||||
|
||||
layout(location = 0) out vec3 FragColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
FragColor = vec3(posinf, neginf, nan);
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
#version 450
|
||||
|
||||
const double posinf = 1.0lf / 0.0lf;
|
||||
const double neginf = -1.0lf / 0.0lf;
|
||||
const double nan = 0.0lf / 0.0lf;
|
||||
|
||||
layout(location = 0) out vec3 FragColor;
|
||||
layout(location = 0) flat in double vTmp;
|
||||
|
||||
void main()
|
||||
{
|
||||
FragColor = vec3(dvec3(posinf, neginf, nan) + vTmp);
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
#version 310 es
|
||||
precision highp float;
|
||||
|
||||
const float posinf = 1.0 / 0.0;
|
||||
const float neginf = -1.0 / 0.0;
|
||||
const float nan = 0.0 / 0.0;
|
||||
|
||||
layout(location = 0) out vec3 FragColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
FragColor = vec3(posinf, neginf, nan);
|
||||
}
|
||||
|
|
@ -125,6 +125,8 @@ inline std::string convert_to_string(T &&t)
|
|||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
// sprintf warning.
|
||||
// We cannot rely on snprintf existing because, ..., MSVC.
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4996)
|
||||
#endif
|
||||
|
|
167
spirv_glsl.cpp
167
spirv_glsl.cpp
|
@ -19,6 +19,7 @@
|
|||
#include "spirv_common.hpp"
|
||||
#include <algorithm>
|
||||
#include <assert.h>
|
||||
#include <cmath>
|
||||
#include <utility>
|
||||
|
||||
using namespace spv;
|
||||
|
@ -371,6 +372,7 @@ string CompilerGLSL::compile()
|
|||
if (options.vulkan_semantics)
|
||||
backend.allow_precision_qualifiers = true;
|
||||
backend.force_gl_in_out_block = true;
|
||||
backend.supports_extensions = true;
|
||||
|
||||
// Scan the SPIR-V to find trivial uses of extensions.
|
||||
find_static_extensions();
|
||||
|
@ -2529,6 +2531,149 @@ string CompilerGLSL::constant_expression(const SPIRConstant &c)
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef _MSC_VER
|
||||
// sprintf warning.
|
||||
// We cannot rely on snprintf existing because, ..., MSVC.
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4996)
|
||||
#endif
|
||||
|
||||
string CompilerGLSL::convert_float_to_string(const SPIRConstant &c, uint32_t col, uint32_t row)
|
||||
{
|
||||
string res;
|
||||
float float_value = c.scalar_f32(col, row);
|
||||
|
||||
if (isnan(float_value) || isinf(float_value))
|
||||
{
|
||||
// Use special representation.
|
||||
if (!is_legacy())
|
||||
{
|
||||
SPIRType out_type;
|
||||
SPIRType in_type;
|
||||
out_type.basetype = SPIRType::Float;
|
||||
in_type.basetype = SPIRType::UInt;
|
||||
out_type.vecsize = 1;
|
||||
in_type.vecsize = 1;
|
||||
out_type.width = 32;
|
||||
in_type.width = 32;
|
||||
|
||||
char print_buffer[32];
|
||||
sprintf(print_buffer, "0x%xu", c.scalar(col, row));
|
||||
res = join(bitcast_glsl_op(out_type, in_type), "(", print_buffer, ")");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (float_value == numeric_limits<float>::infinity())
|
||||
{
|
||||
if (backend.float_literal_suffix)
|
||||
res = "(1.0f / 0.0f)";
|
||||
else
|
||||
res = "(1.0 / 0.0)";
|
||||
}
|
||||
else if (float_value == -numeric_limits<float>::infinity())
|
||||
{
|
||||
if (backend.float_literal_suffix)
|
||||
res = "(-1.0f / 0.0f)";
|
||||
else
|
||||
res = "(-1.0 / 0.0)";
|
||||
}
|
||||
else if (isnan(float_value))
|
||||
{
|
||||
if (backend.float_literal_suffix)
|
||||
res = "(0.0f / 0.0f)";
|
||||
else
|
||||
res = "(0.0 / 0.0)";
|
||||
}
|
||||
else
|
||||
SPIRV_CROSS_THROW("Cannot represent non-finite floating point constant.");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
res = convert_to_string(float_value);
|
||||
if (backend.float_literal_suffix)
|
||||
res += "f";
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
std::string CompilerGLSL::convert_double_to_string(const SPIRConstant &c, uint32_t col, uint32_t row)
|
||||
{
|
||||
string res;
|
||||
float double_value = c.scalar_f64(col, row);
|
||||
|
||||
if (isnan(double_value) || isinf(double_value))
|
||||
{
|
||||
// Use special representation.
|
||||
if (!is_legacy())
|
||||
{
|
||||
SPIRType out_type;
|
||||
SPIRType in_type;
|
||||
out_type.basetype = SPIRType::Double;
|
||||
in_type.basetype = SPIRType::UInt64;
|
||||
out_type.vecsize = 1;
|
||||
in_type.vecsize = 1;
|
||||
out_type.width = 64;
|
||||
in_type.width = 64;
|
||||
|
||||
uint64_t u64_value = c.scalar_u64(col, row);
|
||||
|
||||
if (options.es)
|
||||
SPIRV_CROSS_THROW("64-bit integers/float not supported in ES profile.");
|
||||
require_extension("GL_ARB_gpu_shader_int64");
|
||||
|
||||
char print_buffer[64];
|
||||
sprintf(print_buffer, "0x%llx%s", static_cast<unsigned long long>(u64_value),
|
||||
backend.long_long_literal_suffix ? "ull" : "ul");
|
||||
res = join(bitcast_glsl_op(out_type, in_type), "(", print_buffer, ")");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (options.es)
|
||||
SPIRV_CROSS_THROW("FP64 not supported in ES profile.");
|
||||
if (options.version < 400)
|
||||
require_extension("GL_ARB_gpu_shader_fp64");
|
||||
|
||||
if (double_value == numeric_limits<double>::infinity())
|
||||
{
|
||||
if (backend.double_literal_suffix)
|
||||
res = "(1.0lf / 0.0lf)";
|
||||
else
|
||||
res = "(1.0 / 0.0)";
|
||||
}
|
||||
else if (double_value == -numeric_limits<double>::infinity())
|
||||
{
|
||||
if (backend.double_literal_suffix)
|
||||
res = "(-1.0lf / 0.0lf)";
|
||||
else
|
||||
res = "(-1.0 / 0.0)";
|
||||
}
|
||||
else if (isnan(double_value))
|
||||
{
|
||||
if (backend.double_literal_suffix)
|
||||
res = "(0.0lf / 0.0lf)";
|
||||
else
|
||||
res = "(0.0 / 0.0)";
|
||||
}
|
||||
else
|
||||
SPIRV_CROSS_THROW("Cannot represent non-finite floating point constant.");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
res = convert_to_string(double_value);
|
||||
if (backend.double_literal_suffix)
|
||||
res += "lf";
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
string CompilerGLSL::constant_expression_vector(const SPIRConstant &c, uint32_t vector)
|
||||
{
|
||||
auto type = get<SPIRType>(c.constant_type);
|
||||
|
@ -2595,10 +2740,7 @@ string CompilerGLSL::constant_expression_vector(const SPIRConstant &c, uint32_t
|
|||
case SPIRType::Float:
|
||||
if (splat || swizzle_splat)
|
||||
{
|
||||
res += convert_to_string(c.scalar_f32(vector, 0));
|
||||
if (backend.float_literal_suffix)
|
||||
res += "f";
|
||||
|
||||
res += convert_float_to_string(c, vector, 0);
|
||||
if (swizzle_splat)
|
||||
res = remap_swizzle(get<SPIRType>(c.constant_type), 1, res);
|
||||
}
|
||||
|
@ -2609,10 +2751,8 @@ string CompilerGLSL::constant_expression_vector(const SPIRConstant &c, uint32_t
|
|||
if (options.vulkan_semantics && c.vector_size() > 1 && c.specialization_constant_id(vector, i) != 0)
|
||||
res += to_name(c.specialization_constant_id(vector, i));
|
||||
else
|
||||
res += convert_to_string(c.scalar_f32(vector, i));
|
||||
res += convert_float_to_string(c, vector, i);
|
||||
|
||||
if (backend.float_literal_suffix)
|
||||
res += "f";
|
||||
if (i + 1 < c.vector_size())
|
||||
res += ", ";
|
||||
}
|
||||
|
@ -2622,10 +2762,7 @@ string CompilerGLSL::constant_expression_vector(const SPIRConstant &c, uint32_t
|
|||
case SPIRType::Double:
|
||||
if (splat || swizzle_splat)
|
||||
{
|
||||
res += convert_to_string(c.scalar_f64(vector, 0));
|
||||
if (backend.double_literal_suffix)
|
||||
res += "lf";
|
||||
|
||||
res += convert_double_to_string(c, vector, 0);
|
||||
if (swizzle_splat)
|
||||
res = remap_swizzle(get<SPIRType>(c.constant_type), 1, res);
|
||||
}
|
||||
|
@ -2636,11 +2773,7 @@ string CompilerGLSL::constant_expression_vector(const SPIRConstant &c, uint32_t
|
|||
if (options.vulkan_semantics && c.vector_size() > 1 && c.specialization_constant_id(vector, i) != 0)
|
||||
res += to_name(c.specialization_constant_id(vector, i));
|
||||
else
|
||||
{
|
||||
res += convert_to_string(c.scalar_f64(vector, i));
|
||||
if (backend.double_literal_suffix)
|
||||
res += "lf";
|
||||
}
|
||||
res += convert_double_to_string(c, vector, i);
|
||||
|
||||
if (i + 1 < c.vector_size())
|
||||
res += ", ";
|
||||
|
@ -7672,7 +7805,7 @@ bool CompilerGLSL::has_extension(const std::string &ext) const
|
|||
|
||||
void CompilerGLSL::require_extension(const string &ext)
|
||||
{
|
||||
if (!has_extension(ext))
|
||||
if (backend.supports_extensions && !has_extension(ext))
|
||||
{
|
||||
forced_extensions.push_back(ext);
|
||||
force_recompile = true;
|
||||
|
|
|
@ -333,6 +333,7 @@ protected:
|
|||
bool force_gl_in_out_block = false;
|
||||
bool can_return_array = true;
|
||||
bool allow_truncated_access_chain = false;
|
||||
bool supports_extensions = false;
|
||||
} backend;
|
||||
|
||||
void emit_struct(SPIRType &type);
|
||||
|
@ -525,6 +526,9 @@ protected:
|
|||
const Instruction *get_next_instruction_in_block(const Instruction &instr);
|
||||
static uint32_t mask_relevant_memory_semantics(uint32_t semantics);
|
||||
|
||||
std::string convert_float_to_string(const SPIRConstant &value, uint32_t col, uint32_t row);
|
||||
std::string convert_double_to_string(const SPIRConstant &value, uint32_t col, uint32_t row);
|
||||
|
||||
private:
|
||||
void init()
|
||||
{
|
||||
|
|
Загрузка…
Ссылка в новой задаче