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:
parent
eefab240f7
commit
312dcfb070
43 changed files with 6179 additions and 2765 deletions
10
glslang/Include/Types.h
Normal file → Executable file
10
glslang/Include/Types.h
Normal file → Executable 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
|
||||
|
|
|
|||
|
|
@ -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
78
glslang/MachineIndependent/Intermediate.cpp
Normal file → Executable 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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
1
glslang/MachineIndependent/ParseHelper.h
Normal file → Executable 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);
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
79
glslang/MachineIndependent/glslang.y
Normal file → Executable 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
2321
glslang/MachineIndependent/glslang_tab.cpp
Normal file → Executable file
File diff suppressed because it is too large
Load diff
|
|
@ -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
2
glslang/Public/ShaderLang.h
Normal file → Executable 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.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue