spirv-cross(1)
๐ spirv-cross(1) ๐
User Commands โข the manual page, part 1 of 4 โข bestie edition, no cap
โจ NAME โจ
spirv-cross โ a tool designed for parsing and converting SPIR-V to other shader languages. periodt.
๐ฆ SYNOPSIS ๐ฆ
spirv-cross <...>
๐ DESCRIPTION ๐
๐ Basic ๐
[SPIR-V file](-is stdin) and[--output <output path>]โ if the output path isn't provided, it prints output tostdout. slay.[--dump-resources]โ prints a basic reflection of the SPIR-V module along with other output. โจ[--help]โ prints this help message.
๐ Select backend ๐
By default, OpenGL-style GLSL is the target, with #version and GLSL/ESSL information inherited from the SPIR-V module if present.
--vulkan-semanticsor-Vโ emit Vulkan GLSL instead of plain GLSL. Makes use of Vulkan-only features to match SPIR-V.--mslโ emit Metal Shading Language (MSL).--hlslโ emit HLSL.--reflectโ emit JSON reflection.--cppโ DEPRECATED. Emits C++ code.
๐ Common options ๐
--entry nameโ use a specific entry point. By default, the first entry point in the module is used.--stage <stage (vert, frag, geom, tesc, tese comp)>โ forces use of a certain shader stage. Can disambiguate the entry point if more than one entry point exists with same name, but different stage.--emit-line-directivesโ if SPIR-V hasOpLinedirectives, aim to emit those accurately in output code as well.--rename-entry-point <old> <new> <stage>โ renames an entry point from what is declared in SPIR-V to code output. Mostly relevant for HLSL or MSL.--rename-interface-variable <in|out> <location> <new_variable_name>โ rename an interface variable based on location decoration.--force-zero-initialized-variablesโ forces temporary variables to be initialized to zero. Can be useful in environments where compilers do not allow potentially uninitialized variables. This usually comes up with Phi temporaries.--fixup-clipspaceโ fixup Z clip-space at the end of a vertex shader. The behavior is backend-dependent. GLSL: Rewrites[0, w]Z range (D3D/Metal/Vulkan) to GL-style[-w, w]. HLSL/MSL: Rewrites[-w, w]Z range (GL) to D3D/Metal/Vulkan-style[0, w].--flip-vert-yโ invertsgl_Position.y(or equivalent) at the end of a vertex shader. This is equivalent to using negative viewport height.
๐ GLSL options ๐
--esโ force ESSL.--no-esโ force desktop GLSL.--version <GLSL version>โ e.g.--version 450will emit'#version 450'in shader. Code generation will depend on the version used.--flatten-uboโ emit UBOs as plain uniform arrays which are suitable for use withglUniform4*v(). This can be an optimization on GL implementations where this is faster or works around buggy driver implementations. E.g.:uniform MyUBO { vec4 a; float b, c, d, e; };will be emitted asuniform vec4 MyUBO[2];Caveat: You cannot mix and match floating-point and integer in the same UBO with this option. Legacy GLSL/ESSL (where this flattening makes sense) does not support bit-casting, which would have been the obvious workaround.--extension extโ add#extensionstring of your choosing to GLSL output. Useful if you use variable name remapping to something that requires an extension unknown to SPIRV-Cross.--remove-unused-variablesโ do not emit interface variables which are not statically accessed by the shader.--separate-shader-objectsโ redeclaregl_PerVertexblocks to be suitable for desktop GL separate shader objects.--glsl-emit-push-constant-as-uboโ instead of a plain uniform of struct for push constants, emit a UBO block instead.--glsl-emit-ubo-as-plain-uniformsโ instead of emitting UBOs, emit them as plain uniform structs.--glsl-remap-ext-framebuffer-fetch input-attachment color-locationโ remaps an input attachment to useGL_EXT_shader_framebuffer_fetch.gl_LastFragData[location]is read from. The attachment to read from must be declared as an output in the shader.--vulkan-glsl-disable-ext-samplerless-texture-functionsโ do not allow use ofGL_EXT_samperless_texture_functions, even in Vulkan GLSL. Use oftexelFetchand similar might have to create dummy samplers to work around it.--combined-samplers-inherit-bindingsโ inherit binding information from the textures when building combined image samplers from separate textures and samplers.--no-support-nonzero-baseinstanceโ when usinggl_InstanceIndexwith desktop GL, assume that base instance is always0, and do not attempt to fix upgl_InstanceIDto match Vulkan semantics.--pls-in format input-nameโ remaps a subpass input with name into aGL_EXT_pixel_local_storageinput. Entry in PLS block is ordered where first--pls-inmarks the first entry. Can be called multiple times. Formats allowed:r11f_g11f_b10f,r32f,rg16f,rg16,rgb10_a2,rgba8,rgba8i,rgba8ui,rg16i,rgb10_a2ui,rg16ui,r32ui. Requires ESSL.--pls-out format output-nameโ remaps a color output with name into aGL_EXT_pixel_local_storageoutput. Entry in PLS block is ordered where first--pls-outputmarks the first entry. Can be called multiple times. Formats allowed:r11f_g11f_b10f,r32f,rg16f,rg16,rgb10_a2,rgba8,rgba8i,rgba8ui,rg16i,rgb10_a2ui,rg16ui,r32ui. Requires ESSL.--remap source_name target_name componentsโ remaps a variable to a different name with N components. Main use case is to remap a subpass input togl_LastFragDepthARM. E.g.:uniform subpassInput uDepth; --remap uDepth gl_LastFragDepthARM 1 --extension GL_ARM_shader_framebuffer_fetch_depth_stencil--no-420pack-extensionโ do not make use ofGL_ARB_shading_language_420packin older GL targets to supportlayout(binding).--remap-variable-type <variable_name> <new_variable_type>โ remaps a variable type based on name. Primary use case is supporting external samplers in ESSL for video rendering on Android where you could remap a texture to a YUV one.--glsl-force-flattened-io-blocksโ always flatten I/O blocks and structs.
๐ฆ MSL options ๐ฆ
--msl-version <MMmmpp>โ uses a specific MSL version, e.g.--msl-version 20100for MSL 2.1.--msl-capture-outputโ writes geometry varyings to a buffer instead of as stage-outputs.--msl-swizzle-texture-samplesโ works around lack of support forVkImageViewcomponent swizzles. This has a massive impact on performance and bloat. Do not use this unless you are absolutely forced to. To use this feature, the API side must pass down swizzle buffers. Should only be used by translation layers as a last resort. Recent Metal versions do not require this workaround.--msl-iosโ target iOS Metal instead of macOS Metal.--msl-pad-fragment-outputโ always emit color outputs as 4-component variables. In Metal, the fragment shader must emit at least as many components as the render target format.--msl-domain-lower-leftโ use a lower-left tessellation domain.--msl-argument-buffersโ emit Indirect Argument buffers instead of plain bindings. Requires MSL 2.0 to be enabled.--msl-texture-buffer-nativeโ enable native support for texel buffers. Otherwise, it is emulated as a normal texture.--msl-framebuffer-fetchโ implement subpass inputs with frame buffer fetch. Emits[[color(N)]]inputs in fragment stage. Requires an Apple GPU.--msl-emulate-cube-arrayโ emulate cube arrays with 2D array and manual math.--msl-discrete-descriptor-set <index>โ when using argument buffers, forces a specific descriptor set to be implemented without argument buffers. Useful for implementing push descriptors in emulation layers. Can be used multiple times for each descriptor set in question.--msl-device-argument-buffer <descriptor set index>โ use device address space to hold indirect argument buffers instead of constant. Comes up when trying to support argument buffers which are larger than 64 KiB.--msl-multiviewโ enableSPV_KHR_multiviewemulation.--msl-multiview-no-layered-renderingโ don't set[[render_target_array_index]]in multiview shaders. Useful for devices which don't support layered rendering. Only effective when--msl-multiviewis enabled.--msl-view-index-from-device-indexโ treat the view index as the device index instead. For multi-GPU rendering.--msl-dispatch-baseโ add support forvkCmdDispatchBase()or similar APIs. Offsets the workgroup ID based on a buffer.--msl-dynamic-buffer <set index> <binding>โ marks a buffer as having dynamic offset. The offset is applied in the shader with pointer arithmetic. Useful for argument buffers where it is non-trivial to apply dynamic offset otherwise.--msl-inline-uniform-block <set index> <binding>โ in argument buffers, mark an UBO as being an inline uniform block which is embedded into the argument buffer itself.--msl-decoration-bindingโ use SPIR-V bindings directly as MSL bindings. This does not work in the general case as there is no descriptor set support, and combined image samplers are split up. However, if the shader author knows of binding limitations, this option will avoid the need for reflection on Metal side.--msl-force-active-argument-buffer-resourcesโ (bestie, the description for this one is in the next part, hold on to your seat โจ)
Always emit resources which are part of argument buffers. This makes sure that similar shaders with same resource declarations can share the argument buffer as declaring an argument buffer implies an ABI. ๐ซถ
--msl-force-native-arraysโ instead of implementing array types as a templated value type alastd::array<T>, use plain, native arrays. It's giving worse code-gen ngl, but it can work around driver bugs on certain driver revisions of certain Intel-based Macbooks where template arrays break. ๐ญ--msl-disable-frag-depth-builtinโ disablesFragDepthoutput. Useful if your pipeline does not enable depth, since pipeline creation might otherwise fail. ๐--msl-disable-frag-stencil-ref-builtinโ disableFragStencilRefoutput. Useful if your pipeline does not enable stencil output, because pipeline creation might otherwise fail. ๐--msl-enable-frag-output-mask <mask>โ only selectively enable fragment outputs. Useful if your pipeline does not enable fragment output for certain locations, as pipeline creation might otherwise fail. ๐--msl-no-clip-distance-user-varyingโ do not emit user varyings to emulategl_ClipDistancein fragment shaders. โจ--msl-shader-input <index> <format> <size>โ specify the format of the shader input at <index>. <format> can beany32,any16,u16,u8, orother, to indicate a 32-bit opaque value, 16-bit opaque value, 16-bit unsigned integer, 8-bit unsigned integer, or other-typed variable. <size> is the vector length of the variable, which must be greater than or equal to that declared in the shader. Useful if shader stage interfaces don't match up, as pipeline creation might otherwise fail. ๐ฅ--msl-multi-patch-workgroupโ use the new style of tessellation control processing, where multiple patches are processed per workgroup. This should increase throughput by ensuring all the GPU's SIMD lanes are occupied, but heads up, it is not compatible with the old style. In addition, this style also passes input variables in buffers directly instead of using vertex attribute processing. In a future version of SPIRV-Cross, this will become the default. ๐--msl-vertex-for-tessellationโ when handling a vertex shader, marks it as one that will be used with a new-style tessellation control shader. The vertex shader is output to MSL as a compute kernel which outputs vertices to the buffer in the order they are received, rather than in index order as with--msl-capture-outputnormally. ๐ฆ--msl-additional-fixed-sample-mask <mask>โ set an additional fixed sample mask. If the shader outputs a sample mask, then the final sample mask will be a bitwise AND of the two. ๐--msl-arrayed-subpass-inputโ assume that images of dimensionSubpassDatahave multiple layers. Layered input attachments are accessed relative toBuiltInLayer. This option has no effect if multiview is also enabled. ๐ธ--msl-r32ui-linear-texture-align <alignment>โ the required alignment of linear textures of formatMTLPixelFormatR32Uint. This is used to align the row stride for atomic accesses to such images. โญ--msl-r32ui-linear-texture-align-constant-id <id>โ the function constant ID to use for the linear texture alignment. On MSL 1.2 or later, you can override the alignment by setting this function constant. ๐--msl-texture-1d-as-2dโ emitImagevariables of dimensionDim1Dastexture2d. In Metal, 1D textures do not support all features that 2D textures do. Use this option if your code relies on these features. ๐--msl-ios-use-simdgroup-functionsโ usesimd_*()functions for subgroup ops instead ofquad_*(). Recent Apple GPUs support SIMD-groups larger than a quad. Use this option to take advantage of this support. ๐ฅ--msl-emulate-subgroupsโ assume subgroups of size 1. Intended for Vulkan Portability implementations where Metal support for SIMD-groups is insufficient for true subgroups. ๐ญ--msl-fixed-subgroup-size <size>โ assign a constant <size> to theSubgroupSizebuiltin. Intended for Vulkan Portability implementations whereVK_EXT_subgroup_size_controlis not supported or disabled. If0, assume variable subgroup size as actually exposed by Metal. ๐--msl-force-sample-rate-shadingโ force fragment shaders to run per sample. This adds a[[sample_id]]parameter if none is already present. ๐
๐ฅ HLSL OPTIONS ๐ฅ
--shader-modelโ enables a specific shader model, e.g.--shader-model 50for SM 5.0. ๐--hlsl-enable-compatโ allow point size and point coord to be used, even if they won't work as expected.PointSizeis ignored, andPointCoordreturns(0.5, 0.5). ๐--hlsl-support-nonzero-basevertex-baseinstanceโ support base vertex and base instance by emitting a special cbuffer declared as:
cbuffer SPIRV_Cross_VertexInfo
{
int SPIRV_Cross_BaseVertex;
int SPIRV_Cross_BaseInstance;
};
--hlsl-auto-binding (push, cbv, srv, uav, sampler, all)โ do not emit any: register(#)bindings for specific resource types, and rely on the HLSL compiler to assign something. ๐--hlsl-force-storage-buffer-as-uavโ always emit SSBOs as UAVs, even when marked as read-only. Normally, SSBOs marked withNonWritablewill be emitted as SRVs. ๐--hlsl-nonwritable-uav-texture-as-srvโ emitNonWritablestorage images as SRV textures instead of UAV. Using this option messes with the type system. SPIRV-Cross cannot guarantee that this will work. One major problem area with this feature is function arguments, where we won't know if we're seeing a UAV or SRV. Shader must ensure that read/write state is consistent at all call sites. ๐ญ--set-hlsl-vertex-input-semantic <location> <semantic>โ emits a specific vertex input semantic for a given location. Otherwise,TEXCOORD#is used as semantics, where#is location. โจ--hlsl-enable-16bit-typesโ enables native use ofhalf/int16_t/uint16_tandByteAddressBufferinteraction with these types. Requires SM 6.2. ๐ฆ--hlsl-flatten-matrix-vertex-input-semanticsโ emits matrix vertex inputs with input semantics as if they were independent vectors, e.g.TEXCOORD{2,3,4}rather than matrix formTEXCOORD2_{0,1,2}. ๐ธ
๐ OBSCURE OPTIONS ๐
These options are not meant to be used on a regular basis. They have some occasional uses in the test suite. ๐
--force-temporaryโ aggressively emit temporary expressions instead of forwarding expressions. Very rarely used and under-tested. ๐--revisionโ prints build timestamp and Git commit information (updated when cmake is configured). โญ--iterations iterโ recompiles the same shader over and over, benchmarking related. ๐--disable-storage-image-qualifier-deductionโ if storage images are received without anynonwritableornonreadableinformation, do not attempt to analyze usage, and always emit read/write state. ๐--flatten-multidimensional-arraysโ do not support multi-dimensional arrays and flatten them to one dimension. ๐ง--cpp-interface-name <name>โ emit a specific class name in C++ codegen. ๐
๐ซถ USAGE ๐ซถ
Usage: spirv-cross <...>
๐ธ Basic ๐ธ
[SPIR-V file](-is stdin)[--output <output path>]โ if not provided, prints output tostdout. ๐[--dump-resources]โ prints a basic reflection of the SPIR-V module along with other output. โจ[--help]โ prints this help message. ๐
๐ Select backend ๐
By default, OpenGL-style GLSL is the target, with #version and GLSL/ESSL information inherited from the SPIR-V module if present. ๐
--vulkan-semantics,-Vโ emit Vulkan GLSL instead of plain GLSL. Makes use of Vulkan-only features to match SPIR-V. ๐ฅ--mslโ emit Metal Shading Language (MSL). ๐--hlslโ emit HLSL. โญ--reflectโ emit JSON reflection. ๐ฆ--cppโ DEPRECATED. Emits C++ code. ๐
๐ Common options ๐
--entry nameโ use a specific entry point. By default, the first entry point in the module is used. ๐--stage <stage (vert, frag, geom, tesc, tese comp)>โ forces use of a certain shader stage. Can disambiguate the entry point if more than one entry point exists with same name, but different stage. ๐ธ--emit-line-directivesโ if SPIR-V hasOpLinedirectives, aim to emit those accurately in output code as well. โจ--rename-entry-point <old> <new> <stage>โ renames an entry point from what is declared in SPIR-V to code output. Mostly relevant for HLSL or MSL. ๐--rename-interface-variable <in|out> <location> <new_variable_name>โ rename an interface variable based on location decoration. ๐--force-zero-initialized-variablesโ forces temporary variables to be initialized to zero. Can be useful in environments where compilers do not allow potentially uninitialized variables. This usually comes up with Phi temporaries. ๐ฅ--fixup-clipspaceโ fixup Z clip-space at the end of a vertex shader. The behavior is backend-dependent. GLSL: rewrites[0, w]Z range (D3D/Metal/Vulkan) to GL-style[-w, w]. HLSL/MSL: rewrites[-w, w]Z range (GL) to D3D/Metal/Vulkan-style[0, w]. ๐ฆ--flip-vert-yโ invertsgl_Position.y(or equivalent) at the end of a vertex shader. This is equivalent to using negative viewport height. โญ
๐ GLSL options ๐
--esโ force ESSL. ๐--no-esโ force desktop GLSL. ๐--version <GLSL version>โ e.g.--version 450will emit'#version 450'in shader. Code generation will depend on the version used. ๐--flatten-uboโ
okay so this one's the tail end of the flatten-the-UBOs situation ๐
โ it spits your UBOs out as plain uniform arrays, the kind that play nice with glUniform4*v(). It can be a real optimization on GL implementations where that path is faster, and it also dodges some genuinely cursed buggy driver behaviour. Like, look at this glow-up:
uniform MyUBO { vec4 a; float b, c, d, e; };
gets emitted as
uniform vec4 MyUBO[2];
โ ๏ธ Caveat bestie, no cap: you literally cannot mix floating-point and integer in the same UBO with this on. Legacy GLSL/ESSL (the only place this flattening even makes sense) doesn't support bit-casting, which would've been the obvious workaround. So it's giving "pick a lane." ๐ญ
--extensionext โ drops an#extensionstring of your choosing straight into the GLSL output. Super useful when you're using variable name remapping to something that needs an extension SPIRV-Cross has never heard of. โจ--remove-unused-variablesโ don't emit interface variables that the shader never statically accesses. If nobody's reading it, it's not invited to the party. ๐--separate-shader-objectsโ redeclaresgl_PerVertexblocks so they're suitable for desktop GL separate shader objects. Desktop GL girlies, this one's for you. ๐ซถ--glsl-emit-push-constant-as-uboโ instead of a plain uniform of struct for push constants, emit a UBO block instead. Switching up the fit. ๐--glsl-emit-ubo-as-plain-uniformsโ instead of emitting UBOs, emit them as plain uniform structs. The reverse slay. ๐--glsl-remap-ext-framebuffer-fetchinput-attachment color-location โ remaps an input attachment to useGL_EXT_shader_framebuffer_fetch.gl_LastFragData[location]is what gets read from. Heads up: the attachment you're reading from must be declared as an output in the shader, periodt.--vulkan-glsl-disable-ext-samplerless-texture-functionsโ don't allow use ofGL_EXT_samperless_texture_functions, even in Vulkan GLSL. UsingtexelFetchand friends might force you to create dummy samplers to work around it. ๐ญ--combined-samplers-inherit-bindingsโ inherit binding info from the textures when building combined image samplers out of separate textures and samplers. Sharing is caring. ๐--no-support-nonzero-baseinstanceโ when usinggl_InstanceIndexwith desktop GL, assume the base instance is always0, and don't bother trying to fix upgl_InstanceIDto match Vulkan semantics. No extra work, no extra stress. ๐ธ--pls-informat input-name โ remaps a subpass input with name into aGL_EXT_pixel_local_storageinput. The entry's position in the PLS block is ordered so that the first--pls-inmarks the first entry. Can be called multiple times. Formats allowed:r11f_g11f_b10f,r32f,rg16f,rg16,rgb10_a2,rgba8,rgba8i,rgba8ui,rg16i,rgb10_a2ui,rg16ui,r32ui. Requires ESSL. ๐--pls-outformat output-name โ remaps a color output with name into aGL_EXT_pixel_local_storageoutput. Same ordering rules: the first--pls-outputmarks the first entry. Can be called multiple times. Formats allowed:r11f_g11f_b10f,r32f,rg16f,rg16,rgb10_a2,rgba8,rgba8i,rgba8ui,rg16i,rgb10_a2ui,rg16ui,r32ui. Requires ESSL. ๐--remapsource_name target_name components โ remaps a variable to a different name with N components. The main character use case here is remapping a subpass input togl_LastFragDepthARM. E.g.:
uniform subpassInput uDepth; --remap uDepth gl_LastFragDepthARM 1 --extension GL_ARM_shader_framebuffer_fetch_depth_stencil
--no-420pack-extensionโ do not make use ofGL_ARB_shading_language_420packin older GL targets just to supportlayout(binding). Living without it, we can do it. ๐ช--remap-variable-type<variable_name> <new_variable_type> โ remaps a variable type based on its name. Primary use case: supporting external samplers in ESSL for video rendering on Android, where you could remap a texture to a YUV one. Android girlies rise. ๐--glsl-force-flattened-io-blocksโ always flatten I/O blocks and structs. Flatten everything, bestie. ๐ฆ
๐ MSL options ๐
--msl-version<MMmmpp> โ uses a specific MSL version, e.g.--msl-version 20100for MSL 2.1. Set the vibe, choose your version. โญ--msl-capture-outputโ writes geometry varyings to a buffer instead of as stage-outputs. Rerouting the mail. ๐ฆ--msl-swizzle-texture-samplesโ works around the lack of support forVkImageViewcomponent swizzles.
๐จ Bestie this one has a massive impact on performance and bloat. Do not use this unless you are absolutely, genuinely forced to. To use it, the API side must pass down swizzle buffers. It should only ever be used by translation layers as a last resort. Recent Metal versions do not require this workaround, so likeโฆ check first. ๐
--msl-iosโ target iOS Metal instead of macOS Metal. ๐ฑ--msl-pad-fragment-outputโ always emit color outputs as 4-component variables. In Metal, the fragment shader must emit at least as many components as the render target format. Pad it out. โจ--msl-domain-lower-leftโ use a lower-left tessellation domain. ๐ฆ--msl-argument-buffersโ emit Indirect Argument buffers instead of plain bindings. Requires MSL 2.0 to be enabled. ๐--msl-texture-buffer-nativeโ enable native support for texel buffers. Otherwise, it gets emulated as a normal texture. Fake it till you make it. ๐--msl-framebuffer-fetchโ implement subpass inputs with frame buffer fetch. Emits[[color(N)]]inputs in the fragment stage. Requires an Apple GPU. ๐--msl-emulate-cube-arrayโ emulate cube arrays with a 2D array and manual math. Doing the math ourselves because we're capable like that. ๐งฎ--msl-discrete-descriptor-set<index> โ when using argument buffers, forces a specific descriptor set to be implemented without argument buffers. Super useful for implementing push descriptors in emulation layers. Can be used multiple times, once for each descriptor set in question. ๐--msl-device-argument-buffer<descriptor set index> โ use the device address space to hold indirect argument buffers instead ofconstant. Comes up when you're trying to support argument buffers larger than 64 KiB. Big buffer energy. ๐ฅ--msl-multiviewโ enableSPV_KHR_multiviewemulation. ๐--msl-multiview-no-layered-renderingโ don't set[[render_target_array_index]]in multiview shaders. Useful for devices that don't support layered rendering. Only effective when--msl-multiviewis enabled. โ ๏ธ--msl-view-index-from-device-indexโ treat the view index as the device index instead. For multi-GPU rendering. Teamwork. ๐ซถ--msl-dispatch-baseโ add support forvkCmdDispatchBase()or similar APIs. Offsets the workgroup ID based on a buffer. ๐--msl-dynamic-buffer<set index> <binding> โ marks a buffer as having a dynamic offset. The offset gets applied in the shader with pointer arithmetic. Useful for argument buffers where applying a dynamic offset is otherwise non-trivial. ๐ง--msl-inline-uniform-block<set index> <binding> โ in argument buffers, mark a UBO as being an inline uniform block which is embedded into the argument buffer itself. Nesting era. ๐ช--msl-decoration-bindingโ use SPIR-V bindings directly as MSL bindings. This does not work in the general case, because there's no descriptor set support and combined image samplers get split up. However, if the shader author knows about the binding limitations, this option will avoid the need for reflection on the Metal side. YMMV, iykyk. ๐--msl-force-active-argument-buffer-resourcesโ always emit resources which are part of argument buffers. This makes sure similar shaders with the same resource declarations can share the argument buffer, since declaring an argument buffer implies an ABI. ๐ค--msl-force-native-arraysโ rather than implementing array types as a templated value type alastd::array<T>, use plain, native arrays. This leads to worse code-gen, but it can work around driver bugs on certain driver revisions of certain Intel-based Macbooks where template arrays break. Fixing the laptop, not the code. ๐ป--msl-disable-frag-depth-builtinโ disablesFragDepthoutput. Useful if the pipeline does not enable depth, since pipeline creation might otherwise fail. ๐--msl-disable-frag-stencil-ref-builtinโ disableFragStencilRefoutput. Useful if the pipeline does not enable stencil output, since pipeline creation might otherwise fail. ๐--msl-enable-frag-output-mask<mask> โ only selectively enable fragment outputs. Useful if the pipeline does not enable fragment output for certain locations, since pipeline creation might otherwise fail. ๐ฏ--msl-no-clip-distance-user-varyingโ do not emit user varyings to emulategl_ClipDistancein fragment shaders. โ๏ธ--msl-shader-input<index> <format> <size> โ specify the format of the shader input at <index>. <format> can be'any32','any16','u16','u8', or'other', to indicate a 32-bit opaque value, 16-bit opaque value, 16-bit unsigned integer, 8-bit unsigned integer, or other-typed variable. <size> is the vector length of the variable, which must be greater than or equal to that declared in the shader. Useful if shader stage interfaces don't match up, since pipeline creation might otherwise fail. ๐งฉ--msl-multi-patch-workgroupโ use the new style of tessellation control processing, where multiple patches are processed per workgroup. This should increase throughput by ensuring all the GPU's SIMD lanes are occupied, but it is not compatible with the old style. In addition, this style also passes input variables in buffers directly instead of using vertex attribute processing. In a future version of SPIRV-Cross, this will become the default. Future is now-ish. ๐ฎ--msl-vertex-for-tessellationโ when handling a vertex shader, marks it as one that will be used with a new-style tessellation control shader. The vertex shader is output to MSL as a compute kernel which outputs vertices to the buffer in the order they are received, rather than in index order as with--msl-capture-outputnormally. Order matters, bestie. ๐--msl-additional-fixed-sample-mask<mask> โ set an additional fixed sample mask. If the shader outputs a sample mask, then the final sample mask will be a bitwise AND of the two. ๐--msl-arrayed-subpass-input
Also, quick note on the option from literally one second ago (the layered-attachment one, you know the one ๐
): Assume that images of dimension SubpassData have multiple layers. Layered input attachments are accessed relative to BuiltInLayer. And heads up bestie โ this option has no effect if multiview is also enabled. It's giving "mutually exclusive," fr fr.
--msl-r32ui-linear-texture-align <alignment>โ the required alignment of linear textures of formatMTLPixelFormatR32Uint. It's used to align the row stride for atomic accesses to those images. Alignment matters, no cap ๐--msl-r32ui-linear-texture-align-constant-id <id>โ the function constant ID you use for that linear texture alignment. On MSL 1.2 or later, you can override the alignment by setting this function constant. Override era โจ--msl-texture-1d-as-2dโ emitImagevariables of dimensionDim1Dastexture2d. In Metal, 1D textures do not support all features that 2D textures do. Use this option if your code relies on those features. Fake it till you make it ๐--msl-ios-use-simdgroup-functionsโ usesimd_*()functions for subgroup ops instead ofquad_*(). Recent Apple GPUs support SIMD-groups larger than a quad, so flip this on to actually take advantage of that. Bigger groups, bigger slay ๐ฅ--msl-emulate-subgroupsโ assume subgroups of size 1. Intended for Vulkan Portability implementations where Metal's support for SIMD-groups is just not enough for true subgroups. Pretend era, but on purpose ๐--msl-fixed-subgroup-size <size>โ assign a constant <size> to theSubgroupSizebuiltin. Intended for Vulkan Portability implementations whereVK_EXT_subgroup_size_controlis not supported or disabled. If0, assume variable subgroup size as actually exposed by Metal. Pick your fighter ๐ธ--msl-force-sample-rate-shadingโ force fragment shaders to run per sample. This adds a[[sample_id]]parameter if none is already present. Per sample, per moment, main character energy ๐
๐ฅ HLSL options ๐ฅ
--shader-modelโ enables a specific shader model, e.g.--shader-model 50for SM 5.0.--hlsl-enable-compatโ allow point size and point coord to be used, even if they won't work as expected.PointSizeis ignored, andPointCoordreturns(0.5, 0.5). So likeโฆ it compiles. That's the vibe ๐ญ--hlsl-support-nonzero-basevertex-baseinstanceโ support base vertex and base instance by emitting a special cbuffer declared as:
cbuffer SPIRV_Cross_VertexInfo
{
int SPIRV_Cross_BaseVertex;
int SPIRV_Cross_BaseInstance;
};
--hlsl-auto-binding (push, cbv, srv, uav, sampler, all)โ do not emit any: register(#)bindings for specific resource types, and rely on the HLSL compiler to assign something. Delegate era, we love a handoff ๐ซถ--hlsl-force-storage-buffer-as-uavโ always emit SSBOs as UAVs, even when they're marked as read-only. Normally, SSBOs marked withNonWritableget emitted as SRVs. No read-only privilege here, they're all UAVs now ๐--hlsl-nonwritable-uav-texture-as-srvโ emitNonWritablestorage images as SRV textures instead of UAV.
โ ๏ธ Using this option messes with the type system. SPIRV-Cross cannot guarantee that this will work. One major problem area with this feature is function arguments, where we won't know if we're seeing a UAV or SRV. Shader must ensure that read/write state is consistent at all call sites. Bestie. Be careful. This one is genuinely unhinged ๐
--set-hlsl-vertex-input-semantic <location> <semantic>โ emits a specific vertex input semantic for a given location. Otherwise,TEXCOORD#is used as semantics, where#is location. Custom naming rights, iconic ๐--hlsl-enable-16bit-typesโ enables native use ofhalf/int16_t/uint16_tandByteAddressBufferinteraction with these types. Requires SM 6.2. Gatekeeping, but respectfully โจ--hlsl-flatten-matrix-vertex-input-semanticsโ emits matrix vertex inputs with input semantics as if they were independent vectors, e.g.TEXCOORD{2,3,4}rather than matrix formTEXCOORD2_{0,1,2}. Un-matrix-ify the whole situation ๐
๐ซฃ Obscure options ๐ซฃ
These options are not meant to be used on a regular basis. They have some occasional uses in the test suite. So like, not your everyday thing. You've been warned, bestie ๐
--force-temporaryโ aggressively emit temporary expressions instead of forwarding expressions. Very rarely used and under-tested. Under-tested fr fr, tread lightly ๐--revisionโ prints build timestamp and Git commit information (updated when cmake is configured). Receipts, literally ๐งพ--iterations iterโ recompiles the same shader over and over, benchmarking related. Over and over and over, it's giving treadmill energy ๐โโ๏ธ--disable-storage-image-qualifier-deductionโ if storage images are received without any nonwritable or nonreadable information, do not attempt to analyze usage, and always emit read/write state. No detective work today, we assume the most permissive โจ--flatten-multidimensional-arraysโ do not support multi-dimensional arrays and flatten them to one dimension. One dimension only, we keep it simple ๐--cpp-interface-name <name>โ emit a specific class name in C++ codegen. Name it, own it ๐
and that's the whole page, bestie, we made it to the end ๐ฅน
This gorgeous little manual is for spirv-cross, and it was dated June 2021 โ the page identifies itself as spirv-cross(1), so that's the source/version-and-date energy right there. Go forth and cross some SPIR-V, you absolute icon ๐๐
๐ฆ where this page comes from
- debian bookworm: spirv-cross 2021.01.15+1.3.239.0-1 ยท Apache-2.0
- debian trixie: spirv-cross 2021.01.15+1.4.304.1-2 ยท Apache-2.0
- ubuntu jammy: spirv-cross 2021.01.15-5 ยท Apache-2.0
- ubuntu noble: spirv-cross 2021.01.15+1.3.239.0-1build1 ยท Apache-2.0
- ubuntu questing: spirv-cross 2021.01.15+1.4.321.0-1
- ubuntu resolute: spirv-cross 2021.01.15+1.4.335.0-1 ยท Apache-2.0
- ubuntu stonking: spirv-cross 2021.01.15+1.4.341.0-1 ยท Apache-2.0
- ๐ girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms