summaryrefslogtreecommitdiffstats
path: root/Graphics/GLSLTools
diff options
context:
space:
mode:
authorEgor Yusov <egor.yusov@gmail.com>2018-04-15 04:08:00 +0000
committerEgor Yusov <egor.yusov@gmail.com>2018-04-15 04:08:00 +0000
commita47df897d30a8fdacc28235ab708ac4b28748eae (patch)
treea5c266a835b56a519388253abcd4a19b642db589 /Graphics/GLSLTools
parentAdded glslang to the project (diff)
downloadDiligentCore-a47df897d30a8fdacc28235ab708ac4b28748eae.tar.gz
DiligentCore-a47df897d30a8fdacc28235ab708ac4b28748eae.zip
Added GLSL to SPIRV shader compilation
Diffstat (limited to 'Graphics/GLSLTools')
-rw-r--r--Graphics/GLSLTools/CMakeLists.txt60
-rw-r--r--Graphics/GLSLTools/include/GLSL2SPIRV.h35
-rw-r--r--Graphics/GLSLTools/include/GLSLSourceBuilder.h34
-rw-r--r--Graphics/GLSLTools/src/GLSL2SPIRV.cpp228
-rw-r--r--Graphics/GLSLTools/src/GLSLSourceBuilder.cpp242
5 files changed, 599 insertions, 0 deletions
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;
+}
+
+}