From 44b807e1d0f061889d92126596e1a9b32da42a3c Mon Sep 17 00:00:00 2001 From: John Kessenich Date: Tue, 21 Jan 2014 04:43:23 +0000 Subject: [PATCH] GL_ARB_enhanced_layouts, part 3: Semantics for xfb_*: where they can go, inheritance, etc., but not yet the backing arithmetic for offsets and strides. git-svn-id: https://cvs.khronos.org/svn/repos/ogl/trunk/ecosystem/public/sdk/tools/glslang@24916 e7fa87d3-cd2b-0410-9028-fcbf551c1848 --- Test/440.vert | 34 +++++ Test/baseResults/440.vert.out | 15 ++- glslang/Include/Types.h | 164 ++++++++++++++----------- glslang/Include/revision.h | 4 +- glslang/MachineIndependent/ParseHelper.cpp | 56 ++++++--- glslang/MachineIndependent/ParseHelper.h | 1 + glslang/MachineIndependent/intermOut.cpp | 3 + glslang/MachineIndependent/linkValidate.cpp | 3 + glslang/MachineIndependent/localintermediate.h | 4 +- 9 files changed, 193 insertions(+), 91 deletions(-) diff --git a/Test/440.vert b/Test/440.vert index 3aeebaa..d02e7d3 100644 --- a/Test/440.vert +++ b/Test/440.vert @@ -62,3 +62,37 @@ layout(location = 1, component = 1) out; // ERROR, no global set layout(location = 50, component = 3) out int be; layout(location = 50, component = 0) out vec3 bf; + +out bblck1 { + vec4 bbv; +} bbinst1; + +out bblck2 { + layout(xfb_offset=16) vec4 bbv; +} bbinst2; + +layout(xfb_buffer = 3, xfb_stride = 16) out; + +out bblck3 { + layout(xfb_offset=16) vec4 bbv; +} bbinst3; + +uniform ubblck3 { + layout(xfb_offset=16) vec4 bbv; // ERROR +} ubbinst3; + +layout(xfb_buffer=2, xfb_offset=32, xfb_stride=64) out vec4 bg; +layout( xfb_offset=32, xfb_stride=64) out vec4 bh; + +layout(xfb_offset=48) out; // ERROR + +layout(xfb_stride=32, xfb_buffer=2, xfb_offset=16) out bblck4 { + vec4 bbv1; + vec4 bbv2; +} bbinst4; + +out bblck5 { + layout(xfb_offset=0) vec4 bbv1; + layout(xfb_stride=32, xfb_buffer=3, xfb_offset=16) vec4 bbv2; + layout(xfb_buffer=2) vec4 bbv3; // ERROR, wrong buffer +} bbinst5; diff --git a/Test/baseResults/440.vert.out b/Test/baseResults/440.vert.out index ed94e05..6eef4ab 100644 --- a/Test/baseResults/440.vert.out +++ b/Test/baseResults/440.vert.out @@ -19,9 +19,13 @@ ERROR: 0:55: 'component' : type overflows the available 4 components ERROR: 0:57: 'component' : cannot apply to a matrix, structure, or block ERROR: 0:58: 'component' : cannot apply to a matrix, structure, or block ERROR: 0:61: 'location' : cannot declare a default, use a full declaration -ERROR: 19 compilation errors. No code generated. +ERROR: 0:81: 'xfb layout qualifier' : can only be used on an output +ERROR: 0:87: 'xfb_offset' : cannot declare a default, use a full declaration +ERROR: 0:97: 'xfb_buffer' : member cannot contradict block (or what block inherited from global) +ERROR: 22 compilation errors. No code generated. +in xfb mode ERROR: node is still EOpNull! 0:? Linker Objects 0:? 'a' (layout(location=2 component=2 ) in 2-component vector of float) @@ -55,6 +59,14 @@ ERROR: node is still EOpNull! 0:? 'bd' (out block{layout(location=40 component=2 ) out float u, layout(location=40 component=0 ) out float v, layout(location=40 component=3 ) out float w, layout(location=40 component=1 ) out 2-component vector of float x, layout(location=41 component=3 ) out 2-component vector of float y, layout(location=42 component=1 ) out 4-component vector of float z, layout(location=42 component=1 ) out 4X4 matrix of float ba, layout(location=43 component=1 ) out structure{int a} Ss}) 0:? 'be' (layout(location=50 component=3 ) smooth out int) 0:? 'bf' (layout(location=50 component=0 ) smooth out 3-component vector of float) +0:? 'bbinst1' (out block{out 4-component vector of float bbv}) +0:? 'bbinst2' (out block{layout(xfb_buffer=0 xfb_offset=16 ) out 4-component vector of float bbv}) +0:? 'bbinst3' (out block{layout(xfb_buffer=3 xfb_offset=16 ) out 4-component vector of float bbv}) +0:? 'ubbinst3' (layout(column_major shared ) uniform block{layout(column_major shared xfb_offset=16 ) uniform 4-component vector of float bbv}) +0:? 'bg' (layout(xfb_buffer=2 xfb_offset=32 xfb_stride=64 ) smooth out 4-component vector of float) +0:? 'bh' (layout(xfb_buffer=3 xfb_offset=32 xfb_stride=64 ) smooth out 4-component vector of float) +0:? 'bbinst4' (layout(xfb_buffer=2 xfb_offset=16 xfb_stride=32 ) out block{layout(xfb_buffer=2 xfb_offset=16 ) out 4-component vector of float bbv1, layout(xfb_buffer=2 xfb_offset=16 ) out 4-component vector of float bbv2}) +0:? 'bbinst5' (out block{layout(xfb_buffer=3 xfb_offset=0 ) out 4-component vector of float bbv1, layout(xfb_buffer=3 xfb_offset=16 xfb_stride=32 ) out 4-component vector of float bbv2, out 4-component vector of float bbv3}) 0:? 'gl_VertexID' (gl_VertexId int) 0:? 'gl_InstanceID' (gl_InstanceId int) @@ -63,4 +75,5 @@ Linked vertex stage: ERROR: Linking vertex stage: Missing entry point: Each stage requires one "void main()" entry point +in xfb mode diff --git a/glslang/Include/Types.h b/glslang/Include/Types.h index 8424126..56d70e4 100644 --- a/glslang/Include/Types.h +++ b/glslang/Include/Types.h @@ -255,7 +255,7 @@ public: writeonly = false; clearLayout(); } - TStorageQualifier storage : 6; + TStorageQualifier storage : 6; TPrecisionQualifier precision : 3; bool invariant : 1; bool centroid : 1; @@ -413,9 +413,21 @@ public: } bool hasXfb() const { - return layoutXfbBuffer != layoutXfbBufferEnd || - layoutXfbStride != layoutXfbStrideEnd || - layoutXfbOffset != layoutXfbOffsetEnd; + return hasXfbBuffer() || + hasXfbStride() || + hasXfbOffset(); + } + bool hasXfbBuffer() const + { + return layoutXfbBuffer != layoutXfbBufferEnd; + } + bool hasXfbStride() const + { + return layoutXfbStride != layoutXfbStrideEnd; + } + bool hasXfbOffset() const + { + return layoutXfbOffset != layoutXfbOffsetEnd; } static const char* getLayoutPackingString(TLayoutPacking packing) { @@ -662,7 +674,7 @@ public: { sampler.clear(); qualifier.clear(); - typeName = NewPoolTString(n.c_str()); + typeName = NewPoolTString(n.c_str()); } // For interface blocks TType(TTypeList* userDef, const TString& n, const TQualifier& q) : @@ -670,7 +682,7 @@ public: qualifier(q), arraySizes(0), structure(userDef), fieldName(0) { sampler.clear(); - typeName = NewPoolTString(n.c_str()); + typeName = NewPoolTString(n.c_str()); } virtual ~TType() {} @@ -679,21 +691,21 @@ public: // the instances are sharing the same pool. void shallowCopy(const TType& copyOf) { - basicType = copyOf.basicType; + basicType = copyOf.basicType; sampler = copyOf.sampler; - qualifier = copyOf.qualifier; - vectorSize = copyOf.vectorSize; - matrixCols = copyOf.matrixCols; - matrixRows = copyOf.matrixRows; + qualifier = copyOf.qualifier; + vectorSize = copyOf.vectorSize; + matrixCols = copyOf.matrixCols; + matrixRows = copyOf.matrixRows; arraySizes = copyOf.arraySizes; structure = copyOf.structure; structureSize = copyOf.structureSize; - fieldName = copyOf.fieldName; - typeName = copyOf.typeName; + fieldName = copyOf.fieldName; + typeName = copyOf.typeName; } - void deepCopy(const TType& copyOf) - { + void deepCopy(const TType& copyOf) + { shallowCopy(copyOf); if (arraySizes) { @@ -701,31 +713,31 @@ public: *arraySizes = *copyOf.arraySizes; } - if (structure) { - structure = new TTypeList; - TStructureMapIterator iter; - for (unsigned int i = 0; i < copyOf.structure->size(); ++i) { - TTypeLoc typeLoc; - typeLoc.loc = (*copyOf.structure)[i].loc; - typeLoc.type = new TType(); - typeLoc.type->deepCopy(*(*copyOf.structure)[i].type); - structure->push_back(typeLoc); - } - } - - if (fieldName) - fieldName = NewPoolTString(copyOf.fieldName->c_str()); - if (typeName) - typeName = NewPoolTString(copyOf.typeName->c_str()); - } + if (structure) { + structure = new TTypeList; + TStructureMapIterator iter; + for (unsigned int i = 0; i < copyOf.structure->size(); ++i) { + TTypeLoc typeLoc; + typeLoc.loc = (*copyOf.structure)[i].loc; + typeLoc.type = new TType(); + typeLoc.type->deepCopy(*(*copyOf.structure)[i].type); + structure->push_back(typeLoc); + } + } + + if (fieldName) + fieldName = NewPoolTString(copyOf.fieldName->c_str()); + if (typeName) + typeName = NewPoolTString(copyOf.typeName->c_str()); + } TType* clone() - { - TType *newType = new TType(); - newType->deepCopy(*this); + { + TType *newType = new TType(); + newType->deepCopy(*this); - return newType; - } + return newType; + } // Merge type from parent, where a parentType is at the beginning of a declaration, // establishing some charastics for all subsequent names, while this type @@ -768,14 +780,14 @@ public: virtual void setFieldName(const TString& n) { fieldName = NewPoolTString(n.c_str()); } virtual const TString& getTypeName() const { - assert(typeName); - return *typeName; + assert(typeName); + return *typeName; } virtual const TString& getFieldName() const { - assert(fieldName); - return *fieldName; + assert(fieldName); + return *fieldName; } virtual TBasicType getBasicType() const { return basicType; } @@ -789,7 +801,7 @@ public: virtual bool isScalar() const { return vectorSize == 1 && ! isStruct() && ! isArray(); } virtual bool isVector() const { return vectorSize > 1; } - virtual bool isMatrix() const { return matrixCols ? true : false; } + virtual bool isMatrix() const { return matrixCols ? true : false; } virtual bool isArray() const { return arraySizes != 0; } virtual bool isStruct() const { return structure != 0; } @@ -798,9 +810,9 @@ public: { if (isArray()) return true; - if (! structure) + if (! structure) return false; - for (unsigned int i = 0; i < structure->size(); ++i) { + for (unsigned int i = 0; i < structure->size(); ++i) { if ((*structure)[i].type->containsArray()) return true; } @@ -852,35 +864,41 @@ public: const int maxSize = GlslangMaxTypeLength; char buf[maxSize]; char *p = &buf[0]; - char *end = &buf[maxSize]; + char *end = &buf[maxSize]; if (qualifier.hasLayout()) { - p += snprintf(p, end - p, "layout("); - if (qualifier.hasLocation()) { - p += snprintf(p, end - p, "location=%d ", qualifier.layoutLocation); - if (qualifier.layoutComponent != qualifier.layoutComponentEnd) - p += snprintf(p, end - p, "component=%d ", qualifier.layoutComponent); + // To reduce noise, skip this if the only layout is an xfb_buffer + // with no triggering xfb_offset. + TQualifier noXfbBuffer = qualifier; + noXfbBuffer.layoutXfbBuffer = TQualifier::layoutXfbBufferEnd; + if (noXfbBuffer.hasLayout()) { + p += snprintf(p, end - p, "layout("); + if (qualifier.hasLocation()) { + p += snprintf(p, end - p, "location=%d ", qualifier.layoutLocation); + if (qualifier.layoutComponent != qualifier.layoutComponentEnd) + p += snprintf(p, end - p, "component=%d ", qualifier.layoutComponent); + } + if (qualifier.hasBinding()) + p += snprintf(p, end - p, "binding=%d ", qualifier.layoutBinding); + if (qualifier.hasStream()) + p += snprintf(p, end - p, "stream=%d ", qualifier.layoutStream); + if (qualifier.layoutMatrix != ElmNone) + p += snprintf(p, end - p, "%s ", TQualifier::getLayoutMatrixString(qualifier.layoutMatrix)); + if (qualifier.layoutPacking != ElpNone) + p += snprintf(p, end - p, "%s ", TQualifier::getLayoutPackingString(qualifier.layoutPacking)); + if (qualifier.layoutOffset != -1) + p += snprintf(p, end - p, "offset=%d ", qualifier.layoutOffset); + if (qualifier.layoutAlign != -1) + p += snprintf(p, end - p, "align=%d ", qualifier.layoutAlign); + + if (qualifier.hasXfbBuffer() && qualifier.hasXfbOffset()) + p += snprintf(p, end - p, "xfb_buffer=%d ", qualifier.layoutXfbBuffer); + if (qualifier.hasXfbOffset()) + p += snprintf(p, end - p, "xfb_offset=%d ", qualifier.layoutXfbOffset); + if (qualifier.hasXfbStride()) + p += snprintf(p, end - p, "xfb_stride=%d ", qualifier.layoutXfbStride); + p += snprintf(p, end - p, ") "); } - if (qualifier.hasBinding()) - p += snprintf(p, end - p, "binding=%d ", qualifier.layoutBinding); - if (qualifier.hasStream()) - p += snprintf(p, end - p, "stream=%d ", qualifier.layoutStream); - if (qualifier.layoutMatrix != ElmNone) - p += snprintf(p, end - p, "%s ", TQualifier::getLayoutMatrixString(qualifier.layoutMatrix)); - if (qualifier.layoutPacking != ElpNone) - p += snprintf(p, end - p, "%s ", TQualifier::getLayoutPackingString(qualifier.layoutPacking)); - if (qualifier.layoutOffset != -1) - p += snprintf(p, end - p, "offset=%d ", qualifier.layoutOffset); - if (qualifier.layoutAlign != -1) - p += snprintf(p, end - p, "align=%d ", qualifier.layoutAlign); - - if (qualifier.layoutXfbBuffer != qualifier.layoutXfbBufferEnd) - p += snprintf(p, end - p, "xfb_buffer=%d ", qualifier.layoutXfbBuffer); - if (qualifier.layoutXfbOffset != qualifier.layoutXfbOffsetEnd) - p += snprintf(p, end - p, "xfb_offset=%d ", qualifier.layoutXfbOffset); - if (qualifier.layoutXfbStride != qualifier.layoutXfbStrideEnd) - p += snprintf(p, end - p, "xfb_stride=%d ", qualifier.layoutXfbStride); - p += snprintf(p, end - p, ") "); } if (qualifier.invariant) @@ -1063,7 +1081,7 @@ protected: void buildMangledName(TString&); int getStructSize() const; - TBasicType basicType : 8; + TBasicType basicType : 8; int vectorSize : 4; int matrixCols : 4; int matrixRows : 4; @@ -1074,8 +1092,8 @@ protected: TTypeList* structure; // 0 unless this is a struct mutable int structureSize; // a cache, updated on first access - TString *fieldName; // for structure field names - TString *typeName; // for structure type name + TString *fieldName; // for structure field names + TString *typeName; // for structure type name }; } // end namespace glslang diff --git a/glslang/Include/revision.h b/glslang/Include/revision.h index 6165430..dbaa25c 100644 --- a/glslang/Include/revision.h +++ b/glslang/Include/revision.h @@ -9,5 +9,5 @@ // source have to figure out how to create revision.h just to get a build // going. However, if it is not updated, it can be a version behind. -#define GLSLANG_REVISION "24740" -#define GLSLANG_DATE "2014/01/11 12:29:55" +#define GLSLANG_REVISION "24741" +#define GLSLANG_DATE "2014/01/11 13:35:26" diff --git a/glslang/MachineIndependent/ParseHelper.cpp b/glslang/MachineIndependent/ParseHelper.cpp index 632a17f..ce4c885 100644 --- a/glslang/MachineIndependent/ParseHelper.cpp +++ b/glslang/MachineIndependent/ParseHelper.cpp @@ -101,11 +101,14 @@ TParseContext::TParseContext(TSymbolTable& symt, TIntermediate& interm, bool pb, globalBufferDefaults.layoutMatrix = ElmColumnMajor; globalBufferDefaults.layoutPacking = ElpShared; - // TODO: 4.4 enhanced layouts: defaults for xfb? - globalInputDefaults.clear(); globalOutputDefaults.clear(); + if (language == EShLangVertex || + language == EShLangTessControl || + language == EShLangTessEvaluation || + language == EShLangGeometry) + globalOutputDefaults.layoutXfbBuffer = 0; if (language == EShLangGeometry) globalOutputDefaults.layoutStream = 0; } @@ -1791,7 +1794,7 @@ void TParseContext::globalQualifierCheck(TSourceLoc loc, const TQualifier& quali case EShLangCompute: break; - default: + default: break; } } else { @@ -1827,7 +1830,7 @@ void TParseContext::globalQualifierCheck(TSourceLoc loc, const TQualifier& quali case EShLangCompute: break; - default: + default: break; } } @@ -2869,6 +2872,7 @@ void TParseContext::setLayoutQualifier(TSourceLoc loc, TPublicType& publicType, publicType.qualifier.layoutComponent = value; return; } else if (id.compare(0, 4, "xfb_") == 0) { + intermediate.setXfbMode(); const char* feature = "transform feedback qualifier"; requireStage(loc, (EShLanguageMask)(EShLangVertexMask | EShLangGeometryMask | EShLangTessControlMask | EShLangTessEvaluationMask), feature); requireProfile(loc, ECoreProfile | ECompatibilityProfile, feature); @@ -2878,16 +2882,19 @@ void TParseContext::setLayoutQualifier(TSourceLoc loc, TPublicType& publicType, error(loc, "buffer is too large", id.c_str(), ""); else publicType.qualifier.layoutXfbBuffer = value; + return; } else if (id == "xfb_offset") { if (value >= TQualifier::layoutXfbOffsetEnd) // TODO: 4.4 enhanced layouts: also check against gl_MaxTransformFeedbackInterleavedComponents error(loc, "offset is too large", id.c_str(), ""); else publicType.qualifier.layoutXfbOffset = value; + return; } else if (id == "xfb_stride") { - if (value >= TQualifier::layoutXfbStrideEnd) // TODO: 4.4 enhanced layouts: also check against gl_MaxTransformFeedbackInterleavedComponents + if (value >= TQualifier::layoutXfbStrideEnd) // TODO: 4.4 enhanced layouts: also check against 4*gl_MaxTransformFeedbackInterleavedComponents error(loc, "stride is too large", id.c_str(), ""); else publicType.qualifier.layoutXfbStride = value; + return; } } @@ -2929,7 +2936,7 @@ void TParseContext::setLayoutQualifier(TSourceLoc loc, TPublicType& publicType, case EShLangCompute: break; - default: + default: break; } @@ -2947,8 +2954,10 @@ void TParseContext::mergeObjectLayoutQualifiers(TSourceLoc loc, TQualifier& dst, if (src.hasStream()) dst.layoutStream = src.layoutStream; - if (src.layoutXfbBuffer != TQualifier::layoutXfbBufferEnd) + if (src.hasXfbBuffer()) dst.layoutXfbBuffer = src.layoutXfbBuffer; + if (src.hasXfbOffset()) + dst.layoutXfbOffset = src.layoutXfbOffset; if (! inheritOnly) { if (src.layoutLocation != TQualifier::layoutLocationEnd) @@ -2964,10 +2973,8 @@ void TParseContext::mergeObjectLayoutQualifiers(TSourceLoc loc, TQualifier& dst, if (src.layoutBinding != TQualifier::layoutBindingEnd) dst.layoutBinding = src.layoutBinding; - if (src.layoutXfbStride != TQualifier::layoutXfbStrideEnd) + if (src.hasXfbStride()) dst.layoutXfbStride = src.layoutXfbStride; - if (src.layoutXfbOffset != TQualifier::layoutXfbOffsetEnd) - dst.layoutXfbOffset = src.layoutXfbOffset; } } @@ -3145,6 +3152,10 @@ void TParseContext::layoutQualifierCheck(TSourceLoc loc, const TQualifier& quali if (qualifier.storage != EvqVaryingOut) error(loc, "can only be used on an output", "stream", ""); } + if (qualifier.hasXfb()) { + if (qualifier.storage != EvqVaryingOut) + error(loc, "can only be used on an output", "xfb layout qualifier", ""); + } } // For places that can't have shader-level layout qualifiers @@ -3303,10 +3314,6 @@ TIntermNode* TParseContext::declareVariable(TSourceLoc loc, TString& identifier, invariantCheck(loc, type, identifier); samplerCheck(loc, type, identifier); - // Pick up defaults - if (! type.getQualifier().hasStream() && language == EShLangGeometry && type.getQualifier().storage == EvqVaryingOut) - type.getQualifier().layoutStream = globalOutputDefaults.layoutStream; - 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", ""); @@ -3316,6 +3323,8 @@ TIntermNode* TParseContext::declareVariable(TSourceLoc loc, TString& identifier, if (! symbol) reservedErrorCheck(loc, identifier); + inheritGlobalDefaults(type.getQualifier()); + // Declare the variable if (arraySizes || type.isArray()) { // Arrayness is potentially coming both from the type and from the @@ -3369,6 +3378,17 @@ TIntermNode* TParseContext::declareVariable(TSourceLoc loc, TString& identifier, return initNode; } +// Pick up global defaults from the provide global defaults into dst. +void TParseContext::inheritGlobalDefaults(TQualifier& dst) const +{ + if (dst.storage == EvqVaryingOut) { + if (! dst.hasStream() && language == EShLangGeometry) + dst.layoutStream = globalOutputDefaults.layoutStream; + if (! dst.hasXfbBuffer()) + dst.layoutXfbBuffer = globalOutputDefaults.layoutXfbBuffer; + } +} + // // Declare a non-array variable, the main point being there is no redeclaration // for resizing allowed. @@ -3824,6 +3844,10 @@ void TParseContext::declareBlock(TSourceLoc loc, TTypeList& typeList, const TStr if (defaultQualification.layoutStream != memberQualifier.layoutStream) error(memberLoc, "member cannot contradict block", "stream", ""); } + if (memberQualifier.hasXfbBuffer()) { + if (defaultQualification.layoutXfbBuffer != memberQualifier.layoutXfbBuffer) + error(memberLoc, "member cannot contradict block (or what block inherited from global)", "xfb_buffer", ""); + } if (memberQualifier.layoutPacking != ElpNone) error(memberLoc, "member of block cannot have a packing layout qualifier", typeList[member].type->getFieldName().c_str(), ""); if (memberQualifier.hasLocation()) { @@ -4124,6 +4148,8 @@ void TParseContext::updateStandaloneQualifierDefaults(TSourceLoc loc, const TPub case EvqVaryingOut: if (qualifier.hasStream()) globalOutputDefaults.layoutStream = qualifier.layoutStream; + if (qualifier.hasXfbBuffer()) + globalOutputDefaults.layoutXfbBuffer = qualifier.layoutXfbBuffer; break; default: error(loc, "default qualifier requires 'uniform', 'buffer', 'in', or 'out' storage qualification", "", ""); @@ -4134,6 +4160,8 @@ void TParseContext::updateStandaloneQualifierDefaults(TSourceLoc loc, const TPub error(loc, "cannot declare a default, include a type or full declaration", "binding", ""); if (qualifier.hasLocation()) error(loc, "cannot declare a default, use a full declaration", "location", ""); + if (qualifier.hasXfbOffset()) + error(loc, "cannot declare a default, use a full declaration", "xfb_offset", ""); } // diff --git a/glslang/MachineIndependent/ParseHelper.h b/glslang/MachineIndependent/ParseHelper.h index 7a7763e..4eeb2d3 100644 --- a/glslang/MachineIndependent/ParseHelper.h +++ b/glslang/MachineIndependent/ParseHelper.h @@ -202,6 +202,7 @@ public: protected: void nonInitConstCheck(TSourceLoc, TString& identifier, TType& type); + void inheritGlobalDefaults(TQualifier& dst) const; TVariable* declareNonArray(TSourceLoc, TString& identifier, TType&, bool& newDeclaration); void declareArray(TSourceLoc, TString& identifier, const TType&, TSymbol*&, bool& newDeclaration); TIntermNode* executeInitializer(TSourceLoc, TString& identifier, TIntermTyped* initializer, TVariable* variable); diff --git a/glslang/MachineIndependent/intermOut.cpp b/glslang/MachineIndependent/intermOut.cpp index 64febdb..f510353 100644 --- a/glslang/MachineIndependent/intermOut.cpp +++ b/glslang/MachineIndependent/intermOut.cpp @@ -579,6 +579,9 @@ bool TOutputTraverser::visitSwitch(TVisit /* visit */, TIntermSwitch* node) // void TIntermediate::output(TInfoSink& infoSink, bool tree) { + if (xfbMode) + infoSink.debug << "in xfb mode\n"; + switch (language) { case EShLangVertex: break; diff --git a/glslang/MachineIndependent/linkValidate.cpp b/glslang/MachineIndependent/linkValidate.cpp index 0b9b50b..cec1729 100644 --- a/glslang/MachineIndependent/linkValidate.cpp +++ b/glslang/MachineIndependent/linkValidate.cpp @@ -110,6 +110,9 @@ void TIntermediate::merge(TInfoSink& infoSink, TIntermediate& unit) if (unit.pointMode) pointMode = true; + if (unit.xfbMode) + xfbMode = true; + if (unit.treeRoot == 0) return; diff --git a/glslang/MachineIndependent/localintermediate.h b/glslang/MachineIndependent/localintermediate.h index 2ffda5d..939950a 100644 --- a/glslang/MachineIndependent/localintermediate.h +++ b/glslang/MachineIndependent/localintermediate.h @@ -62,7 +62,7 @@ public: explicit TIntermediate(EShLanguage l, int v = 0, EProfile p = ENoProfile) : language(l), treeRoot(0), profile(p), version(v), numMains(0), numErrors(0), recursive(false), invocations(0), vertices(0), inputPrimitive(ElgNone), outputPrimitive(ElgNone), pixelCenterInteger(false), originUpperLeft(false), - vertexSpacing(EvsNone), vertexOrder(EvoNone), pointMode(false) { } + vertexSpacing(EvsNone), vertexOrder(EvoNone), pointMode(false), xfbMode(false) { } bool postProcess(TIntermNode*, EShLanguage); void output(TInfoSink&, bool tree); void removeTree(); @@ -153,6 +153,7 @@ public: return true; } void setPointMode() { pointMode = true; } + void setXfbMode() { xfbMode = true; } bool setOutputPrimitive(TLayoutGeometry p) { if (outputPrimitive != ElgNone) @@ -202,6 +203,7 @@ protected: TVertexSpacing vertexSpacing; TVertexOrder vertexOrder; bool pointMode; + bool xfbMode; // for detecting recursion: pair is struct TCall { -- 2.7.4