register_types.cpp 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. /*************************************************************************/
  2. /* register_types.cpp */
  3. /*************************************************************************/
  4. /* This file is part of: */
  5. /* GODOT ENGINE */
  6. /* https://godotengine.org */
  7. /*************************************************************************/
  8. /* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
  9. /* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
  10. /* */
  11. /* Permission is hereby granted, free of charge, to any person obtaining */
  12. /* a copy of this software and associated documentation files (the */
  13. /* "Software"), to deal in the Software without restriction, including */
  14. /* without limitation the rights to use, copy, modify, merge, publish, */
  15. /* distribute, sublicense, and/or sell copies of the Software, and to */
  16. /* permit persons to whom the Software is furnished to do so, subject to */
  17. /* the following conditions: */
  18. /* */
  19. /* The above copyright notice and this permission notice shall be */
  20. /* included in all copies or substantial portions of the Software. */
  21. /* */
  22. /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
  23. /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
  24. /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
  25. /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
  26. /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
  27. /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
  28. /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
  29. /*************************************************************************/
  30. #include "register_types.h"
  31. #include "servers/visual/rendering_device.h"
  32. #include <SPIRV/GlslangToSpv.h>
  33. #include <glslang/Include/Types.h>
  34. #include <glslang/Public/ShaderLang.h>
  35. static const TBuiltInResource default_builtin_resource = {
  36. /*maxLights*/ 32,
  37. /*maxClipPlanes*/ 6,
  38. /*maxTextureUnits*/ 32,
  39. /*maxTextureCoords*/ 32,
  40. /*maxVertexAttribs*/ 64,
  41. /*maxVertexUniformComponents*/ 4096,
  42. /*maxVaryingFloats*/ 64,
  43. /*maxVertexTextureImageUnits*/ 32,
  44. /*maxCombinedTextureImageUnits*/ 80,
  45. /*maxTextureImageUnits*/ 32,
  46. /*maxFragmentUniformComponents*/ 4096,
  47. /*maxDrawBuffers*/ 32,
  48. /*maxVertexUniformVectors*/ 128,
  49. /*maxVaryingVectors*/ 8,
  50. /*maxFragmentUniformVectors*/ 16,
  51. /*maxVertexOutputVectors*/ 16,
  52. /*maxFragmentInputVectors*/ 15,
  53. /*minProgramTexelOffset*/ -8,
  54. /*maxProgramTexelOffset*/ 7,
  55. /*maxClipDistances*/ 8,
  56. /*maxComputeWorkGroupCountX*/ 65535,
  57. /*maxComputeWorkGroupCountY*/ 65535,
  58. /*maxComputeWorkGroupCountZ*/ 65535,
  59. /*maxComputeWorkGroupSizeX*/ 1024,
  60. /*maxComputeWorkGroupSizeY*/ 1024,
  61. /*maxComputeWorkGroupSizeZ*/ 64,
  62. /*maxComputeUniformComponents*/ 1024,
  63. /*maxComputeTextureImageUnits*/ 16,
  64. /*maxComputeImageUniforms*/ 8,
  65. /*maxComputeAtomicCounters*/ 8,
  66. /*maxComputeAtomicCounterBuffers*/ 1,
  67. /*maxVaryingComponents*/ 60,
  68. /*maxVertexOutputComponents*/ 64,
  69. /*maxGeometryInputComponents*/ 64,
  70. /*maxGeometryOutputComponents*/ 128,
  71. /*maxFragmentInputComponents*/ 128,
  72. /*maxImageUnits*/ 8,
  73. /*maxCombinedImageUnitsAndFragmentOutputs*/ 8,
  74. /*maxCombinedShaderOutputResources*/ 8,
  75. /*maxImageSamples*/ 0,
  76. /*maxVertexImageUniforms*/ 0,
  77. /*maxTessControlImageUniforms*/ 0,
  78. /*maxTessEvaluationImageUniforms*/ 0,
  79. /*maxGeometryImageUniforms*/ 0,
  80. /*maxFragmentImageUniforms*/ 8,
  81. /*maxCombinedImageUniforms*/ 8,
  82. /*maxGeometryTextureImageUnits*/ 16,
  83. /*maxGeometryOutputVertices*/ 256,
  84. /*maxGeometryTotalOutputComponents*/ 1024,
  85. /*maxGeometryUniformComponents*/ 1024,
  86. /*maxGeometryVaryingComponents*/ 64,
  87. /*maxTessControlInputComponents*/ 128,
  88. /*maxTessControlOutputComponents*/ 128,
  89. /*maxTessControlTextureImageUnits*/ 16,
  90. /*maxTessControlUniformComponents*/ 1024,
  91. /*maxTessControlTotalOutputComponents*/ 4096,
  92. /*maxTessEvaluationInputComponents*/ 128,
  93. /*maxTessEvaluationOutputComponents*/ 128,
  94. /*maxTessEvaluationTextureImageUnits*/ 16,
  95. /*maxTessEvaluationUniformComponents*/ 1024,
  96. /*maxTessPatchComponents*/ 120,
  97. /*maxPatchVertices*/ 32,
  98. /*maxTessGenLevel*/ 64,
  99. /*maxViewports*/ 16,
  100. /*maxVertexAtomicCounters*/ 0,
  101. /*maxTessControlAtomicCounters*/ 0,
  102. /*maxTessEvaluationAtomicCounters*/ 0,
  103. /*maxGeometryAtomicCounters*/ 0,
  104. /*maxFragmentAtomicCounters*/ 8,
  105. /*maxCombinedAtomicCounters*/ 8,
  106. /*maxAtomicCounterBindings*/ 1,
  107. /*maxVertexAtomicCounterBuffers*/ 0,
  108. /*maxTessControlAtomicCounterBuffers*/ 0,
  109. /*maxTessEvaluationAtomicCounterBuffers*/ 0,
  110. /*maxGeometryAtomicCounterBuffers*/ 0,
  111. /*maxFragmentAtomicCounterBuffers*/ 1,
  112. /*maxCombinedAtomicCounterBuffers*/ 1,
  113. /*maxAtomicCounterBufferSize*/ 16384,
  114. /*maxTransformFeedbackBuffers*/ 4,
  115. /*maxTransformFeedbackInterleavedComponents*/ 64,
  116. /*maxCullDistances*/ 8,
  117. /*maxCombinedClipAndCullDistances*/ 8,
  118. /*maxSamples*/ 4,
  119. /*maxMeshOutputVerticesNV*/ 0,
  120. /*maxMeshOutputPrimitivesNV*/ 0,
  121. /*maxMeshWorkGroupSizeX_NV*/ 0,
  122. /*maxMeshWorkGroupSizeY_NV*/ 0,
  123. /*maxMeshWorkGroupSizeZ_NV*/ 0,
  124. /*maxTaskWorkGroupSizeX_NV*/ 0,
  125. /*maxTaskWorkGroupSizeY_NV*/ 0,
  126. /*maxTaskWorkGroupSizeZ_NV*/ 0,
  127. /*maxMeshViewCountNV*/ 0,
  128. /*limits*/ {
  129. /*nonInductiveForLoops*/ 1,
  130. /*whileLoops*/ 1,
  131. /*doWhileLoops*/ 1,
  132. /*generalUniformIndexing*/ 1,
  133. /*generalAttributeMatrixVectorIndexing*/ 1,
  134. /*generalVaryingIndexing*/ 1,
  135. /*generalSamplerIndexing*/ 1,
  136. /*generalVariableIndexing*/ 1,
  137. /*generalConstantMatrixVectorIndexing*/ 1,
  138. }
  139. };
  140. static PoolVector<uint8_t> _compile_shader_glsl(RenderingDevice::ShaderStage p_stage, const String &p_source_code, RenderingDevice::ShaderLanguage p_language, String *r_error) {
  141. PoolVector<uint8_t> ret;
  142. ERR_FAIL_COND_V(p_language == RenderingDevice::SHADER_LANGUAGE_HLSL, ret);
  143. EShLanguage stages[RenderingDevice::SHADER_STAGE_MAX] = {
  144. EShLangVertex,
  145. EShLangFragment,
  146. EShLangTessControl,
  147. EShLangTessEvaluation,
  148. EShLangCompute
  149. };
  150. int ClientInputSemanticsVersion = 100; // maps to, say, #define VULKAN 100
  151. glslang::EShTargetClientVersion VulkanClientVersion = glslang::EShTargetVulkan_1_0;
  152. glslang::EShTargetLanguageVersion TargetVersion = glslang::EShTargetSpv_1_0;
  153. glslang::TShader::ForbidIncluder includer;
  154. glslang::TShader shader(stages[p_stage]);
  155. CharString cs = p_source_code.ascii();
  156. const char *cs_strings = cs.get_data();
  157. shader.setStrings(&cs_strings, 1);
  158. shader.setEnvInput(glslang::EShSourceGlsl, stages[p_stage], glslang::EShClientVulkan, ClientInputSemanticsVersion);
  159. shader.setEnvClient(glslang::EShClientVulkan, VulkanClientVersion);
  160. shader.setEnvTarget(glslang::EShTargetSpv, TargetVersion);
  161. EShMessages messages = (EShMessages)(EShMsgSpvRules | EShMsgVulkanRules);
  162. const int DefaultVersion = 100;
  163. std::string pre_processed_code;
  164. //preprocess
  165. if (!shader.preprocess(&default_builtin_resource, DefaultVersion, ENoProfile, false, false, messages, &pre_processed_code, includer)) {
  166. if (r_error) {
  167. (*r_error) = "Failed pre-process:\n";
  168. (*r_error) += shader.getInfoLog();
  169. (*r_error) += "\n";
  170. (*r_error) += shader.getInfoDebugLog();
  171. }
  172. return ret;
  173. }
  174. //set back..
  175. cs_strings = pre_processed_code.c_str();
  176. shader.setStrings(&cs_strings, 1);
  177. //parse
  178. if (!shader.parse(&default_builtin_resource, DefaultVersion, false, messages)) {
  179. if (r_error) {
  180. (*r_error) = "Failed parse:\n";
  181. (*r_error) += shader.getInfoLog();
  182. (*r_error) += "\n";
  183. (*r_error) += shader.getInfoDebugLog();
  184. }
  185. return ret;
  186. }
  187. //link
  188. glslang::TProgram program;
  189. program.addShader(&shader);
  190. if (!program.link(messages)) {
  191. if (r_error) {
  192. (*r_error) = "Failed link:\n";
  193. (*r_error) += program.getInfoLog();
  194. (*r_error) += "\n";
  195. (*r_error) += program.getInfoDebugLog();
  196. }
  197. return ret;
  198. }
  199. std::vector<uint32_t> SpirV;
  200. spv::SpvBuildLogger logger;
  201. glslang::SpvOptions spvOptions;
  202. glslang::GlslangToSpv(*program.getIntermediate(stages[p_stage]), SpirV, &logger, &spvOptions);
  203. ret.resize(SpirV.size() * sizeof(uint32_t));
  204. {
  205. PoolVector<uint8_t>::Write w = ret.write();
  206. copymem(w.ptr(), &SpirV[0], SpirV.size() * sizeof(uint32_t));
  207. }
  208. return ret;
  209. }
  210. void preregister_glslang_types() {
  211. // initialize in case it's not initialized. This is done once per thread
  212. // and it's safe to call multiple times
  213. glslang::InitializeProcess();
  214. RenderingDevice::shader_set_compile_function(_compile_shader_glsl);
  215. }
  216. void register_glslang_types() {
  217. }
  218. void unregister_glslang_types() {
  219. glslang::FinalizeProcess();
  220. }