summaryrefslogtreecommitdiff
path: root/source/slang-glslang/slang-glslang.cpp
diff options
context:
space:
mode:
authorTim Foley <tfoley@nvidia.com>2017-07-19 11:27:23 -0700
committerTim Foley <tfoley@nvidia.com>2017-07-19 11:27:23 -0700
commita97eac202cec673a0f2e27e808cfdcdd29289c4e (patch)
tree71022a3689bedfffe0ee3d969daffb2ae42fc720 /source/slang-glslang/slang-glslang.cpp
parentc5ed9e8d6bc1668d6075b42b17d65a97c168c98b (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.cpp204
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;
+}