Define SCRGB_NITS for use in HDR color calculations

This commit is contained in:
Sam Lantinga
2026-07-23 08:09:02 -07:00
parent b9d64c45a9
commit 148241117b
7 changed files with 20 additions and 14 deletions

View File

@@ -5448,7 +5448,7 @@ SDL_Surface *SDL_RenderReadPixels(SDL_Renderer *renderer, const SDL_Rect *rect)
SDL_PixelFormat expected_format = (parent ? parent->format : target->format);
if (SDL_COLORSPACETRANSFER(target->colorspace) == SDL_TRANSFER_CHARACTERISTICS_PQ) {
SDL_SetFloatProperty(props, SDL_PROP_SURFACE_SDR_WHITE_POINT_FLOAT, target->SDR_white_point * 80.0f);
SDL_SetFloatProperty(props, SDL_PROP_SURFACE_SDR_WHITE_POINT_FLOAT, target->SDR_white_point * SCRGB_NITS);
} else {
SDL_SetFloatProperty(props, SDL_PROP_SURFACE_SDR_WHITE_POINT_FLOAT, target->SDR_white_point);
}
@@ -5464,7 +5464,7 @@ SDL_Surface *SDL_RenderReadPixels(SDL_Renderer *renderer, const SDL_Rect *rect)
}
} else {
if (SDL_COLORSPACETRANSFER(renderer->output_colorspace) == SDL_TRANSFER_CHARACTERISTICS_PQ) {
SDL_SetFloatProperty(props, SDL_PROP_SURFACE_SDR_WHITE_POINT_FLOAT, renderer->SDR_white_point * 80.0f);
SDL_SetFloatProperty(props, SDL_PROP_SURFACE_SDR_WHITE_POINT_FLOAT, renderer->SDR_white_point * SCRGB_NITS);
} else {
SDL_SetFloatProperty(props, SDL_PROP_SURFACE_SDR_WHITE_POINT_FLOAT, renderer->SDR_white_point);
}

View File

@@ -2681,9 +2681,9 @@ static bool D3D11_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd
color.b *= cmd->data.color.color_scale;
if (renderer->current_colorspace == SDL_COLORSPACE_HDR10) {
color.r = SDL_PQfromNits(color.r * 80.0f);
color.g = SDL_PQfromNits(color.g * 80.0f);
color.b = SDL_PQfromNits(color.b * 80.0f);
color.r = SDL_PQfromNits(color.r * SCRGB_NITS);
color.g = SDL_PQfromNits(color.g * SCRGB_NITS);
color.b = SDL_PQfromNits(color.b * SCRGB_NITS);
}
ID3D11DeviceContext_ClearRenderTargetView(rendererData->d3dContext, D3D11_GetCurrentRenderTargetView(renderer), &color.r);

View File

@@ -3174,9 +3174,9 @@ static bool D3D12_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd
color.b *= cmd->data.color.color_scale;
if (renderer->current_colorspace == SDL_COLORSPACE_HDR10) {
color.r = SDL_PQfromNits(color.r * 80.0f);
color.g = SDL_PQfromNits(color.g * 80.0f);
color.b = SDL_PQfromNits(color.b * 80.0f);
color.r = SDL_PQfromNits(color.r * SCRGB_NITS);
color.g = SDL_PQfromNits(color.g * SCRGB_NITS);
color.b = SDL_PQfromNits(color.b * SCRGB_NITS);
}
ID3D12GraphicsCommandList2_ClearRenderTargetView(rendererData->commandList, rtvDescriptor, &color.r, 0, NULL);

View File

@@ -4166,9 +4166,9 @@ static bool VULKAN_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cm
color.b *= cmd->data.color.color_scale;
if (renderer->current_colorspace == SDL_COLORSPACE_HDR10) {
color.r = SDL_PQfromNits(color.r * 80.0f);
color.g = SDL_PQfromNits(color.g * 80.0f);
color.b = SDL_PQfromNits(color.b * 80.0f);
color.r = SDL_PQfromNits(color.r * SCRGB_NITS);
color.g = SDL_PQfromNits(color.g * SCRGB_NITS);
color.b = SDL_PQfromNits(color.b * SCRGB_NITS);
}
VkClearColorValue clearColor;

View File

@@ -27,6 +27,8 @@
#include "SDL_blit.h"
// The value, in nits, of scRGB 1.0
#define SCRGB_NITS 80.0f
// Pixel format functions
extern void SDL_Get8888AlphaMaskAndShift(const SDL_PixelFormatDetails *fmt, Uint32 *mask, Uint32 *shift);

View File

@@ -24,6 +24,7 @@
#include "SDL_windowsvideo.h"
#include "../../events/SDL_displayevents_c.h"
#include "../SDL_pixels_c.h"
#ifdef HAVE_DXGI1_6_H
#define COBJMACROS
@@ -546,7 +547,7 @@ static void WIN_GetHDRProperties(SDL_VideoDevice *_this, HMONITOR hMonitor, SDL_
if (WIN_GetMonitorDESC1(hMonitor, &desc)) {
if (desc.ColorSpace == DXGI_COLOR_SPACE_RGB_FULL_G2084_NONE_P2020) {
HDR->SDR_white_level = WIN_GetSDRWhitePoint(_this, hMonitor);
HDR->HDR_headroom = (desc.MaxLuminance / 80.0f) / HDR->SDR_white_level;
HDR->HDR_headroom = (desc.MaxLuminance / SCRGB_NITS) / HDR->SDR_white_level;
}
}
}

View File

@@ -15,6 +15,9 @@
#include <SDL3/SDL_test.h>
#include <SDL3/SDL_main.h>
// The value, in nits, of scRGB 1.0
#define SCRGB_NITS 80.0f
#define WINDOW_WIDTH 640
#define WINDOW_HEIGHT 480
@@ -85,7 +88,7 @@ static void UpdateHDRState(void)
}
SDR_white_level = SDL_GetFloatProperty(props, SDL_PROP_RENDERER_SDR_WHITE_POINT_FLOAT, 1.0f);
HDR_headroom = SDL_GetFloatProperty(props, SDL_PROP_RENDERER_HDR_HEADROOM_FLOAT, 1.0f);
if (((SDR_white_level * 80.0f) * HDR_headroom) == 10000.0f) {
if (((SDR_white_level * SCRGB_NITS) * HDR_headroom) == 10000.0f) {
// The system is advertising the PQ luminance range (10000 nits)
// and tone mapping into the actual display capabilities.
// Let's use a more reasonable range for the gradient test.
@@ -693,7 +696,7 @@ static SDL_Texture *CreateHDR10Texture(int width, float max_nits)
// The white point for HDR10 textures is the SDR white level in nits
if (SDR_white_level > 1.0f) {
// We'll match the current display SDR white level so we don't get any scaling here
SDL_SetFloatProperty(props, SDL_PROP_TEXTURE_CREATE_SDR_WHITE_POINT_FLOAT, SDR_white_level * 80.0f);
SDL_SetFloatProperty(props, SDL_PROP_TEXTURE_CREATE_SDR_WHITE_POINT_FLOAT, SDR_white_level * SCRGB_NITS);
} else {
// ITU-R BT.2408-6 recommends using an SDR white point of 203 nits.
SDL_SetFloatProperty(props, SDL_PROP_TEXTURE_CREATE_SDR_WHITE_POINT_FLOAT, 203.0f);