Implement GL_EXT_shader_16bit_storage and GL_EXT_shader_8bit_storage extensions.

These introduce limited support for 8/16-bit types such that they can only be accessed in buffer memory and converted to/from 32-bit types.

Contributed from Khronos-internal work.
This commit is contained in:
John Kessenich 2018-07-03 13:19:51 -06:00
parent eefab240f7
commit 312dcfb070
43 changed files with 6179 additions and 2765 deletions

10
glslang/Include/Types.h Normal file → Executable file
View file

@ -1472,6 +1472,16 @@ public:
return contains([](const TType* t) { return t->isArray() && t->arraySizes->isOuterSpecialization(); } );
}
virtual bool contains16BitInt() const
{
return containsBasicType(EbtInt16) || containsBasicType(EbtUint16);
}
virtual bool contains8BitInt() const
{
return containsBasicType(EbtInt8) || containsBasicType(EbtUint8);
}
// Array editing methods. Array descriptors can be shared across
// type instances. This allows all uses of the same array
// to be updated at once. E.g., all nodes can be explicitly sized

View file

@ -1,3 +1,3 @@
// This header is generated by the make-revision script.
#define GLSLANG_PATCH_LEVEL 2796
#define GLSLANG_PATCH_LEVEL 2797

78
glslang/MachineIndependent/Intermediate.cpp Normal file → Executable file
View file

@ -881,6 +881,9 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt
// like vector and matrix sizes.
TBasicType promoteTo;
// GL_EXT_shader_16bit_storage can't do OpConstantComposite with
// 16-bit types, so disable promotion for those types.
bool canPromoteConstant = true;
switch (op) {
//
@ -897,18 +900,28 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt
break;
case EOpConstructFloat16:
promoteTo = EbtFloat16;
canPromoteConstant = extensionRequested(E_GL_KHX_shader_explicit_arithmetic_types) ||
extensionRequested(E_GL_KHX_shader_explicit_arithmetic_types_float16);
break;
case EOpConstructInt8:
promoteTo = EbtInt8;
canPromoteConstant = extensionRequested(E_GL_KHX_shader_explicit_arithmetic_types) ||
extensionRequested(E_GL_KHX_shader_explicit_arithmetic_types_int8);
break;
case EOpConstructUint8:
promoteTo = EbtUint8;
canPromoteConstant = extensionRequested(E_GL_KHX_shader_explicit_arithmetic_types) ||
extensionRequested(E_GL_KHX_shader_explicit_arithmetic_types_int8);
break;
case EOpConstructInt16:
promoteTo = EbtInt16;
canPromoteConstant = extensionRequested(E_GL_KHX_shader_explicit_arithmetic_types) ||
extensionRequested(E_GL_KHX_shader_explicit_arithmetic_types_int16);
break;
case EOpConstructUint16:
promoteTo = EbtUint16;
canPromoteConstant = extensionRequested(E_GL_KHX_shader_explicit_arithmetic_types) ||
extensionRequested(E_GL_KHX_shader_explicit_arithmetic_types_int16);
break;
case EOpConstructInt:
promoteTo = EbtInt;
@ -999,7 +1012,7 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt
return nullptr;
}
if (node->getAsConstantUnion())
if (canPromoteConstant && node->getAsConstantUnion())
return promoteConstantUnion(promoteTo, node->getAsConstantUnion());
//
@ -1468,16 +1481,16 @@ bool TIntermediate::canImplicitlyPromote(TBasicType from, TBasicType to, TOperat
case EbtUint:
case EbtInt64:
case EbtUint64:
case EbtFloat:
case EbtDouble:
return true;
#ifdef AMD_EXTENSIONS
case EbtInt16:
case EbtUint16:
return extensionRequested(E_GL_AMD_gpu_shader_int16);
case EbtFloat16:
return extensionRequested(E_GL_AMD_gpu_shader_half_float);
#endif
case EbtFloat:
case EbtDouble:
#ifdef AMD_EXTENSIONS
case EbtFloat16:
#endif
return true;
default:
return false;
}
@ -1485,17 +1498,21 @@ bool TIntermediate::canImplicitlyPromote(TBasicType from, TBasicType to, TOperat
switch (from) {
case EbtInt:
case EbtUint:
#ifdef AMD_EXTENSIONS
case EbtInt16:
case EbtUint16:
#endif
case EbtFloat:
#ifdef AMD_EXTENSIONS
case EbtFloat16:
#endif
return true;
case EbtBool:
return (source == EShSourceHlsl);
#ifdef AMD_EXTENSIONS
case EbtInt16:
case EbtUint16:
return extensionRequested(E_GL_AMD_gpu_shader_int16);
#endif
case EbtFloat16:
return
#ifdef AMD_EXTENSIONS
extensionRequested(E_GL_AMD_gpu_shader_half_float) ||
#endif
(source == EShSourceHlsl);
default:
return false;
}
@ -1504,25 +1521,27 @@ bool TIntermediate::canImplicitlyPromote(TBasicType from, TBasicType to, TOperat
case EbtInt:
return version >= 400 || (source == EShSourceHlsl);
case EbtUint:
#ifdef AMD_EXTENSIONS
case EbtInt16:
case EbtUint16:
#endif
return true;
case EbtBool:
return (source == EShSourceHlsl);
#ifdef AMD_EXTENSIONS
case EbtInt16:
case EbtUint16:
return extensionRequested(E_GL_AMD_gpu_shader_int16);
#endif
default:
return false;
}
case EbtInt:
switch (from) {
case EbtInt:
#ifdef AMD_EXTENSIONS
case EbtInt16:
#endif
return true;
case EbtBool:
return (source == EShSourceHlsl);
#ifdef AMD_EXTENSIONS
case EbtInt16:
return extensionRequested(E_GL_AMD_gpu_shader_int16);
#endif
default:
return false;
}
@ -1532,11 +1551,12 @@ bool TIntermediate::canImplicitlyPromote(TBasicType from, TBasicType to, TOperat
case EbtUint:
case EbtInt64:
case EbtUint64:
return true;
#ifdef AMD_EXTENSIONS
case EbtInt16:
case EbtUint16:
return extensionRequested(E_GL_AMD_gpu_shader_int16);
#endif
return true;
default:
return false;
}
@ -1544,32 +1564,36 @@ bool TIntermediate::canImplicitlyPromote(TBasicType from, TBasicType to, TOperat
switch (from) {
case EbtInt:
case EbtInt64:
return true;
#ifdef AMD_EXTENSIONS
case EbtInt16:
return extensionRequested(E_GL_AMD_gpu_shader_int16);
#endif
return true;
default:
return false;
}
#ifdef AMD_EXTENSIONS
case EbtFloat16:
switch (from) {
#ifdef AMD_EXTENSIONS
case EbtInt16:
case EbtUint16:
return extensionRequested(E_GL_AMD_gpu_shader_int16);
case EbtFloat16:
return true;
return extensionRequested(E_GL_AMD_gpu_shader_half_float);
#endif
default:
return false;
}
case EbtUint16:
switch (from) {
#ifdef AMD_EXTENSIONS
case EbtInt16:
case EbtUint16:
return true;
return extensionRequested(E_GL_AMD_gpu_shader_int16);
#endif
default:
return false;
}
#endif
default:
return false;
}

View file

@ -354,96 +354,109 @@ TIntermTyped* TParseContext::handleVariable(const TSourceLoc& loc, TSymbol* symb
//
TIntermTyped* TParseContext::handleBracketDereference(const TSourceLoc& loc, TIntermTyped* base, TIntermTyped* index)
{
TIntermTyped* result = nullptr;
int indexValue = 0;
if (index->getQualifier().isFrontEndConstant())
indexValue = index->getAsConstantUnion()->getConstArray()[0].getIConst();
// basic type checks...
variableCheck(base);
if (! base->isArray() && ! base->isMatrix() && ! base->isVector()) {
if (base->getAsSymbolNode())
error(loc, " left of '[' is not of type array, matrix, or vector ", base->getAsSymbolNode()->getName().c_str(), "");
else
error(loc, " left of '[' is not of type array, matrix, or vector ", "expression", "");
} else if (base->getType().getQualifier().isFrontEndConstant() && index->getQualifier().isFrontEndConstant()) {
// Insert dummy error-recovery result
return intermediate.addConstantUnion(0.0, EbtFloat, loc);
}
if (!base->isArray() && base->isVector()) {
if (base->getType().containsBasicType(EbtFloat16)) {
requireFloat16Arithmetic(loc, "'[' does not operate on types containing float16");
}
if (base->getType().contains16BitInt()) {
requireInt16Arithmetic(loc, "'[' does not operate on types containing (u)int16");
}
if (base->getType().contains8BitInt()) {
requireInt8Arithmetic(loc, "'[' does not operate on types containing (u)int8");
}
}
// check for constant folding
if (base->getType().getQualifier().isFrontEndConstant() && index->getQualifier().isFrontEndConstant()) {
// both base and index are front-end constants
checkIndex(loc, base->getType(), indexValue);
return intermediate.foldDereference(base, indexValue, loc);
} else {
// at least one of base and index is not a front-end constant variable...
}
if (index->getQualifier().isFrontEndConstant())
// at least one of base and index is not a front-end constant variable...
TIntermTyped* result = nullptr;
if (index->getQualifier().isFrontEndConstant())
checkIndex(loc, base->getType(), indexValue);
if (base->getAsSymbolNode() && isIoResizeArray(base->getType()))
handleIoResizeArrayAccess(loc, base);
if (index->getQualifier().isFrontEndConstant()) {
if (base->getType().isUnsizedArray())
base->getWritableType().updateImplicitArraySize(indexValue + 1);
else
checkIndex(loc, base->getType(), indexValue);
if (base->getAsSymbolNode() && isIoResizeArray(base->getType()))
handleIoResizeArrayAccess(loc, base);
if (index->getQualifier().isFrontEndConstant()) {
if (base->getType().isUnsizedArray())
base->getWritableType().updateImplicitArraySize(indexValue + 1);
else
checkIndex(loc, base->getType(), indexValue);
result = intermediate.addIndex(EOpIndexDirect, base, index, loc);
} else {
if (base->getType().isUnsizedArray()) {
// we have a variable index into an unsized array, which is okay,
// depending on the situation
if (base->getAsSymbolNode() && isIoResizeArray(base->getType()))
error(loc, "", "[", "array must be sized by a redeclaration or layout qualifier before being indexed with a variable");
else {
// it is okay for a run-time sized array
checkRuntimeSizable(loc, *base);
}
base->getWritableType().setArrayVariablyIndexed();
}
if (base->getBasicType() == EbtBlock) {
if (base->getQualifier().storage == EvqBuffer)
requireProfile(base->getLoc(), ~EEsProfile, "variable indexing buffer block array");
else if (base->getQualifier().storage == EvqUniform)
profileRequires(base->getLoc(), EEsProfile, 320, Num_AEP_gpu_shader5, AEP_gpu_shader5,
"variable indexing uniform block array");
else {
// input/output blocks either don't exist or can be variable indexed
}
} else if (language == EShLangFragment && base->getQualifier().isPipeOutput())
requireProfile(base->getLoc(), ~EEsProfile, "variable indexing fragment shader output array");
else if (base->getBasicType() == EbtSampler && version >= 130) {
const char* explanation = "variable indexing sampler array";
requireProfile(base->getLoc(), EEsProfile | ECoreProfile | ECompatibilityProfile, explanation);
profileRequires(base->getLoc(), EEsProfile, 320, Num_AEP_gpu_shader5, AEP_gpu_shader5, explanation);
profileRequires(base->getLoc(), ECoreProfile | ECompatibilityProfile, 400, nullptr, explanation);
}
result = intermediate.addIndex(EOpIndexIndirect, base, index, loc);
}
}
if (result == nullptr) {
// Insert dummy error-recovery result
result = intermediate.addConstantUnion(0.0, EbtFloat, loc);
result = intermediate.addIndex(EOpIndexDirect, base, index, loc);
} else {
// Insert valid dereferenced result
TType newType(base->getType(), 0); // dereferenced type
if (base->getType().getQualifier().isConstant() && index->getQualifier().isConstant()) {
newType.getQualifier().storage = EvqConst;
// If base or index is a specialization constant, the result should also be a specialization constant.
if (base->getType().getQualifier().isSpecConstant() || index->getQualifier().isSpecConstant()) {
newType.getQualifier().makeSpecConstant();
if (base->getType().isUnsizedArray()) {
// we have a variable index into an unsized array, which is okay,
// depending on the situation
if (base->getAsSymbolNode() && isIoResizeArray(base->getType()))
error(loc, "", "[", "array must be sized by a redeclaration or layout qualifier before being indexed with a variable");
else {
// it is okay for a run-time sized array
checkRuntimeSizable(loc, *base);
}
} else {
newType.getQualifier().makePartialTemporary();
base->getWritableType().setArrayVariablyIndexed();
}
if (base->getBasicType() == EbtBlock) {
if (base->getQualifier().storage == EvqBuffer)
requireProfile(base->getLoc(), ~EEsProfile, "variable indexing buffer block array");
else if (base->getQualifier().storage == EvqUniform)
profileRequires(base->getLoc(), EEsProfile, 320, Num_AEP_gpu_shader5, AEP_gpu_shader5,
"variable indexing uniform block array");
else {
// input/output blocks either don't exist or can be variable indexed
}
} else if (language == EShLangFragment && base->getQualifier().isPipeOutput())
requireProfile(base->getLoc(), ~EEsProfile, "variable indexing fragment shader output array");
else if (base->getBasicType() == EbtSampler && version >= 130) {
const char* explanation = "variable indexing sampler array";
requireProfile(base->getLoc(), EEsProfile | ECoreProfile | ECompatibilityProfile, explanation);
profileRequires(base->getLoc(), EEsProfile, 320, Num_AEP_gpu_shader5, AEP_gpu_shader5, explanation);
profileRequires(base->getLoc(), ECoreProfile | ECompatibilityProfile, 400, nullptr, explanation);
}
result->setType(newType);
// Propagate nonuniform
if (base->getQualifier().isNonUniform() || index->getQualifier().isNonUniform())
result->getWritableType().getQualifier().nonUniform = true;
if (anyIndexLimits)
handleIndexLimits(loc, base, index);
result = intermediate.addIndex(EOpIndexIndirect, base, index, loc);
}
// Insert valid dereferenced result
TType newType(base->getType(), 0); // dereferenced type
if (base->getType().getQualifier().isConstant() && index->getQualifier().isConstant()) {
newType.getQualifier().storage = EvqConst;
// If base or index is a specialization constant, the result should also be a specialization constant.
if (base->getType().getQualifier().isSpecConstant() || index->getQualifier().isSpecConstant()) {
newType.getQualifier().makeSpecConstant();
}
} else {
newType.getQualifier().makePartialTemporary();
}
result->setType(newType);
// Propagate nonuniform
if (base->getQualifier().isNonUniform() || index->getQualifier().isNonUniform())
result->getWritableType().getQualifier().nonUniform = true;
if (anyIndexLimits)
handleIndexLimits(loc, base, index);
return result;
}
@ -615,6 +628,12 @@ TIntermTyped* TParseContext::handleBinaryMath(const TSourceLoc& loc, const char*
break;
}
if (((left->getType().containsBasicType(EbtFloat16) || right->getType().containsBasicType(EbtFloat16)) && !float16Arithmetic()) ||
((left->getType().contains16BitInt() || right->getType().contains16BitInt()) && !int16Arithmetic()) ||
((left->getType().contains8BitInt() || right->getType().contains8BitInt()) && !int8Arithmetic())) {
allowed = false;
}
TIntermTyped* result = nullptr;
if (allowed)
result = intermediate.addBinaryMath(op, left, right, loc);
@ -630,7 +649,17 @@ TIntermTyped* TParseContext::handleUnaryMath(const TSourceLoc& loc, const char*
{
rValueErrorCheck(loc, str, childNode);
TIntermTyped* result = intermediate.addUnaryMath(op, childNode, loc);
bool allowed = true;
if ((childNode->getType().containsBasicType(EbtFloat16) && !float16Arithmetic()) ||
(childNode->getType().contains16BitInt() && !int16Arithmetic()) ||
(childNode->getType().contains8BitInt() && !int8Arithmetic())) {
allowed = false;
}
TIntermTyped* result = nullptr;
if (allowed)
result = intermediate.addUnaryMath(op, childNode, loc);
if (result)
return result;
@ -692,6 +721,16 @@ TIntermTyped* TParseContext::handleDotDereference(const TSourceLoc& loc, TInterm
TSwizzleSelectors<TVectorSelector> selectors;
parseSwizzleSelector(loc, field, base->getVectorSize(), selectors);
if (base->isVector() && selectors.size() != 1 && base->getType().containsBasicType(EbtFloat16)) {
requireFloat16Arithmetic(loc, "can't swizzle types containing float16");
}
if (base->isVector() && selectors.size() != 1 && base->getType().contains16BitInt()) {
requireInt16Arithmetic(loc, "can't swizzle types containing (u)int16");
}
if (base->isVector() && selectors.size() != 1 && base->getType().contains8BitInt()) {
requireInt8Arithmetic(loc, "can't swizzle types containing (u)int8");
}
if (base->isScalar()) {
if (selectors.size() == 1)
return result;
@ -970,6 +1009,16 @@ TIntermTyped* TParseContext::handleFunctionCall(const TSourceLoc& loc, TFunction
if (builtIn && fnCandidate->getNumExtensions())
requireExtensions(loc, fnCandidate->getNumExtensions(), fnCandidate->getExtensions(), fnCandidate->getName().c_str());
if (builtIn && fnCandidate->getType().containsBasicType(EbtFloat16)) {
requireFloat16Arithmetic(loc, "float16 types can only be in uniform block or buffer storage");
}
if (builtIn && fnCandidate->getType().contains16BitInt()) {
requireInt16Arithmetic(loc, "(u)int16 types can only be in uniform block or buffer storage");
}
if (builtIn && fnCandidate->getType().contains8BitInt()) {
requireInt8Arithmetic(loc, "(u)int8 types can only be in uniform block or buffer storage");
}
if (arguments != nullptr) {
// Make sure qualifications work for these arguments.
TIntermAggregate* aggregate = arguments->getAsAggregate();
@ -995,6 +1044,17 @@ TIntermTyped* TParseContext::handleFunctionCall(const TSourceLoc& loc, TFunction
if (argQualifier.writeonly && ! formalQualifier.writeonly)
error(arguments->getLoc(), message, "writeonly", "");
}
if (builtIn && arg->getAsTyped()->getType().containsBasicType(EbtFloat16)) {
requireFloat16Arithmetic(arguments->getLoc(), "float16 types can only be in uniform block or buffer storage");
}
if (builtIn && arg->getAsTyped()->getType().contains16BitInt()) {
requireInt16Arithmetic(arguments->getLoc(), "(u)int16 types can only be in uniform block or buffer storage");
}
if (builtIn && arg->getAsTyped()->getType().contains8BitInt()) {
requireInt8Arithmetic(arguments->getLoc(), "(u)int8 types can only be in uniform block or buffer storage");
}
// TODO 4.5 functionality: A shader will fail to compile
// if the value passed to the memargument of an atomic memory function does not correspond to a buffer or
// shared variable. It is acceptable to pass an element of an array or a single component of a vector to the
@ -1179,6 +1239,8 @@ void TParseContext::computeBuiltinPrecisions(TIntermTyped& node, const TFunction
TIntermNode* TParseContext::handleReturnValue(const TSourceLoc& loc, TIntermTyped* value)
{
storage16BitAssignmentCheck(loc, value->getType(), "return");
functionReturnsValue = true;
if (currentFunctionType->getBasicType() == EbtVoid) {
error(loc, "void function cannot return a value", "return", "");
@ -2353,6 +2415,68 @@ bool TParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node, T
specConstType = true;
if (function[arg].type->isFloatingDomain())
floatArgument = true;
if (type.isStruct()) {
if (function[arg].type->containsBasicType(EbtFloat16)) {
requireFloat16Arithmetic(loc, "Can't construct structure containing 16-bit type");
}
if (function[arg].type->containsBasicType(EbtUint16) ||
function[arg].type->containsBasicType(EbtInt16)) {
requireInt16Arithmetic(loc, "Can't construct structure containing 16-bit type");
}
if (function[arg].type->containsBasicType(EbtUint8) ||
function[arg].type->containsBasicType(EbtInt8)) {
requireInt8Arithmetic(loc, "Can't construct structure containing 8-bit type");
}
}
}
switch (op) {
case EOpConstructFloat16:
case EOpConstructF16Vec2:
case EOpConstructF16Vec3:
case EOpConstructF16Vec4:
if (type.isArray()) {
requireFloat16Arithmetic(loc, "16-bit array constructors not supported");
}
if (type.isVector() && function.getParamCount() != 1) {
requireFloat16Arithmetic(loc, "16-bit vector constructors only take vector types");
}
break;
case EOpConstructUint16:
case EOpConstructU16Vec2:
case EOpConstructU16Vec3:
case EOpConstructU16Vec4:
case EOpConstructInt16:
case EOpConstructI16Vec2:
case EOpConstructI16Vec3:
case EOpConstructI16Vec4:
if (type.isArray()) {
requireInt16Arithmetic(loc, "16-bit array constructors not supported");
}
if (type.isVector() && function.getParamCount() != 1) {
requireInt16Arithmetic(loc, "16-bit vector constructors only take vector types");
}
break;
case EOpConstructUint8:
case EOpConstructU8Vec2:
case EOpConstructU8Vec3:
case EOpConstructU8Vec4:
case EOpConstructInt8:
case EOpConstructI8Vec2:
case EOpConstructI8Vec3:
case EOpConstructI8Vec4:
if (type.isArray()) {
requireInt8Arithmetic(loc, "8-bit array constructors not supported");
}
if (type.isVector() && function.getParamCount() != 1) {
requireInt8Arithmetic(loc, "8-bit vector constructors only take vector types");
}
break;
default:
break;
}
// inherit constness from children
@ -3037,6 +3161,16 @@ void TParseContext::parameterTypeCheck(const TSourceLoc& loc, TStorageQualifier
{
if ((qualifier == EvqOut || qualifier == EvqInOut) && type.isOpaque())
error(loc, "samplers and atomic_uints cannot be output parameters", type.getBasicTypeString().c_str(), "");
if (!parsingBuiltins && type.containsBasicType(EbtFloat16)) {
requireFloat16Arithmetic(loc, "float16 types can only be in uniform block or buffer storage");
}
if (!parsingBuiltins && type.contains16BitInt()) {
requireInt16Arithmetic(loc, "(u)int16 types can only be in uniform block or buffer storage");
}
if (!parsingBuiltins && type.contains8BitInt()) {
requireInt8Arithmetic(loc, "(u)int8 types can only be in uniform block or buffer storage");
}
}
bool TParseContext::containsFieldWithBasicType(const TType& type, TBasicType basicType)
@ -3811,6 +3945,39 @@ void TParseContext::opaqueCheck(const TSourceLoc& loc, const TType& type, const
error(loc, "can't use with samplers or structs containing samplers", op, "");
}
void TParseContext::storage16BitAssignmentCheck(const TSourceLoc& loc, const TType& type, const char* op)
{
if (type.getBasicType() == EbtStruct && containsFieldWithBasicType(type, EbtFloat16))
requireFloat16Arithmetic(loc, "can't use with structs containing float16");
if (type.isArray() && type.getBasicType() == EbtFloat16)
requireFloat16Arithmetic(loc, "can't use with arrays containing float16");
if (type.getBasicType() == EbtStruct && containsFieldWithBasicType(type, EbtInt16))
requireInt16Arithmetic(loc, "can't use with structs containing int16");
if (type.isArray() && type.getBasicType() == EbtInt16)
requireInt16Arithmetic(loc, "can't use with arrays containing int16");
if (type.getBasicType() == EbtStruct && containsFieldWithBasicType(type, EbtUint16))
requireInt16Arithmetic(loc, "can't use with structs containing uint16");
if (type.isArray() && type.getBasicType() == EbtUint16)
requireInt16Arithmetic(loc, "can't use with arrays containing uint16");
if (type.getBasicType() == EbtStruct && containsFieldWithBasicType(type, EbtInt8))
requireInt8Arithmetic(loc, "can't use with structs containing int8");
if (type.isArray() && type.getBasicType() == EbtInt8)
requireInt8Arithmetic(loc, "can't use with arrays containing int8");
if (type.getBasicType() == EbtStruct && containsFieldWithBasicType(type, EbtUint8))
requireInt8Arithmetic(loc, "can't use with structs containing uint8");
if (type.isArray() && type.getBasicType() == EbtUint8)
requireInt8Arithmetic(loc, "can't use with arrays containing uint8");
}
void TParseContext::specializationCheck(const TSourceLoc& loc, const TType& type, const char* op)
{
if (type.containsSpecializationSize())
@ -5414,6 +5581,18 @@ TIntermNode* TParseContext::declareVariable(const TSourceLoc& loc, TString& iden
atomicUintCheck(loc, type, identifier);
transparentOpaqueCheck(loc, type, identifier);
if (type.getQualifier().storage != EvqUniform && type.getQualifier().storage != EvqBuffer) {
if (type.containsBasicType(EbtFloat16)) {
requireFloat16Arithmetic(loc, "float16 types can only be in uniform block or buffer storage");
}
if (type.contains16BitInt()) {
requireInt16Arithmetic(loc, "(u)int16 types can only be in uniform block or buffer storage");
}
if (type.contains8BitInt()) {
requireInt8Arithmetic(loc, "(u)int8 types can only be in uniform block or buffer storage");
}
}
if (identifier != "gl_FragCoord" && (publicType.shaderQualifiers.originUpperLeft || publicType.shaderQualifiers.pixelCenterInteger))
error(loc, "can only apply origin_upper_left and pixel_center_origin to gl_FragCoord", "layout qualifier", "");
if (identifier != "gl_FragDepth" && publicType.shaderQualifiers.layoutDepth != EldNone)

1
glslang/MachineIndependent/ParseHelper.h Normal file → Executable file
View file

@ -367,6 +367,7 @@ public:
void nestedStructCheck(const TSourceLoc&);
void arrayObjectCheck(const TSourceLoc&, const TType&, const char* op);
void opaqueCheck(const TSourceLoc&, const TType&, const char* op);
void storage16BitAssignmentCheck(const TSourceLoc&, const TType&, const char* op);
void specializationCheck(const TSourceLoc&, const TType&, const char* op);
void structTypeCheck(const TSourceLoc&, TPublicType&);
void inductiveLoopCheck(const TSourceLoc&, TIntermNode* init, TIntermLoop* loop);

View file

@ -1110,6 +1110,7 @@ int TScanContext::tokenizeIdentifier()
afterType = true;
if (parseContext.symbolTable.atBuiltInLevel() ||
((parseContext.extensionTurnedOn(E_GL_KHX_shader_explicit_arithmetic_types) ||
parseContext.extensionTurnedOn(E_GL_EXT_shader_8bit_storage) ||
parseContext.extensionTurnedOn(E_GL_KHX_shader_explicit_arithmetic_types_int8)) &&
parseContext.profile != EEsProfile && parseContext.version >= 450))
return keyword;
@ -1130,6 +1131,7 @@ int TScanContext::tokenizeIdentifier()
#ifdef AMD_EXTENSIONS
parseContext.extensionTurnedOn(E_GL_AMD_gpu_shader_int16) ||
#endif
parseContext.extensionTurnedOn(E_GL_EXT_shader_16bit_storage) ||
parseContext.extensionTurnedOn(E_GL_KHX_shader_explicit_arithmetic_types) ||
parseContext.extensionTurnedOn(E_GL_KHX_shader_explicit_arithmetic_types_int16))))
return keyword;
@ -1201,6 +1203,20 @@ int TScanContext::tokenizeIdentifier()
case F16VEC2:
case F16VEC3:
case F16VEC4:
afterType = true;
if (parseContext.symbolTable.atBuiltInLevel() ||
(parseContext.profile != EEsProfile && parseContext.version >= 450 &&
(
#ifdef AMD_EXTENSIONS
parseContext.extensionTurnedOn(E_GL_AMD_gpu_shader_half_float) ||
#endif
parseContext.extensionTurnedOn(E_GL_EXT_shader_16bit_storage) ||
parseContext.extensionTurnedOn(E_GL_KHX_shader_explicit_arithmetic_types) ||
parseContext.extensionTurnedOn(E_GL_KHX_shader_explicit_arithmetic_types_float16))))
return keyword;
return identifierOrType();
case F16MAT2:
case F16MAT3:
case F16MAT4:

View file

@ -202,6 +202,9 @@ void TParseVersions::initializeExtensionBehavior()
extensionBehavior[E_GL_EXT_nonuniform_qualifier] = EBhDisable;
extensionBehavior[E_GL_EXT_samplerless_texture_functions] = EBhDisable;
extensionBehavior[E_GL_EXT_shader_16bit_storage] = EBhDisable;
extensionBehavior[E_GL_EXT_shader_8bit_storage] = EBhDisable;
// #line and #include
extensionBehavior[E_GL_GOOGLE_cpp_style_line_directive] = EBhDisable;
extensionBehavior[E_GL_GOOGLE_include_directive] = EBhDisable;
@ -363,6 +366,8 @@ void TParseVersions::getPreamble(std::string& preamble)
"#define GL_EXT_post_depth_coverage 1\n"
"#define GL_EXT_control_flow_attributes 1\n"
"#define GL_EXT_nonuniform_qualifier 1\n"
"#define GL_EXT_shader_16bit_storage 1\n"
"#define GL_EXT_shader_8bit_storage 1\n"
"#define GL_EXT_samplerless_texture_functions 1\n"
// GL_KHR_shader_subgroup
@ -813,27 +818,94 @@ void TParseVersions::fullIntegerCheck(const TSourceLoc& loc, const char* op)
void TParseVersions::doubleCheck(const TSourceLoc& loc, const char* op)
{
requireProfile(loc, ECoreProfile | ECompatibilityProfile, op);
profileRequires(loc, ECoreProfile, 400, nullptr, op);
profileRequires(loc, ECompatibilityProfile, 400, nullptr, op);
profileRequires(loc, ECoreProfile | ECompatibilityProfile, 400, nullptr, op);
}
// Call for any operation needing GLSL float16 data-type support.
void TParseVersions::float16Check(const TSourceLoc& loc, const char* op, bool builtIn)
{
if (!builtIn) {
const char* const extensions[] = {
#if AMD_EXTENSIONS
const char* const extensions[3] = {E_GL_AMD_gpu_shader_half_float,
E_GL_AMD_gpu_shader_half_float,
#endif
E_GL_KHX_shader_explicit_arithmetic_types,
E_GL_KHX_shader_explicit_arithmetic_types_float16};
requireExtensions(loc, sizeof(extensions)/sizeof(extensions[0]), extensions, "explicit types");
}
}
bool TParseVersions::float16Arithmetic()
{
const char* const extensions[] = {
#if AMD_EXTENSIONS
E_GL_AMD_gpu_shader_half_float,
#endif
E_GL_KHX_shader_explicit_arithmetic_types,
E_GL_KHX_shader_explicit_arithmetic_types_float16};
return extensionsTurnedOn(sizeof(extensions)/sizeof(extensions[0]), extensions);
}
bool TParseVersions::int16Arithmetic()
{
const char* const extensions[] = {
#if AMD_EXTENSIONS
E_GL_AMD_gpu_shader_int16,
#endif
E_GL_KHX_shader_explicit_arithmetic_types,
E_GL_KHX_shader_explicit_arithmetic_types_int16};
return extensionsTurnedOn(sizeof(extensions)/sizeof(extensions[0]), extensions);
}
bool TParseVersions::int8Arithmetic()
{
const char* const extensions[] = {
E_GL_KHX_shader_explicit_arithmetic_types,
E_GL_KHX_shader_explicit_arithmetic_types_int8};
return extensionsTurnedOn(sizeof(extensions)/sizeof(extensions[0]), extensions);
}
void TParseVersions::requireFloat16Arithmetic(const TSourceLoc& loc, const char* featureDesc)
{
const char* const extensions[] = {
#if AMD_EXTENSIONS
E_GL_AMD_gpu_shader_half_float,
#endif
E_GL_KHX_shader_explicit_arithmetic_types,
E_GL_KHX_shader_explicit_arithmetic_types_float16};
requireExtensions(loc, sizeof(extensions)/sizeof(extensions[0]), extensions, featureDesc);
}
void TParseVersions::requireInt16Arithmetic(const TSourceLoc& loc, const char* featureDesc)
{
const char* const extensions[] = {
#if AMD_EXTENSIONS
E_GL_AMD_gpu_shader_int16,
#endif
E_GL_KHX_shader_explicit_arithmetic_types,
E_GL_KHX_shader_explicit_arithmetic_types_int16};
requireExtensions(loc, sizeof(extensions)/sizeof(extensions[0]), extensions, featureDesc);
}
void TParseVersions::requireInt8Arithmetic(const TSourceLoc& loc, const char* featureDesc)
{
const char* const extensions[] = {
E_GL_KHX_shader_explicit_arithmetic_types,
E_GL_KHX_shader_explicit_arithmetic_types_int8};
requireExtensions(loc, sizeof(extensions)/sizeof(extensions[0]), extensions, featureDesc);
}
void TParseVersions::float16ScalarVectorCheck(const TSourceLoc& loc, const char* op, bool builtIn)
{
if (!builtIn) {
const char* const extensions[] = {
#if AMD_EXTENSIONS
E_GL_AMD_gpu_shader_half_float,
#endif
E_GL_EXT_shader_16bit_storage,
E_GL_KHX_shader_explicit_arithmetic_types,
E_GL_KHX_shader_explicit_arithmetic_types_float16};
#else
const char* const extensions[2] = {E_GL_KHX_shader_explicit_arithmetic_types,
E_GL_KHX_shader_explicit_arithmetic_types_float16};
#endif
requireExtensions(loc, sizeof(extensions)/sizeof(extensions[0]), extensions, "explicit types");
requireProfile(loc, ECoreProfile | ECompatibilityProfile, op);
profileRequires(loc, ECoreProfile, 450, nullptr, op);
profileRequires(loc, ECompatibilityProfile, 450, nullptr, op);
}
}
@ -844,9 +916,6 @@ void TParseVersions::explicitFloat32Check(const TSourceLoc& loc, const char* op,
const char* const extensions[2] = {E_GL_KHX_shader_explicit_arithmetic_types,
E_GL_KHX_shader_explicit_arithmetic_types_float32};
requireExtensions(loc, 2, extensions, "explicit types");
requireProfile(loc, ECoreProfile | ECompatibilityProfile, op);
profileRequires(loc, ECoreProfile, 450, nullptr, op);
profileRequires(loc, ECompatibilityProfile, 450, nullptr, op);
}
}
@ -858,8 +927,7 @@ void TParseVersions::explicitFloat64Check(const TSourceLoc& loc, const char* op,
E_GL_KHX_shader_explicit_arithmetic_types_float64};
requireExtensions(loc, 2, extensions, "explicit types");
requireProfile(loc, ECoreProfile | ECompatibilityProfile, op);
profileRequires(loc, ECoreProfile, 450, nullptr, op);
profileRequires(loc, ECompatibilityProfile, 450, nullptr, op);
profileRequires(loc, ECoreProfile | ECompatibilityProfile, 400, nullptr, op);
}
}
@ -870,9 +938,6 @@ void TParseVersions::explicitInt8Check(const TSourceLoc& loc, const char* op, bo
const char* const extensions[2] = {E_GL_KHX_shader_explicit_arithmetic_types,
E_GL_KHX_shader_explicit_arithmetic_types_int8};
requireExtensions(loc, 2, extensions, "explicit types");
requireProfile(loc, ECoreProfile | ECompatibilityProfile, op);
profileRequires(loc, ECoreProfile, 450, nullptr, op);
profileRequires(loc, ECompatibilityProfile, 450, nullptr, op);
}
}
@ -883,8 +948,7 @@ void TParseVersions::float16OpaqueCheck(const TSourceLoc& loc, const char* op, b
if (! builtIn) {
requireExtensions(loc, 1, &E_GL_AMD_gpu_shader_half_float_fetch, op);
requireProfile(loc, ECoreProfile | ECompatibilityProfile, op);
profileRequires(loc, ECoreProfile, 450, nullptr, op);
profileRequires(loc, ECompatibilityProfile, 450, nullptr, op);
profileRequires(loc, ECoreProfile | ECompatibilityProfile, 400, nullptr, op);
}
}
#endif
@ -893,18 +957,38 @@ void TParseVersions::float16OpaqueCheck(const TSourceLoc& loc, const char* op, b
void TParseVersions::explicitInt16Check(const TSourceLoc& loc, const char* op, bool builtIn)
{
if (! builtIn) {
const char* const extensions[] = {
#if AMD_EXTENSIONS
const char* const extensions[3] = {E_GL_AMD_gpu_shader_int16,
E_GL_KHX_shader_explicit_arithmetic_types,
E_GL_KHX_shader_explicit_arithmetic_types_int16};
#else
const char* const extensions[2] = {E_GL_KHX_shader_explicit_arithmetic_types,
E_GL_KHX_shader_explicit_arithmetic_types_int16};
E_GL_AMD_gpu_shader_int16,
#endif
E_GL_KHX_shader_explicit_arithmetic_types,
E_GL_KHX_shader_explicit_arithmetic_types_int16};
requireExtensions(loc, sizeof(extensions)/sizeof(extensions[0]), extensions, "explicit types");
}
}
void TParseVersions::int16ScalarVectorCheck(const TSourceLoc& loc, const char* op, bool builtIn)
{
if (! builtIn) {
const char* const extensions[] = {
#if AMD_EXTENSIONS
E_GL_AMD_gpu_shader_int16,
#endif
E_GL_EXT_shader_16bit_storage,
E_GL_KHX_shader_explicit_arithmetic_types,
E_GL_KHX_shader_explicit_arithmetic_types_int16};
requireExtensions(loc, sizeof(extensions)/sizeof(extensions[0]), extensions, "explicit types");
}
}
void TParseVersions::int8ScalarVectorCheck(const TSourceLoc& loc, const char* op, bool builtIn)
{
if (! builtIn) {
const char* const extensions[] = {
E_GL_EXT_shader_8bit_storage,
E_GL_KHX_shader_explicit_arithmetic_types,
E_GL_KHX_shader_explicit_arithmetic_types_int8};
requireExtensions(loc, sizeof(extensions)/sizeof(extensions[0]), extensions, "explicit types");
requireProfile(loc, ECoreProfile | ECompatibilityProfile, op);
profileRequires(loc, ECoreProfile, 450, nullptr, op);
profileRequires(loc, ECompatibilityProfile, 450, nullptr, op);
}
}
@ -915,9 +999,6 @@ void TParseVersions::explicitInt32Check(const TSourceLoc& loc, const char* op, b
const char* const extensions[2] = {E_GL_KHX_shader_explicit_arithmetic_types,
E_GL_KHX_shader_explicit_arithmetic_types_int32};
requireExtensions(loc, 2, extensions, "explicit types");
requireProfile(loc, ECoreProfile | ECompatibilityProfile, op);
profileRequires(loc, ECoreProfile, 450, nullptr, op);
profileRequires(loc, ECompatibilityProfile, 450, nullptr, op);
}
}
@ -930,8 +1011,7 @@ void TParseVersions::int64Check(const TSourceLoc& loc, const char* op, bool buil
E_GL_KHX_shader_explicit_arithmetic_types_int64};
requireExtensions(loc, 3, extensions, "shader int64");
requireProfile(loc, ECoreProfile | ECompatibilityProfile, op);
profileRequires(loc, ECoreProfile, 450, nullptr, op);
profileRequires(loc, ECompatibilityProfile, 450, nullptr, op);
profileRequires(loc, ECoreProfile | ECompatibilityProfile, 400, nullptr, op);
}
}

View file

@ -152,6 +152,10 @@ const char* const E_GL_KHR_shader_subgroup_quad = "GL_KHR_shader_sub
const char* const E_GL_EXT_shader_non_constant_global_initializers = "GL_EXT_shader_non_constant_global_initializers";
const char* const E_GL_EXT_shader_image_load_formatted = "GL_EXT_shader_image_load_formatted";
const char* const E_GL_EXT_shader_16bit_storage = "GL_EXT_shader_16bit_storage";
const char* const E_GL_EXT_shader_8bit_storage = "GL_EXT_shader_8bit_storage";
// EXT extensions
const char* const E_GL_EXT_device_group = "GL_EXT_device_group";
const char* const E_GL_EXT_multiview = "GL_EXT_multiview";

79
glslang/MachineIndependent/glslang.y Normal file → Executable file
View file

@ -699,6 +699,7 @@ assignment_expression
| unary_expression assignment_operator assignment_expression {
parseContext.arrayObjectCheck($2.loc, $1->getType(), "array assignment");
parseContext.opaqueCheck($2.loc, $1->getType(), "=");
parseContext.storage16BitAssignmentCheck($2.loc, $1->getType(), "=");
parseContext.specializationCheck($2.loc, $1->getType(), "=");
parseContext.lValueErrorCheck($2.loc, "assign", $1);
parseContext.rValueErrorCheck($2.loc, "assign", $3);
@ -1419,7 +1420,7 @@ type_specifier_nonarray
$$.basicType = EbtDouble;
}
| FLOAT16_T {
parseContext.float16Check($1.loc, "float16_t", parseContext.symbolTable.atBuiltInLevel());
parseContext.float16ScalarVectorCheck($1.loc, "float16_t", parseContext.symbolTable.atBuiltInLevel());
$$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
$$.basicType = EbtFloat16;
}
@ -1443,22 +1444,22 @@ type_specifier_nonarray
$$.basicType = EbtUint;
}
| INT8_T {
parseContext.explicitInt8Check($1.loc, "8-bit signed integer", parseContext.symbolTable.atBuiltInLevel());
parseContext.int8ScalarVectorCheck($1.loc, "8-bit signed integer", parseContext.symbolTable.atBuiltInLevel());
$$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
$$.basicType = EbtInt8;
}
| UINT8_T {
parseContext.explicitInt8Check($1.loc, "8-bit unsigned integer", parseContext.symbolTable.atBuiltInLevel());
parseContext.int8ScalarVectorCheck($1.loc, "8-bit unsigned integer", parseContext.symbolTable.atBuiltInLevel());
$$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
$$.basicType = EbtUint8;
}
| INT16_T {
parseContext.explicitInt16Check($1.loc, "16-bit signed integer", parseContext.symbolTable.atBuiltInLevel());
parseContext.int16ScalarVectorCheck($1.loc, "16-bit signed integer", parseContext.symbolTable.atBuiltInLevel());
$$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
$$.basicType = EbtInt16;
}
| UINT16_T {
parseContext.explicitInt16Check($1.loc, "16-bit unsigned integer", parseContext.symbolTable.atBuiltInLevel());
parseContext.int16ScalarVectorCheck($1.loc, "16-bit unsigned integer", parseContext.symbolTable.atBuiltInLevel());
$$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
$$.basicType = EbtUint16;
}
@ -1520,19 +1521,19 @@ type_specifier_nonarray
$$.setVector(4);
}
| F16VEC2 {
parseContext.float16Check($1.loc, "half float vector", parseContext.symbolTable.atBuiltInLevel());
parseContext.float16ScalarVectorCheck($1.loc, "half float vector", parseContext.symbolTable.atBuiltInLevel());
$$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
$$.basicType = EbtFloat16;
$$.setVector(2);
}
| F16VEC3 {
parseContext.float16Check($1.loc, "half float vector", parseContext.symbolTable.atBuiltInLevel());
parseContext.float16ScalarVectorCheck($1.loc, "half float vector", parseContext.symbolTable.atBuiltInLevel());
$$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
$$.basicType = EbtFloat16;
$$.setVector(3);
}
| F16VEC4 {
parseContext.float16Check($1.loc, "half float vector", parseContext.symbolTable.atBuiltInLevel());
parseContext.float16ScalarVectorCheck($1.loc, "half float vector", parseContext.symbolTable.atBuiltInLevel());
$$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
$$.basicType = EbtFloat16;
$$.setVector(4);
@ -1604,40 +1605,40 @@ type_specifier_nonarray
$$.setVector(4);
}
| I8VEC2 {
parseContext.explicitInt8Check($1.loc, "8-bit signed integer vector", parseContext.symbolTable.atBuiltInLevel());
$$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
$$.basicType = EbtInt8;
$$.setVector(2);
parseContext.int8ScalarVectorCheck($1.loc, "8-bit signed integer vector", parseContext.symbolTable.atBuiltInLevel());
$$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
$$.basicType = EbtInt8;
$$.setVector(2);
}
| I8VEC3 {
parseContext.explicitInt8Check($1.loc, "8-bit signed integer vector", parseContext.symbolTable.atBuiltInLevel());
$$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
$$.basicType = EbtInt8;
$$.setVector(3);
parseContext.int8ScalarVectorCheck($1.loc, "8-bit signed integer vector", parseContext.symbolTable.atBuiltInLevel());
$$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
$$.basicType = EbtInt8;
$$.setVector(3);
}
| I8VEC4 {
parseContext.explicitInt8Check($1.loc, "8-bit signed integer vector", parseContext.symbolTable.atBuiltInLevel());
$$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
$$.basicType = EbtInt8;
$$.setVector(4);
parseContext.int8ScalarVectorCheck($1.loc, "8-bit signed integer vector", parseContext.symbolTable.atBuiltInLevel());
$$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
$$.basicType = EbtInt8;
$$.setVector(4);
}
| I16VEC2 {
parseContext.explicitInt16Check($1.loc, "16-bit signed integer vector", parseContext.symbolTable.atBuiltInLevel());
$$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
$$.basicType = EbtInt16;
$$.setVector(2);
parseContext.int16ScalarVectorCheck($1.loc, "16-bit signed integer vector", parseContext.symbolTable.atBuiltInLevel());
$$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
$$.basicType = EbtInt16;
$$.setVector(2);
}
| I16VEC3 {
parseContext.explicitInt16Check($1.loc, "16-bit signed integer vector", parseContext.symbolTable.atBuiltInLevel());
$$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
$$.basicType = EbtInt16;
$$.setVector(3);
parseContext.int16ScalarVectorCheck($1.loc, "16-bit signed integer vector", parseContext.symbolTable.atBuiltInLevel());
$$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
$$.basicType = EbtInt16;
$$.setVector(3);
}
| I16VEC4 {
parseContext.explicitInt16Check($1.loc, "16-bit signed integer vector", parseContext.symbolTable.atBuiltInLevel());
$$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
$$.basicType = EbtInt16;
$$.setVector(4);
parseContext.int16ScalarVectorCheck($1.loc, "16-bit signed integer vector", parseContext.symbolTable.atBuiltInLevel());
$$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
$$.basicType = EbtInt16;
$$.setVector(4);
}
| I32VEC2 {
parseContext.explicitInt32Check($1.loc, "32-bit signed integer vector", parseContext.symbolTable.atBuiltInLevel());
@ -1694,37 +1695,37 @@ type_specifier_nonarray
$$.setVector(4);
}
| U8VEC2 {
parseContext.explicitInt8Check($1.loc, "8-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel());
parseContext.int8ScalarVectorCheck($1.loc, "8-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel());
$$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
$$.basicType = EbtUint8;
$$.setVector(2);
}
| U8VEC3 {
parseContext.explicitInt8Check($1.loc, "8-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel());
parseContext.int8ScalarVectorCheck($1.loc, "8-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel());
$$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
$$.basicType = EbtInt8;
$$.basicType = EbtUint8;
$$.setVector(3);
}
| U8VEC4 {
parseContext.explicitInt8Check($1.loc, "8-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel());
parseContext.int8ScalarVectorCheck($1.loc, "8-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel());
$$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
$$.basicType = EbtUint8;
$$.setVector(4);
}
| U16VEC2 {
parseContext.explicitInt16Check($1.loc, "16-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel());
parseContext.int16ScalarVectorCheck($1.loc, "16-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel());
$$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
$$.basicType = EbtUint16;
$$.setVector(2);
}
| U16VEC3 {
parseContext.explicitInt16Check($1.loc, "16-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel());
parseContext.int16ScalarVectorCheck($1.loc, "16-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel());
$$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
$$.basicType = EbtUint16;
$$.setVector(3);
}
| U16VEC4 {
parseContext.explicitInt16Check($1.loc, "16-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel());
parseContext.int16ScalarVectorCheck($1.loc, "16-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel());
$$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
$$.basicType = EbtUint16;
$$.setVector(4);

2321
glslang/MachineIndependent/glslang_tab.cpp Normal file → Executable file

File diff suppressed because it is too large Load diff

View file

@ -79,6 +79,15 @@ public:
virtual void fullIntegerCheck(const TSourceLoc&, const char* op);
virtual void doubleCheck(const TSourceLoc&, const char* op);
virtual void float16Check(const TSourceLoc&, const char* op, bool builtIn = false);
virtual void float16ScalarVectorCheck(const TSourceLoc&, const char* op, bool builtIn = false);
virtual bool float16Arithmetic();
virtual void requireFloat16Arithmetic(const TSourceLoc& loc, const char* featureDesc);
virtual void int16ScalarVectorCheck(const TSourceLoc&, const char* op, bool builtIn = false);
virtual bool int16Arithmetic();
virtual void requireInt16Arithmetic(const TSourceLoc& loc, const char* featureDesc);
virtual void int8ScalarVectorCheck(const TSourceLoc&, const char* op, bool builtIn = false);
virtual bool int8Arithmetic();
virtual void requireInt8Arithmetic(const TSourceLoc& loc, const char* featureDesc);
#ifdef AMD_EXTENSIONS
virtual void float16OpaqueCheck(const TSourceLoc&, const char* op, bool builtIn = false);
#endif

2
glslang/Public/ShaderLang.h Normal file → Executable file
View file

@ -70,7 +70,7 @@
// This should always increase, as some paths to do not consume
// a more major number.
// It should increment by one when new functionality is added.
#define GLSLANG_MINOR_VERSION 7
#define GLSLANG_MINOR_VERSION 8
//
// Call before doing any other compiler/linker operations.