<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/99193>99193</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
Implement the `PrimitiveIndex` HLSL Function
</td>
</tr>
<tr>
<th>Labels</th>
<td>
metabug,
backend:DirectX,
HLSL,
backend:SPIR-V,
bot:HLSL
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
farzonl
</td>
</tr>
</table>
<pre>
- [ ] Implement `PrimitiveIndex` clang builtin,
- [ ] Link `PrimitiveIndex` clang builtin with `hlsl_intrinsics.h`
- [ ] Add sema checks for `PrimitiveIndex` to `CheckHLSLBuiltinFunctionCall` in `SemaChecking.cpp`
- [ ] Add codegen for `PrimitiveIndex` to `EmitHLSLBuiltinExpr` in `CGBuiltin.cpp`
- [ ] Add codegen tests to `clang/test/CodeGenHLSL/builtins/PrimitiveIndex.hlsl`
- [ ] Add sema tests to `clang/test/SemaHLSL/BuiltIns/PrimitiveIndex-errors.hlsl`
- [ ] Create the `int_dx_PrimitiveIndex` intrinsic in `IntrinsicsDirectX.td`
- [ ] Create the `DXILOpMapping` of `int_dx_PrimitiveIndex` to `161` in `DXIL.td`
- [ ] Create the `PrimitiveIndex.ll` and `PrimitiveIndex_errors.ll` tests in `llvm/test/CodeGen/DirectX/`
- [ ] Create the `int_spv_PrimitiveIndex` intrinsic in `IntrinsicsSPIRV.td`
- [ ] In SPIRVInstructionSelector.cpp create the `PrimitiveIndex` lowering and map it to `int_spv_PrimitiveIndex` in `SPIRVInstructionSelector::selectIntrinsic`.
- [ ] Create SPIR-V backend test case in `llvm/test/CodeGen/SPIRV/hlsl-intrinsics/PrimitiveIndex.ll`
## DirectX
| DXIL Opcode | DXIL OpName | Shader Model | Shader Stages |
| ----------- | ----------- | ------------ | ------------- |
| 161 | PrimitiveIndex | 6.3 | ('library', 'intersection', 'anyhit', 'closesthit') |
## SPIR-V
<div id="header">
# [PrimitiveId](https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/PrimitiveId.html)
## Short Description
<div class="sectionbody">
PrimitiveId - Primitive ID
</div>
</div>
<div id="content" class="loadable">
<div class="sect1">
## <a href="#_description" class="anchor"></a> Description
<div class="sectionbody">
<div class="dlist">
` PrimitiveId `
Decorating a variable with the ` PrimitiveId ` built-in decoration will
make that variable contain the index of the current primitive.
<div class="paragraph">
The index of the first primitive generated by a drawing command is zero,
and the index is incremented after every individual point, line, or
triangle primitive is processed.
</div>
<div class="paragraph">
For triangles drawn as points or line segments (see <a
href="https://registry.khronos.org/vulkan/specs/1.3-extensions/html/vkspec.html#primsrast-polygonmode"
rel="noopener" target="_blank">Polygon Mode</a> ), the primitive index
is incremented only once, even if multiple points or lines are
eventually drawn.
</div>
<div class="paragraph">
Variables decorated with ` PrimitiveId ` are reset to zero between each
instance drawn.
</div>
<div class="paragraph">
Restarting a primitive topology using primitive restart has no effect on
the value of variables decorated with ` PrimitiveId ` .
</div>
<div class="paragraph">
In tessellation control and tessellation evaluation shaders, it will
contain the index of the patch within the current set of rendering
primitives that corresponds to the shader invocation.
</div>
<div class="paragraph">
In a geometry shader, it will contain the number of primitives presented
as input to the shader since the current set of rendering primitives was
started.
</div>
<div class="paragraph">
In a fragment shader, it will contain the primitive index written by the
mesh shader if a mesh shader is present, or the primitive index written
by the geometry shader if a geometry shader is present, or with the
value that would have been presented as input to the geometry shader had
it been present.
</div>
<div class="paragraph">
In an intersection, any-hit, or closest hit shader, it will contain the
index within the geometry of the triangle or bounding box being
processed.
</div>
</div>
<div class="admonitionblock note">
<table>
<colgroup>
<col style="width: 50%" />
<col style="width: 50%" />
</colgroup>
<tbody>
<tr>
<td class="icon"><em></em></td>
<td class="content"><div class="title">
Note
</div>
<div class="paragraph">
<p>When the <code> PrimitiveId </code> decoration is applied to an
output variable in the mesh shader or geometry shader, the resulting
value is seen through the <code> PrimitiveId </code> decorated input
variable in the fragment shader.</p>
</div>
<div class="paragraph">
<p>The fragment shader using <code> PrimitiveId </code> will need to
declare either the <code> MeshShadingNV </code> ,
<code> MeshShadingEXT </code> , <code> Geometry </code> or
<code> Tessellation </code> capability to satisfy the requirement SPIR-V
has to use <code> PrimitiveId </code> .</p>
</div></td>
</tr>
</tbody>
</table>
</div>
<div class="sidebarblock">
<div class="content">
<div class="title">
Valid Usage
</div>
<div class="ulist">
- <a href="#VUID-PrimitiveId-PrimitiveId-04330"
id="VUID-PrimitiveId-PrimitiveId-04330"></a> <span class="vuid">
VUID-PrimitiveId-PrimitiveId-04330 </span>
The ` PrimitiveId ` decoration **must** be used only within the
` MeshEXT ` , ` MeshNV ` , ` IntersectionKHR ` , ` AnyHitKHR ` ,
` ClosestHitKHR ` , ` TessellationControl ` ,
` TessellationEvaluation ` , ` Geometry ` , or ` Fragment `
` Execution ` ` Model `
- <a href="#VUID-PrimitiveId-Fragment-04331"
id="VUID-PrimitiveId-Fragment-04331"></a> <span class="vuid">
VUID-PrimitiveId-Fragment-04331 </span>
If pipeline contains both the ` Fragment ` and ` Geometry `
` Execution ` ` Model ` and a variable decorated with ` PrimitiveId `
is read from ` Fragment ` shader, then the ` Geometry ` shader
**must** write to the output variables decorated with ` PrimitiveId `
in all execution paths
- <a href="#VUID-PrimitiveId-Fragment-04332"
id="VUID-PrimitiveId-Fragment-04332"></a> <span class="vuid">
VUID-PrimitiveId-Fragment-04332 </span>
If pipeline contains both the ` Fragment ` and ` MeshEXT ` or
` MeshNV ` ` Execution ` ` Model ` and a variable decorated with
` PrimitiveId ` is read from ` Fragment ` shader, then the ` MeshEXT `
or ` MeshNV ` shader **must** write to the output variables decorated
with ` PrimitiveId ` in all execution paths
- <a href="#VUID-PrimitiveId-Fragment-04333"
id="VUID-PrimitiveId-Fragment-04333"></a> <span class="vuid">
VUID-PrimitiveId-Fragment-04333 </span>
If ` Fragment ` ` Execution ` ` Model ` contains a variable decorated
with ` PrimitiveId ` , then either the ` MeshShadingEXT ` ,
` MeshShadingNV ` , ` Geometry ` or ` Tessellation ` capability
**must** also be declared
- <a href="#VUID-PrimitiveId-PrimitiveId-04334"
id="VUID-PrimitiveId-PrimitiveId-04334"></a> <span class="vuid">
VUID-PrimitiveId-PrimitiveId-04334 </span>
The variable decorated with ` PrimitiveId ` within the
` TessellationControl ` , ` TessellationEvaluation ` , ` Fragment ` ,
` IntersectionKHR ` , ` AnyHitKHR ` , or ` ClosestHitKHR `
` Execution ` ` Model ` **must** be declared using the ` Input `
` Storage ` ` Class `
- <a href="#VUID-PrimitiveId-PrimitiveId-04335"
id="VUID-PrimitiveId-PrimitiveId-04335"></a> <span class="vuid">
VUID-PrimitiveId-PrimitiveId-04335 </span>
The variable decorated with ` PrimitiveId ` within the ` Geometry `
` Execution ` ` Model ` **must** be declared using the ` Input ` or
` Output ` ` Storage ` ` Class `
- <a href="#VUID-PrimitiveId-PrimitiveId-04336"
id="VUID-PrimitiveId-PrimitiveId-04336"></a> <span class="vuid">
VUID-PrimitiveId-PrimitiveId-04336 </span>
The variable decorated with ` PrimitiveId ` within the ` MeshEXT ` or
` MeshNV ` ` Execution ` ` Model ` **must** be declared using the
` Output ` ` Storage ` ` Class `
- <a href="#VUID-PrimitiveId-PrimitiveId-04337"
id="VUID-PrimitiveId-PrimitiveId-04337"></a> <span class="vuid">
VUID-PrimitiveId-PrimitiveId-04337 </span>
The variable decorated with ` PrimitiveId ` **must** be declared as a
scalar 32-bit integer value
- <a href="#VUID-PrimitiveId-PrimitiveId-07040"
id="VUID-PrimitiveId-PrimitiveId-07040"></a> <span class="vuid">
VUID-PrimitiveId-PrimitiveId-07040 </span>
The variable decorated with ` PrimitiveId ` within the ` MeshEXT `
` Execution ` ` Model ` **must** also be decorated with the
` PerPrimitiveEXT ` decoration
</div>
</div>
</div>
</div>
</div>
</div>
## Test Case(s)
### Example 1
```hlsl
//dxc PrimitiveIndex_test.hlsl -T lib_6_8 -enable-16bit-types -O0
export uint fn() {
return PrimitiveIndex();
}
```
### SPIRV Example(s):
### Example 2
```hlsl
//dxc PrimitiveIndex_spirv_test.hlsl -T ps_6_8 -E fn -enable-16bit-types -spirv -fspv-target-env=universal1.5 -fcgl -O0
uint fn( ) : SV_Target {
return PrimitiveIndex();
}
```
## HLSL:
Retrieves the autogenerated index of the primitive within the geometry inside the bottom-level acceleration structure instance.
## Syntax
```
uint PrimitiveIndex();
```
## Remarks
For **D3D12\_RAYTRACING\_GEOMETRY\_TYPE\_TRIANGLES**, this is the triangle index within the geometry object.
For **D3D12\_RAYTRACING\_GEOMETRY\_TYPE\_PROCEDURAL\_PRIMITIVE\_AABBS**, this is the index into the AABB array defining the geometry object.
This function can be called from the following raytracing shader types:
* [**Any Hit Shader**](https://github.com/MicrosoftDocs/win32/blob/docs/desktop-src//direct3dhlsl/any-hit-shader.md)
* [**Closest Hit Shader**](https://github.com/MicrosoftDocs/win32/blob/docs/desktop-src//direct3dhlsl/closest-hit-shader.md)
* [**Intersection Shader**](https://github.com/MicrosoftDocs/win32/blob/docs/desktop-src//direct3dhlsl/intersection-shader.md)
## See also
* [Direct3D 12 Raytracing HLSL Reference](https://github.com/MicrosoftDocs/win32/blob/docs/desktop-src//direct3dhlsl/direct3d-12-raytracing-hlsl-reference.md)
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzEW1tz46jy_zTkhbJLlmI7eciDxo5nXP-5VZKd_-5TCkltixMMOoCceD_9qQZdbeee2Z1KlSVomu5fX2gEw4zhawlwQcafyHh-wkqbK32xYvpvJcVJorLdxYCS8SdKxnO63BQCNiAtJZPgp-YbbvkWljKDBzIJaCqYXNOk5MJyScIZCeJ27Fcu714wjN5zmyNdLoy45dJqLg1PzTAnk6DHMM4yamDDaJpDemfoSunj_K3C9hlSffl6_fWTn2hRytRyJWdMCKTiEqmuYcMcJZfrYVoUxyZNVQZrkM9NeLnhtjPf5UOh23lmn6vm5yaxYKypODqgSLjANhIuZiqDzyBxDhIuKvwMCRd9iYaI5KPgPcEfsaiYO2GXR5gPQGulzdE5ZhqYBWpzQOZc2tvs4fYQrcbGFTTLxuZzriG1fw5t9jTr-Z_Lrz-Kb6wouFwjS7V6ckarKPaPJqPWIMjj6YkObT30nsNkdth3WwHjSTzKfiYhtpsDI5JwUWlLwsXzQJpi-yokr38ur34dUW8pqetaSmN16eLhGgSkVml0TJr2Zj6cUah70FyuHQYbVlDKbeVMT4npIu2ReUkUkyg27q1RgEyC4TFIkMngF01YegcyczDTlBl4Bmo3NwkX6LWDNsccho6onBr_woiEEa2t5NumM4qOQ38UGK-08_6dbfz7dc4y0PSbykB0G64tW4PBlorRoP1Hn3k_bBh0GI0mI9ff18U1TYaR-yXhGQmngiea6R0JpyTEtimXFrQBZ4-2lcldzm37ngplwNi67byeusHIW6VqimYZ31KekWhOwjAHVJ6EIYkumzFo1VbYjIznJDzLrS0MOkO4IOFCw5obq3fDu1wrqcxQacxU21LcMbSoKcDZbzSMBvBgQRquXLrauO7cbkTPutnQN533Bc-VtnQOJtW8cCB0dUgFM8arUWGEy2NXlw5_Omjxp8t5w4iEi4xvW-2PtXQBS5W0IC0Jw-78QrGMJQJ6QB6VcrSHtYM7mjGaa1h5MhJGt1lH5_5UTKa5qi3mpGUkunwHSIeEmeAYoB2SSUC7WOI7JUE8h1RpZl3CoVumOWLgK4YqRR0Mc8vigEuaVWMVlhhCkCDesDtMbcy2rBBtxqXjxl3UqJV7SUutse4pavbDx5QpmGZrzYq8q9DNPr8V16bDja5BgmYWMprsKKOZZveoZao2G0yt3NC_QStfU2FDKyDHdSXVriyDjLKVBU1hC3qHBHzLs5IJWiiOTjSjgkvAX6VJEFvNmVwL6AjCDS20SsEYyIbP-OhzWi-UpvUUxukkKTNeFkOVdsJQA2uU3WBSMgDOO0kQt_75QZmgygHbO6Sowj9CxY1mxg4KJXZrJTcqc1EVxBqEn18qVaB5MDAs02uwvv02EUzeeYV_-tEuzXeiBBNMOHPW6kDsFsIg3rOckmJHlUydeWALkvIV3ZTC8gIt1APNUKaBBDGS2ZIJsfPwvtdiv6pAMHW4QNYU5AehxTRQDQbcio_uSROw9wCSAktzVFAay2QKHyPbFRjLdBX8LZpWFUqo9Y6WBrvaDu3pac4MlYrCagWppS5doT22TJSA4bh9jc7vVWLpKnoDQvhUhAlHK-Hqp14HoHz-0biCwaBbcFsnr0czVcFsmjsFqt46daGh1IpqkJmr2UgQN2AZnwdTpTWYQsnMbQlwtJ-ccrlVqRPnAxBgdA1qA1bvKvYd1XopWJabBDRK3ZG0QJ_DiMFUiCFUlHZPWsPR655SvsvwnhkSxM5Z3p_znHorzVxOe0a9vZRA7zW3FiQuATbH8N6AyRsLrCijvYYGCp_Pn2JJgtgz3Ufesz1o3GddL7EkiH3cOHe5V6XIaM62QBMM-8YydN8u-xPkDK3HbW_cR0Avab-GnVEmdwNXqjpFqtqV5vwZ47j05RBsI6nRogq1ZvlUmiaqlBk6VqIeaAJ1fL1gJX1WWZZtlOSulBIqvaNS2f3Cz7pi0DdEs1SJtVZl0W2gxu6QBBne88zmJIrpOCDhGJc1XFrfREzCxcFs1lV8zZtuH7OuWjx1taYvK2HTlJedR5s9Mratij3tHmKW205t_B3xOoT6JU4VzVCt_8_BO4BDBxf4y_7CUOHgezqFJjeUFYXgkGEgMAxDVVqMi6birFyrG9hKH8uPSKXBYD3gfMvHITfUgJNOq3Kdv1pKyHygOoZ9kfaS2NCPL7qmfwuYN4esq6X7RXK7OJXgECVBnEEqsA4BbnPQ--p_A5PjdpvL9fdfe4x8LX2c-PLPm0PqLuPPtX36VK6o7pDddFf0PmnKCpZwwe0OXcMwy81qVxn5vyX3VWG7k8Yixipamhea9wlr7UcWvuneWy9-saGTXV6WsgzPIGHa5aun9379SH6EqB_Prk4VPKN_GLaGlwtV7m8zB0d2wr_-WM4HHVx7z8FpFAV-d9Bs0F82oLd3JtHMFEx2ZduWPGtEo8_zrMyNbJAjbo4pvXlkD9zJSCSMSRhvSgQCn2gC6FTV7qNd6xw_HItR4cJhEvggqNownjpNy86q-39frnp9sdx94bbT2jCf-dW43-t-u5Ezq2rk_dFdmsu2XO6yaeO0avSf7OmiTkD-857nd_kAadmyQEX9R7v6E-CL_KVm7ew0es5ZDqnf6Sl9hkfdZLmiBS_Abb6risfQRHU-onThqT9v97B8CWZuYOczzfO7K8eVG6qBZXSl1eZQmN56KBuBe3auaJyI--6O9TDUVeneWvySDaAXUVImBIVG94LZ3LzVR8JX-Uj40T4SfqSPdLOF0r0kUieM9zhNw3A_w73JaTrCOsZVbugIW5Unb_Uix_XRTwkf60XRq7wo-mgvih7zogNjPOcAjbcd84KnEW0s3K0GK4t2K7u9dWSvSnxs-ajco1_TocBNJXc85TBhFC6zVamavaP2OH1t7XH6G2qP00drj1ek-mOlxhNr_kvX-76ndWz8qvqkNvVBefKiZe9YiVXbvtrp1I65dN9IuoyvrdJsDQ3bGZrplRXIvsHGr_Wa8W_wmvEHe83bSpK32Ka7kP3wub5m_DusNXmttSa_wVqT32Gt9xcHLzPfP2mt6WutNf0N1pp-iLWeBJcZyhxXkzLBNI3CQcKt-9i6Bu0PU94K4zQ4fd2muh7wkTAiz9_s9G_LUJ3yoTt1189_gm6kqAOs3fO_6tPzx7Q0Nw1uwFg6YwZIeGaa2xYOWE-BRJcPbFMIoCN_8u__3IWyoDrzzR7SvdsstxaMdbfO6OCGCp7cTm7P6AAkmmkwmiTcDuyuAEMHP6r4hodCaUtLLi1dSXcD5pyS6ScHI6UabKnl3jSeikRIRKbzroB9HdyNolqTWtkorvU90DV8ja6m4Hrb17gwXuFLupLH1XaD6GBliu3An1oPQG5JNC8l34I2TIyGYzpYpWvRYkSCuMWHOoCimF7_ur1xHCq43N_5GwCrQHCXCmtwrsBqDv4IEigrrWrvQvQPNpujrWNHMlwanvkzv0RZqzYDAVsQlKUpCKi-fvnLZqUGWh9ND3vuer2Tlj00d1AauR0mTyjaVbFhdgUbpu9MexXCB_Q8mo9CMp7dXsV_3VzFs-X3z_j2-fLHt8ubq7_w-eavn5fu92oZf__89fLaj_TbG25wt9s7fnrioCr5D6T1wdqbZPh59WN2Of_jKv7q35bfljfLX64rjj99ekS06mqKrLbISEmZ1mxHM1hxWddZx-W8QUar6nouTZnE9JcyIaDa4LvTCSWEcndkNNtZzVJ8rPbrLgIaB8MkSsafvKCx3NEv3FaX8Crhj9w3W3Obl8kwVRsSLr7xVCujVnau3NWSey6jkISLRKgEI9a3ZmDurCoGRqdVJLurglHmwjtcVAeRg-o4ZZNV-bArXrXj-LdErE5HnxWzu5v6N-TsnvEeCNpGM4BbPXtu4O9vRnM6CulV6zmYkugVrECDTOEfUqN-HYzCQevFA3crVdeyeMVOsosoO4_O2QlcjKbhaDQJpsH4JL9IR-PR2eQMUpacjs_Ow_NJMoXJ-RiSM5ZEaXjCL8IgPA2mo0kYjEan4yFk4fnZNJmeBew0OBufk9MANoyLoRDbzVDp9Qk3poSL8_PReXQiWALCuP8eEIYbsCwp166om5EwrO7dkihuLi9XPf7e-AFZdZ7VdChLorimHc9P9AUKMUjKtSGngeDGmlYsdwp00f4fhEdvJTtj1vf7T0otLp4wZXVH2M1baIV5CD0MIUAbehS2F-H_AgAA___beila">