Skip to content

Commit

Permalink
Add glslang::Language to break cyclic dependency
Browse files Browse the repository at this point in the history
between `HLSL` and `glslang` build targets.

Applications now require a call to `glslang::RegisterHlslLanguage()`
to enable support for the HLSL language.
This is implemented in the HLSL library.

Fixes building of shared libraries.
  • Loading branch information
ben-clayton committed Jun 10, 2020
1 parent 45de441 commit 0b6ece0
Show file tree
Hide file tree
Showing 11 changed files with 330 additions and 44 deletions.
2 changes: 2 additions & 0 deletions Android.mk
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ LOCAL_CXXFLAGS:=-std=c++11 -fno-exceptions -fno-rtti $(GLSLANG_DEFINES)
LOCAL_SRC_FILES:= \
hlsl/hlslAttributes.cpp \
hlsl/hlslGrammar.cpp \
hlsl/hlslLanguage.cpp \
hlsl/hlslOpMap.cpp \
hlsl/hlslParseables.cpp \
hlsl/hlslParseHelper.cpp \
Expand Down Expand Up @@ -58,6 +59,7 @@ LOCAL_SRC_FILES:= \
glslang/MachineIndependent/iomapper.cpp \
glslang/MachineIndependent/limits.cpp \
glslang/MachineIndependent/linkValidate.cpp \
glslang/MachineIndependent/Language.cpp \
glslang/MachineIndependent/parseConst.cpp \
glslang/MachineIndependent/ParseContextBase.cpp \
glslang/MachineIndependent/ParseHelper.cpp \
Expand Down
2 changes: 2 additions & 0 deletions BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ source_set("glslang_sources") {
"glslang/MachineIndependent/Initialize.h",
"glslang/MachineIndependent/IntermTraverse.cpp",
"glslang/MachineIndependent/Intermediate.cpp",
"glslang/MachineIndependent/Language.cpp",
"glslang/MachineIndependent/LiveTraverser.h",
"glslang/MachineIndependent/ParseContextBase.cpp",
"glslang/MachineIndependent/ParseHelper.cpp",
Expand Down Expand Up @@ -151,6 +152,7 @@ source_set("glslang_sources") {
"hlsl/hlslAttributes.h",
"hlsl/hlslGrammar.cpp",
"hlsl/hlslGrammar.h",
"hlsl/hlslLanguage.cpp",
"hlsl/hlslOpMap.cpp",
"hlsl/hlslOpMap.h",
"hlsl/hlslParseHelper.cpp",
Expand Down
4 changes: 4 additions & 0 deletions StandAlone/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ set(LIBRARIES
SPIRV
glslang-default-resource-limits)

if(ENABLE_HLSL)
set(LIBRARIES ${LIBRARIES} HLSL)
endif()

if(ENABLE_SPVREMAPPER)
set(LIBRARIES ${LIBRARIES} SPVRemapper)
endif()
Expand Down
4 changes: 4 additions & 0 deletions StandAlone/StandAlone.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1250,6 +1250,10 @@ void CompileAndLinkShaderFiles(glslang::TWorklist& Worklist)

int singleMain()
{
#ifdef ENABLE_HLSL
glslang::RegisterHlslLanguage();
#endif

glslang::TWorklist workList;
std::for_each(WorkItems.begin(), WorkItems.end(), [&workList](std::unique_ptr<glslang::TWorkItem>& item) {
assert(item);
Expand Down
7 changes: 2 additions & 5 deletions glslang/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ set(SOURCES
MachineIndependent/SymbolTable.cpp
MachineIndependent/Versions.cpp
MachineIndependent/intermOut.cpp
MachineIndependent/Language.cpp
MachineIndependent/limits.cpp
MachineIndependent/linkValidate.cpp
MachineIndependent/parseConst.cpp
Expand Down Expand Up @@ -86,18 +87,14 @@ add_library(glslang ${LIB_TYPE} ${BISON_GLSLParser_OUTPUT_SOURCE} ${SOURCES} ${H
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
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/..>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>)

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/[^/]*")
Expand Down
117 changes: 117 additions & 0 deletions glslang/MachineIndependent/Language.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
//
// 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 3Dlabs Inc. Ltd. 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.
//

#include "Language.h"
#include "ParseHelper.h"
#include "ScanContext.h"

#include <array>

namespace glslang {

namespace {

class GlslLanguage : public Language {
public:
static GlslLanguage instance;

void Initialize() override {
TScanContext::fillInKeywordMap();
}

void Terminate() override {
TScanContext::deleteKeywordMap();
}

EShSource Source() const override {
return EShSourceGlsl;
}

TBuiltInParseables* CreateBuiltInParseables(TInfoSink&) override {
return new TBuiltIns();
}

TParseContextBase* CreateParseContext(TSymbolTable& symbolTable, TIntermediate& intermediate,
int version, EProfile profile,
EShLanguage language, TInfoSink& infoSink,
SpvVersion spvVersion, bool forwardCompatible, EShMessages messages,
bool parsingBuiltIns, std::string sourceEntryPointName) override {
if (sourceEntryPointName.size() == 0)
intermediate.setEntryPointName("main");
TString entryPoint = sourceEntryPointName.c_str();
return new TParseContext(symbolTable, intermediate, parsingBuiltIns, version, profile, spvVersion,
language, infoSink, forwardCompatible, messages, &entryPoint);
}
};

GlslLanguage GlslLanguage::instance;

std::array<Language*, EShSourceCount> languages = {};

// Automatically register the GLSL language when the static initializers are run
// for this compilation unit.
struct AutoRegisterGlslLanguage {
AutoRegisterGlslLanguage() { Language::Register(&GlslLanguage::instance); }
} autoRegisterGlslLanguage;

} // end anonymous namespace

void Language::InitializeAll() {
for (Language* language : languages) {
if (language) {
language->Initialize();
}
}
}

void Language::TerminateAll() {
for (Language* language : languages) {
if (language) {
language->Terminate();
}
}
}

void Language::Register(Language* language) {
EShSource source = language->Source();
languages[source] = language;
}

Language* Language::Get(EShSource source) {
return languages[source];
}

} // end namespace glslang

89 changes: 89 additions & 0 deletions glslang/MachineIndependent/Language.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
//
// 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 3Dlabs Inc. Ltd. 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.
//
#ifndef _GLSLANG_LANGUAGE_INCLUDED_
#define _GLSLANG_LANGUAGE_INCLUDED_

#include "Initialize.h"

namespace glslang {

class TParseContextBase;

// Language is an interface implemented by a source language.
// Languages are registered by source (EShSource).
class Language {
public:
virtual ~Language() {}

// Register() registers the language.
static void Register(Language*);

// Get() returns the registered language for the given source type.
static Language* Get(EShSource source);

// InitializeAll() initializes all the registered languages.
static void InitializeAll();

// TerminateAll() terminates all the registered languages.
static void TerminateAll();

// Initialize() initializes the language.
// Must be called, once, before any other method (with exception to Source()).
virtual void Initialize() = 0;

// Terminate() terminates the language.
// Must be called, once, before process termination.
// No method may be called after calling.
virtual void Terminate() = 0;

// Source() returns the EShSource that this language implements.
virtual EShSource Source() const = 0;

// CreateBuiltInParseables() constructs and returns the parseable strings
// for the given language.
virtual TBuiltInParseables* CreateBuiltInParseables(TInfoSink& infoSink) = 0;

// CreateParseContext() constructs and returns the parse context for the
// given language.
virtual TParseContextBase* CreateParseContext(TSymbolTable& symbolTable, TIntermediate& intermediate,
int version, EProfile profile,
EShLanguage language, TInfoSink& infoSink,
SpvVersion spvVersion, bool forwardCompatible, EShMessages messages,
bool parsingBuiltIns, std::string sourceEntryPointName) = 0;
};

} // end namespace glslang

#endif // _GLSLANG_LANGUAGE_INCLUDED_
53 changes: 14 additions & 39 deletions glslang/MachineIndependent/ShaderLang.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,17 +45,12 @@
#include <iostream>
#include <sstream>
#include <memory>
#include "Language.h"
#include "SymbolTable.h"
#include "ParseHelper.h"
#include "Scan.h"
#include "ScanContext.h"

#ifdef ENABLE_HLSL
#include "../../hlsl/hlslParseHelper.h"
#include "../../hlsl/hlslParseables.h"
#include "../../hlsl/hlslScanContext.h"
#endif

#include "../Include/ShHandle.h"
#include "../../OGLCompilersDLL/InitializeDll.h"

Expand Down Expand Up @@ -83,16 +78,11 @@ using namespace glslang;
// Create a language specific version of parseables.
TBuiltInParseables* CreateBuiltInParseables(TInfoSink& infoSink, EShSource source)
{
switch (source) {
case EShSourceGlsl: return new TBuiltIns(); // GLSL builtIns
#ifdef ENABLE_HLSL
case EShSourceHlsl: return new TBuiltInParseablesHlsl(); // HLSL intrinsics
#endif

default:
infoSink.info.message(EPrefixInternalError, "Unable to determine source language");
return nullptr;
if (Language* language = Language::Get(source)) {
return language->CreateBuiltInParseables(infoSink);
}
infoSink.info.message(EPrefixInternalError, "Unable to determine source language");
return nullptr;
}

// Create a language specific version of a parse context.
Expand All @@ -102,23 +92,14 @@ TParseContextBase* CreateParseContext(TSymbolTable& symbolTable, TIntermediate&
SpvVersion spvVersion, bool forwardCompatible, EShMessages messages,
bool parsingBuiltIns, std::string sourceEntryPointName = "")
{
switch (source) {
case EShSourceGlsl: {
if (sourceEntryPointName.size() == 0)
intermediate.setEntryPointName("main");
TString entryPoint = sourceEntryPointName.c_str();
return new TParseContext(symbolTable, intermediate, parsingBuiltIns, version, profile, spvVersion,
language, infoSink, forwardCompatible, messages, &entryPoint);
}
#ifdef ENABLE_HLSL
case EShSourceHlsl:
return new HlslParseContext(symbolTable, intermediate, parsingBuiltIns, version, profile, spvVersion,
language, infoSink, sourceEntryPointName.c_str(), forwardCompatible, messages);
#endif
default:
infoSink.info.message(EPrefixInternalError, "Unable to determine source language");
return nullptr;
if (Language* lang = Language::Get(source)) {
return lang->CreateParseContext(symbolTable, intermediate,
version, profile, language, infoSink,
spvVersion, forwardCompatible, messages,
parsingBuiltIns, sourceEntryPointName);
}
infoSink.info.message(EPrefixInternalError, "Unable to determine source language");
return nullptr;
}

// Local mapping functions for making arrays of symbol tables....
Expand Down Expand Up @@ -1322,10 +1303,7 @@ int ShInitialize()
if (PerProcessGPA == nullptr)
PerProcessGPA = new TPoolAllocator();

glslang::TScanContext::fillInKeywordMap();
#ifdef ENABLE_HLSL
glslang::HlslScanContext::fillInKeywordMap();
#endif
Language::InitializeAll();

return 1;
}
Expand Down Expand Up @@ -1424,10 +1402,7 @@ int ShFinalize()
PerProcessGPA = nullptr;
}

glslang::TScanContext::deleteKeywordMap();
#ifdef ENABLE_HLSL
glslang::HlslScanContext::deleteKeywordMap();
#endif
Language::TerminateAll();

return 1;
}
Expand Down
7 changes: 7 additions & 0 deletions glslang/Public/ShaderLang.h
Original file line number Diff line number Diff line change
Expand Up @@ -404,6 +404,13 @@ bool InitializeProcess();
// Call once per process to tear down everything
void FinalizeProcess();

#ifdef ENABLE_HLSL
// Call to enable HLSL language support before doing any other compiler/linker
// operations.
// Implemented in the HLSL library.
void RegisterHlslLanguage();
#endif

// Resource type for IO resolver
enum TResourceType {
EResSampler,
Expand Down
Loading

0 comments on commit 0b6ece0

Please sign in to comment.