GLSLContext.cpp 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. #include "GLSLContext.h"
  2. #include "WallpaperEngine/Logging/Log.h"
  3. #include <cassert>
  4. #include <memory>
  5. #include "glslang/Include/ResourceLimits.h"
  6. #include "glslang/Public/ShaderLang.h"
  7. #include "SPIRV/GlslangToSpv.h"
  8. #include "spirv_glsl.hpp"
  9. using namespace WallpaperEngine::Render::Shaders;
  10. TBuiltInResource BuiltInResource = {
  11. .maxLights = 32,
  12. .maxClipPlanes = 6,
  13. .maxTextureUnits = 32,
  14. .maxTextureCoords = 32,
  15. .maxVertexAttribs = 64,
  16. .maxVertexUniformComponents = 4096,
  17. .maxVaryingFloats = 64,
  18. .maxVertexTextureImageUnits = 32,
  19. .maxCombinedTextureImageUnits = 80,
  20. .maxTextureImageUnits = 32,
  21. .maxFragmentUniformComponents = 4096,
  22. .maxDrawBuffers = 32,
  23. .maxVertexUniformVectors = 128,
  24. .maxVaryingVectors = 8,
  25. .maxFragmentUniformVectors = 16,
  26. .maxVertexOutputVectors = 16,
  27. .maxFragmentInputVectors = 15,
  28. .minProgramTexelOffset = -8,
  29. .maxProgramTexelOffset = 7,
  30. .maxClipDistances = 8,
  31. .maxComputeWorkGroupCountX = 65535,
  32. .maxComputeWorkGroupCountY = 65535,
  33. .maxComputeWorkGroupCountZ = 65535,
  34. .maxComputeWorkGroupSizeX = 1024,
  35. .maxComputeWorkGroupSizeY = 1024,
  36. .maxComputeWorkGroupSizeZ = 64,
  37. .maxComputeUniformComponents = 1024,
  38. .maxComputeTextureImageUnits = 16,
  39. .maxComputeImageUniforms = 8,
  40. .maxComputeAtomicCounters = 8,
  41. .maxComputeAtomicCounterBuffers = 1,
  42. .maxVaryingComponents = 60,
  43. .maxVertexOutputComponents = 64,
  44. .maxGeometryInputComponents = 64,
  45. .maxGeometryOutputComponents = 128,
  46. .maxFragmentInputComponents = 128,
  47. .maxImageUnits = 8,
  48. .maxCombinedImageUnitsAndFragmentOutputs = 8,
  49. .maxCombinedShaderOutputResources = 8,
  50. .maxImageSamples = 0,
  51. .maxVertexImageUniforms = 0,
  52. .maxTessControlImageUniforms = 0,
  53. .maxTessEvaluationImageUniforms = 0,
  54. .maxGeometryImageUniforms = 0,
  55. .maxFragmentImageUniforms = 8,
  56. .maxCombinedImageUniforms = 8,
  57. .maxGeometryTextureImageUnits = 16,
  58. .maxGeometryOutputVertices = 256,
  59. .maxGeometryTotalOutputComponents = 1024,
  60. .maxGeometryUniformComponents = 1024,
  61. .maxGeometryVaryingComponents = 64,
  62. .maxTessControlInputComponents = 128,
  63. .maxTessControlOutputComponents = 128,
  64. .maxTessControlTextureImageUnits = 16,
  65. .maxTessControlUniformComponents = 1024,
  66. .maxTessControlTotalOutputComponents = 4096,
  67. .maxTessEvaluationInputComponents = 128,
  68. .maxTessEvaluationOutputComponents = 128,
  69. .maxTessEvaluationTextureImageUnits = 16,
  70. .maxTessEvaluationUniformComponents = 1024,
  71. .maxTessPatchComponents = 120,
  72. .maxPatchVertices = 32,
  73. .maxTessGenLevel = 64,
  74. .maxViewports = 16,
  75. .maxVertexAtomicCounters = 0,
  76. .maxTessControlAtomicCounters = 0,
  77. .maxTessEvaluationAtomicCounters = 0,
  78. .maxGeometryAtomicCounters = 0,
  79. .maxFragmentAtomicCounters = 8,
  80. .maxCombinedAtomicCounters = 8,
  81. .maxAtomicCounterBindings = 1,
  82. .maxVertexAtomicCounterBuffers = 0,
  83. .maxTessControlAtomicCounterBuffers = 0,
  84. .maxTessEvaluationAtomicCounterBuffers = 0,
  85. .maxGeometryAtomicCounterBuffers = 0,
  86. .maxFragmentAtomicCounterBuffers = 1,
  87. .maxCombinedAtomicCounterBuffers = 1,
  88. .maxAtomicCounterBufferSize = 16384,
  89. .maxTransformFeedbackBuffers = 4,
  90. .maxTransformFeedbackInterleavedComponents = 64,
  91. .maxCullDistances = 8,
  92. .maxCombinedClipAndCullDistances = 8,
  93. .maxSamples = 4,
  94. .maxMeshOutputVerticesNV = 256,
  95. .maxMeshOutputPrimitivesNV = 512,
  96. .maxMeshWorkGroupSizeX_NV = 32,
  97. .maxMeshWorkGroupSizeY_NV = 1,
  98. .maxMeshWorkGroupSizeZ_NV = 1,
  99. .maxTaskWorkGroupSizeX_NV = 32,
  100. .maxTaskWorkGroupSizeY_NV = 1,
  101. .maxTaskWorkGroupSizeZ_NV = 1,
  102. .maxMeshViewCountNV = 4,
  103. .limits = {
  104. .nonInductiveForLoops = true,
  105. .whileLoops = true,
  106. .doWhileLoops = true,
  107. .generalUniformIndexing = true,
  108. .generalAttributeMatrixVectorIndexing = true,
  109. .generalVaryingIndexing = true,
  110. .generalSamplerIndexing = true,
  111. .generalVariableIndexing = true,
  112. .generalConstantMatrixVectorIndexing = true,
  113. }
  114. };
  115. GLSLContext::GLSLContext () {
  116. assert (this->sInstance == nullptr);
  117. glslang::InitializeProcess();
  118. }
  119. GLSLContext::~GLSLContext () {
  120. glslang::FinalizeProcess();
  121. }
  122. GLSLContext& GLSLContext::get () {
  123. if (sInstance == nullptr)
  124. sInstance = std::make_unique <GLSLContext> ();
  125. return *sInstance;
  126. }
  127. std::pair<std::string, std::string> GLSLContext::toGlsl (const std::string& vertex, const std::string& fragment) {
  128. glslang::TShader vertexShader (EShLangVertex);
  129. const char* vertexSource = vertex.c_str();
  130. vertexShader.setStrings(&vertexSource, 1);
  131. vertexShader.setEntryPoint("main");
  132. vertexShader.setEnvInput(glslang::EShSourceGlsl, EShLangVertex, glslang::EShClientOpenGL, 330);
  133. vertexShader.setEnvClient(glslang::EShClientOpenGL, glslang::EShTargetOpenGL_450);
  134. vertexShader.setEnvTarget(glslang::EShTargetSpv, glslang::EShTargetSpv_1_5);
  135. vertexShader.setAutoMapLocations (true);
  136. vertexShader.setAutoMapBindings (true);
  137. if (!vertexShader.parse (&BuiltInResource, 100, false, EShMsgDefault)) {
  138. sLog.error ("GLSL vertex unit parsing Failed: ", vertexShader.getInfoLog());
  139. return {"", ""};
  140. }
  141. glslang::TShader fragmentShader (EShLangFragment);
  142. const char* fragmentSource = fragment.c_str();
  143. fragmentShader.setStrings(&fragmentSource, 1);
  144. fragmentShader.setEntryPoint("main");
  145. fragmentShader.setEnvInput(glslang::EShSourceGlsl, EShLangFragment, glslang::EShClientOpenGL, 330);
  146. fragmentShader.setEnvClient(glslang::EShClientOpenGL, glslang::EShTargetOpenGL_450);
  147. fragmentShader.setEnvTarget(glslang::EShTargetSpv, glslang::EShTargetSpv_1_5);
  148. fragmentShader.setAutoMapLocations (true);
  149. fragmentShader.setAutoMapBindings (true);
  150. if (!fragmentShader.parse (&BuiltInResource, 100, false, EShMsgDefault)) {
  151. sLog.error ("GLSL fragment unit parsing Failed: ", fragmentShader.getInfoLog());
  152. return {"", ""};
  153. }
  154. glslang::TProgram program;
  155. program.addShader (&vertexShader);
  156. program.addShader (&fragmentShader);
  157. if (!program.link (EShMsgDefault)) {
  158. sLog.error ("Program Linking Failed: ", program.getInfoLog());
  159. return {"", ""};
  160. }
  161. std::vector<uint32_t> spirv;
  162. glslang::GlslangToSpv (*program.getIntermediate (EShLangVertex), spirv);
  163. spirv_cross::CompilerGLSL vertexCompiler (spirv);
  164. spirv_cross::CompilerGLSL::Options options;
  165. options.version = 330;
  166. options.es = false;
  167. vertexCompiler.set_common_options(options);
  168. spirv.clear ();
  169. glslang::GlslangToSpv (*program.getIntermediate (EShLangFragment), spirv);
  170. spirv_cross::CompilerGLSL fragmentCompiler (spirv);
  171. options.version = 330;
  172. options.es = false;
  173. fragmentCompiler .set_common_options(options);
  174. return {vertexCompiler.compile() + "#if 0\n" + vertex + "\n#endif", fragmentCompiler.compile() + "#if 0\n" + fragment + "\n#endif"};
  175. }
  176. std::unique_ptr <GLSLContext> GLSLContext::sInstance = nullptr;