From 4bb88c4a45707fb88150aa7952b4c9b9f55b1749 Mon Sep 17 00:00:00 2001 From: Kai-Hwa Yao Date: Sun, 9 Jul 2017 22:58:41 -0700 Subject: Allow glslang wrapper to output regular SPIRV before disassembly --- tools/glslang/glslang.cpp | 34 ++++++++++++++++++++-------------- tools/glslang/glslang.h | 4 +++- 2 files changed, 23 insertions(+), 15 deletions(-) (limited to 'tools') diff --git a/tools/glslang/glslang.cpp b/tools/glslang/glslang.cpp index cf563faff..fb697675e 100644 --- a/tools/glslang/glslang.cpp +++ b/tools/glslang/glslang.cpp @@ -51,21 +51,22 @@ static TBuiltInResource gResources = }; static void dump( - std::string const& text, - glslang_OutputFunc outputFunc, - void* outputUserData, - FILE* fallbackStream) + void const* data, + size_t size, + glslang_OutputFunc outputFunc, + void* outputUserData, + FILE* fallbackStream) { if( outputFunc ) { - outputFunc(text.c_str(), outputUserData); + outputFunc(data, size, outputUserData); } else { - fprintf(fallbackStream, "%s", text.c_str()); + fwrite(data, 1, size, fallbackStream); // also output it for debug purposes - OutputDebugStringA(text.c_str()); + OutputDebugStringA((char const*)data); } } @@ -73,7 +74,7 @@ static void dumpDiagnostics( glslang_CompileRequest* request, std::string const& log) { - dump(log, request->diagnosticFunc, request->diagnosticUserData, stderr); + dump(log.c_str(), log.length(), request->diagnosticFunc, request->diagnosticUserData, stderr); } extern "C" @@ -161,14 +162,19 @@ int glslang_compile(glslang_CompileRequest* request) dumpDiagnostics(request, logger.getAllMessages()); - std::stringstream spirvAsmStream; - - spv::Disassemble(spirvAsmStream, spirv); - - dump(spirvAsmStream.str(), request->outputFunc, request->outputUserData, stdout); + if (request->disassembleResult) + { + std::stringstream spirvAsmStream; + spv::Disassemble(spirvAsmStream, spirv); + std::string result = spirvAsmStream.str(); + dump(result.c_str(), result.length(), request->outputFunc, request->outputUserData, stdout); + } + else + { + dump(spirv.data(), spirv.size() * sizeof(spirv[0]), request->outputFunc, request->outputUserData, stdout); + } } - glslang::FinalizeProcess(); return 0; diff --git a/tools/glslang/glslang.h b/tools/glslang/glslang.h index 73c8a978e..8686f019e 100644 --- a/tools/glslang/glslang.h +++ b/tools/glslang/glslang.h @@ -2,7 +2,7 @@ #ifndef GLSLANG_H_INCLUDED #define GLSLANG_H_INCLUDED -typedef void (*glslang_OutputFunc)(char const* text, void* userData); +typedef void (*glslang_OutputFunc)(void const* data, size_t size, void* userData); struct glslang_CompileRequest { @@ -16,6 +16,8 @@ struct glslang_CompileRequest void* outputUserData; int slangStage; + + bool disassembleResult; }; typedef int (*glslang_CompileFunc)(glslang_CompileRequest* request); -- cgit v1.2.3 From 61a816c1e898155aa93c5a740e2b7aad7d7b4fa1 Mon Sep 17 00:00:00 2001 From: Kai-Hwa Yao Date: Mon, 10 Jul 2017 14:11:26 -0700 Subject: Don't assume vector contains contents --- tools/glslang/glslang.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/glslang/glslang.cpp b/tools/glslang/glslang.cpp index fb697675e..e396528d9 100644 --- a/tools/glslang/glslang.cpp +++ b/tools/glslang/glslang.cpp @@ -171,7 +171,7 @@ int glslang_compile(glslang_CompileRequest* request) } else { - dump(spirv.data(), spirv.size() * sizeof(spirv[0]), request->outputFunc, request->outputUserData, stdout); + dump(spirv.data(), spirv.size() * sizeof(unsigned int), request->outputFunc, request->outputUserData, stdout); } } -- cgit v1.2.3 From 22c7a4de0c3810fcfc1099843e42b315c366a7c5 Mon Sep 17 00:00:00 2001 From: Kai-Hwa Yao Date: Mon, 10 Jul 2017 17:44:14 -0700 Subject: Removed spGetTranslationUnitCode; Unified EntryPointResult/TranslationUnitResult, added helper functionality; Ensure null termination when printing raw data --- slang.h | 9 ------- source/slang/compiler.cpp | 68 ++++++++++++++++++++++++++++++++++------------- source/slang/compiler.h | 33 +++++++++++++++-------- source/slang/slang.cpp | 22 ++++----------- tools/glslang/glslang.cpp | 3 ++- 5 files changed, 78 insertions(+), 57 deletions(-) (limited to 'tools') diff --git a/slang.h b/slang.h index 56d962490..f5da206ce 100644 --- a/slang.h +++ b/slang.h @@ -322,15 +322,6 @@ extern "C" SlangCompileRequest* request, int translationUnitIndex); - /** Get the output bytecode associated with a specific translation unit. - - The lifetime of the output pointer is the same as `request`. - */ - SLANG_API void const* spGetTranslationUnitCode( - SlangCompileRequest* request, - int translationUnitIndex, - size_t* outSize); - /** Get the output source code associated with a specific entry point. The lifetime of the output pointer is the same as `request`. diff --git a/source/slang/compiler.cpp b/source/slang/compiler.cpp index 3225aafb2..c04c2150d 100644 --- a/source/slang/compiler.cpp +++ b/source/slang/compiler.cpp @@ -33,6 +33,33 @@ namespace Slang { + // CompileResult + + void CompileResult::append(CompileResult const& result) + { + // Find which to append to + ResultFormat appendTo = ResultFormat::None; + + if (format == ResultFormat::None) + { + format = result.format; + appendTo = result.format; + } + else if (format == result.format) + { + appendTo = format; + } + + if (appendTo == ResultFormat::Text) + { + outputString.append(result.outputString.Buffer()); + } + else if (appendTo == ResultFormat::Binary) + { + outputBinary.AddRange(result.outputBinary.Buffer(), result.outputBinary.Count()); + } + } + // EntryPointRequest TranslationUnitRequest* EntryPointRequest::getTranslationUnit() @@ -355,8 +382,11 @@ namespace Slang if (err) { - OutputDebugStringA((char const *)diagnosticOutput.Buffer()); - fwrite(diagnosticOutput.Buffer(), 1, diagnosticOutput.Count(), stderr); + char const* diagnosticString = (char const*)diagnosticOutput.Buffer(); + String debugStr(diagnosticString, diagnosticString + diagnosticOutput.Count()); + + OutputDebugStringA(debugStr.Buffer()); + fprintf(stderr, "%s", debugStr.Buffer()); exit(1); } @@ -385,10 +415,10 @@ namespace Slang #endif // Do emit logic for a single entry point - EntryPointResult emitEntryPoint( + CompileResult emitEntryPoint( EntryPointRequest* entryPoint) { - EntryPointResult result; + CompileResult result; auto compileRequest = entryPoint->compileRequest; @@ -397,42 +427,42 @@ namespace Slang case CodeGenTarget::HLSL: { String code = emitHLSLForEntryPoint(entryPoint); - result.outputSource.AddRange((uint8_t*)code.Buffer(), code.Length()); + result = CompileResult(code); } break; case CodeGenTarget::GLSL: { String code = emitGLSLForEntryPoint(entryPoint); - result.outputSource.AddRange((uint8_t*)code.Buffer(), code.Length()); + result = CompileResult(code); } break; case CodeGenTarget::DXBytecode: { List code = EmitDXBytecodeForEntryPoint(entryPoint); - result.outputSource.AddRange(code.Buffer(), code.Count()); + result = CompileResult(code); } break; case CodeGenTarget::DXBytecodeAssembly: { List code = EmitDXBytecodeAssemblyForEntryPoint(entryPoint); - result.outputSource.AddRange(code.Buffer(), code.Count()); + result = CompileResult(code); } break; case CodeGenTarget::SPIRV: { List code = emitSPIRVForEntryPoint(entryPoint, false); - result.outputSource.AddRange(code.Buffer(), code.Count()); + result = CompileResult(code); } break; case CodeGenTarget::SPIRVAssembly: { List code = emitSPIRVForEntryPoint(entryPoint, true); - result.outputSource.AddRange(code.Buffer(), code.Count()); + result = CompileResult(code); } break; @@ -449,18 +479,16 @@ namespace Slang } return result; - - } - TranslationUnitResult emitTranslationUnitEntryPoints( + CompileResult emitTranslationUnitEntryPoints( TranslationUnitRequest* translationUnit) { - TranslationUnitResult result; + CompileResult result; for (auto& entryPoint : translationUnit->entryPoints) { - EntryPointResult entryPointResult = emitEntryPoint(entryPoint.Ptr()); + CompileResult entryPointResult = emitEntryPoint(entryPoint.Ptr()); entryPoint->result = entryPointResult; } @@ -468,10 +496,11 @@ namespace Slang // The result for the translation unit will just be the concatenation // of the results for each entry point. This doesn't actually make // much sense, but it is good enough for now. + // + // TODO: Replace this with a packaged JSON and/or binary format. for (auto& entryPoint : translationUnit->entryPoints) { - UInt size = entryPoint->result.outputSource.Count(); - result.outputSource.AddRange(entryPoint->result.outputSource.Buffer(), size); + result.append(entryPoint->result); } return result; @@ -479,7 +508,7 @@ namespace Slang // Do emit logic for an entire translation unit, which might // have zero or more entry points - TranslationUnitResult emitTranslationUnit( + CompileResult emitTranslationUnit( TranslationUnitRequest* translationUnit) { return emitTranslationUnitEntryPoints(translationUnit); @@ -518,8 +547,9 @@ namespace Slang // For most targets, we will do things per-translation-unit for( auto translationUnit : compileRequest->translationUnits ) { - TranslationUnitResult translationUnitResult = emitTranslationUnit(translationUnit.Ptr()); + CompileResult translationUnitResult = emitTranslationUnit(translationUnit.Ptr()); translationUnit->result = translationUnitResult; } } + } diff --git a/source/slang/compiler.h b/source/slang/compiler.h index 3763faec7..2b440ad85 100644 --- a/source/slang/compiler.h +++ b/source/slang/compiler.h @@ -48,13 +48,30 @@ namespace Slang ReflectionJSON = SLANG_REFLECTION_JSON, }; + enum class ResultFormat + { + None, + Text, + Binary + }; + class CompileRequest; class TranslationUnitRequest; - // Result of compiling an entry point - struct EntryPointResult + // Result of compiling an entry point. + // Should only ever be string OR binary. + class CompileResult { - List outputSource; + public: + CompileResult() = default; + CompileResult(String const& str) : format(ResultFormat::Text), outputString(str) {} + CompileResult(List const& buffer) : format(ResultFormat::Binary), outputBinary(buffer) {} + + void append(CompileResult const& result); + + ResultFormat format = ResultFormat::None; + String outputString; + List outputBinary; }; // Describes an entry point that we've been requested to compile @@ -80,7 +97,7 @@ namespace Slang // The resulting output for the enry point // // TODO: low-level code generation should be a distinct step - EntryPointResult result; + CompileResult result; // The translation unit that this entry point came from TranslationUnitRequest* getTranslationUnit(); @@ -105,12 +122,6 @@ namespace Slang String content; }; - // Result of compiling a translation unit - struct TranslationUnitResult - { - List outputSource; - }; - // A single translation unit requested to be compiled. // class TranslationUnitRequest : public RefObject @@ -144,7 +155,7 @@ namespace Slang // The resulting output for the translation unit // // TODO: low-level code generation should be a distinct step - TranslationUnitResult result; + CompileResult result; }; // A directory to be searched when looking for files (e.g., `#include`) diff --git a/source/slang/slang.cpp b/source/slang/slang.cpp index 7f30e91c2..0561f30a9 100644 --- a/source/slang/slang.cpp +++ b/source/slang/slang.cpp @@ -862,18 +862,7 @@ SLANG_API char const* spGetTranslationUnitSource( int translationUnitIndex) { auto req = REQ(request); - return (char const*)req->translationUnits[translationUnitIndex]->result.outputSource.Buffer(); -} - -SLANG_API void const* spGetTranslationUnitCode( - SlangCompileRequest* request, - int translationUnitIndex, - size_t* outSize) -{ - auto req = REQ(request); - Slang::TranslationUnitResult& result = req->translationUnits[translationUnitIndex]->result; - *outSize = (size_t)result.outputSource.Count(); - return result.outputSource.Buffer(); + return req->translationUnits[translationUnitIndex]->result.outputString.Buffer(); } SLANG_API char const* spGetEntryPointSource( @@ -881,8 +870,7 @@ SLANG_API char const* spGetEntryPointSource( int entryPointIndex) { auto req = REQ(request); - return (char const*)req->entryPoints[entryPointIndex]->result.outputSource.Buffer(); - + return req->entryPoints[entryPointIndex]->result.outputString.Buffer(); } SLANG_API void const* spGetEntryPointCode( @@ -891,9 +879,9 @@ SLANG_API void const* spGetEntryPointCode( size_t* outSize) { auto req = REQ(request); - Slang::EntryPointResult& result = req->entryPoints[entryPointIndex]->result; - *outSize = (size_t)result.outputSource.Count(); - return result.outputSource.Buffer(); + Slang::CompileResult& result = req->entryPoints[entryPointIndex]->result; + if(outSize) *outSize = result.outputBinary.Count(); + return result.outputBinary.Buffer(); } // Reflection API diff --git a/tools/glslang/glslang.cpp b/tools/glslang/glslang.cpp index e396528d9..f07937b97 100644 --- a/tools/glslang/glslang.cpp +++ b/tools/glslang/glslang.cpp @@ -66,7 +66,8 @@ static void dump( fwrite(data, 1, size, fallbackStream); // also output it for debug purposes - OutputDebugStringA((char const*)data); + std::string str((char const*)data, size); + OutputDebugStringA(str.c_str()); } } -- cgit v1.2.3