summaryrefslogtreecommitdiff
path: root/modules/glslang
diff options
context:
space:
mode:
authorJuan Linietsky <juan@godotengine.org>2019-07-28 19:58:32 -0300
committerJuan Linietsky <reduzio@gmail.com>2020-02-11 11:53:29 +0100
commit4fe3ee1730167b90ec8ae70c871c1dad032981d5 (patch)
tree98b9f82d3a4defc1560245e40c0ba7b3a674fa81 /modules/glslang
parent60c7498cee169b2cd652045ec19bb526d76f9d61 (diff)
Moved the shader source compilation code outside RenderingDevice and Vulkan
Diffstat (limited to 'modules/glslang')
-rw-r--r--modules/glslang/SCsub68
-rw-r--r--modules/glslang/config.py5
-rw-r--r--modules/glslang/register_types.cpp240
-rw-r--r--modules/glslang/register_types.h34
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();