Added original glslang_c_interface implementation by Viktor Latypov
authorSergey Kosarevsky <sk@linderdaum.com>
Tue, 24 Dec 2019 20:53:05 +0000 (23:53 +0300)
committerSergey Kosarevsky <sk@linderdaum.com>
Tue, 24 Dec 2019 20:53:05 +0000 (23:53 +0300)
glslang/CInterface/glslang_c_interface.cpp [new file with mode: 0644]
glslang/Include/c_shader_types.h [new file with mode: 0644]
glslang/Include/glslang_c_interface.h [new file with mode: 0644]

diff --git a/glslang/CInterface/glslang_c_interface.cpp b/glslang/CInterface/glslang_c_interface.cpp
new file mode 100644 (file)
index 0000000..9923d55
--- /dev/null
@@ -0,0 +1,502 @@
+/**
+BSD 2-Clause License
+
+Copyright (c) 2019, Viktor Latypov
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+   list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright notice,
+   this list of conditions and the following disclaimer in the documentation
+   and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+**/
+
+#include "glslang_c_interface.h"
+
+#include "glslang/Include/ShHandle.h"
+#include "StandAlone/DirStackFileIncluder.h"
+#include "StandAlone/ResourceLimits.h"
+#include "SPIRV/Logger.h"
+#include "SPIRV/SpvTools.h"
+#include "SPIRV/GlslangToSpv.h"
+
+#include "glslang/Include/ResourceLimits.h"
+#include "glslang/MachineIndependent/Versions.h"
+
+typedef struct glslang_shader_s
+{
+       glslang::TShader* shader;
+       std::string preprocessedGLSL;
+} glslang_shader_t;
+
+typedef struct glslang_program_s
+{
+       glslang::TProgram* program;
+       std::vector<unsigned int> spirv;
+       std::string loggerMessages;
+} glslang_program_t;
+
+/* Wrapper/Adapter for C glsl_include_callbacks_t functions
+
+   This class contains a 'glsl_include_callbacks_t' structure
+   with C include_local/include_system callback pointers.
+
+   This class implement TShader::Includer interface
+   by redirecting C++ virtual methods to C callbacks.
+
+   The 'IncludeResult' instances produced by this Includer
+   contain a reference to glsl_include_result_t C structure
+   to allow its lifetime management by another C callback
+   (CallbackIncluder::callbacks::free_include_result)
+*/
+class CallbackIncluder: public glslang::TShader::Includer
+{
+public:
+       /* Wrapper of IncludeResult which stores a glsl_include_result object internally */
+       class CallbackIncludeResult: public glslang::TShader::Includer::IncludeResult
+       {
+       public:
+               CallbackIncludeResult(const std::string& headerName,
+                       const char* const headerData,
+                       const size_t headerLength,
+                       void* userData,
+                       glsl_include_result_t* includeResult):
+                               glslang::TShader::Includer::IncludeResult(
+                                       headerName, headerData, headerLength, userData),
+                               includeResult(includeResult)
+               {}
+
+               virtual ~CallbackIncludeResult() {}
+       protected:
+               friend class CallbackIncluder;
+
+               glsl_include_result_t* includeResult;
+       };
+public:
+       CallbackIncluder(glsl_include_callbacks_t _callbacks, void *_context):
+               callbacks(_callbacks),
+               context(_context)
+       {}
+
+       virtual ~CallbackIncluder() {}
+
+        virtual IncludeResult* includeSystem(const char* headerName,
+                                             const char* includerName,
+                                             size_t inclusionDepth) override
+       {
+               if (this->callbacks.include_system)
+               {
+                       glsl_include_result_t* result =
+                               this->callbacks.include_system(
+                                       this->context,
+                                       headerName,
+                                       includerName,
+                                       inclusionDepth);
+
+                       return new CallbackIncludeResult(
+                               std::string(headerName),
+                               result->header_data,
+                               result->header_length,
+                               nullptr,
+                               result
+                       );
+               }
+
+               return glslang::TShader::Includer::includeSystem(
+                       headerName, includerName, inclusionDepth);
+       }
+
+        virtual IncludeResult* includeLocal(const char* headerName,
+                                            const char* includerName,
+                                            size_t inclusionDepth) override
+       {
+               if (this->callbacks.include_local)
+               {
+                       glsl_include_result_t* result =
+                               this->callbacks.include_local(
+                                       this->context,
+                                       headerName,
+                                       includerName,
+                                       inclusionDepth);
+
+                       return new CallbackIncludeResult(
+                               std::string(headerName),
+                               result->header_data,
+                               result->header_length,
+                               nullptr,
+                               result
+                       );
+               }
+
+               return glslang::TShader::Includer::includeLocal(
+                       headerName, includerName, inclusionDepth);
+       }
+
+       /* This function only calls free_include_result callback
+          when the IncludeResult instance is allocated by a C function */
+       virtual void releaseInclude(IncludeResult* result) override
+       {
+               if (result == nullptr)
+                       return;
+
+               if (this->callbacks.free_include_result && (result->userData == nullptr))
+               {
+                       CallbackIncludeResult* innerResult = static_cast<CallbackIncludeResult *>(result);
+                       /* use internal free() function */
+                       this->callbacks.free_include_result(this->context, innerResult->includeResult);
+                       /* ignore internal fields of TShader::Includer::IncludeResult */
+                       delete result;
+                       return;
+               }
+
+               delete [] static_cast<char*>(result->userData);
+               delete result;
+       }
+private:
+       CallbackIncluder() {}
+
+       /* C callback pointers */
+       glsl_include_callbacks_t callbacks;
+       /* User-defined context */
+       void *context;
+};
+
+int  glslang_initialize_process()
+{
+       return static_cast<int>(glslang::InitializeProcess());
+}
+
+void glslang_finalize_process()
+{
+       glslang::FinalizeProcess();
+}
+
+static EShLanguage c_shader_stage(glslang_stage_t stage)
+{
+       switch(stage)
+       {
+               case SH_STAGE_VERTEX:
+                       return EShLangVertex;
+               case SH_STAGE_TESSCONTROL:
+                       return EShLangTessControl;
+               case SH_STAGE_TESSEVALUATION:
+                       return EShLangTessEvaluation;
+               case SH_STAGE_GEOMETRY:
+                       return EShLangGeometry;
+               case SH_STAGE_FRAGMENT:
+                       return EShLangFragment;
+               case SH_STAGE_COMPUTE:
+                       return EShLangCompute;
+               case SH_STAGE_RAYGEN_NV:
+                       return EShLangRayGenNV;
+               case SH_STAGE_INTERSECT_NV:
+                       return EShLangIntersectNV;
+               case SH_STAGE_ANYHIT_NV:
+                       return EShLangAnyHitNV;
+               case SH_STAGE_CLOSESTHIT_NV:
+                       return EShLangClosestHitNV;
+               case SH_STAGE_MISS_NV:
+                       return EShLangMissNV;
+               case SH_STAGE_CALLABLE_NV:
+                       return EShLangCallableNV;
+               case SH_STAGE_TASK_NV:
+                       return EShLangTaskNV;
+               case SH_STAGE_MESH_NV:
+                       return EShLangMeshNV;
+               default:
+                       break;
+       }
+       return EShLangCount;
+}
+
+static EShMessages c_shader_messages(glslang_messages_t messages)
+{
+       switch(messages)
+       {
+               case SH_MSG_RELAXED_ERRORS:
+                       return EShMsgRelaxedErrors;
+               case SH_MSG_SUPPRESS_WARNINGS:
+                       return EShMsgSuppressWarnings;
+               case SH_MSG_AST:
+                       return EShMsgAST;
+               case SH_MSG_SPV_RULES:
+                       return EShMsgSpvRules;
+               case SH_MSG_VULKAN_RULES:
+                       return EShMsgVulkanRules;
+               case SH_MSG_ONLY_PREPROCESSOR:
+                       return EShMsgOnlyPreprocessor;
+               case SH_MSG_READ_HLSL:
+                       return EShMsgReadHlsl;
+               case SH_MSG_CASCADING_ERRORS:
+                       return EShMsgCascadingErrors;
+               case SH_MSG_KEEP_UNCALLED:
+                       return EShMsgKeepUncalled;
+               case SH_MSG_HLSL_OFFSETS:
+                       return EShMsgHlslOffsets;
+               case SH_MSG_DEBUG_INFO:
+                       return EShMsgDebugInfo;
+               case SH_MSG_HLSL_ENABLE_16BIT_TYPES:
+                       return EShMsgHlslEnable16BitTypes;
+               case SH_MSG_HLSL_LEGALIZATION:
+                       return EShMsgHlslLegalization;
+               case SH_MSG_HLSL_DX9_COMPATIBLE:
+                       return EShMsgHlslDX9Compatible;
+               case SH_MSG_BUILTIN_SYMBOL_TABLE:
+                       return EShMsgBuiltinSymbolTable;
+               default:
+                       break;
+       }
+       return EShMsgDefault;
+}
+
+static glslang::EShTargetLanguageVersion c_shader_target_language_version(glslang_target_language_version_t target_language_version)
+{
+       switch(target_language_version)
+       {
+               case SH_TARGET_SPV_1_0:
+                       return glslang::EShTargetSpv_1_0;
+               case SH_TARGET_SPV_1_1:
+                       return glslang::EShTargetSpv_1_1;
+               case SH_TARGET_SPV_1_2:
+                       return glslang::EShTargetSpv_1_2;
+               case SH_TARGET_SPV_1_3:
+                       return glslang::EShTargetSpv_1_3;
+               case SH_TARGET_SPV_1_4:
+                       return glslang::EShTargetSpv_1_4;
+               case SH_TARGET_SPV_1_5:
+                       return glslang::EShTargetSpv_1_5;
+               default:
+                       break;
+       }
+       return glslang::EShTargetSpv_1_0;
+}
+
+static glslang::EShClient c_shader_client(glslang_client_t client)
+{
+       switch(client)
+       {
+       case SH_CLIENT_VULKAN:
+               return glslang::EShClientVulkan;
+       case SH_CLIENT_OPENGL:
+               return glslang::EShClientOpenGL;
+       default:
+               break;
+       }
+
+       return glslang::EShClientNone;
+}
+
+static glslang::EShTargetClientVersion c_shader_client_version(glslang_target_client_version_t client_version)
+{
+       switch(client_version)
+       {
+               case SH_TARGET_VULKAN_1_1:
+                       return glslang::EShTargetVulkan_1_1;
+               case SH_TARGET_OPENGL_450:
+                       return glslang::EShTargetOpenGL_450;
+               default:
+                       break;
+       }
+
+       return glslang::EShTargetVulkan_1_0;
+}
+
+static glslang::EShTargetLanguage c_shader_target_language(glslang_target_language_t target_language)
+{
+       if (target_language == SH_TARGET_NONE)
+               return glslang::EShTargetNone;
+
+       return glslang::EShTargetSpv;
+}
+
+static glslang::EShSource c_shader_source(glslang_source_t source)
+{
+       switch(source)
+       {
+               case SH_SOURCE_GLSL:
+                       return glslang::EShSourceGlsl;
+               case SH_SOURCE_HLSL:
+                       return glslang::EShSourceHlsl;
+               default:
+                       break;
+       }
+
+       return glslang::EShSourceNone;
+}
+
+static EProfile c_shader_profile(glslang_profile_t profile)
+{
+       switch(profile)
+       {
+               case SH_BAD_PROFILE:
+                       return EBadProfile;
+               case SH_NO_PROFILE:
+                       return ENoProfile;
+               case SH_CORE_PROFILE:
+                       return ECoreProfile;
+               case SH_COMPATIBILITY_PROFILE:
+                       return ECompatibilityProfile;
+               case SH_ES_PROFILE:
+                       return EEsProfile;
+       }
+
+       return EProfile();
+}
+
+glslang_shader_t *glslang_shader_create(glslang_input_t *input)
+{
+       if ( !input || !input->code )
+       {
+               printf("Error creating shader: null input(%p)/input->code\n", input);
+
+               if (input)
+                       printf("input->code = %p\n", input->code);
+
+               return nullptr;
+       }
+
+       glslang_shader_t *shader = new glslang_shader_t();
+
+       shader->shader = new glslang::TShader( c_shader_stage(input->stage) );
+       shader->shader->setStrings( &input->code, 1 );
+       shader->shader->setEnvInput( c_shader_source(input->language), c_shader_stage(input->stage), c_shader_client(input->client), input->default_version );
+       shader->shader->setEnvClient( c_shader_client(input->client), c_shader_client_version(input->client_version) );
+       shader->shader->setEnvTarget( c_shader_target_language(input->target_language), c_shader_target_language_version(input->target_language_version) );
+
+       return shader;
+}
+
+const char* glslang_shader_get_preprocessed_code(glslang_shader_t* shader)
+{
+       return shader->preprocessedGLSL.c_str();
+}
+
+int  glslang_shader_preprocess(glslang_shader_t* shader, glslang_input_t* i)
+{
+       DirStackFileIncluder Includer;
+       /* TODO: use custom callbacks if they are available in 'i->callbacks' */
+       return shader->shader->preprocess(
+               /* No user-defined resources limit */
+               &glslang::DefaultTBuiltInResource,
+               i->default_version,
+               c_shader_profile(i->default_profile),
+               (bool)i->force_default_version_and_profile,
+               (bool)i->forward_compatible,
+               c_shader_messages(i->messages),
+               &shader->preprocessedGLSL,
+               Includer
+       );
+}
+
+int glslang_shader_parse(glslang_shader_t *shader, glslang_input_t *input)
+{
+       const char* preprocessedCStr = shader->preprocessedGLSL.c_str();
+       shader->shader->setStrings( &preprocessedCStr, 1 );
+
+       return shader->shader->parse(
+               /* No user-defined resource limits for now */
+               &glslang::DefaultTBuiltInResource,
+               input->default_version,
+               (bool)input->forward_compatible,
+               c_shader_messages(input->messages)
+       );
+}
+
+const char* glslang_shader_get_info_log(glslang_shader_t *shader)
+{
+       return shader->shader->getInfoLog();
+}
+
+const char* glslang_shader_get_info_debug_log(glslang_shader_t *shader)
+{
+       return shader->shader->getInfoDebugLog();
+}
+
+void glslang_shader_delete(glslang_shader_t *shader)
+{
+       if (!shader)
+               return;
+
+       delete(shader->shader);
+       delete(shader);
+}
+
+glslang_program_t *glslang_program_create()
+{
+       glslang_program_t *p = new glslang_program_t();
+       p->program = new glslang::TProgram();
+       return p;
+}
+
+void glslang_program_SPIRV_generate(glslang_program_t *program, glslang_stage_t stage )
+{
+       spv::SpvBuildLogger logger;
+       glslang::SpvOptions spvOptions;
+       spvOptions.validate = true;
+
+       const glslang::TIntermediate* intermediate = program->program->getIntermediate( c_shader_stage(stage) );
+
+       glslang::GlslangToSpv( *intermediate, program->spirv, &logger, &spvOptions );
+
+       program->loggerMessages = logger.getAllMessages();
+}
+
+size_t glslang_program_SPIRV_get_size(glslang_program_t *program)
+{
+       return program->spirv.size();
+}
+
+void glslang_program_SPIRV_get(glslang_program_t *program, unsigned int* out)
+{
+       memcpy( out, program->spirv.data(), program->spirv.size() * sizeof( unsigned int ) );
+}
+
+const char* glslang_program_SPIRV_get_messages(glslang_program_t *program)
+{
+       return program->loggerMessages.empty() ? nullptr : program->loggerMessages.c_str();
+}
+
+void glslang_program_delete(glslang_program_t *program)
+{
+       if (!program)
+               return;
+
+       delete(program->program);
+       delete(program);
+}
+
+void glslang_program_add_shader(glslang_program_t *program, glslang_shader_t *shader)
+{
+       program->program->addShader(shader->shader);
+}
+
+int glslang_program_link(glslang_program_t *program, int messages)
+{
+       return (int)program->program->link((EShMessages)messages);
+}
+
+const char* glslang_program_get_info_log(glslang_program_t *program)
+{
+       return program->program->getInfoLog();
+}
+
+const char* glslang_program_get_info_debug_log(glslang_program_t *program)
+{
+       return program->program->getInfoDebugLog();
+}
+
diff --git a/glslang/Include/c_shader_types.h b/glslang/Include/c_shader_types.h
new file mode 100644 (file)
index 0000000..563e990
--- /dev/null
@@ -0,0 +1,168 @@
+/**
+BSD 2-Clause License
+
+Copyright (c) 2019, Viktor Latypov
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+   list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright notice,
+   this list of conditions and the following disclaimer in the documentation
+   and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+**/
+
+#ifndef C_SHADER_TYPES_H_INCLUDED
+#define C_SHADER_TYPES_H_INCLUDED
+
+/* EShLanguage counterpart */
+typedef enum {
+    SH_STAGE_VERTEX,
+    SH_STAGE_TESSCONTROL,
+    SH_STAGE_TESSEVALUATION,
+    SH_STAGE_GEOMETRY,
+    SH_STAGE_FRAGMENT,
+    SH_STAGE_COMPUTE,
+    SH_STAGE_RAYGEN_NV,
+    SH_STAGE_INTERSECT_NV,
+    SH_STAGE_ANYHIT_NV,
+    SH_STAGE_CLOSESTHIT_NV,
+    SH_STAGE_MISS_NV,
+    SH_STAGE_CALLABLE_NV,
+    SH_STAGE_TASK_NV,
+    SH_STAGE_MESH_NV,
+    SH_STAGE_COUNT,
+} glslang_stage_t;         // would be better as stage, but this is ancient now
+
+/* EShLanguageMask counterpart */
+typedef enum {
+    SH_STAGE_VERTEX_MASK          = (1 << SH_STAGE_VERTEX),
+    SH_STAGE_TESSCONTROL_MASK     = (1 << SH_STAGE_TESSCONTROL),
+    SH_STAGE_TESSEVALUATION_MASK  = (1 << SH_STAGE_TESSEVALUATION),
+    SH_STAGE_GEOMETRY_MASK        = (1 << SH_STAGE_GEOMETRY),
+    SH_STAGE_FRAGMENT_MASK        = (1 << SH_STAGE_FRAGMENT),
+    SH_STAGE_COMPUTE_MASK         = (1 << SH_STAGE_COMPUTE),
+    SH_STAGE_RAYGEN_NV_MASK       = (1 << SH_STAGE_RAYGEN_NV),
+    SH_STAGE_INTERSECT_NV_MASK    = (1 << SH_STAGE_INTERSECT_NV),
+    SH_STAGE_ANYHIT_NV_MASK       = (1 << SH_STAGE_ANYHIT_NV),
+    SH_STAGE_CLOSESTHIT_NV_MASK   = (1 << SH_STAGE_CLOSESTHIT_NV),
+    SH_STAGE_MISS_NV_MASK         = (1 << SH_STAGE_MISS_NV),
+    SH_STAGE_CALLABLE_NV_MASK     = (1 << SH_STAGE_CALLABLE_NV),
+    SH_STAGE_TASK_NV_MASK         = (1 << SH_STAGE_TASK_NV),
+    SH_STAGE_MESH_NV_MASK         = (1 << SH_STAGE_MESH_NV),
+} glslang_stage_mask_t;
+
+/* EShSource counterpart */
+typedef enum {
+    SH_SOURCE_NONE,
+    SH_SOURCE_GLSL,
+    SH_SOURCE_HLSL,
+} glslang_source_t;
+
+/* EShClient counterpart */
+typedef enum {
+    SH_CLIENT_NONE,
+    SH_CLIENT_VULKAN,
+    SH_CLIENT_OPENGL,
+} glslang_client_t;
+
+/* EShTargetLanguage counterpart */
+typedef enum {
+    SH_TARGET_NONE,
+    SH_TARGET_SPV,
+} glslang_target_language_t;
+
+/* SH_TARGET_ClientVersion counterpart */
+typedef enum {
+    SH_TARGET_VULKAN_1_0 = (1 << 22),
+    SH_TARGET_VULKAN_1_1 = (1 << 22) | (1 << 12),
+    SH_TARGET_OPENGL_450 = 450,
+} glslang_target_client_version_t;
+
+/* SH_TARGET_LanguageVersion counterpart */
+typedef enum {
+    SH_TARGET_SPV_1_0 = (1 << 16),
+    SH_TARGET_SPV_1_1 = (1 << 16) | (1 << 8),
+    SH_TARGET_SPV_1_2 = (1 << 16) | (2 << 8),
+    SH_TARGET_SPV_1_3 = (1 << 16) | (3 << 8),
+    SH_TARGET_SPV_1_4 = (1 << 16) | (4 << 8),
+    SH_TARGET_SPV_1_5 = (1 << 16) | (5 << 8),
+} glslang_target_language_version_t;
+
+/* EShExecutable counterpart */
+typedef enum {
+    SH_EX_VERTEX_FRAGMENT,
+    SH_EX_FRAGMENT
+} glslang_executable_t;
+
+/* EShOptimizationLevel counterpart  */
+typedef enum {
+    SH_OPT_NO_GENERATION,
+    SH_OPT_NONE,
+    SH_OPT_SIMPLE,
+    SH_OPT_FULL,
+} glslang_optimization_level_t;
+
+/* EShTextureSamplerTransformMode counterpart */
+typedef enum {
+    SH_TEX_SAMP_TRANS_KEEP,
+    SH_TEX_SAMP_TRANS_UPGRADE_TEXTURE_REMOVE_SAMPLER,
+} glslang_texture_sampler_transform_mode_t;
+
+/* EShMessages counterpart */
+typedef enum {
+    SH_MSG_DEFAULT                 = 0,
+    SH_MSG_RELAXED_ERRORS          = (1 << 0),
+    SH_MSG_SUPPRESS_WARNINGS       = (1 << 1),
+    SH_MSG_AST                     = (1 << 2),
+    SH_MSG_SPV_RULES               = (1 << 3),
+    SH_MSG_VULKAN_RULES            = (1 << 4),
+    SH_MSG_ONLY_PREPROCESSOR       = (1 << 5),
+    SH_MSG_READ_HLSL               = (1 << 6),
+    SH_MSG_CASCADING_ERRORS        = (1 << 7),
+    SH_MSG_KEEP_UNCALLED           = (1 << 8),
+    SH_MSG_HLSL_OFFSETS            = (1 << 9),
+    SH_MSG_DEBUG_INFO              = (1 << 10),
+    SH_MSG_HLSL_ENABLE_16BIT_TYPES = (1 << 11),
+    SH_MSG_HLSL_LEGALIZATION       = (1 << 12),
+    SH_MSG_HLSL_DX9_COMPATIBLE     = (1 << 13),
+    SH_MSG_BUILTIN_SYMBOL_TABLE    = (1 << 14),
+} glslang_messages_t;
+
+/* EShReflectionOptions counterpart */
+typedef enum
+{
+    SH_REFLECTION_DEFAULT             = 0,
+    SH_REFLECTION_STRICT_ARRAY_SUFFIX = (1 << 0),
+    SH_REFLECTION_BASIC_ARRAY_SUFFIX  = (1 << 1),
+    SH_REFLECTION_INTERMEDIATE_IOO    = (1 << 2),
+    SH_REFLECTION_SEPARATE_BUFFERS    = (1 << 3),
+    SH_REFLECTION_ALL_BLOCK_VARIABLES = (1 << 4),
+    SH_REFLECTION_UNWRAP_IO_BLOCKS    = (1 << 5),
+} glslang_reflection_options_t;
+
+/* EProfile counterpart (from Versions.h) */
+typedef enum {
+    SH_BAD_PROFILE           = 0,
+    SH_NO_PROFILE            = (1 << 0),
+    SH_CORE_PROFILE          = (1 << 1),
+    SH_COMPATIBILITY_PROFILE = (1 << 2),
+    SH_ES_PROFILE            = (1 << 3)
+} glslang_profile_t;
+
+#endif
+
diff --git a/glslang/Include/glslang_c_interface.h b/glslang/Include/glslang_c_interface.h
new file mode 100644 (file)
index 0000000..2c068ed
--- /dev/null
@@ -0,0 +1,127 @@
+/**
+BSD 2-Clause License
+
+Copyright (c) 2019, Viktor Latypov
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+   list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright notice,
+   this list of conditions and the following disclaimer in the documentation
+   and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+**/
+
+#ifndef GLSLANG_C_IFACE_H_INCLUDED
+#define GLSLANG_C_IFACE_H_INCLUDED
+
+#include <stdlib.h>
+
+#include "c_shader_types.h"
+
+typedef struct glslang_shader_s glslang_shader_t;
+typedef struct glslang_program_s glslang_program_t;
+
+typedef struct glslang_input_s
+{
+       glslang_source_t language;
+       glslang_stage_t stage;
+       glslang_client_t client;
+       glslang_target_client_version_t client_version;
+       glslang_target_language_t target_language;
+       glslang_target_language_version_t target_language_version;
+       /** Shader source code */
+       const char* code;
+       int default_version;
+       glslang_profile_t default_profile;
+       int force_default_version_and_profile;
+       int forward_compatible;
+       glslang_messages_t messages;
+} glslang_input_t;
+
+/* Inclusion result structure allocated by C include_local/include_system callbacks */
+typedef struct glsl_include_result_s
+{
+       /* Header file name or NULL if inclusion failed */
+       const char *header_name;
+
+       /* Header contents or NULL */
+       const char *header_data;
+       size_t     header_length;
+
+} glsl_include_result_t;
+
+/* Callback for local file inclusion */
+typedef glsl_include_result_t* (*glsl_include_local_func)(
+       void *ctx,
+       const char *header_name,
+       const char *includer_name,
+       size_t include_depth);
+
+/* Callback for system file inclusion */
+typedef glsl_include_result_t* (*glsl_include_system_func)(
+       void *ctx,
+       const char *header_name,
+       const char *includer_name,
+       size_t include_depth); 
+
+/* Callback for include result destruction */
+typedef int (*glsl_free_include_result_func)(
+       void *ctx,
+       glsl_include_result_t *result);
+
+/* Collection of callbacks for GLSL preprocessor */
+typedef struct glsl_include_callbacks_s
+{
+       glsl_include_system_func      include_system;
+       glsl_include_local_func       include_local;
+       glsl_free_include_result_func free_include_result;
+} glsl_include_callbacks_t;
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+int  glslang_initialize_process();
+void glslang_finalize_process();
+
+glslang_shader_t *glslang_shader_create(glslang_input_t *input);
+void glslang_shader_delete(glslang_shader_t *shader);
+int glslang_shader_preprocess(glslang_shader_t *shader, glslang_input_t *input);
+int glslang_shader_parse(glslang_shader_t *shader, glslang_input_t *input);
+const char* glslang_shader_get_preprocessed_code(glslang_shader_t *shader);
+const char* glslang_shader_get_info_log(glslang_shader_t *shader);
+const char* glslang_shader_get_info_debug_log(glslang_shader_t *shader);
+
+glslang_program_t *glslang_program_create();
+void glslang_program_delete(glslang_program_t *program);
+void glslang_program_add_shader(glslang_program_t *program, glslang_shader_t *shader);
+int glslang_program_link(glslang_program_t *program, int messages);
+void glslang_program_SPIRV_generate(glslang_program_t *program, glslang_stage_t stage);
+size_t glslang_program_SPIRV_get_size(glslang_program_t *program);
+void glslang_program_SPIRV_get(glslang_program_t *program, unsigned int *);
+const char* glslang_program_SPIRV_get_messages(glslang_program_t *program);
+const char* glslang_program_get_info_log(glslang_program_t *program);
+const char* glslang_program_get_info_debug_log(glslang_program_t *program);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  /* #ifdef GLSLANG_C_IFACE_INCLUDED */
+