Add GL_OES_standard_derivatives. Also added extension infrastructure that allows built-in symbols to be tagged with extensions and automatically error checked against them.
git-svn-id: https://cvs.khronos.org/svn/repos/ogl/trunk/ecosystem/public/sdk/tools/glslang@24002 e7fa87d3-cd2b-0410-9028-fcbf551c1848
This commit is contained in:
		
							parent
							
								
									115a0adc29
								
							
						
					
					
						commit
						06a37c3964
					
				@ -88,4 +88,16 @@ void foo234()
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    texture3D(s3D2, vec3(0.2), 0.2);
 | 
					    texture3D(s3D2, vec3(0.2), 0.2);
 | 
				
			||||||
    texture3DProj(s3D2, v[1], 0.4);
 | 
					    texture3DProj(s3D2, v[1], 0.4);
 | 
				
			||||||
 | 
					    dFdx(v[0]);    // ERROR
 | 
				
			||||||
 | 
					    dFdy(3.2);     // ERROR
 | 
				
			||||||
 | 
					    fwidth(f13);   // ERROR
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#extension GL_OES_standard_derivatives : enable
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void foo236()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    dFdx(v[0]);
 | 
				
			||||||
 | 
					    dFdy(3.2);
 | 
				
			||||||
 | 
					    fwidth(f13);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -42,7 +42,10 @@ ERROR: 0:76: 'h' : cannot use storage or interpolation qualifiers on structure m
 | 
				
			|||||||
ERROR: 0:77: 'i' : cannot use invariant qualifier on structure members 
 | 
					ERROR: 0:77: 'i' : cannot use invariant qualifier on structure members 
 | 
				
			||||||
ERROR: 0:80: 'sampler3D' : Reserved word. 
 | 
					ERROR: 0:80: 'sampler3D' : Reserved word. 
 | 
				
			||||||
ERROR: 0:80: 'sampler/image' : type requires declaration of default precision qualifier 
 | 
					ERROR: 0:80: 'sampler/image' : type requires declaration of default precision qualifier 
 | 
				
			||||||
ERROR: 37 compilation errors.  No code generated.
 | 
					ERROR: 0:91: 'dFdx' : required extension not requested: GL_OES_standard_derivatives
 | 
				
			||||||
 | 
					ERROR: 0:92: 'dFdy' : required extension not requested: GL_OES_standard_derivatives
 | 
				
			||||||
 | 
					ERROR: 0:93: 'fwidth' : required extension not requested: GL_OES_standard_derivatives
 | 
				
			||||||
 | 
					ERROR: 40 compilation errors.  No code generated.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ERROR: node is still EOpNull!
 | 
					ERROR: node is still EOpNull!
 | 
				
			||||||
0:3  Sequence
 | 
					0:3  Sequence
 | 
				
			||||||
@ -142,6 +145,27 @@ ERROR: node is still EOpNull!
 | 
				
			|||||||
0:90            1 (const int)
 | 
					0:90            1 (const int)
 | 
				
			||||||
0:90        Constant:
 | 
					0:90        Constant:
 | 
				
			||||||
0:90          0.400000
 | 
					0:90          0.400000
 | 
				
			||||||
 | 
					0:91      dPdx (mediump 4-component vector of float)
 | 
				
			||||||
 | 
					0:91        direct index (smooth mediump 4-component vector of float)
 | 
				
			||||||
 | 
					0:91          'v' (smooth in 3-element array of mediump 4-component vector of float)
 | 
				
			||||||
 | 
					0:91          Constant:
 | 
				
			||||||
 | 
					0:91            0 (const int)
 | 
				
			||||||
 | 
					0:92      Constant:
 | 
				
			||||||
 | 
					0:92        0.000000
 | 
				
			||||||
 | 
					0:93      fwidth (mediump float)
 | 
				
			||||||
 | 
					0:93        'f13' (invariant mediump float)
 | 
				
			||||||
 | 
					0:98  Function Definition: foo236( (void)
 | 
				
			||||||
 | 
					0:98    Function Parameters: 
 | 
				
			||||||
 | 
					0:100    Sequence
 | 
				
			||||||
 | 
					0:100      dPdx (mediump 4-component vector of float)
 | 
				
			||||||
 | 
					0:100        direct index (smooth mediump 4-component vector of float)
 | 
				
			||||||
 | 
					0:100          'v' (smooth in 3-element array of mediump 4-component vector of float)
 | 
				
			||||||
 | 
					0:100          Constant:
 | 
				
			||||||
 | 
					0:100            0 (const int)
 | 
				
			||||||
 | 
					0:101      Constant:
 | 
				
			||||||
 | 
					0:101        0.000000
 | 
				
			||||||
 | 
					0:102      fwidth (mediump float)
 | 
				
			||||||
 | 
					0:102        'f13' (invariant mediump float)
 | 
				
			||||||
0:?   Linker Objects
 | 
					0:?   Linker Objects
 | 
				
			||||||
0:?     'a' (3-element array of mediump int)
 | 
					0:?     'a' (3-element array of mediump int)
 | 
				
			||||||
0:?     'uint' (mediump int)
 | 
					0:?     'uint' (mediump int)
 | 
				
			||||||
 | 
				
			|||||||
@ -42,8 +42,10 @@
 | 
				
			|||||||
// Where to put a built-in:
 | 
					// Where to put a built-in:
 | 
				
			||||||
//   TBuiltIns::initialize(version,profile)       context-independent textual built-ins; add them to the right string
 | 
					//   TBuiltIns::initialize(version,profile)       context-independent textual built-ins; add them to the right string
 | 
				
			||||||
//   TBuiltIns::initialize(resources,...)         context-dependent textual built-ins; add them to the right string
 | 
					//   TBuiltIns::initialize(resources,...)         context-dependent textual built-ins; add them to the right string
 | 
				
			||||||
//   IdentifyBuiltIns(...,symbolTable)            context-independent programmatic additions/mappings to the symbol table
 | 
					//   IdentifyBuiltIns(...,symbolTable)            context-independent programmatic additions/mappings to the symbol table,
 | 
				
			||||||
//   IdentifyBuiltIns(...,symbolTable, resources) context-dependent programmatic additions/mappings to the symbol table
 | 
					//                                                including identify what extensions are needed if a version does not allow a symbol
 | 
				
			||||||
 | 
					//   IdentifyBuiltIns(...,symbolTable, resources) context-dependent programmatic additions/mappings to the symbol table,
 | 
				
			||||||
 | 
					//                                                including identify what extensions are needed if a version does not allow a symbol
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "../Include/intermediate.h"
 | 
					#include "../Include/intermediate.h"
 | 
				
			||||||
@ -2120,8 +2122,8 @@ void SpecialQualifier(const char* name, TStorageQualifier qualifier, TSymbolTabl
 | 
				
			|||||||
void IdentifyBuiltIns(int version, EProfile profile, EShLanguage language, TSymbolTable& symbolTable)
 | 
					void IdentifyBuiltIns(int version, EProfile profile, EShLanguage language, TSymbolTable& symbolTable)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    //
 | 
					    //
 | 
				
			||||||
    // First, insert some special built-in variables that are not in
 | 
					    // Tag built-in variables and functions with additional qualifier and extension information
 | 
				
			||||||
    // the built-in text strings.
 | 
					    // that cannot be declared with the text strings.
 | 
				
			||||||
    //
 | 
					    //
 | 
				
			||||||
    switch(language) {
 | 
					    switch(language) {
 | 
				
			||||||
    case EShLangVertex:
 | 
					    case EShLangVertex:
 | 
				
			||||||
@ -2141,6 +2143,11 @@ void IdentifyBuiltIns(int version, EProfile profile, EShLanguage language, TSymb
 | 
				
			|||||||
        SpecialQualifier("gl_PointCoord",  EvqPointCoord, symbolTable);
 | 
					        SpecialQualifier("gl_PointCoord",  EvqPointCoord, symbolTable);
 | 
				
			||||||
        SpecialQualifier("gl_FragColor",   EvqFragColor, symbolTable);
 | 
					        SpecialQualifier("gl_FragColor",   EvqFragColor, symbolTable);
 | 
				
			||||||
        SpecialQualifier("gl_FragDepth",   EvqFragDepth, symbolTable);
 | 
					        SpecialQualifier("gl_FragDepth",   EvqFragDepth, symbolTable);
 | 
				
			||||||
 | 
					        if (version == 100) {
 | 
				
			||||||
 | 
					            symbolTable.setFunctionExtensions("dFdx",   1, &GL_OES_standard_derivatives);
 | 
				
			||||||
 | 
					            symbolTable.setFunctionExtensions("dFdy",   1, &GL_OES_standard_derivatives);
 | 
				
			||||||
 | 
					            symbolTable.setFunctionExtensions("fwidth", 1, &GL_OES_standard_derivatives);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    case EShLangCompute:
 | 
					    case EShLangCompute:
 | 
				
			||||||
 | 
				
			|||||||
@ -385,6 +385,10 @@ TIntermTyped* TParseContext::handleVariable(TSourceLoc loc, TSymbol* symbol, TSt
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    TIntermTyped* node = 0;
 | 
					    TIntermTyped* node = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Error check for function requiring specific extensions present.
 | 
				
			||||||
 | 
					    if (symbol && symbol->getNumExtensions())
 | 
				
			||||||
 | 
					        requireExtensions(loc, symbol->getNumExtensions(), symbol->getExtensions(), symbol->getName().c_str());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const TAnonMember* anon = symbol ? symbol->getAsAnonMember() : 0;
 | 
					    const TAnonMember* anon = symbol ? symbol->getAsAnonMember() : 0;
 | 
				
			||||||
    if (anon) {
 | 
					    if (anon) {
 | 
				
			||||||
        // it was a member of an anonymous container, have to insert its dereference
 | 
					        // it was a member of an anonymous container, have to insert its dereference
 | 
				
			||||||
@ -903,6 +907,10 @@ TIntermTyped* TParseContext::handleFunctionCall(TSourceLoc loc, TFunction* fnCal
 | 
				
			|||||||
        bool builtIn;
 | 
					        bool builtIn;
 | 
				
			||||||
        fnCandidate = findFunction(loc, *fnCall, builtIn);
 | 
					        fnCandidate = findFunction(loc, *fnCall, builtIn);
 | 
				
			||||||
        if (fnCandidate) {
 | 
					        if (fnCandidate) {
 | 
				
			||||||
 | 
					            // Error check for function requiring specific extensions present.
 | 
				
			||||||
 | 
					            if (builtIn && fnCandidate->getNumExtensions())
 | 
				
			||||||
 | 
					                requireExtensions(loc, fnCandidate->getNumExtensions(), fnCandidate->getExtensions(), fnCandidate->getName().c_str());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            //
 | 
					            //
 | 
				
			||||||
            // A declared function.  But, it might still map to a built-in
 | 
					            // A declared function.  But, it might still map to a built-in
 | 
				
			||||||
            // operation.
 | 
					            // operation.
 | 
				
			||||||
 | 
				
			|||||||
@ -185,6 +185,7 @@ public:
 | 
				
			|||||||
    void requireStage(TSourceLoc, EShLanguage, const char *featureDesc);
 | 
					    void requireStage(TSourceLoc, EShLanguage, const char *featureDesc);
 | 
				
			||||||
    void checkDeprecated(TSourceLoc, int queryProfiles, int depVersion, const char *featureDesc);
 | 
					    void checkDeprecated(TSourceLoc, int queryProfiles, int depVersion, const char *featureDesc);
 | 
				
			||||||
    void requireNotRemoved(TSourceLoc, int queryProfiles, int removedVersion, const char *featureDesc);
 | 
					    void requireNotRemoved(TSourceLoc, int queryProfiles, int removedVersion, const char *featureDesc);
 | 
				
			||||||
 | 
					    void requireExtensions(TSourceLoc, int numExtensions, const char* const extensions[], const char *featureDesc);
 | 
				
			||||||
    TExtensionBehavior getExtensionBehavior(const char*);
 | 
					    TExtensionBehavior getExtensionBehavior(const char*);
 | 
				
			||||||
    bool extensionsTurnedOn(int numExtensions, const char* const extensions[]);
 | 
					    bool extensionsTurnedOn(int numExtensions, const char* const extensions[]);
 | 
				
			||||||
    void updateExtensionBehavior(const char* const extension, const char* behavior);
 | 
					    void updateExtensionBehavior(const char* const extension, const char* behavior);
 | 
				
			||||||
 | 
				
			|||||||
@ -207,6 +207,23 @@ void TSymbolTableLevel::relateToOperator(const char* name, TOperator op)
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Make all function overloads of the given name require an extension(s).
 | 
				
			||||||
 | 
					// Should only be used for a version/profile that actually needs the extension(s).
 | 
				
			||||||
 | 
					void TSymbolTableLevel::setFunctionExtensions(const char* name, int num, const char* const extensions[])
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    tLevel::const_iterator candidate = level.lower_bound(name);
 | 
				
			||||||
 | 
					    while (candidate != level.end()) {
 | 
				
			||||||
 | 
					        const TString& candidateName = (*candidate).first;
 | 
				
			||||||
 | 
					        TString::size_type parenAt = candidateName.find_first_of('(');
 | 
				
			||||||
 | 
					        if (parenAt != candidateName.npos && candidateName.compare(0, parenAt, name) == 0) {
 | 
				
			||||||
 | 
					            TSymbol* symbol = candidate->second;
 | 
				
			||||||
 | 
					            symbol->setExtensions(num, extensions);
 | 
				
			||||||
 | 
					        } else
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        ++candidate;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
// Make all symbols in this table level read only.
 | 
					// Make all symbols in this table level read only.
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
@ -230,6 +247,8 @@ TVariable::TVariable(const TVariable& copyOf) : TSymbol(copyOf)
 | 
				
			|||||||
{	
 | 
					{	
 | 
				
			||||||
    type.deepCopy(copyOf.type);
 | 
					    type.deepCopy(copyOf.type);
 | 
				
			||||||
    userType = copyOf.userType;
 | 
					    userType = copyOf.userType;
 | 
				
			||||||
 | 
					    extensions = 0;
 | 
				
			||||||
 | 
					    setExtensions(copyOf.numExtensions, copyOf.extensions);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (! copyOf.unionArray.empty()) {
 | 
					    if (! copyOf.unionArray.empty()) {
 | 
				
			||||||
        assert(!copyOf.type.getStruct());
 | 
					        assert(!copyOf.type.getStruct());
 | 
				
			||||||
@ -255,6 +274,8 @@ TFunction::TFunction(const TFunction& copyOf) : TSymbol(copyOf)
 | 
				
			|||||||
        parameters.back().copyParam(copyOf.parameters[i]);
 | 
					        parameters.back().copyParam(copyOf.parameters[i]);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    extensions = 0;    
 | 
				
			||||||
 | 
					    setExtensions(copyOf.numExtensions, copyOf.extensions);
 | 
				
			||||||
    returnType.deepCopy(copyOf.returnType);
 | 
					    returnType.deepCopy(copyOf.returnType);
 | 
				
			||||||
    mangledName = copyOf.mangledName;
 | 
					    mangledName = copyOf.mangledName;
 | 
				
			||||||
    op = copyOf.op;
 | 
					    op = copyOf.op;
 | 
				
			||||||
 | 
				
			|||||||
@ -81,9 +81,9 @@ class TAnonMember;
 | 
				
			|||||||
class TSymbol {
 | 
					class TSymbol {
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
    POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator())
 | 
					    POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator())
 | 
				
			||||||
    explicit TSymbol(const TString *n) :  name(n), writable(true) { }
 | 
					    explicit TSymbol(const TString *n) :  name(n), writable(true), numExtensions(0), extensions(0) { }
 | 
				
			||||||
	virtual TSymbol* clone() const = 0;
 | 
						virtual TSymbol* clone() const = 0;
 | 
				
			||||||
    virtual ~TSymbol() { }
 | 
					    virtual ~TSymbol() { delete [] extensions; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    virtual const TString& getName() const { return *name; }
 | 
					    virtual const TString& getName() const { return *name; }
 | 
				
			||||||
    virtual void changeName(const TString* newName) { name = newName; }
 | 
					    virtual void changeName(const TString* newName) { name = newName; }
 | 
				
			||||||
@ -97,6 +97,16 @@ public:
 | 
				
			|||||||
    virtual TType& getWritableType() = 0;
 | 
					    virtual TType& getWritableType() = 0;
 | 
				
			||||||
    virtual void setUniqueId(int id) { uniqueId = id; }
 | 
					    virtual void setUniqueId(int id) { uniqueId = id; }
 | 
				
			||||||
    virtual int getUniqueId() const { return uniqueId; }
 | 
					    virtual int getUniqueId() const { return uniqueId; }
 | 
				
			||||||
 | 
					    virtual void setExtensions(int num, const char* const exts[])
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        assert(extensions == 0);
 | 
				
			||||||
 | 
					        numExtensions = num;
 | 
				
			||||||
 | 
					        extensions = new const char*[numExtensions];
 | 
				
			||||||
 | 
					        for (int e = 0; e < num; ++e)
 | 
				
			||||||
 | 
					            extensions[e] = exts[e];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    virtual int getNumExtensions() const { return numExtensions; }
 | 
				
			||||||
 | 
					    virtual const char** getExtensions() const { return extensions; }
 | 
				
			||||||
    virtual void dump(TInfoSink &infoSink) const = 0;
 | 
					    virtual void dump(TInfoSink &infoSink) const = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    virtual bool isReadOnly() const { return ! writable; }
 | 
					    virtual bool isReadOnly() const { return ! writable; }
 | 
				
			||||||
@ -109,6 +119,11 @@ protected:
 | 
				
			|||||||
    const TString *name;
 | 
					    const TString *name;
 | 
				
			||||||
    unsigned int uniqueId;      // For cross-scope comparing during code generation
 | 
					    unsigned int uniqueId;      // For cross-scope comparing during code generation
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // For tracking what extensions must be present 
 | 
				
			||||||
 | 
					    // (don't use if correct version/profile is present).
 | 
				
			||||||
 | 
					    int numExtensions;
 | 
				
			||||||
 | 
					    const char** extensions; // an array of pointers to existing constant char strings
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    //
 | 
					    //
 | 
				
			||||||
    // N.B.: Non-const functions that will be generally used should assert an this,
 | 
					    // N.B.: Non-const functions that will be generally used should assert an this,
 | 
				
			||||||
    // to avoid overwriting shared symbol-table information.
 | 
					    // to avoid overwriting shared symbol-table information.
 | 
				
			||||||
@ -376,6 +391,7 @@ public:
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void relateToOperator(const char* name, TOperator op);
 | 
					    void relateToOperator(const char* name, TOperator op);
 | 
				
			||||||
 | 
					    void setFunctionExtensions(const char* name, int num, const char* const extensions[]);
 | 
				
			||||||
    void dump(TInfoSink &infoSink) const;
 | 
					    void dump(TInfoSink &infoSink) const;
 | 
				
			||||||
	TSymbolTableLevel* clone() const;
 | 
						TSymbolTableLevel* clone() const;
 | 
				
			||||||
    void readOnly();
 | 
					    void readOnly();
 | 
				
			||||||
@ -551,6 +567,12 @@ public:
 | 
				
			|||||||
        for (unsigned int level = 0; level < table.size(); ++level)
 | 
					        for (unsigned int level = 0; level < table.size(); ++level)
 | 
				
			||||||
            table[level]->relateToOperator(name, op);
 | 
					            table[level]->relateToOperator(name, op);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    void setFunctionExtensions(const char* name, int num, const char* const extensions[])
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        for (unsigned int level = 0; level < table.size(); ++level)
 | 
				
			||||||
 | 
					            table[level]->setFunctionExtensions(name, num, extensions);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    int getMaxSymbolId() { return uniqueId; }
 | 
					    int getMaxSymbolId() { return uniqueId; }
 | 
				
			||||||
    void dump(TInfoSink &infoSink) const;
 | 
					    void dump(TInfoSink &infoSink) const;
 | 
				
			||||||
 | 
				
			|||||||
@ -60,6 +60,7 @@
 | 
				
			|||||||
//        requireStage()
 | 
					//        requireStage()
 | 
				
			||||||
//        checkDeprecated()
 | 
					//        checkDeprecated()
 | 
				
			||||||
//        requireNotRemoved()
 | 
					//        requireNotRemoved()
 | 
				
			||||||
 | 
					//        requireExtensions()
 | 
				
			||||||
//    
 | 
					//    
 | 
				
			||||||
//    Typically, only the first two calls are needed.  They go into a code path that 
 | 
					//    Typically, only the first two calls are needed.  They go into a code path that 
 | 
				
			||||||
//    implements Feature F, and will log the proper error/warning messages.  Parsing 
 | 
					//    implements Feature F, and will log the proper error/warning messages.  Parsing 
 | 
				
			||||||
@ -129,8 +130,12 @@
 | 
				
			|||||||
// 
 | 
					// 
 | 
				
			||||||
//        ~EEsProfile
 | 
					//        ~EEsProfile
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
// 6) If built-in symbols are added by the extension, add them in Initialize.cpp; see
 | 
					// 6) If built-in symbols are added by the extension, add them in Initialize.cpp:  Their use
 | 
				
			||||||
//    the comment at the top of that file for where to put them.
 | 
					//    will be automatically error checked against the extensions enabled at that moment.
 | 
				
			||||||
 | 
					//    see the comment at the top of Initialize.cpp for where to put them.  Establish them at
 | 
				
			||||||
 | 
					//    the earliest release that supports the extension.  Then, tag them with the
 | 
				
			||||||
 | 
					//    set of extensions that both enable them and are necessary, given the version of the symbol
 | 
				
			||||||
 | 
					//    table. (There is a different symbol table for each version.)
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "ParseHelper.h"
 | 
					#include "ParseHelper.h"
 | 
				
			||||||
@ -145,6 +150,7 @@ namespace glslang {
 | 
				
			|||||||
void TParseContext::initializeExtensionBehavior()
 | 
					void TParseContext::initializeExtensionBehavior()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    extensionBehavior[GL_OES_texture_3D]               = EBhDisable;
 | 
					    extensionBehavior[GL_OES_texture_3D]               = EBhDisable;
 | 
				
			||||||
 | 
					    extensionBehavior[GL_OES_standard_derivatives]     = EBhDisable;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    extensionBehavior[GL_ARB_texture_rectangle]        = EBhDisable;
 | 
					    extensionBehavior[GL_ARB_texture_rectangle]        = EBhDisable;
 | 
				
			||||||
    extensionBehavior[GL_3DL_array_objects]            = EBhDisable;
 | 
					    extensionBehavior[GL_3DL_array_objects]            = EBhDisable;
 | 
				
			||||||
@ -159,8 +165,9 @@ const char* TParseContext::getPreamble()
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    if (profile == EEsProfile) {
 | 
					    if (profile == EEsProfile) {
 | 
				
			||||||
        return
 | 
					        return
 | 
				
			||||||
 | 
					            "#define GL_ES 1\n"
 | 
				
			||||||
            "#define GL_OES_texture_3D 1\n"
 | 
					            "#define GL_OES_texture_3D 1\n"
 | 
				
			||||||
            "#define GL_ES 1\n";
 | 
					            "#define GL_OES_standard_derivatives 1\n";
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
        return
 | 
					        return
 | 
				
			||||||
            "#define GL_FRAGMENT_PRECISION_HIGH 1\n"
 | 
					            "#define GL_FRAGMENT_PRECISION_HIGH 1\n"
 | 
				
			||||||
@ -316,6 +323,41 @@ void TParseContext::requireNotRemoved(TSourceLoc loc, int profileMask, int remov
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Use when there are no profile/version to check, it's just an error if one of the
 | 
				
			||||||
 | 
					// extensions is not present.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					void TParseContext::requireExtensions(TSourceLoc loc, int numExtensions, const char* const extensions[], const char *featureDesc)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    // First, see if any of the extensions are enabled
 | 
				
			||||||
 | 
					    for (int i = 0; i < numExtensions; ++i) {
 | 
				
			||||||
 | 
					        TExtensionBehavior behavior = getExtensionBehavior(extensions[i]);
 | 
				
			||||||
 | 
					        if (behavior == EBhEnable || behavior == EBhRequire)
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // See if any extensions want to give a warning on use; give warnings for all such extensions
 | 
				
			||||||
 | 
					    bool warned = false;
 | 
				
			||||||
 | 
					    for (int i = 0; i < numExtensions; ++i) {
 | 
				
			||||||
 | 
					        TExtensionBehavior behavior = getExtensionBehavior(extensions[i]);
 | 
				
			||||||
 | 
					        if (behavior == EBhWarn) {
 | 
				
			||||||
 | 
					            infoSink.info.message(EPrefixWarning, ("extension " + TString(extensions[i]) + " is being used for " + featureDesc).c_str(), loc);
 | 
				
			||||||
 | 
					            warned = true;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (warned)
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // If we get this far, give errors explaining what extensions are needed
 | 
				
			||||||
 | 
					    if (numExtensions == 1)
 | 
				
			||||||
 | 
					        error(loc, "required extension not requested:", featureDesc, extensions[0]);
 | 
				
			||||||
 | 
					    else {
 | 
				
			||||||
 | 
					        error(loc, "required extension not requested:", featureDesc, "Possible extensions include:");
 | 
				
			||||||
 | 
					        for (int i = 0; i < numExtensions; ++i)
 | 
				
			||||||
 | 
					            infoSink.info.message(EPrefixNone, extensions[i]);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
TExtensionBehavior TParseContext::getExtensionBehavior(const char* extension)
 | 
					TExtensionBehavior TParseContext::getExtensionBehavior(const char* extension)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    TMap<TString, TExtensionBehavior>::iterator iter = extensionBehavior.find(TString(extension));
 | 
					    TMap<TString, TExtensionBehavior>::iterator iter = extensionBehavior.find(TString(extension));
 | 
				
			||||||
@ -375,12 +417,12 @@ void TParseContext::updateExtensionBehavior(const char* extension, const char* b
 | 
				
			|||||||
        if (iter == extensionBehavior.end()) {
 | 
					        if (iter == extensionBehavior.end()) {
 | 
				
			||||||
            switch (behavior) {
 | 
					            switch (behavior) {
 | 
				
			||||||
            case EBhRequire:
 | 
					            case EBhRequire:
 | 
				
			||||||
                error(getCurrentLoc(), "extension not supported", "#extension", extension);
 | 
					                error(getCurrentLoc(), "extension not supported:", "#extension", extension);
 | 
				
			||||||
                break;
 | 
					                break;
 | 
				
			||||||
            case EBhEnable:
 | 
					            case EBhEnable:
 | 
				
			||||||
            case EBhWarn:
 | 
					            case EBhWarn:
 | 
				
			||||||
            case EBhDisable:
 | 
					            case EBhDisable:
 | 
				
			||||||
                warn(getCurrentLoc(), "extension not supported", "#extension", extension);
 | 
					                warn(getCurrentLoc(), "extension not supported:", "#extension", extension);
 | 
				
			||||||
                break;
 | 
					                break;
 | 
				
			||||||
            default:
 | 
					            default:
 | 
				
			||||||
                assert(0 && "unexpected behavior");
 | 
					                assert(0 && "unexpected behavior");
 | 
				
			||||||
 | 
				
			|||||||
@ -73,7 +73,7 @@ typedef enum {
 | 
				
			|||||||
// functions, but better to have the compiler do spelling checks.
 | 
					// functions, but better to have the compiler do spelling checks.
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
const char* const GL_OES_texture_3D               = "GL_OES_texture_3D";
 | 
					const char* const GL_OES_texture_3D               = "GL_OES_texture_3D";
 | 
				
			||||||
 | 
					const char* const GL_OES_standard_derivatives     = "GL_OES_standard_derivatives";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const char* const GL_ARB_texture_rectangle        = "GL_ARB_texture_rectangle";
 | 
					const char* const GL_ARB_texture_rectangle        = "GL_ARB_texture_rectangle";
 | 
				
			||||||
const char* const GL_3DL_array_objects            = "GL_3DL_array_objects";
 | 
					const char* const GL_3DL_array_objects            = "GL_3DL_array_objects";
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user