资讯动态

Slang 编译器核心模块(Core Module)与 Prelude 体系深度解析:内置标准库、标准模块与逐目标预置头的构建与扩展

发布时间:2026/9/18 3:18:44 来源:尧图企业网站定制
Slang 编译器核心模块Core Module与 Prelude 体系深度解析内置标准库、标准模块与逐目标预置头的构建与扩展【免费下载链接】slangMaking it easier to work with shaders项目地址: https://gitcode.com/GitHub_Trending/sl/slang本文系统性剖析 Slang 着色器语言编译器仓库中随编译器分发的三类内置代码——核心模块core module、GLSL 模块GLSL module与标准模块standard modules——以及面向各输出目标的 prelude 头文件机制。读者将理解这些内置库在构建期如何被嵌入或独立编译、运行时如何按需加载、SLANG_EMBED_CORE_MODULE等 CMake 选项如何改变错误暴露时机并掌握在*.meta.slang中新增内置函数/内在函数intrinsic的完整操作流程。文中所有结论均以 docs/generated/design/cross-cutting/core-module.md 为骨架并给出对应的源码路径佐证。编译器随附的已发布 Slang 代码三类不同构建期处理的对象Slang 编译器并不是一个只处理用户源代码的空壳它随自身发布三族已发布的 Slang 代码它们在构建期享有截然不同的处理方式核心模块core module——一组位于 source/slang 下的*.meta.slang源文件被直接嵌入libslang使编译器在编译期即可使用它们。它们定义了内置类型、转换规则、内在函数以及各目标的拼写形式spellings。GLSL 模块GLSL module——同样被嵌入的模块提供 GLSL 风格的名称如vec3、mat4、gl_*系统值。标准模块standard modules——独立编译的.slang-module文件安装在与编译器二进制相邻的目录中当用户代码执行import且限定名映射到该目录的子目录时按需加载目前有import slang.neural、import experimental.workgraph与import slang.numerics。与前两者不同逐目标的preludeprelude 目录是另一类概念它们是随文本目标输出一起分发的 C/C/CUDA 头文件供下游工具链编译 Slang 所产出的代码使用它们本身不是 Slang 源码。需要强调的是prelude 属于输出侧output-side而非输入侧input-side它们不参与前端语义检查。核心模块语言词汇表的来源组成文件与职责划分核心模块由三个*.meta.slang文件构成职责分明source/slang/core.meta.slang —— 基础类型int8_t、int32_t、int64_t、float、half、double、指针/大小类型与类型别名。文件首行即声明public module core;是一个以core命名的 Slang 模块。source/slang/hlsl.meta.slang —— HLSL 兼容名称Texture2D、RWTexture2D、StructuredBuffer以及mul、dot、length等内在函数。source/slang/diff.meta.slang —— 供微分 IR pass 消费的自动微分autodiff表面以attribute_syntax声明的[ForwardDerivative]、[BackwardDerivative]、[PrimalSubstitute]及其...Of变体、[DerivativeMember]、[NoDiffThis]属性NullDifferential类型Array、Optional、Tuple对IDifferentiable/IDifferentiablePtrType的合规conformance以及面向 PyTorch 的TensorView、DiffTensorView、TorchTensor类型。从 source/slang/diff.meta.slang 第 44 行起即可看到attribute_syntax [ForwardDerivative(function)] : ForwardDerivativeAttribute;等一系列声明。__target_switch一个 HLSL 兼容名如何适配所有目标一个 HLSL 兼容内在函数并不会在所有目标上都被当作函数调用。这些内在函数写成__target_switch形式其 case 给出逐目标的形态普通 Slang 函数体放在default分支中在没有任何 case 匹配时使用——该函数体会被发射为一个生成的辅助函数。mul是最典型的例子对float4x4与float4的mul(m, v)目标发射形态HLSLmul(m, v)GLSL、Metal、WGSL(v * m)—— 乘法运算符而非函数调用SPIR-VOpVectorTimesMatrixCUDA、C由default函数体生成的mul_n辅助函数dot与length在 HLSL、GLSL、Metal、WGSL 上保留原名在 SPIR-V 上变为OpDot与GLSL.std.450的Length扩展指令在 CUDA 与 C 上同样回退为生成的dot_n/length_n辅助函数。这一机制的实际写法可参考 source/slang/hlsl.meta.slang 中ByteAddressBuffer.GetDimensions等方法的__target_switch结构case 分支使用__intrinsic_asmdefault分支调用通用辅助函数。嵌入胶水代码与两种嵌入策略核心模块的嵌入胶水位于 source/slang-core-modulesource/slang-core-module/slang-embedded-core-module.cpp —— 将预编译的核心模块字节链接进libslang。在 CMake 选项SLANG_EMBED_CORE_MODULE开启时使用默认开启。source/slang-core-module/slang-embedded-core-module-source.cpp —— 变体嵌入原始.slang源码而非预编译字节用于引导构建流程首次生成嵌入产物时。两种嵌入策略的选择在 source/slang/CMakeLists.txt 中以一对生成器表达式generator expression表达分别挑选slang-embedded-core-module/slang-embedded-core-module-source或其slang-no-...兄弟目标。顶层 CMakeLists.txt 要求SLANG_EMBED_CORE_MODULE与SLANG_EMBED_CORE_MODULE_SOURCE至少开启其一否则在配置期直接报错One of SLANG_EMBED_CORE_MODULE and SLANG_EMBED_CORE_MODULE_SOURCE must be enabled。核心模块提供了什么核心模块文件搭建了用户代码以及元模块自身依赖的语言词汇表。它以public module core;开头随后是一组标量别名float16_t、float32_t、float64_t、int32_t、uint32_t、size_t、usize_t、ssize_t见 source/slang/core.meta.slang 第 1–24 行然后通过syntax声明声明修饰符语法constexpr、globallycoherent、pervertex……。这些是真正的修饰符而非仅仅是被接受的拼写其中一部分在 lowering 后还会存续于发射代码中globallycoherent缓冲在 HLSL 上发射globallycoherent在 GLSL 上发射coherent在 SPIR-V 上发射Coherentdecoration。matrix展示了如何在 Slang 侧给 C 侧常量一个类型而不是让它作为裸整数传递其第四个泛型参数是let L : MatrixLayoutMode MatrixLayoutMode.Unknownsource/slang/core.meta.slang 第 2308 行而MatrixLayoutMode是紧邻其上第 2298 行的一个//hidden:枚举其三个 case 直接从 C 宏中拼接取值——Unknown $(SLANG_MATRIX_LAYOUT_MODE_UNKNOWN)、RowMajor、ColumnMajor——这样两处定义不可能漂移。该枚举上方的注释解释了它为何不用int未解析的布局必须保持为泛型参数中可识别的形态因为它与行列数并排出现。完整的声明集合覆盖标量/向量/矩阵类型通过__intrinsic_op修饰符映射到 IR 操作码的运算符重载以__implicit_conversion声明的隐式转换代价IRangedValue接口及其逐标量扩展Optional与Tuple以及自动微分词汇本身——IDifferentiable与DifferentialPair魔法类型在 source/slang/core.meta.slang 中声明而非在 diff 元模块中。其中三个类型无需import即可直接使用值得单独说明其表面OptionalT——hasValue与value属性、来自T的隐式转换、none字面量也是默认初始化产生的值。Tupleeach T—— 位置成员_0、_1、……可组合成 swizzle如t._2_1_0用makeTuple构造。IRangedValue——static const This maxValue与minValue由各标量类型的扩展为每个内置数值类型提供以合规该接口。HLSL 元模块在此之上叠加 HLSL 命名的纹理/采样器/缓冲类型与对应内在函数使 HLSL 代码无需修改即可编译。它也是使用__target_intrinsic(target, text)修饰符为声明提供逐目标拼写的地方例如RayDesc及其字段在hlsl与cuda下的不同拼写见 source/slang/hlsl.meta.slang 第 19686 行附近的__target_intrinsic(hlsl, RayDesc)。GLSL 模块随需加载的内置方言模块source/slang/glsl.meta.slang 提供 GLSL 风格的别名vec3、mat4、gl_*系统值由 source/slang-glsl-module 通过 source/slang-glsl-module/slang-embedded-glsl-module.cpp 嵌入。全局会话global session在创建时若设置了SlangGlobalSessionDesc::enableGLSL即 source/slang/slang-api.cpp 中的if (desc-enableGLSL)分支则加载 GLSL 内置模块此后用户代码的import glsl通过 source/slang/slang-session.cpp 中glslModuleName的特例逻辑取回这个已经加载的内置模块。GLSL 模块的嵌入头文件与核心模块共享同一次slang-bootstrap调用生成见下文构建核心模块构建侧由generate_glsl_module_header目标承接。标准模块独立编译、按需加载的.slang-module标准模块是独立编译的.slang-module文件随版本化目录安装在编译器共享库libslang.so/slang.dll旁边由运行时通过import加载——其限定名映射到该目录的子目录。findStandardModulePathsource/slang/slang-session.cpp 第 41–52 行的注释明确说明标准模块与 libslang.so/slang.dll 同置于 SLANG_STANDARD_MODULE_DIR_NAME 下并把moduleName .slang-module拼接到目录路径后检查文件是否存在。构建基础设施位于 source/standard-modules其细节由 source/standard-modules/README.md 说明。现有模块一览每个 source/standard-modules 下的子目录都有各自的CMakeLists.txt由 source/standard-modules/CMakeLists.txt 中的add_subdirectory拉入产出一个或多个.slang-module产物。目前存在三个模块目录入口文件模块文件名变量导入路径neuralneural.slangSLANG_NEURAL_MODULE_FILE_NAMEneural.slang-moduleimport slang.neuralexperimentalworkgraph.slangSLANG_WORKGRAPH_MODULE_FILE_NAMEworkgraph.slang-moduleimport experimental.workgraphnumericsnumerics.slang无——路径直接在其自身CMakeLists.txt中构建import slang.numerics一个子目录对应一个产物的形状只对前两者成立。numerics/是例外也是值得研读的一般情形由于运行时查找纯粹基于路径并不限制每个目录只能有一个模块它产出了四个产物——一个公开、三个私有。numerics.slang-module落在slang/输出目录即import slang.numerics解析到的文件其余三个——__builtin.slang-module、__builtin_differentiable.slang-module与differentiable.slang-module——落在更下一层的slang/numerics/因此只能以slang.numerics.__builtin等限定名访问见 source/standard-modules/numerics/CMakeLists.txt 第 5–15 行的输出目录与文件路径定义。三个模块各自的内容neural 模块在 source/standard-modules/neural/neural.slang 中声明[ExperimentalModule] module neural;通过__include指令拉入目录其余部分向量与存储抽象ivector.slang、inline-vector.slang、istorages.slang、bindless-storage.slang、矩阵乘法后端accelerate-vector-coopmat.slang、WaveMatrix.slang、mma-tiled-*.slang家族及其布局辅助、层/激活/编码器接口与实现ilayer.slang、iactivation.slang、iencoder.slang、layers.slang、activations.slang、permuto-encoder.slang以及支撑代码hash-function.slang、shared-memory-pool.slang、vectorized-reader.slang、network-parameter-layout-converter.slang。unit-test/子目录存放可被__include的测试源码仅当设置SLANG_STANDARD_MODULE_DEVELOP_BUILD时才编译进模块此时编译命令追加-DUNIT_TEST并通过-I解析而非复制到输出目录。experimental 模块在 source/standard-modules/experimental/workgraph.slang 中声明[ExperimentalModule] module workgraph;持有工作图work-graph词汇以attribute_syntax声明的节点属性[NodeLaunch]、[NodeMaxDispatchGrid]、[MaxRecords]、[NodeID]……、输入/输出记录类型DispatchNodeInputRecord、ThreadNodeInputRecord、GroupNodeOutputRecords、NodeOutput、NodeOutputArray……以及BarrierMemoryTypeFlags/BarrierSemanticFlags枚举与消费它们的Barrier重载。numerics 模块在 source/standard-modules/numerics/numerics.slang 中声明[ExperimentalModule] module numerics;提供与表示无关的数值接口与针对它们编写的泛型运算interfaces.slang中的接口层级INumericShapedType及其标量细化、IAdditive、INumeric、ISignedNumeric、IIntegerType比较阶梯IEquatable/IPartiallyOrdered/ITotallyOrdered以及产生IBooleanMask的分量式变体将这些接口绑定到具体类型的合规声明builtin-conformances.slang、floating-point-conformances.slang、cooperative-vector-conformances.slang以及wrappers.slang。并行的differentiable-*集合构建附属模块differentiable它__exported import了slang.numerics并用可微需求与显式求导规则将其细化。两个__builtin*.slang适配器被刻意排除在公开导入图之外因为它们不导入公开模块其查找环境中不可能包含公开的接口泛型重载于是其调用解析到既有的核心模块运算而非递归地选择一个 witness 支撑的重载。从 source/standard-modules/numerics/CMakeLists.txt 第 59–63 行的注释可以读到这一设计意图的完整表述。[ExperimentalModule]门控导入而非仅仅打标签三个模块都携带的[ExperimentalModule]属性在 source/slang/core.meta.slang 中以attribute_syntax声明门控的是导入行为本身而不仅仅是给模块打标签未启用实验特性时导入会失败报E00104——module is an experimental module, need to enable -experimental-feature to load this module该错误信息会点名被解析的模块路径与解除封锁的选项。检查逻辑位于 source/slang/slang-session.cpp 第 1820 行附近已加载模块的 IR 携带IRExperimentalModuleDecoration且CompilerOptionName::ExperimentalFeature未设置时即触发诊断诊断本身定义为need-to-enable-experiment-feature编号 104见 source/slang/slang-diagnostics.lua 第 553–558 行。标准模块的构建配置两个目录共享 source/standard-modules/CMakeLists.txt 定义的配置SLANG_STANDARD_MODULE_DIR_NAME—— 版本化输出目录名slang-standard-module-${SLANG_VERSION_NUMERIC}。SLANG_STANDARD_MODULE_INSTALL_DIR—— Windows 上为bin/其他平台为lib/再拼接上述目录名。表中各模块文件名变量。这些值通过configure_file替换进 source/standard-modules/slang-standard-module-config.h.in生成内部头文件slang-standard-module-config.h由generate_standard_module_config_header目标承接。运行时 source/slang/slang-session.cpp 消费SLANG_STANDARD_MODULE_DIR_NAME定位libslang旁的目录findStandardModulePath再追加被导入模块的限定名加.slang-module于是slang.neural解析为slang/neural.slang-moduleexperimental.workgraph解析为experimental/workgraph.slang-module。每个标准模块在构建期由构建中已有的 Slang 编译器编译见 source/standard-modules/neural/CMakeLists.txt 与 source/standard-modules/experimental/CMakeLists.txtadd_custom_command以-load-core-module指向${core_module_archive_without_timestamp}即核心模块构建产生的slang-core-module-without-timestamp.bin归档来调用编译器并依赖generate_core_module目标。加载预构建的核心归档意味着标准模块构建步骤不会重新编译核心模块。各目录对编译器的选择略有不同。当设置SLANG_GENERATORS_PATH时三者都改用该路径下的slang-bootstrap二进制而非本构建产物——这正是交叉编译避免在构建主机上运行目标平台编译器的做法。否则neural/与numerics/始终使用slang-bootstrap目标因此两者都不要求存在slangcexperimental/在SLANG_EMBED_CORE_MODULE与SLANG_ENABLE_SLANGC同时开启时使用$TARGET_FILE:slangc其余情况回退到slang-bootstrap与 source/standard-modules/neural/CMakeLists.txt 第 33–54 行的编译器选择逻辑一致。numerics/还展示了同一目录内产物之间为何需要相互排序而不能仅仅对着核心模块排序公开模块导入适配器因此每个适配器序列化出的.slang-module是导入它的公开产物的普通构建依赖其add_custom_command必须先行执行。标准模块机制是设计为可扩展的新模块放入source/standard-modules/name/并在父CMakeLists.txt中增加一个add_subdirectory即可。Preludes输出侧的嵌入字符串而非随附头文件机制澄清默认 prelude 是嵌入字符串Prelude 是预先置于文本目标输出之前的头文件文本使下游工具链能够编译 Slang 所发射的代码。它们属于输出侧而非输入侧不参与前端检查。原设计文档描述prelude 头文件随目标输出一并发射、通过#include prelude式机制引入这一描述与实际默认路径不符需要修正默认编译器路径将每个*-prelude.h通过slang-embed工具在构建期转成 C 字符串全局会话注册 CUDA、C、HLSL 字符串作为默认语言 prelude发射阶段直接把选中的字符串写入生成源码。自定义 prelude 字符串本身可以包含#include但这并不是已发布默认 prelude 的引入方式。三处源码证据prelude/CMakeLists.txt 第 6–21 行glob_append(prelude_headers *-prelude.h)收集所有 prelude 头文件逐个执行slang-embed ${input} ${output}生成对应的.cpp源文件并组成名为prelude的 OBJECT 库供slang链接。source/slang/slang-global-session.cpp 第 125–128 行会话构造函数注册默认语言 prelude——m_languagePreludes[Index(SourceLanguage::CUDA)] get_slang_cuda_prelude();、CPP 与 HLSL 同理这些get_slang_*_prelude()即来自slang-embed生成的字符串。source/slang/slang-emit.cpp 第 3111–3123 行发射阶段按目标选择字符串并直接写入——CodeGenTarget::PyTorchCppBinding时sourceWriter.emit(get_slang_torch_prelude())异构目标heterogeneous时先emit(get_slang_cpp_host_prelude())否则通过session-getPreludeForLanguage(sourceLanguage)取得所选语言的 prelude 并sourceWriter.emit(prelude)。需要同时说明两点细节头文件本身也会被安装prelude库的INSTALL属性调用方可以自行用一段仅#include其中一个头文件的文本覆盖某种语言的 prelude——命令行工具正是走了这条路径因此-target cpp发射结果的开头是 include 而非头文件正文#include install-dir/slang-cpp-prelude.h其后生成的入口点会用头文件定义的一个宏SLANG_PRELUDE_EXPORT标记。-target cuda是同样的形态使用 prelude/slang-cuda-prelude.h。prelude 头文件清单Prelude用途prelude/slang-cpp-prelude.hC 着色器输出prelude/slang-cpp-types-core.hC 共享核心类型prelude/slang-cpp-types.hC 扩展类型prelude/slang-cpp-scalar-intrinsics.hC 标量内在函数实现prelude/slang-cpp-host-prelude.h宿主侧 C 运行时prelude/slang-cuda-prelude.hCUDAprelude/slang-hlsl-prelude.hHLSLprelude/slang-llvm.hslang-llvm集成prelude/slang-torch-prelude.hPyTorch 胶水GLSL、Metal、WGSL 与 SPIR-V 不以同样的方式使用prelude/头文件它们的内置词汇由各后端直接发射或交由下游工具链处理。构建核心模块两种嵌入模式与三个构建产物两种嵌入模式的取舍依据 CLAUDE.md 与 source/slang/CMakeLists.txtcmake -DSLANG_EMBED_CORE_MODULEON默认将预编译的核心模块烘焙进libslang。此时*.meta.slang中的错误会在C 构建期暴露因为嵌入产物是*.meta.slang源码的构建产物。cmake -DSLANG_EMBED_CORE_MODULEOFF使slangc与slang-test的 C 构建独立于核心模块编译。修正这里并不能简单表述为错误只在运行时暴露。更精确的不变量是——禁用嵌入将核心模块编译与 C 编译解耦元源码错误从独立的generate_core_module步骤暴露而一次正常的全量/共享构建仍会急切地执行该步骤非嵌入共享构建会挂上ALL目标generate_core_module_cache它依赖generate_core_module见 source/slang/CMakeLists.txt 第 370–404 行两个标准模块的ALL目标也依赖同一个生成器目标见 source/standard-modules/neural/CMakeLists.txt 第 82 行与 experimental 对应文件因此构建过程会运行slang-bootstrap -compile-core-module并在此阶段报告元源码错误。运行时编译仅是兜底当既没有有效缓存也没有嵌入模块时才发生。SLANG_EMBED_CORE_MODULE_SOURCE选项同样控制是否将原始 Slang 源码文本与预编译字节一并嵌入slang-bootstrap在交叉编译场景使用。顶层 CMakeLists.txt 第 530–533 行强制二者至少其一开启否则配置失败。一次调用产出三个构建产物source/slang-core-module/CMakeLists.txt 第 141–166 行中单次slang-bootstrap调用通过一次-compile-core-module运行产出三个构建产物slang-core-module-without-timestamp.bin—— 编译后核心模块的独立 RIFF/LZ4 归档经-save-core-module写出由 CMake 变量core_module_archive_without_timestamp命名。该归档通过-load-core-module喂给标准模块构建使上述模块基于同一核心模块编译而无需重编该变量被导出到父作用域供standard-modules/子目录引用。可嵌入的核心模块头文件-save-core-module-bin-source由slang-embedded-core-module消费。可嵌入的 GLSL 模块头文件-save-glsl-module-bin-source由slang-embedded-glsl-module消费。这些输出通过自定义目标generate_core_module、generate_glsl_module_header与伞形目标generate_core_module_headers接线。下游目标依赖自定义目标而非直接依赖生成文件在 Visual Studio 生成器下对 byproduct 的文件级依赖会把生产者命令复制进每个依赖项目导致核心生成运行多次。Windows 上还有一个细节当SLANG_EMBED_CORE_MODULE关闭且SLANG_LIB_TYPE为SHARED时同一自定义命令会先把slang共享库复制到slang-bootstrap旁因为slang-bootstrap位于generators/而库位于bin/Windows 加载器只搜索可执行文件自身所在目录见 source/slang-core-module/CMakeLists.txt 第 120–139 行的注释与复制逻辑。运行时核心模块缓存当SLANG_EMBED_CORE_MODULE关闭时库内没有核心模块全局会话首次使用就须从嵌入库中的源码文本编译核心模块。为避免此开销非嵌入共享构建在库旁生成缓存文件。缓存格式由 source/core/slang-builtin-module-cache.h 中BuiltinModuleCache::read/write实现文件布局为[uint64_t 库时间戳][序列化模块字节]时间戳以宿主字节序写入——因为缓存与产生它的那个共享库构建绑定并非可移植模块归档。零时间戳是失败哨兵write会拒绝它从而永远不会创建可能匹配失败哨兵的缓存该头文件第 12–41 行的注释完整说明了这一设计。该文件由构建急切写入当SLANG_EMBED_CORE_MODULE关闭且SLANG_LIB_TYPE为SHARED时source/slang/CMakeLists.txt 第 373–419 行添加generate_core_module_cache目标ALL运行 tools/slang-core-module-cache 工具并传入三个参数——链接好的slang库、上述slang-core-module-without-timestamp.bin归档、以及输出路径slang-core-module.binWindows 位于运行时输出目录其他平台位于库输出目录。工具只读取库的修改时间戳为既有归档加前缀而不是编译任何东西。注意两个.bin是不同产物slang-core-module-without-timestamp.bin是构建期传给-load-core-module的归档slang-core-module.bin是加时间戳前缀的运行时缓存。由于安装保留库的时间戳安装后的缓存保持有效而重写时间戳的打包方式会导致运行时拒绝并重新生成缓存。添加一个新的内置函数完整操作流程要向用户代码暴露新的内在函数决定归属通用语言级新增放核心模块source/slang/core.meta.slang方言专属名称放 HLSL 或 GLSL 元模块微分支持放 diff 元模块。声明函数或类型使用__intrinsic_op(IROp)或__target_intrinsic(target, text)等修饰符映射到 IR 或逐目标拼写。__target_intrinsic的用法可参考 source/slang/hlsl.meta.slang 中RayDesc的声明。若新内在函数需要发射代码中的运行时辅助函数在 prelude 下对应 prelude 中增加条目并安排发射后端将其纳入作用域。重新构建无论何种嵌入模式*.meta.slang文本都必须重新经过slang-generate并重新嵌入库中——触碰变更的元文件后先重建generate_core_module_headers目标再重建工具精确命令序列见 CLAUDE.md。SLANG_EMBED_CORE_MODULEON时重建还会复现嵌入的编译后模块元源码错误在 C 构建期暴露OFF时则在同一构建的generate_core_module步骤暴露而非只在运行时。补充测试在 tests 下添加测试用例。不在本文档范围内完整内在函数列表权威来源是各*.meta.slang文件本身在文档中枚举会复制一份生成产物并在每次变更时漂移。标准模块面向用户的文档各模块文档与源码并列存放如 source/standard-modules/neural并收录于 docs/user-guide。小结核心模块、GLSL 模块、标准模块与 prelude 构成了 Slang 编译器自带语言的四根支柱前两者以内嵌形式随libslang分发标准模块以独立.slang-module文件按版本化目录随库安装、由import按路径解析并按需加载prelude 则在构建期被slang-embed转成字符串、发射时直接写入目标源码。理解SLANG_EMBED_CORE_MODULE/SLANG_EMBED_CORE_MODULE_SOURCE两种嵌入模式、slang-bootstrap -compile-core-module的一次调用三产物、以及运行时缓存[时间戳][模块字节]的格式与失效条件是开发者在*.meta.slang中安全新增内置函数、或排查标准模块加载问题的前提。【免费下载链接】slangMaking it easier to work with shaders项目地址: https://gitcode.com/GitHub_Trending/sl/slang创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价