Commit 8ff43de8 by Rex Xu

Implement the extension GL_ARB_gpu_shader_int64

- Add new keyword int64_t/uint64_t/i64vec/u64vec. - Support 64-bit integer literals (dec/hex/oct). - Support built-in operators for 64-bit integer type. - Add implicit and explicit type conversion for 64-bit integer type. - Add new built-in functions defined in this extension.
parent 010e93fe
......@@ -606,7 +606,7 @@ Id Builder::findScalarConstant(Op typeClass, Op opcode, Id typeId, unsigned valu
return 0;
}
// Version of findScalarConstant (see above) for scalars that take two operands (e.g. a 'double').
// Version of findScalarConstant (see above) for scalars that take two operands (e.g. a 'double' or 'int64').
Id Builder::findScalarConstant(Op typeClass, Op opcode, Id typeId, unsigned v1, unsigned v2) const
{
Instruction* constant;
......@@ -711,6 +711,31 @@ Id Builder::makeIntConstant(Id typeId, unsigned value, bool specConstant)
return c->getResultId();
}
Id Builder::makeInt64Constant(Id typeId, unsigned long long value, bool specConstant)
{
Op opcode = specConstant ? OpSpecConstant : OpConstant;
unsigned op1 = value & 0xFFFFFFFF;
unsigned op2 = value >> 32;
// See if we already made it. Applies only to regular constants, because specialization constants
// must remain distinct for the purpose of applying a SpecId decoration.
if (! specConstant) {
Id existing = findScalarConstant(OpTypeInt, opcode, typeId, op1, op2);
if (existing)
return existing;
}
Instruction* c = new Instruction(getUniqueId(), typeId, opcode);
c->addImmediateOperand(op1);
c->addImmediateOperand(op2);
constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(c));
groupedConstants[OpTypeInt].push_back(c);
module.mapInstruction(c);
return c->getResultId();
}
Id Builder::makeFloatConstant(float f, bool specConstant)
{
Op opcode = specConstant ? OpSpecConstant : OpConstant;
......
......@@ -188,6 +188,8 @@ public:
Id makeBoolConstant(bool b, bool specConstant = false);
Id makeIntConstant(int i, bool specConstant = false) { return makeIntConstant(makeIntType(32), (unsigned)i, specConstant); }
Id makeUintConstant(unsigned u, bool specConstant = false) { return makeIntConstant(makeUintType(32), u, specConstant); }
Id makeInt64Constant(long long i, bool specConstant = false) { return makeInt64Constant(makeIntType(64), (unsigned long long)i, specConstant); }
Id makeUint64Constant(unsigned long long u, bool specConstant = false) { return makeInt64Constant(makeUintType(64), u, specConstant); }
Id makeFloatConstant(float f, bool specConstant = false);
Id makeDoubleConstant(double d, bool specConstant = false);
......@@ -533,6 +535,7 @@ public:
protected:
Id makeIntConstant(Id typeId, unsigned value, bool specConstant);
Id makeInt64Constant(Id typeId, unsigned long long value, bool specConstant);
Id findScalarConstant(Op typeClass, Op opcode, Id typeId, unsigned value) const;
Id findScalarConstant(Op typeClass, Op opcode, Id typeId, unsigned v1, unsigned v2) const;
Id findCompositeConstant(Op typeClass, std::vector<Id>& comps) const;
......
#version 450
#extension GL_ARB_gpu_shader_int64: enable
layout(binding = 0) uniform Uniforms
{
uint index;
};
layout(std140, binding = 1) uniform Block
{
i64vec3 i64v;
uint64_t u64;
} block;
void main()
{
}
void literal()
{
const int64_t i64Const[3] =
{
-0x1111111111111111l, // Hex
-1l, // Dec
040000000000l, // Oct
};
int64_t i64 = i64Const[index];
const uint64_t u64Const[] =
{
0xFFFFFFFFFFFFFFFFul, // Hex
4294967296UL, // Dec
077777777777ul, // Oct
};
uint64_t u64 = u64Const[index];
}
void typeCast()
{
bvec2 bv;
ivec2 iv;
uvec2 uv;
vec2 fv;
dvec2 dv;
i64vec2 i64v;
u64vec2 u64v;
i64v = i64vec2(bv); // bool -> int64
u64v = u64vec2(bv); // bool -> uint64
i64v = iv; // int -> int64
iv = ivec2(i64v); // int64 -> int
u64v = uv; // uint -> uint64
uv = uvec2(u64v); // uint64 -> uint
fv = vec2(i64v); // int64 -> float
dv = i64v; // int64 -> double
fv = vec2(u64v); // uint64 -> float
dv = u64v; // uint64 -> double
i64v = i64vec2(fv); // float -> int64
i64v = i64vec2(dv); // double -> int64
u64v = u64vec2(fv); // float -> uint64
u64v = u64vec2(dv); // double -> uint64
bv = bvec2(i64v); // int64 -> bool
bv = bvec2(u64v); // uint64 -> bool
u64v = i64v; // int64 -> uint64
i64v = i64vec2(u64v); // uint64 -> int64
uv = uvec2(i64v); // int64 -> uint
i64v = i64vec2(uv); // uint -> int64
iv = ivec2(u64v); // uint64 -> int
u64v = iv; // int -> uint64
}
void operators()
{
u64vec3 u64v;
int64_t i64;
uvec3 uv;
int i;
bool b;
// Unary
u64v++;
i64--;
++i64;
--u64v;
u64v = ~u64v;
i64 = +i64;
u64v = -u64v;
// Arithmetic
i64 += i64;
u64v -= u64v;
i64 *= i;
u64v /= uv;
u64v %= i;
u64v = u64v + uv;
i64 = i64 - i;
u64v = u64v * uv;
i64 = i64 * i;
i64 = i64 % i;
// Shift
u64v <<= i;
i64 >>= uv.y;
i64 = i64 << u64v.z;
u64v = u64v << i64;
// Relational
b = (u64v.x != i64);
b = (i64 == u64v.x);
b = (u64v.x > uv.y);
b = (i64 < i);
b = (u64v.y >= uv.x);
b = (i64 <= i);
// Bitwise
u64v |= i;
i64 = i64 | i;
i64 &= i;
u64v = u64v & uv;
u64v ^= i64;
u64v = u64v ^ i64;
}
void builtinFuncs()
{
i64vec2 i64v;
u64vec3 u64v;
dvec3 dv;
bvec3 bv;
int64_t i64;
uint64_t u64;
// abs()
i64v = abs(i64v);
// sign()
i64 = sign(i64);
// min()
i64v = min(i64v, i64);
i64v = min(i64v, i64vec2(-1));
u64v = min(u64v, u64);
u64v = min(u64v, u64vec3(0));
// max()
i64v = max(i64v, i64);
i64v = max(i64v, i64vec2(-1));
u64v = max(u64v, u64);
u64v = max(u64v, u64vec3(0));
// clamp()
i64v = clamp(i64v, -i64, i64);
i64v = clamp(i64v, -i64v, i64v);
u64v = clamp(u64v, -u64, u64);
u64v = clamp(u64v, -u64v, u64v);
// mix()
i64 = mix(i64v.x, i64v.y, true);
i64v = mix(i64vec2(i64), i64vec2(-i64), bvec2(false));
u64 = mix(u64v.x, u64v.y, true);
u64v = mix(u64vec3(u64), u64vec3(-u64), bvec3(false));
// doubleBitsToInt64()
i64v = doubleBitsToInt64(dv.xy);
// doubleBitsToUint64()
u64v.x = doubleBitsToUint64(dv.z);
// int64BitsToDouble()
dv.xy = int64BitsToDouble(i64v);
// uint64BitsToDouble()
dv = uint64BitsToDouble(u64v);
// packInt2x32()
i64 = packInt2x32(ivec2(1, 2));
// unpackInt2x32()
ivec2 iv = unpackInt2x32(i64);
// packUint2x32()
u64 = packUint2x32(uvec2(2, 3));
// unpackUint2x32()
uvec2 uv = unpackUint2x32(u64);
// lessThan()
bv = lessThan(u64v, u64vec3(u64));
bv.xy = lessThan(i64v, i64vec2(i64));
// lessThanEqual()
bv = lessThanEqual(u64v, u64vec3(u64));
bv.xy = lessThanEqual(i64v, i64vec2(i64));
// greaterThan()
bv = greaterThan(u64v, u64vec3(u64));
bv.xy = greaterThan(i64v, i64vec2(i64));
// greaterThanEqual()
bv = greaterThanEqual(u64v, u64vec3(u64));
bv.xy = greaterThanEqual(i64v, i64vec2(i64));
// equal()
bv = equal(u64v, u64vec3(u64));
bv.xy = equal(i64v, i64vec2(i64));
// notEqual()
bv = notEqual(u64v, u64vec3(u64));
bv.xy = notEqual(i64v, i64vec2(i64));
}
\ No newline at end of file
......@@ -53,6 +53,7 @@ spv.forwardFun.frag
spv.functionCall.frag
spv.functionSemantics.frag
spv.interpOps.frag
spv.int64.frag
spv.layoutNested.vert
spv.length.frag
spv.localAggregates.frag
......
......@@ -48,6 +48,8 @@ enum TBasicType {
EbtDouble,
EbtInt,
EbtUint,
EbtInt64,
EbtUint64,
EbtBool,
EbtAtomicUint,
EbtSampler,
......
......@@ -182,6 +182,8 @@ struct TSampler { // misnomer now; includes images, textures without sampler,
case EbtFloat: break;
case EbtInt: s.append("i"); break;
case EbtUint: s.append("u"); break;
case EbtInt64: s.append("i64"); break;
case EbtUint64: s.append("u64"); break;
default: break; // some compilers want this
}
if (image) {
......@@ -1319,6 +1321,8 @@ public:
case EbtDouble:
case EbtInt:
case EbtUint:
case EbtInt64:
case EbtUint64:
case EbtBool:
return true;
default:
......@@ -1409,6 +1413,8 @@ public:
case EbtDouble: return "double";
case EbtInt: return "int";
case EbtUint: return "uint";
case EbtInt64: return "int64_t";
case EbtUint64: return "uint64_t";
case EbtBool: return "bool";
case EbtAtomicUint: return "atomic_uint";
case EbtSampler: return "sampler/image";
......
......@@ -81,22 +81,44 @@ enum TOperator {
EOpConvUintToBool,
EOpConvFloatToBool,
EOpConvDoubleToBool,
EOpConvInt64ToBool,
EOpConvUint64ToBool,
EOpConvBoolToFloat,
EOpConvIntToFloat,
EOpConvUintToFloat,
EOpConvDoubleToFloat,
EOpConvInt64ToFloat,
EOpConvUint64ToFloat,
EOpConvUintToInt,
EOpConvFloatToInt,
EOpConvBoolToInt,
EOpConvDoubleToInt,
EOpConvInt64ToInt,
EOpConvUint64ToInt,
EOpConvIntToUint,
EOpConvFloatToUint,
EOpConvBoolToUint,
EOpConvDoubleToUint,
EOpConvInt64ToUint,
EOpConvUint64ToUint,
EOpConvIntToDouble,
EOpConvUintToDouble,
EOpConvFloatToDouble,
EOpConvBoolToDouble,
EOpConvInt64ToDouble,
EOpConvUint64ToDouble,
EOpConvBoolToInt64,
EOpConvIntToInt64,
EOpConvUintToInt64,
EOpConvFloatToInt64,
EOpConvDoubleToInt64,
EOpConvUint64ToInt64,
EOpConvBoolToUint64,
EOpConvIntToUint64,
EOpConvUintToUint64,
EOpConvFloatToUint64,
EOpConvDoubleToUint64,
EOpConvInt64ToUint64,
//
// binary operations
......@@ -194,6 +216,10 @@ enum TOperator {
EOpFloatBitsToUint,
EOpIntBitsToFloat,
EOpUintBitsToFloat,
EOpDoubleBitsToInt64,
EOpDoubleBitsToUint64,
EOpInt64BitsToDouble,
EOpUint64BitsToDouble,
EOpPackSnorm2x16,
EOpUnpackSnorm2x16,
EOpPackUnorm2x16,
......@@ -206,6 +232,10 @@ enum TOperator {
EOpUnpackHalf2x16,
EOpPackDouble2x32,
EOpUnpackDouble2x32,
EOpPackInt2x32,
EOpUnpackInt2x32,
EOpPackUint2x32,
EOpUnpackUint2x32,
EOpLength,
EOpDistance,
......@@ -287,6 +317,8 @@ enum TOperator {
EOpConstructGuardStart,
EOpConstructInt, // these first scalar forms also identify what implicit conversion is needed
EOpConstructUint,
EOpConstructInt64,
EOpConstructUint64,
EOpConstructBool,
EOpConstructFloat,
EOpConstructDouble,
......@@ -305,6 +337,12 @@ enum TOperator {
EOpConstructUVec2,
EOpConstructUVec3,
EOpConstructUVec4,
EOpConstructI64Vec2,
EOpConstructI64Vec3,
EOpConstructI64Vec4,
EOpConstructU64Vec2,
EOpConstructU64Vec3,
EOpConstructU64Vec4,
EOpConstructMat2x2,
EOpConstructMat2x3,
EOpConstructMat2x4,
......
......@@ -194,6 +194,22 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TIntermTyped* right
} else
newConstArray[i].setUConst(leftUnionArray[i].getUConst() / rightUnionArray[i].getUConst());
break;
case EbtInt64:
if (rightUnionArray[i] == 0)
newConstArray[i].setI64Const(0x7FFFFFFFFFFFFFFFll);
else if (rightUnionArray[i].getI64Const() == -1 && leftUnionArray[i].getI64Const() == (long long)0x8000000000000000)
newConstArray[i].setI64Const(0x8000000000000000);
else
newConstArray[i].setI64Const(leftUnionArray[i].getI64Const() / rightUnionArray[i].getI64Const());
break;
case EbtUint64:
if (rightUnionArray[i] == 0) {
newConstArray[i].setU64Const(0xFFFFFFFFFFFFFFFFull);
} else
newConstArray[i].setU64Const(leftUnionArray[i].getU64Const() / rightUnionArray[i].getU64Const());
break;
default:
return 0;
}
......@@ -419,6 +435,8 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType)
case EbtFloat: newConstArray[i].setDConst(-unionArray[i].getDConst()); break;
case EbtInt: newConstArray[i].setIConst(-unionArray[i].getIConst()); break;
case EbtUint: newConstArray[i].setUConst(static_cast<unsigned int>(-static_cast<int>(unionArray[i].getUConst()))); break;
case EbtInt64: newConstArray[i].setI64Const(-unionArray[i].getI64Const()); break;
case EbtUint64: newConstArray[i].setU64Const(static_cast<unsigned int>(-static_cast<int>(unionArray[i].getU64Const()))); break;
default:
return 0;
}
......@@ -566,6 +584,8 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType)
case EOpFloatBitsToUint:
case EOpIntBitsToFloat:
case EOpUintBitsToFloat:
case EOpDoubleBitsToInt64:
case EOpDoubleBitsToUint64:
default:
return 0;
......@@ -651,7 +671,10 @@ TIntermTyped* TIntermediate::fold(TIntermAggregate* aggrNode)
bool isFloatingPoint = children[0]->getAsTyped()->getBasicType() == EbtFloat ||
children[0]->getAsTyped()->getBasicType() == EbtDouble;
bool isSigned = children[0]->getAsTyped()->getBasicType() == EbtInt;
bool isSigned = children[0]->getAsTyped()->getBasicType() == EbtInt ||
children[0]->getAsTyped()->getBasicType() == EbtInt64;
bool isInt64 = children[0]->getAsTyped()->getBasicType() == EbtInt64 ||
children[0]->getAsTyped()->getBasicType() == EbtUint64;
if (componentwise) {
for (int comp = 0; comp < objectSize; comp++) {
......@@ -674,29 +697,52 @@ TIntermTyped* TIntermediate::fold(TIntermAggregate* aggrNode)
case EOpMin:
if (isFloatingPoint)
newConstArray[comp].setDConst(std::min(childConstUnions[0][arg0comp].getDConst(), childConstUnions[1][arg1comp].getDConst()));
else if (isSigned)
newConstArray[comp].setIConst(std::min(childConstUnions[0][arg0comp].getIConst(), childConstUnions[1][arg1comp].getIConst()));
else
newConstArray[comp].setUConst(std::min(childConstUnions[0][arg0comp].getUConst(), childConstUnions[1][arg1comp].getUConst()));
else if (isSigned) {
if (isInt64)
newConstArray[comp].setI64Const(std::min(childConstUnions[0][arg0comp].getI64Const(), childConstUnions[1][arg1comp].getI64Const()));
else
newConstArray[comp].setIConst(std::min(childConstUnions[0][arg0comp].getIConst(), childConstUnions[1][arg1comp].getIConst()));
} else {
if (isInt64)
newConstArray[comp].setU64Const(std::min(childConstUnions[0][arg0comp].getU64Const(), childConstUnions[1][arg1comp].getU64Const()));
else
newConstArray[comp].setUConst(std::min(childConstUnions[0][arg0comp].getUConst(), childConstUnions[1][arg1comp].getUConst()));
}
break;
case EOpMax:
if (isFloatingPoint)
newConstArray[comp].setDConst(std::max(childConstUnions[0][arg0comp].getDConst(), childConstUnions[1][arg1comp].getDConst()));
else if (isSigned)
newConstArray[comp].setIConst(std::max(childConstUnions[0][arg0comp].getIConst(), childConstUnions[1][arg1comp].getIConst()));
else
newConstArray[comp].setUConst(std::max(childConstUnions[0][arg0comp].getUConst(), childConstUnions[1][arg1comp].getUConst()));
else if (isSigned) {
if (isInt64)
newConstArray[comp].setI64Const(std::max(childConstUnions[0][arg0comp].getI64Const(), childConstUnions[1][arg1comp].getI64Const()));
else
newConstArray[comp].setIConst(std::max(childConstUnions[0][arg0comp].getIConst(), childConstUnions[1][arg1comp].getIConst()));
} else {
if (isInt64)
newConstArray[comp].setU64Const(std::max(childConstUnions[0][arg0comp].getU64Const(), childConstUnions[1][arg1comp].getU64Const()));
else
newConstArray[comp].setUConst(std::max(childConstUnions[0][arg0comp].getUConst(), childConstUnions[1][arg1comp].getUConst()));
}
break;
case EOpClamp:
if (isFloatingPoint)
newConstArray[comp].setDConst(std::min(std::max(childConstUnions[0][arg0comp].getDConst(), childConstUnions[1][arg1comp].getDConst()),
newConstArray[comp].setDConst(std::min(std::max(childConstUnions[0][arg0comp].getDConst(), childConstUnions[1][arg1comp].getDConst()),
childConstUnions[2][arg2comp].getDConst()));
else if (isSigned)
newConstArray[comp].setIConst(std::min(std::max(childConstUnions[0][arg0comp].getIConst(), childConstUnions[1][arg1comp].getIConst()),
childConstUnions[2][arg2comp].getIConst()));
else
newConstArray[comp].setUConst(std::min(std::max(childConstUnions[0][arg0comp].getUConst(), childConstUnions[1][arg1comp].getUConst()),
childConstUnions[2][arg2comp].getUConst()));
else if (isSigned) {
if (isInt64)
newConstArray[comp].setI64Const(std::min(std::max(childConstUnions[0][arg0comp].getI64Const(), childConstUnions[1][arg1comp].getI64Const()),
childConstUnions[2][arg2comp].getI64Const()));
else
newConstArray[comp].setIConst(std::min(std::max(childConstUnions[0][arg0comp].getIConst(), childConstUnions[1][arg1comp].getIConst()),
childConstUnions[2][arg2comp].getIConst()));
} else {
if (isInt64)
newConstArray[comp].setU64Const(std::min(std::max(childConstUnions[0][arg0comp].getU64Const(), childConstUnions[1][arg1comp].getU64Const()),
childConstUnions[2][arg2comp].getU64Const()));
else
newConstArray[comp].setUConst(std::min(std::max(childConstUnions[0][arg0comp].getUConst(), childConstUnions[1][arg1comp].getUConst()),
childConstUnions[2][arg2comp].getUConst()));
}
break;
case EOpLessThan:
newConstArray[comp].setBConst(childConstUnions[0][arg0comp] < childConstUnions[1][arg1comp]);
......
......@@ -75,6 +75,8 @@ TBuiltIns::TBuiltIns()
prefixes[EbtFloat] = "";
prefixes[EbtInt] = "i";
prefixes[EbtUint] = "u";
prefixes[EbtInt64] = "i64";
prefixes[EbtUint64] = "u64";
postfixes[2] = "2";
postfixes[3] = "3";
postfixes[4] = "4";
......@@ -626,6 +628,145 @@ void TBuiltIns::initialize(int version, EProfile profile, int spv, int vulkan)
"dmat2 inverse(dmat2);"
"dmat3 inverse(dmat3);"
"dmat4 inverse(dmat4);"
"\n");
}
if (profile != EEsProfile && version >= 450) {
commonBuiltins.append(
"int64_t abs(int64_t);"
"i64vec2 abs(i64vec2);"
"i64vec3 abs(i64vec3);"
"i64vec4 abs(i64vec4);"
"int64_t sign(int64_t);"
"i64vec2 sign(i64vec2);"
"i64vec3 sign(i64vec3);"
"i64vec4 sign(i64vec4);"
"int64_t min(int64_t, int64_t);"
"i64vec2 min(i64vec2, int64_t);"
"i64vec3 min(i64vec3, int64_t);"
"i64vec4 min(i64vec4, int64_t);"
"i64vec2 min(i64vec2, i64vec2);"
"i64vec3 min(i64vec3, i64vec3);"
"i64vec4 min(i64vec4, i64vec4);"
"uint64_t min(uint64_t, uint64_t);"
"u64vec2 min(u64vec2, uint64_t);"
"u64vec3 min(u64vec3, uint64_t);"
"u64vec4 min(u64vec4, uint64_t);"
"u64vec2 min(u64vec2, u64vec2);"
"u64vec3 min(u64vec3, u64vec3);"
"u64vec4 min(u64vec4, u64vec4);"
"int64_t max(int64_t, int64_t);"
"i64vec2 max(i64vec2, int64_t);"
"i64vec3 max(i64vec3, int64_t);"
"i64vec4 max(i64vec4, int64_t);"
"i64vec2 max(i64vec2, i64vec2);"
"i64vec3 max(i64vec3, i64vec3);"
"i64vec4 max(i64vec4, i64vec4);"
"uint64_t max(uint64_t, uint64_t);"
"u64vec2 max(u64vec2, uint64_t);"
"u64vec3 max(u64vec3, uint64_t);"
"u64vec4 max(u64vec4, uint64_t);"
"u64vec2 max(u64vec2, u64vec2);"
"u64vec3 max(u64vec3, u64vec3);"
"u64vec4 max(u64vec4, u64vec4);"
"int64_t clamp(int64_t, int64_t, int64_t);"
"i64vec2 clamp(i64vec2, int64_t, int64_t);"
"i64vec3 clamp(i64vec3, int64_t, int64_t);"
"i64vec4 clamp(i64vec4, int64_t, int64_t);"
"i64vec2 clamp(i64vec2, i64vec2, i64vec2);"
"i64vec3 clamp(i64vec3, i64vec3, i64vec3);"
"i64vec4 clamp(i64vec4, i64vec4, i64vec4);"
"uint64_t clamp(uint64_t, uint64_t, uint64_t);"
"u64vec2 clamp(u64vec2, uint64_t, uint64_t);"
"u64vec3 clamp(u64vec3, uint64_t, uint64_t);"
"u64vec4 clamp(u64vec4, uint64_t, uint64_t);"
"u64vec2 clamp(u64vec2, u64vec2, u64vec2);"
"u64vec3 clamp(u64vec3, u64vec3, u64vec3);"
"u64vec4 clamp(u64vec4, u64vec4, u64vec4);"
"int64_t mix(int64_t, int64_t, bool);"
"i64vec2 mix(i64vec2, i64vec2, bvec2);"
"i64vec3 mix(i64vec3, i64vec3, bvec3);"
"i64vec4 mix(i64vec4, i64vec4, bvec4);"
"uint64_t mix(uint64_t, uint64_t, bool);"
"u64vec2 mix(u64vec2, u64vec2, bvec2);"
"u64vec3 mix(u64vec3, u64vec3, bvec3);"
"u64vec4 mix(u64vec4, u64vec4, bvec4);"
"int64_t doubleBitsToInt64(double);"
"i64vec2 doubleBitsToInt64(dvec2);"
"i64vec3 doubleBitsToInt64(dvec3);"
"i64vec4 doubleBitsToInt64(dvec4);"
"uint64_t doubleBitsToUint64(double);"
"u64vec2 doubleBitsToUint64(dvec2);"
"u64vec3 doubleBitsToUint64(dvec3);"
"u64vec4 doubleBitsToUint64(dvec4);"
"double int64BitsToDouble(int64_t);"
"dvec2 int64BitsToDouble(i64vec2);"
"dvec3 int64BitsToDouble(i64vec3);"
"dvec4 int64BitsToDouble(i64vec4);"
"double uint64BitsToDouble(uint64_t);"
"dvec2 uint64BitsToDouble(u64vec2);"
"dvec3 uint64BitsToDouble(u64vec3);"
"dvec4 uint64BitsToDouble(u64vec4);"
"int64_t packInt2x32(ivec2);"
"uint64_t packUint2x32(uvec2);"
"ivec2 unpackInt2x32(int64_t);"
"uvec2 unpackUint2x32(uint64_t);"
"bvec2 lessThan(i64vec2, i64vec2);"
"bvec3 lessThan(i64vec3, i64vec3);"
"bvec4 lessThan(i64vec4, i64vec4);"
"bvec2 lessThan(u64vec2, u64vec2);"
"bvec3 lessThan(u64vec3, u64vec3);"
"bvec4 lessThan(u64vec4, u64vec4);"
"bvec2 lessThanEqual(i64vec2, i64vec2);"
"bvec3 lessThanEqual(i64vec3, i64vec3);"
"bvec4 lessThanEqual(i64vec4, i64vec4);"
"bvec2 lessThanEqual(u64vec2, u64vec2);"
"bvec3 lessThanEqual(u64vec3, u64vec3);"
"bvec4 lessThanEqual(u64vec4, u64vec4);"
"bvec2 greaterThan(i64vec2, i64vec2);"
"bvec3 greaterThan(i64vec3, i64vec3);"
"bvec4 greaterThan(i64vec4, i64vec4);"
"bvec2 greaterThan(u64vec2, u64vec2);"
"bvec3 greaterThan(u64vec3, u64vec3);"
"bvec4 greaterThan(u64vec4, u64vec4);"
"bvec2 greaterThanEqual(i64vec2, i64vec2);"
"bvec3 greaterThanEqual(i64vec3, i64vec3);"
"bvec4 greaterThanEqual(i64vec4, i64vec4);"
"bvec2 greaterThanEqual(u64vec2, u64vec2);"
"bvec3 greaterThanEqual(u64vec3, u64vec3);"
"bvec4 greaterThanEqual(u64vec4, u64vec4);"
"bvec2 equal(i64vec2, i64vec2);"
"bvec3 equal(i64vec3, i64vec3);"
"bvec4 equal(i64vec4, i64vec4);"
"bvec2 equal(u64vec2, u64vec2);"
"bvec3 equal(u64vec3, u64vec3);"
"bvec4 equal(u64vec4, u64vec4);"
"bvec2 notEqual(i64vec2, i64vec2);"
"bvec3 notEqual(i64vec3, i64vec3);"
"bvec4 notEqual(i64vec4, i64vec4);"
"bvec2 notEqual(u64vec2, u64vec2);"
"bvec3 notEqual(u64vec3, u64vec3);"
"bvec4 notEqual(u64vec4, u64vec4);"
"\n"
);
}
......@@ -3650,6 +3791,10 @@ void IdentifyBuiltIns(int version, EProfile profile, int spv, int vulkan, EShLan
symbolTable.relateToOperator("floatBitsToUint", EOpFloatBitsToUint);
symbolTable.relateToOperator("intBitsToFloat", EOpIntBitsToFloat);
symbolTable.relateToOperator("uintBitsToFloat", EOpUintBitsToFloat);
symbolTable.relateToOperator("doubleBitsToInt64", EOpDoubleBitsToInt64);
symbolTable.relateToOperator("doubleBitsToUint64", EOpDoubleBitsToUint64);
symbolTable.relateToOperator("int64BitsToDouble", EOpInt64BitsToDouble);
symbolTable.relateToOperator("uint64BitsToDouble", EOpUint64BitsToDouble);
symbolTable.relateToOperator("packSnorm2x16", EOpPackSnorm2x16);
symbolTable.relateToOperator("unpackSnorm2x16", EOpUnpackSnorm2x16);
......@@ -3667,6 +3812,11 @@ void IdentifyBuiltIns(int version, EProfile profile, int spv, int vulkan, EShLan
symbolTable.relateToOperator("packHalf2x16", EOpPackHalf2x16);
symbolTable.relateToOperator("unpackHalf2x16", EOpUnpackHalf2x16);
symbolTable.relateToOperator("packInt2x32", EOpPackInt2x32);
symbolTable.relateToOperator("unpackInt2x32", EOpUnpackInt2x32);
symbolTable.relateToOperator("packUint2x32", EOpPackUint2x32);
symbolTable.relateToOperator("unpackUint2x32", EOpUnpackUint2x32);
symbolTable.relateToOperator("length", EOpLength);
symbolTable.relateToOperator("distance", EOpDistance);
symbolTable.relateToOperator("dot", EOpDot);
......
......@@ -1812,6 +1812,24 @@ TOperator TParseContext::mapTypeToConstructorOp(const TType& type) const
default: break; // some compilers want this
}
break;
case EbtInt64:
switch(type.getVectorSize()) {
case 1: op = EOpConstructInt64; break;
case 2: op = EOpConstructI64Vec2; break;
case 3: op = EOpConstructI64Vec3; break;
case 4: op = EOpConstructI64Vec4; break;
default: break; // some compilers want this
}
break;
case EbtUint64:
switch(type.getVectorSize()) {
case 1: op = EOpConstructUint64; break;
case 2: op = EOpConstructU64Vec2; break;
case 3: op = EOpConstructU64Vec3; break;
case 4: op = EOpConstructU64Vec4; break;
default: break; // some compilers want this
}
break;
case EbtBool:
switch(type.getVectorSize()) {
case 1: op = EOpConstructBool; break;
......@@ -2534,13 +2552,19 @@ void TParseContext::globalQualifierTypeCheck(const TSourceLoc& loc, const TQuali
return;
}
if (publicType.basicType == EbtInt || publicType.basicType == EbtUint || publicType.basicType == EbtDouble)
if (publicType.basicType == EbtInt || publicType.basicType == EbtUint ||
publicType.basicType == EbtInt64 || publicType.basicType == EbtUint64 ||
publicType.basicType == EbtDouble)
profileRequires(loc, EEsProfile, 300, nullptr, "shader input/output");
if (! qualifier.flat) {
if (publicType.basicType == EbtInt || publicType.basicType == EbtUint || publicType.basicType == EbtDouble ||
(publicType.userDef && (publicType.userDef->containsBasicType(EbtInt) ||
publicType.userDef->containsBasicType(EbtUint) ||
if (publicType.basicType == EbtInt || publicType.basicType == EbtUint ||
publicType.basicType == EbtInt64 || publicType.basicType == EbtUint64 ||
publicType.basicType == EbtDouble ||
(publicType.userDef && (publicType.userDef->containsBasicType(EbtInt) ||
publicType.userDef->containsBasicType(EbtUint) ||
publicType.userDef->containsBasicType(EbtInt64) ||
publicType.userDef->containsBasicType(EbtUint64) ||
publicType.userDef->containsBasicType(EbtDouble)))) {
if (qualifier.storage == EvqVaryingIn && language == EShLangFragment)
error(loc, "must be qualified as flat", TType::getBasicString(publicType.basicType), GetStorageQualifierString(qualifier.storage));
......@@ -4415,6 +4439,8 @@ void TParseContext::layoutTypeCheck(const TSourceLoc& loc, const TType& type)
{
case EbtInt:
case EbtUint:
case EbtInt64:
case EbtUint64:
case EbtBool:
case EbtFloat:
case EbtDouble:
......@@ -5226,6 +5252,20 @@ TIntermTyped* TParseContext::constructBuiltIn(const TType& type, TOperator op, T
basicOp = EOpConstructUint;
break;
case EOpConstructI64Vec2:
case EOpConstructI64Vec3:
case EOpConstructI64Vec4:
case EOpConstructInt64:
basicOp = EOpConstructInt64;
break;
case EOpConstructU64Vec2:
case EOpConstructU64Vec3:
case EOpConstructU64Vec4:
case EOpConstructUint64:
basicOp = EOpConstructUint64;
break;
case EOpConstructBVec2:
case EOpConstructBVec3:
case EOpConstructBVec4:
......
......@@ -454,6 +454,15 @@ void TScanContext::fillInKeywordMap()
(*KeywordMap)["uvec3"] = UVEC3;
(*KeywordMap)["uvec4"] = UVEC4;
(*KeywordMap)["int64_t"] = INT64_T;
(*KeywordMap)["uint64_t"] = UINT64_T;
(*KeywordMap)["i64vec2"] = I64VEC2;
(*KeywordMap)["i64vec3"] = I64VEC3;
(*KeywordMap)["i64vec4"] = I64VEC4;
(*KeywordMap)["u64vec2"] = U64VEC2;
(*KeywordMap)["u64vec3"] = U64VEC3;
(*KeywordMap)["u64vec4"] = U64VEC4;
(*KeywordMap)["sampler2D"] = SAMPLER2D;
(*KeywordMap)["samplerCube"] = SAMPLERCUBE;
(*KeywordMap)["samplerCubeArray"] = SAMPLERCUBEARRAY;
......@@ -667,10 +676,12 @@ int TScanContext::tokenize(TPpContext* pp, TParserToken& token)
case PpAtomDecrement: return DEC_OP;
case PpAtomIncrement: return INC_OP;
case PpAtomConstInt: parserToken->sType.lex.i = ppToken.ival; return INTCONSTANT;
case PpAtomConstUint: parserToken->sType.lex.i = ppToken.ival; return UINTCONSTANT;
case PpAtomConstFloat: parserToken->sType.lex.d = ppToken.dval; return FLOATCONSTANT;
case PpAtomConstDouble: parserToken->sType.lex.d = ppToken.dval; return DOUBLECONSTANT;
case PpAtomConstInt: parserToken->sType.lex.i = ppToken.ival; return INTCONSTANT;
case PpAtomConstUint: parserToken->sType.lex.i = ppToken.ival; return UINTCONSTANT;
case PpAtomConstInt64: parserToken->sType.lex.i64 = ppToken.i64val; return INT64CONSTANT;
case PpAtomConstUint64: parserToken->sType.lex.i64 = ppToken.i64val; return UINT64CONSTANT;
case PpAtomConstFloat: parserToken->sType.lex.d = ppToken.dval; return FLOATCONSTANT;
case PpAtomConstDouble: parserToken->sType.lex.d = ppToken.dval; return DOUBLECONSTANT;
case PpAtomIdentifier:
{
int token = tokenizeIdentifier();
......@@ -914,6 +925,18 @@ int TScanContext::tokenizeIdentifier()
reservedWord();
return keyword;
case INT64_T:
case UINT64_T:
case I64VEC2:
case I64VEC3:
case I64VEC4:
case U64VEC2:
case U64VEC3:
case U64VEC4:
if (parseContext.profile != EEsProfile && parseContext.version >= 450)
return keyword;
return identifierOrType();
case SAMPLERCUBEARRAY:
case SAMPLERCUBEARRAYSHADOW:
case ISAMPLERCUBEARRAY:
......
......@@ -62,6 +62,8 @@ void TType::buildMangledName(TString& mangledName)
case EbtDouble: mangledName += 'd'; break;
case EbtInt: mangledName += 'i'; break;
case EbtUint: mangledName += 'u'; break;
case EbtInt64: mangledName += "i64"; break;
case EbtUint64: mangledName += "u64"; break;
case EbtBool: mangledName += 'b'; break;
case EbtAtomicUint: mangledName += "au"; break;
case EbtSampler:
......
......@@ -174,6 +174,7 @@ void TParseVersions::initializeExtensionBehavior()
extensionBehavior[E_GL_ARB_derivative_control] = EBhDisable;
extensionBehavior[E_GL_ARB_shader_texture_image_samples] = EBhDisable;
extensionBehavior[E_GL_ARB_viewport_array] = EBhDisable;
extensionBehavior[E_GL_ARB_gpu_shader_int64] = EBhDisable;
extensionBehavior[E_GL_ARB_gl_spirv] = EBhDisable;
extensionBehavior[E_GL_ARB_sparse_texture2] = EBhDisable;
extensionBehavior[E_GL_ARB_sparse_texture_clamp] = EBhDisable;
......@@ -278,6 +279,7 @@ const char* TParseVersions::getPreamble()
"#define GL_ARB_derivative_control 1\n"
"#define GL_ARB_shader_texture_image_samples 1\n"
"#define GL_ARB_viewport_array 1\n"
"#define GL_ARB_gpu_shader_int64 1\n"
"#define GL_ARB_gl_spirv 1\n"
"#define GL_ARB_sparse_texture2 1\n"
"#define GL_ARB_sparse_texture_clamp 1\n"
......@@ -627,6 +629,17 @@ void TParseVersions::doubleCheck(const TSourceLoc& loc, const char* op)
profileRequires(loc, ECompatibilityProfile, 400, nullptr, op);
}
// Call for any operation needing GLSL 64-bit integer data-type support.
void TParseVersions::int64Check(const TSourceLoc& loc, const char* op, bool builtIn)
{
if (! builtIn) {
requireExtensions(loc, 1, &E_GL_ARB_gpu_shader_int64, "shader int64");
requireProfile(loc, ECoreProfile | ECompatibilityProfile, op);
profileRequires(loc, ECoreProfile, 450, nullptr, op);
profileRequires(loc, ECompatibilityProfile, 450, nullptr, op);
}
}
// Call for any operation removed because SPIR-V is in use.
void TParseVersions::spvRemoved(const TSourceLoc& loc, const char* op)
{
......
......@@ -111,6 +111,7 @@ const char* const E_GL_ARB_shader_draw_parameters = "GL_ARB_shader_draw_pa
const char* const E_GL_ARB_derivative_control = "GL_ARB_derivative_control";
const char* const E_GL_ARB_shader_texture_image_samples = "GL_ARB_shader_texture_image_samples";
const char* const E_GL_ARB_viewport_array = "GL_ARB_viewport_array";
const char* const E_GL_ARB_gpu_shader_int64 = "GL_ARB_gpu_shader_int64";
const char* const E_GL_ARB_gl_spirv = "GL_ARB_gl_spirv";
const char* const E_GL_ARB_sparse_texture2 = "GL_ARB_sparse_texture2";
const char* const E_GL_ARB_sparse_texture_clamp = "GL_ARB_sparse_texture_clamp";
......
......@@ -41,6 +41,16 @@
#define GL_UNSIGNED_INT_VEC3 0x8DC7
#define GL_UNSIGNED_INT_VEC4 0x8DC8
#define GL_INT64_ARB 0x140E
#define GL_INT64_VEC2_ARB 0x8FE9
#define GL_INT64_VEC3_ARB 0x8FEA
#define GL_INT64_VEC4_ARB 0x8FEB
#define GL_UNSIGNED_INT64_ARB 0x140F
#define GL_UNSIGNED_INT64_VEC2_ARB 0x8FE5
#define GL_UNSIGNED_INT64_VEC3_ARB 0x8FE6
#define GL_UNSIGNED_INT64_VEC4_ARB 0x8FE7
#define GL_BOOL 0x8B56
#define GL_BOOL_VEC2 0x8B57
#define GL_BOOL_VEC3 0x8B58
......
......@@ -70,6 +70,8 @@ using namespace glslang;
glslang::TString *string;
int i;
unsigned int u;
long long i64;
unsigned long long u64;
bool b;
double d;
};
......@@ -117,9 +119,9 @@ extern int yylex(YYSTYPE*, TParseContext&);
%expect 1 // One shift reduce conflict because of if | else
%token <lex> ATTRIBUTE VARYING
%token <lex> CONST BOOL FLOAT DOUBLE INT UINT
%token <lex> CONST BOOL FLOAT DOUBLE INT UINT INT64_T UINT64_T
%token <lex> BREAK CONTINUE DO ELSE FOR IF DISCARD RETURN SWITCH CASE DEFAULT SUBROUTINE
%token <lex> BVEC2 BVEC3 BVEC4 IVEC2 IVEC3 IVEC4 UVEC2 UVEC3 UVEC4 VEC2 VEC3 VEC4
%token <lex> BVEC2 BVEC3 BVEC4 IVEC2 IVEC3 IVEC4 I64VEC2 I64VEC3 I64VEC4 UVEC2 UVEC3 UVEC4 U64VEC2 U64VEC3 U64VEC4 VEC2 VEC3 VEC4
%token <lex> MAT2 MAT3 MAT4 CENTROID IN OUT INOUT
%token <lex> UNIFORM PATCH SAMPLE BUFFER SHARED
%token <lex> COHERENT VOLATILE RESTRICT READONLY WRITEONLY
......@@ -180,7 +182,7 @@ extern int yylex(YYSTYPE*, TParseContext&);
%token <lex> STRUCT VOID WHILE
%token <lex> IDENTIFIER TYPE_NAME
%token <lex> FLOATCONSTANT DOUBLECONSTANT INTCONSTANT UINTCONSTANT BOOLCONSTANT
%token <lex> FLOATCONSTANT DOUBLECONSTANT INTCONSTANT UINTCONSTANT INT64CONSTANT UINT64CONSTANT BOOLCONSTANT
%token <lex> LEFT_OP RIGHT_OP
%token <lex> INC_OP DEC_OP LE_OP GE_OP EQ_OP NE_OP
%token <lex> AND_OP OR_OP XOR_OP MUL_ASSIGN DIV_ASSIGN ADD_ASSIGN
......@@ -257,6 +259,14 @@ primary_expression
parseContext.fullIntegerCheck($1.loc, "unsigned literal");
$$ = parseContext.intermediate.addConstantUnion($1.u, $1.loc, true);
}
| INT64CONSTANT {
parseContext.int64Check($1.loc, "64-bit integer literal");
$$ = parseContext.intermediate.addConstantUnion($1.i64, $1.loc, true);
}
| UINT64CONSTANT {
parseContext.int64Check($1.loc, "64-bit unsigned integer literal");
$$ = parseContext.intermediate.addConstantUnion($1.u64, $1.loc, true);
}
| FLOATCONSTANT {
$$ = parseContext.intermediate.addConstantUnion($1.d, EbtFloat, $1.loc, true);
}
......@@ -1309,6 +1319,16 @@ type_specifier_nonarray
$$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
$$.basicType = EbtUint;
}
| INT64_T {
parseContext.int64Check($1.loc, "64-bit integer", parseContext.symbolTable.atBuiltInLevel());
$$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
$$.basicType = EbtInt64;
}
| UINT64_T {
parseContext.int64Check($1.loc, "64-bit unsigned integer", parseContext.symbolTable.atBuiltInLevel());
$$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
$$.basicType = EbtUint64;
}
| BOOL {
$$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
$$.basicType = EbtBool;
......@@ -1376,6 +1396,24 @@ type_specifier_nonarray
$$.basicType = EbtInt;
$$.setVector(4);
}
| I64VEC2 {
parseContext.int64Check($1.loc, "64-bit integer vector", parseContext.symbolTable.atBuiltInLevel());
$$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
$$.basicType = EbtInt64;
$$.setVector(2);
}
| I64VEC3 {
parseContext.int64Check($1.loc, "64-bit integer vector", parseContext.symbolTable.atBuiltInLevel());
$$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
$$.basicType = EbtInt64;
$$.setVector(3);
}
| I64VEC4 {
parseContext.int64Check($1.loc, "64-bit integer vector", parseContext.symbolTable.atBuiltInLevel());
$$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
$$.basicType = EbtInt64;
$$.setVector(4);
}
| UVEC2 {
parseContext.fullIntegerCheck($1.loc, "unsigned integer vector");
$$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
......@@ -1394,6 +1432,24 @@ type_specifier_nonarray
$$.basicType = EbtUint;
$$.setVector(4);
}
| U64VEC2 {
parseContext.int64Check($1.loc, "64-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel());
$$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
$$.basicType = EbtUint64;
$$.setVector(2);
}
| U64VEC3 {
parseContext.int64Check($1.loc, "64-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel());
$$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
$$.basicType = EbtUint64;
$$.setVector(3);
}
| U64VEC4 {
parseContext.int64Check($1.loc, "64-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel());
$$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
$$.basicType = EbtUint64;
$$.setVector(4);
}
| MAT2 {
$$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
$$.basicType = EbtFloat;
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -206,22 +206,44 @@ bool TOutputTraverser::visitUnary(TVisit /* visit */, TIntermUnary* node)
case EOpConvUintToBool: out.debug << "Convert uint to bool"; break;
case EOpConvFloatToBool: out.debug << "Convert float to bool"; break;
case EOpConvDoubleToBool: out.debug << "Convert double to bool"; break;
case EOpConvInt64ToBool: out.debug << "Convert int64 to bool"; break;
case EOpConvUint64ToBool: out.debug << "Convert uint64 to bool"; break;
case EOpConvIntToFloat: out.debug << "Convert int to float"; break;
case EOpConvUintToFloat: out.debug << "Convert uint to float"; break;
case EOpConvDoubleToFloat: out.debug << "Convert double to float"; break;
case EOpConvInt64ToFloat: out.debug << "Convert int64 to float"; break;
case EOpConvUint64ToFloat: out.debug << "Convert uint64 to float"; break;
case EOpConvBoolToFloat: out.debug << "Convert bool to float"; break;
case EOpConvUintToInt: out.debug << "Convert uint to int"; break;
case EOpConvFloatToInt: out.debug << "Convert float to int"; break;
case EOpConvDoubleToInt: out.debug << "Convert double to int"; break;
case EOpConvBoolToInt: out.debug << "Convert bool to int"; break;
case EOpConvInt64ToInt: out.debug << "Convert int64 to int"; break;
case EOpConvUint64ToInt: out.debug << "Convert uint64 to int"; break;
case EOpConvIntToUint: out.debug << "Convert int to uint"; break;
case EOpConvFloatToUint: out.debug << "Convert float to uint"; break;
case EOpConvDoubleToUint: out.debug << "Convert double to uint"; break;
case EOpConvBoolToUint: out.debug << "Convert bool to uint"; break;
case EOpConvInt64ToUint: out.debug << "Convert int64 to uint"; break;
case EOpConvUint64ToUint: out.debug << "Convert uint64 to uint"; break;
case EOpConvIntToDouble: out.debug << "Convert int to double"; break;
case EOpConvUintToDouble: out.debug << "Convert uint to double"; break;
case EOpConvFloatToDouble: out.debug << "Convert float to double"; break;
case EOpConvBoolToDouble: out.debug << "Convert bool to double"; break;
case EOpConvInt64ToDouble: out.debug << "Convert int64 to double"; break;
case EOpConvUint64ToDouble: out.debug << "Convert uint64 to double"; break;
case EOpConvBoolToInt64: out.debug << "Convert bool to int64"; break;
case EOpConvIntToInt64: out.debug << "Convert int to int64"; break;
case EOpConvUintToInt64: out.debug << "Convert uint to int64"; break;
case EOpConvFloatToInt64: out.debug << "Convert float to int64"; break;
case EOpConvDoubleToInt64: out.debug << "Convert double to int64"; break;
case EOpConvUint64ToInt64: out.debug << "Convert uint64 to int64"; break;
case EOpConvBoolToUint64: out.debug << "Convert bool to uint64"; break;
case EOpConvIntToUint64: out.debug << "Convert int to uint64"; break;
case EOpConvUintToUint64: out.debug << "Convert uint to uint64"; break;
case EOpConvFloatToUint64: out.debug << "Convert float to uint64"; break;
case EOpConvDoubleToUint64: out.debug << "Convert double to uint64"; break;
case EOpConvInt64ToUint64: out.debug << "Convert uint64 to uint64"; break;
case EOpRadians: out.debug << "radians"; break;
case EOpDegrees: out.debug << "degrees"; break;
......@@ -261,6 +283,10 @@ bool TOutputTraverser::visitUnary(TVisit /* visit */, TIntermUnary* node)
case EOpFloatBitsToUint:out.debug << "floatBitsToUint"; break;
case EOpIntBitsToFloat: out.debug << "intBitsToFloat"; break;
case EOpUintBitsToFloat:out.debug << "uintBitsToFloat"; break;
case EOpDoubleBitsToInt64: out.debug << "doubleBitsToInt64"; break;
case EOpDoubleBitsToUint64: out.debug << "doubleBitsToUint64"; break;
case EOpInt64BitsToDouble: out.debug << "int64BitsToDouble"; break;
case EOpUint64BitsToDouble: out.debug << "uint64BitsToDouble"; break;
case EOpPackSnorm2x16: out.debug << "packSnorm2x16"; break;
case EOpUnpackSnorm2x16:out.debug << "unpackSnorm2x16"; break;
case EOpPackUnorm2x16: out.debug << "packUnorm2x16"; break;
......@@ -275,6 +301,11 @@ bool TOutputTraverser::visitUnary(TVisit /* visit */, TIntermUnary* node)
case EOpPackDouble2x32: out.debug << "PackDouble2x32"; break;
case EOpUnpackDouble2x32: out.debug << "UnpackDouble2x32"; break;
case EOpPackInt2x32: out.debug << "packInt2x32"; break;
case EOpUnpackInt2x32: out.debug << "unpackInt2x32"; break;
case EOpPackUint2x32: out.debug << "packUint2x32"; break;
case EOpUnpackUint2x32: out.debug << "unpackUint2x32"; break;
case EOpLength: out.debug << "length"; break;
case EOpNormalize: out.debug << "normalize"; break;
case EOpDPdx: out.debug << "dPdx"; break;
......@@ -366,6 +397,14 @@ bool TOutputTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node
case EOpConstructUVec2: out.debug << "Construct uvec2"; break;
case EOpConstructUVec3: out.debug << "Construct uvec3"; break;
case EOpConstructUVec4: out.debug << "Construct uvec4"; break;
case EOpConstructInt64: out.debug << "Construct int64_t"; break;
case EOpConstructI64Vec2: out.debug << "Construct i64vec2"; break;
case EOpConstructI64Vec3: out.debug << "Construct i64vec3"; break;
case EOpConstructI64Vec4: out.debug << "Construct i64vec4"; break;
case EOpConstructUint64: out.debug << "Construct uint64_t"; break;
case EOpConstructU64Vec2: out.debug << "Construct u64vec2"; break;
case EOpConstructU64Vec3: out.debug << "Construct u64vec3"; break;
case EOpConstructU64Vec4: out.debug << "Construct u64vec4"; break;
case EOpConstructMat2x2: out.debug << "Construct mat2"; break;
case EOpConstructMat2x3: out.debug << "Construct mat2x3"; break;
case EOpConstructMat2x4: out.debug << "Construct mat2x4"; break;
......@@ -582,6 +621,24 @@ static void OutputConstantUnion(TInfoSink& out, const TIntermTyped* node, const
out.debug << buf << "\n";
}
break;
case EbtInt64:
{
const int maxSize = 300;
char buf[maxSize];
snprintf(buf, maxSize, "%lld (%s)", constUnion[i].getI64Const(), "const int64_t");
out.debug << buf << "\n";
}
break;
case EbtUint64:
{
const int maxSize = 300;
char buf[maxSize];
snprintf(buf, maxSize, "%llu (%s)", constUnion[i].getU64Const(), "const uint64_t");
out.debug << buf << "\n";
}
break;
default:
out.info.message(EPrefixInternalError, "Unknown constant", node->getLoc());
break;
......
......@@ -880,6 +880,8 @@ const int baseAlignmentVec4Std140 = 16;
int TIntermediate::getBaseAlignmentScalar(const TType& type, int& size)
{
switch (type.getBasicType()) {
case EbtInt64:
case EbtUint64:
case EbtDouble: size = 8; return 8;
default: size = 4; return 4;
}
......
......@@ -191,6 +191,8 @@ public:
TIntermConstantUnion* addConstantUnion(const TConstUnionArray&, const TType&, const TSourceLoc&, bool literal = false) const;
TIntermConstantUnion* addConstantUnion(int, const TSourceLoc&, bool literal = false) const;
TIntermConstantUnion* addConstantUnion(unsigned int, const TSourceLoc&, bool literal = false) const;
TIntermConstantUnion* addConstantUnion(long long, const TSourceLoc&, bool literal = false) const;
TIntermConstantUnion* addConstantUnion(unsigned long long, const TSourceLoc&, bool literal = false) const;
TIntermConstantUnion* addConstantUnion(bool, const TSourceLoc&, bool literal = false) const;
TIntermConstantUnion* addConstantUnion(double, TBasicType, const TSourceLoc&, bool literal = false) const;
TIntermTyped* promoteConstantUnion(TBasicType, TIntermConstantUnion*) const;
......
......@@ -76,6 +76,7 @@ public:
virtual void updateExtensionBehavior(int line, const char* const extension, const char* behavior);
virtual void fullIntegerCheck(const TSourceLoc&, const char* op);
virtual void doubleCheck(const TSourceLoc&, const char* op);
virtual void int64Check(const TSourceLoc&, const char* op, bool builtIn = false);
virtual void spvRemoved(const TSourceLoc&, const char* op);
virtual void vulkanRemoved(const TSourceLoc&, const char* op);
virtual void requireVulkan(const TSourceLoc&, const char* op);
......
......@@ -705,7 +705,8 @@ int TPpContext::CPPerror(TPpToken* ppToken)
TSourceLoc loc = ppToken->loc;
while (token != '\n' && token != EndOfInput) {
if (token == PpAtomConstInt || token == PpAtomConstUint ||
if (token == PpAtomConstInt || token == PpAtomConstUint ||
token == PpAtomConstInt64 || token == PpAtomConstUint64 ||
token == PpAtomConstFloat || token == PpAtomConstDouble) {
message.append(ppToken->name);
} else if (token == PpAtomIdentifier || token == PpAtomConstString) {
......@@ -736,6 +737,8 @@ int TPpContext::CPPpragma(TPpToken* ppToken)
case PpAtomIdentifier:
case PpAtomConstInt:
case PpAtomConstUint:
case PpAtomConstInt64:
case PpAtomConstUint64:
case PpAtomConstFloat:
case PpAtomConstDouble:
tokens.push_back(ppToken->name);
......
......@@ -111,6 +111,7 @@ public:
bool space; // true if a space (for white space or a removed comment) should also be recognized, in front of the token returned
int ival;
double dval;
long long i64val;
int atom;
char name[MaxTokenLength + 1];
};
......
......@@ -141,6 +141,8 @@ void TPpContext::RecordToken(TokenStream *pTok, int token, TPpToken* ppToken)
break;
case PpAtomConstInt:
case PpAtomConstUint:
case PpAtomConstInt64:
case PpAtomConstUint64:
case PpAtomConstFloat:
case PpAtomConstDouble:
str = ppToken->name;
......@@ -193,6 +195,8 @@ int TPpContext::ReadToken(TokenStream *pTok, TPpToken *ppToken)
case PpAtomConstDouble:
case PpAtomConstInt:
case PpAtomConstUint:
case PpAtomConstInt64:
case PpAtomConstUint64:
len = 0;
ch = lReadByte(pTok);
while (ch != 0 && ch != EndOfInput) {
......@@ -227,6 +231,16 @@ int TPpContext::ReadToken(TokenStream *pTok, TPpToken *ppToken)
} else
ppToken->ival = atoi(ppToken->name);
break;
case PpAtomConstInt64:
case PpAtomConstUint64:
if (len > 0 && tokenText[0] == '0') {
if (len > 1 && (tokenText[1] == 'x' || tokenText[1] == 'X'))
ppToken->i64val = std::stoll(ppToken->name, 0, 16);
else
ppToken->i64val = std::stoll(ppToken->name, 0, 8);
} else
ppToken->i64val = std::stoll(ppToken->name);
break;
}
}
......
......@@ -119,6 +119,8 @@ enum EFixedAtoms {
PpAtomConstInt,
PpAtomConstUint,
PpAtomConstInt64,
PpAtomConstUint64,
PpAtomConstFloat,
PpAtomConstDouble,
PpAtomConstString,
......
......@@ -540,6 +540,8 @@ public:
case EbtDouble: return GL_DOUBLE_VEC2 + offset;
case EbtInt: return GL_INT_VEC2 + offset;
case EbtUint: return GL_UNSIGNED_INT_VEC2 + offset;
case EbtInt64: return GL_INT64_ARB + offset;
case EbtUint64: return GL_UNSIGNED_INT64_ARB + offset;
case EbtBool: return GL_BOOL_VEC2 + offset;
case EbtAtomicUint: return GL_UNSIGNED_INT_ATOMIC_COUNTER + offset;
default: return 0;
......@@ -605,6 +607,8 @@ public:
case EbtDouble: return GL_DOUBLE;
case EbtInt: return GL_INT;
case EbtUint: return GL_UNSIGNED_INT;
case EbtInt64: return GL_INT64_ARB;
case EbtUint64: return GL_UNSIGNED_INT64_ARB;
case EbtBool: return GL_BOOL;
case EbtAtomicUint: return GL_UNSIGNED_INT_ATOMIC_COUNTER;
default: return 0;
......
......@@ -119,6 +119,7 @@ INSTANTIATE_TEST_CASE_P(
"spv.functionCall.frag",
"spv.functionSemantics.frag",
"spv.interpOps.frag",
"spv.int64.frag",
"spv.layoutNested.vert",
"spv.length.frag",
"spv.localAggregates.frag",
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment