/*************************************************************************/ /* register_types.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ /* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ /* "Software"), to deal in the Software without restriction, including */ /* without limitation the rights to use, copy, modify, merge, publish, */ /* distribute, sublicense, and/or sell copies of the Software, and to */ /* permit persons to whom the Software is furnished to do so, subject to */ /* the following conditions: */ /* */ /* The above copyright notice and this permission notice shall be */ /* included in all copies or substantial portions of the Software. */ /* */ /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ #include "register_types.h" #include "servers/visual/rendering_device.h" #include #include #include static const TBuiltInResource default_builtin_resource = { /*maxLights*/ 32, /*maxClipPlanes*/ 6, /*maxTextureUnits*/ 32, /*maxTextureCoords*/ 32, /*maxVertexAttribs*/ 64, /*maxVertexUniformComponents*/ 4096, /*maxVaryingFloats*/ 64, /*maxVertexTextureImageUnits*/ 32, /*maxCombinedTextureImageUnits*/ 80, /*maxTextureImageUnits*/ 32, /*maxFragmentUniformComponents*/ 4096, /*maxDrawBuffers*/ 32, /*maxVertexUniformVectors*/ 128, /*maxVaryingVectors*/ 8, /*maxFragmentUniformVectors*/ 16, /*maxVertexOutputVectors*/ 16, /*maxFragmentInputVectors*/ 15, /*minProgramTexelOffset*/ -8, /*maxProgramTexelOffset*/ 7, /*maxClipDistances*/ 8, /*maxComputeWorkGroupCountX*/ 65535, /*maxComputeWorkGroupCountY*/ 65535, /*maxComputeWorkGroupCountZ*/ 65535, /*maxComputeWorkGroupSizeX*/ 1024, /*maxComputeWorkGroupSizeY*/ 1024, /*maxComputeWorkGroupSizeZ*/ 64, /*maxComputeUniformComponents*/ 1024, /*maxComputeTextureImageUnits*/ 16, /*maxComputeImageUniforms*/ 8, /*maxComputeAtomicCounters*/ 8, /*maxComputeAtomicCounterBuffers*/ 1, /*maxVaryingComponents*/ 60, /*maxVertexOutputComponents*/ 64, /*maxGeometryInputComponents*/ 64, /*maxGeometryOutputComponents*/ 128, /*maxFragmentInputComponents*/ 128, /*maxImageUnits*/ 8, /*maxCombinedImageUnitsAndFragmentOutputs*/ 8, /*maxCombinedShaderOutputResources*/ 8, /*maxImageSamples*/ 0, /*maxVertexImageUniforms*/ 0, /*maxTessControlImageUniforms*/ 0, /*maxTessEvaluationImageUniforms*/ 0, /*maxGeometryImageUniforms*/ 0, /*maxFragmentImageUniforms*/ 8, /*maxCombinedImageUniforms*/ 8, /*maxGeometryTextureImageUnits*/ 16, /*maxGeometryOutputVertices*/ 256, /*maxGeometryTotalOutputComponents*/ 1024, /*maxGeometryUniformComponents*/ 1024, /*maxGeometryVaryingComponents*/ 64, /*maxTessControlInputComponents*/ 128, /*maxTessControlOutputComponents*/ 128, /*maxTessControlTextureImageUnits*/ 16, /*maxTessControlUniformComponents*/ 1024, /*maxTessControlTotalOutputComponents*/ 4096, /*maxTessEvaluationInputComponents*/ 128, /*maxTessEvaluationOutputComponents*/ 128, /*maxTessEvaluationTextureImageUnits*/ 16, /*maxTessEvaluationUniformComponents*/ 1024, /*maxTessPatchComponents*/ 120, /*maxPatchVertices*/ 32, /*maxTessGenLevel*/ 64, /*maxViewports*/ 16, /*maxVertexAtomicCounters*/ 0, /*maxTessControlAtomicCounters*/ 0, /*maxTessEvaluationAtomicCounters*/ 0, /*maxGeometryAtomicCounters*/ 0, /*maxFragmentAtomicCounters*/ 8, /*maxCombinedAtomicCounters*/ 8, /*maxAtomicCounterBindings*/ 1, /*maxVertexAtomicCounterBuffers*/ 0, /*maxTessControlAtomicCounterBuffers*/ 0, /*maxTessEvaluationAtomicCounterBuffers*/ 0, /*maxGeometryAtomicCounterBuffers*/ 0, /*maxFragmentAtomicCounterBuffers*/ 1, /*maxCombinedAtomicCounterBuffers*/ 1, /*maxAtomicCounterBufferSize*/ 16384, /*maxTransformFeedbackBuffers*/ 4, /*maxTransformFeedbackInterleavedComponents*/ 64, /*maxCullDistances*/ 8, /*maxCombinedClipAndCullDistances*/ 8, /*maxSamples*/ 4, /*maxMeshOutputVerticesNV*/ 0, /*maxMeshOutputPrimitivesNV*/ 0, /*maxMeshWorkGroupSizeX_NV*/ 0, /*maxMeshWorkGroupSizeY_NV*/ 0, /*maxMeshWorkGroupSizeZ_NV*/ 0, /*maxTaskWorkGroupSizeX_NV*/ 0, /*maxTaskWorkGroupSizeY_NV*/ 0, /*maxTaskWorkGroupSizeZ_NV*/ 0, /*maxMeshViewCountNV*/ 0, /*limits*/ { /*nonInductiveForLoops*/ 1, /*whileLoops*/ 1, /*doWhileLoops*/ 1, /*generalUniformIndexing*/ 1, /*generalAttributeMatrixVectorIndexing*/ 1, /*generalVaryingIndexing*/ 1, /*generalSamplerIndexing*/ 1, /*generalVariableIndexing*/ 1, /*generalConstantMatrixVectorIndexing*/ 1, } }; static PoolVector _compile_shader_glsl(RenderingDevice::ShaderStage p_stage, const String &p_source_code, RenderingDevice::ShaderLanguage p_language, String *r_error) { PoolVector ret; ERR_FAIL_COND_V(p_language == RenderingDevice::SHADER_LANGUAGE_HLSL, ret); EShLanguage stages[RenderingDevice::SHADER_STAGE_MAX] = { EShLangVertex, EShLangFragment, EShLangTessControl, EShLangTessEvaluation, EShLangCompute }; int ClientInputSemanticsVersion = 100; // maps to, say, #define VULKAN 100 glslang::EShTargetClientVersion VulkanClientVersion = glslang::EShTargetVulkan_1_0; glslang::EShTargetLanguageVersion TargetVersion = glslang::EShTargetSpv_1_0; glslang::TShader::ForbidIncluder includer; glslang::TShader shader(stages[p_stage]); CharString cs = p_source_code.ascii(); const char *cs_strings = cs.get_data(); shader.setStrings(&cs_strings, 1); shader.setEnvInput(glslang::EShSourceGlsl, stages[p_stage], glslang::EShClientVulkan, ClientInputSemanticsVersion); shader.setEnvClient(glslang::EShClientVulkan, VulkanClientVersion); shader.setEnvTarget(glslang::EShTargetSpv, TargetVersion); EShMessages messages = (EShMessages)(EShMsgSpvRules | EShMsgVulkanRules); const int DefaultVersion = 100; std::string pre_processed_code; //preprocess if (!shader.preprocess(&default_builtin_resource, DefaultVersion, ENoProfile, false, false, messages, &pre_processed_code, includer)) { if (r_error) { (*r_error) = "Failed pre-process:\n"; (*r_error) += shader.getInfoLog(); (*r_error) += "\n"; (*r_error) += shader.getInfoDebugLog(); } return ret; } //set back.. cs_strings = pre_processed_code.c_str(); shader.setStrings(&cs_strings, 1); //parse if (!shader.parse(&default_builtin_resource, DefaultVersion, false, messages)) { if (r_error) { (*r_error) = "Failed parse:\n"; (*r_error) += shader.getInfoLog(); (*r_error) += "\n"; (*r_error) += shader.getInfoDebugLog(); } return ret; } //link glslang::TProgram program; program.addShader(&shader); if (!program.link(messages)) { if (r_error) { (*r_error) = "Failed link:\n"; (*r_error) += program.getInfoLog(); (*r_error) += "\n"; (*r_error) += program.getInfoDebugLog(); } return ret; } std::vector SpirV; spv::SpvBuildLogger logger; glslang::SpvOptions spvOptions; glslang::GlslangToSpv(*program.getIntermediate(stages[p_stage]), SpirV, &logger, &spvOptions); ret.resize(SpirV.size() * sizeof(uint32_t)); { PoolVector::Write w = ret.write(); copymem(w.ptr(), &SpirV[0], SpirV.size() * sizeof(uint32_t)); } return ret; } void preregister_glslang_types() { // initialize in case it's not initialized. This is done once per thread // and it's safe to call multiple times glslang::InitializeProcess(); RenderingDevice::shader_set_compile_function(_compile_shader_glsl); } void register_glslang_types() { } void unregister_glslang_types() { glslang::FinalizeProcess(); }