Merge pull request #2038 from corporateshark/c_interface

Implemented C-language interface for glslang
This commit is contained in:
John Kessenich 2020-01-24 04:10:09 -07:00 committed by GitHub
commit 965bd4d966
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 771 additions and 3 deletions

View File

@ -0,0 +1,451 @@
/**
This code is based on the glslang_c_interface implementation by Viktor Latypov
**/
/**
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/Include/glslang_c_interface.h"
#include "SPIRV/GlslangToSpv.h"
#include "SPIRV/Logger.h"
#include "SPIRV/SpvTools.h"
#include "StandAlone/DirStackFileIncluder.h"
#include "StandAlone/ResourceLimits.h"
#include "glslang/Include/ShHandle.h"
#include "glslang/Include/ResourceLimits.h"
#include "glslang/MachineIndependent/Versions.h"
static_assert(GLSLANG_STAGE_COUNT == EShLangCount, "");
static_assert(GLSLANG_STAGE_MASK_COUNT == EShLanguageMaskCount, "");
static_assert(GLSLANG_SOURCE_COUNT == glslang::EShSourceCount, "");
static_assert(GLSLANG_CLIENT_COUNT == glslang::EShClientCount, "");
static_assert(GLSLANG_TARGET_COUNT == glslang::EShTargetCount, "");
static_assert(GLSLANG_TARGET_CLIENT_VERSION_COUNT == glslang::EShTargetClientVersionCount, "");
static_assert(GLSLANG_TARGET_LANGUAGE_VERSION_COUNT == glslang::EShTargetLanguageVersionCount, "");
static_assert(GLSLANG_OPT_LEVEL_COUNT == EshOptLevelCount, "");
static_assert(GLSLANG_TEX_SAMP_TRANS_COUNT == EShTexSampTransCount, "");
static_assert(GLSLANG_MSG_COUNT == EShMsgCount, "");
static_assert(GLSLANG_REFLECTION_COUNT == EShReflectionCount, "");
static_assert(GLSLANG_PROFILE_COUNT == EProfileCount, "");
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 GLSLANG_STAGE_VERTEX:
return EShLangVertex;
case GLSLANG_STAGE_TESSCONTROL:
return EShLangTessControl;
case GLSLANG_STAGE_TESSEVALUATION:
return EShLangTessEvaluation;
case GLSLANG_STAGE_GEOMETRY:
return EShLangGeometry;
case GLSLANG_STAGE_FRAGMENT:
return EShLangFragment;
case GLSLANG_STAGE_COMPUTE:
return EShLangCompute;
case GLSLANG_STAGE_RAYGEN_NV:
return EShLangRayGenNV;
case GLSLANG_STAGE_INTERSECT_NV:
return EShLangIntersectNV;
case GLSLANG_STAGE_ANYHIT_NV:
return EShLangAnyHitNV;
case GLSLANG_STAGE_CLOSESTHIT_NV:
return EShLangClosestHitNV;
case GLSLANG_STAGE_MISS_NV:
return EShLangMissNV;
case GLSLANG_STAGE_CALLABLE_NV:
return EShLangCallableNV;
case GLSLANG_STAGE_TASK_NV:
return EShLangTaskNV;
case GLSLANG_STAGE_MESH_NV:
return EShLangMeshNV;
default:
break;
}
return EShLangCount;
}
static int c_shader_messages(glslang_messages_t messages)
{
#define CONVERT_MSG(in, out) \
if ((messages & in) == in) \
res |= out;
int res = 0;
CONVERT_MSG(GLSLANG_MSG_RELAXED_ERRORS_BIT, EShMsgRelaxedErrors);
CONVERT_MSG(GLSLANG_MSG_SUPPRESS_WARNINGS_BIT, EShMsgSuppressWarnings);
CONVERT_MSG(GLSLANG_MSG_AST_BIT, EShMsgAST);
CONVERT_MSG(GLSLANG_MSG_SPV_RULES_BIT, EShMsgSpvRules);
CONVERT_MSG(GLSLANG_MSG_VULKAN_RULES_BIT, EShMsgVulkanRules);
CONVERT_MSG(GLSLANG_MSG_ONLY_PREPROCESSOR_BIT, EShMsgOnlyPreprocessor);
CONVERT_MSG(GLSLANG_MSG_READ_HLSL_BIT, EShMsgReadHlsl);
CONVERT_MSG(GLSLANG_MSG_CASCADING_ERRORS_BIT, EShMsgCascadingErrors);
CONVERT_MSG(GLSLANG_MSG_KEEP_UNCALLED_BIT, EShMsgKeepUncalled);
CONVERT_MSG(GLSLANG_MSG_HLSL_OFFSETS_BIT, EShMsgHlslOffsets);
CONVERT_MSG(GLSLANG_MSG_DEBUG_INFO_BIT, EShMsgDebugInfo);
CONVERT_MSG(GLSLANG_MSG_HLSL_ENABLE_16BIT_TYPES_BIT, EShMsgHlslEnable16BitTypes);
CONVERT_MSG(GLSLANG_MSG_HLSL_LEGALIZATION_BIT, EShMsgHlslLegalization);
CONVERT_MSG(GLSLANG_MSG_HLSL_DX9_COMPATIBLE_BIT, EShMsgHlslDX9Compatible);
CONVERT_MSG(GLSLANG_MSG_BUILTIN_SYMBOL_TABLE_BIT, EShMsgBuiltinSymbolTable);
return res;
#undef CONVERT_MSG
}
static glslang::EShTargetLanguageVersion
c_shader_target_language_version(glslang_target_language_version_t target_language_version)
{
switch (target_language_version) {
case GLSLANG_TARGET_SPV_1_0:
return glslang::EShTargetSpv_1_0;
case GLSLANG_TARGET_SPV_1_1:
return glslang::EShTargetSpv_1_1;
case GLSLANG_TARGET_SPV_1_2:
return glslang::EShTargetSpv_1_2;
case GLSLANG_TARGET_SPV_1_3:
return glslang::EShTargetSpv_1_3;
case GLSLANG_TARGET_SPV_1_4:
return glslang::EShTargetSpv_1_4;
case GLSLANG_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 GLSLANG_CLIENT_VULKAN:
return glslang::EShClientVulkan;
case GLSLANG_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 GLSLANG_TARGET_VULKAN_1_1:
return glslang::EShTargetVulkan_1_1;
case GLSLANG_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 == GLSLANG_TARGET_NONE)
return glslang::EShTargetNone;
return glslang::EShTargetSpv;
}
static glslang::EShSource c_shader_source(glslang_source_t source)
{
switch (source) {
case GLSLANG_SOURCE_GLSL:
return glslang::EShSourceGlsl;
case GLSLANG_SOURCE_HLSL:
return glslang::EShSourceHlsl;
default:
break;
}
return glslang::EShSourceNone;
}
static EProfile c_shader_profile(glslang_profile_t profile)
{
switch (profile) {
case GLSLANG_BAD_PROFILE:
return EBadProfile;
case GLSLANG_NO_PROFILE:
return ENoProfile;
case GLSLANG_CORE_PROFILE:
return ECoreProfile;
case GLSLANG_COMPATIBILITY_PROFILE:
return ECompatibilityProfile;
case GLSLANG_ES_PROFILE:
return EEsProfile;
}
return EProfile();
}
glslang_shader_t* glslang_shader_create(const 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, const 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,
(EShMessages)c_shader_messages(i->messages), &shader->preprocessedGLSL, Includer
);
}
int glslang_shader_parse(glslang_shader_t* shader, const 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,
(EShMessages)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));
}
unsigned int* glslang_program_SPIRV_get_ptr(glslang_program_t* program)
{
return program->spirv.data();
}
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();
}

View File

@ -41,7 +41,8 @@ set(SOURCES
MachineIndependent/preprocessor/PpTokens.cpp MachineIndependent/preprocessor/PpTokens.cpp
MachineIndependent/propagateNoContraction.cpp MachineIndependent/propagateNoContraction.cpp
GenericCodeGen/CodeGen.cpp GenericCodeGen/CodeGen.cpp
GenericCodeGen/Link.cpp) GenericCodeGen/Link.cpp
CInterface/glslang_c_interface.cpp)
set(HEADERS set(HEADERS
Public/ShaderLang.h Public/ShaderLang.h
@ -49,6 +50,8 @@ set(HEADERS
Include/BaseTypes.h Include/BaseTypes.h
Include/Common.h Include/Common.h
Include/ConstantUnion.h Include/ConstantUnion.h
Include/glslang_c_interface.h
Include/glslang_c_shader_types.h
Include/InfoSink.h Include/InfoSink.h
Include/InitializeGlobals.h Include/InitializeGlobals.h
Include/intermediate.h Include/intermediate.h

View File

@ -0,0 +1,119 @@
/**
This code is based on the glslang_c_interface implementation by Viktor Latypov
**/
/**
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 "glslang_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(const glslang_input_t* input);
void glslang_shader_delete(glslang_shader_t* shader);
int glslang_shader_preprocess(glslang_shader_t* shader, const glslang_input_t* input);
int glslang_shader_parse(glslang_shader_t* shader, const 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); // glslang_messages_t
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*);
unsigned int* glslang_program_SPIRV_get_ptr(glslang_program_t* program);
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 */

View File

@ -0,0 +1,182 @@
/**
This code is based on the glslang_c_interface implementation by Viktor Latypov
**/
/**
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
#define LAST_ELEMENT_MARKER(x) x
/* EShLanguage counterpart */
typedef enum {
GLSLANG_STAGE_VERTEX,
GLSLANG_STAGE_TESSCONTROL,
GLSLANG_STAGE_TESSEVALUATION,
GLSLANG_STAGE_GEOMETRY,
GLSLANG_STAGE_FRAGMENT,
GLSLANG_STAGE_COMPUTE,
GLSLANG_STAGE_RAYGEN_NV,
GLSLANG_STAGE_INTERSECT_NV,
GLSLANG_STAGE_ANYHIT_NV,
GLSLANG_STAGE_CLOSESTHIT_NV,
GLSLANG_STAGE_MISS_NV,
GLSLANG_STAGE_CALLABLE_NV,
GLSLANG_STAGE_TASK_NV,
GLSLANG_STAGE_MESH_NV,
LAST_ELEMENT_MARKER(GLSLANG_STAGE_COUNT),
} glslang_stage_t; // would be better as stage, but this is ancient now
/* EShLanguageMask counterpart */
typedef enum {
GLSLANG_STAGE_VERTEX_MASK = (1 << GLSLANG_STAGE_VERTEX),
GLSLANG_STAGE_TESSCONTROL_MASK = (1 << GLSLANG_STAGE_TESSCONTROL),
GLSLANG_STAGE_TESSEVALUATION_MASK = (1 << GLSLANG_STAGE_TESSEVALUATION),
GLSLANG_STAGE_GEOMETRY_MASK = (1 << GLSLANG_STAGE_GEOMETRY),
GLSLANG_STAGE_FRAGMENT_MASK = (1 << GLSLANG_STAGE_FRAGMENT),
GLSLANG_STAGE_COMPUTE_MASK = (1 << GLSLANG_STAGE_COMPUTE),
GLSLANG_STAGE_RAYGEN_NV_MASK = (1 << GLSLANG_STAGE_RAYGEN_NV),
GLSLANG_STAGE_INTERSECT_NV_MASK = (1 << GLSLANG_STAGE_INTERSECT_NV),
GLSLANG_STAGE_ANYHIT_NV_MASK = (1 << GLSLANG_STAGE_ANYHIT_NV),
GLSLANG_STAGE_CLOSESTHIT_NV_MASK = (1 << GLSLANG_STAGE_CLOSESTHIT_NV),
GLSLANG_STAGE_MISS_NV_MASK = (1 << GLSLANG_STAGE_MISS_NV),
GLSLANG_STAGE_CALLABLE_NV_MASK = (1 << GLSLANG_STAGE_CALLABLE_NV),
GLSLANG_STAGE_TASK_NV_MASK = (1 << GLSLANG_STAGE_TASK_NV),
GLSLANG_STAGE_MESH_NV_MASK = (1 << GLSLANG_STAGE_MESH_NV),
LAST_ELEMENT_MARKER(GLSLANG_STAGE_MASK_COUNT),
} glslang_stage_mask_t;
/* EShSource counterpart */
typedef enum {
GLSLANG_SOURCE_NONE,
GLSLANG_SOURCE_GLSL,
GLSLANG_SOURCE_HLSL,
LAST_ELEMENT_MARKER(GLSLANG_SOURCE_COUNT),
} glslang_source_t;
/* EShClient counterpart */
typedef enum {
GLSLANG_CLIENT_NONE,
GLSLANG_CLIENT_VULKAN,
GLSLANG_CLIENT_OPENGL,
LAST_ELEMENT_MARKER(GLSLANG_CLIENT_COUNT),
} glslang_client_t;
/* EShTargetLanguage counterpart */
typedef enum {
GLSLANG_TARGET_NONE,
GLSLANG_TARGET_SPV,
LAST_ELEMENT_MARKER(GLSLANG_TARGET_COUNT),
} glslang_target_language_t;
/* SH_TARGET_ClientVersion counterpart */
typedef enum {
GLSLANG_TARGET_VULKAN_1_0 = (1 << 22),
GLSLANG_TARGET_VULKAN_1_1 = (1 << 22) | (1 << 12),
GLSLANG_TARGET_OPENGL_450 = 450,
LAST_ELEMENT_MARKER(GLSLANG_TARGET_CLIENT_VERSION_COUNT),
} glslang_target_client_version_t;
/* SH_TARGET_LanguageVersion counterpart */
typedef enum {
GLSLANG_TARGET_SPV_1_0 = (1 << 16),
GLSLANG_TARGET_SPV_1_1 = (1 << 16) | (1 << 8),
GLSLANG_TARGET_SPV_1_2 = (1 << 16) | (2 << 8),
GLSLANG_TARGET_SPV_1_3 = (1 << 16) | (3 << 8),
GLSLANG_TARGET_SPV_1_4 = (1 << 16) | (4 << 8),
GLSLANG_TARGET_SPV_1_5 = (1 << 16) | (5 << 8),
LAST_ELEMENT_MARKER(GLSLANG_TARGET_LANGUAGE_VERSION_COUNT),
} glslang_target_language_version_t;
/* EShExecutable counterpart */
typedef enum { GLSLANG_EX_VERTEX_FRAGMENT, GLSLANG_EX_FRAGMENT } glslang_executable_t;
/* EShOptimizationLevel counterpart */
typedef enum {
GLSLANG_OPT_NO_GENERATION,
GLSLANG_OPT_NONE,
GLSLANG_OPT_SIMPLE,
GLSLANG_OPT_FULL,
LAST_ELEMENT_MARKER(GLSLANG_OPT_LEVEL_COUNT),
} glslang_optimization_level_t;
/* EShTextureSamplerTransformMode counterpart */
typedef enum {
GLSLANG_TEX_SAMP_TRANS_KEEP,
GLSLANG_TEX_SAMP_TRANS_UPGRADE_TEXTURE_REMOVE_SAMPLER,
LAST_ELEMENT_MARKER(GLSLANG_TEX_SAMP_TRANS_COUNT),
} glslang_texture_sampler_transform_mode_t;
/* EShMessages counterpart */
typedef enum {
GLSLANG_MSG_DEFAULT_BIT = 0,
GLSLANG_MSG_RELAXED_ERRORS_BIT = (1 << 0),
GLSLANG_MSG_SUPPRESS_WARNINGS_BIT = (1 << 1),
GLSLANG_MSG_AST_BIT = (1 << 2),
GLSLANG_MSG_SPV_RULES_BIT = (1 << 3),
GLSLANG_MSG_VULKAN_RULES_BIT = (1 << 4),
GLSLANG_MSG_ONLY_PREPROCESSOR_BIT = (1 << 5),
GLSLANG_MSG_READ_HLSL_BIT = (1 << 6),
GLSLANG_MSG_CASCADING_ERRORS_BIT = (1 << 7),
GLSLANG_MSG_KEEP_UNCALLED_BIT = (1 << 8),
GLSLANG_MSG_HLSL_OFFSETS_BIT = (1 << 9),
GLSLANG_MSG_DEBUG_INFO_BIT = (1 << 10),
GLSLANG_MSG_HLSL_ENABLE_16BIT_TYPES_BIT = (1 << 11),
GLSLANG_MSG_HLSL_LEGALIZATION_BIT = (1 << 12),
GLSLANG_MSG_HLSL_DX9_COMPATIBLE_BIT = (1 << 13),
GLSLANG_MSG_BUILTIN_SYMBOL_TABLE_BIT = (1 << 14),
LAST_ELEMENT_MARKER(GLSLANG_MSG_COUNT),
} glslang_messages_t;
/* EShReflectionOptions counterpart */
typedef enum {
GLSLANG_REFLECTION_DEFAULT_BIT = 0,
GLSLANG_REFLECTION_STRICT_ARRAY_SUFFIX_BIT = (1 << 0),
GLSLANG_REFLECTION_BASIC_ARRAY_SUFFIX_BIT = (1 << 1),
GLSLANG_REFLECTION_INTERMEDIATE_IOO_BIT = (1 << 2),
GLSLANG_REFLECTION_SEPARATE_BUFFERS_BIT = (1 << 3),
GLSLANG_REFLECTION_ALL_BLOCK_VARIABLES_BIT = (1 << 4),
GLSLANG_REFLECTION_UNWRAP_IO_BLOCKS_BIT = (1 << 5),
LAST_ELEMENT_MARKER(GLSLANG_REFLECTION_COUNT),
} glslang_reflection_options_t;
/* EProfile counterpart (from Versions.h) */
typedef enum {
GLSLANG_BAD_PROFILE = 0,
GLSLANG_NO_PROFILE = (1 << 0),
GLSLANG_CORE_PROFILE = (1 << 1),
GLSLANG_COMPATIBILITY_PROFILE = (1 << 2),
GLSLANG_ES_PROFILE = (1 << 3),
LAST_ELEMENT_MARKER(GLSLANG_PROFILE_COUNT),
} glslang_profile_t;
#undef LAST_ELEMENT_MARKER
#endif

View File

@ -38,6 +38,8 @@
#ifndef _VERSIONS_INCLUDED_ #ifndef _VERSIONS_INCLUDED_
#define _VERSIONS_INCLUDED_ #define _VERSIONS_INCLUDED_
#define LAST_ELEMENT_MARKER(x) x
// //
// Help manage multiple profiles, versions, extensions etc. // Help manage multiple profiles, versions, extensions etc.
// //
@ -54,7 +56,8 @@ typedef enum {
ENoProfile = (1 << 0), // only for desktop, before profiles showed up ENoProfile = (1 << 0), // only for desktop, before profiles showed up
ECoreProfile = (1 << 1), ECoreProfile = (1 << 1),
ECompatibilityProfile = (1 << 2), ECompatibilityProfile = (1 << 2),
EEsProfile = (1 << 3) EEsProfile = (1 << 3),
LAST_ELEMENT_MARKER(EProfileCount),
} EProfile; } EProfile;
namespace glslang { namespace glslang {

View File

@ -100,7 +100,7 @@ typedef enum {
EShLangCallableNV, EShLangCallableNV,
EShLangTaskNV, EShLangTaskNV,
EShLangMeshNV, EShLangMeshNV,
EShLangCount, LAST_ELEMENT_MARKER(EShLangCount),
} EShLanguage; // would be better as stage, but this is ancient now } EShLanguage; // would be better as stage, but this is ancient now
typedef enum { typedef enum {
@ -118,6 +118,7 @@ typedef enum {
EShLangCallableNVMask = (1 << EShLangCallableNV), EShLangCallableNVMask = (1 << EShLangCallableNV),
EShLangTaskNVMask = (1 << EShLangTaskNV), EShLangTaskNVMask = (1 << EShLangTaskNV),
EShLangMeshNVMask = (1 << EShLangMeshNV), EShLangMeshNVMask = (1 << EShLangMeshNV),
LAST_ELEMENT_MARKER(EShLanguageMaskCount),
} EShLanguageMask; } EShLanguageMask;
namespace glslang { namespace glslang {
@ -128,18 +129,21 @@ typedef enum {
EShSourceNone, EShSourceNone,
EShSourceGlsl, // GLSL, includes ESSL (OpenGL ES GLSL) EShSourceGlsl, // GLSL, includes ESSL (OpenGL ES GLSL)
EShSourceHlsl, // HLSL EShSourceHlsl, // HLSL
LAST_ELEMENT_MARKER(EShSourceCount),
} EShSource; // if EShLanguage were EShStage, this could be EShLanguage instead } EShSource; // if EShLanguage were EShStage, this could be EShLanguage instead
typedef enum { typedef enum {
EShClientNone, // use when there is no client, e.g. for validation EShClientNone, // use when there is no client, e.g. for validation
EShClientVulkan, EShClientVulkan,
EShClientOpenGL, EShClientOpenGL,
LAST_ELEMENT_MARKER(EShClientCount),
} EShClient; } EShClient;
typedef enum { typedef enum {
EShTargetNone, EShTargetNone,
EShTargetSpv, // SPIR-V (preferred spelling) EShTargetSpv, // SPIR-V (preferred spelling)
EshTargetSpv = EShTargetSpv, // legacy spelling EshTargetSpv = EShTargetSpv, // legacy spelling
LAST_ELEMENT_MARKER(EShTargetCount),
} EShTargetLanguage; } EShTargetLanguage;
typedef enum { typedef enum {
@ -147,6 +151,7 @@ typedef enum {
EShTargetVulkan_1_1 = (1 << 22) | (1 << 12), // Vulkan 1.1 EShTargetVulkan_1_1 = (1 << 22) | (1 << 12), // Vulkan 1.1
EShTargetVulkan_1_2 = (1 << 22) | (2 << 12), // Vulkan 1.2 EShTargetVulkan_1_2 = (1 << 22) | (2 << 12), // Vulkan 1.2
EShTargetOpenGL_450 = 450, // OpenGL EShTargetOpenGL_450 = 450, // OpenGL
LAST_ELEMENT_MARKER(EShTargetClientVersionCount),
} EShTargetClientVersion; } EShTargetClientVersion;
typedef EShTargetClientVersion EshTargetClientVersion; typedef EShTargetClientVersion EshTargetClientVersion;
@ -158,6 +163,7 @@ typedef enum {
EShTargetSpv_1_3 = (1 << 16) | (3 << 8), // SPIR-V 1.3 EShTargetSpv_1_3 = (1 << 16) | (3 << 8), // SPIR-V 1.3
EShTargetSpv_1_4 = (1 << 16) | (4 << 8), // SPIR-V 1.4 EShTargetSpv_1_4 = (1 << 16) | (4 << 8), // SPIR-V 1.4
EShTargetSpv_1_5 = (1 << 16) | (5 << 8), // SPIR-V 1.5 EShTargetSpv_1_5 = (1 << 16) | (5 << 8), // SPIR-V 1.5
LAST_ELEMENT_MARKER(EShTargetLanguageVersionCount),
} EShTargetLanguageVersion; } EShTargetLanguageVersion;
struct TInputLanguage { struct TInputLanguage {
@ -207,6 +213,7 @@ typedef enum {
EShOptNone, EShOptNone,
EShOptSimple, // Optimizations that can be done quickly EShOptSimple, // Optimizations that can be done quickly
EShOptFull, // Optimizations that will take more time EShOptFull, // Optimizations that will take more time
LAST_ELEMENT_MARKER(EshOptLevelCount),
} EShOptimizationLevel; } EShOptimizationLevel;
// //
@ -215,6 +222,7 @@ typedef enum {
typedef enum { typedef enum {
EShTexSampTransKeep, // keep textures and samplers as is (default) EShTexSampTransKeep, // keep textures and samplers as is (default)
EShTexSampTransUpgradeTextureRemoveSampler, // change texture w/o embeded sampler into sampled texture and throw away all samplers EShTexSampTransUpgradeTextureRemoveSampler, // change texture w/o embeded sampler into sampled texture and throw away all samplers
LAST_ELEMENT_MARKER(EShTexSampTransCount),
} EShTextureSamplerTransformMode; } EShTextureSamplerTransformMode;
// //
@ -237,6 +245,7 @@ enum EShMessages {
EShMsgHlslLegalization = (1 << 12), // enable HLSL Legalization messages EShMsgHlslLegalization = (1 << 12), // enable HLSL Legalization messages
EShMsgHlslDX9Compatible = (1 << 13), // enable HLSL DX9 compatible mode (right now only for samplers) EShMsgHlslDX9Compatible = (1 << 13), // enable HLSL DX9 compatible mode (right now only for samplers)
EShMsgBuiltinSymbolTable = (1 << 14), // print the builtin symbol table EShMsgBuiltinSymbolTable = (1 << 14), // print the builtin symbol table
LAST_ELEMENT_MARKER(EShMsgCount),
}; };
// //
@ -250,6 +259,7 @@ typedef enum {
EShReflectionSeparateBuffers = (1 << 3), // buffer variables and buffer blocks are reflected separately EShReflectionSeparateBuffers = (1 << 3), // buffer variables and buffer blocks are reflected separately
EShReflectionAllBlockVariables = (1 << 4), // reflect all variables in blocks, even if they are inactive EShReflectionAllBlockVariables = (1 << 4), // reflect all variables in blocks, even if they are inactive
EShReflectionUnwrapIOBlocks = (1 << 5), // unwrap input/output blocks the same as with uniform blocks EShReflectionUnwrapIOBlocks = (1 << 5), // unwrap input/output blocks the same as with uniform blocks
LAST_ELEMENT_MARKER(EShReflectionCount),
} EShReflectionOptions; } EShReflectionOptions;
// //