Add support for int64/uint64 in GLSL.

This commit is contained in:
Hans-Kristian Arntzen 2016-07-27 11:27:00 +02:00
parent fa0255c43b
commit fc2230ffff
7 changed files with 189 additions and 2 deletions

View File

@ -0,0 +1,50 @@
#version 450
#extension GL_ARB_gpu_shader_int64 : require
layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
struct M0
{
int64_t v;
i64vec2 b[2];
uint64_t c;
uint64_t d[5];
};
layout(binding = 0, std430) buffer SSBO0
{
i64vec4 a;
M0 m0;
} ssbo_0;
layout(binding = 1, std430) buffer SSBO1
{
u64vec4 b;
M0 m0;
} ssbo_1;
layout(binding = 2, std430) buffer SSBO2
{
int64_t a[4];
i64vec2 b[4];
} ssbo_2;
layout(binding = 3, std140) buffer SSBO3
{
int64_t a[4];
i64vec2 b[4];
} ssbo_3;
void main()
{
ssbo_0.a = (ssbo_0.a + i64vec4(10l, 20l, 30l, 40l));
ssbo_1.b = (ssbo_1.b + u64vec4(999999999999999999ul, 8888888888888888ul, 77777777777777777ul, 6666666666666666ul));
ssbo_0.a = (ssbo_0.a + i64vec4(20l));
ssbo_0.a = abs((ssbo_0.a + i64vec4(ssbo_1.b)));
ssbo_0.a = (ssbo_0.a + i64vec4(1l));
ssbo_1.b = (ssbo_1.b + u64vec4(i64vec4(1l)));
ssbo_0.a = (ssbo_0.a - i64vec4(1l));
ssbo_1.b = (ssbo_1.b - u64vec4(i64vec4(1l)));
ssbo_1.b = doubleBitsToUint64(int64BitsToDouble(ssbo_0.a));
ssbo_0.a = doubleBitsToInt64(uint64BitsToDouble(ssbo_1.b));
}

View File

@ -0,0 +1,52 @@
#version 450
#extension GL_ARB_gpu_shader_int64 : require
layout(local_size_x = 1) in;
struct M0
{
int64_t v;
i64vec2 b[2];
uint64_t c;
uint64_t d[5];
};
// Test buffer layout handling.
layout(std430, binding = 0) buffer SSBO0
{
i64vec4 a;
M0 m0;
} ssbo_0;
layout(std430, binding = 1) buffer SSBO1
{
u64vec4 b;
M0 m0;
} ssbo_1;
layout(std430, binding = 2) buffer SSBO2
{
int64_t a[4];
i64vec2 b[4];
} ssbo_2;
layout(std140, binding = 3) buffer SSBO3
{
int64_t a[4];
i64vec2 b[4];
} ssbo_3;
void main()
{
ssbo_0.a += i64vec4(10, 20, 30, 40);
ssbo_1.b += u64vec4(999999999999999999ul, 8888888888888888ul, 77777777777777777ul, 6666666666666666ul);
ssbo_0.a += 20;
ssbo_0.a = abs(ssbo_0.a + i64vec4(ssbo_1.b));
ssbo_0.a++;
ssbo_1.b++;
ssbo_0.a--;
ssbo_1.b--;
ssbo_1.b = doubleBitsToUint64(int64BitsToDouble(ssbo_0.a));
ssbo_0.a = doubleBitsToInt64(uint64BitsToDouble(ssbo_1.b));
}

View File

@ -164,6 +164,8 @@ struct SPIRType : IVariant
Char,
Int,
UInt,
Int64,
UInt64,
AtomicCounter,
Float,
Double,

View File

@ -274,6 +274,7 @@ string CompilerCPP::compile()
options.version = 450;
backend.float_literal_suffix = true;
backend.double_literal_suffix = false;
backend.long_long_literal_suffix = true;
backend.uint32_t_literal_suffix = true;
backend.basic_int_type = "int32_t";
backend.basic_uint_type = "uint32_t";

View File

@ -1040,7 +1040,8 @@ void Compiler::parse(const Instruction &instruction)
uint32_t id = ops[0];
uint32_t width = ops[1];
auto &type = set<SPIRType>(id);
type.basetype = ops[2] ? SPIRType::Int : SPIRType::UInt;
type.basetype =
ops[2] ? (width > 32 ? SPIRType::Int64 : SPIRType::Int) : (width > 32 ? SPIRType::UInt64 : SPIRType::UInt);
type.width = width;
break;
}
@ -1268,7 +1269,7 @@ void Compiler::parse(const Instruction &instruction)
{
uint32_t id = ops[1];
auto &type = get<SPIRType>(ops[0]);
if (type.basetype == SPIRType::Double)
if (type.width > 32)
set<SPIRConstant>(id, ops[0], ops[2] | (uint64_t(ops[3]) << 32)).specialization = op == OpSpecConstant;
else
set<SPIRConstant>(id, ops[0], ops[2]).specialization = op == OpSpecConstant;

View File

@ -190,6 +190,14 @@ void CompilerGLSL::find_static_extensions()
if (!options.es && options.version < 400)
require_extension("GL_ARB_gpu_shader_fp64");
}
if (type.basetype == SPIRType::Int64 || type.basetype == SPIRType::UInt64)
{
if (options.es)
throw CompilerError("64-bit integers not supported in ES profile.");
if (!options.es)
require_extension("GL_ARB_gpu_shader_int64");
}
}
}
}
@ -604,6 +612,8 @@ uint32_t CompilerGLSL::type_to_std430_base_size(const SPIRType &type)
switch (type.basetype)
{
case SPIRType::Double:
case SPIRType::Int64:
case SPIRType::UInt64:
return 8;
default:
return 4;
@ -1397,6 +1407,54 @@ string CompilerGLSL::constant_expression_vector(const SPIRConstant &c, uint32_t
}
break;
case SPIRType::Int64:
if (splat)
{
res += convert_to_string(c.scalar_i64(vector, 0));
if (backend.long_long_literal_suffix)
res += "ll";
else
res += "l";
}
else
{
for (uint32_t i = 0; i < c.vector_size(); i++)
{
res += convert_to_string(c.scalar_i64(vector, i));
if (backend.long_long_literal_suffix)
res += "ll";
else
res += "l";
if (i + 1 < c.vector_size())
res += ", ";
}
}
break;
case SPIRType::UInt64:
if (splat)
{
res += convert_to_string(c.scalar_u64(vector, 0));
if (backend.long_long_literal_suffix)
res += "ull";
else
res += "ul";
}
else
{
for (uint32_t i = 0; i < c.vector_size(); i++)
{
res += convert_to_string(c.scalar_u64(vector, i));
if (backend.long_long_literal_suffix)
res += "ull";
else
res += "ul";
if (i + 1 < c.vector_size())
res += ", ";
}
}
break;
case SPIRType::UInt:
if (splat)
{
@ -2288,16 +2346,28 @@ string CompilerGLSL::bitcast_glsl_op(const SPIRType &out_type, const SPIRType &i
{
if (out_type.basetype == SPIRType::UInt && in_type.basetype == SPIRType::Int)
return type_to_glsl(out_type);
else if (out_type.basetype == SPIRType::UInt64 && in_type.basetype == SPIRType::Int64)
return type_to_glsl(out_type);
else if (out_type.basetype == SPIRType::UInt && in_type.basetype == SPIRType::Float)
return "floatBitsToUint";
else if (out_type.basetype == SPIRType::Int && in_type.basetype == SPIRType::UInt)
return type_to_glsl(out_type);
else if (out_type.basetype == SPIRType::Int64 && in_type.basetype == SPIRType::UInt64)
return type_to_glsl(out_type);
else if (out_type.basetype == SPIRType::Int && in_type.basetype == SPIRType::Float)
return "floatBitsToInt";
else if (out_type.basetype == SPIRType::Float && in_type.basetype == SPIRType::UInt)
return "uintBitsToFloat";
else if (out_type.basetype == SPIRType::Float && in_type.basetype == SPIRType::Int)
return "intBitsToFloat";
else if (out_type.basetype == SPIRType::Int64 && in_type.basetype == SPIRType::Double)
return "doubleBitsToInt64";
else if (out_type.basetype == SPIRType::UInt64 && in_type.basetype == SPIRType::Double)
return "doubleBitsToUint64";
else if (out_type.basetype == SPIRType::Double && in_type.basetype == SPIRType::Int64)
return "int64BitsToDouble";
else if (out_type.basetype == SPIRType::Double && in_type.basetype == SPIRType::UInt64)
return "uint64BitsToDouble";
else
return "";
}
@ -4308,6 +4378,10 @@ string CompilerGLSL::type_to_glsl(const SPIRType &type)
return "float";
case SPIRType::Double:
return "double";
case SPIRType::Int64:
return "int64_t";
case SPIRType::UInt64:
return "uint64_t";
default:
return "???";
}
@ -4326,6 +4400,10 @@ string CompilerGLSL::type_to_glsl(const SPIRType &type)
return join("vec", type.vecsize);
case SPIRType::Double:
return join("dvec", type.vecsize);
case SPIRType::Int64:
return join("i64vec", type.vecsize);
case SPIRType::UInt64:
return join("u64vec", type.vecsize);
default:
return "???";
}
@ -4344,6 +4422,7 @@ string CompilerGLSL::type_to_glsl(const SPIRType &type)
return join("mat", type.vecsize);
case SPIRType::Double:
return join("dmat", type.vecsize);
// Matrix types not supported for int64/uint64.
default:
return "???";
}
@ -4362,6 +4441,7 @@ string CompilerGLSL::type_to_glsl(const SPIRType &type)
return join("mat", type.columns, "x", type.vecsize);
case SPIRType::Double:
return join("dmat", type.columns, "x", type.vecsize);
// Matrix types not supported for int64/uint64.
default:
return "???";
}

View File

@ -220,6 +220,7 @@ protected:
bool float_literal_suffix = false;
bool double_literal_suffix = true;
bool uint32_t_literal_suffix = true;
bool long_long_literal_suffix = false;
const char *basic_int_type = "int";
const char *basic_uint_type = "uint";
bool swizzle_is_function = false;