diff options
Diffstat (limited to 'modules/glslang/register_types.cpp')
| -rw-r--r-- | modules/glslang/register_types.cpp | 246 |
1 files changed, 246 insertions, 0 deletions
diff --git a/modules/glslang/register_types.cpp b/modules/glslang/register_types.cpp new file mode 100644 index 0000000000..1e4481a6a0 --- /dev/null +++ b/modules/glslang/register_types.cpp @@ -0,0 +1,246 @@ +/*************************************************************************/ +/* 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 <SPIRV/GlslangToSpv.h> +#include <glslang/Include/Types.h> +#include <glslang/Public/ShaderLang.h> + +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<uint8_t> _compile_shader_glsl(RenderingDevice::ShaderStage p_stage, const String &p_source_code, RenderingDevice::ShaderLanguage p_language, String *r_error) { + + PoolVector<uint8_t> 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<uint32_t> 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<uint8_t>::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(); +} |
