reflection.h 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. //
  2. // Copyright (C) 2013-2016 LunarG, Inc.
  3. //
  4. // All rights reserved.
  5. //
  6. // Redistribution and use in source and binary forms, with or without
  7. // modification, are permitted provided that the following conditions
  8. // are met:
  9. //
  10. // Redistributions of source code must retain the above copyright
  11. // notice, this list of conditions and the following disclaimer.
  12. //
  13. // Redistributions in binary form must reproduce the above
  14. // copyright notice, this list of conditions and the following
  15. // disclaimer in the documentation and/or other materials provided
  16. // with the distribution.
  17. //
  18. // Neither the name of 3Dlabs Inc. Ltd. nor the names of its
  19. // contributors may be used to endorse or promote products derived
  20. // from this software without specific prior written permission.
  21. //
  22. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  23. // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  24. // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  25. // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  26. // COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  27. // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  28. // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  29. // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  30. // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  31. // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  32. // ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  33. // POSSIBILITY OF SUCH DAMAGE.
  34. //
  35. #if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE)
  36. #ifndef _REFLECTION_INCLUDED
  37. #define _REFLECTION_INCLUDED
  38. #include "../Public/ShaderLang.h"
  39. #include "../Include/Types.h"
  40. #include <list>
  41. #include <set>
  42. //
  43. // A reflection database and its interface, consistent with the OpenGL API reflection queries.
  44. //
  45. namespace glslang {
  46. class TIntermediate;
  47. class TIntermAggregate;
  48. class TReflectionTraverser;
  49. // The full reflection database
  50. class TReflection {
  51. public:
  52. TReflection(EShReflectionOptions opts, EShLanguage first, EShLanguage last)
  53. : options(opts), firstStage(first), lastStage(last), badReflection(TObjectReflection::badReflection())
  54. {
  55. for (int dim=0; dim<3; ++dim)
  56. localSize[dim] = 0;
  57. }
  58. virtual ~TReflection() {}
  59. // grow the reflection stage by stage
  60. bool addStage(EShLanguage, const TIntermediate&);
  61. // for mapping a uniform index to a uniform object's description
  62. int getNumUniforms() { return (int)indexToUniform.size(); }
  63. const TObjectReflection& getUniform(int i) const
  64. {
  65. if (i >= 0 && i < (int)indexToUniform.size())
  66. return indexToUniform[i];
  67. else
  68. return badReflection;
  69. }
  70. // for mapping a block index to the block's description
  71. int getNumUniformBlocks() const { return (int)indexToUniformBlock.size(); }
  72. const TObjectReflection& getUniformBlock(int i) const
  73. {
  74. if (i >= 0 && i < (int)indexToUniformBlock.size())
  75. return indexToUniformBlock[i];
  76. else
  77. return badReflection;
  78. }
  79. // for mapping an pipeline input index to the input's description
  80. int getNumPipeInputs() { return (int)indexToPipeInput.size(); }
  81. const TObjectReflection& getPipeInput(int i) const
  82. {
  83. if (i >= 0 && i < (int)indexToPipeInput.size())
  84. return indexToPipeInput[i];
  85. else
  86. return badReflection;
  87. }
  88. // for mapping an pipeline output index to the output's description
  89. int getNumPipeOutputs() { return (int)indexToPipeOutput.size(); }
  90. const TObjectReflection& getPipeOutput(int i) const
  91. {
  92. if (i >= 0 && i < (int)indexToPipeOutput.size())
  93. return indexToPipeOutput[i];
  94. else
  95. return badReflection;
  96. }
  97. // for mapping from an atomic counter to the uniform index
  98. int getNumAtomicCounters() const { return (int)atomicCounterUniformIndices.size(); }
  99. const TObjectReflection& getAtomicCounter(int i) const
  100. {
  101. if (i >= 0 && i < (int)atomicCounterUniformIndices.size())
  102. return getUniform(atomicCounterUniformIndices[i]);
  103. else
  104. return badReflection;
  105. }
  106. // for mapping a buffer variable index to a buffer variable object's description
  107. int getNumBufferVariables() { return (int)indexToBufferVariable.size(); }
  108. const TObjectReflection& getBufferVariable(int i) const
  109. {
  110. if (i >= 0 && i < (int)indexToBufferVariable.size())
  111. return indexToBufferVariable[i];
  112. else
  113. return badReflection;
  114. }
  115. // for mapping a storage block index to the storage block's description
  116. int getNumStorageBuffers() const { return (int)indexToBufferBlock.size(); }
  117. const TObjectReflection& getStorageBufferBlock(int i) const
  118. {
  119. if (i >= 0 && i < (int)indexToBufferBlock.size())
  120. return indexToBufferBlock[i];
  121. else
  122. return badReflection;
  123. }
  124. // for mapping any name to its index (block names, uniform names and input/output names)
  125. int getIndex(const char* name) const
  126. {
  127. TNameToIndex::const_iterator it = nameToIndex.find(name);
  128. if (it == nameToIndex.end())
  129. return -1;
  130. else
  131. return it->second;
  132. }
  133. // see getIndex(const char*)
  134. int getIndex(const TString& name) const { return getIndex(name.c_str()); }
  135. // for mapping any name to its index (only pipe input/output names)
  136. int getPipeIOIndex(const char* name, const bool inOrOut) const
  137. {
  138. TNameToIndex::const_iterator it = inOrOut ? pipeInNameToIndex.find(name) : pipeOutNameToIndex.find(name);
  139. if (it == (inOrOut ? pipeInNameToIndex.end() : pipeOutNameToIndex.end()))
  140. return -1;
  141. else
  142. return it->second;
  143. }
  144. // see gePipeIOIndex(const char*, const bool)
  145. int getPipeIOIndex(const TString& name, const bool inOrOut) const { return getPipeIOIndex(name.c_str(), inOrOut); }
  146. // Thread local size
  147. unsigned getLocalSize(int dim) const { return dim <= 2 ? localSize[dim] : 0; }
  148. void dump();
  149. protected:
  150. friend class glslang::TReflectionTraverser;
  151. void buildCounterIndices(const TIntermediate&);
  152. void buildUniformStageMask(const TIntermediate& intermediate);
  153. void buildAttributeReflection(EShLanguage, const TIntermediate&);
  154. // Need a TString hash: typedef std::unordered_map<TString, int> TNameToIndex;
  155. typedef std::map<std::string, int> TNameToIndex;
  156. typedef std::vector<TObjectReflection> TMapIndexToReflection;
  157. typedef std::vector<int> TIndices;
  158. TMapIndexToReflection& GetBlockMapForStorage(TStorageQualifier storage)
  159. {
  160. if ((options & EShReflectionSeparateBuffers) && storage == EvqBuffer)
  161. return indexToBufferBlock;
  162. return indexToUniformBlock;
  163. }
  164. TMapIndexToReflection& GetVariableMapForStorage(TStorageQualifier storage)
  165. {
  166. if ((options & EShReflectionSeparateBuffers) && storage == EvqBuffer)
  167. return indexToBufferVariable;
  168. return indexToUniform;
  169. }
  170. EShReflectionOptions options;
  171. EShLanguage firstStage;
  172. EShLanguage lastStage;
  173. TObjectReflection badReflection; // return for queries of -1 or generally out of range; has expected descriptions with in it for this
  174. TNameToIndex nameToIndex; // maps names to indexes; can hold all types of data: uniform/buffer and which function names have been processed
  175. TNameToIndex pipeInNameToIndex; // maps pipe in names to indexes, this is a fix to seperate pipe I/O from uniforms and buffers.
  176. TNameToIndex pipeOutNameToIndex; // maps pipe out names to indexes, this is a fix to seperate pipe I/O from uniforms and buffers.
  177. TMapIndexToReflection indexToUniform;
  178. TMapIndexToReflection indexToUniformBlock;
  179. TMapIndexToReflection indexToBufferVariable;
  180. TMapIndexToReflection indexToBufferBlock;
  181. TMapIndexToReflection indexToPipeInput;
  182. TMapIndexToReflection indexToPipeOutput;
  183. TIndices atomicCounterUniformIndices;
  184. unsigned int localSize[3];
  185. };
  186. } // end namespace glslang
  187. #endif // _REFLECTION_INCLUDED
  188. #endif // !GLSLANG_WEB && !GLSLANG_ANGLE