@@ -70,3 +70,107 @@ no_ablend
7070
7171``no_ablend `` forcefully disables blending.
7272Specifying ``blend_src, blend_dst `` or ``blend_asrc, blend_adst `` will have no effect.
73+
74+ --------------------
75+ supports directives
76+ --------------------
77+
78+ In addition to supporting :ref: `shader blocks <shader-blocks >`, the ``supports `` keyword can reference
79+ several built-in directives that reserve special resources for the bindless materials system and multidraw rendering.
80+
81+ supports __static_cbuf
82+ ======================
83+
84+ ``supports __static_cbuf `` reserves a constant buffer at register **b1 ** for material parameters.
85+ This cbuffer is used by the bindless materials system to pass per-material static constants
86+ (such as bindless texture/sampler indices from ``@staticSmp ``/``@staticTex `` declarations) to the shader.
87+
88+ Use this directive in **shader blocks ** when shaders supporting the block declare material textures or other
89+ static material properties. The reserved register (b1) will not be assigned to any other resource by the compiler.
90+
91+ .. note ::
92+ If a shader inherits the b1 reservation from a supported block but does not actually declare any static
93+ constants, the compiler will automatically unreserve the slot. This only happens at the shader level;
94+ blocks always keep the reservation.
95+
96+ .. code-block :: text
97+
98+ block(scene) my_scene
99+ {
100+ supports __static_cbuf;
101+
102+ // block-level bindings go here
103+ (vs) { world_view_pos@f3 = world_view_pos; }
104+ }
105+
106+ shader my_shader
107+ {
108+ supports my_scene;
109+
110+ // material textures -- their bindless indices are stored in the b1 cbuffer
111+ texture diffuse_tex = material.texture.diffuse;
112+ texture normal_tex = material.texture[1];
113+ (ps) {
114+ diffuse_tex@staticSmp = diffuse_tex;
115+ normal_tex@staticSmp = normal_tex;
116+ }
117+ }
118+
119+ .. note ::
120+ This directive is unrelated to user-defined ``@cbuf `` bindings. ``supports __static_cbuf `` only reserves the
121+ internal material-params cbuffer at b1. You can still use ``@cbuf `` for your own constant buffers as usual.
122+
123+ supports __static_multidraw_cbuf
124+ ================================
125+
126+ ``supports __static_multidraw_cbuf `` does everything ``__static_cbuf `` does (reserves b1 for material parameters),
127+ but additionally enables **multidraw-optimized constant buffer packing **. With this directive, material parameters
128+ from multiple draw calls are packed into a single buffer, enabling indirect multidraw rendering where many objects
129+ with different materials can be drawn in one API call.
130+
131+ This directive is only meaningful on platforms that support bindless rendering:
132+
133+ - DX12
134+ - PS4 / PS5
135+ - Vulkan with bindless enabled
136+
137+ .. warning ::
138+ When ``__static_multidraw_cbuf `` is enabled, **dynamic stcode must not depend on material parameters **.
139+ With multidraw, dynamic stcode runs once per combined draw call (not per individual draw).
140+ Mixing dynamic and static (material) operands in the same stcode expression will produce a compilation error.
141+
142+ .. code-block :: text
143+
144+ if (hardware.dx12 || hardware.ps4 || hardware.ps5 || (hardware.vulkan && hardware.bindless))
145+ {
146+ supports __static_multidraw_cbuf;
147+ }
148+
149+ supports __draw_id
150+ ==================
151+
152+ ``supports __draw_id `` provides the ``get_draw_id() `` HLSL function, which returns a per-draw-call identifier.
153+ If the per-draw data is small enough to fit in a dword, it can be passed directly as the draw ID value.
154+ Otherwise, the draw ID is used to index into buffers that store per-draw or per-material data.
155+
156+ Currently only supported on **DX12 **, where the compiler generates a dedicated cbuffer at register b7 (space1)
157+ containing a ``uint __draw_id ``, and a ``get_draw_id() `` helper that reads from it.
158+ The driver fills this value for each draw call automatically.
159+
160+ On **PS4/PS5 ** and **Vulkan **, ``get_draw_id() `` is not provided by this directive. Instead, the draw ID
161+ is emulated through instance offsets and wave operations.
162+ See the ``SUPPORT_MULTIDRAW `` / ``ENABLE_MULTI_DRAW `` macros in shader include files for platform-specific setup.
163+
164+ .. code-block :: text
165+
166+ if (hardware.dx12)
167+ {
168+ supports __draw_id;
169+ hlsl(vs) {
170+ // get_draw_id() is now available
171+ // draw ID packs both instance offset and material offset
172+ uint draw_id = get_draw_id();
173+ uint inst_offset = (draw_id >> MATRICES_OFFSET_SHIFT) << 2;
174+ uint material_offset = draw_id & MATERIAL_OFFSET_MASK;
175+ }
176+ }
0 commit comments