Skip to content

Commit 1d53169

Browse files
DarkKilaueaalvinhochunallenwp
committed
Support output to HDR monitors
Co-authored-by: Alvin Wong <[email protected]> Co-authored-by: Allen Pestaluky <[email protected]>
1 parent e6aa06d commit 1d53169

File tree

55 files changed

+1542
-198
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

55 files changed

+1542
-198
lines changed

core/config/project_settings.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1691,6 +1691,8 @@ ProjectSettings::ProjectSettings() {
16911691
GLOBAL_DEF(PropertyInfo(Variant::INT, "display/window/size/window_width_override", PROPERTY_HINT_RANGE, "0,7680,1,or_greater"), 0); // 8K resolution
16921692
GLOBAL_DEF(PropertyInfo(Variant::INT, "display/window/size/window_height_override", PROPERTY_HINT_RANGE, "0,4320,1,or_greater"), 0); // 8K resolution
16931693

1694+
GLOBAL_DEF("display/window/hdr/request_hdr_output", false);
1695+
16941696
GLOBAL_DEF("display/window/energy_saving/keep_screen_on", true);
16951697
GLOBAL_DEF("animation/warnings/check_invalid_track_paths", true);
16961698
GLOBAL_DEF("animation/warnings/check_angle_interpolation_type_conflicting", true);

doc/classes/DisplayServer.xml

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2131,6 +2131,44 @@
21312131
Returns the current value of the given window's [param flag].
21322132
</description>
21332133
</method>
2134+
<method name="window_get_hdr_output_current_max_luminance" qualifiers="const">
2135+
<return type="float" />
2136+
<param index="0" name="window_id" type="int" default="0" />
2137+
<description>
2138+
Returns the current maximum luminance in nits (cd/m²) for HDR content for the window specified by [param window_id].
2139+
If max luminance is being auto adjusted based on the display's capabilities, this will return that value.
2140+
Otherwise, it will return the value set by [method window_set_hdr_output_max_luminance].
2141+
[b]Note:[/b] Requires support for [constant FEATURE_HDR_OUTPUT].
2142+
</description>
2143+
</method>
2144+
<method name="window_get_hdr_output_current_reference_luminance" qualifiers="const">
2145+
<return type="float" />
2146+
<param index="0" name="window_id" type="int" default="0" />
2147+
<description>
2148+
Returns the current reference luminance in nits (cd/m²) for HDR content for the window specified by [param window_id].
2149+
If reference luminance is being auto adjusted based on the display's capabilities, this will return that value.
2150+
Otherwise, it will return the value set by [method window_set_hdr_output_reference_luminance].
2151+
[b]Note:[/b] Requires support for [constant FEATURE_HDR_OUTPUT].
2152+
</description>
2153+
</method>
2154+
<method name="window_get_hdr_output_max_luminance" qualifiers="const">
2155+
<return type="float" />
2156+
<param index="0" name="window_id" type="int" default="0" />
2157+
<description>
2158+
Returns the maximum luminance in nits (cd/m²) set for HDR content for the window specified by [param window_id].
2159+
Negative values indicate that the value is being auto adjusted based on the display's capabilities.
2160+
[b]Note:[/b] Requires support for [constant FEATURE_HDR_OUTPUT].
2161+
</description>
2162+
</method>
2163+
<method name="window_get_hdr_output_reference_luminance" qualifiers="const">
2164+
<return type="float" />
2165+
<param index="0" name="window_id" type="int" default="0" />
2166+
<description>
2167+
Returns the SDR reference luminance in nits (cd/m²) set for HDR content for the window specified by [param window_id].
2168+
Negative values indicate that the value is being auto adjusted based on the display's capabilities.
2169+
[b]Note:[/b] Requires support for [constant FEATURE_HDR_OUTPUT].
2170+
</description>
2171+
</method>
21342172
<method name="window_get_max_size" qualifiers="const">
21352173
<return type="Vector2i" />
21362174
<param index="0" name="window_id" type="int" default="0" />
@@ -2161,6 +2199,13 @@
21612199
[b]Note:[/b] This method is implemented on Android, Linux (X11/Wayland), macOS, and Windows.
21622200
</description>
21632201
</method>
2202+
<method name="window_get_output_max_linear_value" qualifiers="const">
2203+
<return type="float" />
2204+
<param index="0" name="window_id" type="int" default="0" />
2205+
<description>
2206+
Equivalent to [method Window.get_output_max_linear_value].
2207+
</description>
2208+
</method>
21642209
<method name="window_get_popup_safe_rect" qualifiers="const">
21652210
<return type="Rect2i" />
21662211
<param index="0" name="window" type="int" />
@@ -2226,6 +2271,32 @@
22262271
Returns [code]true[/code] if the window specified by [param window_id] is focused.
22272272
</description>
22282273
</method>
2274+
<method name="window_is_hdr_output_enabled" qualifiers="const">
2275+
<return type="bool" />
2276+
<param index="0" name="window_id" type="int" default="0" />
2277+
<description>
2278+
Returns whether HDR output is currently enabled for the window specified by [param window_id].
2279+
This value may change dynamically based on system settings, display capabilities, and which display the window is currently on.
2280+
[b]Note:[/b] Requires support for [constant FEATURE_HDR_OUTPUT].
2281+
</description>
2282+
</method>
2283+
<method name="window_is_hdr_output_requested" qualifiers="const">
2284+
<return type="bool" />
2285+
<param index="0" name="window_id" type="int" default="0" />
2286+
<description>
2287+
Returns whether HDR output is requested for the window specified by [param window_id].
2288+
[b]Note:[/b] Requires support for [constant FEATURE_HDR_OUTPUT].
2289+
</description>
2290+
</method>
2291+
<method name="window_is_hdr_output_supported" qualifiers="const">
2292+
<return type="bool" />
2293+
<param index="0" name="window_id" type="int" default="0" />
2294+
<description>
2295+
Returns whether the window specified by [param window_id] supports HDR output.
2296+
This depends on the platform, display capabilities, system settings, and the display the window is currently on.
2297+
[b]Note:[/b] Requires support for [constant FEATURE_HDR_OUTPUT].
2298+
</description>
2299+
</method>
22292300
<method name="window_is_maximize_allowed" qualifiers="const">
22302301
<return type="bool" />
22312302
<param index="0" name="window_id" type="int" default="0" />
@@ -2261,6 +2332,18 @@
22612332
Makes the window specified by [param window_id] request attention, which is materialized by the window title and taskbar entry blinking until the window is focused. This usually has no visible effect if the window is currently focused. The exact behavior varies depending on the operating system.
22622333
</description>
22632334
</method>
2335+
<method name="window_request_hdr_output">
2336+
<return type="void" />
2337+
<param index="0" name="enable" type="bool" />
2338+
<param index="1" name="window_id" type="int" default="0" />
2339+
<description>
2340+
Sets whether HDR output should be requested for the window specified by [param window_id], falling back to SDR if not supported, and automatically switching between HDR and SDR as the window moves between displays, display capabilities change, or system settings are modified.
2341+
Only available on platforms that support HDR output, have HDR enabled in the system settings, and have a compatible display connected.
2342+
[b]Note:[/b] Some integrated GPUs have poor support for HDR output, even when they claim to support it. If you experience issues, try disabling this setting.
2343+
[b]Note:[/b] Requires support for [constant FEATURE_HDR_OUTPUT].
2344+
[b]Note:[/b] Requires support by the rendering device.
2345+
</description>
2346+
</method>
22642347
<method name="window_set_color">
22652348
<return type="void" />
22662349
<param index="0" name="color" type="Color" />
@@ -2308,6 +2391,34 @@
23082391
Enables or disables the given window's given [param flag].
23092392
</description>
23102393
</method>
2394+
<method name="window_set_hdr_output_max_luminance">
2395+
<return type="void" />
2396+
<param index="0" name="max_luminance" type="float" />
2397+
<param index="1" name="window_id" type="int" default="0" />
2398+
<description>
2399+
Sets the maximum luminance in nits (cd/m²) for HDR content for the window specified by [param window_id].
2400+
Set to a negative value to automatically use the display's maximum capability.
2401+
By default, this is set to [code]-1[/code].
2402+
This controls the maximum brightness of bright elements in HDR content, typically by scaling down highlights within the scene.
2403+
[b]Note:[/b] Requires support for [constant FEATURE_HDR_OUTPUT].
2404+
[b]Note:[/b] Requires support by the rendering device.
2405+
[b]Note:[/b] On some platforms, setting a custom max luminance is not supported and will always be auto adjusted based on the display's capabilities.
2406+
</description>
2407+
</method>
2408+
<method name="window_set_hdr_output_reference_luminance">
2409+
<return type="void" />
2410+
<param index="0" name="reference_luminance" type="float" />
2411+
<param index="1" name="window_id" type="int" default="0" />
2412+
<description>
2413+
Sets the SDR reference luminance in nits (cd/m²) for HDR content for the window specified by [param window_id].
2414+
Set to a negative value to automatically adjust to the reference level set by the OS or window manager.
2415+
By default, this is set to [code]-1[/code].
2416+
This controls the brightness of SDR content (such as UI) when HDR is enabled.
2417+
[b]Note:[/b] Requires support for [constant FEATURE_HDR_OUTPUT].
2418+
[b]Note:[/b] Requires support by the rendering device.
2419+
[b]Note:[/b] On some platforms, setting a custom reference luminance is not supported and will always be auto adjusted based on the display's capabilities.
2420+
</description>
2421+
</method>
23112422
<method name="window_set_ime_active">
23122423
<return type="void" />
23132424
<param index="0" name="active" type="bool" />
@@ -2620,6 +2731,9 @@
26202731
<constant name="FEATURE_ACCESSIBILITY_SCREEN_READER" value="34" enum="Feature">
26212732
Display server supports interaction with screen reader or Braille display. [b]Linux (X11/Wayland), macOS, Windows[/b]
26222733
</constant>
2734+
<constant name="FEATURE_HDR_OUTPUT" value="35" enum="Feature">
2735+
Display server supports HDR output. [b]Windows[/b]
2736+
</constant>
26232737
<constant name="ROLE_UNKNOWN" value="0" enum="AccessibilityRole">
26242738
Unknown or custom role.
26252739
</constant>

doc/classes/Environment.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -425,10 +425,12 @@
425425
</constant>
426426
<constant name="TONE_MAPPER_FILMIC" value="2" enum="ToneMapper">
427427
Uses a film-like tonemapping curve to prevent clipping of bright values and provide better contrast than [constant TONE_MAPPER_REINHARDT]. Slightly slower than [constant TONE_MAPPER_REINHARDT].
428+
[b]Note:[/b] This tonemapper does not support HDR output and clips output to the [code]0.0-1.0[/code] range. A different tonemapper should be used when rendering to an HDR display.
428429
</constant>
429430
<constant name="TONE_MAPPER_ACES" value="3" enum="ToneMapper">
430431
Uses a high-contrast film-like tonemapping curve and desaturates bright values for a more realistic appearance. Slightly slower than [constant TONE_MAPPER_FILMIC].
431432
[b]Note:[/b] This tonemapping operator is called "ACES Fitted" in Godot 3.x.
433+
[b]Note:[/b] This tonemapper does not support HDR output and clips output to the [code]0.0-1.0[/code] range. A different tonemapper should be used when rendering to an HDR display.
432434
</constant>
433435
<constant name="TONE_MAPPER_AGX" value="4" enum="ToneMapper">
434436
Uses a film-like tonemapping curve and desaturates bright values for a more realistic appearance. Better than other tonemappers at maintaining the hue of colors as they become brighter. The slowest tonemapping option.

doc/classes/ProjectSettings.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -969,6 +969,11 @@
969969
The default screen orientation to use on mobile devices. See [enum DisplayServer.ScreenOrientation] for possible values.
970970
[b]Note:[/b] When set to a portrait orientation, this project setting does not flip the project resolution's width and height automatically. Instead, you have to set [member display/window/size/viewport_width] and [member display/window/size/viewport_height] accordingly.
971971
</member>
972+
<member name="display/window/hdr/request_hdr_output" type="bool" setter="" getter="" default="false">
973+
If [code]true[/code], requests HDR output for the main window and editor, falling back to SDR if not supported, and automatically switching between HDR and SDR as the window moves between displays, display capabilities change, or system settings are modified.
974+
Only available on platforms that support HDR output, have HDR enabled in the system settings, and have a compatible display connected.
975+
[b]Note:[/b] Some integrated GPUs have poor support for HDR output, even when they claim to support it. If you experience issues, try disabling this setting.
976+
</member>
972977
<member name="display/window/ios/allow_high_refresh_rate" type="bool" setter="" getter="" default="true">
973978
If [code]true[/code], iOS devices that support high refresh rate/"ProMotion" will be allowed to render at up to 120 frames per second.
974979
</member>

doc/classes/RenderingDevice.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2524,6 +2524,9 @@
25242524
<constant name="SUPPORTS_IMAGE_ATOMIC_32_BIT" value="7" enum="Features">
25252525
Support for 32-bit image atomic operations.
25262526
</constant>
2527+
<constant name="SUPPORTS_HDR_OUTPUT" value="9" enum="Features">
2528+
Features support for high dynamic range (HDR) output.
2529+
</constant>
25272530
<constant name="LIMIT_MAX_BOUND_UNIFORM_SETS" value="0" enum="Limit">
25282531
Maximum number of uniform sets that can be bound at a given time.
25292532
</constant>

doc/classes/RenderingServer.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5504,10 +5504,12 @@
55045504
</constant>
55055505
<constant name="ENV_TONE_MAPPER_FILMIC" value="2" enum="EnvironmentToneMapper">
55065506
Uses a film-like tonemapping curve to prevent clipping of bright values and provide better contrast than [constant ENV_TONE_MAPPER_REINHARD]. Slightly slower than [constant ENV_TONE_MAPPER_REINHARD].
5507+
[b]Note:[/b] This tonemapper does not support HDR output and clips output to the [code]0.0-1.0[/code] range. A different tonemapper should be used when rendering to an HDR display.
55075508
</constant>
55085509
<constant name="ENV_TONE_MAPPER_ACES" value="3" enum="EnvironmentToneMapper">
55095510
Uses a high-contrast film-like tonemapping curve and desaturates bright values for a more realistic appearance. Slightly slower than [constant ENV_TONE_MAPPER_FILMIC].
55105511
[b]Note:[/b] This tonemapping operator is called "ACES Fitted" in Godot 3.x.
5512+
[b]Note:[/b] This tonemapper does not support HDR output and clips output to the [code]0.0-1.0[/code] range. A different tonemapper should be used when rendering to an HDR display.
55115513
</constant>
55125514
<constant name="ENV_TONE_MAPPER_AGX" value="4" enum="EnvironmentToneMapper">
55135515
Uses a film-like tonemapping curve and desaturates bright values for a more realistic appearance. Better than other tonemappers at maintaining the hue of colors as they become brighter. The slowest tonemapping option.

doc/classes/Window.xml

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,32 @@
120120
Returns layout direction and text writing direction.
121121
</description>
122122
</method>
123+
<method name="get_output_max_linear_value" qualifiers="const">
124+
<return type="float" />
125+
<description>
126+
Returns the maximum value for linear color components that can be displayed in this window, regardless of SDR or HDR output. This method will return 1.0 if HDR is not enabled or not supported.
127+
Use this to scale content to max out the display's brightness, for example lasers or other bright effects. The following is an example that produces the brightest red color that the display can produce:
128+
[codeblocks]
129+
[gdscript]
130+
var bright_red: Color = Color.RED
131+
# Color must be linear-encoded to use math operations correctly.
132+
bright_red = bright_red.srgb_to_linear()
133+
# Record the original alpha value.
134+
var original_alpha: float = bright_red.a
135+
# Adjust brightness to be the brightest possible, regardless of SDR or HDR output.
136+
bright_red = bright_red * get_window().get_output_max_linear_value()
137+
# Restore the original alpha channel value.
138+
bright_red.a = original_alpha
139+
# Convert back to nonlinear sRGB encoding.
140+
bright_red = bright_red.linear_to_srgb()
141+
[/gdscript]
142+
[csharp]
143+
// TODO
144+
[/csharp]
145+
[/codeblocks]
146+
[b]Note:[/b] You will need to convert sRGB colors to linear before multiplying by this value to get correct results.
147+
</description>
148+
</method>
123149
<method name="get_position_with_decorations" qualifiers="const">
124150
<return type="Vector2i" />
125151
<description>
@@ -341,6 +367,13 @@
341367
Returns [code]true[/code] if the window is currently embedded in another window.
342368
</description>
343369
</method>
370+
<method name="is_hdr_output_supported" qualifiers="const">
371+
<return type="bool" />
372+
<description>
373+
Returns [code]true[/code] if the window supports HDR output.
374+
This depends on the platform, display capabilities, system settings, and the display the window is currently on.
375+
</description>
376+
</method>
344377
<method name="is_layout_rtl" qualifiers="const">
345378
<return type="bool" />
346379
<description>
@@ -628,6 +661,11 @@
628661
<member name="force_native" type="bool" setter="set_force_native" getter="get_force_native" default="false">
629662
If [code]true[/code], native window will be used regardless of parent viewport and project settings.
630663
</member>
664+
<member name="hdr_output_requested" type="bool" setter="set_hdr_output_requested" getter="is_hdr_output_requested" default="false">
665+
If [code]true[/code], requests HDR output for the window, falling back to SDR if not supported, and automatically switching between HDR and SDR as the window moves between displays, display capabilities change, or system settings are modified.
666+
Only available on platforms that support HDR output, have HDR enabled in the system settings, and have a compatible display connected.
667+
[b]Note:[/b] Some integrated GPUs have poor support for HDR output, even when they claim to support it. If you experience issues, try disabling this setting.
668+
</member>
631669
<member name="initial_position" type="int" setter="set_initial_position" getter="get_initial_position" enum="Window.WindowInitialPosition" default="0">
632670
Specifies the initial type of position for the [Window].
633671
</member>

drivers/d3d12/rendering_context_driver_d3d12.cpp

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,52 @@ DisplayServer::VSyncMode RenderingContextDriverD3D12::surface_get_vsync_mode(Sur
282282
return surface->vsync_mode;
283283
}
284284

285+
void RenderingContextDriverD3D12::surface_set_hdr_output_enabled(SurfaceID p_surface, bool p_enabled) {
286+
Surface *surface = (Surface *)(p_surface);
287+
surface->hdr_output = p_enabled;
288+
surface->needs_resize = true;
289+
}
290+
291+
bool RenderingContextDriverD3D12::surface_get_hdr_output_enabled(SurfaceID p_surface) const {
292+
Surface *surface = (Surface *)(p_surface);
293+
return surface->hdr_output;
294+
}
295+
296+
void RenderingContextDriverD3D12::surface_set_hdr_output_reference_luminance(SurfaceID p_surface, float p_reference_luminance) {
297+
Surface *surface = (Surface *)(p_surface);
298+
surface->hdr_reference_luminance = p_reference_luminance;
299+
}
300+
301+
float RenderingContextDriverD3D12::surface_get_hdr_output_reference_luminance(SurfaceID p_surface) const {
302+
Surface *surface = (Surface *)(p_surface);
303+
return surface->hdr_reference_luminance;
304+
}
305+
306+
void RenderingContextDriverD3D12::surface_set_hdr_output_max_luminance(SurfaceID p_surface, float p_max_luminance) {
307+
Surface *surface = (Surface *)(p_surface);
308+
surface->hdr_max_luminance = p_max_luminance;
309+
}
310+
311+
float RenderingContextDriverD3D12::surface_get_hdr_output_max_luminance(SurfaceID p_surface) const {
312+
Surface *surface = (Surface *)(p_surface);
313+
return surface->hdr_max_luminance;
314+
}
315+
316+
void RenderingContextDriverD3D12::surface_set_hdr_output_linear_luminance_scale(SurfaceID p_surface, float p_linear_luminance_scale) {
317+
Surface *surface = (Surface *)(p_surface);
318+
surface->hdr_linear_luminance_scale = p_linear_luminance_scale;
319+
}
320+
321+
float RenderingContextDriverD3D12::surface_get_hdr_output_linear_luminance_scale(SurfaceID p_surface) const {
322+
Surface *surface = (Surface *)(p_surface);
323+
return surface->hdr_linear_luminance_scale;
324+
}
325+
326+
float RenderingContextDriverD3D12::surface_get_hdr_output_max_value(SurfaceID p_surface) const {
327+
Surface *surface = (Surface *)(p_surface);
328+
return MAX(surface->hdr_max_luminance / MAX(surface->hdr_reference_luminance, 1.0f), 1.0f);
329+
}
330+
285331
uint32_t RenderingContextDriverD3D12::surface_get_width(SurfaceID p_surface) const {
286332
Surface *surface = (Surface *)(p_surface);
287333
return surface->width;

0 commit comments

Comments
 (0)