Slang IR Decoration 家族技术参考:基于 gap-intake 流程的逐项校验与修正记录
2026/9/20 6:07:50 网站建设 项目流程
  • 编译器
  • 图形学
  • 编程语言

【免费下载链接】slang

Making it easier to work with shaders

项目地址:https://gitcode.com/GitHub_Trending/sl/slang
点击查看免费下载

本篇技术指南以 Slang 编译器仓库中docs/generated/design/ir-reference/decorations.md的 gap-intake(文档缺口接收/校正)报告为核心主体,系统梳理 Slang IR 中Decoration家族 196 个具体 opcode 的语义、操作数编码与产生路径,并结合-dump-ir编译器实测与源码证据,逐条讲解报告中 8 个已修正(fixed)、2 个被驳回(rejected-bogus)、1 个判定越界(rejected-out-of-scope)的缺口结论。读完本文,你将掌握:如何阅读 Slang IR 转储中的各种 decoration,entryPointinterpolationModesynthesizedParameterGroup等关键装饰的精确编码规则,以及 decoration 从 AST 修饰符到 IR 的完整产生链路。

背景:什么是 gap-intake,以及本次重跑解决了什么

docs/generated/design/ir-reference/decorations.md是 Slang 仓库中按 opcode 逐个讲解Decoration家族的参考文档,覆盖 slang-ir-insts.lua 第 1756 行起的整个Decoration条目(在source_commit时共 196 个具体 opcode)。为了让这类生成式文档与源码保持同步,仓库维护了一套 gap-intake 流程:由docs/generated/design/_meta/prompts/ir-reference-decorations.md定义写作边界,逐条审计文档中的每个断言,找出"与源码不符"的缺口(gap),给出证据并决定修文(fixed)、驳回(rejected-bogus)、越界(rejected-out-of-scope)或延期(deferred)。

本报告是decorations.md页面的重跑:第一轮曾把单个缺口901ca639c751以"本机无法运行编译器、只能靠-dump-ir裁决"为由标记为 deferred。这一前提被证明是错的——构建目录中存在一个与HEAD编译器源码一致的原生 macOS-arm64slangc-version输出为2026.14.1-80-g6122d03def,且git diff --stat 6122d03def HEAD -- source/ include/为空,说明其编译器源码即HEAD本身)。实际运行-dump-ir后,该缺口从deferred转为fixed,deferred 计数归零。最终行动分布为:8 个 fixed、2 个 rejected-bogus、1 个 rejected-out-of-scope、0 个 deferred、0 个 escalated。

缺口判定总览

报告对 11 个缺口逐条给出了 Action、Evidence(源码/测试/实测证据)与 Fix summary,完整汇总如下:

Gap IDActionEvidenceFix summary
a13d8a468a77rejected-out-of-scopedocs/generated/design/_meta/prompts/ir-reference-decorations.mdlines 75-81,## Forbidden content: "Backend-specific consumption of decorations — see [../pipeline/06-emit.md]"。逐 target 列出[unroll]/[branch]在 hlsl / glsl / spirv / metal / wgsl 中变成什么的表,正属于该禁写范畴,且 callout 已链接06-emit.md
33fbeb8b7617fixedslang-lower-to-ir.cpp,位于TargetProgram::createIRModuleForLayout(行 16381):decoration 由asFuncDecl->inferredCapabilityRequirements构建,过滤出_spirv_1_0..latestSpirvAtommetallib_2_3..latestMetalAtom;没有任何[require(...)]路径会添加它。Builder 位于 slang-ir-insts.h将错误的require(...)AST 起源替换为 layout-IR 生产者与推断能力集路径,并注明只记录 SPIR-V 版本与 Metal-library 两种原子
320bf7714a3dfixedslang-ir-insts.h:getProfile()返回Profile(Profile::RawVal(getIntVal(getProfileInst())));slang-ir-insts.h 存储profile.raw;slang-lower-to-ir.cpp 传入entryPoint->getProfile()。编码见 slang-profile.h。-stage vertex时的值1entry-point-vertex-profile.slang验证扩展entryPointcallout:tag 是Profile::RawVal(高 16 位ProfileVersion、低 16 位Stage),而非裸 stage 代码
dbe97ebb7283fixedcore.meta.slang 与 L4756-4757:attribute_syntax [format(format : String)]/[vk_image_format(format : String)] : FormatAttribute;slang-ir-insts.h:addFormatDecoration(IRInst*, ImageFormat)存储getIntValue(getIntType(), IRIntegerValue(format))format行展示带引号实参,并说明操作数是字符串解析出的整数ImageFormat
e19c29a6b653fixedslang-ir-insts.h:enum class IRInterpolationMode { Linear, NoPerspective, NoInterpolation, Centroid, Sample, PerVertex };修饰符映射见 slang-lower-to-ir.cpp;源码拼写见 slang-parser.cpp 与 core.meta.slang。值 0/2/4 由interpolation-mode-{linear,nointerpolation,sample}.slang钉死interpolationMode增加完整六值映射 callout(缺口原列表漏掉了PerVertex5),并让表格行指向该 callout
7bb8913f2a18rejected-boguscore.meta.slang 声明attribute_syntax [vk_location(location : int)] : GLSLLocationAttribute,故vk_location是该属性的真实名字且可写;slang-parser.cpp(parseAttributeName)把作用域属性名中的每个::重写为_,这正是[vk::location(7)]glsl-location-decoration.slang中到达同一属性的原因。缺口"[vk_location(...)]不可写"的前提不成立行仍被改写为以用户实际书写的拼写开头
863b0c0f87dcfixedcore.meta.slang:__attributeTarget(LoopStmt)+attribute_syntax [ForceUnroll(count: int = 0)];slang-lower-to-ir.cpp 从循环语句上读取修饰符;slang-ir-insts.h:addLoopForceUnrollDecoration追加getIntValue(getIntType(), iters),尽管 Lua 条目(slang-ir-insts.lua)声明为无操作数。操作数形式由force-unroll-on-loop.slang钉死,E31002 由force-unroll-on-function-error.slang钉死ForceUnroll行修正为 builder 追加count: IRIntLit的写法(与vulkanRayPayload行一致),并记录仅限LoopStmt的属性目标和默认值0
69f3396b03ebrejected-bogus这是两个不同 opcode 而非同一名字的两种拼写。slang-ir-insts.lua 声明 decorationstreamOutputTypeDecoration;slang-ir-insts.lua 在TypeLayout下声明streamOutputTypeLayout,由 slang-ir-insts.h 的IRStreamOutputTypeLayout : IRTypeLayout包装。stream-output-type-decoration.slang匹配到的是 type-layout inst。decoration 本身仅由 slang-ir-glsl-legalize.cpp 产生,故-target hlsl转储中不可能出现
bd7183d2d708fixedslang-ir-insts.h 是addBuiltinDecoration的唯一定义,slang-lower-to-ir.cpp 是其唯一调用点,位于visitInterfaceDecl(行 12073)内、decl->findModifier<BuiltinAttribute>()之下。[builtin]声明于 core.meta.slang;core.meta.slang中 12 处、hlsl.meta.slang中 6 处使用全部位于interface声明上,包括 hlsl.meta.slang 的IBufferDataLayout——它是RWStructuredBufferhlsl.meta.slang:74)的默认布局约束将行从 "Core-module lowering" / "an inst" 收窄为interface声明上的[builtin]属性,并点名IBufferDataLayout作为普通代码会接触到的案例
93335aeba9c7fixedslang-ir-insts.h:IRConstructorDecoration::getSynthesizedStatus()读取cast<IRBoolLit>(getOperand(0));slang-ir-insts.h:addConstructorDecoration(IRInst*, bool synthesizedConstructor);唯一调用者 slang-lower-to-ir.cpp 传入constructorDecl->containsFlavor(ConstructorDecl::ConstructorFlavor::SynthesizedDefault)将已废弃的(variadic, min=1)单元格替换为(1 个无名操作数:IRBoolLit,由 getSynthesizedStatus() 读取),并说明true标记编译器合成的默认构造函数而非用户手写的__init
901ca639c751fixed重跑:通过运行编译器裁决(第一轮误以为不可能)。build-arm64/Debug/bin/slangc-version2026.14.1-80-g6122d03def)配合SLANG_ASSERT=release-assert-only,对[shader("compute")] [numthreads(1,1,1)] void computeMain(uniform float scale, uint3 tid : SV_DispatchThreadID)(函数体写outBuf[tid.x] = scale)执行slangc -dump-ir -target hlsl -entry computeMain -o out.hlsl x.slang:在AFTER collectEntryPointUniformParams及之后的所有快照中,struct %EntryPointParams上都打印[synthesizedParameterGroup];把scale移到文件作用域成为全局uniform float scale后,从AFTER collectGlobalUniformParameters起打印在struct %GlobalParams上。两者与受监控的生产者 slang-ir-entry-point-uniforms.cpp(ensureCollectedParamAndTypeHaveBeenCreated)和 slang-ir-collect-global-uniforms.cpp 一致。两个结构都不出现在LOWER-TO-IR快照中,因为 slang-emit.cpp 与 L1275 在目标降级(target lowering)期间运行两个 pass。普通数据前置条件是 slang-ir-collect-global-uniforms.cpp,用只含RWStructuredBufferTexture2D的对照组程序验证:整个转储零匹配。glsl / spirv / metal / wgsl 结果相同synthesizedParameterGroupcallout 追加第二段:给出可达的 entry-point 与 global 两种写法(含 target 与 options)、全局收集的普通数据前置条件,以及两个结构均不出现在LOWER-TO-IR快照中的说明

八个已修正缺口(fixed):文档修正背后的技术事实

requireCapabilityAtom:来自推断能力集而非[require(...)]

33fbeb8b7617指出原文档把该 decoration 的 AST 起源错误地写成require(...)属性。实际上它由 slang-lower-to-ir.cpp 中TargetProgram::createIRModuleForLayout(行 16381)从 entry point 的inferredCapabilityRequirements(推断能力需求)构建,并只记录 SPIR-V 版本原子(_spirv_1_0..latestSpirvAtom)与 Metal-library 原子(metallib_2_3..latestMetalAtom两类。推论:若在 IR 转储中看到requireCapabilityAtom,它反映的是编译器在布局阶段推断出的能力集合,而不是源码里某个[require(...)]的直接产物。Builder 入口在 slang-ir-insts.h。

entryPoint:profile tag 是Profile::RawVal,不是裸 stage 代码

320bf7714a3d修正了entryPoint装饰的 profile 操作数编码。IREntryPointDecoration::getProfile(slang-ir-insts.h)通过Profile(Profile::RawVal(getIntVal(getProfileInst())))重建Profile;slang-ir-insts.h 存储的是profile.raw;lowering 侧由 slang-lower-to-ir.cpp 传入entryPoint->getProfile()

Profile::RawVal的位布局由 slang-profile.h 的PROFILE宏钉死:TAG = (uint32_t(ProfileVersion::VERSION) << 16) | uint32_t(Stage::STAGE)——高 16 位是ProfileVersion,低 16 位是StagegetStage()raw & 0xFFFF取出,getVersion()raw >> 16取出)。因此一个用-stage vertex编译、未显式指定 profile 版本的 entry point,其 profile tag 打印为1(即裸Stage值),这一行为由entry-point-vertex-profile.slang测试钉死。读懂这一点,你在-dump-ir输出里看到[entryPoint(1, "computeMain", ...)]时就能立刻反推出 stage 与版本位。

format:操作数是字符串解析出的整数ImageFormat

dbe97ebb7283澄清了formatdecoration 的实参形态。AST 侧,core.meta.slang 与 L4756-4757 声明attribute_syntax [format(format : String)][vk_image_format(format : String)] : FormatAttribute——实参是带引号的字符串,如[format("rgba32f")],而非裸标识符。IR 侧,addFormatDecoration(IRInst*, ImageFormat)(slang-ir-insts.h)把该字符串解析出的ImageFormat枚举值经getIntValue(getIntType(), IRIntegerValue(format))存储为整数常量。所以转储中[format(N)]里的NImageFormat枚举的整数值。

interpolationMode:六值编码,不是位掩码

e19c29a6b653补充了interpolationMode的完整编码表。modeOperand是普通的整数IRInterpolationMode值(slang-ir-insts.h),不是位掩码

枚举源码修饰符
0Linearlinear
1NoPerspectivenoperspective
2NoInterpolationnointerpolation
3Centroidcentroid
4Samplesample
5PerVertexpervertex(Slang 自有)

映射发生在addVarDecorations(slang-lower-to-ir.cpp),一个源码修饰符对应一个值;源码拼写见 slang-parser.cpp 与 core.meta.slang。因此转储中出现[interpolationMode(2 : Int)]就意味着源码写的是nointerpolation。缺口原列表遗漏了PerVertex(5),这正是本次修正补齐的内容。值 0/2/4 由interpolation-mode-{linear,nointerpolation,sample}.slang三个测试钉死。

ForceUnroll:builder 追加的count: IRIntLit,且只作用于循环语句

863b0c0f87dc修正了ForceUnroll的操作数形态与属性目标。AST 侧,core.meta.slang 声明__attributeTarget(LoopStmt)+attribute_syntax [ForceUnroll(count: int = 0)],因此[ForceUnroll]只能写在循环语句上count省略时默认0。lowering 在 slang-lower-to-ir.cpp 从循环语句读取修饰符;addLoopForceUnrollDecoration(slang-ir-insts.h)总是追加getIntValue(getIntType(), iters)作为操作数——即使 Lua 条目(slang-ir-insts.lua)声明该 decoration 无操作数。这就是"builder 追加操作数"的典型例子:表格不能只看 Lua 声明,还要看 C++ builder 的实际行为。操作数形式由force-unroll-on-loop.slang钉死;把[ForceUnroll]写到函数上触发的诊断 E31002 由force-unroll-on-function-error.slang钉死。

BuiltinDecoration:只来自[builtin]属性 +interface声明

bd7183d2d708BuiltinDecoration的来源从笼统的 "Core-module lowering" 收窄为精确的"[builtin]属性(BuiltinAttribute)标注的interface声明"。证据链:addBuiltinDecoration的唯一定义在 slang-ir-insts.h,唯一调用点在 slang-lower-to-ir.cpp 的visitInterfaceDecl(行 12073)内,且受decl->findModifier<BuiltinAttribute>()保护。属性本身声明于 core.meta.slang(实际位于 L4900-L4901,__attributeTarget(DeclBase)+attribute_syntax [builtin] : BuiltinAttribute)。全仓*.meta.slang中共 18 处使用(core.meta.slang12 处、hlsl.meta.slang6 处)全部落在interface声明上,典型代表是 hlsl.meta.slang 的IBufferDataLayout——它是RWStructuredBufferhlsl.meta.slang:74)的默认布局约束,也就是说普通代码里每个RWStructuredBuffer都会通过它间接关联到BuiltinDecoration

constructor:单个无名IRBoolLit操作数标记合成构造函数

93335aeba9c7修正了constructordecoration 的操作数规格。原文档单元格写的(variadic, min=1)已过时;实际是恰好 1 个无名操作数:一个IRBoolLit,由IRConstructorDecoration::getSynthesizedStatus()(slang-ir-insts.h)以cast<IRBoolLit>(getOperand(0))读取。addConstructorDecoration(IRInst*, bool synthesizedConstructor)(slang-ir-insts.h)的唯一调用者 slang-lower-to-ir.cpp 传入constructorDecl->containsFlavor(ConstructorDecl::ConstructorFlavor::SynthesizedDefault)——即true表示这是编译器合成的默认构造函数false表示用户手写的__init

synthesizedParameterGroup:用-dump-ir实测钉死的产生时机

901ca639c751是本轮重跑的核心成果,也是唯一动用真实编译器实测裁决的缺口。第一轮因"本机无法运行编译器"将其延期,但build-arm64/Debug/bin/slangc的存在推翻了这个前提。实测条件与结论如下:

  • 工具链slangc -version2026.14.1-80-g6122d03def,且git diff --stat 6122d03def HEAD -- source/ include/为空,保证二进制与HEAD源码一致;配合SLANG_ASSERT=release-assert-only运行。
  • entry-point 形态:源码
    [shader("compute")] [numthreads(1,1,1)] void computeMain(uniform float scale, uint3 tid : SV_DispatchThreadID) { outBuf[tid.x] = scale; }

    slangc -dump-ir -target hlsl -entry computeMain -o out.hlsl x.slang编译,在AFTER collectEntryPointUniformParams及之后所有快照中,struct %EntryPointParams上都出现[synthesizedParameterGroup]

  • 全局形态:把scale移到文件作用域成为uniform float scale,marker 从AFTER collectGlobalUniformParameters起出现在struct %GlobalParams上。
  • 生产者:两者分别与 slang-ir-entry-point-uniforms.cpp(ensureCollectedParamAndTypeHaveBeenCreated,注释明确说明该 struct 是编译器为收集 entry point 的uniform/资源参数而合成的,标记它可避免类型合法化阶段对"资源从常量缓冲泄漏"的 E31106/E31107 误报)和 slang-ir-collect-global-uniforms.cpp 一致。
  • 快照时机:两个结构都不出现在LOWER-TO-IR快照中,因为 slang-emit.cpp 与 L1275 在目标降级期间运行这两个 pass——这解释了第一轮观察为何扑空:在LOWER-TO-IR阶段本来就不可能看到它们。
  • 普通数据前置条件:全局收集在全局作用域不含 "ordinary" 数据(LayoutResourceKind::Uniform)时整体跳过,见 slang-ir-collect-global-uniforms.cpp(代码注释也确认了该特殊分支的存在)。对照组程序只含RWStructuredBufferTexture2D,整个-dump-ir输出零匹配,验证了该前置条件。
  • 跨 target 一致性:glsl / spirv / metal / wgsl 目标下计数与结论相同。

这个案例示范了文档校正的完整方法论:当静态阅读无法裁决时,用与HEAD源码一致的编译器做-dump-ir差分实验,并用对照组验证边界条件。

两个被驳回的缺口(rejected-bogus):文档原样成立

[vk_location(...)]可写:缺口前提本身是错的

7bb8913f2a18声称[vk_location(...)]不可写,但这与源码矛盾。core.meta.slang 明确声明attribute_syntax [vk_location(location : int)] : GLSLLocationAttribute——vk_location正是该属性的真实名字,当然可写。[vk::location(7)]这种写法之所以也能用,是因为parseAttributeName(slang-parser.cpp)会把作用域属性名中的每个::重写为_,两条拼写最终到达同一个GLSLLocationAttribute。该行仍被改写为以用户实际书写的[vk::location(N)]拼写开头,但判定的核心结论是:原缺口不成立,驳回。

streamOutputTypeDecorationstreamOutputTypeLayout是两个 opcode

69f3396b03eb把两者误认为同一 opcode 的两种拼写。实际上:streamOutputTypeDecoration(decoration 家族)声明于 slang-ir-insts.lua,唯一生产者是 slang-ir-glsl-legalize.cpp;streamOutputTypeLayout则位于TypeLayout条目下(slang-ir-insts.lua),由 slang-ir-insts.h 的IRStreamOutputTypeLayout : IRTypeLayout包装。缺口作者在stream-output-type-decoration.slang里匹配到的其实是 type-layout inst——而真正的 decoration 只在 GLSL 合法化中产生,所以-target hlsl转储里自然找不到它。教训:同名前缀的 opcode 可能分属不同家族,判断前先查 Lua 条目所在的顶级分类。

一个越界缺口(rejected-out-of-scope):边界即文档边界

a13d8a468a77提议为[unroll]/[branch]在 hlsl / glsl / spirv / metal / wgsl 各后端中的最终形态建一张 per-target 表。这被驳回为越界,依据是 ir-reference-decorations.md 中## Forbidden content的明文规定:"Backend-specific consumption of decorations — see [../pipeline/06-emit.md]"(后端对 decoration 的消费,见 pipeline/06-emit.md)。也就是说,decorations.md只负责"decoration 是什么、怎么产生","后端怎么消费"归06-emit.md,两者以 callout 链接衔接。这条判定同时是本文读者理解文档边界的注脚:控制流提示装饰(branch/flatten/loopControl)本身不携带 IR 语义,只是透传到后端 emit 阶段选择对应的目标控制流结构。

文档主体速览:Decoration 家族的分类骨架

为了让上面每个缺口落在上下文里,这里给出decorations.md的家族分类骨架(opcode 全表见 decorations.md)。Decoration是所有装饰的公共基类,其下按用途分为十余个族:

  • Naming and provenancenameHinthighLevelDeclBuiltinDecorationKnownBuiltinDecorationUserTypeNameCOMInterfaceCOMWitnessDecorationUserExterntransitory
  • Layout and bindinglayoutAlignedAddressDecorationSizeAndAlignmentOffsetpackoffsetglslLocationglslOffsetvkStructOffsetHasExplicitHLSLBindingsynthesizedParameterGroupBinaryInterfaceTypePhysicalTypeoutput/inputglslOuterArray
  • Loop and branch hintsbranchflattenloopControlloopMaxItersloopExitPrimalValueForceUnrollloopCounterDecoration/loopCounterUpdateDecoration
  • Target-specific definition and intrinsicstargettargetIntrinsicrequirePreludeintrinsicOpspirvOpDecoration
  • Capability and availabilityrequireCapabilityAtomrequireSPIRVVersionrequireGLSLVersionrequireGLSLExtensionrequireWGSLExtensionrequireCUDASMVersionshader64BitIndexingavailableInDownstreamIR、SPIR-V 描述符索引、NVAPI 相关(requiresNVAPI/nvapiMagic/nvapiSlot);
  • Interpolation and shader IOinterpolationModeTargetSystemValuesemantic、射线载荷一族(raypayload/vulkanRayPayload/vulkanRayPayloadIn/vulkanHitAttributes/vulkanHitObjectAttributes/vulkanCallablePayload/vulkanCallablePayloadIn)、earlyDepthStencilglslFragDepthGreater/glslFragDepthLesspreciseformatperprimitive
  • Mesh shader, geometry shader, and per-vertex:图元类型一族(pointPrimitiveTypetriangleAdjPrimitiveType)、streamOutputTypeDecorationvertices/indices/primitivesHLSLMeshPayloadDecorationPositionOutput/PositionInputPerVertexstageReadAccess/stageWriteAccess
  • Entry-point and stageentryPointentryPointParam、细分/几何属性(patchConstantFuncmaxTessFactoroutputControlPointsoutputTopologypartitioningdomainmaxVertexCountinstance)、numThreadsfpDenormalPreserve/fpDenormalFlushToZerowaveSize、派生组与收敛(DerivativeGroupQuad/DerivativeGroupLinear/MaximallyReconverges/QuadDerivatives/RequireFullQuads);
  • Work-graph nodesnodeLaunchnodeMaxDispatchGridnodeDispatchGridmaxRecordsnodeIDnodeIsProgramEntrynodeArraySizeallowSparseNodesworkGraphRecordType/workGraphRecordElementType
  • Linkage and lifetimeimport/export/public/hlslExportexternCpp/externCdllImport/dllExport、CUDA/PyTorch 一族(cudaDeviceExport/CudaKernel/CudaHost/TorchEntryPoint/AutoPyBindCUDA/前后向导数引用/PyExportDecoration)、dependsOnkeepAliveTargetBuiltinVar
  • Inlining and optimizationunsafeForceInlineEarlyForceInlineAllowPreTranslationInliningnoInlinenoRefInlinealwaysFoldnoSideEffectreadNoneDynamicUniformDefaultValue等;
  • Specialization, conformance, and existentialsSpecializeDecorationSpecializationDepthDecorationSequentialIDDecorationDynamicDispatchWitnessDecorationStaticRequirementDecorationBuiltinRequirementDecorationDispatchFuncDecorationTypeConstraintDecorationResultWitnessRTTI_typeSizeAnyValueSizeSpecializationConstantDecoration
  • Differentiation markersAutoDiffOriginalValueDecorationBackwardDerivativePrimalContextDecorationPrimalContextDecorationprimalInstDecoration/diffInstDecoration/mixedDiffInstDecorationRecomputeBlockDecorationPreferCheckpointDecoration/PreferRecomputeDecoration等;
  • SPIR-V backend hintsspvBufferBlockspvBlockNonUniformResourceMemoryQualifierSetDecoration
  • Debug and reflectionDebugLocationDebugFunctionCounterBuffer
  • OtherBitFieldAccessorDecorationconstructormethodFloatingPointModeOverrideexperimentalModuleDisallowSpecializationWithExistentialsDecoration

几个值得单列的关键装饰(详情见 decorations.md 的 Notable opcodes 一节):

  • nameHint携带可读名字穿越所有 IR pass,绝大多数后端用它选择输出变量/函数名,pass 作者重写 inst 时应保留它;
  • layoutLayoutopcode(offset/size/register 绑定信息,见 metadata.md)挂到参数/类型上;
  • targetIntrinsic编码"该函数由目标特定拼写实现",2 操作数形式(capability-set +IRStringLit)与 4 操作数形式(再追加 predicate 字符串与 type scrutinee)由IRBuilder::addTargetIntrinsicDecoration(slang-ir-insts.h)按需构建,同一函数可挂多个;
  • intrinsicOp是核心模块内置函数到实际 IR opcode 的链接,单个整数操作数即kIROp_*标签;
  • branch/flatten/loopControl是纯控制流提示,无自身 IR 语义,透传给后端 emit;
  • keepAlive是 DCE 抑制装饰,前端(entry point、export 等)与 IR pass 都会添加;
  • shader64BitIndexing只挂在 entry-point 函数上(lowerFrontEndEntryPointToIR,slang-lower-to-ir.cpp),lowering 从推断能力集中查找spvShader64BitIndexingEXT原子,统一覆盖"属性写在 entry point 上 / 写在可调用函数上 / 显式[require(spvShader64BitIndexingEXT)]"三种拼写,因为 SPIR-V 的Shader64BitIndexingEXT执行模式是 entry-point 作用域的;
  • workGraphRecordType/workGraphRecordElementType声明但无生产者/消费者,名字在 slang-ir-insts-stable-names.lua 中保留,防止未来不相关 opcode 复用这些稳定身份(新式 work-graph 记录改用Type.WorkGraphRecordTypeBaseopcode);
  • BuiltinRequirementDecoration给接口的 requirement key 打上BuiltinRequirementKind角色标签(如IDifferentiable.Differential),使后续 pass 按角色而非按(语义无序的)requirement 列表位置定位内置需求。

本次重跑的方法论沉淀

从这轮 gap-intake 中可以提炼出一套可复用的文档校验方法:

  1. 静态证据优先:每条断言都能锚定到源码(Lua 声明、C++ builder/accessor、lowering 调用点、.meta.slang属性声明)或测试(*.slang测试钉死操作数值);
  2. 生成器 vs builder 的落差ForceUnroll案例表明 Lua 条目声明的操作数未必等于实际形态,必须核对 C++ builder 是否追加操作数;
  3. 同名前缀须查家族streamOutputTypeDecorationvsstreamOutputTypeLayout案例表明,opcode 归属(Decoration vs TypeLayout)决定其产生路径与可见目标;
  4. 必要时运行编译器synthesizedParameterGroup案例表明,静态阅读无法裁决时,用与HEAD一致的编译器跑-dump-ir,对照快照名(LOWER-TO-IRvsAFTER collectEntryPointUniformParams)定位 pass 时机,再用对照组验证边界条件(普通数据前置条件);
  5. 受监控路径闭环:第一轮标记的四个"被引用但未被监控"的源码文件(slang-profile.h、slang-ir-glsl-legalize.cpp、slang-ir-entry-point-uniforms.cpp、slang-ir-collect-global-uniforms.cpp)在HEAD上均已进入watched_paths(可用regenerate.py show ir-reference/decorations.md查询),且新修文本引用的901ca639c751也指向受监控路径,追踪闭环。

延伸阅读

  • ir-reference/decorations.md — 本文校验的目标文档本体,含全部 196 个 opcode 的完整表格;
  • ir-instructions.md — opcode schema、op flags、hoistable/parent 约定与"新增 opcode"工作流;
  • metadata.md —layoutdecoration 挂接的Layoutopcode 与Attropcode;
  • differentiation.md — 与 autodiff decoration 互补的 autodiffopcode
  • resources-and-atomics.md — 绑定/插值/mesh-shader decoration 所作用的资源与 shader-IO opcode;
  • modifiers.md — 产生多数 decoration 的 AST 侧修饰符;
  • 04-ast-to-ir.md — AST 修饰符如何降级为 IR decoration;
  • 05-ir-passes.md — 引入合成 decoration 的各个 pass(autodiff、linker、specialization 等);
  • 06-emit.md — 各后端在 emit 阶段如何消费 decoration(也是 out-of-scope 缺口被指向的去处);
  • glossary.md —decorationtarget intrinsicentry pointdifferential pair等术语定义。
  • 编译器
  • 图形学
  • 编程语言

【免费下载链接】slang

Making it easier to work with shaders

项目地址:https://gitcode.com/GitHub_Trending/sl/slang
点击查看免费下载

相关推荐

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询