diff options
| author | Egor Yusov <egor.yusov@gmail.com> | 2018-04-15 04:08:00 +0000 |
|---|---|---|
| committer | Egor Yusov <egor.yusov@gmail.com> | 2018-04-15 04:08:00 +0000 |
| commit | a47df897d30a8fdacc28235ab708ac4b28748eae (patch) | |
| tree | a5c266a835b56a519388253abcd4a19b642db589 /Graphics | |
| parent | Added glslang to the project (diff) | |
| download | DiligentCore-a47df897d30a8fdacc28235ab708ac4b28748eae.tar.gz DiligentCore-a47df897d30a8fdacc28235ab708ac4b28748eae.zip | |
Added GLSL to SPIRV shader compilation
Diffstat (limited to 'Graphics')
| -rw-r--r-- | Graphics/CMakeLists.txt | 20 | ||||
| -rw-r--r-- | Graphics/GLSLTools/CMakeLists.txt | 60 | ||||
| -rw-r--r-- | Graphics/GLSLTools/include/GLSL2SPIRV.h | 35 | ||||
| -rw-r--r-- | Graphics/GLSLTools/include/GLSLSourceBuilder.h | 34 | ||||
| -rw-r--r-- | Graphics/GLSLTools/src/GLSL2SPIRV.cpp | 228 | ||||
| -rw-r--r-- | Graphics/GLSLTools/src/GLSLSourceBuilder.cpp | 242 | ||||
| -rw-r--r-- | Graphics/GraphicsEngineOpenGL/CMakeLists.txt | 3 | ||||
| -rw-r--r-- | Graphics/GraphicsEngineOpenGL/src/ShaderGLImpl.cpp | 229 | ||||
| -rw-r--r-- | Graphics/GraphicsEngineVulkan/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | Graphics/GraphicsEngineVulkan/include/ShaderVkImpl.h | 2 | ||||
| -rw-r--r-- | Graphics/GraphicsEngineVulkan/src/ShaderVkImpl.cpp | 12 | ||||
| -rw-r--r-- | Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanInstance.cpp | 5 | ||||
| -rw-r--r-- | Graphics/HLSL2GLSLConverterLib/include/GLSLDefinitions.h | 12 | ||||
| -rw-r--r-- | Graphics/HLSL2GLSLConverterLib/include/GLSLDefinitions_inc.h | 12 |
14 files changed, 639 insertions, 256 deletions
diff --git a/Graphics/CMakeLists.txt b/Graphics/CMakeLists.txt index 8d54598f..f7b332d3 100644 --- a/Graphics/CMakeLists.txt +++ b/Graphics/CMakeLists.txt @@ -6,35 +6,39 @@ set(DLL_DBG_SUFFIX _${ARCH}d) add_library(GraphicsEngineInterface INTERFACE) target_include_directories(GraphicsEngineInterface INTERFACE - GraphicsEngine/interface + GraphicsEngine/interface ) target_link_libraries(GraphicsEngineInterface INTERFACE - Primitives + Primitives ) add_subdirectory(GraphicsAccessories) add_subdirectory(GraphicsEngine) if(D3D11_SUPPORTED OR D3D12_SUPPORTED) - add_subdirectory(GraphicsEngineD3DBase) + add_subdirectory(GraphicsEngineD3DBase) endif() if(D3D11_SUPPORTED) - add_subdirectory(GraphicsEngineD3D11) + add_subdirectory(GraphicsEngineD3D11) endif() if(D3D12_SUPPORTED) - add_subdirectory(GraphicsEngineD3D12) + add_subdirectory(GraphicsEngineD3D12) +endif() + +if(GL_SUPPORTED OR GLES_SUPPORTED OR VULKAN_SUPPORTED) + add_subdirectory(GLSLTools) endif() if(VULKAN_SUPPORTED) - add_subdirectory(GraphicsEngineVulkan) + add_subdirectory(GraphicsEngineVulkan) endif() if(GL_SUPPORTED OR GLES_SUPPORTED OR VULKAN_SUPPORTED) - add_subdirectory(HLSL2GLSLConverterLib) - add_subdirectory(GraphicsEngineOpenGL) + add_subdirectory(HLSL2GLSLConverterLib) + add_subdirectory(GraphicsEngineOpenGL) endif() add_subdirectory(GraphicsTools)
\ No newline at end of file diff --git a/Graphics/GLSLTools/CMakeLists.txt b/Graphics/GLSLTools/CMakeLists.txt new file mode 100644 index 00000000..73238baa --- /dev/null +++ b/Graphics/GLSLTools/CMakeLists.txt @@ -0,0 +1,60 @@ +cmake_minimum_required (VERSION 3.6) + +project(GLSLTools CXX) + +set(INCLUDE + include/GLSLSourceBuilder.h +) + +set(SOURCE + src/GLSLSourceBuilder.cpp +) + +if(VULKAN_SUPPORTED) + list(APPEND SOURCE + src/GLSL2SPIRV.cpp + ) + list(APPEND INCLUDE + include/GLSL2SPIRV.h + ) +endif() + +add_library(GLSLTools STATIC ${SOURCE} ${INCLUDE}) + +target_include_directories(GLSLTools +PUBLIC + include +PRIVATE + ../HLSL2GLSLConverterLib/include +) + +target_link_libraries(GLSLTools +PRIVATE + BuildSettings + Common +PUBLIC + HLSL2GLSLConverterLib + GraphicsEngineInterface +) + +if(VULKAN_SUPPORTED) + target_link_libraries(GLSLTools + PRIVATE + glslang + SPIRV + ) + target_include_directories(GLSLTools + PRIVATE + ../../External/glslang + ) +endif() + +set_common_target_properties(GLSLTools) + +source_group("src" FILES ${SOURCE}) +source_group("include" FILES ${INCLUDE}) +source_group("interface" FILES ${INTERFACE}) + +set_target_properties(GLSLTools PROPERTIES + FOLDER Core/Graphics +) diff --git a/Graphics/GLSLTools/include/GLSL2SPIRV.h b/Graphics/GLSLTools/include/GLSL2SPIRV.h new file mode 100644 index 00000000..26256629 --- /dev/null +++ b/Graphics/GLSLTools/include/GLSL2SPIRV.h @@ -0,0 +1,35 @@ +/* Copyright 2015-2018 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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 OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +#include "Shader.h" + +namespace Diligent +{ + +void InitializeGlslang(); +void FinalizeGlslang(); +std::vector<unsigned int> GLSLtoSPIRV(const SHADER_TYPE ShaderType, const char *ShaderSource); + +}
\ No newline at end of file diff --git a/Graphics/GLSLTools/include/GLSLSourceBuilder.h b/Graphics/GLSLTools/include/GLSLSourceBuilder.h new file mode 100644 index 00000000..c0ab5a7d --- /dev/null +++ b/Graphics/GLSLTools/include/GLSLSourceBuilder.h @@ -0,0 +1,34 @@ +/* Copyright 2015-2018 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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 OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +#include "BasicTypes.h" +#include "Shader.h" + +namespace Diligent +{ + +String BuildGLSLSourceString(const ShaderCreationAttribs &CreationAttribs); + +}
\ No newline at end of file diff --git a/Graphics/GLSLTools/src/GLSL2SPIRV.cpp b/Graphics/GLSLTools/src/GLSL2SPIRV.cpp new file mode 100644 index 00000000..e36a3196 --- /dev/null +++ b/Graphics/GLSLTools/src/GLSL2SPIRV.cpp @@ -0,0 +1,228 @@ +/* Copyright 2015-2018 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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 OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#if PLATFORM_ANDROID + // Android specific include files. +# include <unordered_map> + + // Header files. +# include <android_native_app_glue.h> +# include "shaderc/shaderc.hpp" + // Static variable that keeps ANativeWindow and asset manager instances. + //static android_app *Android_application = nullptr; +#elif (defined(VK_USE_PLATFORM_IOS_MVK) || defined(VK_USE_PLATFORM_MACOS_MVK)) +# include <MoltenGLSLToSPIRVConverter/GLSLToSPIRVConverter.h> +#else +# include "SPIRV/GlslangToSpv.h" +#endif + +#include "GLSL2SPIRV.h" +#include "DebugUtilities.h" + +namespace Diligent +{ + +void InitializeGlslang() +{ +#if !PLATFORM_ANDROID + glslang::InitializeProcess(); +#endif +} + +void FinalizeGlslang() +{ +#if !PLATFORM_ANDROID + glslang::FinalizeProcess(); +#endif +} + +EShLanguage ShaderTypeToShLanguage(SHADER_TYPE ShaderType) +{ + switch(ShaderType) + { + case SHADER_TYPE_VERTEX: return EShLangVertex; + case SHADER_TYPE_HULL: return EShLangTessControl; + case SHADER_TYPE_DOMAIN: return EShLangTessEvaluation; + case SHADER_TYPE_GEOMETRY: return EShLangGeometry; + case SHADER_TYPE_PIXEL: return EShLangFragment; + case SHADER_TYPE_COMPUTE: return EShLangCompute; + + default: + UNEXPECTED("Unexpected shader type"); + return EShLangCount; + } +} + +TBuiltInResource InitResources() +{ + TBuiltInResource Resources; + + Resources.maxLights = 32; + Resources.maxClipPlanes = 6; + Resources.maxTextureUnits = 32; + Resources.maxTextureCoords = 32; + Resources.maxVertexAttribs = 64; + Resources.maxVertexUniformComponents = 4096; + Resources.maxVaryingFloats = 64; + Resources.maxVertexTextureImageUnits = 32; + Resources.maxCombinedTextureImageUnits = 80; + Resources.maxTextureImageUnits = 32; + Resources.maxFragmentUniformComponents = 4096; + Resources.maxDrawBuffers = 32; + Resources.maxVertexUniformVectors = 128; + Resources.maxVaryingVectors = 8; + Resources.maxFragmentUniformVectors = 16; + Resources.maxVertexOutputVectors = 16; + Resources.maxFragmentInputVectors = 15; + Resources.minProgramTexelOffset = -8; + Resources.maxProgramTexelOffset = 7; + Resources.maxClipDistances = 8; + Resources.maxComputeWorkGroupCountX = 65535; + Resources.maxComputeWorkGroupCountY = 65535; + Resources.maxComputeWorkGroupCountZ = 65535; + Resources.maxComputeWorkGroupSizeX = 1024; + Resources.maxComputeWorkGroupSizeY = 1024; + Resources.maxComputeWorkGroupSizeZ = 64; + Resources.maxComputeUniformComponents = 1024; + Resources.maxComputeTextureImageUnits = 16; + Resources.maxComputeImageUniforms = 8; + Resources.maxComputeAtomicCounters = 8; + Resources.maxComputeAtomicCounterBuffers = 1; + Resources.maxVaryingComponents = 60; + Resources.maxVertexOutputComponents = 64; + Resources.maxGeometryInputComponents = 64; + Resources.maxGeometryOutputComponents = 128; + Resources.maxFragmentInputComponents = 128; + Resources.maxImageUnits = 8; + Resources.maxCombinedImageUnitsAndFragmentOutputs = 8; + Resources.maxCombinedShaderOutputResources = 8; + Resources.maxImageSamples = 0; + Resources.maxVertexImageUniforms = 0; + Resources.maxTessControlImageUniforms = 0; + Resources.maxTessEvaluationImageUniforms = 0; + Resources.maxGeometryImageUniforms = 0; + Resources.maxFragmentImageUniforms = 8; + Resources.maxCombinedImageUniforms = 8; + Resources.maxGeometryTextureImageUnits = 16; + Resources.maxGeometryOutputVertices = 256; + Resources.maxGeometryTotalOutputComponents = 1024; + Resources.maxGeometryUniformComponents = 1024; + Resources.maxGeometryVaryingComponents = 64; + Resources.maxTessControlInputComponents = 128; + Resources.maxTessControlOutputComponents = 128; + Resources.maxTessControlTextureImageUnits = 16; + Resources.maxTessControlUniformComponents = 1024; + Resources.maxTessControlTotalOutputComponents = 4096; + Resources.maxTessEvaluationInputComponents = 128; + Resources.maxTessEvaluationOutputComponents = 128; + Resources.maxTessEvaluationTextureImageUnits = 16; + Resources.maxTessEvaluationUniformComponents = 1024; + Resources.maxTessPatchComponents = 120; + Resources.maxPatchVertices = 32; + Resources.maxTessGenLevel = 64; + Resources.maxViewports = 16; + Resources.maxVertexAtomicCounters = 0; + Resources.maxTessControlAtomicCounters = 0; + Resources.maxTessEvaluationAtomicCounters = 0; + Resources.maxGeometryAtomicCounters = 0; + Resources.maxFragmentAtomicCounters = 8; + Resources.maxCombinedAtomicCounters = 8; + Resources.maxAtomicCounterBindings = 1; + Resources.maxVertexAtomicCounterBuffers = 0; + Resources.maxTessControlAtomicCounterBuffers = 0; + Resources.maxTessEvaluationAtomicCounterBuffers = 0; + Resources.maxGeometryAtomicCounterBuffers = 0; + Resources.maxFragmentAtomicCounterBuffers = 1; + Resources.maxCombinedAtomicCounterBuffers = 1; + Resources.maxAtomicCounterBufferSize = 16384; + Resources.maxTransformFeedbackBuffers = 4; + Resources.maxTransformFeedbackInterleavedComponents = 64; + Resources.maxCullDistances = 8; + Resources.maxCombinedClipAndCullDistances = 8; + Resources.maxSamples = 4; + Resources.limits.nonInductiveForLoops = 1; + Resources.limits.whileLoops = 1; + Resources.limits.doWhileLoops = 1; + Resources.limits.generalUniformIndexing = 1; + Resources.limits.generalAttributeMatrixVectorIndexing = 1; + Resources.limits.generalVaryingIndexing = 1; + Resources.limits.generalSamplerIndexing = 1; + Resources.limits.generalVariableIndexing = 1; + Resources.limits.generalConstantMatrixVectorIndexing = 1; + + return Resources; +} + +std::vector<unsigned int> GLSLtoSPIRV(const SHADER_TYPE ShaderType, const char *ShaderSource) +{ + std::vector<unsigned int> spirv; + +#if PLATFORM_ANDROID + + // On Android, use shaderc instead. + shaderc::Compiler compiler; + shaderc::SpvCompilationResult module = + compiler.CompileGlslToSpv(pshader, strlen(pshader), MapShadercType(shader_type), "shader"); + if (module.GetCompilationStatus() != shaderc_compilation_status_success) { + LOGE("Error: Id=%d, Msg=%s", module.GetCompilationStatus(), module.GetErrorMessage().c_str()); + return false; + } + spirv.assign(module.cbegin(), module.cend()); + +#else + + EShLanguage ShLang = ShaderTypeToShLanguage(ShaderType); + glslang::TShader Shader(ShLang); + TBuiltInResource Resources = InitResources(); + + // Enable SPIR-V and Vulkan rules when parsing GLSL + EShMessages messages = (EShMessages)(EShMsgSpvRules | EShMsgVulkanRules); + + const char *ShaderStrings[] = { ShaderSource }; + Shader.setStrings(ShaderStrings, 1); + + if (!Shader.parse(&Resources, 100, false, messages)) + { + LOG_ERROR_MESSAGE("Failed to parse shader source: \n", Shader.getInfoLog(), '\n', Shader.getInfoDebugLog()); + return std::move(spirv); + } + + glslang::TProgram Program; + Program.addShader(&Shader); + + // + // Program-level processing... + // + if (!Program.link(messages)) + { + LOG_ERROR_MESSAGE("Failed to link program: \n", Shader.getInfoLog(), '\n', Shader.getInfoDebugLog()); + return std::move(spirv); + } + + glslang::GlslangToSpv(*Program.getIntermediate(ShLang), spirv); +#endif + + return std::move(spirv); +} + +} diff --git a/Graphics/GLSLTools/src/GLSLSourceBuilder.cpp b/Graphics/GLSLTools/src/GLSLSourceBuilder.cpp new file mode 100644 index 00000000..064f18aa --- /dev/null +++ b/Graphics/GLSLTools/src/GLSLSourceBuilder.cpp @@ -0,0 +1,242 @@ +/* Copyright 2015-2018 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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 OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include <cstring> + +#include "GLSLSourceBuilder.h" +#include "DebugUtilities.h" +#include "HLSL2GLSLConverterImpl.h" +#include "RefCntAutoPtr.h" +#include "DataBlobImpl.h" + +namespace Diligent +{ + +String BuildGLSLSourceString(const ShaderCreationAttribs &CreationAttribs) +{ + String GLSLSource; + + auto ShaderType = CreationAttribs.Desc.ShaderType; + +#if PLATFORM_WIN32 || PLATFORM_LINUX + GLSLSource.append( + "#version 430 core\n" + "#define DESKTOP_GL 1\n" + ); +# if PLATFORM_WIN32 + GLSLSource.append("#define PLATFORM_WIN32 1\n"); +# elif PLATFORM_LINUX + GLSLSource.append("#define PLATFORM_LINUX 1\n"); +# else +# error Unexpected platform +# endif +#elif PLATFORM_MACOS + GLSLSource.append( + "#version 410 core\n" + "#define DESKTOP_GL 1\n" + "#define PLATFORM_MACOS 1\n" + ); +#elif PLATFORM_IOS + GLSLSource.append( + "#version 300 es\n" + "#extension GL_EXT_separate_shader_objects : enable\n" + "#ifndef GL_ES\n" + "# define GL_ES 1\n" + "#endif\n" + + "#define PLATFORM_IOS 1\n" + + "precision highp float;\n" + "precision highp int;\n" + //"precision highp uint;\n" + + "precision highp sampler2D;\n" + "precision highp sampler3D;\n" + "precision highp samplerCube;\n" + "precision highp samplerCubeShadow;\n" + "precision highp sampler2DShadow;\n" + "precision highp sampler2DArray;\n" + "precision highp sampler2DArrayShadow;\n" + + "precision highp isampler2D;\n" + "precision highp isampler3D;\n" + "precision highp isamplerCube;\n" + "precision highp isampler2DArray;\n" + + "precision highp usampler2D;\n" + "precision highp usampler3D;\n" + "precision highp usamplerCube;\n" + "precision highp usampler2DArray;\n" + ); + + // Built-in variable 'gl_Position' must be redeclared before use, with separate shader objects. + if (ShaderType == SHADER_TYPE_VERTEX) + GLSLSource.append("out vec4 gl_Position;\n"); + +#elif PLATFORM_ANDROID + GLSLSource.append( + "#version 310 es\n" + "#extension GL_EXT_texture_cube_map_array : enable\n" + ); + + if (ShaderType == SHADER_TYPE_GEOMETRY) + GLSLSource.append("#extension GL_EXT_geometry_shader : enable\n"); + + if (ShaderType == SHADER_TYPE_HULL || ShaderType == SHADER_TYPE_DOMAIN) + GLSLSource.append("#extension GL_EXT_tessellation_shader : enable\n"); + + GLSLSource.append( + "#ifndef GL_ES\n" + "# define GL_ES 1\n" + "#endif\n" + + "#define PLATFORM_ANDROID 1\n" + + "precision highp float;\n" + "precision highp int;\n" + //"precision highp uint;\n" // This line causes shader compilation error on NVidia! + + "precision highp sampler2D;\n" + "precision highp sampler3D;\n" + "precision highp samplerCube;\n" + "precision highp samplerCubeArray;\n" + "precision highp samplerCubeShadow;\n" + "precision highp samplerCubeArrayShadow;\n" + "precision highp sampler2DShadow;\n" + "precision highp sampler2DArray;\n" + "precision highp sampler2DArrayShadow;\n" + "precision highp sampler2DMS;\n" // ES3.1 + + "precision highp isampler2D;\n" + "precision highp isampler3D;\n" + "precision highp isamplerCube;\n" + "precision highp isamplerCubeArray;\n" + "precision highp isampler2DArray;\n" + "precision highp isampler2DMS;\n" // ES3.1 + + "precision highp usampler2D;\n" + "precision highp usampler3D;\n" + "precision highp usamplerCube;\n" + "precision highp usamplerCubeArray;\n" + "precision highp usampler2DArray;\n" + "precision highp usampler2DMS;\n" // ES3.1 + + "precision highp image2D;\n" + "precision highp image3D;\n" + "precision highp imageCube;\n" + "precision highp image2DArray;\n" + + "precision highp iimage2D;\n" + "precision highp iimage3D;\n" + "precision highp iimageCube;\n" + "precision highp iimage2DArray;\n" + + "precision highp uimage2D;\n" + "precision highp uimage3D;\n" + "precision highp uimageCube;\n" + "precision highp uimage2DArray;\n" + ); +#elif +# error "Undefined platform" +#endif + // It would be much more convenient to use row_major matrices. + // But unfortunatelly on NVIDIA, the following directive + // layout(std140, row_major) uniform; + // does not have any effect on matrices that are part of structures + // So we have to use column-major matrices which are default in both + // DX and GLSL. + GLSLSource.append( + "layout(std140) uniform;\n" + ); + + const Char* ShaderTypeDefine = nullptr; + switch (ShaderType) + { + case SHADER_TYPE_VERTEX: ShaderTypeDefine = "#define VERTEX_SHADER\n"; break; + case SHADER_TYPE_PIXEL: ShaderTypeDefine = "#define FRAGMENT_SHADER\n"; break; + case SHADER_TYPE_GEOMETRY: ShaderTypeDefine = "#define GEOMETRY_SHADER\n"; break; + case SHADER_TYPE_HULL: ShaderTypeDefine = "#define TESS_CONTROL_SHADER\n"; break; + case SHADER_TYPE_DOMAIN: ShaderTypeDefine = "#define TESS_EVALUATION_SHADER\n"; break; + case SHADER_TYPE_COMPUTE: ShaderTypeDefine = "#define COMPUTE_SHADER\n"; break; + default: UNEXPECTED("Shader type is not specified"); + } + GLSLSource += ShaderTypeDefine; + + if (CreationAttribs.Macros != nullptr) + { + auto *pMacro = CreationAttribs.Macros; + while (pMacro->Name != nullptr && pMacro->Definition != nullptr) + { + GLSLSource += "#define "; + GLSLSource += pMacro->Name; + GLSLSource += ' '; + GLSLSource += pMacro->Definition; + GLSLSource += "\n"; + ++pMacro; + } + } + + RefCntAutoPtr<IDataBlob> pFileData(MakeNewRCObj<DataBlobImpl>()(0)); + auto ShaderSource = CreationAttribs.Source; + size_t SourceLen = 0; + if (ShaderSource) + { + SourceLen = strlen(ShaderSource); + } + else + { + VERIFY(CreationAttribs.pShaderSourceStreamFactory, "Input stream factory is null"); + RefCntAutoPtr<IFileStream> pSourceStream; + CreationAttribs.pShaderSourceStreamFactory->CreateInputStream(CreationAttribs.FilePath, &pSourceStream); + if (pSourceStream == nullptr) + LOG_ERROR_AND_THROW("Failed to open shader source file"); + + pSourceStream->Read(pFileData); + ShaderSource = reinterpret_cast<char*>(pFileData->GetDataPtr()); + SourceLen = pFileData->GetSize(); + } + + if (CreationAttribs.SourceLanguage == SHADER_SOURCE_LANGUAGE_HLSL) + { + // Convert HLSL to GLSL + const auto &Converter = HLSL2GLSLConverterImpl::GetInstance(); + HLSL2GLSLConverterImpl::ConversionAttribs Attribs; + Attribs.pSourceStreamFactory = CreationAttribs.pShaderSourceStreamFactory; + Attribs.ppConversionStream = CreationAttribs.ppConversionStream; + Attribs.HLSLSource = ShaderSource; + Attribs.NumSymbols = SourceLen; + Attribs.EntryPoint = CreationAttribs.EntryPoint; + Attribs.ShaderType = CreationAttribs.Desc.ShaderType; + Attribs.IncludeDefinitions = true; + Attribs.InputFileName = CreationAttribs.FilePath; + auto ConvertedSource = Converter.Convert(Attribs); + + GLSLSource.append(ConvertedSource); + } + else + GLSLSource.append(ShaderSource); + + return GLSLSource; +} + +} diff --git a/Graphics/GraphicsEngineOpenGL/CMakeLists.txt b/Graphics/GraphicsEngineOpenGL/CMakeLists.txt index 551b57fb..6b7e2037 100644 --- a/Graphics/GraphicsEngineOpenGL/CMakeLists.txt +++ b/Graphics/GraphicsEngineOpenGL/CMakeLists.txt @@ -161,11 +161,12 @@ set(PRIVATE_DEPENDENCIES Common TargetPlatform GraphicsEngine + GLSLTools ) set(PUBLIC_DEPENDENCIES GraphicsEngineOpenGLInterface - HLSL2GLSLConverterLib + HLSL2GLSLConverterLib ) if(PLATFORM_WIN32) diff --git a/Graphics/GraphicsEngineOpenGL/src/ShaderGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/ShaderGLImpl.cpp index 7b9d93ac..e3a0478a 100644 --- a/Graphics/GraphicsEngineOpenGL/src/ShaderGLImpl.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/ShaderGLImpl.cpp @@ -26,7 +26,7 @@ #include "ShaderGLImpl.h" #include "RenderDeviceGLImpl.h" #include "DataBlobImpl.h" -#include "HLSL2GLSLConverterImpl.h" +#include "GLSLSourceBuilder.h" using namespace Diligent; @@ -38,222 +38,7 @@ ShaderGLImpl::ShaderGLImpl(IReferenceCounters *pRefCounters, RenderDeviceGLImpl m_GlProgObj(false), m_GLShaderObj( false, GLObjectWrappers::GLShaderObjCreateReleaseHelper( GetGLShaderType( m_Desc.ShaderType ) ) ) { - std::vector<const char *> ShaderStrings; - - // Each element in the length array may contain the length of the corresponding string - // (the null character is not counted as part of the string length). - // Not specifying lengths causes shader compilation errors on Android - std::vector<GLint> Lenghts; - - String Settings; - -#if PLATFORM_WIN32 || PLATFORM_LINUX - Settings.append( - "#version 430 core\n" - "#define DESKTOP_GL 1\n" - ); -# if PLATFORM_WIN32 - Settings.append("#define PLATFORM_WIN32 1\n"); -# elif PLATFORM_LINUX - Settings.append("#define PLATFORM_LINUX 1\n"); -# else -# error Unexpected platform -# endif -#elif PLATFORM_MACOS - Settings.append( - "#version 410 core\n" - "#define DESKTOP_GL 1\n" - "#define PLATFORM_MACOS 1\n" - ); -#elif PLATFORM_IOS - Settings.append( - "#version 300 es\n" - "#extension GL_EXT_separate_shader_objects : enable\n" - "#ifndef GL_ES\n" - "# define GL_ES 1\n" - "#endif\n" - - "#define PLATFORM_IOS 1\n" - - "precision highp float;\n" - "precision highp int;\n" - //"precision highp uint;\n" - - "precision highp sampler2D;\n" - "precision highp sampler3D;\n" - "precision highp samplerCube;\n" - "precision highp samplerCubeShadow;\n" - "precision highp sampler2DShadow;\n" - "precision highp sampler2DArray;\n" - "precision highp sampler2DArrayShadow;\n" - - "precision highp isampler2D;\n" - "precision highp isampler3D;\n" - "precision highp isamplerCube;\n" - "precision highp isampler2DArray;\n" - - "precision highp usampler2D;\n" - "precision highp usampler3D;\n" - "precision highp usamplerCube;\n" - "precision highp usampler2DArray;\n" - ); - - // Built-in variable 'gl_Position' must be redeclared before use, with separate shader objects. - if(m_Desc.ShaderType == SHADER_TYPE_VERTEX) - Settings.append("out vec4 gl_Position;\n"); - -#elif PLATFORM_ANDROID - Settings.append( - "#version 310 es\n" - "#extension GL_EXT_texture_cube_map_array : enable\n" - ); - - if(m_Desc.ShaderType == SHADER_TYPE_GEOMETRY) - Settings.append("#extension GL_EXT_geometry_shader : enable\n"); - - if(m_Desc.ShaderType == SHADER_TYPE_HULL || m_Desc.ShaderType == SHADER_TYPE_DOMAIN) - Settings.append("#extension GL_EXT_tessellation_shader : enable\n"); - - Settings.append( - "#ifndef GL_ES\n" - "# define GL_ES 1\n" - "#endif\n" - - "#define PLATFORM_ANDROID 1\n" - - "precision highp float;\n" - "precision highp int;\n" - //"precision highp uint;\n" // This line causes shader compilation error on NVidia! - - "precision highp sampler2D;\n" - "precision highp sampler3D;\n" - "precision highp samplerCube;\n" - "precision highp samplerCubeArray;\n" - "precision highp samplerCubeShadow;\n" - "precision highp samplerCubeArrayShadow;\n" - "precision highp sampler2DShadow;\n" - "precision highp sampler2DArray;\n" - "precision highp sampler2DArrayShadow;\n" - "precision highp sampler2DMS;\n" // ES3.1 - - "precision highp isampler2D;\n" - "precision highp isampler3D;\n" - "precision highp isamplerCube;\n" - "precision highp isamplerCubeArray;\n" - "precision highp isampler2DArray;\n" - "precision highp isampler2DMS;\n" // ES3.1 - - "precision highp usampler2D;\n" - "precision highp usampler3D;\n" - "precision highp usamplerCube;\n" - "precision highp usamplerCubeArray;\n" - "precision highp usampler2DArray;\n" - "precision highp usampler2DMS;\n" // ES3.1 - - "precision highp image2D;\n" - "precision highp image3D;\n" - "precision highp imageCube;\n" - "precision highp image2DArray;\n" - - "precision highp iimage2D;\n" - "precision highp iimage3D;\n" - "precision highp iimageCube;\n" - "precision highp iimage2DArray;\n" - - "precision highp uimage2D;\n" - "precision highp uimage3D;\n" - "precision highp uimageCube;\n" - "precision highp uimage2DArray;\n" - ); -#elif -# error "Undefined platform" -#endif - // It would be much more convenient to use row_major matrices. - // But unfortunatelly on NVIDIA, the following directive - // layout(std140, row_major) uniform; - // does not have any effect on matrices that are part of structures - // So we have to use column-major matrices which are default in both - // DX and GLSL. - Settings.append( - "layout(std140) uniform;\n" - ); - - ShaderStrings.push_back(Settings.c_str()); - Lenghts.push_back( static_cast<GLint>( Settings.length() ) ); - - const Char* ShaderTypeDefine = nullptr; - switch( m_Desc.ShaderType ) - { - case SHADER_TYPE_VERTEX: ShaderTypeDefine = "#define VERTEX_SHADER\n"; break; - case SHADER_TYPE_PIXEL: ShaderTypeDefine = "#define FRAGMENT_SHADER\n"; break; - case SHADER_TYPE_GEOMETRY: ShaderTypeDefine = "#define GEOMETRY_SHADER\n"; break; - case SHADER_TYPE_HULL: ShaderTypeDefine = "#define TESS_CONTROL_SHADER\n"; break; - case SHADER_TYPE_DOMAIN: ShaderTypeDefine = "#define TESS_EVALUATION_SHADER\n";break; - case SHADER_TYPE_COMPUTE: ShaderTypeDefine = "#define COMPUTE_SHADER\n"; break; - default: UNEXPECTED("Shader type is not specified"); - } - ShaderStrings.push_back( ShaderTypeDefine ); - Lenghts.push_back( static_cast<GLint>( strlen(ShaderTypeDefine) ) ); - - String UserDefines; - if( CreationAttribs.Macros != nullptr) - { - auto *pMacro = CreationAttribs.Macros; - while( pMacro->Name != nullptr && pMacro->Definition != nullptr ) - { - UserDefines += "#define "; - UserDefines += pMacro->Name; - UserDefines += ' '; - UserDefines += pMacro->Definition; - UserDefines += "\n"; - ++pMacro; - } - ShaderStrings.push_back( UserDefines.c_str() ); - Lenghts.push_back( static_cast<GLint>( UserDefines.length() ) ); - } - - RefCntAutoPtr<IDataBlob> pFileData(MakeNewRCObj<DataBlobImpl>()(0)); - auto ShaderSource = CreationAttribs.Source; - GLuint SourceLen = 0; - if( ShaderSource ) - { - SourceLen = (GLint)strlen(ShaderSource); - } - else - { - VERIFY(CreationAttribs.pShaderSourceStreamFactory, "Input stream factory is null"); - RefCntAutoPtr<IFileStream> pSourceStream; - CreationAttribs.pShaderSourceStreamFactory->CreateInputStream( CreationAttribs.FilePath, &pSourceStream ); - if (pSourceStream == nullptr) - LOG_ERROR_AND_THROW("Failed to open shader source file"); - - pSourceStream->Read( pFileData ); - ShaderSource = reinterpret_cast<char*>(pFileData->GetDataPtr()); - SourceLen = static_cast<GLint>( pFileData->GetSize() ); - } - - String ConvertedSource; - if( CreationAttribs.SourceLanguage == SHADER_SOURCE_LANGUAGE_HLSL ) - { - // Convert HLSL to GLSL - const auto &Converter = HLSL2GLSLConverterImpl::GetInstance(); - HLSL2GLSLConverterImpl::ConversionAttribs Attribs; - Attribs.pSourceStreamFactory = CreationAttribs.pShaderSourceStreamFactory; - Attribs.ppConversionStream = CreationAttribs.ppConversionStream; - Attribs.HLSLSource = ShaderSource; - Attribs.NumSymbols = SourceLen; - Attribs.EntryPoint = CreationAttribs.EntryPoint; - Attribs.ShaderType = CreationAttribs.Desc.ShaderType; - Attribs.IncludeDefinitions = true; - Attribs.InputFileName = CreationAttribs.FilePath; - ConvertedSource = Converter.Convert(Attribs); - - ShaderSource = ConvertedSource.c_str(); - SourceLen = static_cast<GLint>( ConvertedSource.length() ); - } - - ShaderStrings.push_back( ShaderSource ); - Lenghts.push_back( SourceLen ); + auto GLSLSource = BuildGLSLSourceString(CreationAttribs); // Note: there is a simpler way to create the program: //m_uiShaderSeparateProg = glCreateShaderProgramv(GL_VERTEX_SHADER, _countof(ShaderStrings), ShaderStrings); @@ -268,11 +53,15 @@ ShaderGLImpl::ShaderGLImpl(IReferenceCounters *pRefCounters, RenderDeviceGLImpl // Create empty shader object auto GLShaderType = GetGLShaderType(m_Desc.ShaderType); GLObjectWrappers::GLShaderObj ShaderObj(true, GLObjectWrappers::GLShaderObjCreateReleaseHelper(GLShaderType)); - - VERIFY( ShaderStrings.size() == Lenghts.size(), "Incosistent array size" ); + + // Each element in the length array may contain the length of the corresponding string + // (the null character is not counted as part of the string length). + // Not specifying lengths causes shader compilation errors on Android + const char * ShaderStrings[] = { GLSLSource.c_str() }; + GLint Lenghts[] = { static_cast<GLint>(GLSLSource.length()) }; // Provide source strings (the strings will be saved in internal OpenGL memory) - glShaderSource(ShaderObj, static_cast<GLuint>( ShaderStrings.size() ), ShaderStrings.data(), Lenghts.data() ); + glShaderSource(ShaderObj, _countof(ShaderStrings), ShaderStrings, Lenghts ); // When the shader is compiled, it will be compiled as if all of the given strings were concatenated end-to-end. glCompileShader(ShaderObj); GLint compiled = GL_FALSE; diff --git a/Graphics/GraphicsEngineVulkan/CMakeLists.txt b/Graphics/GraphicsEngineVulkan/CMakeLists.txt index bf8a78ea..5d417d8a 100644 --- a/Graphics/GraphicsEngineVulkan/CMakeLists.txt +++ b/Graphics/GraphicsEngineVulkan/CMakeLists.txt @@ -158,6 +158,7 @@ set(PRIVATE_DEPENDENCIES Common TargetPlatform GraphicsEngine + GLSLTools ) if(PLATFORM_WIN32) diff --git a/Graphics/GraphicsEngineVulkan/include/ShaderVkImpl.h b/Graphics/GraphicsEngineVulkan/include/ShaderVkImpl.h index 904ae379..4bd9d43d 100644 --- a/Graphics/GraphicsEngineVulkan/include/ShaderVkImpl.h +++ b/Graphics/GraphicsEngineVulkan/include/ShaderVkImpl.h @@ -47,7 +47,7 @@ class ShaderVkImpl : public ShaderBase<IShaderVk, IRenderDeviceVk> public: typedef ShaderBase<IShaderVk, IRenderDeviceVk> TShaderBase; - ShaderVkImpl(IReferenceCounters *pRefCounters, class RenderDeviceVkImpl *pRenderDeviceVk, const ShaderCreationAttribs &ShaderCreationAttribs); + ShaderVkImpl(IReferenceCounters *pRefCounters, class RenderDeviceVkImpl *pRenderDeviceVk, const ShaderCreationAttribs &CreationAttribs); ~ShaderVkImpl(); //virtual void QueryInterface( const Diligent::INTERFACE_ID &IID, IObject **ppInterface )override; diff --git a/Graphics/GraphicsEngineVulkan/src/ShaderVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/ShaderVkImpl.cpp index 0b96448c..d012b1bc 100644 --- a/Graphics/GraphicsEngineVulkan/src/ShaderVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/ShaderVkImpl.cpp @@ -26,6 +26,8 @@ #include "ShaderVkImpl.h" #include "RenderDeviceVkImpl.h" #include "DataBlobImpl.h" +#include "GLSLSourceBuilder.h" +#include "GLSL2SPIRV.h" //#include "D3DShaderResourceLoader.h" using namespace Diligent; @@ -34,13 +36,19 @@ namespace Diligent { -ShaderVkImpl::ShaderVkImpl(IReferenceCounters *pRefCounters, RenderDeviceVkImpl *pRenderDeviceVk, const ShaderCreationAttribs &ShaderCreationAttribs) : - TShaderBase(pRefCounters, pRenderDeviceVk, ShaderCreationAttribs.Desc)/*, +ShaderVkImpl::ShaderVkImpl(IReferenceCounters *pRefCounters, RenderDeviceVkImpl *pRenderDeviceVk, const ShaderCreationAttribs &CreationAttribs) : + TShaderBase(pRefCounters, pRenderDeviceVk, CreationAttribs.Desc)/*, ShaderD3DBase(ShaderCreationAttribs), m_StaticResLayout(*this, GetRawAllocator()), m_DummyShaderVar(*this), m_ConstResCache(ShaderResourceCacheVk::DbgCacheContentType::StaticShaderResources)*/ { + auto GLSLSource = BuildGLSLSourceString(CreationAttribs); + auto SPIRV = GLSLtoSPIRV(m_Desc.ShaderType, GLSLSource.c_str()); + if(SPIRV.empty()) + { + LOG_ERROR_AND_THROW("Failed to compile shader"); + } /* // Load shader resources auto &Allocator = GetRawAllocator(); diff --git a/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanInstance.cpp b/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanInstance.cpp index a47c0ec0..a8e34a82 100644 --- a/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanInstance.cpp +++ b/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanInstance.cpp @@ -26,6 +26,7 @@ #include "VulkanErrors.h" #include "VulkanUtilities/VulkanInstance.h" #include "VulkanUtilities/VulkanDebug.h" +#include "GLSL2SPIRV.h" namespace VulkanUtilities { @@ -186,6 +187,8 @@ namespace VulkanUtilities CHECK_VK_ERROR(err, "Failed to enumerate physical devices"); VERIFY_EXPR(m_PhysicalDevices.size() == PhysicalDeviceCount); } + + Diligent::InitializeGlslang(); } VulkanInstance::~VulkanInstance() @@ -195,6 +198,8 @@ namespace VulkanUtilities VulkanUtilities::FreeDebugCallback(m_VkInstance); } vkDestroyInstance(m_VkInstance, m_pVkAllocator); + + Diligent::FinalizeGlslang(); } VkPhysicalDevice VulkanInstance::SelectPhysicalDevice() diff --git a/Graphics/HLSL2GLSLConverterLib/include/GLSLDefinitions.h b/Graphics/HLSL2GLSLConverterLib/include/GLSLDefinitions.h index 2f9b6ead..8fb4fd70 100644 --- a/Graphics/HLSL2GLSLConverterLib/include/GLSLDefinitions.h +++ b/Graphics/HLSL2GLSLConverterLib/include/GLSLDefinitions.h @@ -236,18 +236,6 @@ bool4 isfinite( vec4 f4 ) return bool4( isfinite( f4.xyz ), isfinite( f4.w ) ); } -#ifndef GL_ES - float noise( float x ){ return noise1( x ); } - vec2 noise( vec2 x ){ return noise2( x ); } - vec3 noise( vec3 x ){ return noise3( x ); } - vec4 noise( vec4 x ){ return noise4( x ); } -#else - float noise( float x ){ return 0.0; } - vec2 noise( vec2 x ){ return vec2(0.0, 0.0); } - vec3 noise( vec3 x ){ return vec3(0.0, 0.0, 0.0); } - vec4 noise( vec4 x ){ return vec4(0.0, 0.0, 0.0, 0.0); } -#endif - float log10( float x ) { return log( x ) / log( 10.0 ); diff --git a/Graphics/HLSL2GLSLConverterLib/include/GLSLDefinitions_inc.h b/Graphics/HLSL2GLSLConverterLib/include/GLSLDefinitions_inc.h index 48bb7060..cdbc0527 100644 --- a/Graphics/HLSL2GLSLConverterLib/include/GLSLDefinitions_inc.h +++ b/Graphics/HLSL2GLSLConverterLib/include/GLSLDefinitions_inc.h @@ -236,18 +236,6 @@ " return bool4( isfinite( f4.xyz ), isfinite( f4.w ) );\n" "}\n" "\n" -"#ifndef GL_ES\n" -" float noise( float x ){ return noise1( x ); }\n" -" vec2 noise( vec2 x ){ return noise2( x ); }\n" -" vec3 noise( vec3 x ){ return noise3( x ); }\n" -" vec4 noise( vec4 x ){ return noise4( x ); }\n" -"#else\n" -" float noise( float x ){ return 0.0; }\n" -" vec2 noise( vec2 x ){ return vec2(0.0, 0.0); }\n" -" vec3 noise( vec3 x ){ return vec3(0.0, 0.0, 0.0); }\n" -" vec4 noise( vec4 x ){ return vec4(0.0, 0.0, 0.0, 0.0); }\n" -"#endif\n" -"\n" "float log10( float x )\n" "{\n" " return log( x ) / log( 10.0 );\n" |
