Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions examples/cpu-shader-llvm/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,19 @@ if(SLANG_ENABLE_SLANGC)
# it as a custom command.
add_custom_command(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/shader.o
COMMAND slangc -target shader-object-code -emit-cpu-via-llvm -O3 -g0 ${CMAKE_CURRENT_SOURCE_DIR}/shader.slang -o ${CMAKE_CURRENT_BINARY_DIR}/shader.o
COMMAND
slangc -load-core-module ${core_module_archive} -target
shader-object-code -emit-cpu-via-llvm -O3 -g0
${CMAKE_CURRENT_SOURCE_DIR}/shader.slang -o
${CMAKE_CURRENT_BINARY_DIR}/shader.o
COMMAND_EXPAND_LISTS
MAIN_DEPENDENCY ${CMAKE_CURRENT_SOURCE_DIR}/shader.slang
VERBATIM
)
add_custom_target(cpu-shader-llvm-link-shader DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/shader.o)
# This dependency is added so that the custom command above is able to use
# slangc and slang-llvm.
add_dependencies(cpu-shader-llvm-link-shader slangc slang-llvm)
# slangc, slang-llvm, and the generated core module archive.
add_dependencies(cpu-shader-llvm-link-shader slangc slang-llvm generate_core_module)

# Mark shader.o as a generated file before `slang_add_target` consumes it
# via `EXPLICIT_SOURCE` below. `slang_add_target` is a function (separate
Expand Down
58 changes: 51 additions & 7 deletions source/slang-core-module/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ set(core_module_generated_header_dir ${CMAKE_CURRENT_BINARY_DIR})
set(core_module_generated_header
${core_module_generated_header_dir}/slang-core-module-generated.h
)
set(core_module_archive ${CMAKE_CURRENT_BINARY_DIR}/slang-core-module.bin)
set(glsl_module_generated_header_dir
${CMAKE_CURRENT_BINARY_DIR}/../slang-glsl-module
)
Expand All @@ -112,6 +113,7 @@ set(glsl_module_generated_header_dir
PARENT_SCOPE
)
set(glsl_module_generated_header ${glsl_module_generated_header} PARENT_SCOPE)
set(core_module_archive ${core_module_archive} PARENT_SCOPE)

# When SLANG_EMBED_CORE_MODULE=OFF, slang-without-embedded-core-module is an ALIAS
# for slang, whose DLL (slang-compiler.dll) is placed in bin/ rather than generators/.
Expand All @@ -136,24 +138,66 @@ endif()

add_custom_command(
OUTPUT
${core_module_archive}
${core_module_generated_header}
${bootstrap_pre_copy_command}
COMMAND ${CMAKE_COMMAND} -E make_directory ${core_module_generated_header_dir}
COMMAND
"$<TARGET_FILE:slang-bootstrap>"
-compile-core-module
-archive-type
riff-lz4
-save-core-module
${core_module_archive}
-save-core-module-bin-source
${core_module_generated_header}
DEPENDS
slang-bootstrap
slang-without-embedded-core-module
${bootstrap_extra_deps}
VERBATIM
)

add_custom_target(
generate_core_module
DEPENDS ${core_module_archive} ${core_module_generated_header}
)
set_target_properties(generate_core_module PROPERTIES FOLDER generated)

# Downstream generator targets depend on generate_core_module instead of the
# archive file directly. With Visual Studio, a file-level dependency on the
# byproduct copies the producer command into the dependent utility project, which
# makes multi-target builds run the core generation command more than once.
add_custom_command(
OUTPUT
${glsl_module_generated_header}
${bootstrap_pre_copy_command}
COMMAND ${CMAKE_COMMAND} -E make_directory ${glsl_module_generated_header_dir}
COMMAND
slang-bootstrap -archive-type riff-lz4 -save-core-module-bin-source
${core_module_generated_header} -save-glsl-module-bin-source
"$<TARGET_FILE:slang-bootstrap>"
-load-core-module
${core_module_archive}
-archive-type
riff-lz4
-save-glsl-module-bin-source
${glsl_module_generated_header}
DEPENDS
slang-bootstrap
slang-without-embedded-core-module
${bootstrap_extra_deps}
VERBATIM
)
# Add a target so that we can depend on the above step when we create the glsl
# module

add_custom_target(
generate_glsl_module_header
DEPENDS ${glsl_module_generated_header}
)
add_dependencies(generate_glsl_module_header generate_core_module)
set_target_properties(generate_glsl_module_header PROPERTIES FOLDER generated)

# Add a target so that existing dependents can request both generated headers.
add_custom_target(
generate_core_module_headers
DEPENDS ${core_module_generated_header} ${glsl_module_generated_header}
DEPENDS generate_core_module generate_glsl_module_header
)
set_target_properties(generate_core_module_headers PROPERTIES FOLDER generated)

Expand All @@ -177,7 +221,7 @@ set(core_module_common_args
slang_add_target(
${core_module_common_args}
TARGET_NAME slang-embedded-core-module
REQUIRES generate_core_module_headers
REQUIRES generate_core_module
EXTRA_COMPILE_DEFINITIONS_PRIVATE SLANG_EMBED_CORE_MODULE
INCLUDE_DIRECTORIES_PRIVATE ${core_module_generated_header_dir}
)
Expand Down
9 changes: 4 additions & 5 deletions source/slang-glsl-module/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,9 @@
# Generate an embeddable glsl module
#

# This header is generated in the same call to slang-bootstrap that generates
# the core module embed, which can be found in
# ../slang-core-module/CMakeLists.txt
# The target to look for is generate_core_module_headers
# This header is generated by a slang-bootstrap invocation that loads the
# precompiled core module, which can be found in ../slang-core-module/CMakeLists.txt.
# The target to look for is generate_glsl_module_header.

# CMake doesn't allow creating an implicit dependency across directory scopes,
# see https://cmake.org/cmake/help/v3.31/prop_sf/GENERATED.html. Because of
Expand All @@ -19,7 +18,7 @@ slang_add_target(
EXPLICIT_SOURCE
./slang-embedded-glsl-module.cpp
${glsl_module_generated_header}
REQUIRES generate_core_module_headers
REQUIRES generate_glsl_module_header
EXCLUDE_FROM_ALL
EXTRA_COMPILE_DEFINITIONS_PRIVATE SLANG_SHARED_LIBRARY_TOOL
EXPORT_SET_NAME SlangTargets
Expand Down
119 changes: 79 additions & 40 deletions source/slang/slang-options.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1369,6 +1369,14 @@ struct OptionsParser
bool redundantProfileSet = false;
};

struct PendingBuiltinModuleSave
{
slang::BuiltinModuleName moduleName = slang::BuiltinModuleName::Core;
SlangArchiveType archiveType = SLANG_ARCHIVE_TYPE_RIFF_LZ4;
String fileName;
bool writeAsSourceBytes = false;
};

int addTranslationUnit(SlangSourceLanguage language, Stage impliedStage);

void addInputSlangPath(String const& path);
Expand All @@ -1389,6 +1397,10 @@ struct OptionsParser
void addOutputPath(String const& path, CodeGenTarget impliedFormat);

void addOutputPath(char const* inPath);
SlangResult addPendingBuiltinModuleSave(
slang::BuiltinModuleName moduleName,
bool writeAsSourceBytes);
SlangResult writePendingBuiltinModuleSaves();
RawEntryPoint* getCurrentEntryPoint();

void setStage(RawEntryPoint* rawEntryPoint, Stage stage);
Expand Down Expand Up @@ -1513,7 +1525,8 @@ struct OptionsParser
bool m_stdinConsumed = false;
bool m_hasLoadedRepro = false;
bool m_compileCoreModule = false;
slang::CompileCoreModuleFlags m_compileCoreModuleFlags;
slang::CompileCoreModuleFlags m_compileCoreModuleFlags = 0;
List<PendingBuiltinModuleSave> m_pendingBuiltinModuleSaves;

SlangArchiveType m_archiveType = SLANG_ARCHIVE_TYPE_RIFF_LZ4;

Expand Down Expand Up @@ -1824,6 +1837,63 @@ void OptionsParser::addOutputPath(char const* inPath)
}
}

SlangResult OptionsParser::addPendingBuiltinModuleSave(
slang::BuiltinModuleName moduleName,
bool writeAsSourceBytes)
{
CommandLineArg fileName;
SLANG_RETURN_ON_FAIL(m_reader.expectArg(fileName));

PendingBuiltinModuleSave save;
save.moduleName = moduleName;
save.archiveType = m_archiveType;
save.fileName = fileName.value;
save.writeAsSourceBytes = writeAsSourceBytes;
m_pendingBuiltinModuleSaves.add(save);
return SLANG_OK;
}

SlangResult OptionsParser::writePendingBuiltinModuleSaves()
{
for (const auto& save : m_pendingBuiltinModuleSaves)
{
ComPtr<ISlangBlob> blob;
SlangResult saveResult =
m_session->saveBuiltinModule(save.moduleName, save.archiveType, blob.writeRef());
if (SLANG_FAILED(saveResult))
{
SLANG_RETURN_ON_FAIL(m_session->compileBuiltinModule(
save.moduleName,
save.moduleName == slang::BuiltinModuleName::Core ? m_compileCoreModuleFlags : 0));
SLANG_RETURN_ON_FAIL(
m_session->saveBuiltinModule(save.moduleName, save.archiveType, blob.writeRef()));
}

if (!save.writeAsSourceBytes)
{
SLANG_RETURN_ON_FAIL(File::writeAllBytes(
save.fileName,
blob->getBufferPointer(),
blob->getBufferSize()));
continue;
}

StringBuilder builder;
StringWriter writer(&builder, 0);

SLANG_RETURN_ON_FAIL(HexDumpUtil::dumpSourceBytes(
(const uint8_t*)blob->getBufferPointer(),
blob->getBufferSize(),
16,
&writer));

SLANG_RETURN_ON_FAIL(
File::writeNativeText(save.fileName, builder.getBuffer(), builder.getLength()));
}

return SLANG_OK;
}

OptionsParser::RawEntryPoint* OptionsParser::getCurrentEntryPoint()
{
auto rawEntryPointCount = m_rawEntryPoints.getCount();
Expand Down Expand Up @@ -2740,48 +2810,16 @@ SlangResult OptionsParser::_parse(int argc, char const* const* argv)
break;
}
case OptionKind::SaveCoreModule:
{
CommandLineArg fileName;
SLANG_RETURN_ON_FAIL(m_reader.expectArg(fileName));

ComPtr<ISlangBlob> blob;

SLANG_RETURN_ON_FAIL(m_session->saveCoreModule(m_archiveType, blob.writeRef()));
SLANG_RETURN_ON_FAIL(File::writeAllBytes(
fileName.value,
blob->getBufferPointer(),
blob->getBufferSize()));
break;
}
SLANG_RETURN_ON_FAIL(
addPendingBuiltinModuleSave(slang::BuiltinModuleName::Core, false));
break;
case OptionKind::SaveCoreModuleBinSource:
case OptionKind::SaveGLSLModuleBinSource:
{
CommandLineArg fileName;
SLANG_RETURN_ON_FAIL(m_reader.expectArg(fileName));

ComPtr<ISlangBlob> blob;

if (optionKind == OptionKind::SaveCoreModuleBinSource)
{
SLANG_RETURN_ON_FAIL(m_session->saveCoreModule(m_archiveType, blob.writeRef()));
}
else
{
SLANG_RETURN_ON_FAIL(m_session->saveBuiltinModule(
slang::BuiltinModuleName::GLSL,
m_archiveType,
blob.writeRef()));
}
StringBuilder builder;
StringWriter writer(&builder, 0);

SLANG_RETURN_ON_FAIL(HexDumpUtil::dumpSourceBytes(
(const uint8_t*)blob->getBufferPointer(),
blob->getBufferSize(),
16,
&writer));

File::writeNativeText(fileName.value, builder.getBuffer(), builder.getLength());
const auto moduleName = optionKind == OptionKind::SaveCoreModuleBinSource
? slang::BuiltinModuleName::Core
: slang::BuiltinModuleName::GLSL;
SLANG_RETURN_ON_FAIL(addPendingBuiltinModuleSave(moduleName, true));
break;
}
case OptionKind::DumpIrIds:
Expand Down Expand Up @@ -3880,6 +3918,7 @@ SlangResult OptionsParser::_parse(int argc, char const* const* argv)
{
SLANG_RETURN_ON_FAIL(m_session->compileCoreModule(m_compileCoreModuleFlags));
}
SLANG_RETURN_ON_FAIL(writePendingBuiltinModuleSaves());

// TODO(JS): This is a restriction because of how setting of state works for load repro
// If a repro has been loaded, then many of the following options will overwrite
Expand Down
34 changes: 8 additions & 26 deletions source/standard-modules/neural/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,10 @@ foreach(shader_file ${neural_shader_sources})
list(APPEND neural_copied_files ${dest_file})
endforeach()

# Determine which compiler to use for building the module
# Determine which bootstrap compiler to use for building the module.
# For cross-compilation, use slang-bootstrap from SLANG_GENERATORS_PATH
# (slang-bootstrap is a standalone tool with no external dependencies)
# Otherwise, use the slangc built as part of this build
# Otherwise, use the slang-bootstrap target built as part of this build.
if(SLANG_GENERATORS_PATH)
if(CMAKE_HOST_WIN32)
set(CMAKE_HOST_EXECUTABLE_SUFFIX ".exe")
Expand All @@ -44,32 +44,14 @@ if(SLANG_GENERATORS_PATH)
"${SLANG_GENERATORS_PATH}/slang-bootstrap${CMAKE_HOST_EXECUTABLE_SUFFIX}"
)
set(SLANG_COMPILER_DEPENDENCY)
set(SLANG_COMPILER_EXTRA_DEPS)
elseif(NOT SLANG_EMBED_CORE_MODULE)
# When the binary core module is not embedded, slangc (isBootstrap=false) would
# try to load the binary GLSL module from slang-glsl-module.dll. That binary was
# compiled by slang-bootstrap against its own core-from-source compilation and may
# not be compatible with slangc's independently compiled core module, causing a
# crash. Use slang-bootstrap instead: it compiles core and GLSL from source
# (isBootstrap=true skips binary-module loading) so there is no mismatch.
# We also depend on generate_core_module_headers, which (on Windows shared builds)
# copies slang-compiler.dll into the generators/ directory so slang-bootstrap
# can find it at runtime.
set(SLANG_COMPILER slang-bootstrap)
set(SLANG_COMPILER_DEPENDENCY slang-bootstrap)
set(SLANG_COMPILER_EXTRA_DEPS generate_core_module_headers)
elseif(SLANG_ENABLE_SLANGC)
set(SLANG_COMPILER "$<TARGET_FILE:slangc>")
set(SLANG_COMPILER_DEPENDENCY slangc slang)
set(SLANG_COMPILER_EXTRA_DEPS)
else()
# When SLANG_ENABLE_SLANGC is OFF, slangc is not built as a target. Fall back
# to slang-bootstrap (a generator always built regardless of SLANG_ENABLE_SLANGC)
# rather than a system-installed slangc that may not be present.
# Build standard modules with slang-bootstrap so this target never requires
# slangc.exe. Load the generated core module so this step does not recompile it.
set(SLANG_COMPILER slang-bootstrap)
set(SLANG_COMPILER_DEPENDENCY slang-bootstrap)
set(SLANG_COMPILER_EXTRA_DEPS generate_core_module_headers)
endif()
set(SLANG_COMPILER_CORE_MODULE_ARGS -load-core-module ${core_module_archive})
set(SLANG_COMPILER_EXTRA_DEPS generate_core_module)

# Determine compiler flags based on build type
if(SLANG_STANDARD_MODULE_DEVELOP_BUILD)
Expand All @@ -83,8 +65,8 @@ endif()
add_custom_command(
OUTPUT ${neural_module_file}
COMMAND
${SLANG_COMPILER} ${NEURAL_MODULE_DEFINES} -I ${CMAKE_CURRENT_SOURCE_DIR}
neural.slang -o ${SLANG_NEURAL_MODULE_FILE_NAME}
${SLANG_COMPILER} ${SLANG_COMPILER_CORE_MODULE_ARGS} ${NEURAL_MODULE_DEFINES} -I
${CMAKE_CURRENT_SOURCE_DIR} neural.slang -o ${SLANG_NEURAL_MODULE_FILE_NAME}
DEPENDS
${neural_copied_files}
${neural_unittest_sources}
Expand Down