diff options
author | Juan Linietsky <juan@godotengine.org> | 2019-07-28 19:58:32 -0300 |
---|---|---|
committer | Juan Linietsky <reduzio@gmail.com> | 2020-02-11 11:53:29 +0100 |
commit | 4fe3ee1730167b90ec8ae70c871c1dad032981d5 (patch) | |
tree | 98b9f82d3a4defc1560245e40c0ba7b3a674fa81 /modules/glslang | |
parent | 60c7498cee169b2cd652045ec19bb526d76f9d61 (diff) |
Moved the shader source compilation code outside RenderingDevice and Vulkan
Diffstat (limited to 'modules/glslang')
-rw-r--r-- | modules/glslang/SCsub | 68 | ||||
-rw-r--r-- | modules/glslang/config.py | 5 | ||||
-rw-r--r-- | modules/glslang/register_types.cpp | 240 | ||||
-rw-r--r-- | modules/glslang/register_types.h | 34 |
4 files changed, 347 insertions, 0 deletions
diff --git a/modules/glslang/SCsub b/modules/glslang/SCsub new file mode 100644 index 0000000000..484036dc94 --- /dev/null +++ b/modules/glslang/SCsub @@ -0,0 +1,68 @@ +#!/usr/bin/env python + +Import('env') +Import('env_modules') + +env_glslang = env_modules.Clone() + +# Thirdparty source files +# Not unbundled so far since not widespread as shared library +thirdparty_dir = "#thirdparty/glslang/" +thirdparty_sources = [ +"glslang/MachineIndependent/RemoveTree.cpp", +"glslang/MachineIndependent/ParseHelper.cpp", +"glslang/MachineIndependent/iomapper.cpp", +"glslang/MachineIndependent/propagateNoContraction.cpp", +"glslang/MachineIndependent/Intermediate.cpp", +"glslang/MachineIndependent/linkValidate.cpp", +"glslang/MachineIndependent/attribute.cpp", +"glslang/MachineIndependent/Scan.cpp", +"glslang/MachineIndependent/Initialize.cpp", +"glslang/MachineIndependent/Constant.cpp", +"glslang/MachineIndependent/reflection.cpp", +"glslang/MachineIndependent/limits.cpp", +"glslang/MachineIndependent/preprocessor/PpScanner.cpp", +"glslang/MachineIndependent/preprocessor/PpTokens.cpp", +"glslang/MachineIndependent/preprocessor/PpAtom.cpp", +"glslang/MachineIndependent/preprocessor/PpContext.cpp", +"glslang/MachineIndependent/preprocessor/Pp.cpp", +"glslang/MachineIndependent/InfoSink.cpp", +"glslang/MachineIndependent/intermOut.cpp", +"glslang/MachineIndependent/SymbolTable.cpp", +"glslang/MachineIndependent/glslang_tab.cpp", +"glslang/MachineIndependent/pch.cpp", +"glslang/MachineIndependent/Versions.cpp", +"glslang/MachineIndependent/ShaderLang.cpp", +"glslang/MachineIndependent/parseConst.cpp", +"glslang/MachineIndependent/PoolAlloc.cpp", +"glslang/MachineIndependent/ParseContextBase.cpp", +"glslang/MachineIndependent/IntermTraverse.cpp", +"glslang/GenericCodeGen/Link.cpp", +"glslang/GenericCodeGen/CodeGen.cpp", +"OGLCompilersDLL/InitializeDll.cpp", +"SPIRV/InReadableOrder.cpp", +"SPIRV/GlslangToSpv.cpp", +"SPIRV/SpvBuilder.cpp", +"SPIRV/SpvTools.cpp", +"SPIRV/disassemble.cpp", +"SPIRV/doc.cpp", +"SPIRV/SPVRemapper.cpp", +"SPIRV/SpvPostProcess.cpp", +"SPIRV/Logger.cpp" +] + +if (env["platform"]=="windows"): + thirdparty_sources.append("glslang/OSDependent/Windows/ossource.cpp") +else: + thirdparty_sources.append("glslang/OSDependent/Unix/ossource.cpp") + +thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources] + + +env_glslang.add_source_files(env.modules_sources, thirdparty_sources) +# Godot's own source files +env_glslang.add_source_files(env.modules_sources, "*.cpp") +env.Prepend(CPPPATH=[thirdparty_dir]) + + + diff --git a/modules/glslang/config.py b/modules/glslang/config.py new file mode 100644 index 0000000000..1c8cd12a2d --- /dev/null +++ b/modules/glslang/config.py @@ -0,0 +1,5 @@ +def can_build(env, platform): + return True + +def configure(env): + pass diff --git a/modules/glslang/register_types.cpp b/modules/glslang/register_types.cpp new file mode 100644 index 0000000000..ef159e743d --- /dev/null +++ b/modules/glslang/register_types.cpp @@ -0,0 +1,240 @@ +/*************************************************************************/ +/* register_types.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 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 "thirdparty/glslang/SPIRV/GlslangToSpv.h" +#include "thirdparty/glslang/glslang/Include/Types.h" +#include "thirdparty/glslang/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, + .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); + + // initialize in case it's not initialized. This is done once per thread + // and it's safe to call multiple times + glslang::InitializeProcess(); + 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() { + RenderingDevice::shader_set_compile_function(_compile_shader_glsl); +} + +void register_glslang_types() { +} +void unregister_glslang_types() { + + +} diff --git a/modules/glslang/register_types.h b/modules/glslang/register_types.h new file mode 100644 index 0000000000..83bfaf8d93 --- /dev/null +++ b/modules/glslang/register_types.h @@ -0,0 +1,34 @@ +/*************************************************************************/ +/* register_types.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 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. */ +/*************************************************************************/ + +#define MODULE_GLSLANG_HAS_PREREGISTER +void preregister_glslang_types(); +void register_glslang_types(); +void unregister_glslang_types(); |