From 1a6c8ecb20fcca190c96bd4be25e59b169d6e9f8 Mon Sep 17 00:00:00 2001 From: Ben Clayton Date: Wed, 10 Jun 2020 16:45:15 +0100 Subject: [PATCH 1/2] C Interface: Split SPIR-V C interface to own file This breaks a cyclic dependency between the SPIRV and glslang build targets. --- SPIRV/CInterface/spirv_c_interface.cpp | 110 +++++++++++++++++++++ SPIRV/CMakeLists.txt | 3 +- glslang/CInterface/glslang_c_interface.cpp | 33 ------- 3 files changed, 112 insertions(+), 34 deletions(-) create mode 100644 SPIRV/CInterface/spirv_c_interface.cpp diff --git a/SPIRV/CInterface/spirv_c_interface.cpp b/SPIRV/CInterface/spirv_c_interface.cpp new file mode 100644 index 00000000..c88b8085 --- /dev/null +++ b/SPIRV/CInterface/spirv_c_interface.cpp @@ -0,0 +1,110 @@ +/** + 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" + +typedef struct glslang_program_s { + glslang::TProgram* program; + std::vector spirv; + std::string loggerMessages; +} glslang_program_t; + +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 EShLangRayGen; + case GLSLANG_STAGE_INTERSECT_NV: + return EShLangIntersect; + case GLSLANG_STAGE_ANYHIT_NV: + return EShLangAnyHit; + case GLSLANG_STAGE_CLOSESTHIT_NV: + return EShLangClosestHit; + case GLSLANG_STAGE_MISS_NV: + return EShLangMiss; + case GLSLANG_STAGE_CALLABLE_NV: + return EShLangCallable; + case GLSLANG_STAGE_TASK_NV: + return EShLangTaskNV; + case GLSLANG_STAGE_MESH_NV: + return EShLangMeshNV; + default: + break; + } + return EShLangCount; +} + +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(); +} diff --git a/SPIRV/CMakeLists.txt b/SPIRV/CMakeLists.txt index 8451446d..5e90086d 100644 --- a/SPIRV/CMakeLists.txt +++ b/SPIRV/CMakeLists.txt @@ -6,7 +6,8 @@ set(SOURCES SpvPostProcess.cpp doc.cpp SpvTools.cpp - disassemble.cpp) + disassemble.cpp + CInterface/spirv_c_interface.cpp) set(SPVREMAP_SOURCES SPVRemapper.cpp diff --git a/glslang/CInterface/glslang_c_interface.cpp b/glslang/CInterface/glslang_c_interface.cpp index c4c24a9e..54283e6f 100644 --- a/glslang/CInterface/glslang_c_interface.cpp +++ b/glslang/CInterface/glslang_c_interface.cpp @@ -32,9 +32,6 @@ 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" @@ -401,36 +398,6 @@ glslang_program_t* glslang_program_create() 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) From dcad9ad05646a70683afa37cb5f6f12741be269c Mon Sep 17 00:00:00 2001 From: Ben Clayton Date: Mon, 15 Jun 2020 13:54:55 +0100 Subject: [PATCH 2/2] CMake: Fold HLSL source into glslang ... and stub the HLSL target. Fixes the building of shared libraries. This breaks the cyclic dependency between the `glslang` and `hlsl` targets (by essentially removing the `hlsl` target). The `BUILD.gn` and `BUILD.bazel` build rules already pull the `HLSL` source into the `glslang` target. `Android.mk` is the only remaining build config that has a dedicated `HLSL` target, but this is explicity static and does not suffer the same link-time issues with the cyclic dependency (we may wish to stub this target too). Related issue: #1484, #2147 Related PR: #2267 --- glslang/CMakeLists.txt | 27 ++++++++++++++++++++++----- hlsl/CMakeLists.txt | 29 +++++------------------------ hlsl/stub.cpp | 40 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 67 insertions(+), 29 deletions(-) create mode 100644 hlsl/stub.cpp diff --git a/glslang/CMakeLists.txt b/glslang/CMakeLists.txt index a0259a3d..606bbdcb 100644 --- a/glslang/CMakeLists.txt +++ b/glslang/CMakeLists.txt @@ -82,11 +82,32 @@ set(HEADERS glslang_pch(SOURCES MachineIndependent/pch.cpp) +if(ENABLE_HLSL) + list(APPEND SOURCES + ../hlsl/hlslAttributes.cpp + ../hlsl/hlslParseHelper.cpp + ../hlsl/hlslScanContext.cpp + ../hlsl/hlslOpMap.cpp + ../hlsl/hlslTokenStream.cpp + ../hlsl/hlslGrammar.cpp + ../hlsl/hlslParseables.cpp) + + list(APPEND HEADERS + ../hlsl/hlslAttributes.h + ../hlsl/hlslParseHelper.h + ../hlsl/hlslTokens.h + ../hlsl/hlslScanContext.h + ../hlsl/hlslOpMap.h + ../hlsl/hlslTokenStream.h + ../hlsl/hlslGrammar.h + ../hlsl/hlslParseables.h) +endif(ENABLE_HLSL) + add_library(glslang ${LIB_TYPE} ${BISON_GLSLParser_OUTPUT_SOURCE} ${SOURCES} ${HEADERS}) set_property(TARGET glslang PROPERTY FOLDER glslang) set_property(TARGET glslang PROPERTY POSITION_INDEPENDENT_CODE ON) target_link_libraries(glslang OGLCompiler OSDependent) -target_include_directories(glslang PUBLIC +target_include_directories(glslang PUBLIC $ $) @@ -94,10 +115,6 @@ if(WIN32 AND BUILD_SHARED_LIBS) set_target_properties(glslang PROPERTIES PREFIX "") endif() -if(ENABLE_HLSL) - target_link_libraries(glslang HLSL) -endif() - if(WIN32) source_group("Public" REGULAR_EXPRESSION "Public/*") source_group("MachineIndependent" REGULAR_EXPRESSION "MachineIndependent/[^/]*") diff --git a/hlsl/CMakeLists.txt b/hlsl/CMakeLists.txt index ae0d4d4e..d0866312 100644 --- a/hlsl/CMakeLists.txt +++ b/hlsl/CMakeLists.txt @@ -1,25 +1,10 @@ -set(SOURCES - hlslAttributes.cpp - hlslParseHelper.cpp - hlslScanContext.cpp - hlslOpMap.cpp - hlslTokenStream.cpp - hlslGrammar.cpp - hlslParseables.cpp) -set(HEADERS - hlslAttributes.h - hlslParseHelper.h - hlslTokens.h - hlslScanContext.h - hlslOpMap.h - hlslTokenStream.h - hlslGrammar.h - hlslParseables.h) +# The HLSL source is directly embedded into the glslang target when ENABLE_HLSL +# is set. +# The HLSL target is now just a stub that exists for backwards compatibility for +# projects that referenced this target. -glslang_pch(SOURCES pch.cpp) - -add_library(HLSL ${LIB_TYPE} ${SOURCES} ${HEADERS}) +add_library(HLSL ${LIB_TYPE} "stub.cpp") set_property(TARGET HLSL PROPERTY FOLDER hlsl) set_property(TARGET HLSL PROPERTY POSITION_INDEPENDENT_CODE ON) @@ -27,10 +12,6 @@ if(WIN32 AND BUILD_SHARED_LIBS) set_target_properties(HLSL PROPERTIES PREFIX "") endif() -if(WIN32) - source_group("Source" FILES ${SOURCES} ${HEADERS}) -endif(WIN32) - if(ENABLE_GLSLANG_INSTALL) if(BUILD_SHARED_LIBS) install(TARGETS HLSL EXPORT HLSLTargets diff --git a/hlsl/stub.cpp b/hlsl/stub.cpp new file mode 100644 index 00000000..c53b9395 --- /dev/null +++ b/hlsl/stub.cpp @@ -0,0 +1,40 @@ +// +// Copyright (C) 2020 Google, Inc. +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 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. +// +// Neither the name of Google, Inc., nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// 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 HOLDERS 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. +// + +// The HLSL source is directly embedded into the glslang target when ENABLE_HLSL +// is set. +// The HLSL target is now just a stub that exists for backwards compatibility +// for projects that referenced this target. As a target requires at least one +// source file to build, this file acts as that stub.