ShaderProgramDump.cpp 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. // Copyright (C) 2009-2020, Panagiotis Christopoulos Charitos and contributors.
  2. // All rights reserved.
  3. // Code licensed under the BSD License.
  4. // http://www.anki3d.org/LICENSE
  5. #include <anki/shader_compiler/ShaderProgramDump.h>
  6. #include <anki/util/Serializer.h>
  7. #include <anki/util/StringList.h>
  8. #include <SPIRV-Cross/spirv_glsl.hpp>
  9. namespace anki
  10. {
  11. #define ANKI_TAB " "
  12. static void disassembleBlock(const ShaderProgramBinaryBlockInstance& instance, const ShaderProgramBinaryBlock& block,
  13. StringListAuto& lines)
  14. {
  15. lines.pushBackSprintf(ANKI_TAB ANKI_TAB ANKI_TAB "%-32s set %4u binding %4u size %4u\n", block.m_name.getBegin(),
  16. block.m_set, block.m_binding, instance.m_size);
  17. for(U32 i = 0; i < instance.m_variables.getSize(); ++i)
  18. {
  19. const ShaderProgramBinaryVariableInstance& varInstance = instance.m_variables[i];
  20. const ShaderProgramBinaryVariable& var = block.m_variables[varInstance.m_index];
  21. lines.pushBackSprintf(ANKI_TAB ANKI_TAB ANKI_TAB ANKI_TAB "%-48s type %8s blockInfo %d,%d,%d,%d\n",
  22. var.m_name.getBegin(), shaderVariableDataTypeToString(var.m_type).cstr(),
  23. varInstance.m_blockInfo.m_offset, varInstance.m_blockInfo.m_arraySize,
  24. varInstance.m_blockInfo.m_arrayStride, varInstance.m_blockInfo.m_matrixStride);
  25. }
  26. }
  27. void dumpShaderProgramBinary(const ShaderProgramBinary& binary, StringAuto& humanReadable)
  28. {
  29. GenericMemoryPoolAllocator<U8> alloc = humanReadable.getAllocator();
  30. StringListAuto lines(alloc);
  31. if(binary.m_libraryName[0])
  32. {
  33. lines.pushBack("**LIBRARY**\n");
  34. lines.pushBackSprintf(ANKI_TAB "%s\n\n", &binary.m_libraryName[0]);
  35. }
  36. if(binary.m_rayType != MAX_U32)
  37. {
  38. lines.pushBack("**RAY TYPE**\n");
  39. lines.pushBackSprintf(ANKI_TAB "%u\n\n", binary.m_rayType);
  40. }
  41. lines.pushBack("**MUTATORS**\n");
  42. if(binary.m_mutators.getSize() > 0)
  43. {
  44. for(const ShaderProgramBinaryMutator& mutator : binary.m_mutators)
  45. {
  46. lines.pushBackSprintf(ANKI_TAB "%-32s ", &mutator.m_name[0]);
  47. for(U32 i = 0; i < mutator.m_values.getSize(); ++i)
  48. {
  49. lines.pushBackSprintf((i < mutator.m_values.getSize() - 1) ? "%d," : "%d", mutator.m_values[i]);
  50. }
  51. lines.pushBack("\n");
  52. }
  53. }
  54. else
  55. {
  56. lines.pushBack(ANKI_TAB "N/A\n");
  57. }
  58. lines.pushBack("\n**BINARIES**\n");
  59. U32 count = 0;
  60. for(const ShaderProgramBinaryCodeBlock& code : binary.m_codeBlocks)
  61. {
  62. spirv_cross::CompilerGLSL::Options options;
  63. options.vulkan_semantics = true;
  64. options.version = 460;
  65. const unsigned int* spvb = reinterpret_cast<const unsigned int*>(code.m_binary.getBegin());
  66. ANKI_ASSERT((code.m_binary.getSize() % (sizeof(unsigned int))) == 0);
  67. std::vector<unsigned int> spv(spvb, spvb + code.m_binary.getSize() / sizeof(unsigned int));
  68. spirv_cross::CompilerGLSL compiler(spv);
  69. compiler.set_common_options(options);
  70. std::string glsl = compiler.compile();
  71. StringListAuto sourceLines(alloc);
  72. sourceLines.splitString(glsl.c_str(), '\n');
  73. StringAuto newGlsl(alloc);
  74. sourceLines.join("\n" ANKI_TAB ANKI_TAB, newGlsl);
  75. lines.pushBackSprintf(ANKI_TAB "#%u \n" ANKI_TAB ANKI_TAB "%s\n", count++, newGlsl.cstr());
  76. }
  77. lines.pushBack("\n**SHADER VARIANTS**\n");
  78. count = 0;
  79. for(const ShaderProgramBinaryVariant& variant : binary.m_variants)
  80. {
  81. lines.pushBackSprintf(ANKI_TAB "#%u\n", count++);
  82. // Uniform blocks
  83. if(variant.m_uniformBlocks.getSize() > 0)
  84. {
  85. lines.pushBackSprintf(ANKI_TAB ANKI_TAB "Uniform blocks\n");
  86. for(const ShaderProgramBinaryBlockInstance& instance : variant.m_uniformBlocks)
  87. {
  88. disassembleBlock(instance, binary.m_uniformBlocks[instance.m_index], lines);
  89. }
  90. }
  91. // Storage blocks
  92. if(variant.m_storageBlocks.getSize() > 0)
  93. {
  94. lines.pushBackSprintf(ANKI_TAB ANKI_TAB "Storage blocks\n");
  95. for(const ShaderProgramBinaryBlockInstance& instance : variant.m_storageBlocks)
  96. {
  97. disassembleBlock(instance, binary.m_storageBlocks[instance.m_index], lines);
  98. }
  99. }
  100. // Opaque
  101. if(variant.m_opaques.getSize() > 0)
  102. {
  103. lines.pushBackSprintf(ANKI_TAB ANKI_TAB "Opaque\n");
  104. for(const ShaderProgramBinaryOpaqueInstance& instance : variant.m_opaques)
  105. {
  106. const ShaderProgramBinaryOpaque& o = binary.m_opaques[instance.m_index];
  107. lines.pushBackSprintf(ANKI_TAB ANKI_TAB ANKI_TAB "%-32s set %4u binding %4u type %12s arraySize %4u\n",
  108. o.m_name.getBegin(), o.m_set, o.m_binding,
  109. shaderVariableDataTypeToString(o.m_type).cstr(), instance.m_arraySize);
  110. }
  111. }
  112. // Push constants
  113. if(variant.m_pushConstantBlock)
  114. {
  115. lines.pushBackSprintf(ANKI_TAB ANKI_TAB "Push constants\n");
  116. disassembleBlock(*variant.m_pushConstantBlock, *binary.m_pushConstantBlock, lines);
  117. }
  118. // Constants
  119. if(variant.m_constants.getSize() > 0)
  120. {
  121. lines.pushBackSprintf(ANKI_TAB ANKI_TAB "Specialization constants\n");
  122. for(const ShaderProgramBinaryConstantInstance& instance : variant.m_constants)
  123. {
  124. const ShaderProgramBinaryConstant& c = binary.m_constants[instance.m_index];
  125. lines.pushBackSprintf(ANKI_TAB ANKI_TAB ANKI_TAB "%-32s type %8s id %4u\n", c.m_name.getBegin(),
  126. shaderVariableDataTypeToString(c.m_type).cstr(), c.m_constantId);
  127. }
  128. }
  129. // Binary indices
  130. lines.pushBack(ANKI_TAB ANKI_TAB "Binaries ");
  131. for(ShaderType shaderType : EnumIterable<ShaderType>())
  132. {
  133. if(variant.m_codeBlockIndices[shaderType] < MAX_U32)
  134. {
  135. lines.pushBackSprintf("%u", variant.m_codeBlockIndices[shaderType]);
  136. }
  137. else
  138. {
  139. lines.pushBack("-");
  140. }
  141. if(shaderType != ShaderType::LAST)
  142. {
  143. lines.pushBack(",");
  144. }
  145. }
  146. lines.pushBack("\n");
  147. }
  148. // Mutations
  149. lines.pushBack("\n**MUTATIONS**\n");
  150. count = 0;
  151. for(const ShaderProgramBinaryMutation& mutation : binary.m_mutations)
  152. {
  153. lines.pushBackSprintf(ANKI_TAB "#%-4u variantIndex %5u values (", count++, mutation.m_variantIndex);
  154. if(mutation.m_values.getSize() > 0)
  155. {
  156. for(U32 i = 0; i < mutation.m_values.getSize(); ++i)
  157. {
  158. lines.pushBackSprintf((i < mutation.m_values.getSize() - 1) ? "%s %4d, " : "%s %4d",
  159. binary.m_mutators[i].m_name.getBegin(), I32(mutation.m_values[i]));
  160. }
  161. lines.pushBack(")");
  162. }
  163. else
  164. {
  165. lines.pushBack("N/A)");
  166. }
  167. lines.pushBack("\n");
  168. }
  169. lines.join("", humanReadable);
  170. }
  171. #undef ANKI_TAB
  172. } // end namespace anki