ShaderStage.cpp 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. /**
  2. * Copyright (c) 2006-2022 LOVE Development Team
  3. *
  4. * This software is provided 'as-is', without any express or implied
  5. * warranty. In no event will the authors be held liable for any damages
  6. * arising from the use of this software.
  7. *
  8. * Permission is granted to anyone to use this software for any purpose,
  9. * including commercial applications, and to alter it and redistribute it
  10. * freely, subject to the following restrictions:
  11. *
  12. * 1. The origin of this software must not be misrepresented; you must not
  13. * claim that you wrote the original software. If you use this software
  14. * in a product, an acknowledgment in the product documentation would be
  15. * appreciated but is not required.
  16. * 2. Altered source versions must be plainly marked as such, and must not be
  17. * misrepresented as being the original software.
  18. * 3. This notice may not be removed or altered from any source distribution.
  19. **/
  20. #include <iostream>
  21. #include "ShaderStage.h"
  22. #include "common/Exception.h"
  23. #include "Graphics.h"
  24. #include "libraries/glslang/glslang/Public/ShaderLang.h"
  25. // TODO: Use love.graphics to determine actual limits?
  26. static const TBuiltInResource defaultTBuiltInResource = {
  27. /* .MaxLights = */ 32,
  28. /* .MaxClipPlanes = */ 6,
  29. /* .MaxTextureUnits = */ 32,
  30. /* .MaxTextureCoords = */ 32,
  31. /* .MaxVertexAttribs = */ 64,
  32. /* .MaxVertexUniformComponents = */ 16384,
  33. /* .MaxVaryingFloats = */ 128,
  34. /* .MaxVertexTextureImageUnits = */ 32,
  35. /* .MaxCombinedTextureImageUnits = */ 80,
  36. /* .MaxTextureImageUnits = */ 32,
  37. /* .MaxFragmentUniformComponents = */ 16384,
  38. /* .MaxDrawBuffers = */ 8,
  39. /* .MaxVertexUniformVectors = */ 4096,
  40. /* .MaxVaryingVectors = */ 32,
  41. /* .MaxFragmentUniformVectors = */ 4096,
  42. /* .MaxVertexOutputVectors = */ 32,
  43. /* .MaxFragmentInputVectors = */ 31,
  44. /* .MinProgramTexelOffset = */ -8,
  45. /* .MaxProgramTexelOffset = */ 7,
  46. /* .MaxClipDistances = */ 8,
  47. /* .MaxComputeWorkGroupCountX = */ 65535,
  48. /* .MaxComputeWorkGroupCountY = */ 65535,
  49. /* .MaxComputeWorkGroupCountZ = */ 65535,
  50. /* .MaxComputeWorkGroupSizeX = */ 1024,
  51. /* .MaxComputeWorkGroupSizeY = */ 1024,
  52. /* .MaxComputeWorkGroupSizeZ = */ 64,
  53. /* .MaxComputeUniformComponents = */ 1024,
  54. /* .MaxComputeTextureImageUnits = */ 32,
  55. /* .MaxComputeImageUniforms = */ 16,
  56. /* .MaxComputeAtomicCounters = */ 4096,
  57. /* .MaxComputeAtomicCounterBuffers = */ 8,
  58. /* .MaxVaryingComponents = */ 128,
  59. /* .MaxVertexOutputComponents = */ 128,
  60. /* .MaxGeometryInputComponents = */ 128,
  61. /* .MaxGeometryOutputComponents = */ 128,
  62. /* .MaxFragmentInputComponents = */ 128,
  63. /* .MaxImageUnits = */ 192,
  64. /* .MaxCombinedImageUnitsAndFragmentOutputs = */ 144,
  65. /* .MaxCombinedShaderOutputResources = */ 144,
  66. /* .MaxImageSamples = */ 32,
  67. /* .MaxVertexImageUniforms = */ 16,
  68. /* .MaxTessControlImageUniforms = */ 16,
  69. /* .MaxTessEvaluationImageUniforms = */ 16,
  70. /* .MaxGeometryImageUniforms = */ 16,
  71. /* .MaxFragmentImageUniforms = */ 16,
  72. /* .MaxCombinedImageUniforms = */ 80,
  73. /* .MaxGeometryTextureImageUnits = */ 16,
  74. /* .MaxGeometryOutputVertices = */ 256,
  75. /* .MaxGeometryTotalOutputComponents = */ 1024,
  76. /* .MaxGeometryUniformComponents = */ 1024,
  77. /* .MaxGeometryVaryingComponents = */ 64,
  78. /* .MaxTessControlInputComponents = */ 128,
  79. /* .MaxTessControlOutputComponents = */ 128,
  80. /* .MaxTessControlTextureImageUnits = */ 16,
  81. /* .MaxTessControlUniformComponents = */ 1024,
  82. /* .MaxTessControlTotalOutputComponents = */ 4096,
  83. /* .MaxTessEvaluationInputComponents = */ 128,
  84. /* .MaxTessEvaluationOutputComponents = */ 128,
  85. /* .MaxTessEvaluationTextureImageUnits = */ 16,
  86. /* .MaxTessEvaluationUniformComponents = */ 1024,
  87. /* .MaxTessPatchComponents = */ 120,
  88. /* .MaxPatchVertices = */ 32,
  89. /* .MaxTessGenLevel = */ 64,
  90. /* .MaxViewports = */ 16,
  91. /* .MaxVertexAtomicCounters = */ 4096,
  92. /* .MaxTessControlAtomicCounters = */ 4096,
  93. /* .MaxTessEvaluationAtomicCounters = */ 4096,
  94. /* .MaxGeometryAtomicCounters = */ 4096,
  95. /* .MaxFragmentAtomicCounters = */ 4096,
  96. /* .MaxCombinedAtomicCounters = */ 4096,
  97. /* .MaxAtomicCounterBindings = */ 8,
  98. /* .MaxVertexAtomicCounterBuffers = */ 8,
  99. /* .MaxTessControlAtomicCounterBuffers = */ 8,
  100. /* .MaxTessEvaluationAtomicCounterBuffers = */ 8,
  101. /* .MaxGeometryAtomicCounterBuffers = */ 8,
  102. /* .MaxFragmentAtomicCounterBuffers = */ 8,
  103. /* .MaxCombinedAtomicCounterBuffers = */ 8,
  104. /* .MaxAtomicCounterBufferSize = */ 16384,
  105. /* .MaxTransformFeedbackBuffers = */ 4,
  106. /* .MaxTransformFeedbackInterleavedComponents = */ 64,
  107. /* .MaxCullDistances = */ 8,
  108. /* .MaxCombinedClipAndCullDistances = */ 8,
  109. /* .MaxSamples = */ 32,
  110. /* .maxMeshOutputVerticesNV = */ 256,
  111. /* .maxMeshOutputPrimitivesNV = */ 512,
  112. /* .maxMeshWorkGroupSizeX_NV = */ 32,
  113. /* .maxMeshWorkGroupSizeY_NV = */ 1,
  114. /* .maxMeshWorkGroupSizeZ_NV = */ 1,
  115. /* .maxTaskWorkGroupSizeX_NV = */ 32,
  116. /* .maxTaskWorkGroupSizeY_NV = */ 1,
  117. /* .maxTaskWorkGroupSizeZ_NV = */ 1,
  118. /* .maxMeshViewCountNV = */ 4,
  119. /* .maxDualSourceDrawBuffersEXT = */ 1,
  120. /* .limits = */ {
  121. /* .nonInductiveForLoops = */ 1,
  122. /* .whileLoops = */ 1,
  123. /* .doWhileLoops = */ 1,
  124. /* .generalUniformIndexing = */ 1,
  125. /* .generalAttributeMatrixVectorIndexing = */ 1,
  126. /* .generalVaryingIndexing = */ 1,
  127. /* .generalSamplerIndexing = */ 1,
  128. /* .generalVariableIndexing = */ 1,
  129. /* .generalConstantMatrixVectorIndexing = */ 1,
  130. }
  131. };
  132. namespace love
  133. {
  134. namespace graphics
  135. {
  136. ShaderStage::ShaderStage(Graphics *gfx, ShaderStageType stage, const std::string &glsl, bool gles, const std::string &cachekey)
  137. : stageType(stage)
  138. , source(glsl)
  139. , cacheKey(cachekey)
  140. , glslangValidationShader(nullptr)
  141. {
  142. EShLanguage glslangStage = EShLangCount;
  143. if (stage == SHADERSTAGE_VERTEX)
  144. glslangStage = EShLangVertex;
  145. else if (stage == SHADERSTAGE_PIXEL)
  146. glslangStage = EShLangFragment;
  147. else if (stage == SHADERSTAGE_COMPUTE)
  148. glslangStage = EShLangCompute;
  149. else
  150. throw love::Exception("Cannot compile shader stage: unknown stage type.");
  151. auto glslangShader = new glslang::TShader(glslangStage);
  152. bool supportsGLSL3 = gfx->getCapabilities().features[Graphics::FEATURE_GLSL3];
  153. int defaultversion = gles ? 100 : 120;
  154. EProfile defaultprofile = ENoProfile;
  155. const char *csrc = glsl.c_str();
  156. int srclen = (int) glsl.length();
  157. glslangShader->setStringsWithLengths(&csrc, &srclen, 1);
  158. bool forcedefault = false;
  159. if (source.find("#define LOVE_GLSL1_ON_GLSL3") != std::string::npos)
  160. forcedefault = true;
  161. bool forwardcompat = supportsGLSL3 && !forcedefault;
  162. if (!glslangShader->parse(&defaultTBuiltInResource, defaultversion, defaultprofile, forcedefault, forwardcompat, EShMsgSuppressWarnings))
  163. {
  164. const char *stagename = "unknown";
  165. getConstant(stage, stagename);
  166. std::string err = "Error validating " + std::string(stagename) + " shader:\n\n"
  167. + std::string(glslangShader->getInfoLog()) + "\n"
  168. + std::string(glslangShader->getInfoDebugLog()) + "\n\nShader Code:\n"
  169. + glsl;
  170. delete glslangShader;
  171. throw love::Exception("%s", err.c_str());
  172. }
  173. glslangValidationShader = glslangShader;
  174. }
  175. ShaderStage::~ShaderStage()
  176. {
  177. if (!cacheKey.empty())
  178. {
  179. auto gfx = Module::getInstance<Graphics>(Module::M_GRAPHICS);
  180. if (gfx != nullptr)
  181. gfx->cleanupCachedShaderStage(stageType, cacheKey);
  182. }
  183. delete glslangValidationShader;
  184. }
  185. bool ShaderStage::getConstant(const char *in, ShaderStageType &out)
  186. {
  187. return stageNames.find(in, out);
  188. }
  189. bool ShaderStage::getConstant(ShaderStageType in, const char *&out)
  190. {
  191. return stageNames.find(in, out);
  192. }
  193. const char *ShaderStage::getConstant(ShaderStageType in)
  194. {
  195. const char *name = nullptr;
  196. getConstant(in, name);
  197. return name;
  198. }
  199. StringMap<ShaderStageType, SHADERSTAGE_MAX_ENUM>::Entry ShaderStage::stageNameEntries[] =
  200. {
  201. { "vertex", SHADERSTAGE_VERTEX },
  202. { "pixel", SHADERSTAGE_PIXEL },
  203. { "compute", SHADERSTAGE_COMPUTE },
  204. };
  205. StringMap<ShaderStageType, SHADERSTAGE_MAX_ENUM> ShaderStage::stageNames(ShaderStage::stageNameEntries, sizeof(ShaderStage::stageNameEntries));
  206. } // graphics
  207. } // love