Skip to content

Commit 0bfc2cc

Browse files
committed
Link through slang-glslang
1 parent e3f519b commit 0bfc2cc

File tree

7 files changed

+83
-46
lines changed

7 files changed

+83
-46
lines changed

source/slang-glslang/CMakeLists.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ if(SLANG_ENABLE_SLANG_GLSLANG)
66
.
77
MODULE
88
USE_FEWER_WARNINGS
9-
LINK_WITH_PRIVATE glslang SPIRV SPIRV-Tools-opt
9+
LINK_WITH_PRIVATE glslang SPIRV SPIRV-Tools-opt SPIRV-Tools-link
1010
INCLUDE_DIRECTORIES_PRIVATE ${slang_SOURCE_DIR}/include
1111
INSTALL
1212
EXPORT_SET_NAME SlangTargets

source/slang-glslang/slang-glslang.cpp

+63
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include "slang.h"
88
#include "spirv-tools/libspirv.h"
99
#include "spirv-tools/optimizer.hpp"
10+
#include "spirv-tools/linker.hpp"
1011

1112
#ifdef _WIN32
1213
#include <windows.h>
@@ -977,3 +978,65 @@ extern "C"
977978
request.set(*inRequest);
978979
return glslang_compile_1_1(&request);
979980
}
981+
982+
extern "C"
983+
#ifdef _MSC_VER
984+
_declspec(dllexport)
985+
#else
986+
__attribute__((__visibility__("default")))
987+
#endif
988+
int glslang_linkSPIRV(glslang_LinkRequest* request)
989+
{
990+
if (!request || !request->modules || request->linkResult)
991+
return false;
992+
993+
try
994+
{
995+
spvtools::Context context(SPV_ENV_UNIVERSAL_1_5);
996+
spvtools::LinkerOptions options = {};
997+
998+
spvtools::MessageConsumer consumer = [](spv_message_level_t level,
999+
const char* source,
1000+
const spv_position_t& position,
1001+
const char* message)
1002+
{
1003+
printf("SPIRV-TOOLS: %s\n", message);
1004+
printf("SPIRV-TOOLS: %s\n", source);
1005+
printf("SPIRV-TOOLS: %zu:%zu\n", position.index, position.column);
1006+
};
1007+
context.SetMessageConsumer(consumer);
1008+
1009+
std::vector<std::vector<uint32_t>> moduleVecs(request->moduleCount);
1010+
std::vector<const uint32_t*> moduleData(request->moduleCount);
1011+
std::vector<size_t> moduleSizes(request->moduleCount);
1012+
1013+
for (size_t i = 0; i < request->moduleCount; ++i)
1014+
{
1015+
moduleData[i] = request->modules[i];
1016+
moduleSizes[i] = request->moduleSizes[i];
1017+
}
1018+
1019+
std::vector<uint32_t> linkedBinary;
1020+
spv_result_t success = spvtools::Link(
1021+
context,
1022+
moduleData.data(),
1023+
moduleSizes.data(),
1024+
request->moduleCount,
1025+
&linkedBinary,
1026+
options);
1027+
1028+
if (success == SPV_SUCCESS)
1029+
{
1030+
request->linkResult = new uint32_t[linkedBinary.size()];
1031+
memcpy((void*)request->linkResult, linkedBinary.data(),
1032+
linkedBinary.size() * sizeof(uint32_t));
1033+
request->linkResultSize = linkedBinary.size();
1034+
}
1035+
1036+
return success;
1037+
}
1038+
catch(...)
1039+
{
1040+
return false;
1041+
}
1042+
}

source/slang-glslang/slang-glslang.h

+10-1
Original file line numberDiff line numberDiff line change
@@ -152,10 +152,19 @@ inline void glslang_CompileRequest_1_2::set(const glslang_CompileRequest_1_1& in
152152
memcpy(this, &in, sizeof(in));
153153
}
154154

155+
typedef struct glslang_LinkRequest_t
156+
{
157+
const uint32_t** modules; // Input: array of pointers to SPIR-V modules
158+
const uint32_t* moduleSizes; // Input: array of sizes of SPIR-V modules in 32-bit words
159+
int moduleCount; // Input: number of modules in the array
160+
const uint32_t* linkResult; // Output: pointer to linked SPIR-V module
161+
size_t linkResultSize; // Output: size of the linked SPIR-V module in 32-bit words
162+
} glslang_LinkRequest;
163+
155164
typedef int (*glslang_CompileFunc_1_0)(glslang_CompileRequest_1_0* request);
156165
typedef int (*glslang_CompileFunc_1_1)(glslang_CompileRequest_1_1* request);
157166
typedef int (*glslang_CompileFunc_1_2)(glslang_CompileRequest_1_2* request);
158167
typedef bool (*glslang_ValidateSPIRVFunc)(const uint32_t* contents, int contentsSize);
159168
typedef bool (*glslang_DisassembleSPIRVFunc)(const uint32_t* contents, int contentsSize);
160-
169+
typedef bool (*glslang_LinkSPIRVFunc)(glslang_LinkRequest* request);
161170
#endif

tools/CMakeLists.txt

-1
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,6 @@ if(SLANG_ENABLE_GFX)
141141
$<$<BOOL:${SLANG_ENABLE_XLIB}>:X11::X11>
142142
$<$<BOOL:${SLANG_ENABLE_CUDA}>:CUDA::cuda_driver>
143143
$<$<BOOL:${SLANG_ENABLE_NVAPI}>:${NVAPI_LIBRARIES}>
144-
SPIRV-Tools-link
145144
LINK_WITH_FRAMEWORK Foundation Cocoa QuartzCore Metal
146145
EXTRA_COMPILE_DEFINITIONS_PRIVATE
147146
$<$<BOOL:${SLANG_ENABLE_CUDA}>:GFX_ENABLE_CUDA>

tools/gfx/vulkan/vk-device.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -1019,6 +1019,7 @@ SlangResult DeviceImpl::initialize(const Desc& desc)
10191019
SLANG_RETURN_ON_FAIL(RendererBase::initialize(desc));
10201020
SlangResult initDeviceResult = SLANG_OK;
10211021

1022+
m_glslang.init();
10221023
for (int forceSoftware = 0; forceSoftware <= 1; forceSoftware++)
10231024
{
10241025
initDeviceResult = m_module.init(forceSoftware != 0);

tools/gfx/vulkan/vk-device.h

+2
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
#include "vk-base.h"
55
#include "vk-framebuffer.h"
6+
#include "glslang-module.h"
67

78
namespace gfx
89
{
@@ -196,6 +197,7 @@ class DeviceImpl : public RendererBase
196197

197198
VulkanModule m_module;
198199
VulkanApi m_api;
200+
GlslangModule m_glslang;
199201

200202
VulkanDeviceQueue m_deviceQueue;
201203
uint32_t m_queueFamilyIndex;

tools/gfx/vulkan/vk-shader-program.cpp

+6-43
Original file line numberDiff line numberDiff line change
@@ -71,53 +71,16 @@ VkPipelineShaderStageCreateInfo ShaderProgramImpl::compileEntryPoint(
7171
return shaderStageCreateInfo;
7272
}
7373

74-
static ComPtr<ISlangBlob> linkUsingSPIRVTools(List<ComPtr<ISlangBlob> > kernelCodes)
75-
{
76-
spvtools::Context context(SPV_ENV_UNIVERSAL_1_5);
77-
spvtools::LinkerOptions options;
78-
spvtools::MessageConsumer consumer = [](spv_message_level_t level,
79-
const char* source,
80-
const spv_position_t& position,
81-
const char* message)
82-
{
83-
printf("SPIRV-TOOLS: %s\n", message);
84-
printf("SPIRV-TOOLS: %s\n", source);
85-
printf("SPIRV-TOOLS: %zu:%zu\n", position.index, position.column);
86-
};
87-
context.SetMessageConsumer(consumer);
88-
std::vector<uint32_t*> binaries;
89-
std::vector<size_t> binary_sizes;
90-
for (auto kernelCode : kernelCodes)
91-
{
92-
binaries.push_back((uint32_t*)kernelCode->getBufferPointer());
93-
binary_sizes.push_back(kernelCode->getBufferSize() / sizeof(uint32_t));
94-
}
95-
96-
std::vector<uint32_t> linked_binary;
97-
98-
spvtools::Link(
99-
context,
100-
binaries.data(),
101-
binary_sizes.data(),
102-
binaries.size(),
103-
&linked_binary,
104-
options);
105-
106-
// Create a blob to hold the linked binary
107-
ComPtr<ISlangBlob> linkedKernelCode;
108-
109-
// Replace kernel code with linked binary
110-
// Creates a new blob with the linked binary
111-
linkedKernelCode = RawBlob::create(linked_binary.data(), linked_binary.size() * sizeof(uint32_t));
112-
113-
return linkedKernelCode;
114-
}
115-
11674
Result ShaderProgramImpl::createShaderModule(
11775
slang::EntryPointReflection* entryPointInfo,
11876
List<ComPtr<ISlangBlob>>& kernelCodes)
11977
{
120-
ComPtr<ISlangBlob> linkedKernel = linkUsingSPIRVTools(kernelCodes);
78+
ComPtr<ISlangBlob> linkedKernel = m_device->m_glslang.linkSPIRV(kernelCodes);
79+
if (!linkedKernel)
80+
{
81+
return SLANG_FAIL;
82+
}
83+
12184
m_codeBlobs.add(linkedKernel);
12285

12386
VkShaderModule shaderModule;

0 commit comments

Comments
 (0)