diff options
| author | Tim Foley <tfoley@nvidia.com> | 2017-07-19 11:27:23 -0700 |
|---|---|---|
| committer | Tim Foley <tfoley@nvidia.com> | 2017-07-19 11:27:23 -0700 |
| commit | a97eac202cec673a0f2e27e808cfdcdd29289c4e (patch) | |
| tree | 71022a3689bedfffe0ee3d969daffb2ae42fc720 /source/slang-glslang/slang-glslang.cpp | |
| parent | c5ed9e8d6bc1668d6075b42b17d65a97c168c98b (diff) | |
Build a dynamic library for Slang
- Change the `slang` project from a static library to a dynamic one
- Add some details around `slang.h` to make sure DLL export stuff is working
- Make the `slangc` executable use the dynamic library
- Rename the `glslang` sub-project to `slang-glslang` and move it into the main source hierarchy
- This reflects the fact that it isn't a stand-alone tool, and isn't in any way a standard binary of glslang, but rather just an artifact of how Slang uses glslang
Diffstat (limited to 'source/slang-glslang/slang-glslang.cpp')
| -rw-r--r-- | source/slang-glslang/slang-glslang.cpp | 204 |
1 files changed, 204 insertions, 0 deletions
diff --git a/source/slang-glslang/slang-glslang.cpp b/source/slang-glslang/slang-glslang.cpp new file mode 100644 index 000000000..650e58ef6 --- /dev/null +++ b/source/slang-glslang/slang-glslang.cpp @@ -0,0 +1,204 @@ +// slang-glslang.cpp +#include "slang-glslang.h" + + +#include "StandAlone/ResourceLimits.h" +#include "StandAlone/Worklist.h" +#include "glslang/Include/ShHandle.h" +#include "glslang/Include/revision.h" +#include "glslang/Public/ShaderLang.h" +#include "SPIRV/GlslangToSpv.h" +#include "SPIRV/GLSL.std.450.h" +#include "SPIRV/doc.h" +#include "SPIRV/disassemble.h" + +#include "../../Slang.h" + +#if 0 +#include <cstring> +#include <cstdlib> +#include <cctype> +#include <cmath> +#include <array> +#include <memory> +#include <thread> +#endif + +#ifdef _WIN32 +#include <Windows.h> +#endif + +#include <sstream> + +// This is a wrapper to allow us to run the `glslang` compiler +// in a controlled fashion. + +#define UNLIMITED 9999 + +static TBuiltInResource gResources = +{ + UNLIMITED, UNLIMITED, UNLIMITED, UNLIMITED, UNLIMITED, UNLIMITED, UNLIMITED, UNLIMITED, UNLIMITED, UNLIMITED, + UNLIMITED, UNLIMITED, UNLIMITED, UNLIMITED, UNLIMITED, UNLIMITED, UNLIMITED,-UNLIMITED, UNLIMITED, UNLIMITED, + UNLIMITED, UNLIMITED, UNLIMITED, UNLIMITED, UNLIMITED, UNLIMITED, UNLIMITED, UNLIMITED, UNLIMITED, UNLIMITED, + UNLIMITED, UNLIMITED, UNLIMITED, UNLIMITED, UNLIMITED, UNLIMITED, UNLIMITED, UNLIMITED, UNLIMITED, UNLIMITED, + UNLIMITED, UNLIMITED, UNLIMITED, UNLIMITED, UNLIMITED, UNLIMITED, UNLIMITED, UNLIMITED, UNLIMITED, UNLIMITED, + UNLIMITED, UNLIMITED, UNLIMITED, UNLIMITED, UNLIMITED, UNLIMITED, UNLIMITED, UNLIMITED, UNLIMITED, UNLIMITED, + UNLIMITED, UNLIMITED, UNLIMITED, UNLIMITED, UNLIMITED, UNLIMITED, UNLIMITED, UNLIMITED, UNLIMITED, UNLIMITED, + UNLIMITED, UNLIMITED, UNLIMITED, UNLIMITED, UNLIMITED, UNLIMITED, UNLIMITED, UNLIMITED, UNLIMITED, UNLIMITED, + UNLIMITED, UNLIMITED, UNLIMITED, + + { true, true, true, true, true, true, true, true, true, } +}; + +static void dump( + void const* data, + size_t size, + glslang_OutputFunc outputFunc, + void* outputUserData, + FILE* fallbackStream) +{ + if( outputFunc ) + { + outputFunc(data, size, outputUserData); + } + else + { + fwrite(data, 1, size, fallbackStream); + + // also output it for debug purposes + std::string str((char const*)data, size); + OutputDebugStringA(str.c_str()); + } +} + +static void dumpDiagnostics( + glslang_CompileRequest* request, + std::string const& log) +{ + dump(log.c_str(), log.length(), request->diagnosticFunc, request->diagnosticUserData, stderr); +} + +static int glslang_compileGLSLToSPIRV(glslang_CompileRequest* request) +{ + EShLanguage glslangStage; + switch( request->slangStage ) + { +#define CASE(SP, GL) case SLANG_STAGE_##SP: glslangStage = EShLang##GL; break + CASE(VERTEX, Vertex); + CASE(FRAGMENT, Fragment); + CASE(GEOMETRY, Geometry); + CASE(HULL, TessControl); + CASE(DOMAIN, TessEvaluation); + CASE(COMPUTE, Compute); + +#undef CASE + + default: + return 1; + } + + // TODO: compute glslang stage to use + + glslang::TShader* shader = new glslang::TShader(glslangStage); + auto shaderPtr = std::unique_ptr<glslang::TShader>(shader); + + glslang::TProgram* program = new glslang::TProgram(); + auto programPtr = std::unique_ptr<glslang::TProgram>(program); + + char const* sourceText = (char const*)request->inputBegin; + char const* sourceTextEnd = (char const*)request->inputEnd; + + int sourceTextLength = (int)(sourceTextEnd - sourceText); + + shader->setPreamble("#extension GL_GOOGLE_cpp_style_line_directive : require\n"); + + shader->setStringsWithLengthsAndNames( + &sourceText, + &sourceTextLength, + &request->sourcePath, + 1); + + EShMessages messages = EShMessages(EShMsgSpvRules | EShMsgVulkanRules); + + if( !shader->parse(&gResources, 110, false, messages) ) + { + dumpDiagnostics(request, shader->getInfoLog()); + return 1; + } + + program->addShader(shader); + + if( !program->link(messages) ) + { + dumpDiagnostics(request, program->getInfoLog()); + return 1; + } + + if( !program->mapIO() ) + { + dumpDiagnostics(request, program->getInfoLog()); + return 1; + } + + for(int stage = 0; stage < EShLangCount; ++stage) + { + auto stageIntermediate = program->getIntermediate((EShLanguage)stage); + if(!stageIntermediate) + continue; + + std::vector<unsigned int> spirv; + std::string warningsErrors; + spv::SpvBuildLogger logger; + glslang::GlslangToSpv(*stageIntermediate, spirv, &logger); + + dumpDiagnostics(request, logger.getAllMessages()); + + dump(spirv.data(), spirv.size() * sizeof(unsigned int), request->outputFunc, request->outputUserData, stdout); + } + + return 0; +} + +static int glslang_dissassembleSPIRV(glslang_CompileRequest* request) +{ + typedef unsigned int SPIRVWord; + + SPIRVWord const* spirvBegin = (SPIRVWord const*)request->inputBegin; + SPIRVWord const* spirvEnd = (SPIRVWord const*)request->inputEnd; + + std::vector<SPIRVWord> spirv(spirvBegin, spirvEnd); + + std::stringstream spirvAsmStream; + spv::Disassemble(spirvAsmStream, spirv); + std::string result = spirvAsmStream.str(); + dump(result.c_str(), result.length(), request->outputFunc, request->outputUserData, stdout); + + return 0; +} + +extern "C" +_declspec(dllexport) +int glslang_compile(glslang_CompileRequest* request) +{ + glslang::InitializeProcess(); + + int result = 0; + switch(request->action) + { + default: + result = 1; + break; + + case GLSLANG_ACTION_COMPILE_GLSL_TO_SPIRV: + result = glslang_compileGLSLToSPIRV(request); + break; + + case GLSLANG_ACTION_DISSASSEMBLE_SPIRV: + result = glslang_dissassembleSPIRV(request); + break; + } + + glslang::FinalizeProcess(); + + return result; +} |
