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 ...@@ -606,7 +606,7 @@ Id Builder::findScalarConstant(Op typeClass, Op opcode, Id typeId, unsigned valu
return 0; 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 Id Builder::findScalarConstant(Op typeClass, Op opcode, Id typeId, unsigned v1, unsigned v2) const
{ {
Instruction* constant; Instruction* constant;
...@@ -711,6 +711,31 @@ Id Builder::makeIntConstant(Id typeId, unsigned value, bool specConstant) ...@@ -711,6 +711,31 @@ Id Builder::makeIntConstant(Id typeId, unsigned value, bool specConstant)
return c->getResultId(); 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) Id Builder::makeFloatConstant(float f, bool specConstant)
{ {
Op opcode = specConstant ? OpSpecConstant : OpConstant; Op opcode = specConstant ? OpSpecConstant : OpConstant;
......
...@@ -188,6 +188,8 @@ public: ...@@ -188,6 +188,8 @@ public:
Id makeBoolConstant(bool b, bool specConstant = false); Id makeBoolConstant(bool b, bool specConstant = false);
Id makeIntConstant(int i, bool specConstant = false) { return makeIntConstant(makeIntType(32), (unsigned)i, specConstant); } 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 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 makeFloatConstant(float f, bool specConstant = false);
Id makeDoubleConstant(double d, bool specConstant = false); Id makeDoubleConstant(double d, bool specConstant = false);
...@@ -533,6 +535,7 @@ public: ...@@ -533,6 +535,7 @@ public:
protected: protected:
Id makeIntConstant(Id typeId, unsigned value, bool specConstant); 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 value) const;
Id findScalarConstant(Op typeClass, Op opcode, Id typeId, unsigned v1, unsigned v2) const; Id findScalarConstant(Op typeClass, Op opcode, Id typeId, unsigned v1, unsigned v2) const;
Id findCompositeConstant(Op typeClass, std::vector<Id>& comps) 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 ...@@ -53,6 +53,7 @@ spv.forwardFun.frag
spv.functionCall.frag spv.functionCall.frag
spv.functionSemantics.frag spv.functionSemantics.frag
spv.interpOps.frag spv.interpOps.frag
spv.int64.frag
spv.layoutNested.vert spv.layoutNested.vert
spv.length.frag spv.length.frag
spv.localAggregates.frag spv.localAggregates.frag
......
...@@ -48,6 +48,8 @@ enum TBasicType { ...@@ -48,6 +48,8 @@ enum TBasicType {
EbtDouble, EbtDouble,
EbtInt, EbtInt,
EbtUint, EbtUint,
EbtInt64,
EbtUint64,
EbtBool, EbtBool,
EbtAtomicUint, EbtAtomicUint,
EbtSampler, EbtSampler,
......
...@@ -182,6 +182,8 @@ struct TSampler { // misnomer now; includes images, textures without sampler, ...@@ -182,6 +182,8 @@ struct TSampler { // misnomer now; includes images, textures without sampler,
case EbtFloat: break; case EbtFloat: break;
case EbtInt: s.append("i"); break; case EbtInt: s.append("i"); break;
case EbtUint: s.append("u"); 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 default: break; // some compilers want this
} }
if (image) { if (image) {
...@@ -1319,6 +1321,8 @@ public: ...@@ -1319,6 +1321,8 @@ public:
case EbtDouble: case EbtDouble:
case EbtInt: case EbtInt:
case EbtUint: case EbtUint:
case EbtInt64:
case EbtUint64:
case EbtBool: case EbtBool:
return true; return true;
default: default:
...@@ -1409,6 +1413,8 @@ public: ...@@ -1409,6 +1413,8 @@ public:
case EbtDouble: return "double"; case EbtDouble: return "double";
case EbtInt: return "int"; case EbtInt: return "int";
case EbtUint: return "uint"; case EbtUint: return "uint";
case EbtInt64: return "int64_t";
case EbtUint64: return "uint64_t";
case EbtBool: return "bool"; case EbtBool: return "bool";
case EbtAtomicUint: return "atomic_uint"; case EbtAtomicUint: return "atomic_uint";
case EbtSampler: return "sampler/image"; case EbtSampler: return "sampler/image";
......
...@@ -81,22 +81,44 @@ enum TOperator { ...@@ -81,22 +81,44 @@ enum TOperator {
EOpConvUintToBool, EOpConvUintToBool,
EOpConvFloatToBool, EOpConvFloatToBool,
EOpConvDoubleToBool, EOpConvDoubleToBool,
EOpConvInt64ToBool,
EOpConvUint64ToBool,
EOpConvBoolToFloat, EOpConvBoolToFloat,
EOpConvIntToFloat, EOpConvIntToFloat,
EOpConvUintToFloat, EOpConvUintToFloat,
EOpConvDoubleToFloat, EOpConvDoubleToFloat,
EOpConvInt64ToFloat,
EOpConvUint64ToFloat,
EOpConvUintToInt, EOpConvUintToInt,
EOpConvFloatToInt, EOpConvFloatToInt,
EOpConvBoolToInt, EOpConvBoolToInt,
EOpConvDoubleToInt, EOpConvDoubleToInt,
EOpConvInt64ToInt,
EOpConvUint64ToInt,
EOpConvIntToUint, EOpConvIntToUint,
EOpConvFloatToUint, EOpConvFloatToUint,
EOpConvBoolToUint, EOpConvBoolToUint,
EOpConvDoubleToUint, EOpConvDoubleToUint,
EOpConvInt64ToUint,
EOpConvUint64ToUint,
EOpConvIntToDouble, EOpConvIntToDouble,
EOpConvUintToDouble, EOpConvUintToDouble,
EOpConvFloatToDouble, EOpConvFloatToDouble,
EOpConvBoolToDouble, EOpConvBoolToDouble,
EOpConvInt64ToDouble,
EOpConvUint64ToDouble,
EOpConvBoolToInt64,
EOpConvIntToInt64,
EOpConvUintToInt64,
EOpConvFloatToInt64,
EOpConvDoubleToInt64,
EOpConvUint64ToInt64,
EOpConvBoolToUint64,
EOpConvIntToUint64,
EOpConvUintToUint64,
EOpConvFloatToUint64,
EOpConvDoubleToUint64,
EOpConvInt64ToUint64,
// //
// binary operations // binary operations
...@@ -194,6 +216,10 @@ enum TOperator { ...@@ -194,6 +216,10 @@ enum TOperator {
EOpFloatBitsToUint, EOpFloatBitsToUint,
EOpIntBitsToFloat, EOpIntBitsToFloat,
EOpUintBitsToFloat, EOpUintBitsToFloat,
EOpDoubleBitsToInt64,
EOpDoubleBitsToUint64,
EOpInt64BitsToDouble,
EOpUint64BitsToDouble,
EOpPackSnorm2x16, EOpPackSnorm2x16,
EOpUnpackSnorm2x16, EOpUnpackSnorm2x16,
EOpPackUnorm2x16, EOpPackUnorm2x16,
...@@ -206,6 +232,10 @@ enum TOperator { ...@@ -206,6 +232,10 @@ enum TOperator {
EOpUnpackHalf2x16, EOpUnpackHalf2x16,
EOpPackDouble2x32, EOpPackDouble2x32,
EOpUnpackDouble2x32, EOpUnpackDouble2x32,
EOpPackInt2x32,
EOpUnpackInt2x32,
EOpPackUint2x32,
EOpUnpackUint2x32,
EOpLength, EOpLength,
EOpDistance, EOpDistance,
...@@ -287,6 +317,8 @@ enum TOperator { ...@@ -287,6 +317,8 @@ enum TOperator {
EOpConstructGuardStart, EOpConstructGuardStart,
EOpConstructInt, // these first scalar forms also identify what implicit conversion is needed EOpConstructInt, // these first scalar forms also identify what implicit conversion is needed
EOpConstructUint, EOpConstructUint,
EOpConstructInt64,
EOpConstructUint64,
EOpConstructBool, EOpConstructBool,
EOpConstructFloat, EOpConstructFloat,
EOpConstructDouble, EOpConstructDouble,
...@@ -305,6 +337,12 @@ enum TOperator { ...@@ -305,6 +337,12 @@ enum TOperator {
EOpConstructUVec2, EOpConstructUVec2,
EOpConstructUVec3, EOpConstructUVec3,
EOpConstructUVec4, EOpConstructUVec4,
EOpConstructI64Vec2,
EOpConstructI64Vec3,
EOpConstructI64Vec4,
EOpConstructU64Vec2,
EOpConstructU64Vec3,
EOpConstructU64Vec4,
EOpConstructMat2x2, EOpConstructMat2x2,
EOpConstructMat2x3, EOpConstructMat2x3,
EOpConstructMat2x4, EOpConstructMat2x4,
......
...@@ -194,6 +194,22 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TIntermTyped* right ...@@ -194,6 +194,22 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TIntermTyped* right
} else } else
newConstArray[i].setUConst(leftUnionArray[i].getUConst() / rightUnionArray[i].getUConst()); newConstArray[i].setUConst(leftUnionArray[i].getUConst() / rightUnionArray[i].getUConst());
break; 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: default:
return 0; return 0;
} }
...@@ -419,6 +435,8 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType) ...@@ -419,6 +435,8 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType)
case EbtFloat: newConstArray[i].setDConst(-unionArray[i].getDConst()); break; case EbtFloat: newConstArray[i].setDConst(-unionArray[i].getDConst()); break;
case EbtInt: newConstArray[i].setIConst(-unionArray[i].getIConst()); 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 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: default:
return 0; return 0;
} }
...@@ -566,6 +584,8 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType) ...@@ -566,6 +584,8 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType)
case EOpFloatBitsToUint: case EOpFloatBitsToUint:
case EOpIntBitsToFloat: case EOpIntBitsToFloat:
case EOpUintBitsToFloat: case EOpUintBitsToFloat:
case EOpDoubleBitsToInt64:
case EOpDoubleBitsToUint64:
default: default:
return 0; return 0;
...@@ -651,7 +671,10 @@ TIntermTyped* TIntermediate::fold(TIntermAggregate* aggrNode) ...@@ -651,7 +671,10 @@ TIntermTyped* TIntermediate::fold(TIntermAggregate* aggrNode)
bool isFloatingPoint = children[0]->getAsTyped()->getBasicType() == EbtFloat || bool isFloatingPoint = children[0]->getAsTyped()->getBasicType() == EbtFloat ||
children[0]->getAsTyped()->getBasicType() == EbtDouble; 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) { if (componentwise) {
for (int comp = 0; comp < objectSize; comp++) { for (int comp = 0; comp < objectSize; comp++) {
...@@ -674,29 +697,52 @@ TIntermTyped* TIntermediate::fold(TIntermAggregate* aggrNode) ...@@ -674,29 +697,52 @@ TIntermTyped* TIntermediate::fold(TIntermAggregate* aggrNode)
case EOpMin: case EOpMin:
if (isFloatingPoint) if (isFloatingPoint)
newConstArray[comp].setDConst(std::min(childConstUnions[0][arg0comp].getDConst(), childConstUnions[1][arg1comp].getDConst())); newConstArray[comp].setDConst(std::min(childConstUnions[0][arg0comp].getDConst(), childConstUnions[1][arg1comp].getDConst()));
else if (isSigned) else if (isSigned) {
newConstArray[comp].setIConst(std::min(childConstUnions[0][arg0comp].getIConst(), childConstUnions[1][arg1comp].getIConst())); if (isInt64)
else newConstArray[comp].setI64Const(std::min(childConstUnions[0][arg0comp].getI64Const(), childConstUnions[1][arg1comp].getI64Const()));
newConstArray[comp].setUConst(std::min(childConstUnions[0][arg0comp].getUConst(), childConstUnions[1][arg1comp].getUConst())); 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; break;
case EOpMax: case EOpMax:
if (isFloatingPoint) if (isFloatingPoint)
newConstArray[comp].setDConst(std::max(childConstUnions[0][arg0comp].getDConst(), childConstUnions[1][arg1comp].getDConst())); newConstArray[comp].setDConst(std::max(childConstUnions[0][arg0comp].getDConst(), childConstUnions[1][arg1comp].getDConst()));
else if (isSigned) else if (isSigned) {
newConstArray[comp].setIConst(std::max(childConstUnions[0][arg0comp].getIConst(), childConstUnions[1][arg1comp].getIConst())); if (isInt64)
else newConstArray[comp].setI64Const(std::max(childConstUnions[0][arg0comp].getI64Const(), childConstUnions[1][arg1comp].getI64Const()));
newConstArray[comp].setUConst(std::max(childConstUnions[0][arg0comp].getUConst(), childConstUnions[1][arg1comp].getUConst())); 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; break;
case EOpClamp: case EOpClamp:
if (isFloatingPoint) 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())); childConstUnions[2][arg2comp].getDConst()));
else if (isSigned) else if (isSigned) {
newConstArray[comp].setIConst(std::min(std::max(childConstUnions[0][arg0comp].getIConst(), childConstUnions[1][arg1comp].getIConst()), if (isInt64)
childConstUnions[2][arg2comp].getIConst())); newConstArray[comp].setI64Const(std::min(std::max(childConstUnions[0][arg0comp].getI64Const(), childConstUnions[1][arg1comp].getI64Const()),
else childConstUnions[2][arg2comp].getI64Const()));
newConstArray[comp].setUConst(std::min(std::max(childConstUnions[0][arg0comp].getUConst(), childConstUnions[1][arg1comp].getUConst()), else
childConstUnions[2][arg2comp].getUConst())); 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; break;
case EOpLessThan: case EOpLessThan:
newConstArray[comp].setBConst(childConstUnions[0][arg0comp] < childConstUnions[1][arg1comp]); newConstArray[comp].setBConst(childConstUnions[0][arg0comp] < childConstUnions[1][arg1comp]);
......
...@@ -75,6 +75,8 @@ TBuiltIns::TBuiltIns() ...@@ -75,6 +75,8 @@ TBuiltIns::TBuiltIns()
prefixes[EbtFloat] = ""; prefixes[EbtFloat] = "";
prefixes[EbtInt] = "i"; prefixes[EbtInt] = "i";
prefixes[EbtUint] = "u"; prefixes[EbtUint] = "u";
prefixes[EbtInt64] = "i64";
prefixes[EbtUint64] = "u64";
postfixes[2] = "2"; postfixes[2] = "2";
postfixes[3] = "3"; postfixes[3] = "3";
postfixes[4] = "4"; postfixes[4] = "4";
...@@ -626,6 +628,145 @@ void TBuiltIns::initialize(int version, EProfile profile, int spv, int vulkan) ...@@ -626,6 +628,145 @@ void TBuiltIns::initialize(int version, EProfile profile, int spv, int vulkan)
"dmat2 inverse(dmat2);" "dmat2 inverse(dmat2);"
"dmat3 inverse(dmat3);" "dmat3 inverse(dmat3);"
"dmat4 inverse(dmat4);" "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 ...@@ -3650,6 +3791,10 @@ void IdentifyBuiltIns(int version, EProfile profile, int spv, int vulkan, EShLan
symbolTable.relateToOperator("floatBitsToUint", EOpFloatBitsToUint); symbolTable.relateToOperator("floatBitsToUint", EOpFloatBitsToUint);
symbolTable.relateToOperator("intBitsToFloat", EOpIntBitsToFloat); symbolTable.relateToOperator("intBitsToFloat", EOpIntBitsToFloat);
symbolTable.relateToOperator("uintBitsToFloat", EOpUintBitsToFloat); 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("packSnorm2x16", EOpPackSnorm2x16);
symbolTable.relateToOperator("unpackSnorm2x16", EOpUnpackSnorm2x16); symbolTable.relateToOperator("unpackSnorm2x16", EOpUnpackSnorm2x16);
...@@ -3667,6 +3812,11 @@ void IdentifyBuiltIns(int version, EProfile profile, int spv, int vulkan, EShLan ...@@ -3667,6 +3812,11 @@ void IdentifyBuiltIns(int version, EProfile profile, int spv, int vulkan, EShLan
symbolTable.relateToOperator("packHalf2x16", EOpPackHalf2x16); symbolTable.relateToOperator("packHalf2x16", EOpPackHalf2x16);
symbolTable.relateToOperator("unpackHalf2x16", EOpUnpackHalf2x16); 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("length", EOpLength);
symbolTable.relateToOperator("distance", EOpDistance); symbolTable.relateToOperator("distance", EOpDistance);
symbolTable.relateToOperator("dot", EOpDot); symbolTable.relateToOperator("dot", EOpDot);
......
...@@ -1812,6 +1812,24 @@ TOperator TParseContext::mapTypeToConstructorOp(const TType& type) const ...@@ -1812,6 +1812,24 @@ TOperator TParseContext::mapTypeToConstructorOp(const TType& type) const
default: break; // some compilers want this default: break; // some compilers want this
} }
break; 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: case EbtBool:
switch(type.getVectorSize()) { switch(type.getVectorSize()) {
case 1: op = EOpConstructBool; break; case 1: op = EOpConstructBool; break;
...@@ -2534,13 +2552,19 @@ void TParseContext::globalQualifierTypeCheck(const TSourceLoc& loc, const TQuali ...@@ -2534,13 +2552,19 @@ void TParseContext::globalQualifierTypeCheck(const TSourceLoc& loc, const TQuali
return; 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"); profileRequires(loc, EEsProfile, 300, nullptr, "shader input/output");
if (! qualifier.flat) { if (! qualifier.flat) {
if (publicType.basicType == EbtInt || publicType.basicType == EbtUint || publicType.basicType == EbtDouble || if (publicType.basicType == EbtInt || publicType.basicType == EbtUint ||
(publicType.userDef && (publicType.userDef->containsBasicType(EbtInt) || publicType.basicType == EbtInt64 || publicType.basicType == EbtUint64 ||
publicType.userDef->containsBasicType(EbtUint) || 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)))) { publicType.userDef->containsBasicType(EbtDouble)))) {
if (qualifier.storage == EvqVaryingIn && language == EShLangFragment) if (qualifier.storage == EvqVaryingIn && language == EShLangFragment)
error(loc, "must be qualified as flat", TType::getBasicString(publicType.basicType), GetStorageQualifierString(qualifier.storage)); 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) ...@@ -4415,6 +4439,8 @@ void TParseContext::layoutTypeCheck(const TSourceLoc& loc, const TType& type)
{ {
case EbtInt: case EbtInt:
case EbtUint: case EbtUint:
case EbtInt64:
case EbtUint64:
case EbtBool: case EbtBool:
case EbtFloat: case EbtFloat:
case EbtDouble: case EbtDouble:
...@@ -5226,6 +5252,20 @@ TIntermTyped* TParseContext::constructBuiltIn(const TType& type, TOperator op, T ...@@ -5226,6 +5252,20 @@ TIntermTyped* TParseContext::constructBuiltIn(const TType& type, TOperator op, T
basicOp = EOpConstructUint; basicOp = EOpConstructUint;
break; 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 EOpConstructBVec2:
case EOpConstructBVec3: case EOpConstructBVec3:
case EOpConstructBVec4: case EOpConstructBVec4:
......
...@@ -454,6 +454,15 @@ void TScanContext::fillInKeywordMap() ...@@ -454,6 +454,15 @@ void TScanContext::fillInKeywordMap()
(*KeywordMap)["uvec3"] = UVEC3; (*KeywordMap)["uvec3"] = UVEC3;
(*KeywordMap)["uvec4"] = UVEC4; (*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)["sampler2D"] = SAMPLER2D;
(*KeywordMap)["samplerCube"] = SAMPLERCUBE; (*KeywordMap)["samplerCube"] = SAMPLERCUBE;
(*KeywordMap)["samplerCubeArray"] = SAMPLERCUBEARRAY; (*KeywordMap)["samplerCubeArray"] = SAMPLERCUBEARRAY;
...@@ -667,10 +676,12 @@ int TScanContext::tokenize(TPpContext* pp, TParserToken& token) ...@@ -667,10 +676,12 @@ int TScanContext::tokenize(TPpContext* pp, TParserToken& token)
case PpAtomDecrement: return DEC_OP; case PpAtomDecrement: return DEC_OP;
case PpAtomIncrement: return INC_OP; case PpAtomIncrement: return INC_OP;
case PpAtomConstInt: parserToken->sType.lex.i = ppToken.ival; return INTCONSTANT; case PpAtomConstInt: parserToken->sType.lex.i = ppToken.ival; return INTCONSTANT;
case PpAtomConstUint: parserToken->sType.lex.i = ppToken.ival; return UINTCONSTANT; case PpAtomConstUint: parserToken->sType.lex.i = ppToken.ival; return UINTCONSTANT;
case PpAtomConstFloat: parserToken->sType.lex.d = ppToken.dval; return FLOATCONSTANT; case PpAtomConstInt64: parserToken->sType.lex.i64 = ppToken.i64val; return INT64CONSTANT;
case PpAtomConstDouble: parserToken->sType.lex.d = ppToken.dval; return DOUBLECONSTANT; 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: case PpAtomIdentifier:
{ {
int token = tokenizeIdentifier(); int token = tokenizeIdentifier();
...@@ -914,6 +925,18 @@ int TScanContext::tokenizeIdentifier() ...@@ -914,6 +925,18 @@ int TScanContext::tokenizeIdentifier()
reservedWord(); reservedWord();
return keyword; 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 SAMPLERCUBEARRAY:
case SAMPLERCUBEARRAYSHADOW: case SAMPLERCUBEARRAYSHADOW:
case ISAMPLERCUBEARRAY: case ISAMPLERCUBEARRAY:
......
...@@ -62,6 +62,8 @@ void TType::buildMangledName(TString& mangledName) ...@@ -62,6 +62,8 @@ void TType::buildMangledName(TString& mangledName)
case EbtDouble: mangledName += 'd'; break; case EbtDouble: mangledName += 'd'; break;
case EbtInt: mangledName += 'i'; break; case EbtInt: mangledName += 'i'; break;
case EbtUint: mangledName += 'u'; break; case EbtUint: mangledName += 'u'; break;
case EbtInt64: mangledName += "i64"; break;
case EbtUint64: mangledName += "u64"; break;
case EbtBool: mangledName += 'b'; break; case EbtBool: mangledName += 'b'; break;
case EbtAtomicUint: mangledName += "au"; break; case EbtAtomicUint: mangledName += "au"; break;
case EbtSampler: case EbtSampler:
......
...@@ -174,6 +174,7 @@ void TParseVersions::initializeExtensionBehavior() ...@@ -174,6 +174,7 @@ void TParseVersions::initializeExtensionBehavior()
extensionBehavior[E_GL_ARB_derivative_control] = EBhDisable; extensionBehavior[E_GL_ARB_derivative_control] = EBhDisable;
extensionBehavior[E_GL_ARB_shader_texture_image_samples] = EBhDisable; extensionBehavior[E_GL_ARB_shader_texture_image_samples] = EBhDisable;
extensionBehavior[E_GL_ARB_viewport_array] = 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_gl_spirv] = EBhDisable;
extensionBehavior[E_GL_ARB_sparse_texture2] = EBhDisable; extensionBehavior[E_GL_ARB_sparse_texture2] = EBhDisable;
extensionBehavior[E_GL_ARB_sparse_texture_clamp] = EBhDisable; extensionBehavior[E_GL_ARB_sparse_texture_clamp] = EBhDisable;
...@@ -278,6 +279,7 @@ const char* TParseVersions::getPreamble() ...@@ -278,6 +279,7 @@ const char* TParseVersions::getPreamble()
"#define GL_ARB_derivative_control 1\n" "#define GL_ARB_derivative_control 1\n"
"#define GL_ARB_shader_texture_image_samples 1\n" "#define GL_ARB_shader_texture_image_samples 1\n"
"#define GL_ARB_viewport_array 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_gl_spirv 1\n"
"#define GL_ARB_sparse_texture2 1\n" "#define GL_ARB_sparse_texture2 1\n"
"#define GL_ARB_sparse_texture_clamp 1\n" "#define GL_ARB_sparse_texture_clamp 1\n"
...@@ -627,6 +629,17 @@ void TParseVersions::doubleCheck(const TSourceLoc& loc, const char* op) ...@@ -627,6 +629,17 @@ void TParseVersions::doubleCheck(const TSourceLoc& loc, const char* op)
profileRequires(loc, ECompatibilityProfile, 400, nullptr, 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. // Call for any operation removed because SPIR-V is in use.
void TParseVersions::spvRemoved(const TSourceLoc& loc, const char* op) 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 ...@@ -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_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_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_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_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_texture2 = "GL_ARB_sparse_texture2";
const char* const E_GL_ARB_sparse_texture_clamp = "GL_ARB_sparse_texture_clamp"; const char* const E_GL_ARB_sparse_texture_clamp = "GL_ARB_sparse_texture_clamp";
......
...@@ -41,6 +41,16 @@ ...@@ -41,6 +41,16 @@
#define GL_UNSIGNED_INT_VEC3 0x8DC7 #define GL_UNSIGNED_INT_VEC3 0x8DC7
#define GL_UNSIGNED_INT_VEC4 0x8DC8 #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 0x8B56
#define GL_BOOL_VEC2 0x8B57 #define GL_BOOL_VEC2 0x8B57
#define GL_BOOL_VEC3 0x8B58 #define GL_BOOL_VEC3 0x8B58
......
...@@ -70,6 +70,8 @@ using namespace glslang; ...@@ -70,6 +70,8 @@ using namespace glslang;
glslang::TString *string; glslang::TString *string;
int i; int i;
unsigned int u; unsigned int u;
long long i64;
unsigned long long u64;
bool b; bool b;
double d; double d;
}; };
...@@ -117,9 +119,9 @@ extern int yylex(YYSTYPE*, TParseContext&); ...@@ -117,9 +119,9 @@ extern int yylex(YYSTYPE*, TParseContext&);
%expect 1 // One shift reduce conflict because of if | else %expect 1 // One shift reduce conflict because of if | else
%token <lex> ATTRIBUTE VARYING %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> 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> MAT2 MAT3 MAT4 CENTROID IN OUT INOUT
%token <lex> UNIFORM PATCH SAMPLE BUFFER SHARED %token <lex> UNIFORM PATCH SAMPLE BUFFER SHARED
%token <lex> COHERENT VOLATILE RESTRICT READONLY WRITEONLY %token <lex> COHERENT VOLATILE RESTRICT READONLY WRITEONLY
...@@ -180,7 +182,7 @@ extern int yylex(YYSTYPE*, TParseContext&); ...@@ -180,7 +182,7 @@ extern int yylex(YYSTYPE*, TParseContext&);
%token <lex> STRUCT VOID WHILE %token <lex> STRUCT VOID WHILE
%token <lex> IDENTIFIER TYPE_NAME %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> LEFT_OP RIGHT_OP
%token <lex> INC_OP DEC_OP LE_OP GE_OP EQ_OP NE_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 %token <lex> AND_OP OR_OP XOR_OP MUL_ASSIGN DIV_ASSIGN ADD_ASSIGN
...@@ -257,6 +259,14 @@ primary_expression ...@@ -257,6 +259,14 @@ primary_expression
parseContext.fullIntegerCheck($1.loc, "unsigned literal"); parseContext.fullIntegerCheck($1.loc, "unsigned literal");
$$ = parseContext.intermediate.addConstantUnion($1.u, $1.loc, true); $$ = 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 { | FLOATCONSTANT {
$$ = parseContext.intermediate.addConstantUnion($1.d, EbtFloat, $1.loc, true); $$ = parseContext.intermediate.addConstantUnion($1.d, EbtFloat, $1.loc, true);
} }
...@@ -1309,6 +1319,16 @@ type_specifier_nonarray ...@@ -1309,6 +1319,16 @@ type_specifier_nonarray
$$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
$$.basicType = EbtUint; $$.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 { | BOOL {
$$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
$$.basicType = EbtBool; $$.basicType = EbtBool;
...@@ -1376,6 +1396,24 @@ type_specifier_nonarray ...@@ -1376,6 +1396,24 @@ type_specifier_nonarray
$$.basicType = EbtInt; $$.basicType = EbtInt;
$$.setVector(4); $$.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 { | UVEC2 {
parseContext.fullIntegerCheck($1.loc, "unsigned integer vector"); parseContext.fullIntegerCheck($1.loc, "unsigned integer vector");
$$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
...@@ -1394,6 +1432,24 @@ type_specifier_nonarray ...@@ -1394,6 +1432,24 @@ type_specifier_nonarray
$$.basicType = EbtUint; $$.basicType = EbtUint;
$$.setVector(4); $$.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 { | MAT2 {
$$.init($1.loc, parseContext.symbolTable.atGlobalLevel()); $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
$$.basicType = EbtFloat; $$.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) ...@@ -206,22 +206,44 @@ bool TOutputTraverser::visitUnary(TVisit /* visit */, TIntermUnary* node)
case EOpConvUintToBool: out.debug << "Convert uint to bool"; break; case EOpConvUintToBool: out.debug << "Convert uint to bool"; break;
case EOpConvFloatToBool: out.debug << "Convert float to bool"; break; case EOpConvFloatToBool: out.debug << "Convert float to bool"; break;
case EOpConvDoubleToBool: out.debug << "Convert double 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 EOpConvIntToFloat: out.debug << "Convert int to float"; break;
case EOpConvUintToFloat: out.debug << "Convert uint to float"; break; case EOpConvUintToFloat: out.debug << "Convert uint to float"; break;
case EOpConvDoubleToFloat: out.debug << "Convert double 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 EOpConvBoolToFloat: out.debug << "Convert bool to float"; break;
case EOpConvUintToInt: out.debug << "Convert uint to int"; break; case EOpConvUintToInt: out.debug << "Convert uint to int"; break;
case EOpConvFloatToInt: out.debug << "Convert float to int"; break; case EOpConvFloatToInt: out.debug << "Convert float to int"; break;
case EOpConvDoubleToInt: out.debug << "Convert double to int"; break; case EOpConvDoubleToInt: out.debug << "Convert double to int"; break;
case EOpConvBoolToInt: out.debug << "Convert bool 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 EOpConvIntToUint: out.debug << "Convert int to uint"; break;
case EOpConvFloatToUint: out.debug << "Convert float to uint"; break; case EOpConvFloatToUint: out.debug << "Convert float to uint"; break;
case EOpConvDoubleToUint: out.debug << "Convert double to uint"; break; case EOpConvDoubleToUint: out.debug << "Convert double to uint"; break;
case EOpConvBoolToUint: out.debug << "Convert bool 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 EOpConvIntToDouble: out.debug << "Convert int to double"; break;
case EOpConvUintToDouble: out.debug << "Convert uint to double"; break; case EOpConvUintToDouble: out.debug << "Convert uint to double"; break;
case EOpConvFloatToDouble: out.debug << "Convert float to double"; break; case EOpConvFloatToDouble: out.debug << "Convert float to double"; break;
case EOpConvBoolToDouble: out.debug << "Convert bool 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 EOpRadians: out.debug << "radians"; break;
case EOpDegrees: out.debug << "degrees"; break; case EOpDegrees: out.debug << "degrees"; break;
...@@ -261,6 +283,10 @@ bool TOutputTraverser::visitUnary(TVisit /* visit */, TIntermUnary* node) ...@@ -261,6 +283,10 @@ bool TOutputTraverser::visitUnary(TVisit /* visit */, TIntermUnary* node)
case EOpFloatBitsToUint:out.debug << "floatBitsToUint"; break; case EOpFloatBitsToUint:out.debug << "floatBitsToUint"; break;
case EOpIntBitsToFloat: out.debug << "intBitsToFloat"; break; case EOpIntBitsToFloat: out.debug << "intBitsToFloat"; break;
case EOpUintBitsToFloat:out.debug << "uintBitsToFloat"; 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 EOpPackSnorm2x16: out.debug << "packSnorm2x16"; break;
case EOpUnpackSnorm2x16:out.debug << "unpackSnorm2x16"; break; case EOpUnpackSnorm2x16:out.debug << "unpackSnorm2x16"; break;
case EOpPackUnorm2x16: out.debug << "packUnorm2x16"; break; case EOpPackUnorm2x16: out.debug << "packUnorm2x16"; break;
...@@ -275,6 +301,11 @@ bool TOutputTraverser::visitUnary(TVisit /* visit */, TIntermUnary* node) ...@@ -275,6 +301,11 @@ bool TOutputTraverser::visitUnary(TVisit /* visit */, TIntermUnary* node)
case EOpPackDouble2x32: out.debug << "PackDouble2x32"; break; case EOpPackDouble2x32: out.debug << "PackDouble2x32"; break;
case EOpUnpackDouble2x32: out.debug << "UnpackDouble2x32"; 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 EOpLength: out.debug << "length"; break;
case EOpNormalize: out.debug << "normalize"; break; case EOpNormalize: out.debug << "normalize"; break;
case EOpDPdx: out.debug << "dPdx"; break; case EOpDPdx: out.debug << "dPdx"; break;
...@@ -366,6 +397,14 @@ bool TOutputTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node ...@@ -366,6 +397,14 @@ bool TOutputTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node
case EOpConstructUVec2: out.debug << "Construct uvec2"; break; case EOpConstructUVec2: out.debug << "Construct uvec2"; break;
case EOpConstructUVec3: out.debug << "Construct uvec3"; break; case EOpConstructUVec3: out.debug << "Construct uvec3"; break;
case EOpConstructUVec4: out.debug << "Construct uvec4"; 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 EOpConstructMat2x2: out.debug << "Construct mat2"; break;
case EOpConstructMat2x3: out.debug << "Construct mat2x3"; break; case EOpConstructMat2x3: out.debug << "Construct mat2x3"; break;
case EOpConstructMat2x4: out.debug << "Construct mat2x4"; break; case EOpConstructMat2x4: out.debug << "Construct mat2x4"; break;
...@@ -582,6 +621,24 @@ static void OutputConstantUnion(TInfoSink& out, const TIntermTyped* node, const ...@@ -582,6 +621,24 @@ static void OutputConstantUnion(TInfoSink& out, const TIntermTyped* node, const
out.debug << buf << "\n"; out.debug << buf << "\n";
} }
break; 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: default:
out.info.message(EPrefixInternalError, "Unknown constant", node->getLoc()); out.info.message(EPrefixInternalError, "Unknown constant", node->getLoc());
break; break;
......
...@@ -880,6 +880,8 @@ const int baseAlignmentVec4Std140 = 16; ...@@ -880,6 +880,8 @@ const int baseAlignmentVec4Std140 = 16;
int TIntermediate::getBaseAlignmentScalar(const TType& type, int& size) int TIntermediate::getBaseAlignmentScalar(const TType& type, int& size)
{ {
switch (type.getBasicType()) { switch (type.getBasicType()) {
case EbtInt64:
case EbtUint64:
case EbtDouble: size = 8; return 8; case EbtDouble: size = 8; return 8;
default: size = 4; return 4; default: size = 4; return 4;
} }
......
...@@ -191,6 +191,8 @@ public: ...@@ -191,6 +191,8 @@ public:
TIntermConstantUnion* addConstantUnion(const TConstUnionArray&, const TType&, const TSourceLoc&, bool literal = false) const; TIntermConstantUnion* addConstantUnion(const TConstUnionArray&, const TType&, const TSourceLoc&, bool literal = false) const;
TIntermConstantUnion* addConstantUnion(int, 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(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(bool, const TSourceLoc&, bool literal = false) const;
TIntermConstantUnion* addConstantUnion(double, TBasicType, const TSourceLoc&, bool literal = false) const; TIntermConstantUnion* addConstantUnion(double, TBasicType, const TSourceLoc&, bool literal = false) const;
TIntermTyped* promoteConstantUnion(TBasicType, TIntermConstantUnion*) const; TIntermTyped* promoteConstantUnion(TBasicType, TIntermConstantUnion*) const;
......
...@@ -76,6 +76,7 @@ public: ...@@ -76,6 +76,7 @@ public:
virtual void updateExtensionBehavior(int line, const char* const extension, const char* behavior); virtual void updateExtensionBehavior(int line, const char* const extension, const char* behavior);
virtual void fullIntegerCheck(const TSourceLoc&, const char* op); virtual void fullIntegerCheck(const TSourceLoc&, const char* op);
virtual void doubleCheck(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 spvRemoved(const TSourceLoc&, const char* op);
virtual void vulkanRemoved(const TSourceLoc&, const char* op); virtual void vulkanRemoved(const TSourceLoc&, const char* op);
virtual void requireVulkan(const TSourceLoc&, const char* op); virtual void requireVulkan(const TSourceLoc&, const char* op);
......
...@@ -705,7 +705,8 @@ int TPpContext::CPPerror(TPpToken* ppToken) ...@@ -705,7 +705,8 @@ int TPpContext::CPPerror(TPpToken* ppToken)
TSourceLoc loc = ppToken->loc; TSourceLoc loc = ppToken->loc;
while (token != '\n' && token != EndOfInput) { while (token != '\n' && token != EndOfInput) {
if (token == PpAtomConstInt || token == PpAtomConstUint || if (token == PpAtomConstInt || token == PpAtomConstUint ||
token == PpAtomConstInt64 || token == PpAtomConstUint64 ||
token == PpAtomConstFloat || token == PpAtomConstDouble) { token == PpAtomConstFloat || token == PpAtomConstDouble) {
message.append(ppToken->name); message.append(ppToken->name);
} else if (token == PpAtomIdentifier || token == PpAtomConstString) { } else if (token == PpAtomIdentifier || token == PpAtomConstString) {
...@@ -736,6 +737,8 @@ int TPpContext::CPPpragma(TPpToken* ppToken) ...@@ -736,6 +737,8 @@ int TPpContext::CPPpragma(TPpToken* ppToken)
case PpAtomIdentifier: case PpAtomIdentifier:
case PpAtomConstInt: case PpAtomConstInt:
case PpAtomConstUint: case PpAtomConstUint:
case PpAtomConstInt64:
case PpAtomConstUint64:
case PpAtomConstFloat: case PpAtomConstFloat:
case PpAtomConstDouble: case PpAtomConstDouble:
tokens.push_back(ppToken->name); tokens.push_back(ppToken->name);
......
...@@ -111,6 +111,7 @@ public: ...@@ -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 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; int ival;
double dval; double dval;
long long i64val;
int atom; int atom;
char name[MaxTokenLength + 1]; char name[MaxTokenLength + 1];
}; };
......
...@@ -141,6 +141,8 @@ void TPpContext::RecordToken(TokenStream *pTok, int token, TPpToken* ppToken) ...@@ -141,6 +141,8 @@ void TPpContext::RecordToken(TokenStream *pTok, int token, TPpToken* ppToken)
break; break;
case PpAtomConstInt: case PpAtomConstInt:
case PpAtomConstUint: case PpAtomConstUint:
case PpAtomConstInt64:
case PpAtomConstUint64:
case PpAtomConstFloat: case PpAtomConstFloat:
case PpAtomConstDouble: case PpAtomConstDouble:
str = ppToken->name; str = ppToken->name;
...@@ -193,6 +195,8 @@ int TPpContext::ReadToken(TokenStream *pTok, TPpToken *ppToken) ...@@ -193,6 +195,8 @@ int TPpContext::ReadToken(TokenStream *pTok, TPpToken *ppToken)
case PpAtomConstDouble: case PpAtomConstDouble:
case PpAtomConstInt: case PpAtomConstInt:
case PpAtomConstUint: case PpAtomConstUint:
case PpAtomConstInt64:
case PpAtomConstUint64:
len = 0; len = 0;
ch = lReadByte(pTok); ch = lReadByte(pTok);
while (ch != 0 && ch != EndOfInput) { while (ch != 0 && ch != EndOfInput) {
...@@ -227,6 +231,16 @@ int TPpContext::ReadToken(TokenStream *pTok, TPpToken *ppToken) ...@@ -227,6 +231,16 @@ int TPpContext::ReadToken(TokenStream *pTok, TPpToken *ppToken)
} else } else
ppToken->ival = atoi(ppToken->name); ppToken->ival = atoi(ppToken->name);
break; 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 { ...@@ -119,6 +119,8 @@ enum EFixedAtoms {
PpAtomConstInt, PpAtomConstInt,
PpAtomConstUint, PpAtomConstUint,
PpAtomConstInt64,
PpAtomConstUint64,
PpAtomConstFloat, PpAtomConstFloat,
PpAtomConstDouble, PpAtomConstDouble,
PpAtomConstString, PpAtomConstString,
......
...@@ -540,6 +540,8 @@ public: ...@@ -540,6 +540,8 @@ public:
case EbtDouble: return GL_DOUBLE_VEC2 + offset; case EbtDouble: return GL_DOUBLE_VEC2 + offset;
case EbtInt: return GL_INT_VEC2 + offset; case EbtInt: return GL_INT_VEC2 + offset;
case EbtUint: return GL_UNSIGNED_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 EbtBool: return GL_BOOL_VEC2 + offset;
case EbtAtomicUint: return GL_UNSIGNED_INT_ATOMIC_COUNTER + offset; case EbtAtomicUint: return GL_UNSIGNED_INT_ATOMIC_COUNTER + offset;
default: return 0; default: return 0;
...@@ -605,6 +607,8 @@ public: ...@@ -605,6 +607,8 @@ public:
case EbtDouble: return GL_DOUBLE; case EbtDouble: return GL_DOUBLE;
case EbtInt: return GL_INT; case EbtInt: return GL_INT;
case EbtUint: return GL_UNSIGNED_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 EbtBool: return GL_BOOL;
case EbtAtomicUint: return GL_UNSIGNED_INT_ATOMIC_COUNTER; case EbtAtomicUint: return GL_UNSIGNED_INT_ATOMIC_COUNTER;
default: return 0; default: return 0;
......
...@@ -119,6 +119,7 @@ INSTANTIATE_TEST_CASE_P( ...@@ -119,6 +119,7 @@ INSTANTIATE_TEST_CASE_P(
"spv.functionCall.frag", "spv.functionCall.frag",
"spv.functionSemantics.frag", "spv.functionSemantics.frag",
"spv.interpOps.frag", "spv.interpOps.frag",
"spv.int64.frag",
"spv.layoutNested.vert", "spv.layoutNested.vert",
"spv.length.frag", "spv.length.frag",
"spv.localAggregates.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