ShaderStage.cpp 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. /**
  2. * Copyright (c) 2006-2020 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 "ShaderStage.h"
  21. #include "common/Exception.h"
  22. #include "Graphics.h"
  23. #include "libraries/glslang/glslang/Public/ShaderLang.h"
  24. // TODO: Use love.graphics to determine actual limits?
  25. static const TBuiltInResource defaultTBuiltInResource = {
  26. /* .MaxLights = */ 32,
  27. /* .MaxClipPlanes = */ 6,
  28. /* .MaxTextureUnits = */ 32,
  29. /* .MaxTextureCoords = */ 32,
  30. /* .MaxVertexAttribs = */ 64,
  31. /* .MaxVertexUniformComponents = */ 16384,
  32. /* .MaxVaryingFloats = */ 128,
  33. /* .MaxVertexTextureImageUnits = */ 32,
  34. /* .MaxCombinedTextureImageUnits = */ 80,
  35. /* .MaxTextureImageUnits = */ 32,
  36. /* .MaxFragmentUniformComponents = */ 16384,
  37. /* .MaxDrawBuffers = */ 8,
  38. /* .MaxVertexUniformVectors = */ 4096,
  39. /* .MaxVaryingVectors = */ 32,
  40. /* .MaxFragmentUniformVectors = */ 4096,
  41. /* .MaxVertexOutputVectors = */ 32,
  42. /* .MaxFragmentInputVectors = */ 31,
  43. /* .MinProgramTexelOffset = */ -8,
  44. /* .MaxProgramTexelOffset = */ 7,
  45. /* .MaxClipDistances = */ 8,
  46. /* .MaxComputeWorkGroupCountX = */ 65535,
  47. /* .MaxComputeWorkGroupCountY = */ 65535,
  48. /* .MaxComputeWorkGroupCountZ = */ 65535,
  49. /* .MaxComputeWorkGroupSizeX = */ 1024,
  50. /* .MaxComputeWorkGroupSizeY = */ 1024,
  51. /* .MaxComputeWorkGroupSizeZ = */ 64,
  52. /* .MaxComputeUniformComponents = */ 1024,
  53. /* .MaxComputeTextureImageUnits = */ 32,
  54. /* .MaxComputeImageUniforms = */ 16,
  55. /* .MaxComputeAtomicCounters = */ 4096,
  56. /* .MaxComputeAtomicCounterBuffers = */ 8,
  57. /* .MaxVaryingComponents = */ 128,
  58. /* .MaxVertexOutputComponents = */ 128,
  59. /* .MaxGeometryInputComponents = */ 128,
  60. /* .MaxGeometryOutputComponents = */ 128,
  61. /* .MaxFragmentInputComponents = */ 128,
  62. /* .MaxImageUnits = */ 192,
  63. /* .MaxCombinedImageUnitsAndFragmentOutputs = */ 144,
  64. /* .MaxCombinedShaderOutputResources = */ 144,
  65. /* .MaxImageSamples = */ 32,
  66. /* .MaxVertexImageUniforms = */ 16,
  67. /* .MaxTessControlImageUniforms = */ 16,
  68. /* .MaxTessEvaluationImageUniforms = */ 16,
  69. /* .MaxGeometryImageUniforms = */ 16,
  70. /* .MaxFragmentImageUniforms = */ 16,
  71. /* .MaxCombinedImageUniforms = */ 80,
  72. /* .MaxGeometryTextureImageUnits = */ 16,
  73. /* .MaxGeometryOutputVertices = */ 256,
  74. /* .MaxGeometryTotalOutputComponents = */ 1024,
  75. /* .MaxGeometryUniformComponents = */ 1024,
  76. /* .MaxGeometryVaryingComponents = */ 64,
  77. /* .MaxTessControlInputComponents = */ 128,
  78. /* .MaxTessControlOutputComponents = */ 128,
  79. /* .MaxTessControlTextureImageUnits = */ 16,
  80. /* .MaxTessControlUniformComponents = */ 1024,
  81. /* .MaxTessControlTotalOutputComponents = */ 4096,
  82. /* .MaxTessEvaluationInputComponents = */ 128,
  83. /* .MaxTessEvaluationOutputComponents = */ 128,
  84. /* .MaxTessEvaluationTextureImageUnits = */ 16,
  85. /* .MaxTessEvaluationUniformComponents = */ 1024,
  86. /* .MaxTessPatchComponents = */ 120,
  87. /* .MaxPatchVertices = */ 32,
  88. /* .MaxTessGenLevel = */ 64,
  89. /* .MaxViewports = */ 16,
  90. /* .MaxVertexAtomicCounters = */ 4096,
  91. /* .MaxTessControlAtomicCounters = */ 4096,
  92. /* .MaxTessEvaluationAtomicCounters = */ 4096,
  93. /* .MaxGeometryAtomicCounters = */ 4096,
  94. /* .MaxFragmentAtomicCounters = */ 4096,
  95. /* .MaxCombinedAtomicCounters = */ 4096,
  96. /* .MaxAtomicCounterBindings = */ 8,
  97. /* .MaxVertexAtomicCounterBuffers = */ 8,
  98. /* .MaxTessControlAtomicCounterBuffers = */ 8,
  99. /* .MaxTessEvaluationAtomicCounterBuffers = */ 8,
  100. /* .MaxGeometryAtomicCounterBuffers = */ 8,
  101. /* .MaxFragmentAtomicCounterBuffers = */ 8,
  102. /* .MaxCombinedAtomicCounterBuffers = */ 8,
  103. /* .MaxAtomicCounterBufferSize = */ 16384,
  104. /* .MaxTransformFeedbackBuffers = */ 4,
  105. /* .MaxTransformFeedbackInterleavedComponents = */ 64,
  106. /* .MaxCullDistances = */ 8,
  107. /* .MaxCombinedClipAndCullDistances = */ 8,
  108. /* .MaxSamples = */ 32,
  109. /* .maxMeshOutputVerticesNV = */ 256,
  110. /* .maxMeshOutputPrimitivesNV = */ 512,
  111. /* .maxMeshWorkGroupSizeX_NV = */ 32,
  112. /* .maxMeshWorkGroupSizeY_NV = */ 1,
  113. /* .maxMeshWorkGroupSizeZ_NV = */ 1,
  114. /* .maxTaskWorkGroupSizeX_NV = */ 32,
  115. /* .maxTaskWorkGroupSizeY_NV = */ 1,
  116. /* .maxTaskWorkGroupSizeZ_NV = */ 1,
  117. /* .maxMeshViewCountNV = */ 4,
  118. /* .limits = */ {
  119. /* .nonInductiveForLoops = */ 1,
  120. /* .whileLoops = */ 1,
  121. /* .doWhileLoops = */ 1,
  122. /* .generalUniformIndexing = */ 1,
  123. /* .generalAttributeMatrixVectorIndexing = */ 1,
  124. /* .generalVaryingIndexing = */ 1,
  125. /* .generalSamplerIndexing = */ 1,
  126. /* .generalVariableIndexing = */ 1,
  127. /* .generalConstantMatrixVectorIndexing = */ 1,
  128. }
  129. };
  130. namespace love
  131. {
  132. namespace graphics
  133. {
  134. ShaderStage::ShaderStage(Graphics *gfx, StageType stage, const std::string &glsl, bool gles, const std::string &cachekey)
  135. : stageType(stage)
  136. , source(glsl)
  137. , cacheKey(cachekey)
  138. , glslangShader(nullptr)
  139. {
  140. EShLanguage glslangStage = EShLangCount;
  141. if (stage == STAGE_VERTEX)
  142. glslangStage = EShLangVertex;
  143. else if (stage == STAGE_PIXEL)
  144. glslangStage = EShLangFragment;
  145. else
  146. throw love::Exception("Cannot compile shader stage: unknown stage type.");
  147. glslangShader = new glslang::TShader(glslangStage);
  148. bool supportsGLSL3 = gfx->getCapabilities().features[Graphics::FEATURE_GLSL3];
  149. int defaultversion = gles ? 100 : 120;
  150. EProfile defaultprofile = ENoProfile;
  151. const char *csrc = glsl.c_str();
  152. int srclen = (int) glsl.length();
  153. glslangShader->setStringsWithLengths(&csrc, &srclen, 1);
  154. bool forcedefault = false;
  155. if (source.find("#define LOVE_GLSL1_ON_GLSL3") != std::string::npos)
  156. forcedefault = true;
  157. bool forwardcompat = supportsGLSL3 && !forcedefault;
  158. if (!glslangShader->parse(&defaultTBuiltInResource, defaultversion, defaultprofile, forcedefault, forwardcompat, EShMsgSuppressWarnings))
  159. {
  160. const char *stagename = "unknown";
  161. getConstant(stage, stagename);
  162. std::string err = "Error validating " + std::string(stagename) + " shader:\n\n"
  163. + std::string(glslangShader->getInfoLog()) + "\n"
  164. + std::string(glslangShader->getInfoDebugLog());
  165. delete glslangShader;
  166. throw love::Exception("%s", err.c_str());
  167. }
  168. }
  169. ShaderStage::~ShaderStage()
  170. {
  171. if (!cacheKey.empty())
  172. {
  173. auto gfx = Module::getInstance<Graphics>(Module::M_GRAPHICS);
  174. if (gfx != nullptr)
  175. gfx->cleanupCachedShaderStage(stageType, cacheKey);
  176. }
  177. delete glslangShader;
  178. }
  179. bool ShaderStage::getConstant(const char *in, StageType &out)
  180. {
  181. return stageNames.find(in, out);
  182. }
  183. bool ShaderStage::getConstant(StageType in, const char *&out)
  184. {
  185. return stageNames.find(in, out);
  186. }
  187. const char *ShaderStage::getConstant(StageType in)
  188. {
  189. const char *name = nullptr;
  190. getConstant(in, name);
  191. return name;
  192. }
  193. StringMap<ShaderStage::StageType, ShaderStage::STAGE_MAX_ENUM>::Entry ShaderStage::stageNameEntries[] =
  194. {
  195. { "vertex", STAGE_VERTEX },
  196. { "pixel", STAGE_PIXEL },
  197. };
  198. StringMap<ShaderStage::StageType, ShaderStage::STAGE_MAX_ENUM> ShaderStage::stageNames(ShaderStage::stageNameEntries, sizeof(ShaderStage::stageNameEntries));
  199. } // graphics
  200. } // love