Support constants of 16-bit integral type in GLSL and MSL.

Constants of 8-bit type aren't supported in GLSL, since there's no
extension letting you use them.
This commit is contained in:
Chip Davis 2018-11-02 14:39:55 -05:00
parent 117ccf407c
commit ca4744ab72
10 changed files with 200 additions and 0 deletions

View File

@ -0,0 +1,21 @@
#include <metal_stdlib>
#include <simd/simd.h>
using namespace metal;
struct main0_out
{
half foo [[color(0)]];
short bar [[color(1)]];
ushort baz [[color(2)]];
};
fragment main0_out main0()
{
main0_out out = {};
out.foo = 1.0h;
out.bar = 2;
out.baz = 3u;
return out;
}

View File

@ -0,0 +1,29 @@
#version 450
#if defined(GL_AMD_gpu_shader_half_float)
#extension GL_AMD_gpu_shader_half_float : require
#elif defined(GL_NV_gpu_shader5)
#extension GL_NV_gpu_shader5 : require
#elif defined(GL_EXT_shader_16bit_storage)
#extension GL_EXT_shader_16bit_storage : require
#else
#error No extension available for FP16.
#endif
#if defined(GL_AMD_gpu_shader_int16)
#extension GL_AMD_gpu_shader_int16 : require
#elif defined(GL_EXT_shader_16bit_storage)
#extension GL_EXT_shader_16bit_storage : require
#else
#error No extension available for Int16.
#endif
layout(location = 0) out float16_t foo;
layout(location = 1) out int16_t bar;
layout(location = 2) out uint16_t baz;
void main()
{
foo = 1.0hf;
bar = 2s;
baz = 3us;
}

View File

@ -0,0 +1,21 @@
#include <metal_stdlib>
#include <simd/simd.h>
using namespace metal;
struct main0_out
{
half foo [[color(0)]];
short bar [[color(1)]];
ushort baz [[color(2)]];
};
fragment main0_out main0()
{
main0_out out = {};
out.foo = 1.0h;
out.bar = 2;
out.baz = 3u;
return out;
}

View File

@ -0,0 +1,29 @@
#version 450
#if defined(GL_AMD_gpu_shader_half_float)
#extension GL_AMD_gpu_shader_half_float : require
#elif defined(GL_NV_gpu_shader5)
#extension GL_NV_gpu_shader5 : require
#elif defined(GL_EXT_shader_16bit_storage)
#extension GL_EXT_shader_16bit_storage : require
#else
#error No extension available for FP16.
#endif
#if defined(GL_AMD_gpu_shader_int16)
#extension GL_AMD_gpu_shader_int16 : require
#elif defined(GL_EXT_shader_16bit_storage)
#extension GL_EXT_shader_16bit_storage : require
#else
#error No extension available for Int16.
#endif
layout(location = 0) out float16_t foo;
layout(location = 1) out int16_t bar;
layout(location = 2) out uint16_t baz;
void main()
{
foo = 1.0hf;
bar = 2s;
baz = 3us;
}

View File

@ -0,0 +1,14 @@
#version 450 core
#extension GL_AMD_gpu_shader_int16 : require
#extension GL_AMD_gpu_shader_half_float : require
layout(location = 0) out float16_t foo;
layout(location = 1) out int16_t bar;
layout(location = 2) out uint16_t baz;
void main() {
foo = 1.0hf;
bar = 2s;
baz = 3us;
}

View File

@ -0,0 +1,14 @@
#version 450 core
#extension GL_AMD_gpu_shader_int16 : require
#extension GL_AMD_gpu_shader_half_float : require
layout(location = 0) out float16_t foo;
layout(location = 1) out int16_t bar;
layout(location = 2) out uint16_t baz;
void main() {
foo = 1.0hf;
bar = 2s;
baz = 3us;
}

View File

@ -3351,6 +3351,72 @@ string CompilerGLSL::constant_expression_vector(const SPIRConstant &c, uint32_t
}
break;
case SPIRType::UShort:
if (splat)
{
res += convert_to_string(c.scalar(vector, 0));
if (is_legacy())
{
// Fake unsigned constant literals with signed ones if possible.
// Things like array sizes, etc, tend to be unsigned even though they could just as easily be signed.
if (c.scalar_i16(vector, 0) < 0)
SPIRV_CROSS_THROW("Tried to convert uint literal into int, but this made the literal negative.");
}
else if (backend.uint16_t_literal_suffix)
res += backend.uint16_t_literal_suffix;
}
else
{
for (uint32_t i = 0; i < c.vector_size(); i++)
{
if (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(vector, i));
if (is_legacy())
{
// Fake unsigned constant literals with signed ones if possible.
// Things like array sizes, etc, tend to be unsigned even though they could just as easily be signed.
if (c.scalar_i16(vector, i) < 0)
SPIRV_CROSS_THROW(
"Tried to convert uint literal into int, but this made the literal negative.");
}
else if (backend.uint16_t_literal_suffix)
res += backend.uint16_t_literal_suffix;
}
if (i + 1 < c.vector_size())
res += ", ";
}
}
break;
case SPIRType::Short:
if (splat)
{
res += convert_to_string(c.scalar_i16(vector, 0));
if (backend.int16_t_literal_suffix)
res += backend.int16_t_literal_suffix;
}
else
{
for (uint32_t i = 0; i < c.vector_size(); i++)
{
if (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_i16(vector, i));
if (backend.int16_t_literal_suffix)
res += backend.int16_t_literal_suffix;
}
if (i + 1 < c.vector_size())
res += ", ";
}
}
break;
case SPIRType::Boolean:
if (splat)
res += c.scalar(vector, 0) ? "true" : "false";

View File

@ -366,6 +366,8 @@ protected:
const char *basic_int16_type = "int16_t";
const char *basic_uint16_type = "uint16_t";
const char *half_literal_suffix = "hf";
const char *int16_t_literal_suffix = "s";
const char *uint16_t_literal_suffix = "us";
bool swizzle_is_function = false;
bool shared_is_implied = false;
bool flexible_member_array_supported = true;

View File

@ -4616,6 +4616,8 @@ string CompilerHLSL::compile()
backend.half_literal_suffix = nullptr;
backend.long_long_literal_suffix = true;
backend.uint32_t_literal_suffix = true;
backend.int16_t_literal_suffix = nullptr;
backend.uint16_t_literal_suffix = "u";
backend.basic_int_type = "int";
backend.basic_uint_type = "uint";
backend.swizzle_is_function = false;

View File

@ -390,6 +390,8 @@ string CompilerMSL::compile()
backend.float_literal_suffix = false;
backend.half_literal_suffix = "h";
backend.uint32_t_literal_suffix = true;
backend.int16_t_literal_suffix = nullptr;
backend.uint16_t_literal_suffix = "u";
backend.basic_int_type = "int";
backend.basic_uint_type = "uint";
backend.basic_int8_type = "char";