A second take on HDR support with an SDR white point and HDR headroom

This better reflects how HDR content is actually used, e.g. most content is in the SDR range, with specular highlights and bright details beyond the SDR range, in the HDR headroom.

This more closely matches how HDR is handled on Apple platforms, as EDR.

This also greatly simplifies application code which no longer has to think about color scaling. SDR content is rendered at the appropriate brightness automatically, and HDR content is scaled to the correct range for the display HDR headroom.
This commit is contained in:
Sam Lantinga 2024-02-19 08:45:02 -08:00
parent 3b7533f4a2
commit 4ba6aeee9d
24 changed files with 430 additions and 546 deletions

View file

@ -246,12 +246,12 @@ static DXGI_FORMAT SDLPixelFormatToDXGITextureFormat(Uint32 format, Uint32 color
case SDL_PIXELFORMAT_RGBA64_FLOAT:
return DXGI_FORMAT_R16G16B16A16_FLOAT;
case SDL_PIXELFORMAT_ARGB8888:
if (colorspace == SDL_COLORSPACE_SCRGB) {
if (colorspace == SDL_COLORSPACE_SRGB_LINEAR) {
return DXGI_FORMAT_B8G8R8A8_UNORM_SRGB;
}
return DXGI_FORMAT_B8G8R8A8_UNORM;
case SDL_PIXELFORMAT_XRGB8888:
if (colorspace == SDL_COLORSPACE_SCRGB) {
if (colorspace == SDL_COLORSPACE_SRGB_LINEAR) {
return DXGI_FORMAT_B8G8R8X8_UNORM_SRGB;
}
return DXGI_FORMAT_B8G8R8X8_UNORM;
@ -276,12 +276,12 @@ static DXGI_FORMAT SDLPixelFormatToDXGIMainResourceViewFormat(Uint32 format, Uin
case SDL_PIXELFORMAT_RGBA64_FLOAT:
return DXGI_FORMAT_R16G16B16A16_FLOAT;
case SDL_PIXELFORMAT_ARGB8888:
if (colorspace == SDL_COLORSPACE_SCRGB) {
if (colorspace == SDL_COLORSPACE_SRGB_LINEAR) {
return DXGI_FORMAT_B8G8R8A8_UNORM_SRGB;
}
return DXGI_FORMAT_B8G8R8A8_UNORM;
case SDL_PIXELFORMAT_XRGB8888:
if (colorspace == SDL_COLORSPACE_SCRGB) {
if (colorspace == SDL_COLORSPACE_SRGB_LINEAR) {
return DXGI_FORMAT_B8G8R8X8_UNORM_SRGB;
}
return DXGI_FORMAT_B8G8R8X8_UNORM;
@ -880,7 +880,7 @@ static HRESULT D3D11_CreateSwapChain(SDL_Renderer *renderer, int w, int h)
swapChainDesc.Width = w;
swapChainDesc.Height = h;
switch (renderer->output_colorspace) {
case SDL_COLORSPACE_SCRGB:
case SDL_COLORSPACE_SRGB_LINEAR:
swapChainDesc.Format = DXGI_FORMAT_R16G16B16A16_FLOAT;
break;
case SDL_COLORSPACE_HDR10:
@ -979,7 +979,7 @@ static HRESULT D3D11_CreateSwapChain(SDL_Renderer *renderer, int w, int h)
UINT colorspace_support = 0;
DXGI_COLOR_SPACE_TYPE colorspace;
switch (renderer->output_colorspace) {
case SDL_COLORSPACE_SCRGB:
case SDL_COLORSPACE_SRGB_LINEAR:
colorspace = DXGI_COLOR_SPACE_RGB_FULL_G10_NONE_P709;
break;
case SDL_COLORSPACE_HDR10:
@ -2699,7 +2699,7 @@ SDL_Renderer *D3D11_CreateRenderer(SDL_Window *window, SDL_PropertiesID create_p
SDL_SetupRendererColorspace(renderer, create_props);
if (renderer->output_colorspace != SDL_COLORSPACE_SRGB &&
renderer->output_colorspace != SDL_COLORSPACE_SCRGB
renderer->output_colorspace != SDL_COLORSPACE_SRGB_LINEAR
/*&& renderer->output_colorspace != SDL_COLORSPACE_HDR10*/) {
SDL_SetError("Unsupported output colorspace");
SDL_free(renderer);