<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/99231>99231</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
Implement the `SetMeshOutputCounts` 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 `SetMeshOutputCounts` clang builtin,
- [ ] Link `SetMeshOutputCounts` clang builtin with `hlsl_intrinsics.h`
- [ ] Add sema checks for `SetMeshOutputCounts` to `CheckHLSLBuiltinFunctionCall` in `SemaChecking.cpp`
- [ ] Add codegen for `SetMeshOutputCounts` to `EmitHLSLBuiltinExpr` in `CGBuiltin.cpp`
- [ ] Add codegen tests to `clang/test/CodeGenHLSL/builtins/SetMeshOutputCounts.hlsl`
- [ ] Add sema tests to `clang/test/SemaHLSL/BuiltIns/SetMeshOutputCounts-errors.hlsl`
- [ ] Create the `int_dx_SetMeshOutputCounts` intrinsic in `IntrinsicsDirectX.td`
- [ ] Create the `DXILOpMapping` of `int_dx_SetMeshOutputCounts` to `168` in `DXIL.td`
- [ ] Create the `SetMeshOutputCounts.ll` and `SetMeshOutputCounts_errors.ll` tests in `llvm/test/CodeGen/DirectX/`
- [ ] Create the `int_spv_SetMeshOutputCounts` intrinsic in `IntrinsicsSPIRV.td`
- [ ] In SPIRVInstructionSelector.cpp create the `SetMeshOutputCounts` lowering and map it to `int_spv_SetMeshOutputCounts` in `SPIRVInstructionSelector::selectIntrinsic`.
- [ ] Create SPIR-V backend test case in `llvm/test/CodeGen/SPIRV/hlsl-intrinsics/SetMeshOutputCounts.ll`
## DirectX
| DXIL Opcode | DXIL OpName | Shader Model | Shader Stages |
| ----------- | ----------- | ------------ | ------------- |
| 168 | SetMeshOutputCounts | 6.5 | ('mesh',) |
## SPIR-V
# [OpSetMeshOutputsEXT](https://registry.khronos.org/SPIR-V/specs/unified1/SPIRV.html#OpSetMeshOutputsEXT):
## Description:
Reserved.
[Capability](https://registry.khronos.org/SPIR-V/specs/unified1/SPIRV.html#Capability):
**MeshShadingEXT**
[Reserved](https://registry.khronos.org/SPIR-V/specs/unified1/SPIRV.html#Unified).
<table>
<colgroup>
<col style="width: 25%" />
<col style="width: 25%" />
<col style="width: 25%" />
<col style="width: 25%" />
</colgroup>
<thead>
<tr>
<th>Word Count</th>
<th>Opcode</th>
<th>Results</th>
<th>Operands</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p>3</p></td>
<td class="tableblock halign-left valign-top"><p>5295</p></td>
<td
class="tableblock halign-left valign-top"><p><em><id></em><br />
<em>Vertex Count</em></p></td>
<td
class="tableblock halign-left valign-top"><p><em><id></em><br />
<em>Primitive Count</em></p></td>
</tr>
</tbody>
</table>
## Test Case(s)
### Example 1
```hlsl
//dxc SetMeshOutputCounts_test.hlsl -T lib_6_8 -enable-16bit-types -O0
[numthreads(1, 1, 1)]
[outputtopology("triangle")]
[shader("mesh")]
void fn(in uint gi : SV_GroupIndex, in uint vi : SV_ViewID) {
SetMeshOutputCounts(1, 1);
}
```
### SPIRV Example(s):
### Example 2
```hlsl
//dxc SetMeshOutputCounts_spirv_test.hlsl -T lib_6_8 -E fn -enable-16bit-types -spirv -fspv-target-env=universal1.5 -fcgl -O0
struct MeshPerVertex {
float4 position : SV_Position;
};
[numthreads(1, 1, 1)]
[outputtopology("triangle")]
[shader("mesh")]
void fn(in uint gi : SV_GroupIndex, in uint vi : SV_ViewID,
out vertices MeshPerVertex verts[3], out indices uint3 primitiveInd[3]) {
SetMeshOutputCounts(1, 1);
}
```
## HLSL:
This function sets the actual number of outputs from the threadgroup.
## Syntax
```c++
void SetMeshOutputCounts(
uint numVertices,
uint numPrimitives);
```
## Remarks
At the beginning of the shader the implementation internally sets a
count of vertices and primitives to be exported from a threadgroup to 0.
It means that if a mesh shader returns without calling this function,
it will not output any mesh. This function sets the actual number of
outputs from the threadgroup.
Some restrictions on the function use and interactions with output arrays follow.
1. This function can only be called once per shader.
2. This call must occur before any writes to any of the
[shared output arrays](https://microsoft.github.io/DirectX-Specs/d3d/MeshShader.html#shared-output-arrays).
The validator will verify this is the case.
3. If the compiler can prove that this function is not called,
then the threadgroup doesn't have any output.
If the shader writes to any of the
[shared output arrays](https://microsoft.github.io/DirectX-Specs/d3d/MeshShader.html#shared-output-arrays),
compilation and shader validation will fail.
If the shader does not call any of these functions,
the compiler will issue a warning,
and no rasterization work will be issued.
4. Only the input values from the first active thread are used.
5. This call must dominate all writes to
[shared output arrays](https://microsoft.github.io/DirectX-Specs/d3d/MeshShader.html#shared-output-arrays).
In other words, there must not be any execution path
that even appears to reach any writes to any output array
without first having executed this call.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzUWVtv2zoS_jXMy8CGTfkSP_ghceKugXZTNN1s3wJaGkncUKRAUkp8fv1iSMmXxmna3T3YngPhxBwOZ4bfNxxeKpyThUZcsuk1m95ciMaXxi5zYf8wWl1sTbZbDoBNr4FNb2BT1Qor1B7YbHSP_hO68q7xdeNXptHesdkIUiV0AdtGKi814ys2ujoY-Cj108-OhWfpS1IulVOPUnsrtZOpG5ZsNjqxepVl4LASkJaYPjnIjf2BE2-oc0Wqf_t4__E6els3OvXS6JVQirSkjiYqETSlLoZpXZ_znJoMC9Q_5fW2kv7I6e1LbQ_OVh868XuePDrvOosBMsbXJGN8vTIZfkBNPhhfd0g6xtdnwhoSsG9i-QMnhErnIUS8ecvDAK019ryjlUXhEXyJ5EFq_5i9PL4B3p78DqnNPhlupMXUfxv67Mf2b75tPt7Vn0RdS12QSZO_79YbIKXx7PJAEhl619s5sGNaCZ29ofDYYRX1IvrRpVJt9Yphxtfd3Blfv4-tq9tfB_f-8-bLw5nJbjSEro123jZh2dyjwtQbS6kL6XtgkFtlntFKXQRIKlEDSN-l27sBB7NvRMCSK5ZcudDaT4XNRsNzCJGRwQNsRfqEOguoQyocvoN88M34mvJ6cKhMbywz1eU-fTxhPIGeuSibr4CyCu5qWuBw1P67qGL7vhQZWvhkMlTHgnsvCnQk6QwNDv_BO-3XgsGRofHsMjp6PaEgnw2n4S_jl4zPK3Ql43Mq93zRW9lPN6K8FxEJd_WJYXf77Sub3jB-WXpfO-KQrxlfWyyk83Y3fCqt0cYNjS06_AdEgKsxwN5omUvMxj03w9JXivHknBu-IPMndKBLrawpi2IXsNHVF3RoW8yGner0eiVqsZVK-t2fEeqR9RAhhPjoo_iJb6mLED_JALow2fS6j_TPiOofUc74oschWXmxVciS29hKjSqsaepjATi_I5UbxvmzzHxJ8-FTRh8Hiuw3U2Z8_WoevkSRHVr2qIMlt_80NoOwHuLwIDzqj4v5fN8XdI3y7q2BaIXOXvdSy560TgOks9rZcDM6VzkXcQjkbZVJn6AUShZ6oDD30Mbf3tSMcxqarAiJJHqqo4R8Zv8Tu1O-mP7QNBtd_cfGWbLCiv7ymfIsuZYZ47OCfkVHsTNZbe1JDgTxA1qPL8fE9tq_X6yfraykly3-Srivs-gkb0hwtLxHp4XyK-2PK-GQ8UtHZWrUV0uIGqR0-yLomgBj6p2N4hdOgKOuKGUv6bl95ZH22XBWhMFXUHL7OHu8hAFqCmgwnm2lH_hdjQ4Gd6N9VdZN5UuLInOMX44ZX0H_vwUVxKBjghdvaqNMsQtbFvdWCl0oJDqOVF3YWKNK3NUO3a2RGeSa8UupoZHaQyGBasr9w-MHqh0bneELee_7233_g8TnzU3cHa9j8OeON4cpLCgHaC--OcbxFOpQqnvAe076ze0MJfyXKXG1tO0bxNxCrs_TE0bBIHd1O_DCFugHqFuW3DRatmidUOPhFAZ5WqgDl_EkBxTCZ7TdQuzBWuTKCD-B2jhJ-3QP6-eufQAr_vjL5UU8MS1M46FF62WK7jsoSOzY9DoJ-_wKSFXqLGiS0QTqviBsdLZX_O8TrkuicOPrk-trKR3k3Z0ZHNJVsUQQqW-EAt1UW7R0x4oIO8itqYJG5CTstMPTQ-JOe_FyqDh9ACnj1_R1MJ-fA6V7AFY31UMHX8QUAPY9-4LpDrM9nuc-li9YCfvkouzKh8C3WEit6cJi8iCIGRF-yv5dRAQ4pPZotVBqF5ERtENQqDR0zy7de_aMhZv2FgFfamM9ZhEwcQwXaYRbzMZDhUIT4sKDzEEAZWQfkEXfWO3C8wnlSCqUorD9MWURHOnhWSoF2viOKRB6F6wN4ScpZqOrnyD53lQIFp23MthzYHRQ3TtoHAZIAniiUwpPQH1k1oqdg9woZZ47s-MhfBdnKjQYrXYEJs0cMzA6RajRdgB1Q3k_lLSgapwHk6aNhS3mxmIA4tlKH6mhVuQ9VNZQDyzZPo7t3AG8kqk1zuR-WEhfNtuhNIer--C-O35nScb4uj_oo-2P39HLIHoZdF7iWRy-lhhOFZnwxkYeW7Qy30WmZaSLbrPdjJMhwCbmbmqqWiq0Aa7amhZjMp3kCJmgzIgwHpaTL1F_TzNkBp1mfO6hFG1EL0Y97EZtTlbNW8gC_N_B7SYaIYoLmvKyC7xDnKQB8lxIdX6KhMgev6NpukPSuxNQD6wEy9K5BkHAs7BUdg6qFI02YIXzaOUfXTDGPsVxW4xD-5vrZAhwRysiVCpNiLZCNXi0XnNpnaeVLdueVRAWaU32Vqavl0tmKqmFRyDJntDfZn1sNBhfEprG0iFgRVO1GGMnXrYxTfEF0yZgWAtf7ukQHrBFDaKuUdiQqhZFWp4rDEeT7Mb3xTciW4qWKnD0hFlcZgTk8CJbJtkiWYgLXI7nfDyejUfz8UW53KYTvpjOk0maLxCTmcgnY5zNJ4jz8XjGswu55CM-Gc3HMz4az6fj4STlmCxwnkyml5fjSc4mI6woO5VqK7r3X4S0WC4WPBlfKLFF5cKzPx1ovNg2RTjTrBjn3XsYS672b4xdT3z2faXWvyf0Hcaz5KrXnd5c2CUFMdg2hWOTkZIuPIt1YXnpFS4P_7bw43dDsgr9a_1FY9XyNKG6NEpNxfi6e8ALzmtr_oWpZ3wdcKC0ilC0S_7vAAAA__9q19x8">