// //Copyright (C) 2016 LunarG, Inc. // //All rights reserved. // //Redistribution and use in source and binary forms, with or without //modification, are permitted provided that the following conditions //are met: // // Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // // Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following // disclaimer in the documentation and/or other materials provided // with the distribution. // // Neither the name of 3Dlabs Inc. Ltd. nor the names of its // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // //THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS //"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT //LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS //FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE //COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, //INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, //BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; //LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER //CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT //LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN //ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE //POSSIBILITY OF SUCH DAMAGE. // #include "../Include/Common.h" #include "iomapper.h" #include "LiveTraverser.h" #include "localintermediate.h" #include "gl_types.h" #include #include // // Map IO bindings. // // High-level algorithm for one stage: // // 1. Traverse all code (live+dead) to find the explicitly provided bindings. // // 2. Traverse (just) the live code to determine which non-provided bindings // require auto-numbering. We do not auto-number dead ones. // // 3. Traverse all the code to apply the bindings: // a. explicitly given bindings are offset according to their type // b. implicit live bindings are auto-numbered into the holes, using // any open binding slot. // c. implicit dead bindings are left un-bound. // namespace glslang { // Map of IDs to bindings typedef std::unordered_map TBindingMap; typedef std::unordered_set TUsedBindings; // This traverses the AST to determine which bindings are used, and which are implicit // (for subsequent auto-numbering) class TBindingTraverser : public TLiveTraverser { public: TBindingTraverser(const TIntermediate& i, TBindingMap& bindingMap, TUsedBindings& usedBindings, bool traverseDeadCode = false) : TLiveTraverser(i, traverseDeadCode, true, true, false), bindingMap(bindingMap), usedBindings(usedBindings) { } protected: virtual void visitSymbol(TIntermSymbol* base) { if (base->getQualifier().storage == EvqUniform) addUniform(*base); } // Return the right binding base given the variable type. int getBindingBase(const TType& type) { if (type.getBasicType() == EbtSampler) { const TSampler& sampler = type.getSampler(); if (sampler.isPureSampler()) return intermediate.getShiftSamplerBinding(); if (sampler.isTexture()) return intermediate.getShiftTextureBinding(); } if (type.getQualifier().isUniformOrBuffer()) return intermediate.getShiftUboBinding(); return -1; // not a type with a binding } // Mark a given base symbol ID as being bound to 'binding' void markBinding(const TIntermSymbol& base, int binding) { bindingMap[base.getId()] = binding; if (binding >= 0) { // const TType& type = base.getType(); const unsigned int size = 1; // type.isArray() ? type.getCumulativeArraySize() : 1; for (unsigned int offset=0; offsettraverse(&it_binding_all); // Traverse just live code to find things that need implicit bindings. it_binding_live.pushFunction(intermediate.getEntryPointMangledName().c_str()); while (! it_binding_live.functions.empty()) { TIntermNode* function = it_binding_live.functions.back(); it_binding_live.functions.pop_back(); function->traverse(&it_binding_live); } // Bind everything that needs a binding and doesn't have one. root->traverse(&it_iomap); return true; } } // end namespace glslang