Version 1.0
Term | Definition |
---|---|
RTV | Render Target View |
UAV | Unordered Access View |
SRV | Shader Resource View |
999E5 | DXGI_FORMAT_R9G9B9E5_SHAREDEXP |
This document describes what is needed to revise the existing support for DXGI_FORMAT_R9G9B9E5_SHAREDEXP
. This format existed previously in D3D11 and D3D12, but in a reduced capacity. The aim is to bring in optional support for this format so that it can be used as a render target and as a unordered access view.
The details of the format as it existed in Direct3D 11 can be found here. This document aims to build on top of that spec and bring first-class support for DXGI_FORMAT_R9G9B9E5_SHAREDEXP
as an RTV and UAV.
High Dynamic Range (HDR) technology has revolutionized the visual quality of digital content, providing a wider range of colors and luminance levels. Direct3D 12 plans to support developers by exposing more of DXGI_FORMAT_R9G9B9E5_SHAREDEXP
, which gives a much better color definition in almost every color space. 999E5 promises a lot of utility as a float format that is half the size of R16G16B16A16_FLOAT
, while being almost on par with R16G16B16A16_FLOAT
on image quality except in the most contrived scenarios. The image below is an exaggerated banding comparison between R11G11B10 vs 999E5 [0..200].
This format was previously only available in Direct3D as a shader resource. To use the format previously, applications would alias with a 32-bit type format, create a resource that is DXGI_FORMAT_R9G9B9E5_SHAREDEXP
format, and copy into said resource. More recently, relaxed casting options allowed developers greater flexbility to write into the DXGI_FORMAT_R9G9B9E5_SHAREDEXP
format. With this optional feature (depending on driver support), applications will be able to write and use DXGI_FORMAT_R9G9B9E5_SHAREDEXP
directly without the casts. This means relying on hardware format conversions between the format memory and the float data in the shader. Applications can also rely on hardware supporting output merger blending.
The revision for 999E5 comes in two major groups.
Drivers that report support for display also has support for RTV/UAV.
Applications can use DXGI_FORMAT_R9G9B9E5_SHAREDEXP
consistently through the resource creation, view creation, and pipeline creation process. This would be consistent with how applications use DXGI_FORMAT_R32G32B32A32_UINT
, or any other format that doesn’t require casting to use. The following support would be added to DXGI_FORMAT_R9G9B9E5_SHAREDEXP
.
As a resource:
As a RTV:
As a UAV:
Applications can create resources of format 999E5 on the swapchain and display them, depending on driver support. The swapchain supports presentation via composition, DirectFlip, DirectFlip with MPO, and Independant Flip. Drivers that report group 2 support should have group 1 support.
Microsoft Display Capture Toolkit will also add support for presenting MPO planes in this format.
This format works on cross-adapter presentation as well, CASO and non-CASO.
Application are able to create resources with this format and create RTVs and UAVs of this format, contingent on hardware support. This change will come for both D3D11 and D3D12. Applications can create resources of this format on the swap chain and present them.
Applications should check whether their devices can support this format as an RT/UAV, as this is an optional support. Applications can use CheckFeatureSupport with D3D12_FEATURE_FORMAT_SUPPORT
to check the support for a format.
Relevant bits (from here):
D3D11 | D3D12 |
---|---|
D3D11_FORMAT_SUPPORT_RENDER_TARGET | D3D12_FORMAT_SUPPORT1_RENDER_TARGET |
D3D11_FORMAT_SUPPORT_MULTISAMPLE_RENDERTARGET | D3D12_FORMAT_SUPPORT1_MULTISAMPLE_RENDERTARGET |
D3D11_FORMAT_SUPPORT_MULTISAMPLE_RESOLVE | D3D12_FORMAT_SUPPORT1_MULTISAMPLE_RESOLVE |
D3D11_FORMAT_SUPPORT_MULTISAMPLE_LOAD | D3D12_FORMAT_SUPPORT1_MULTISAMPLE_LOAD |
D3D11_FORMAT_SUPPORT_TYPED_UNORDERED_ACCESS_VIEW | D3D12_FORMAT_SUPPORT1_TYPED_UNORDERED_ACCESS_VIEW |
D3D11_FORMAT_SUPPORT_BLENDABLE | D3D12_FORMAT_SUPPORT1_BLENDABLE |
D3D11_FORMAT_SUPPORT2_UAV_TYPED_LOAD | D3D12_FORMAT_SUPPORT2_UAV_TYPED_LOAD |
D3D11_FORMAT_SUPPORT2_UAV_TYPED_STORE | D3D12_FORMAT_SUPPORT2_UAV_TYPED_STORE |
As each support group is all-or-nothing, applications need only check one of these bits to assume if all the above bits are set. Older versions of D3D12 will not report support for this feature, while newer versions will query the driver.
Example:
D3D12_FEATURE_DATA_FORMAT_SUPPORT formatSupport{};
formatSupport.Format = DXGI_FORMAT_R9G9B9E5_SHAREDEXP;
m_device->CheckFeatureSupport(D3D12_FEATURE_FORMAT_SUPPORT, &formatSupport, sizeof(D3D12_FEATURE_DATA_FORMAT_SUPPORT));
if (formatSupport.Support1 & D3D12_FORMAT_SUPPORT1_RENDER_TARGET)
{
// Since it is all-or-nothing, supporting render target means support updated 999E5 revision
printf("Format supports rtv and uav\n");
}
Note: Applications still need to check for multisamping level support via ID3D12Device::CheckFeatureSupport
with CheckMultisampleQualityLevels
.
Applications should check whether their hardware can support displaying 999E5 via the same function CheckFeatureSupport with D3D12_FEATURE_FORMAT_SUPPORT
.
In this case, the application should check against D3D12_FORMAT_SUPPORT1_DISPLAY
.
Example:
D3D12_FEATURE_DATA_FORMAT_SUPPORT formatSupport{};
formatSupport.Format = DXGI_FORMAT_R9G9B9E5_SHAREDEXP;
m_device->CheckFeatureSupport(D3D12_FEATURE_FORMAT_SUPPORT, &formatSupport, sizeof(D3D12_FEATURE_DATA_FORMAT_SUPPORT));
if (formatSupport.Support1 & D3D12_FORMAT_SUPPORT1_DISPLAY)
{
// Format can display!
printf("Format supports present\n");
}
// ... Eventually create a DXGI swap chain with this format...
| D3D11 | D3D12 | |————————————————–|—————————————————| | D3D11_FORMAT_SUPPORT2_MULTIPLANE_OVERLAY | D3D12_FORMAT_SUPPORT2_MULTIPLANE_OVERLAY | | D3D11_FORMAT_SUPPORT2_DISPLAYABLE | | | D3D11_FORMAT_SUPPORT_DISPLAY | D3D12_FORMAT_SUPPORT1_DISPLAY |
Note: Using this format on the swap chain requires an up-to-date version of Windows. Applications may still fail swap chain creation with the Agility SDK if the Windows version is not high enough.
A new color space, DXGI_COLOR_SPACE_RGB_FULL_G10_NONE_P2020
, will be added to accomodate R9G9B9E5_SHAREDEXP as a color format. Currently only R9G9B9E5 will work with DXGI_COLOR_SPACE_RGB_FULL_G10_NONE_P2020
.
The rules of conversion to float and back for this format will stay the same. These rules are descibed in the D3D11.3 spec.
There is an implementation in hlsl in the DirectX Graphics Sample’s mini engine that can be used as a reference.
Whenever a 999E5 render target is used, the accompanying D3D12_RENDER_TARGET_BLEND_DESC::RenderTargetWriteMask
must be set to D3D12_COLOR_WRITE_ENABLE_ALL
. Partial updates to some component is not supported. While 999E5 does not support alpha writing, setting COLOR_WRITE_ENABLE_ALPHA
is required for the exponent component to be written.
The existing format requirement table for hardware feature level 12.1 and above would need to modified to support these changes. In particular, format DXGI_FORMAT_R9G9B9E5_SHAREDEXP
will now have optional support for
Previously the runtime would report these supports as not available. By changing these to optional, the runtime will query the driver on the supported features of the format.
This section describes the tech stack on Microsoft’s side that may be changed to accomodate display. The general flow of a display buffer in user mode is
[Applicatiion] -> [DXGI] -> [DWM] -> [DDisplay] -> [Driver]
With certain optimizations available in DWM to blit/bypass itself.
The DXGI swap chain can create and hold resources in this format. From here, applications can call Present
to display the resource.
There will be a new DXGI Color Space that supports R9G9B9E5_SHAREDEXP. The new color space type is
DXGI_COLOR_SPACE_RGB_FULL_G10_NONE_P2020
This is to accomodate the fact that R9G9B9E5 cannot hold negative values, which would mean it cannot be used in the scRGB space. The properties of the new color space are
Property | Value |
---|---|
Colorspace | RGB |
Range | 0-255 |
Gamma | 1.0 |
Siting | Image |
Primaries | BT.2020 |
The DXGI swap chain is primarily responsible for passing the format and the color space to DWM/Display/DxgKrnl.
IDXGISwapChain*::CheckColorSpaceSupport
DXGI_COLOR_SPACE_RGB_FULL_G10_NONE_P2020
IDXGIFactory*::CreateSwapChain
DXGI_COLOR_SPACE_RGB_FULL_G10_NONE_P2020
.D3D12_FORMAT_SUPPORT1_DISPLAY
IDXGIOutput4::CheckOverlayColorSpaceSupport
DXGI_COLOR_SPACE_RGB_FULL_G10_NONE_P2020
, return DXGI_OVERLAY_COLOR_SPACE_SUPPORT_FLAG_PRESENT
As there is a new color space, DWM would require shader changes to be able to handle this new color space. DWM functions equivalently as before, the only requirement is that DWM be able to handle composing from R9G9B9E5_SHAREDEXP
format and the RGB_FULL_G10_NONE_P2020
color space.
Due to a lack of alpha in the format, DWM will not use R9G9B9E5_SHAREDEXP
in composition mode.
The modes that support fullscreen are (and hence benefit from R9G9B9E5):
GPUs that claim display support must provide support for all the above modes.
Composite swap chains will also work with this format.
Same as DWM, the composite swap chain would have to be able to handle this new color space.
Display/DxgKrnl is required to work with this format, if driver support is declared.
There might be changes required in D3DKMTCheckMultiPlaneOverlaySupport*
and CheckColorspaceSupport
that will need to support this format.
999E5 previously existed as an SRV, so there is already WARP decoding support for this format. The following will be added to WARP
In the case of a newer runtime running on older drivers, the runtime will first determine the driver’s DDI version. If the driver’s DDI is below 107, the runtime will report not support instead of querying the driver.
Drivers would report support for this format via PFND3D12DDI_CHECKFORMATSUPPORT
for D3D12 and PFND3D10DDI_CHECKFORMATSUPPORT
for D3D11. This is an optional support for drivers.
DDI Version: 107
The new bit to report is
#define D3D12DDI_FORMAT_SUPPORT_DISPLAY 0x00200000
The runtime would check the driver’s DDI against 107. If the driver reports a lower DDI, the runtime won’t query the driver and instead report no support.
Minor Header Version: 24 D3DWDDM3_2_DDI_BUILD_VERSION 1
The new bit to report is
D3D11_1DDI_FORMAT_SUPPORT_DISPLAY 0x00200000
Note that there is no DDI check in D3D11, hence updated D3D11 runtimes would always query the drivers on 999E5 support.
Drivers are required to treat the below two groups of support as all-or-nothing.
RTV/UAV Support
D3D11 | D3D12 |
---|---|
D3D10_DDI_FORMAT_SUPPORT_RENDERTARGET | D3D12DDI_FORMAT_SUPPORT_RENDERTARGET |
D3D10_DDI_FORMAT_SUPPORT_BLENDABLE | D3D12DDI_FORMAT_SUPPORT_BLENDABLE |
D3D10_DDI_FORMAT_SUPPORT_MULTISAMPLE_RENDERTARGET | D3D12DDI_FORMAT_SUPPORT_MULTISAMPLE_RENDERTARGET |
D3D10_DDI_FORMAT_SUPPORT_MULTISAMPLE_LOAD | D3D12DDI_FORMAT_SUPPORT_MULTISAMPLE_LOAD |
D3D11_1DDI_FORMAT_SUPPORT_UAV_WRITES | D3D12DDI_FORMAT_SUPPORT_UAV_READS |
D3DWDDM2_0DDI_FORMAT_SUPPORT_UAV_READS | D3D12DDI_FORMAT_SUPPORT_UAV_WRITES |
Display Support
D3D11 | D3D12 |
---|---|
D3D11_1DDI_FORMAT_SUPPORT_MULTIPLANE_OVERLAY | D3D12DDI_FORMAT_SUPPORT_MULTIPLANE_OVERLAY |
D3D11_1DDI_FORMAT_SUPPORT_DISPLAY | D3D12DDI_FORMAT_SUPPORT_DISPLAY |
D3D11_FORMAT_SUPPORT2_DISPLAYABLE |
The following DDI has changed to handle 999E5 for presenting and display out. If 999E5 is supported as a display option, it should also come with multiple overlay support. The relevant HLK tests would also need to be updated. This list is not conclusive yet, and may be updated as time goes on.
In order to support CASO, DXGI would create a cross-adapter resource via pfnCreateResource
. The driver evaluates whether a resource in 999E5 format can be created.
While the DDIs remain the same, the behavior expected can be different hence the DDIs are listed out. There are no new DDIs added.
// d3dumddi.h
HRESULT Pfnd3dddiCreateresource(HANDLE hDevice, D3DDDIARG_CREATERESOURCE *unnamedParam2) // We need to be able to create a resource in 999E5 for CASO
HRESULT pfnCheckMultiplaneOverlayColorSpaceSupport(DXGI_DDI_ARG_CHECKMULTIPLANEOVERLAYCOLORSPACESUPPORT*);
// d3dkmddi.h
DXGKDDI_CHECKMULTIPLANEOVERLAYSUPPORT3 DxgkddiCheckmultiplaneoverlaysupport3;
NTSTATUS DxgkddiCheckmultiplaneoverlaysupport3(
IN_CONST_HANDLE hAdapter,
IN_OUT_PDXGKARG_CHECKMULTIPLANEOVERLAYSUPPORT3 pCheckMultiPlaneOverlaySupport
)
//d3d12umddi.h
void PFND3D12DDI_PRESENT_0051 (D3D12DDI_HCOMMANDLIST, D3D12DDI_HCOMMANDQUEUE, CONST D3D12DDIARG_PRESENT_0001*, D3D12DDI_PRESENT_0051*, D3D12DDI_PRESENT_CONTEXTS_0051* D3D12DDI_PRESENT_HWQUEUES_0051* );
HRESULT PFND3DDDI_CHECKDIRECTFLIPSUPPORT (HANDLE hDevice, D3DDDIARG_CHECKDIRECTFLIPSUPPORT*);
R9G9B9E5_SHAREDEXP and the new color space will need to be exposed in d3dukmdt.h
DDIs. The following is added.
D3DDDIFORMAT
contains a new entry, named D3DDDIFMT_E5B9G9R9
to represent this format. This is so that the graphics kernal can understand this format.D3DDDI_COLOR_SPACE_TYPE
contains a new entry, named D3DDDI_COLOR_SPACE_RGB_FULL_G10_NONE_P2020
The debug layer validates the following
D3D12_RENDER_TARGET_BLEND_DESC::RenderTargetWriteMask
must be set to D3D12_COLOR_WRITE_ENABLE_ALL
The debug layer validates if the DXGI/Windows version is high enough to support this format for presenting.
The functional unit tests will be written in TAEF and they will test for negatives.
CheckFeatureSupport