Revert "Merge pull request #1792 from Roy-AMD/automapping-opengl-location"
This reverts commit 50ada66c2717fb579979d54ac723475de2b1a5c4, reversing changes made to 3464b6f519be1500faa60698918f13f4dd796dd0.
This commit is contained in:
		
							parent
							
								
									50ada66c27
								
							
						
					
					
						commit
						302fe97e7b
					
				| @ -1852,7 +1852,7 @@ const char* TShader::getInfoDebugLog() | ||||
|     return infoSink->debug.c_str(); | ||||
| } | ||||
| 
 | ||||
| TProgram::TProgram() : reflection(0), linked(false) | ||||
| TProgram::TProgram() : reflection(0), ioMapper(nullptr), linked(false) | ||||
| { | ||||
|     pool = new TPoolAllocator; | ||||
|     infoSink = new TInfoSink; | ||||
| @ -1864,6 +1864,7 @@ TProgram::TProgram() : reflection(0), linked(false) | ||||
| 
 | ||||
| TProgram::~TProgram() | ||||
| { | ||||
|     delete ioMapper; | ||||
|     delete infoSink; | ||||
|     delete reflection; | ||||
| 
 | ||||
| @ -2034,24 +2035,21 @@ void TProgram::dumpReflection() { if (reflection != nullptr) reflection->dump(); | ||||
| //
 | ||||
| // I/O mapping implementation.
 | ||||
| //
 | ||||
| bool TProgram::mapIO(TIoMapResolver* pResolver, TIoMapper* pIoMapper) | ||||
| bool TProgram::mapIO(TIoMapResolver* resolver) | ||||
| { | ||||
|     if (! linked) | ||||
|     if (! linked || ioMapper) | ||||
|         return false; | ||||
|     TIoMapper* ioMapper = nullptr; | ||||
|     TIoMapper defaultIOMapper; | ||||
|     if (pIoMapper == nullptr) | ||||
|         ioMapper = &defaultIOMapper; | ||||
|     else | ||||
|         ioMapper = pIoMapper; | ||||
| 
 | ||||
|     ioMapper = new TIoMapper; | ||||
| 
 | ||||
|     for (int s = 0; s < EShLangCount; ++s) { | ||||
|         if (intermediate[s]) { | ||||
|             if (! ioMapper->addStage((EShLanguage)s, *intermediate[s], *infoSink, pResolver)) | ||||
|             if (! ioMapper->addStage((EShLanguage)s, *intermediate[s], *infoSink, resolver)) | ||||
|                 return false; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     return ioMapper->doMap(pResolver, *infoSink); | ||||
|     return true; | ||||
| } | ||||
| 
 | ||||
| } // end namespace glslang
 | ||||
|  | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @ -36,9 +36,8 @@ | ||||
| #ifndef _IOMAPPER_INCLUDED | ||||
| #define _IOMAPPER_INCLUDED | ||||
| 
 | ||||
| #include "LiveTraverser.h" | ||||
| #include <unordered_map> | ||||
| #include <unordered_set> | ||||
| #include "../Public/ShaderLang.h" | ||||
| 
 | ||||
| //
 | ||||
| // A reflection database and its interface, consistent with the OpenGL API reflection queries.
 | ||||
| //
 | ||||
| @ -48,245 +47,15 @@ class TInfoSink; | ||||
| namespace glslang { | ||||
| 
 | ||||
| class TIntermediate; | ||||
| struct TVarEntryInfo { | ||||
|     int id; | ||||
|     TIntermSymbol* symbol; | ||||
|     bool live; | ||||
|     int newBinding; | ||||
|     int newSet; | ||||
|     int newLocation; | ||||
|     int newComponent; | ||||
|     int newIndex; | ||||
|     EShLanguage stage; | ||||
|     struct TOrderById { | ||||
|         inline bool operator()(const TVarEntryInfo& l, const TVarEntryInfo& r) { return l.id < r.id; } | ||||
|     }; | ||||
| 
 | ||||
|     struct TOrderByPriority { | ||||
|         // ordering:
 | ||||
|         // 1) has both binding and set
 | ||||
|         // 2) has binding but no set
 | ||||
|         // 3) has no binding but set
 | ||||
|         // 4) has no binding and no set
 | ||||
|         inline bool operator()(const TVarEntryInfo& l, const TVarEntryInfo& r) { | ||||
|             const TQualifier& lq = l.symbol->getQualifier(); | ||||
|             const TQualifier& rq = r.symbol->getQualifier(); | ||||
| 
 | ||||
|             // simple rules:
 | ||||
|             // has binding gives 2 points
 | ||||
|             // has set gives 1 point
 | ||||
|             // who has the most points is more important.
 | ||||
|             int lPoints = (lq.hasBinding() ? 2 : 0) + (lq.hasSet() ? 1 : 0); | ||||
|             int rPoints = (rq.hasBinding() ? 2 : 0) + (rq.hasSet() ? 1 : 0); | ||||
| 
 | ||||
|             if (lPoints == rPoints) | ||||
|                 return l.id < r.id; | ||||
|             return lPoints > rPoints; | ||||
|         } | ||||
|     }; | ||||
| }; | ||||
| 
 | ||||
| // Base class for shared TIoMapResolver services, used by several derivations.
 | ||||
| struct TDefaultIoResolverBase : public glslang::TIoMapResolver { | ||||
| public: | ||||
|     TDefaultIoResolverBase(const TIntermediate& intermediate); | ||||
|     typedef std::vector<int> TSlotSet; | ||||
|     typedef std::unordered_map<int, TSlotSet> TSlotSetMap; | ||||
| 
 | ||||
|     // grow the reflection stage by stage
 | ||||
|     void notifyBinding(EShLanguage, TVarEntryInfo& /*ent*/) override {} | ||||
|     void notifyInOut(EShLanguage, TVarEntryInfo& /*ent*/) override {} | ||||
|     void beginNotifications(EShLanguage) override {} | ||||
|     void endNotifications(EShLanguage) override {} | ||||
|     void beginResolve(EShLanguage) override {} | ||||
|     void endResolve(EShLanguage) override {} | ||||
|     void beginCollect(EShLanguage) override {} | ||||
|     void endCollect(EShLanguage) override {} | ||||
|     void reserverResourceSlot(TVarEntryInfo& /*ent*/, TInfoSink& /*infoSink*/) override {} | ||||
|     void reserverStorageSlot(TVarEntryInfo& /*ent*/, TInfoSink& /*infoSink*/) override {} | ||||
|     int getBaseBinding(TResourceType res, unsigned int set) const; | ||||
|     const std::vector<std::string>& getResourceSetBinding() const; | ||||
|     virtual TResourceType getResourceType(const glslang::TType& type) = 0; | ||||
|     bool doAutoBindingMapping() const; | ||||
|     bool doAutoLocationMapping() const; | ||||
|     TSlotSet::iterator findSlot(int set, int slot); | ||||
|     bool checkEmpty(int set, int slot); | ||||
|     bool validateInOut(EShLanguage /*stage*/, TVarEntryInfo& /*ent*/) override { return true; }; | ||||
|     int reserveSlot(int set, int slot, int size = 1); | ||||
|     int getFreeSlot(int set, int base, int size = 1); | ||||
|     int resolveSet(EShLanguage /*stage*/, TVarEntryInfo& ent) override; | ||||
|     int resolveUniformLocation(EShLanguage /*stage*/, TVarEntryInfo& ent) override; | ||||
|     int resolveInOutLocation(EShLanguage stage, TVarEntryInfo& ent) override; | ||||
|     int resolveInOutComponent(EShLanguage /*stage*/, TVarEntryInfo& ent) override; | ||||
|     int resolveInOutIndex(EShLanguage /*stage*/, TVarEntryInfo& ent) override; | ||||
|     void addStage(EShLanguage stage) override { | ||||
|         if (stage < EShLangCount) | ||||
|             stageMask[stage] = true; | ||||
|     }; | ||||
|     uint32_t computeTypeLocationSize(const TType& type, EShLanguage stage); | ||||
| 
 | ||||
|     TSlotSetMap slots; | ||||
| 
 | ||||
| protected: | ||||
|     TDefaultIoResolverBase(TDefaultIoResolverBase&); | ||||
|     TDefaultIoResolverBase& operator=(TDefaultIoResolverBase&); | ||||
|     const TIntermediate& intermediate; | ||||
|     int nextUniformLocation; | ||||
|     int nextInputLocation; | ||||
|     int nextOutputLocation; | ||||
|     bool stageMask[EShLangCount + 1]; | ||||
|     // Return descriptor set specific base if there is one, and the generic base otherwise.
 | ||||
|     int selectBaseBinding(int base, int descriptorSetBase) const { | ||||
|         return descriptorSetBase != -1 ? descriptorSetBase : base; | ||||
|     } | ||||
| 
 | ||||
|     static int getLayoutSet(const glslang::TType& type) { | ||||
|         if (type.getQualifier().hasSet()) | ||||
|             return type.getQualifier().layoutSet; | ||||
|         else | ||||
|             return 0; | ||||
|     } | ||||
| 
 | ||||
|     static bool isSamplerType(const glslang::TType& type) { | ||||
|         return type.getBasicType() == glslang::EbtSampler && type.getSampler().isPureSampler(); | ||||
|     } | ||||
| 
 | ||||
|     static bool isTextureType(const glslang::TType& type) { | ||||
|         return (type.getBasicType() == glslang::EbtSampler && | ||||
|                 (type.getSampler().isTexture() || type.getSampler().isSubpass())); | ||||
|     } | ||||
| 
 | ||||
|     static bool isUboType(const glslang::TType& type) { | ||||
|         return type.getQualifier().storage == EvqUniform; | ||||
|     } | ||||
| 
 | ||||
|     static bool isImageType(const glslang::TType& type) { | ||||
|         return type.getBasicType() == glslang::EbtSampler && type.getSampler().isImage(); | ||||
|     } | ||||
| 
 | ||||
|     static bool isSsboType(const glslang::TType& type) { | ||||
|         return type.getQualifier().storage == EvqBuffer; | ||||
|     } | ||||
| 
 | ||||
|     // Return true if this is a SRV (shader resource view) type:
 | ||||
|     static bool isSrvType(const glslang::TType& type) { | ||||
|         return isTextureType(type) || type.getQualifier().storage == EvqBuffer; | ||||
|     } | ||||
| 
 | ||||
|     // Return true if this is a UAV (unordered access view) type:
 | ||||
|     static bool isUavType(const glslang::TType& type) { | ||||
|         if (type.getQualifier().readonly) | ||||
|             return false; | ||||
|         return (type.getBasicType() == glslang::EbtSampler && type.getSampler().isImage()) || | ||||
|                 (type.getQualifier().storage == EvqBuffer); | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| // Defaulf I/O resolver for OpenGL
 | ||||
| struct TDefaultGlslIoResolver : public TDefaultIoResolverBase { | ||||
| public: | ||||
|     typedef std::map<TString, int> TVarSlotMap;  // <resourceName, location/binding>
 | ||||
|     typedef std::map<int, TVarSlotMap> TSlotMap; // <resourceKey, TVarSlotMap>
 | ||||
|     TDefaultGlslIoResolver(const TIntermediate& intermediate); | ||||
|     bool validateBinding(EShLanguage /*stage*/, TVarEntryInfo& /*ent*/) { return true; }; | ||||
|     TResourceType getResourceType(const glslang::TType& type) override; | ||||
|     int resolveInOutLocation(EShLanguage stage, TVarEntryInfo& ent) override; | ||||
|     int resolveUniformLocation(EShLanguage /*stage*/, TVarEntryInfo& ent) override; | ||||
|     int resolveBinding(EShLanguage /*stage*/, TVarEntryInfo& ent); | ||||
|     void beginResolve(EShLanguage /*stage*/); | ||||
|     void endResolve(EShLanguage stage); | ||||
|     void beginCollect(EShLanguage) override; | ||||
|     void endCollect(EShLanguage) override; | ||||
|     void reserverStorageSlot(TVarEntryInfo& ent, TInfoSink& infoSink); | ||||
|     void reserverResourceSlot(TVarEntryInfo& ent, TInfoSink& infoSink); | ||||
|     // in/out symbol and uniform symbol are stored in the same resourceSlotMap, the storage key is used to identify each type of symbol.
 | ||||
|     // We use stage and storage qualifier to construct a storage key. it can help us identify the same storage resource used in different stage.
 | ||||
|     // if a resource is a program resource and we don't need know it usage stage, we can use same stage to build storage key.
 | ||||
|     // Note: both stage and type must less then 0xffff.
 | ||||
|     int buildStorageKey(EShLanguage stage, TStorageQualifier type) { | ||||
|         assert(stage <= 0xffff && type <= 0xffff); | ||||
|         return (stage << 16) | type; | ||||
|     }; | ||||
| 
 | ||||
| protected: | ||||
|     // Use for mark pre stage, to get more interface symbol information.
 | ||||
|     EShLanguage preStage; | ||||
|     // Use for mark current shader stage for resolver
 | ||||
|     EShLanguage currentStage; | ||||
|     // Slot map for storage resource(location of uniform and interface symbol) It's a program share slot
 | ||||
|     TSlotMap resourceSlotMap; | ||||
|     // Slot map for other resource(image, ubo, ssbo), It's a program share slot.
 | ||||
|     TSlotMap storageSlotMap; | ||||
| }; | ||||
| 
 | ||||
| typedef std::map<TString, TVarEntryInfo> TVarLiveMap; | ||||
| 
 | ||||
| // override function "operator=", if a vector<const _Kty, _Ty> being sort,
 | ||||
| // when use vc++, the sort function will call :
 | ||||
| // pair& operator=(const pair<_Other1, _Other2>& _Right)
 | ||||
| // {
 | ||||
| //     first = _Right.first;
 | ||||
| //     second = _Right.second;
 | ||||
| //     return (*this);
 | ||||
| // }
 | ||||
| // that will make a const type handing on left.
 | ||||
| // override this function can avoid a compiler error.
 | ||||
| // In the future, if the vc++ compiler can handle such a situation,
 | ||||
| // this part of the code will be removed.
 | ||||
| struct TVarLivePair : std::pair<const TString, TVarEntryInfo> { | ||||
|     TVarLivePair(std::pair<const TString, TVarEntryInfo>& _Right) : pair(_Right.first, _Right.second) {} | ||||
|     TVarLivePair& operator=(const TVarLivePair& _Right) { | ||||
|         const_cast<TString&>(first) = _Right.first; | ||||
|         second = _Right.second; | ||||
|         return (*this); | ||||
|     }; | ||||
| }; | ||||
| typedef std::vector<TVarLivePair> TVarLiveVector; | ||||
| 
 | ||||
| // I/O mapper
 | ||||
| class TIoMapper { | ||||
| public: | ||||
|     TIoMapper() {} | ||||
|     virtual ~TIoMapper() {} | ||||
|     // grow the reflection stage by stage
 | ||||
|     bool virtual addStage(EShLanguage, TIntermediate&, TInfoSink&, TIoMapResolver*); | ||||
|     bool virtual doMap(TIoMapResolver*, TInfoSink&) { return true; }; | ||||
| }; | ||||
| 
 | ||||
| // I/O mapper for OpenGL
 | ||||
| class TGlslIoMapper : public TIoMapper { | ||||
| public: | ||||
|     TGlslIoMapper() { | ||||
|         memset(inVarMaps,     0, sizeof(TVarLiveMap*)   * (EShLangCount + 1)); | ||||
|         memset(outVarMaps,    0, sizeof(TVarLiveMap*)   * (EShLangCount + 1)); | ||||
|         memset(uniformVarMap, 0, sizeof(TVarLiveMap*)   * (EShLangCount + 1)); | ||||
|         memset(intermediates, 0, sizeof(TIntermediate*) * (EShLangCount + 1)); | ||||
|     } | ||||
|     virtual ~TGlslIoMapper() { | ||||
|         for (size_t stage = 0; stage < EShLangCount; stage++) { | ||||
|             if (inVarMaps[stage] != nullptr) { | ||||
|                 delete inVarMaps[stage]; | ||||
|                 inVarMaps[stage] = nullptr; | ||||
|             } | ||||
|             if (outVarMaps[stage] != nullptr) { | ||||
|                 delete outVarMaps[stage]; | ||||
|                 outVarMaps[stage] = nullptr; | ||||
|             } | ||||
|             if (uniformVarMap[stage] != nullptr) { | ||||
|                 delete uniformVarMap[stage]; | ||||
|                 uniformVarMap[stage] = nullptr; | ||||
|             } | ||||
|             if (intermediates[stage] != nullptr) | ||||
|                 intermediates[stage] = nullptr; | ||||
|         } | ||||
|     } | ||||
|     // grow the reflection stage by stage
 | ||||
|     bool addStage(EShLanguage, TIntermediate&, TInfoSink&, TIoMapResolver*) override; | ||||
|     bool doMap(TIoMapResolver*, TInfoSink&) override; | ||||
|     TVarLiveMap *inVarMaps[EShLangCount], *outVarMaps[EShLangCount], | ||||
|                 *uniformVarMap[EShLangCount]; | ||||
|     TIntermediate* intermediates[EShLangCount]; | ||||
|     bool hadError = false; | ||||
|     bool addStage(EShLanguage, TIntermediate&, TInfoSink&, TIoMapResolver*); | ||||
| }; | ||||
| 
 | ||||
| } // end namespace glslang
 | ||||
|  | ||||
| @ -648,7 +648,6 @@ protected: | ||||
| 
 | ||||
| class TReflection; | ||||
| class TIoMapper; | ||||
| struct TVarEntryInfo; | ||||
| 
 | ||||
| // Allows to customize the binding layout after linking.
 | ||||
| // All used uniform variables will invoke at least validateBinding.
 | ||||
| @ -680,50 +679,40 @@ public: | ||||
| 
 | ||||
|   // Should return true if the resulting/current binding would be okay.
 | ||||
|   // Basic idea is to do aliasing binding checks with this.
 | ||||
|     virtual bool validateBinding(EShLanguage stage, TVarEntryInfo& ent) = 0; | ||||
|   virtual bool validateBinding(EShLanguage stage, const char* name, const TType& type, bool is_live) = 0; | ||||
|   // Should return a value >= 0 if the current binding should be overridden.
 | ||||
|   // Return -1 if the current binding (including no binding) should be kept.
 | ||||
|     virtual int resolveBinding(EShLanguage stage, TVarEntryInfo& ent) = 0; | ||||
|   virtual int resolveBinding(EShLanguage stage, const char* name, const TType& type, bool is_live) = 0; | ||||
|   // Should return a value >= 0 if the current set should be overridden.
 | ||||
|   // Return -1 if the current set (including no set) should be kept.
 | ||||
|     virtual int resolveSet(EShLanguage stage, TVarEntryInfo& ent) = 0; | ||||
|   virtual int resolveSet(EShLanguage stage, const char* name, const TType& type, bool is_live) = 0; | ||||
|   // Should return a value >= 0 if the current location should be overridden.
 | ||||
|   // Return -1 if the current location (including no location) should be kept.
 | ||||
|     virtual int resolveUniformLocation(EShLanguage stage, TVarEntryInfo& ent) = 0; | ||||
|   virtual int resolveUniformLocation(EShLanguage stage, const char* name, const TType& type, bool is_live) = 0; | ||||
|   // Should return true if the resulting/current setup would be okay.
 | ||||
|   // Basic idea is to do aliasing checks and reject invalid semantic names.
 | ||||
|     virtual bool validateInOut(EShLanguage stage, TVarEntryInfo& ent) = 0; | ||||
|   virtual bool validateInOut(EShLanguage stage, const char* name, const TType& type, bool is_live) = 0; | ||||
|   // Should return a value >= 0 if the current location should be overridden.
 | ||||
|   // Return -1 if the current location (including no location) should be kept.
 | ||||
|     virtual int resolveInOutLocation(EShLanguage stage, TVarEntryInfo& ent) = 0; | ||||
|   virtual int resolveInOutLocation(EShLanguage stage, const char* name, const TType& type, bool is_live) = 0; | ||||
|   // Should return a value >= 0 if the current component index should be overridden.
 | ||||
|   // Return -1 if the current component index (including no index) should be kept.
 | ||||
|     virtual int resolveInOutComponent(EShLanguage stage, TVarEntryInfo& ent) = 0; | ||||
|   virtual int resolveInOutComponent(EShLanguage stage, const char* name, const TType& type, bool is_live) = 0; | ||||
|   // Should return a value >= 0 if the current color index should be overridden.
 | ||||
|   // Return -1 if the current color index (including no index) should be kept.
 | ||||
|     virtual int resolveInOutIndex(EShLanguage stage, TVarEntryInfo& ent) = 0; | ||||
|   virtual int resolveInOutIndex(EShLanguage stage, const char* name, const TType& type, bool is_live) = 0; | ||||
|   // Notification of a uniform variable
 | ||||
|     virtual void notifyBinding(EShLanguage stage, TVarEntryInfo& ent) = 0; | ||||
|   virtual void notifyBinding(EShLanguage stage, const char* name, const TType& type, bool is_live) = 0; | ||||
|   // Notification of a in or out variable
 | ||||
|     virtual void notifyInOut(EShLanguage stage, TVarEntryInfo& ent) = 0; | ||||
|     // Called by mapIO when it starts its notify pass for the given stage
 | ||||
|     virtual void beginNotifications(EShLanguage stage) = 0; | ||||
|   virtual void notifyInOut(EShLanguage stage, const char* name, const TType& type, bool is_live) = 0; | ||||
|   // Called by mapIO when it has finished the notify pass
 | ||||
|   virtual void endNotifications(EShLanguage stage) = 0; | ||||
|   // Called by mapIO when it starts its notify pass for the given stage
 | ||||
|   virtual void beginNotifications(EShLanguage stage) = 0; | ||||
|   // Called by mipIO when it starts its resolve pass for the given stage
 | ||||
|   virtual void beginResolve(EShLanguage stage) = 0; | ||||
|   // Called by mapIO when it has finished the resolve pass
 | ||||
|   virtual void endResolve(EShLanguage stage) = 0; | ||||
|     // Called by mapIO when it starts its symbol collect for teh given stage
 | ||||
|     virtual void beginCollect(EShLanguage stage) = 0; | ||||
|     // Called by mapIO when it has finished the symbol collect
 | ||||
|     virtual void endCollect(EShLanguage stage) = 0; | ||||
|     // Called by TSlotCollector to resolve storage locations or bindings
 | ||||
|     virtual void reserverStorageSlot(TVarEntryInfo& ent, TInfoSink& infoSink) = 0; | ||||
|     // Called by TSlotCollector to resolve resource locations or bindings
 | ||||
|     virtual void reserverResourceSlot(TVarEntryInfo& ent, TInfoSink& infoSink) = 0; | ||||
|     // Called by mapIO.addStage to set shader stage mask to mark a stage be added to this pipeline
 | ||||
|     virtual void addStage(EShLanguage stage) = 0; | ||||
| }; | ||||
| 
 | ||||
| // Make one TProgram per set of shaders that will get linked together.  Add all
 | ||||
| @ -835,7 +824,7 @@ public: | ||||
|     // I/O mapping: apply base offsets and map live unbound variables
 | ||||
|     // If resolver is not provided it uses the previous approach
 | ||||
|     // and respects auto assignment and offsets.
 | ||||
|     bool mapIO(TIoMapResolver* pResolver = nullptr, TIoMapper* pIoMapper = nullptr); | ||||
|     bool mapIO(TIoMapResolver* resolver = NULL); | ||||
| 
 | ||||
| protected: | ||||
|     bool linkStage(EShLanguage, EShMessages); | ||||
| @ -846,6 +835,7 @@ protected: | ||||
|     bool newedIntermediate[EShLangCount];      // track which intermediate were "new" versus reusing a singleton unit in a stage
 | ||||
|     TInfoSink* infoSink; | ||||
|     TReflection* reflection; | ||||
|     TIoMapper* ioMapper; | ||||
|     bool linked; | ||||
| 
 | ||||
| private: | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 John Kessenich
						John Kessenich