Atomic memory function can only be used for shader storage block member or shared variable.

Signed-off-by: ZhiqianXia <xzq0528@outlook.com>
This commit is contained in:
ZhiqianXia 2021-07-12 16:57:25 +08:00
parent 4b7b86d568
commit cf52f73a0c
9 changed files with 478 additions and 2 deletions

View file

@ -2676,7 +2676,11 @@ TIntermTyped* TIntermediate::addSwizzle(TSwizzleSelectors<selectorType>& selecto
// 'swizzleOkay' says whether or not it is okay to consider a swizzle
// a valid part of the dereference chain.
//
const TIntermTyped* TIntermediate::findLValueBase(const TIntermTyped* node, bool swizzleOkay)
// 'BufferReferenceOk' says if type is buffer_reference, the routine stop to find the most left node.
//
//
const TIntermTyped* TIntermediate::findLValueBase(const TIntermTyped* node, bool swizzleOkay , bool bufferReferenceOk)
{
do {
const TIntermBinary* binary = node->getAsBinaryNode();
@ -2694,6 +2698,8 @@ const TIntermTyped* TIntermediate::findLValueBase(const TIntermTyped* node, bool
return nullptr;
}
node = node->getAsBinaryNode()->getLeft();
if (bufferReferenceOk && node->isReference())
return node;
} while (true);
}

View file

@ -2409,6 +2409,14 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan
arg0->getType().isFloatingDomain()) {
requireExtensions(loc, 1, &E_GL_EXT_shader_atomic_float2, fnCandidate.getName().c_str());
}
const TIntermTyped* base = TIntermediate::findLValueBase(arg0, true , true);
const TType* refType = (base->getType().isReference()) ? base->getType().getReferentType() : nullptr;
const TQualifier& qualifier = (refType != nullptr) ? refType->getQualifier() : base->getType().getQualifier();
if (qualifier.storage != EvqShared && qualifier.storage != EvqBuffer)
error(loc,"Atomic memory function can only be used for shader storage block member or shared variable.",
fnCandidate.getName().c_str(), "");
break;
}

View file

@ -538,7 +538,7 @@ public:
TIntermTyped* foldSwizzle(TIntermTyped* node, TSwizzleSelectors<TVectorSelector>& fields, const TSourceLoc&);
// Tree ops
static const TIntermTyped* findLValueBase(const TIntermTyped*, bool swizzleOkay);
static const TIntermTyped* findLValueBase(const TIntermTyped*, bool swizzleOkay , bool BufferReferenceOk = false);
// Linkage related
void addSymbolLinkageNodes(TIntermAggregate*& linkage, EShLanguage, TSymbolTable&);