ShaderProgramBinaryDumpMain.cpp 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. // Copyright (C) 2009-present, 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/ShaderCompiler/ShaderCompiler.h>
  6. #include <AnKi/ShaderCompiler/ShaderDump.h>
  7. #include <AnKi/Util/ThreadHive.h>
  8. #include <AnKi/Util/System.h>
  9. #include <ThirdParty/SpirvCross/spirv.hpp>
  10. using namespace anki;
  11. static const char* kUsage = R"(Dump the shader binary to stdout
  12. Usage: %s [options] input_shader_program_binary
  13. Options:
  14. -stats <0|1> : Print performance statistics for all shaders. Default 0
  15. -binary <0|1> : Print the whole shader program binary. Default 1
  16. -glsl <0|1> : Print GLSL. Default 1
  17. -spirv <0|1> : Print SPIR-V. Default 0
  18. -v : Verbose log
  19. )";
  20. static Error parseCommandLineArgs(WeakArray<char*> argv, Bool& dumpStats, Bool& dumpBinary, Bool& glsl, Bool& spirv, String& filename)
  21. {
  22. // Parse config
  23. if(argv.getSize() < 2)
  24. {
  25. return Error::kUserData;
  26. }
  27. dumpStats = false;
  28. dumpBinary = true;
  29. glsl = true;
  30. spirv = false;
  31. filename = argv[argv.getSize() - 1];
  32. for(U32 i = 1; i < argv.getSize() - 1; i++)
  33. {
  34. if(CString(argv[i]) == "-stats")
  35. {
  36. ++i;
  37. if(i >= argv.getSize())
  38. {
  39. return Error::kUserData;
  40. }
  41. if(CString(argv[i]) == "1")
  42. {
  43. dumpStats = true;
  44. }
  45. else if(CString(argv[i]) == "0")
  46. {
  47. dumpStats = false;
  48. }
  49. else
  50. {
  51. return Error::kUserData;
  52. }
  53. }
  54. else if(CString(argv[i]) == "-binary")
  55. {
  56. ++i;
  57. if(i >= argv.getSize())
  58. {
  59. return Error::kUserData;
  60. }
  61. if(CString(argv[i]) == "1")
  62. {
  63. dumpBinary = true;
  64. }
  65. else if(CString(argv[i]) == "0")
  66. {
  67. dumpBinary = false;
  68. }
  69. else
  70. {
  71. return Error::kUserData;
  72. }
  73. }
  74. else if(CString(argv[i]) == "-glsl")
  75. {
  76. ++i;
  77. if(i >= argv.getSize())
  78. {
  79. return Error::kUserData;
  80. }
  81. if(CString(argv[i]) == "1")
  82. {
  83. glsl = true;
  84. }
  85. else if(CString(argv[i]) == "0")
  86. {
  87. glsl = false;
  88. }
  89. else
  90. {
  91. return Error::kUserData;
  92. }
  93. }
  94. else if(CString(argv[i]) == "-spirv")
  95. {
  96. ++i;
  97. if(i >= argv.getSize())
  98. {
  99. return Error::kUserData;
  100. }
  101. if(CString(argv[i]) == "1")
  102. {
  103. spirv = true;
  104. }
  105. else if(CString(argv[i]) == "0")
  106. {
  107. spirv = false;
  108. }
  109. else
  110. {
  111. return Error::kUserData;
  112. }
  113. }
  114. else if(CString(argv[i]) == "-v")
  115. {
  116. Logger::getSingleton().enableVerbosity(true);
  117. }
  118. }
  119. if(spirv || glsl)
  120. {
  121. dumpBinary = true;
  122. }
  123. return Error::kNone;
  124. }
  125. Error dump(CString fname, Bool bDumpStats, Bool dumpBinary, Bool glsl, Bool spirv)
  126. {
  127. ShaderBinary* binary;
  128. ANKI_CHECK(deserializeShaderBinaryFromFile(fname, binary, ShaderCompilerMemoryPool::getSingleton()));
  129. class Dummy
  130. {
  131. public:
  132. ShaderBinary* m_binary;
  133. ~Dummy()
  134. {
  135. ShaderCompilerMemoryPool::getSingleton().free(m_binary);
  136. }
  137. } dummy{binary};
  138. if(dumpBinary)
  139. {
  140. ShaderDumpOptions options;
  141. options.m_writeGlsl = glsl;
  142. options.m_writeSpirv = spirv;
  143. options.m_maliStats = options.m_amdStats = bDumpStats;
  144. ShaderCompilerString txt;
  145. dumpShaderBinary(options, *binary, txt);
  146. printf("%s\n", txt.cstr());
  147. }
  148. return Error::kNone;
  149. }
  150. ANKI_MAIN_FUNCTION(myMain)
  151. int myMain(int argc, char** argv)
  152. {
  153. class Dummy
  154. {
  155. public:
  156. ~Dummy()
  157. {
  158. DefaultMemoryPool::freeSingleton();
  159. ShaderCompilerMemoryPool::freeSingleton();
  160. }
  161. } dummy;
  162. DefaultMemoryPool::allocateSingleton(allocAligned, nullptr);
  163. ShaderCompilerMemoryPool::allocateSingleton(allocAligned, nullptr);
  164. String filename;
  165. Bool dumpStats;
  166. Bool dumpBinary;
  167. Bool glsl;
  168. Bool spirv;
  169. if(parseCommandLineArgs(WeakArray<char*>(argv, argc), dumpStats, dumpBinary, glsl, spirv, filename))
  170. {
  171. ANKI_LOGE(kUsage, argv[0]);
  172. return 1;
  173. }
  174. const Error err = dump(filename, dumpStats, dumpBinary, glsl, spirv);
  175. if(err)
  176. {
  177. ANKI_LOGE("Can't dump due to an error. Bye");
  178. return 1;
  179. }
  180. return 0;
  181. }