<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">