From 8cded6ccb9a370c793a8806435006a3e54cb4eb8 Mon Sep 17 00:00:00 2001 From: Sergey Kosarevsky Date: Tue, 24 Dec 2019 23:53:05 +0300 Subject: [PATCH] Added original glslang_c_interface implementation by Viktor Latypov --- glslang/CInterface/glslang_c_interface.cpp | 502 +++++++++++++++++++++ glslang/Include/c_shader_types.h | 168 +++++++ glslang/Include/glslang_c_interface.h | 127 ++++++ 3 files changed, 797 insertions(+) create mode 100644 glslang/CInterface/glslang_c_interface.cpp create mode 100644 glslang/Include/c_shader_types.h create mode 100644 glslang/Include/glslang_c_interface.h diff --git a/glslang/CInterface/glslang_c_interface.cpp b/glslang/CInterface/glslang_c_interface.cpp new file mode 100644 index 00000000..9923d555 --- /dev/null +++ b/glslang/CInterface/glslang_c_interface.cpp @@ -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 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(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(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(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 index 00000000..563e990b --- /dev/null +++ b/glslang/Include/c_shader_types.h @@ -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 index 00000000..2c068ed1 --- /dev/null +++ b/glslang/Include/glslang_c_interface.h @@ -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 + +#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 */ +