Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
196 changes: 196 additions & 0 deletions proposals/NNNN-feature-profiles.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,196 @@
---
title: "[NNNN] - Feature-based Target Profiles"
params:
authors:
- llvm-beanz: Chris Bieneman
status: Under Consideration
sponsors:
- llvm-beanz: Chris Bieneman
---

## Introduction

This proposal seeks to introduce a new more formalized way of specifying target
profiles as a set of features to allow the compiler to utilize when generating
outputs. This proposal pairs stricter availability checks with explicit opt-in
mechanisms for optional features to help avoid the compiler introducing
unexpected dependencies on optional features which may not be widely supported.

## Motivation

Today DXC and Clang both implicitly and aggressively opt in to optional features
which may not be supported by all devices. This places a burden on users to
ensure that they are aware of the potential impacts on deployment for shaders
utilizing features which they may or may not have intended.

This feature addresses this problem by defining clear target profiles derived
from DirectX Shader Models for DirectX targets and [Vulkan
Profiles](https://github.com/KhronosGroup/Vulkan-Profiles) for Vulkan, and
compiler features to enable opting in to optional features that layer on top of
the specified target profile.

## Proposed solution

The core of this proposal revolves around a new definition for "target profiles"
that the shader compiler will translate to available feature sets. Target
profiles is a term of art in the FXC and DXC compilers surfaced to users via the
`-T` flag.

This proposal does not change the behavior for any of the values supported by
the `-T` flag in existing compilers. The current profiles map to shader stage
and shader model version and will enable a shader-model feature set and _all_
optional features.

Target profiles should be flexible and easy to define. A target profile may
either be supported on a single target (e.g. a Vulkan profile may only be
supported when targeting Vulkan SPIRV), or it may be supported across all
targets. A target profile should specify a name and a set of target definitions
where each target definition is: a base target triple, a list of shader stages,
and a set of optional features on top of that base.

This pattern applies to existing target profiles. For example the following
would be a definition of the `6_0` profile for Shader Model 6.0:

```
ProfileName: 6_0
TargetDefinitions:
- BaseTriple: dxil-shadermodel1.0
Stages: [pixel, vertex, geometry, hull, domain, compute]
RequiredFeatures:
- Doubles
- ComputeShadersPlusRawAndStructuredBuffers
- UAVsAtEveryStage
- Max64UAVs
- MinimumPrecision
- DX11_1_DoubleExtensions
- DX11_1_ShaderExtensions
- LEVEL9ComparisonFiltering
- TiledResources
- StencilRef
- InnerCoverage
- TypedUAVLoadAdditionalFormats
- ROVs
- ViewportAndRTArrayIndexFromAnyShaderFeedingRasterizer
- WaveOps
- Int64Ops
```

This pattern can also support more flexible profile definitions such as a
profile for Android 15 based on the Khronos-vended Vulkan profile:

```
ProfileName: Android15
TargetDefinitions:
- BaseTriple: spirv-vulkan1.3
Stages: [pixel, vertex, compute] # Not really sure what all Android supports...
RequiredFeatures:
- VK_KHR_maintenance5
- VK_KHR_shader_float16_int8
- VK_KHR_16bit_storage
- VK_KHR_vertex_attribute_divisor
- VK_EXT_custom_border_color
- VK_EXT_device_memory_report
- VK_EXT_external_memory_acquire_unmodified
- VK_EXT_index_type_uint8
- VK_EXT_load_store_op_none
- VK_EXT_primitive_topology_list_restart
- VK_EXT_provoking_vertex
- VK_EXT_scalar_block_layout
- VK_EXT_surface_maintenance1
- VK_EXT_swapchain_maintenance1
- VK_EXT_4444_formats
- VK_ANDROID_external_format_resolve
- VK_GOOGLE_surfaceless_query
```

Features marked "Required" are enabled in the compiler and available to use
without triggering diagnostics when the target profile is specified. Features
not explicitly required are treated as unavailable unless they have been
explicitly enabled by the user.

A target profile does not force required features into the final compiled
program; only _used_ features will be captured in shader annotations (e.g.
feature flags, annotating instructions, or metadata).

### Overriding Profile Settings

A target profile should initialize a set of base configurations. Those
configurations can be overridden with additional flags. Notably Clang's existing
`-triple` and `-target-feature` can be used to override the base triple or
enable and disable specific target features.

### Policy Around Included Profiles

Allowing unrestricted contributions of profiles into the compiler could negate
the benefits of this proposal by making it difficult for users to identify the
correct profile to use. To mitigate this problem we should integrate profiles to
the compiler that:

* Describe official API versioning schemes (DirectX feature levels and Shader
Models, Metal versions, Vulkan versions).
* Align with an official notion of target profiles such as [Vulkan
profiles](https://github.com/KhronosGroup/Vulkan-Profiles/tree/main), or any
similar concept that may arise from recognized industry consortiums or
standards bodies.

### Example Usage

```
clang-dxc -T cs_6_0 ...
```

Builds a compute shader for Shader Model 6.0, allowing all optional features of
SM 6.0 and earlier.

```
clang-dxc -T cs_Android15 ...
```

Builds a compute shader for Android 15, targeting SPIRV 1.3 and allowing the
required features supported by the Android 15 profile.

```
clang-dxc -T cs_DirectX_12_1 ...
```

Builds a compute shader for the DirectX 12_1 feature tier, targeting DXIL 1.0
and a defined set of optional features aligning with 12_1's required features
documented on
[learn.microsoft](https://learn.microsoft.com/en-us/windows/win32/direct3d12/hardware-feature-levels).


```
clang-dxc -T cs_DirectX_12_1 -target-feature +NativeLowPrecision ...
```

Builds a compute shader for the DirectX 12_1 feature tier, targeting DXIL 1.2
with 16-bit native types enabled, and a defined set of optional features
aligning with 12_1's required features documented on
[learn.microsoft](https://learn.microsoft.com/en-us/windows/win32/direct3d12/hardware-feature-levels).

```
clang-dxc -T cs_DirectX_12_1 -triple dxil-shadermodel6.4 ...
```

Builds a compute shader for the DirectX 12_1 feature tier, targeting DXIL 1.4
and a defined set of optional features aligning with 12_1's required features
documented on
[learn.microsoft](https://learn.microsoft.com/en-us/windows/win32/direct3d12/hardware-feature-levels).

```
clang-dxc -T cs_DirectX_12_1 -target-feature -Doubles ...
```

Builds a compute shader for the DirectX 12_1 feature tier, targeting DXIL 1.0
and a defined set of optional features aligning with 12_1's required features
documented on
[learn.microsoft](https://learn.microsoft.com/en-us/windows/win32/direct3d12/hardware-feature-levels),
but disallowing the use of double-precision floating point values.

## Outstanding Questions

* Should target profiles support a restricted set of optional features?
* Can we rely on using LLVM's target features capabilities to drive this?
* Should we support a `pragma` to enable features via source?
* Common profiles across runtimes?
* Should we have a format for user-defined profiles as input to the compiler?