ShaderStage.cpp 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. /**
  2. * Copyright (c) 2006-2017 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. /* .limits = */ {
  110. /* .nonInductiveForLoops = */ 1,
  111. /* .whileLoops = */ 1,
  112. /* .doWhileLoops = */ 1,
  113. /* .generalUniformIndexing = */ 1,
  114. /* .generalAttributeMatrixVectorIndexing = */ 1,
  115. /* .generalVaryingIndexing = */ 1,
  116. /* .generalSamplerIndexing = */ 1,
  117. /* .generalVariableIndexing = */ 1,
  118. /* .generalConstantMatrixVectorIndexing = */ 1,
  119. }
  120. };
  121. namespace love
  122. {
  123. namespace graphics
  124. {
  125. ShaderStage::ShaderStage(Graphics *gfx, StageType stage, const std::string &glsl, bool gles, const std::string &cachekey)
  126. : stageType(stage)
  127. , source(glsl)
  128. , cacheKey(cachekey)
  129. , glslangShader(nullptr)
  130. {
  131. EShLanguage glslangStage = EShLangCount;
  132. if (stage == STAGE_VERTEX)
  133. glslangStage = EShLangVertex;
  134. else if (stage == STAGE_PIXEL)
  135. glslangStage = EShLangFragment;
  136. else
  137. throw love::Exception("Cannot compile shader stage: unknown stage type.");
  138. glslangShader = new glslang::TShader(glslangStage);
  139. bool supportsGLSL3 = gfx->getCapabilities().features[Graphics::FEATURE_GLSL3];
  140. int defaultversion = gles ? 100 : 120;
  141. EProfile defaultprofile = ENoProfile;
  142. const char *csrc = glsl.c_str();
  143. int srclen = (int) glsl.length();
  144. glslangShader->setStringsWithLengths(&csrc, &srclen, 1);
  145. bool forcedefault = false;
  146. if (source.find("#define LOVE_GLSL1_ON_GLSL3") != std::string::npos)
  147. forcedefault = true;
  148. bool forwardcompat = supportsGLSL3 && !forcedefault;
  149. if (!glslangShader->parse(&defaultTBuiltInResource, defaultversion, defaultprofile, forcedefault, forwardcompat, EShMsgSuppressWarnings))
  150. {
  151. const char *stagename = "unknown";
  152. getConstant(stage, stagename);
  153. std::string err = "Error validating " + std::string(stagename) + " shader:\n\n"
  154. + std::string(glslangShader->getInfoLog()) + "\n"
  155. + std::string(glslangShader->getInfoDebugLog());
  156. delete glslangShader;
  157. throw love::Exception("%s", err.c_str());
  158. }
  159. }
  160. ShaderStage::~ShaderStage()
  161. {
  162. if (!cacheKey.empty())
  163. {
  164. auto gfx = Module::getInstance<Graphics>(Module::M_GRAPHICS);
  165. if (gfx != nullptr)
  166. gfx->cleanupCachedShaderStage(stageType, cacheKey);
  167. }
  168. delete glslangShader;
  169. }
  170. bool ShaderStage::getConstant(const char *in, StageType &out)
  171. {
  172. return stageNames.find(in, out);
  173. }
  174. bool ShaderStage::getConstant(StageType in, const char *&out)
  175. {
  176. return stageNames.find(in, out);
  177. }
  178. StringMap<ShaderStage::StageType, ShaderStage::STAGE_MAX_ENUM>::Entry ShaderStage::stageNameEntries[] =
  179. {
  180. { "vertex", STAGE_VERTEX },
  181. { "pixel", STAGE_PIXEL },
  182. };
  183. StringMap<ShaderStage::StageType, ShaderStage::STAGE_MAX_ENUM> ShaderStage::stageNames(ShaderStage::stageNameEntries, sizeof(ShaderStage::stageNameEntries));
  184. } // graphics
  185. } // love