Notification phase for io remapper
authort.jung <t.jung@gaijin.ru>
Fri, 28 Apr 2017 13:54:57 +0000 (15:54 +0200)
committert.jung <t.jung@gaijin.ru>
Fri, 28 Apr 2017 13:54:57 +0000 (15:54 +0200)
Adds a notification phase to the io remapper.
The idea behind this is to give the user a
chance to group uniforms and/or in/out variables
for a better pipeline layout sharing for vulkan.

Change-Id: I7492421085a4156ed3534f01d906ab390d73a623

glslang/MachineIndependent/iomapper.cpp
glslang/Public/ShaderLang.h

index 8b80cbe..e68e0f8 100644 (file)
@@ -201,6 +201,36 @@ public:
     const TVarLiveMap&    uniformList;
 };
 
+struct TNotifyUniformAdaptor
+{
+    EShLanguage stage;
+    TIoMapResolver& resolver;
+    inline TNotifyUniformAdaptor(EShLanguage s, TIoMapResolver& r)
+      : stage(s)
+      , resolver(r)
+    {
+    }
+    inline void operator()(TVarEntryInfo& ent)
+    {
+        resolver.notifyBinding(stage, ent.symbol->getName().c_str(), ent.symbol->getType(), ent.live);
+    }
+};
+
+struct TNotifyInOutAdaptor
+{
+    EShLanguage stage;
+    TIoMapResolver& resolver;
+    inline TNotifyInOutAdaptor(EShLanguage s, TIoMapResolver& r)
+      : stage(s)
+      , resolver(r)
+    {
+    }
+    inline void operator()(TVarEntryInfo& ent)
+    {
+        resolver.notifyInOut(stage, ent.symbol->getName().c_str(), ent.symbol->getType(), ent.live);
+    }
+};
+
 struct TResolverUniformAdaptor
 {
     TResolverUniformAdaptor(EShLanguage s, TIoMapResolver& r, TInfoSink& i, bool& e, TIntermediate& interm)
@@ -383,6 +413,10 @@ struct TDefaultIoResolverBase : public glslang::TIoMapResolver
         return -1;
     }
 
+    void notifyBinding(EShLanguage stage, const char* name, const TType& type, bool is_live) override {}
+    void notifyInOut(EShLanguage stage, const char* name, const TType& type, bool is_live) override {}
+    void endNotifications() override {}
+
 protected:
     static int getLayoutSet(const glslang::TType& type) {
         if (type.getQualifier().hasSet())
@@ -674,8 +708,14 @@ bool TIoMapper::addStage(EShLanguage stage, TIntermediate &intermediate, TInfoSi
     std::sort(uniformVarMap.begin(), uniformVarMap.end(), TVarEntryInfo::TOrderByPriority());
 
     bool hadError = false;
+    TNotifyInOutAdaptor inOutNotify(stage, *resolver);
+    TNotifyUniformAdaptor uniformNotify(stage, *resolver);
     TResolverUniformAdaptor uniformResolve(stage, *resolver, infoSink, hadError, intermediate);
     TResolverInOutAdaptor inOutResolve(stage, *resolver, infoSink, hadError, intermediate);
+    std::for_each(inVarMap.begin(), inVarMap.end(), inOutNotify);
+    std::for_each(outVarMap.begin(), outVarMap.end(), inOutNotify);
+    std::for_each(uniformVarMap.begin(), uniformVarMap.end(), uniformNotify);
+    resolver->endNotifications();
     std::for_each(inVarMap.begin(), inVarMap.end(), inOutResolve);
     std::for_each(outVarMap.begin(), outVarMap.end(), inOutResolve);
     std::for_each(uniformVarMap.begin(), uniformVarMap.end(), uniformResolve);
index 432329c..c2aa1ad 100644 (file)
@@ -463,6 +463,13 @@ class TIoMapper;
 // 5) all uniforms with set but no binding defined
 // 6) all uniforms with no binding and no set defined
 //
+// mapIO will use this resolver in two phases. The first
+// phase is a notification phase, calling the corresponging
+// notifiy callbacks, this phase ends with a call to endNotifications.
+// Phase two starts directly after the call to endNotifications
+// and calls all other callbacks to validate and to get the
+// bindings, sets, locations, component and color indices. 
+//
 // NOTE: that still limit checks are applied to bindings and sets
 // and may result in an error.
 class TIoMapResolver
@@ -491,6 +498,12 @@ public:
   // 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, const char* name, const TType& type, bool is_live) = 0;
+  // Notification of a uniform variable
+  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, const char* name, const TType& type, bool is_live) = 0;
+  // Called by mapIO when it has finished the notify pass
+  virtual void endNotifications() = 0;
 };
 
 // Make one TProgram per set of shaders that will get linked together.  Add all