Skip to content

Commit

Permalink
Use disassemble API from SPIRV-Tools
Browse files Browse the repository at this point in the history
This commit uses C API version of SPIRV disassemble function rather than
calling spirv-dis.exe.

This allows us to use a correct version of SPIRV disassble function that
Slangc.exe is using.
  • Loading branch information
jkwak-work committed Jan 3, 2025
1 parent 114c976 commit ce85004
Show file tree
Hide file tree
Showing 7 changed files with 72 additions and 68 deletions.
10 changes: 10 additions & 0 deletions source/compiler-core/slang-downstream-compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,9 @@ class IDownstreamCompiler : public ICastable
/// Validate and return the result
virtual SLANG_NO_THROW SlangResult SLANG_MCALL
validate(const uint32_t* contents, int contentsSize) = 0;
/// Disassemble and print to stdout
virtual SLANG_NO_THROW SlangResult SLANG_MCALL
disassemble(const uint32_t* contents, int contentsSize) = 0;

/// True if underlying compiler uses file system to communicate source
virtual SLANG_NO_THROW bool SLANG_MCALL isFileBased() = 0;
Expand Down Expand Up @@ -374,6 +377,13 @@ class DownstreamCompilerBase : public ComBaseObject, public IDownstreamCompiler
SLANG_UNUSED(contentsSize);
return SLANG_FAIL;
}
virtual SLANG_NO_THROW SlangResult SLANG_MCALL
disassemble(const uint32_t* contents, int contentsSize) SLANG_OVERRIDE
{
SLANG_UNUSED(contents);
SLANG_UNUSED(contentsSize);
return SLANG_FAIL;
}

DownstreamCompilerBase(const Desc& desc)
: m_desc(desc)
Expand Down
19 changes: 18 additions & 1 deletion source/compiler-core/slang-glslang-compiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ class GlslangDownstreamCompiler : public DownstreamCompilerBase
SLANG_OVERRIDE;
virtual SLANG_NO_THROW SlangResult SLANG_MCALL
validate(const uint32_t* contents, int contentsSize) SLANG_OVERRIDE;
virtual SLANG_NO_THROW SlangResult SLANG_MCALL
disassemble(const uint32_t* contents, int contentsSize) SLANG_OVERRIDE;

/// Must be called before use
SlangResult init(ISlangSharedLibrary* library);
Expand All @@ -63,6 +65,7 @@ class GlslangDownstreamCompiler : public DownstreamCompilerBase
glslang_CompileFunc_1_1 m_compile_1_1 = nullptr;
glslang_CompileFunc_1_2 m_compile_1_2 = nullptr;
glslang_ValidateSPIRVFunc m_validate = nullptr;
glslang_DisassembleSPIRVFunc m_disassemble = nullptr;

ComPtr<ISlangSharedLibrary> m_sharedLibrary;

Expand All @@ -75,7 +78,7 @@ SlangResult GlslangDownstreamCompiler::init(ISlangSharedLibrary* library)
m_compile_1_1 = (glslang_CompileFunc_1_1)library->findFuncByName("glslang_compile_1_1");
m_compile_1_2 = (glslang_CompileFunc_1_2)library->findFuncByName("glslang_compile_1_2");
m_validate = (glslang_ValidateSPIRVFunc)library->findFuncByName("glslang_validateSPIRV");

m_disassemble = (glslang_DisassembleSPIRVFunc)library->findFuncByName("glslang_disassembleSPIRV");

if (m_compile_1_0 == nullptr && m_compile_1_1 == nullptr && m_compile_1_2 == nullptr)
{
Expand Down Expand Up @@ -305,6 +308,20 @@ SlangResult GlslangDownstreamCompiler::validate(const uint32_t* contents, int co
return SLANG_FAIL;
}

SlangResult GlslangDownstreamCompiler::disassemble(const uint32_t* contents, int contentsSize)
{
if (m_disassemble == nullptr)
{
return SLANG_FAIL;
}

if (m_disassemble(contents, contentsSize))
{
return SLANG_OK;
}
return SLANG_FAIL;
}

bool GlslangDownstreamCompiler::canConvert(const ArtifactDesc& from, const ArtifactDesc& to)
{
// Can only disassemble blobs that are SPIR-V
Expand Down
38 changes: 37 additions & 1 deletion source/slang-glslang/slang-glslang.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ extern "C"
#else
__attribute__((__visibility__("default")))
#endif
bool glslang_validateSPIRV(const uint32_t* contents, int contentsSize)
bool glslang_validateSPIRV(const uint32_t* contents, int contentsSize)
{
spv_target_env target_env = SPV_ENV_VULKAN_1_3;

Expand All @@ -182,6 +182,42 @@ extern "C"
return tools.Validate(contents, contentsSize, options);
}

// Disassemble the given SPIRV-ASM instructions.
extern "C"
#ifdef _MSC_VER
_declspec(dllexport)
#else
__attribute__((__visibility__("default")))
#endif
bool glslang_disassembleSPIRV(const uint32_t* contents, int contentsSize)
{
static const auto kDefaultEnvironment = SPV_ENV_UNIVERSAL_1_5;

uint32_t options = SPV_BINARY_TO_TEXT_OPTION_NONE;
options |= SPV_BINARY_TO_TEXT_OPTION_COMMENT;
options |= SPV_BINARY_TO_TEXT_OPTION_PRINT;
options |= SPV_BINARY_TO_TEXT_OPTION_COLOR;

spv_diagnostic diagnostic = nullptr;
spv_context context = spvContextCreate(kDefaultEnvironment);
spv_result_t error = spvBinaryToText(
context,
contents,
contentsSize,
options,
nullptr,
&diagnostic);
spvContextDestroy(context);
if (error)
{
spvDiagnosticPrint(diagnostic);
spvDiagnosticDestroy(diagnostic);
return false;
}

return true;
}

// Apply the SPIRV-Tools optimizer to generated SPIR-V based on the desired optimization level
// TODO: add flag for optimizing SPIR-V size as well
static void glslang_optimizeSPIRV(
Expand Down
1 change: 1 addition & 0 deletions source/slang-glslang/slang-glslang.h
Original file line number Diff line number Diff line change
Expand Up @@ -156,5 +156,6 @@ typedef int (*glslang_CompileFunc_1_0)(glslang_CompileRequest_1_0* request);
typedef int (*glslang_CompileFunc_1_1)(glslang_CompileRequest_1_1* request);
typedef int (*glslang_CompileFunc_1_2)(glslang_CompileRequest_1_2* request);
typedef bool (*glslang_ValidateSPIRVFunc)(const uint32_t* contents, int contentsSize);
typedef bool (*glslang_DisassembleSPIRVFunc)(const uint32_t* contents, int contentsSize);

#endif
21 changes: 6 additions & 15 deletions source/slang/slang-emit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,6 @@
#include "slang-legalize-types.h"
#include "slang-lower-to-ir.h"
#include "slang-mangle.h"
#include "slang-spirv-val.h"
#include "slang-syntax.h"
#include "slang-type-layout.h"
#include "slang-visitor.h"
Expand Down Expand Up @@ -1942,18 +1941,16 @@ SlangResult emitSPIRVForEntryPointsDirectly(
ArtifactUtil::createArtifactForCompileTarget(asExternal(codeGenContext->getTargetFormat()));
artifact->addRepresentationUnknown(ListBlob::moveCreate(spirv));

#if 0
// Dump the unoptimized SPIRV after lowering from slang IR -> SPIRV
String err; String dis;
disassembleSPIRV(spirv, err, dis);
printf("%s", dis.begin());
#endif

IDownstreamCompiler* compiler = codeGenContext->getSession()->getOrLoadDownstreamCompiler(
PassThroughMode::SpirvOpt,
codeGenContext->getSink());
if (compiler)
{
#if 0
// Dump the unoptimized SPIRV after lowering from slang IR -> SPIRV
compiler->disassemble((uint32_t*)spirv.getBuffer(), int(spirv.getCount() / 4));
#endif

if (!codeGenContext->shouldSkipSPIRVValidation())
{
StringBuilder runSpirvValEnvVar;
Expand All @@ -1966,13 +1963,7 @@ SlangResult emitSPIRVForEntryPointsDirectly(
(uint32_t*)spirv.getBuffer(),
int(spirv.getCount() / 4))))
{
String err;
String dis;
disassembleSPIRV(spirv, err, dis);
codeGenContext->getSink()->diagnoseWithoutSourceView(
SourceLoc{},
Diagnostics::spirvValidationFailed,
dis);
compiler->disassemble((uint32_t*)spirv.getBuffer(), int(spirv.getCount() / 4));
}
}
}
Expand Down
41 changes: 0 additions & 41 deletions source/slang/slang-spirv-val.cpp

This file was deleted.

10 changes: 0 additions & 10 deletions source/slang/slang-spirv-val.h

This file was deleted.

0 comments on commit ce85004

Please sign in to comment.