mirror of https://github.com/godotengine/godot
Compare commits
2 Commits
b3ff650459
...
9d3eb1f8ff
| Author | SHA1 | Date |
|---|---|---|
|
|
9d3eb1f8ff | |
|
|
bed8d6aa20 |
|
|
@ -1510,6 +1510,13 @@ ProjectSettings::ProjectSettings() {
|
||||||
GLOBAL_DEF("display/window/size/no_focus", false);
|
GLOBAL_DEF("display/window/size/no_focus", false);
|
||||||
GLOBAL_DEF("display/window/size/sharp_corners", false);
|
GLOBAL_DEF("display/window/size/sharp_corners", false);
|
||||||
|
|
||||||
|
GLOBAL_DEF("display/window/hdr/enabled", false);
|
||||||
|
GLOBAL_DEF("display/window/hdr/prefer_high_precision", false);
|
||||||
|
GLOBAL_DEF("display/window/hdr/use_screen_luminance", true);
|
||||||
|
GLOBAL_DEF(PropertyInfo(Variant::FLOAT, "display/window/hdr/reference_luminance", PROPERTY_HINT_RANGE, "0,2000,1,or_greater"), 80.0f); // sRGB standard of 80 nits
|
||||||
|
GLOBAL_DEF(PropertyInfo(Variant::FLOAT, "display/window/hdr/min_luminance", PROPERTY_HINT_RANGE, "0,2000,1,or_greater"), 0.0f);
|
||||||
|
GLOBAL_DEF(PropertyInfo(Variant::FLOAT, "display/window/hdr/max_luminance", PROPERTY_HINT_RANGE, "0,2000,1,or_greater"), 1000.0f);
|
||||||
|
|
||||||
GLOBAL_DEF(PropertyInfo(Variant::INT, "display/window/size/window_width_override", PROPERTY_HINT_RANGE, "0,7680,1,or_greater"), 0); // 8K resolution
|
GLOBAL_DEF(PropertyInfo(Variant::INT, "display/window/size/window_width_override", PROPERTY_HINT_RANGE, "0,7680,1,or_greater"), 0); // 8K resolution
|
||||||
GLOBAL_DEF(PropertyInfo(Variant::INT, "display/window/size/window_height_override", PROPERTY_HINT_RANGE, "0,4320,1,or_greater"), 0); // 8K resolution
|
GLOBAL_DEF(PropertyInfo(Variant::INT, "display/window/size/window_height_override", PROPERTY_HINT_RANGE, "0,4320,1,or_greater"), 0); // 8K resolution
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1090,6 +1090,25 @@
|
||||||
[b]Note:[/b] On macOS, this method requires "Screen Recording" permission, if permission is not granted it will return desktop wallpaper color.
|
[b]Note:[/b] On macOS, this method requires "Screen Recording" permission, if permission is not granted it will return desktop wallpaper color.
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
|
<method name="screen_get_max_average_luminance" qualifiers="const">
|
||||||
|
<return type="float" />
|
||||||
|
<param index="0" name="screen" type="int" default="-1" />
|
||||||
|
<description>
|
||||||
|
Returns the maximum full screen luminance of [param screen] in nits (cd/m²).
|
||||||
|
Some displays support brighter luminance in small areas, but this is the maximum luminance that can be achieved across the entire screen.
|
||||||
|
[b]Note:[/b] Requires support for [constant FEATURE_HDR].
|
||||||
|
[b]Note:[/b] On Windows, this method is implemented only in builds with D3D12 enabled.
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
|
<method name="screen_get_max_luminance" qualifiers="const">
|
||||||
|
<return type="float" />
|
||||||
|
<param index="0" name="screen" type="int" default="-1" />
|
||||||
|
<description>
|
||||||
|
Returns the maximum luminance of a pixel on [param screen] in nits (cd/m²).
|
||||||
|
[b]Note:[/b] Requires support for [constant FEATURE_HDR].
|
||||||
|
[b]Note:[/b] On Windows, this method is implemented only in builds with D3D12 enabled.
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
<method name="screen_get_max_scale" qualifiers="const">
|
<method name="screen_get_max_scale" qualifiers="const">
|
||||||
<return type="float" />
|
<return type="float" />
|
||||||
<description>
|
<description>
|
||||||
|
|
@ -1098,6 +1117,15 @@
|
||||||
[b]Note:[/b] This method is implemented only on macOS.
|
[b]Note:[/b] This method is implemented only on macOS.
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
|
<method name="screen_get_min_luminance" qualifiers="const">
|
||||||
|
<return type="float" />
|
||||||
|
<param index="0" name="screen" type="int" default="-1" />
|
||||||
|
<description>
|
||||||
|
Returns the minimum luminance of a pixel on [param screen] in nits (cd/m²).
|
||||||
|
[b]Note:[/b] Requires support for [constant FEATURE_HDR].
|
||||||
|
[b]Note:[/b] On Windows, this method is implemented only in builds with D3D12 enabled.
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
<method name="screen_get_orientation" qualifiers="const">
|
<method name="screen_get_orientation" qualifiers="const">
|
||||||
<return type="int" enum="DisplayServer.ScreenOrientation" />
|
<return type="int" enum="DisplayServer.ScreenOrientation" />
|
||||||
<param index="0" name="screen" type="int" default="-1" />
|
<param index="0" name="screen" type="int" default="-1" />
|
||||||
|
|
@ -1156,6 +1184,15 @@
|
||||||
[b]Note:[/b] This method is implemented on Android, iOS, Web, macOS, and Linux (Wayland).
|
[b]Note:[/b] This method is implemented on Android, iOS, Web, macOS, and Linux (Wayland).
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
|
<method name="screen_get_sdr_white_level" qualifiers="const">
|
||||||
|
<return type="float" />
|
||||||
|
<param index="0" name="screen" type="int" default="-1" />
|
||||||
|
<description>
|
||||||
|
Returns the standard dynamic range (SDR) white level of [param screen] in nits (cd/m²).
|
||||||
|
This is the maximum brightness SDR content (such as UI) should be rendered at to match other applications on the display.
|
||||||
|
[b]Note:[/b] Requires support for [constant FEATURE_HDR].
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
<method name="screen_get_size" qualifiers="const">
|
<method name="screen_get_size" qualifiers="const">
|
||||||
<return type="Vector2i" />
|
<return type="Vector2i" />
|
||||||
<param index="0" name="screen" type="int" default="-1" />
|
<param index="0" name="screen" type="int" default="-1" />
|
||||||
|
|
@ -1170,6 +1207,15 @@
|
||||||
Returns the portion of the screen that is not obstructed by a status bar in pixels. See also [method screen_get_size].
|
Returns the portion of the screen that is not obstructed by a status bar in pixels. See also [method screen_get_size].
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
|
<method name="screen_is_hdr_supported" qualifiers="const">
|
||||||
|
<return type="bool" />
|
||||||
|
<param index="0" name="screen" type="int" default="-1" />
|
||||||
|
<description>
|
||||||
|
Returns [code]true[/code] if the [param screen] supports HDR.
|
||||||
|
[b]Note:[/b] Requires support for [constant FEATURE_HDR].
|
||||||
|
[b]Note:[/b] On Windows, this method is implemented only in builds with D3D12 enabled.
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
<method name="screen_is_kept_on" qualifiers="const">
|
<method name="screen_is_kept_on" qualifiers="const">
|
||||||
<return type="bool" />
|
<return type="bool" />
|
||||||
<description>
|
<description>
|
||||||
|
|
@ -1481,6 +1527,30 @@
|
||||||
Returns the current value of the given window's [param flag].
|
Returns the current value of the given window's [param flag].
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
|
<method name="window_get_hdr_output_max_luminance" qualifiers="const">
|
||||||
|
<return type="float" />
|
||||||
|
<param index="0" name="window_id" type="int" default="0" />
|
||||||
|
<description>
|
||||||
|
Returns the maximum luminance in nits (cd/m²) set for HDR content for the window specified by [param window_id].
|
||||||
|
[b]Note:[/b] Requires support for [constant FEATURE_HDR].
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
|
<method name="window_get_hdr_output_min_luminance" qualifiers="const">
|
||||||
|
<return type="float" />
|
||||||
|
<param index="0" name="window_id" type="int" default="0" />
|
||||||
|
<description>
|
||||||
|
Returns the minimum luminance in nits (cd/m²) set for HDR content for the window specified by [param window_id].
|
||||||
|
[b]Note:[/b] Requires support for [constant FEATURE_HDR].
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
|
<method name="window_get_hdr_output_reference_luminance" qualifiers="const">
|
||||||
|
<return type="float" />
|
||||||
|
<param index="0" name="window_id" type="int" default="0" />
|
||||||
|
<description>
|
||||||
|
Returns the SDR reference luminance in nits (cd/m²) set for HDR content for the window specified by [param window_id].
|
||||||
|
[b]Note:[/b] Requires support for [constant FEATURE_HDR].
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
<method name="window_get_max_size" qualifiers="const">
|
<method name="window_get_max_size" qualifiers="const">
|
||||||
<return type="Vector2i" />
|
<return type="Vector2i" />
|
||||||
<param index="0" name="window_id" type="int" default="0" />
|
<param index="0" name="window_id" type="int" default="0" />
|
||||||
|
|
@ -1576,6 +1646,29 @@
|
||||||
Returns [code]true[/code] if the window specified by [param window_id] is focused.
|
Returns [code]true[/code] if the window specified by [param window_id] is focused.
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
|
<method name="window_is_hdr_output_enabled" qualifiers="const">
|
||||||
|
<return type="bool" />
|
||||||
|
<param index="0" name="window_id" type="int" default="0" />
|
||||||
|
<description>
|
||||||
|
Returns whether HDR output is requested for the window specified by [param window_id].
|
||||||
|
[b]Note:[/b] Requires support for [constant FEATURE_HDR].
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
|
<method name="window_is_hdr_output_preferring_high_precision" qualifiers="const">
|
||||||
|
<return type="bool" />
|
||||||
|
<param index="0" name="window_id" type="int" default="0" />
|
||||||
|
<description>
|
||||||
|
Returns whether the window specified by [param window_id] prefers a high precision (16-bit per color) HDR framebuffer.
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
|
<method name="window_is_hdr_output_using_screen_luminance" qualifiers="const">
|
||||||
|
<return type="bool" />
|
||||||
|
<param index="0" name="window_id" type="int" default="0" />
|
||||||
|
<description>
|
||||||
|
Returns whether the window specified by [param window_id] is using the screen's luminance for HDR output.
|
||||||
|
[b]Note:[/b] Requires support for [constant FEATURE_HDR].
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
<method name="window_is_maximize_allowed" qualifiers="const">
|
<method name="window_is_maximize_allowed" qualifiers="const">
|
||||||
<return type="bool" />
|
<return type="bool" />
|
||||||
<param index="0" name="window_id" type="int" default="0" />
|
<param index="0" name="window_id" type="int" default="0" />
|
||||||
|
|
@ -1648,6 +1741,71 @@
|
||||||
Enables or disables the given window's given [param flag]. See [enum WindowFlags] for possible values and their behavior.
|
Enables or disables the given window's given [param flag]. See [enum WindowFlags] for possible values and their behavior.
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
|
<method name="window_set_hdr_output_enabled">
|
||||||
|
<return type="void" />
|
||||||
|
<param index="0" name="enabled" type="bool" />
|
||||||
|
<param index="1" name="window_id" type="int" default="0" />
|
||||||
|
<description>
|
||||||
|
Sets whether HDR output should be enabled for the window specified by [param window_id], falling back to SDR if not supported.
|
||||||
|
Only available on platforms that support HDR output, have HDR enabled in the system settings, and have a compatible display connected.
|
||||||
|
[b]Note:[/b] Requires support for [constant FEATURE_HDR].
|
||||||
|
[b]Note:[/b] Requires support by the rendering device.
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
|
<method name="window_set_hdr_output_max_luminance">
|
||||||
|
<return type="void" />
|
||||||
|
<param index="0" name="max_luminance" type="float" />
|
||||||
|
<param index="1" name="window_id" type="int" default="0" />
|
||||||
|
<description>
|
||||||
|
Sets the maximum luminance in nits (cd/m²) for HDR content for the window specified by [param window_id].
|
||||||
|
[b]Note:[/b] Requires support for [constant FEATURE_HDR].
|
||||||
|
[b]Note:[/b] Requires support by the rendering device.
|
||||||
|
[b]Note:[/b] Ignored if [method window_is_hdr_output_using_screen_luminance] is [code]true[/code].
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
|
<method name="window_set_hdr_output_min_luminance">
|
||||||
|
<return type="void" />
|
||||||
|
<param index="0" name="min_luminance" type="float" />
|
||||||
|
<param index="1" name="window_id" type="int" default="0" />
|
||||||
|
<description>
|
||||||
|
Sets the minimum luminance in nits (cd/m²) for HDR content for the window specified by [param window_id].
|
||||||
|
[b]Note:[/b] Requires support for [constant FEATURE_HDR].
|
||||||
|
[b]Note:[/b] Requires support by the rendering device.
|
||||||
|
[b]Note:[/b] Ignored if [method window_is_hdr_output_using_screen_luminance] is [code]true[/code].
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
|
<method name="window_set_hdr_output_prefer_high_precision">
|
||||||
|
<return type="void" />
|
||||||
|
<param index="0" name="enabled" type="bool" />
|
||||||
|
<param index="1" name="window_id" type="int" default="0" />
|
||||||
|
<description>
|
||||||
|
Sets whether the window specified by [param window_id] prefers a high precision (16-bit per color) framebuffer.
|
||||||
|
[b]Note:[/b] Requires support for [constant FEATURE_HDR].
|
||||||
|
[b]Note:[/b] Requires support by the rendering device.
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
|
<method name="window_set_hdr_output_reference_luminance">
|
||||||
|
<return type="void" />
|
||||||
|
<param index="0" name="reference_luminance" type="float" />
|
||||||
|
<param index="1" name="window_id" type="int" default="0" />
|
||||||
|
<description>
|
||||||
|
Sets the SDR reference luminance in nits (cd/m²) for HDR content for the window specified by [param window_id].
|
||||||
|
This controls the brightness of SDR content (such as UI) when HDR is enabled.
|
||||||
|
[b]Note:[/b] Requires support for [constant FEATURE_HDR].
|
||||||
|
[b]Note:[/b] Requires support by the rendering device.
|
||||||
|
[b]Note:[/b] Ignored if [method window_is_hdr_output_using_screen_luminance] is [code]true[/code].
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
|
<method name="window_set_hdr_output_use_screen_luminance">
|
||||||
|
<return type="void" />
|
||||||
|
<param index="0" name="enabled" type="bool" />
|
||||||
|
<param index="1" name="window_id" type="int" default="0" />
|
||||||
|
<description>
|
||||||
|
Sets whether the window specified by [param window_id] should use the screen's luminance for HDR output.
|
||||||
|
While this is enabled, the window will ignore attempts to set luminance values.
|
||||||
|
[b]Note:[/b] Requires support for [constant FEATURE_HDR].
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
<method name="window_set_ime_active">
|
<method name="window_set_ime_active">
|
||||||
<return type="void" />
|
<return type="void" />
|
||||||
<param index="0" name="active" type="bool" />
|
<param index="0" name="active" type="bool" />
|
||||||
|
|
@ -1952,6 +2110,9 @@
|
||||||
<constant name="FEATURE_EMOJI_AND_SYMBOL_PICKER" value="31" enum="Feature">
|
<constant name="FEATURE_EMOJI_AND_SYMBOL_PICKER" value="31" enum="Feature">
|
||||||
Display server supports system emoji and symbol picker. [b]Windows, macOS[/b]
|
Display server supports system emoji and symbol picker. [b]Windows, macOS[/b]
|
||||||
</constant>
|
</constant>
|
||||||
|
<constant name="FEATURE_HDR" value="32" enum="Feature">
|
||||||
|
Display server supports HDR output. [b]Windows[/b]
|
||||||
|
</constant>
|
||||||
<constant name="MOUSE_MODE_VISIBLE" value="0" enum="MouseMode">
|
<constant name="MOUSE_MODE_VISIBLE" value="0" enum="MouseMode">
|
||||||
Makes the mouse cursor visible if it is hidden.
|
Makes the mouse cursor visible if it is hidden.
|
||||||
</constant>
|
</constant>
|
||||||
|
|
|
||||||
|
|
@ -836,6 +836,30 @@
|
||||||
The default screen orientation to use on mobile devices. See [enum DisplayServer.ScreenOrientation] for possible values.
|
The default screen orientation to use on mobile devices. See [enum DisplayServer.ScreenOrientation] for possible values.
|
||||||
[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.
|
[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.
|
||||||
</member>
|
</member>
|
||||||
|
<member name="display/window/hdr/enabled" type="bool" setter="" getter="" default="false">
|
||||||
|
If [code]true[/code], enables HDR output on supported platforms, falling back to SDR if not supported.
|
||||||
|
Only available on platforms that support HDR output, have HDR enabled in the system settings, and have a compatible display connected.
|
||||||
|
</member>
|
||||||
|
<member name="display/window/hdr/max_luminance" type="float" setter="" getter="" default="1000.0">
|
||||||
|
Sets the maximum luminance of the display in nits (cd/m²) when HDR is enabled.
|
||||||
|
</member>
|
||||||
|
<member name="display/window/hdr/min_luminance" type="float" setter="" getter="" default="0.0">
|
||||||
|
Sets the minimum luminance of the display in nits (cd/m²) when HDR is enabled.
|
||||||
|
</member>
|
||||||
|
<member name="display/window/hdr/prefer_high_precision" type="bool" setter="" getter="" default="false">
|
||||||
|
If [code]true[/code], uses 16 bit per color buffers for the frame buffer when HDR is enabled.
|
||||||
|
If [code]false[/code], uses 10 bit per color buffers, with 2 bits for alpha, for the frame buffer when HDR is enabled.
|
||||||
|
This may improve color precision and reduce banding in the final image, but will use more memory and may reduce performance.
|
||||||
|
If transparent backgrounds are enabled, you may want to enable this setting to enable smooth blending of HDR content.
|
||||||
|
</member>
|
||||||
|
<member name="display/window/hdr/reference_luminance" type="float" setter="" getter="" default="80.0">
|
||||||
|
Sets the SDR reference luminance of the display in nits (cd/m²) when HDR is enabled.
|
||||||
|
This is used to scale the HDR effect to ensure sRGB content looks the same in both SDR and HDR.
|
||||||
|
</member>
|
||||||
|
<member name="display/window/hdr/use_screen_luminance" type="bool" setter="" getter="" default="true">
|
||||||
|
If [code]true[/code], uses the screen's luminance as reported by the display server to set luminance for the window.
|
||||||
|
If information is missing for the display, will fall back to luminance values set in project settings.
|
||||||
|
</member>
|
||||||
<member name="display/window/ios/allow_high_refresh_rate" type="bool" setter="" getter="" default="true">
|
<member name="display/window/ios/allow_high_refresh_rate" type="bool" setter="" getter="" default="true">
|
||||||
If [code]true[/code], iOS devices that support high refresh rate/"ProMotion" will be allowed to render at up to 120 frames per second.
|
If [code]true[/code], iOS devices that support high refresh rate/"ProMotion" will be allowed to render at up to 120 frames per second.
|
||||||
</member>
|
</member>
|
||||||
|
|
@ -3184,6 +3208,9 @@
|
||||||
[b]Note:[/b] This setting will have no effect when using the Compatibility renderer, which always renders in low dynamic range for performance reasons.
|
[b]Note:[/b] This setting will have no effect when using the Compatibility renderer, which always renders in low dynamic range for performance reasons.
|
||||||
[b]Note:[/b] This property is only read when the project starts. To toggle HDR 2D at runtime, set [member Viewport.use_hdr_2d] on the root [Viewport].
|
[b]Note:[/b] This property is only read when the project starts. To toggle HDR 2D at runtime, set [member Viewport.use_hdr_2d] on the root [Viewport].
|
||||||
</member>
|
</member>
|
||||||
|
<member name="rendering/viewport/tonemap_to_window" type="bool" setter="" getter="" default="true">
|
||||||
|
If [code]true[/code], enables [member Viewport.tonemap_to_window] on the root viewport.
|
||||||
|
</member>
|
||||||
<member name="rendering/viewport/transparent_background" type="bool" setter="" getter="" default="false">
|
<member name="rendering/viewport/transparent_background" type="bool" setter="" getter="" default="false">
|
||||||
If [code]true[/code], enables [member Viewport.transparent_bg] on the root viewport. This allows per-pixel transparency to be effective after also enabling [member display/window/size/transparent] and [member display/window/per_pixel_transparency/allowed].
|
If [code]true[/code], enables [member Viewport.transparent_bg] on the root viewport. This allows per-pixel transparency to be effective after also enabling [member display/window/size/transparent] and [member display/window/per_pixel_transparency/allowed].
|
||||||
</member>
|
</member>
|
||||||
|
|
|
||||||
|
|
@ -758,6 +758,22 @@
|
||||||
Returns [code]true[/code] if implementation supports using a texture of [param format] with the given [param sampler_filter].
|
Returns [code]true[/code] if implementation supports using a texture of [param format] with the given [param sampler_filter].
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
|
<method name="screen_get_color_format" qualifiers="const">
|
||||||
|
<return type="int" enum="RenderingDevice.DataFormat" />
|
||||||
|
<param index="0" name="screen" type="int" default="0" />
|
||||||
|
<description>
|
||||||
|
Returns the color format of the given screen.
|
||||||
|
[b]Note:[/b] Only the main [RenderingDevice] returned by [method RenderingServer.get_rendering_device] has a format. If called on a local [RenderingDevice], this method prints an error and returns [constant DATA_FORMAT_MAX].
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
|
<method name="screen_get_color_space" qualifiers="const">
|
||||||
|
<return type="int" enum="RenderingDevice.ColorSpace" />
|
||||||
|
<param index="0" name="screen" type="int" default="0" />
|
||||||
|
<description>
|
||||||
|
Returns the color space of the given screen.
|
||||||
|
[b]Note:[/b] Only the main [RenderingDevice] returned by [method RenderingServer.get_rendering_device] has a format. If called on a local [RenderingDevice], this method prints an error and returns [constant COLOR_SPACE_MAX].
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
<method name="screen_get_framebuffer_format" qualifiers="const">
|
<method name="screen_get_framebuffer_format" qualifiers="const">
|
||||||
<return type="int" />
|
<return type="int" />
|
||||||
<param index="0" name="screen" type="int" default="0" />
|
<param index="0" name="screen" type="int" default="0" />
|
||||||
|
|
@ -1874,6 +1890,18 @@
|
||||||
<constant name="DATA_FORMAT_MAX" value="218" enum="DataFormat">
|
<constant name="DATA_FORMAT_MAX" value="218" enum="DataFormat">
|
||||||
Represents the size of the [enum DataFormat] enum.
|
Represents the size of the [enum DataFormat] enum.
|
||||||
</constant>
|
</constant>
|
||||||
|
<constant name="COLOR_SPACE_SRGB_LINEAR" value="0" enum="ColorSpace">
|
||||||
|
Color space using Rec 709 primaries and linear gamma.
|
||||||
|
</constant>
|
||||||
|
<constant name="COLOR_SPACE_SRGB_NONLINEAR" value="1" enum="ColorSpace">
|
||||||
|
Color space using Rec 709 primaries and non-linear sRGB gamma.
|
||||||
|
</constant>
|
||||||
|
<constant name="COLOR_SPACE_HDR10_ST2084" value="2" enum="ColorSpace">
|
||||||
|
Color space using Rec 2020 primaries and the ST 2084 transfer function.
|
||||||
|
</constant>
|
||||||
|
<constant name="COLOR_SPACE_MAX" value="3" enum="ColorSpace">
|
||||||
|
Represents the size of the [enum ColorSpace] enum.
|
||||||
|
</constant>
|
||||||
<constant name="BARRIER_MASK_VERTEX" value="1" enum="BarrierMask" is_bitfield="true">
|
<constant name="BARRIER_MASK_VERTEX" value="1" enum="BarrierMask" is_bitfield="true">
|
||||||
Vertex shader barrier mask.
|
Vertex shader barrier mask.
|
||||||
</constant>
|
</constant>
|
||||||
|
|
@ -2454,6 +2482,9 @@
|
||||||
<constant name="SUPPORTS_BUFFER_DEVICE_ADDRESS" value="6" enum="Features">
|
<constant name="SUPPORTS_BUFFER_DEVICE_ADDRESS" value="6" enum="Features">
|
||||||
Features support for buffer device address extension.
|
Features support for buffer device address extension.
|
||||||
</constant>
|
</constant>
|
||||||
|
<constant name="SUPPORTS_HDR_OUTPUT" value="7" enum="Features">
|
||||||
|
Features support for high dynamic range (HDR) output.
|
||||||
|
</constant>
|
||||||
<constant name="LIMIT_MAX_BOUND_UNIFORM_SETS" value="0" enum="Limit">
|
<constant name="LIMIT_MAX_BOUND_UNIFORM_SETS" value="0" enum="Limit">
|
||||||
Maximum number of uniform sets that can be bound at a given time.
|
Maximum number of uniform sets that can be bound at a given time.
|
||||||
</constant>
|
</constant>
|
||||||
|
|
|
||||||
|
|
@ -1493,6 +1493,16 @@
|
||||||
Sets the variables to be used with the "tonemap" post-process effect. See [Environment] for more details.
|
Sets the variables to be used with the "tonemap" post-process effect. See [Environment] for more details.
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
|
<method name="environment_set_tonemap_range">
|
||||||
|
<return type="void" />
|
||||||
|
<param index="0" name="env" type="RID" />
|
||||||
|
<param index="1" name="min_value" type="float" />
|
||||||
|
<param index="2" name="max_value" type="float" />
|
||||||
|
<description>
|
||||||
|
Sets the range of the tonemapper, defining the minimum and maximum values after tonemapping.
|
||||||
|
[b]Note:[/b] This is ignored when using [constant ENV_TONE_MAPPER_LINEAR].
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
<method name="environment_set_volumetric_fog">
|
<method name="environment_set_volumetric_fog">
|
||||||
<return type="void" />
|
<return type="void" />
|
||||||
<param index="0" name="env" type="RID" />
|
<param index="0" name="env" type="RID" />
|
||||||
|
|
@ -4190,6 +4200,14 @@
|
||||||
[b]Note:[/b] When the 3D scaling mode is set to FSR 1.0, this value is used to adjust the automatic mipmap bias which is calculated internally based on the scale factor. The formula for this is [code]-log2(1.0 / scale) + mipmap_bias[/code].
|
[b]Note:[/b] When the 3D scaling mode is set to FSR 1.0, this value is used to adjust the automatic mipmap bias which is calculated internally based on the scale factor. The formula for this is [code]-log2(1.0 / scale) + mipmap_bias[/code].
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
|
<method name="viewport_set_tonemap_to_screen">
|
||||||
|
<return type="void" />
|
||||||
|
<param index="0" name="viewport" type="RID" />
|
||||||
|
<param index="1" name="enabled" type="bool" />
|
||||||
|
<description>
|
||||||
|
If [code]true[/code], the viewport will tonemap its content to the window's HDR output luminance range, if HDR output is enabled.
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
<method name="viewport_set_transparent_background">
|
<method name="viewport_set_transparent_background">
|
||||||
<return type="void" />
|
<return type="void" />
|
||||||
<param index="0" name="viewport" type="RID" />
|
<param index="0" name="viewport" type="RID" />
|
||||||
|
|
|
||||||
|
|
@ -415,6 +415,10 @@
|
||||||
[b]Note:[/b] If [member scaling_3d_scale] is lower than [code]1.0[/code] (exclusive), [member texture_mipmap_bias] is used to adjust the automatic mipmap bias which is calculated internally based on the scale factor. The formula for this is [code]log2(scaling_3d_scale) + mipmap_bias[/code].
|
[b]Note:[/b] If [member scaling_3d_scale] is lower than [code]1.0[/code] (exclusive), [member texture_mipmap_bias] is used to adjust the automatic mipmap bias which is calculated internally based on the scale factor. The formula for this is [code]log2(scaling_3d_scale) + mipmap_bias[/code].
|
||||||
To control this property on the root viewport, set the [member ProjectSettings.rendering/textures/default_filters/texture_mipmap_bias] project setting.
|
To control this property on the root viewport, set the [member ProjectSettings.rendering/textures/default_filters/texture_mipmap_bias] project setting.
|
||||||
</member>
|
</member>
|
||||||
|
<member name="tonemap_to_window" type="bool" setter="set_tonemap_to_window" getter="is_tonemapping_to_window" default="false">
|
||||||
|
If [code]true[/code], the viewport will tonemap its content to the window's HDR output luminance range, if HDR output is enabled.
|
||||||
|
This is useful for viewports that are not the root of the window, but still need their content to adjust to the capabilities of the display.
|
||||||
|
</member>
|
||||||
<member name="transparent_bg" type="bool" setter="set_transparent_background" getter="has_transparent_background" default="false">
|
<member name="transparent_bg" type="bool" setter="set_transparent_background" getter="has_transparent_background" default="false">
|
||||||
If [code]true[/code], the viewport should render its background as transparent.
|
If [code]true[/code], the viewport should render its background as transparent.
|
||||||
</member>
|
</member>
|
||||||
|
|
|
||||||
|
|
@ -614,6 +614,26 @@
|
||||||
<member name="force_native" type="bool" setter="set_force_native" getter="get_force_native" default="false">
|
<member name="force_native" type="bool" setter="set_force_native" getter="get_force_native" default="false">
|
||||||
If [code]true[/code], native window will be used regardless of parent viewport and project settings.
|
If [code]true[/code], native window will be used regardless of parent viewport and project settings.
|
||||||
</member>
|
</member>
|
||||||
|
<member name="hdr_output_enabled" type="bool" setter="set_hdr_output_enabled" getter="is_hdr_output_enabled" default="false">
|
||||||
|
If [code]true[/code], the [Window] will output in HDR.
|
||||||
|
Only available on platforms that support HDR output, have HDR enabled in the system settings, and have a compatible display connected.
|
||||||
|
</member>
|
||||||
|
<member name="hdr_output_max_luminance" type="float" setter="set_hdr_output_max_luminance" getter="get_hdr_output_max_luminance" default="1000.0">
|
||||||
|
The maximum luminance in nits (cd/m²) when HDR is enabled.
|
||||||
|
</member>
|
||||||
|
<member name="hdr_output_min_luminance" type="float" setter="set_hdr_output_min_luminance" getter="get_hdr_output_min_luminance" default="0.0">
|
||||||
|
The minimum luminance in nits (cd/m²) when HDR is enabled.
|
||||||
|
</member>
|
||||||
|
<member name="hdr_output_prefer_high_precision" type="bool" setter="set_hdr_output_prefer_high_precision" getter="is_hdr_output_preferring_high_precision" default="false">
|
||||||
|
If [code]true[/code], the [Window] will prefer high-precision (16-bit per color) framebuffer when available and HDR is enabled.
|
||||||
|
</member>
|
||||||
|
<member name="hdr_output_reference_luminance" type="float" setter="set_hdr_output_reference_luminance" getter="get_hdr_output_reference_luminance" default="80.0">
|
||||||
|
The SDR reference luminance in nits (cd/m²) when HDR is enabled.
|
||||||
|
This controls the brightness of SDR content (such as UI) when HDR is enabled.
|
||||||
|
</member>
|
||||||
|
<member name="hdr_output_use_screen_luminance" type="bool" setter="set_hdr_output_use_screen_luminance" getter="is_hdr_output_using_screen_luminance" default="false">
|
||||||
|
If [code]true[/code], the [Window] will use the screen's luminance to adjust the HDR output.
|
||||||
|
</member>
|
||||||
<member name="initial_position" type="int" setter="set_initial_position" getter="get_initial_position" enum="Window.WindowInitialPosition" default="0">
|
<member name="initial_position" type="int" setter="set_initial_position" getter="get_initial_position" enum="Window.WindowInitialPosition" default="0">
|
||||||
Specifies the initial type of position for the [Window]. See [enum WindowInitialPosition] constants.
|
Specifies the initial type of position for the [Window]. See [enum WindowInitialPosition] constants.
|
||||||
</member>
|
</member>
|
||||||
|
|
@ -693,6 +713,7 @@
|
||||||
<member name="title" type="String" setter="set_title" getter="get_title" default="""">
|
<member name="title" type="String" setter="set_title" getter="get_title" default="""">
|
||||||
The window's title. If the [Window] is native, title styles set in [Theme] will have no effect.
|
The window's title. If the [Window] is native, title styles set in [Theme] will have no effect.
|
||||||
</member>
|
</member>
|
||||||
|
<member name="tonemap_to_window" type="bool" setter="set_tonemap_to_window" getter="is_tonemapping_to_window" overrides="Viewport" default="true" />
|
||||||
<member name="transient" type="bool" setter="set_transient" getter="is_transient" default="false">
|
<member name="transient" type="bool" setter="set_transient" getter="is_transient" default="false">
|
||||||
If [code]true[/code], the [Window] is transient, i.e. it's considered a child of another [Window]. The transient window will be destroyed with its transient parent and will return focus to their parent when closed. The transient window is displayed on top of a non-exclusive full-screen parent window. Transient windows can't enter full-screen mode.
|
If [code]true[/code], the [Window] is transient, i.e. it's considered a child of another [Window]. The transient window will be destroyed with its transient parent and will return focus to their parent when closed. The transient window is displayed on top of a non-exclusive full-screen parent window. Transient windows can't enter full-screen mode.
|
||||||
Note that behavior might be different depending on the platform.
|
Note that behavior might be different depending on the platform.
|
||||||
|
|
|
||||||
|
|
@ -282,6 +282,58 @@ DisplayServer::VSyncMode RenderingContextDriverD3D12::surface_get_vsync_mode(Sur
|
||||||
return surface->vsync_mode;
|
return surface->vsync_mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RenderingContextDriverD3D12::surface_set_hdr_output_enabled(SurfaceID p_surface, bool p_enabled) {
|
||||||
|
Surface *surface = (Surface *)(p_surface);
|
||||||
|
surface->hdr_output = p_enabled;
|
||||||
|
surface->needs_resize = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RenderingContextDriverD3D12::surface_get_hdr_output_enabled(SurfaceID p_surface) const {
|
||||||
|
Surface *surface = (Surface *)(p_surface);
|
||||||
|
return surface->hdr_output;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RenderingContextDriverD3D12::surface_set_hdr_output_prefer_high_precision(SurfaceID p_surface, bool p_enabled) {
|
||||||
|
Surface *surface = (Surface *)(p_surface);
|
||||||
|
surface->hdr_prefer_high_precision = p_enabled;
|
||||||
|
surface->needs_resize = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RenderingContextDriverD3D12::surface_get_hdr_output_prefer_high_precision(SurfaceID p_surface) const {
|
||||||
|
Surface *surface = (Surface *)(p_surface);
|
||||||
|
return surface->hdr_prefer_high_precision;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RenderingContextDriverD3D12::surface_set_hdr_output_reference_luminance(SurfaceID p_surface, float p_reference_luminance) {
|
||||||
|
Surface *surface = (Surface *)(p_surface);
|
||||||
|
surface->hdr_reference_luminance = p_reference_luminance;
|
||||||
|
}
|
||||||
|
|
||||||
|
float RenderingContextDriverD3D12::surface_get_hdr_output_reference_luminance(SurfaceID p_surface) const {
|
||||||
|
Surface *surface = (Surface *)(p_surface);
|
||||||
|
return surface->hdr_reference_luminance;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RenderingContextDriverD3D12::surface_set_hdr_output_min_luminance(SurfaceID p_surface, float p_min_luminance) {
|
||||||
|
Surface *surface = (Surface *)(p_surface);
|
||||||
|
surface->hdr_min_luminance = p_min_luminance;
|
||||||
|
}
|
||||||
|
|
||||||
|
float RenderingContextDriverD3D12::surface_get_hdr_output_min_luminance(SurfaceID p_surface) const {
|
||||||
|
Surface *surface = (Surface *)(p_surface);
|
||||||
|
return surface->hdr_min_luminance;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RenderingContextDriverD3D12::surface_set_hdr_output_max_luminance(SurfaceID p_surface, float p_max_luminance) {
|
||||||
|
Surface *surface = (Surface *)(p_surface);
|
||||||
|
surface->hdr_max_luminance = p_max_luminance;
|
||||||
|
}
|
||||||
|
|
||||||
|
float RenderingContextDriverD3D12::surface_get_hdr_output_max_luminance(SurfaceID p_surface) const {
|
||||||
|
Surface *surface = (Surface *)(p_surface);
|
||||||
|
return surface->hdr_max_luminance;
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t RenderingContextDriverD3D12::surface_get_width(SurfaceID p_surface) const {
|
uint32_t RenderingContextDriverD3D12::surface_get_width(SurfaceID p_surface) const {
|
||||||
Surface *surface = (Surface *)(p_surface);
|
Surface *surface = (Surface *)(p_surface);
|
||||||
return surface->width;
|
return surface->width;
|
||||||
|
|
|
||||||
|
|
@ -109,6 +109,16 @@ public:
|
||||||
virtual void surface_set_size(SurfaceID p_surface, uint32_t p_width, uint32_t p_height) override;
|
virtual void surface_set_size(SurfaceID p_surface, uint32_t p_width, uint32_t p_height) override;
|
||||||
virtual void surface_set_vsync_mode(SurfaceID p_surface, DisplayServer::VSyncMode p_vsync_mode) override;
|
virtual void surface_set_vsync_mode(SurfaceID p_surface, DisplayServer::VSyncMode p_vsync_mode) override;
|
||||||
virtual DisplayServer::VSyncMode surface_get_vsync_mode(SurfaceID p_surface) const override;
|
virtual DisplayServer::VSyncMode surface_get_vsync_mode(SurfaceID p_surface) const override;
|
||||||
|
virtual void surface_set_hdr_output_enabled(SurfaceID p_surface, bool p_enabled) override;
|
||||||
|
virtual bool surface_get_hdr_output_enabled(SurfaceID p_surface) const override;
|
||||||
|
virtual void surface_set_hdr_output_prefer_high_precision(SurfaceID p_surface, bool p_enabled) override;
|
||||||
|
virtual bool surface_get_hdr_output_prefer_high_precision(SurfaceID p_surface) const override;
|
||||||
|
virtual void surface_set_hdr_output_reference_luminance(SurfaceID p_surface, float p_reference_luminance) override;
|
||||||
|
virtual float surface_get_hdr_output_reference_luminance(SurfaceID p_surface) const override;
|
||||||
|
virtual void surface_set_hdr_output_min_luminance(SurfaceID p_surface, float p_min_luminance) override;
|
||||||
|
virtual float surface_get_hdr_output_min_luminance(SurfaceID p_surface) const override;
|
||||||
|
virtual void surface_set_hdr_output_max_luminance(SurfaceID p_surface, float p_max_luminance) override;
|
||||||
|
virtual float surface_get_hdr_output_max_luminance(SurfaceID p_surface) const override;
|
||||||
virtual uint32_t surface_get_width(SurfaceID p_surface) const override;
|
virtual uint32_t surface_get_width(SurfaceID p_surface) const override;
|
||||||
virtual uint32_t surface_get_height(SurfaceID p_surface) const override;
|
virtual uint32_t surface_get_height(SurfaceID p_surface) const override;
|
||||||
virtual void surface_set_needs_resize(SurfaceID p_surface, bool p_needs_resize) override;
|
virtual void surface_set_needs_resize(SurfaceID p_surface, bool p_needs_resize) override;
|
||||||
|
|
@ -128,6 +138,13 @@ public:
|
||||||
uint32_t height = 0;
|
uint32_t height = 0;
|
||||||
DisplayServer::VSyncMode vsync_mode = DisplayServer::VSYNC_ENABLED;
|
DisplayServer::VSyncMode vsync_mode = DisplayServer::VSYNC_ENABLED;
|
||||||
bool needs_resize = false;
|
bool needs_resize = false;
|
||||||
|
|
||||||
|
bool hdr_output = false;
|
||||||
|
bool hdr_prefer_high_precision = false;
|
||||||
|
float hdr_reference_luminance = 0.0f;
|
||||||
|
float hdr_min_luminance = 0.0f;
|
||||||
|
float hdr_max_luminance = 0.0f;
|
||||||
|
|
||||||
ComPtr<IDCompositionDevice> composition_device;
|
ComPtr<IDCompositionDevice> composition_device;
|
||||||
ComPtr<IDCompositionTarget> composition_target;
|
ComPtr<IDCompositionTarget> composition_target;
|
||||||
ComPtr<IDCompositionVisual> composition_visual;
|
ComPtr<IDCompositionVisual> composition_visual;
|
||||||
|
|
|
||||||
|
|
@ -334,6 +334,12 @@ const RenderingDeviceDriverD3D12::D3D12Format RenderingDeviceDriverD3D12::RD_TO_
|
||||||
/* DATA_FORMAT_G16_B16_R16_3PLANE_444_UNORM */ {},
|
/* DATA_FORMAT_G16_B16_R16_3PLANE_444_UNORM */ {},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const DXGI_COLOR_SPACE_TYPE RenderingDeviceDriverD3D12::RD_TO_DXGI_COLOR_SPACE_TYPE[RDD::COLOR_SPACE_MAX]{
|
||||||
|
/* COLOR_SPACE_SRGB_LINEAR */ DXGI_COLOR_SPACE_RGB_FULL_G10_NONE_P709,
|
||||||
|
/* COLOR_SPACE_SRGB_NONLINEAR */ DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709,
|
||||||
|
/* COLOR_SPACE_HDR10_ST2084 */ DXGI_COLOR_SPACE_RGB_FULL_G2084_NONE_P2020,
|
||||||
|
};
|
||||||
|
|
||||||
Error RenderingDeviceDriverD3D12::DescriptorsHeap::allocate(ID3D12Device *p_device, D3D12_DESCRIPTOR_HEAP_TYPE p_type, uint32_t p_descriptor_count, bool p_for_gpu) {
|
Error RenderingDeviceDriverD3D12::DescriptorsHeap::allocate(ID3D12Device *p_device, D3D12_DESCRIPTOR_HEAP_TYPE p_type, uint32_t p_descriptor_count, bool p_for_gpu) {
|
||||||
ERR_FAIL_COND_V(heap, ERR_ALREADY_EXISTS);
|
ERR_FAIL_COND_V(heap, ERR_ALREADY_EXISTS);
|
||||||
ERR_FAIL_COND_V(p_descriptor_count == 0, ERR_INVALID_PARAMETER);
|
ERR_FAIL_COND_V(p_descriptor_count == 0, ERR_INVALID_PARAMETER);
|
||||||
|
|
@ -2405,6 +2411,11 @@ void RenderingDeviceDriverD3D12::command_buffer_execute_secondary(CommandBufferI
|
||||||
void RenderingDeviceDriverD3D12::_swap_chain_release(SwapChain *p_swap_chain) {
|
void RenderingDeviceDriverD3D12::_swap_chain_release(SwapChain *p_swap_chain) {
|
||||||
_swap_chain_release_buffers(p_swap_chain);
|
_swap_chain_release_buffers(p_swap_chain);
|
||||||
|
|
||||||
|
if (p_swap_chain->render_pass.id != 0) {
|
||||||
|
render_pass_free(p_swap_chain->render_pass);
|
||||||
|
p_swap_chain->render_pass = RenderPassID();
|
||||||
|
}
|
||||||
|
|
||||||
p_swap_chain->d3d_swap_chain.Reset();
|
p_swap_chain->d3d_swap_chain.Reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2423,10 +2434,10 @@ void RenderingDeviceDriverD3D12::_swap_chain_release_buffers(SwapChain *p_swap_c
|
||||||
p_swap_chain->framebuffers.clear();
|
p_swap_chain->framebuffers.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
RDD::SwapChainID RenderingDeviceDriverD3D12::swap_chain_create(RenderingContextDriver::SurfaceID p_surface) {
|
RDD::RenderPassID RenderingDeviceDriverD3D12::_swap_chain_create_render_pass(RDD::DataFormat p_format) {
|
||||||
// Create the render pass that will be used to draw to the swap chain's framebuffers.
|
// Create the render pass that will be used to draw to the swap chain's framebuffers.
|
||||||
RDD::Attachment attachment;
|
RDD::Attachment attachment;
|
||||||
attachment.format = DATA_FORMAT_R8G8B8A8_UNORM;
|
attachment.format = p_format;
|
||||||
attachment.samples = RDD::TEXTURE_SAMPLES_1;
|
attachment.samples = RDD::TEXTURE_SAMPLES_1;
|
||||||
attachment.load_op = RDD::ATTACHMENT_LOAD_OP_CLEAR;
|
attachment.load_op = RDD::ATTACHMENT_LOAD_OP_CLEAR;
|
||||||
attachment.store_op = RDD::ATTACHMENT_STORE_OP_STORE;
|
attachment.store_op = RDD::ATTACHMENT_STORE_OP_STORE;
|
||||||
|
|
@ -2437,14 +2448,35 @@ RDD::SwapChainID RenderingDeviceDriverD3D12::swap_chain_create(RenderingContextD
|
||||||
color_ref.aspect.set_flag(RDD::TEXTURE_ASPECT_COLOR_BIT);
|
color_ref.aspect.set_flag(RDD::TEXTURE_ASPECT_COLOR_BIT);
|
||||||
subpass.color_references.push_back(color_ref);
|
subpass.color_references.push_back(color_ref);
|
||||||
|
|
||||||
RenderPassID render_pass = render_pass_create(attachment, subpass, {}, 1);
|
return render_pass_create(attachment, subpass, {}, 1);
|
||||||
ERR_FAIL_COND_V(!render_pass, SwapChainID());
|
}
|
||||||
|
|
||||||
// Create the empty swap chain until it is resized.
|
void RenderingDeviceDriverD3D12::_determine_swap_chain_format(SwapChain *p_swap_chain, DataFormat &r_format, ColorSpace &r_color_space) {
|
||||||
|
DEV_ASSERT(p_swap_chain);
|
||||||
|
DEV_ASSERT(p_swap_chain->surface != 0);
|
||||||
|
|
||||||
|
// Direct3D Hardware level 10 mandates support for all these formats.
|
||||||
|
// Godot requires at least Hardware level 11, so these formats are guaranteed to be supported.
|
||||||
|
if (context_driver->surface_get_hdr_output_enabled(p_swap_chain->surface)) {
|
||||||
|
if (context_driver->surface_get_hdr_output_prefer_high_precision(p_swap_chain->surface)) {
|
||||||
|
r_format = DATA_FORMAT_R16G16B16A16_SFLOAT;
|
||||||
|
r_color_space = COLOR_SPACE_SRGB_LINEAR;
|
||||||
|
} else {
|
||||||
|
r_format = DATA_FORMAT_A2R10G10B10_UNORM_PACK32;
|
||||||
|
r_color_space = COLOR_SPACE_HDR10_ST2084;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
r_format = DATA_FORMAT_R8G8B8A8_UNORM;
|
||||||
|
r_color_space = COLOR_SPACE_SRGB_NONLINEAR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RDD::SwapChainID RenderingDeviceDriverD3D12::swap_chain_create(RenderingContextDriver::SurfaceID p_surface) {
|
||||||
|
DEV_ASSERT(p_surface != 0);
|
||||||
|
|
||||||
|
// Create an empty swap chain until it is resized.
|
||||||
SwapChain *swap_chain = memnew(SwapChain);
|
SwapChain *swap_chain = memnew(SwapChain);
|
||||||
swap_chain->surface = p_surface;
|
swap_chain->surface = p_surface;
|
||||||
swap_chain->data_format = attachment.format;
|
|
||||||
swap_chain->render_pass = render_pass;
|
|
||||||
return SwapChainID(swap_chain);
|
return SwapChainID(swap_chain);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2486,17 +2518,27 @@ Error RenderingDeviceDriverD3D12::swap_chain_resize(CommandQueueID p_cmd_queue,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (swap_chain->d3d_swap_chain != nullptr && creation_flags != swap_chain->creation_flags) {
|
RDD::DataFormat new_data_format;
|
||||||
// The swap chain must be recreated if the creation flags are different.
|
RDD::ColorSpace new_color_space;
|
||||||
|
_determine_swap_chain_format(swap_chain, new_data_format, new_color_space);
|
||||||
|
|
||||||
|
if (swap_chain->d3d_swap_chain != nullptr && (creation_flags != swap_chain->creation_flags || new_data_format != swap_chain->data_format)) {
|
||||||
|
// The swap chain must be recreated if the creation flags or data format are different.
|
||||||
_swap_chain_release(swap_chain);
|
_swap_chain_release(swap_chain);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
swap_chain->data_format = new_data_format;
|
||||||
|
|
||||||
DXGI_SWAP_CHAIN_DESC1 swap_chain_desc = {};
|
DXGI_SWAP_CHAIN_DESC1 swap_chain_desc = {};
|
||||||
if (swap_chain->d3d_swap_chain != nullptr) {
|
if (swap_chain->d3d_swap_chain != nullptr) {
|
||||||
_swap_chain_release_buffers(swap_chain);
|
_swap_chain_release_buffers(swap_chain);
|
||||||
res = swap_chain->d3d_swap_chain->ResizeBuffers(p_desired_framebuffer_count, surface->width, surface->height, DXGI_FORMAT_UNKNOWN, creation_flags);
|
res = swap_chain->d3d_swap_chain->ResizeBuffers(p_desired_framebuffer_count, surface->width, surface->height, DXGI_FORMAT_UNKNOWN, creation_flags);
|
||||||
ERR_FAIL_COND_V(!SUCCEEDED(res), ERR_UNAVAILABLE);
|
ERR_FAIL_COND_V(!SUCCEEDED(res), ERR_UNAVAILABLE);
|
||||||
} else {
|
} else {
|
||||||
|
DEV_ASSERT(swap_chain->render_pass.id == 0);
|
||||||
|
swap_chain->render_pass = _swap_chain_create_render_pass(new_data_format);
|
||||||
|
ERR_FAIL_COND_V(!swap_chain->render_pass, ERR_CANT_CREATE);
|
||||||
|
|
||||||
swap_chain_desc.BufferCount = p_desired_framebuffer_count;
|
swap_chain_desc.BufferCount = p_desired_framebuffer_count;
|
||||||
swap_chain_desc.Format = RD_TO_D3D12_FORMAT[swap_chain->data_format].general_format;
|
swap_chain_desc.Format = RD_TO_D3D12_FORMAT[swap_chain->data_format].general_format;
|
||||||
swap_chain_desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
|
swap_chain_desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
|
||||||
|
|
@ -2525,6 +2567,13 @@ Error RenderingDeviceDriverD3D12::swap_chain_resize(CommandQueueID p_cmd_queue,
|
||||||
ERR_FAIL_COND_V(!SUCCEEDED(res), ERR_CANT_CREATE);
|
ERR_FAIL_COND_V(!SUCCEEDED(res), ERR_CANT_CREATE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (swap_chain->color_space != new_color_space) {
|
||||||
|
res = swap_chain->d3d_swap_chain->SetColorSpace1(RD_TO_DXGI_COLOR_SPACE_TYPE[new_color_space]);
|
||||||
|
ERR_FAIL_COND_V(!SUCCEEDED(res), ERR_CANT_CREATE);
|
||||||
|
|
||||||
|
swap_chain->color_space = new_color_space;
|
||||||
|
}
|
||||||
|
|
||||||
if (surface->composition_device.Get() == nullptr) {
|
if (surface->composition_device.Get() == nullptr) {
|
||||||
using PFN_DCompositionCreateDevice = HRESULT(WINAPI *)(IDXGIDevice *, REFIID, void **);
|
using PFN_DCompositionCreateDevice = HRESULT(WINAPI *)(IDXGIDevice *, REFIID, void **);
|
||||||
PFN_DCompositionCreateDevice pfn_DCompositionCreateDevice = (PFN_DCompositionCreateDevice)(void *)GetProcAddress(context_driver->lib_dcomp, "DCompositionCreateDevice");
|
PFN_DCompositionCreateDevice pfn_DCompositionCreateDevice = (PFN_DCompositionCreateDevice)(void *)GetProcAddress(context_driver->lib_dcomp, "DCompositionCreateDevice");
|
||||||
|
|
@ -2634,10 +2683,14 @@ RDD::DataFormat RenderingDeviceDriverD3D12::swap_chain_get_format(SwapChainID p_
|
||||||
return swap_chain->data_format;
|
return swap_chain->data_format;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RDD::ColorSpace RenderingDeviceDriverD3D12::swap_chain_get_color_space(SwapChainID p_swap_chain) {
|
||||||
|
const SwapChain *swap_chain = (const SwapChain *)(p_swap_chain.id);
|
||||||
|
return swap_chain->color_space;
|
||||||
|
}
|
||||||
|
|
||||||
void RenderingDeviceDriverD3D12::swap_chain_free(SwapChainID p_swap_chain) {
|
void RenderingDeviceDriverD3D12::swap_chain_free(SwapChainID p_swap_chain) {
|
||||||
SwapChain *swap_chain = (SwapChain *)(p_swap_chain.id);
|
SwapChain *swap_chain = (SwapChain *)(p_swap_chain.id);
|
||||||
_swap_chain_release(swap_chain);
|
_swap_chain_release(swap_chain);
|
||||||
render_pass_free(swap_chain->render_pass);
|
|
||||||
memdelete(swap_chain);
|
memdelete(swap_chain);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -6280,6 +6333,8 @@ bool RenderingDeviceDriverD3D12::has_feature(Features p_feature) {
|
||||||
return true;
|
return true;
|
||||||
case SUPPORTS_BUFFER_DEVICE_ADDRESS:
|
case SUPPORTS_BUFFER_DEVICE_ADDRESS:
|
||||||
return true;
|
return true;
|
||||||
|
case SUPPORTS_HDR_OUTPUT:
|
||||||
|
return true;
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -100,6 +100,7 @@ class RenderingDeviceDriverD3D12 : public RenderingDeviceDriver {
|
||||||
};
|
};
|
||||||
|
|
||||||
static const D3D12Format RD_TO_D3D12_FORMAT[RDD::DATA_FORMAT_MAX];
|
static const D3D12Format RD_TO_D3D12_FORMAT[RDD::DATA_FORMAT_MAX];
|
||||||
|
static const DXGI_COLOR_SPACE_TYPE RD_TO_DXGI_COLOR_SPACE_TYPE[RDD::COLOR_SPACE_MAX];
|
||||||
|
|
||||||
struct DeviceLimits {
|
struct DeviceLimits {
|
||||||
uint64_t max_srvs_per_shader_stage = 0;
|
uint64_t max_srvs_per_shader_stage = 0;
|
||||||
|
|
@ -506,10 +507,13 @@ private:
|
||||||
TightLocalVector<TextureInfo> render_targets_info;
|
TightLocalVector<TextureInfo> render_targets_info;
|
||||||
TightLocalVector<FramebufferID> framebuffers;
|
TightLocalVector<FramebufferID> framebuffers;
|
||||||
RDD::DataFormat data_format = DATA_FORMAT_MAX;
|
RDD::DataFormat data_format = DATA_FORMAT_MAX;
|
||||||
|
RDD::ColorSpace color_space = COLOR_SPACE_MAX;
|
||||||
};
|
};
|
||||||
|
|
||||||
void _swap_chain_release(SwapChain *p_swap_chain);
|
void _swap_chain_release(SwapChain *p_swap_chain);
|
||||||
void _swap_chain_release_buffers(SwapChain *p_swap_chain);
|
void _swap_chain_release_buffers(SwapChain *p_swap_chain);
|
||||||
|
RenderPassID _swap_chain_create_render_pass(RDD::DataFormat p_format);
|
||||||
|
void _determine_swap_chain_format(SwapChain *p_swap_chain, DataFormat &r_format, ColorSpace &r_color_space);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual SwapChainID swap_chain_create(RenderingContextDriver::SurfaceID p_surface) override;
|
virtual SwapChainID swap_chain_create(RenderingContextDriver::SurfaceID p_surface) override;
|
||||||
|
|
@ -517,6 +521,7 @@ public:
|
||||||
virtual FramebufferID swap_chain_acquire_framebuffer(CommandQueueID p_cmd_queue, SwapChainID p_swap_chain, bool &r_resize_required) override;
|
virtual FramebufferID swap_chain_acquire_framebuffer(CommandQueueID p_cmd_queue, SwapChainID p_swap_chain, bool &r_resize_required) override;
|
||||||
virtual RenderPassID swap_chain_get_render_pass(SwapChainID p_swap_chain) override;
|
virtual RenderPassID swap_chain_get_render_pass(SwapChainID p_swap_chain) override;
|
||||||
virtual DataFormat swap_chain_get_format(SwapChainID p_swap_chain) override;
|
virtual DataFormat swap_chain_get_format(SwapChainID p_swap_chain) override;
|
||||||
|
virtual ColorSpace swap_chain_get_color_space(SwapChainID p_swap_chain) override;
|
||||||
virtual void swap_chain_free(SwapChainID p_swap_chain) override;
|
virtual void swap_chain_free(SwapChainID p_swap_chain) override;
|
||||||
|
|
||||||
/*********************/
|
/*********************/
|
||||||
|
|
|
||||||
|
|
@ -76,6 +76,16 @@ public:
|
||||||
void surface_set_size(SurfaceID p_surface, uint32_t p_width, uint32_t p_height) final override;
|
void surface_set_size(SurfaceID p_surface, uint32_t p_width, uint32_t p_height) final override;
|
||||||
void surface_set_vsync_mode(SurfaceID p_surface, DisplayServer::VSyncMode p_vsync_mode) final override;
|
void surface_set_vsync_mode(SurfaceID p_surface, DisplayServer::VSyncMode p_vsync_mode) final override;
|
||||||
DisplayServer::VSyncMode surface_get_vsync_mode(SurfaceID p_surface) const final override;
|
DisplayServer::VSyncMode surface_get_vsync_mode(SurfaceID p_surface) const final override;
|
||||||
|
virtual void surface_set_hdr_output_enabled(SurfaceID p_surface, bool p_enabled) final override;
|
||||||
|
virtual bool surface_get_hdr_output_enabled(SurfaceID p_surface) const final override;
|
||||||
|
virtual void surface_set_hdr_output_prefer_high_precision(SurfaceID p_surface, bool p_enabled) override;
|
||||||
|
virtual bool surface_get_hdr_output_prefer_high_precision(SurfaceID p_surface) const override;
|
||||||
|
virtual void surface_set_hdr_output_reference_luminance(SurfaceID p_surface, float p_reference_luminance) final override;
|
||||||
|
virtual float surface_get_hdr_output_reference_luminance(SurfaceID p_surface) const final override;
|
||||||
|
virtual void surface_set_hdr_output_min_luminance(SurfaceID p_surface, float p_min_luminance) final override;
|
||||||
|
virtual float surface_get_hdr_output_min_luminance(SurfaceID p_surface) const final override;
|
||||||
|
virtual void surface_set_hdr_output_max_luminance(SurfaceID p_surface, float p_max_luminance) final override;
|
||||||
|
virtual float surface_get_hdr_output_max_luminance(SurfaceID p_surface) const final override;
|
||||||
uint32_t surface_get_width(SurfaceID p_surface) const final override;
|
uint32_t surface_get_width(SurfaceID p_surface) const final override;
|
||||||
uint32_t surface_get_height(SurfaceID p_surface) const final override;
|
uint32_t surface_get_height(SurfaceID p_surface) const final override;
|
||||||
void surface_set_needs_resize(SurfaceID p_surface, bool p_needs_resize) final override;
|
void surface_set_needs_resize(SurfaceID p_surface, bool p_needs_resize) final override;
|
||||||
|
|
@ -109,6 +119,12 @@ public:
|
||||||
bool needs_resize = false;
|
bool needs_resize = false;
|
||||||
double present_minimum_duration = 0.0;
|
double present_minimum_duration = 0.0;
|
||||||
|
|
||||||
|
bool hdr_output = false;
|
||||||
|
bool hdr_prefer_high_precision = false;
|
||||||
|
float hdr_reference_luminance = 0.0f;
|
||||||
|
float hdr_min_luminance = 0.0f;
|
||||||
|
float hdr_max_luminance = 0.0f;
|
||||||
|
|
||||||
Surface(
|
Surface(
|
||||||
#ifdef __OBJC__
|
#ifdef __OBJC__
|
||||||
id<MTLDevice> p_device
|
id<MTLDevice> p_device
|
||||||
|
|
|
||||||
|
|
@ -211,6 +211,58 @@ DisplayServer::VSyncMode RenderingContextDriverMetal::surface_get_vsync_mode(Sur
|
||||||
return surface->vsync_mode;
|
return surface->vsync_mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RenderingContextDriverMetal::surface_set_hdr_output_enabled(SurfaceID p_surface, bool p_enabled) {
|
||||||
|
Surface *surface = (Surface *)(p_surface);
|
||||||
|
surface->hdr_output = p_enabled;
|
||||||
|
surface->needs_resize = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RenderingContextDriverMetal::surface_get_hdr_output_enabled(SurfaceID p_surface) const {
|
||||||
|
Surface *surface = (Surface *)(p_surface);
|
||||||
|
return surface->hdr_output;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RenderingContextDriverMetal::surface_set_hdr_output_prefer_high_precision(SurfaceID p_surface, bool p_enabled) {
|
||||||
|
Surface *surface = (Surface *)(p_surface);
|
||||||
|
surface->hdr_prefer_high_precision = p_enabled;
|
||||||
|
surface->needs_resize = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RenderingContextDriverMetal::surface_get_hdr_output_prefer_high_precision(SurfaceID p_surface) const {
|
||||||
|
Surface *surface = (Surface *)(p_surface);
|
||||||
|
return surface->hdr_prefer_high_precision;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RenderingContextDriverMetal::surface_set_hdr_output_reference_luminance(SurfaceID p_surface, float p_reference_luminance) {
|
||||||
|
Surface *surface = (Surface *)(p_surface);
|
||||||
|
surface->hdr_reference_luminance = p_reference_luminance;
|
||||||
|
}
|
||||||
|
|
||||||
|
float RenderingContextDriverMetal::surface_get_hdr_output_reference_luminance(SurfaceID p_surface) const {
|
||||||
|
Surface *surface = (Surface *)(p_surface);
|
||||||
|
return surface->hdr_reference_luminance;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RenderingContextDriverMetal::surface_set_hdr_output_min_luminance(SurfaceID p_surface, float p_min_luminance) {
|
||||||
|
Surface *surface = (Surface *)(p_surface);
|
||||||
|
surface->hdr_min_luminance = p_min_luminance;
|
||||||
|
}
|
||||||
|
|
||||||
|
float RenderingContextDriverMetal::surface_get_hdr_output_min_luminance(SurfaceID p_surface) const {
|
||||||
|
Surface *surface = (Surface *)(p_surface);
|
||||||
|
return surface->hdr_min_luminance;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RenderingContextDriverMetal::surface_set_hdr_output_max_luminance(SurfaceID p_surface, float p_max_luminance) {
|
||||||
|
Surface *surface = (Surface *)(p_surface);
|
||||||
|
surface->hdr_max_luminance = p_max_luminance;
|
||||||
|
}
|
||||||
|
|
||||||
|
float RenderingContextDriverMetal::surface_get_hdr_output_max_luminance(SurfaceID p_surface) const {
|
||||||
|
Surface *surface = (Surface *)(p_surface);
|
||||||
|
return surface->hdr_max_luminance;
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t RenderingContextDriverMetal::surface_get_width(SurfaceID p_surface) const {
|
uint32_t RenderingContextDriverMetal::surface_get_width(SurfaceID p_surface) const {
|
||||||
Surface *surface = (Surface *)(p_surface);
|
Surface *surface = (Surface *)(p_surface);
|
||||||
return surface->width;
|
return surface->width;
|
||||||
|
|
|
||||||
|
|
@ -222,6 +222,7 @@ public:
|
||||||
virtual RenderPassID swap_chain_get_render_pass(SwapChainID p_swap_chain) override final;
|
virtual RenderPassID swap_chain_get_render_pass(SwapChainID p_swap_chain) override final;
|
||||||
virtual DataFormat swap_chain_get_format(SwapChainID p_swap_chain) override final;
|
virtual DataFormat swap_chain_get_format(SwapChainID p_swap_chain) override final;
|
||||||
virtual void swap_chain_set_max_fps(SwapChainID p_swap_chain, int p_max_fps) override final;
|
virtual void swap_chain_set_max_fps(SwapChainID p_swap_chain, int p_max_fps) override final;
|
||||||
|
virtual ColorSpace swap_chain_get_color_space(SwapChainID p_swap_chain) override final;
|
||||||
virtual void swap_chain_free(SwapChainID p_swap_chain) override final;
|
virtual void swap_chain_free(SwapChainID p_swap_chain) override final;
|
||||||
|
|
||||||
#pragma mark - Frame Buffer
|
#pragma mark - Frame Buffer
|
||||||
|
|
|
||||||
|
|
@ -1029,6 +1029,10 @@ void RenderingDeviceDriverMetal::swap_chain_set_max_fps(SwapChainID p_swap_chain
|
||||||
metal_surface->set_max_fps(p_max_fps);
|
metal_surface->set_max_fps(p_max_fps);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RDD::ColorSpace RenderingDeviceDriverMetal::swap_chain_get_color_space(SwapChainID p_swap_chain) {
|
||||||
|
return RDD::COLOR_SPACE_SRGB_NONLINEAR;
|
||||||
|
}
|
||||||
|
|
||||||
void RenderingDeviceDriverMetal::swap_chain_free(SwapChainID p_swap_chain) {
|
void RenderingDeviceDriverMetal::swap_chain_free(SwapChainID p_swap_chain) {
|
||||||
SwapChain *swap_chain = (SwapChain *)(p_swap_chain.id);
|
SwapChain *swap_chain = (SwapChain *)(p_swap_chain.id);
|
||||||
_swap_chain_release(swap_chain);
|
_swap_chain_release(swap_chain);
|
||||||
|
|
|
||||||
|
|
@ -436,6 +436,9 @@ Error RenderingContextDriverVulkan::_initialize_instance_extensions() {
|
||||||
// This extension allows us to use the properties2 features to query additional device capabilities.
|
// This extension allows us to use the properties2 features to query additional device capabilities.
|
||||||
_register_requested_instance_extension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, false);
|
_register_requested_instance_extension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, false);
|
||||||
|
|
||||||
|
// This extension allows us to use colorspaces other than SRGB.
|
||||||
|
_register_requested_instance_extension(VK_EXT_SWAPCHAIN_COLOR_SPACE_EXTENSION_NAME, false);
|
||||||
|
|
||||||
#if defined(USE_VOLK) && (defined(MACOS_ENABLED) || defined(IOS_ENABLED))
|
#if defined(USE_VOLK) && (defined(MACOS_ENABLED) || defined(IOS_ENABLED))
|
||||||
_register_requested_instance_extension(VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME, true);
|
_register_requested_instance_extension(VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME, true);
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -991,6 +994,58 @@ DisplayServer::VSyncMode RenderingContextDriverVulkan::surface_get_vsync_mode(Su
|
||||||
return surface->vsync_mode;
|
return surface->vsync_mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RenderingContextDriverVulkan::surface_set_hdr_output_enabled(SurfaceID p_surface, bool p_enabled) {
|
||||||
|
Surface *surface = (Surface *)(p_surface);
|
||||||
|
surface->hdr_output = p_enabled;
|
||||||
|
surface->needs_resize = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RenderingContextDriverVulkan::surface_get_hdr_output_enabled(SurfaceID p_surface) const {
|
||||||
|
Surface *surface = (Surface *)(p_surface);
|
||||||
|
return surface->hdr_output;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RenderingContextDriverVulkan::surface_set_hdr_output_prefer_high_precision(SurfaceID p_surface, bool p_enabled) {
|
||||||
|
Surface *surface = (Surface *)(p_surface);
|
||||||
|
surface->hdr_prefer_high_precision = p_enabled;
|
||||||
|
surface->needs_resize = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RenderingContextDriverVulkan::surface_get_hdr_output_prefer_high_precision(SurfaceID p_surface) const {
|
||||||
|
Surface *surface = (Surface *)(p_surface);
|
||||||
|
return surface->hdr_prefer_high_precision;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RenderingContextDriverVulkan::surface_set_hdr_output_reference_luminance(SurfaceID p_surface, float p_reference_luminance) {
|
||||||
|
Surface *surface = (Surface *)(p_surface);
|
||||||
|
surface->hdr_reference_luminance = p_reference_luminance;
|
||||||
|
}
|
||||||
|
|
||||||
|
float RenderingContextDriverVulkan::surface_get_hdr_output_reference_luminance(SurfaceID p_surface) const {
|
||||||
|
Surface *surface = (Surface *)(p_surface);
|
||||||
|
return surface->hdr_reference_luminance;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RenderingContextDriverVulkan::surface_set_hdr_output_min_luminance(SurfaceID p_surface, float p_min_luminance) {
|
||||||
|
Surface *surface = (Surface *)(p_surface);
|
||||||
|
surface->hdr_min_luminance = p_min_luminance;
|
||||||
|
}
|
||||||
|
|
||||||
|
float RenderingContextDriverVulkan::surface_get_hdr_output_min_luminance(SurfaceID p_surface) const {
|
||||||
|
Surface *surface = (Surface *)(p_surface);
|
||||||
|
return surface->hdr_min_luminance;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RenderingContextDriverVulkan::surface_set_hdr_output_max_luminance(SurfaceID p_surface, float p_max_luminance) {
|
||||||
|
Surface *surface = (Surface *)(p_surface);
|
||||||
|
surface->hdr_max_luminance = p_max_luminance;
|
||||||
|
}
|
||||||
|
|
||||||
|
float RenderingContextDriverVulkan::surface_get_hdr_output_max_luminance(SurfaceID p_surface) const {
|
||||||
|
Surface *surface = (Surface *)(p_surface);
|
||||||
|
return surface->hdr_max_luminance;
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t RenderingContextDriverVulkan::surface_get_width(SurfaceID p_surface) const {
|
uint32_t RenderingContextDriverVulkan::surface_get_width(SurfaceID p_surface) const {
|
||||||
Surface *surface = (Surface *)(p_surface);
|
Surface *surface = (Surface *)(p_surface);
|
||||||
return surface->width;
|
return surface->width;
|
||||||
|
|
@ -1021,6 +1076,10 @@ bool RenderingContextDriverVulkan::is_debug_utils_enabled() const {
|
||||||
return enabled_instance_extension_names.has(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
|
return enabled_instance_extension_names.has(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool RenderingContextDriverVulkan::is_colorspace_supported() const {
|
||||||
|
return enabled_instance_extension_names.has(VK_EXT_SWAPCHAIN_COLOR_SPACE_EXTENSION_NAME);
|
||||||
|
}
|
||||||
|
|
||||||
VkInstance RenderingContextDriverVulkan::instance_get() const {
|
VkInstance RenderingContextDriverVulkan::instance_get() const {
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -139,12 +139,23 @@ public:
|
||||||
virtual void surface_set_size(SurfaceID p_surface, uint32_t p_width, uint32_t p_height) override;
|
virtual void surface_set_size(SurfaceID p_surface, uint32_t p_width, uint32_t p_height) override;
|
||||||
virtual void surface_set_vsync_mode(SurfaceID p_surface, DisplayServer::VSyncMode p_vsync_mode) override;
|
virtual void surface_set_vsync_mode(SurfaceID p_surface, DisplayServer::VSyncMode p_vsync_mode) override;
|
||||||
virtual DisplayServer::VSyncMode surface_get_vsync_mode(SurfaceID p_surface) const override;
|
virtual DisplayServer::VSyncMode surface_get_vsync_mode(SurfaceID p_surface) const override;
|
||||||
|
virtual void surface_set_hdr_output_enabled(SurfaceID p_surface, bool p_enabled) override;
|
||||||
|
virtual bool surface_get_hdr_output_enabled(SurfaceID p_surface) const override;
|
||||||
|
virtual void surface_set_hdr_output_prefer_high_precision(SurfaceID p_surface, bool p_enabled) override;
|
||||||
|
virtual bool surface_get_hdr_output_prefer_high_precision(SurfaceID p_surface) const override;
|
||||||
|
virtual void surface_set_hdr_output_reference_luminance(SurfaceID p_surface, float p_reference_luminance) override;
|
||||||
|
virtual float surface_get_hdr_output_reference_luminance(SurfaceID p_surface) const override;
|
||||||
|
virtual void surface_set_hdr_output_min_luminance(SurfaceID p_surface, float p_min_luminance) override;
|
||||||
|
virtual float surface_get_hdr_output_min_luminance(SurfaceID p_surface) const override;
|
||||||
|
virtual void surface_set_hdr_output_max_luminance(SurfaceID p_surface, float p_max_luminance) override;
|
||||||
|
virtual float surface_get_hdr_output_max_luminance(SurfaceID p_surface) const override;
|
||||||
virtual uint32_t surface_get_width(SurfaceID p_surface) const override;
|
virtual uint32_t surface_get_width(SurfaceID p_surface) const override;
|
||||||
virtual uint32_t surface_get_height(SurfaceID p_surface) const override;
|
virtual uint32_t surface_get_height(SurfaceID p_surface) const override;
|
||||||
virtual void surface_set_needs_resize(SurfaceID p_surface, bool p_needs_resize) override;
|
virtual void surface_set_needs_resize(SurfaceID p_surface, bool p_needs_resize) override;
|
||||||
virtual bool surface_get_needs_resize(SurfaceID p_surface) const override;
|
virtual bool surface_get_needs_resize(SurfaceID p_surface) const override;
|
||||||
virtual void surface_destroy(SurfaceID p_surface) override;
|
virtual void surface_destroy(SurfaceID p_surface) override;
|
||||||
virtual bool is_debug_utils_enabled() const override;
|
virtual bool is_debug_utils_enabled() const override;
|
||||||
|
bool is_colorspace_supported() const;
|
||||||
|
|
||||||
// Vulkan-only methods.
|
// Vulkan-only methods.
|
||||||
struct Surface {
|
struct Surface {
|
||||||
|
|
@ -153,6 +164,12 @@ public:
|
||||||
uint32_t height = 0;
|
uint32_t height = 0;
|
||||||
DisplayServer::VSyncMode vsync_mode = DisplayServer::VSYNC_ENABLED;
|
DisplayServer::VSyncMode vsync_mode = DisplayServer::VSYNC_ENABLED;
|
||||||
bool needs_resize = false;
|
bool needs_resize = false;
|
||||||
|
|
||||||
|
bool hdr_output = false;
|
||||||
|
bool hdr_prefer_high_precision = false;
|
||||||
|
float hdr_reference_luminance = 0.0f;
|
||||||
|
float hdr_min_luminance = 0.0f;
|
||||||
|
float hdr_max_luminance = 0.0f;
|
||||||
};
|
};
|
||||||
|
|
||||||
VkInstance instance_get() const;
|
VkInstance instance_get() const;
|
||||||
|
|
|
||||||
|
|
@ -2862,6 +2862,99 @@ void RenderingDeviceDriverVulkan::command_buffer_execute_secondary(CommandBuffer
|
||||||
/**** SWAP CHAIN ****/
|
/**** SWAP CHAIN ****/
|
||||||
/********************/
|
/********************/
|
||||||
|
|
||||||
|
struct FormatCandidate {
|
||||||
|
VkFormat format;
|
||||||
|
VkColorSpaceKHR colorspace;
|
||||||
|
};
|
||||||
|
|
||||||
|
bool RenderingDeviceDriverVulkan::_determine_swap_chain_format(RenderingContextDriver::SurfaceID p_surface, VkFormat &r_format, VkColorSpaceKHR &r_color_space) {
|
||||||
|
DEV_ASSERT(p_surface != 0);
|
||||||
|
|
||||||
|
RenderingContextDriverVulkan::Surface *surface = (RenderingContextDriverVulkan::Surface *)(p_surface);
|
||||||
|
const RenderingContextDriverVulkan::Functions &functions = context_driver->functions_get();
|
||||||
|
|
||||||
|
// Retrieve the formats supported by the surface.
|
||||||
|
uint32_t format_count = 0;
|
||||||
|
VkResult err = functions.GetPhysicalDeviceSurfaceFormatsKHR(physical_device, surface->vk_surface, &format_count, nullptr);
|
||||||
|
ERR_FAIL_COND_V(err != VK_SUCCESS, false);
|
||||||
|
|
||||||
|
TightLocalVector<VkSurfaceFormatKHR> formats;
|
||||||
|
formats.resize(format_count);
|
||||||
|
err = functions.GetPhysicalDeviceSurfaceFormatsKHR(physical_device, surface->vk_surface, &format_count, formats.ptr());
|
||||||
|
ERR_FAIL_COND_V(err != VK_SUCCESS, false);
|
||||||
|
|
||||||
|
// If the format list includes just one entry of VK_FORMAT_UNDEFINED, the surface has no preferred format.
|
||||||
|
if (format_count == 1 && formats[0].format == VK_FORMAT_UNDEFINED) {
|
||||||
|
r_format = VK_FORMAT_B8G8R8A8_UNORM;
|
||||||
|
r_color_space = formats[0].colorSpace;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool colorspace_supported = context_driver->is_colorspace_supported();
|
||||||
|
bool hdr_output_requested = context_driver->surface_get_hdr_output_enabled(p_surface);
|
||||||
|
bool high_precision_requested = context_driver->surface_get_hdr_output_prefer_high_precision(p_surface);
|
||||||
|
|
||||||
|
// Determine which formats to prefer based on the requested capabilities.
|
||||||
|
LocalVector<FormatCandidate> preferred_formats = LocalVector<FormatCandidate>();
|
||||||
|
preferred_formats.reserve(5);
|
||||||
|
|
||||||
|
// If the surface requests HDR output, try to get an HDR format.
|
||||||
|
if (hdr_output_requested && colorspace_supported) {
|
||||||
|
if (high_precision_requested) {
|
||||||
|
// If high precision is requested, add the high precision format to the top.
|
||||||
|
preferred_formats.push_back({ VK_FORMAT_R16G16B16A16_SFLOAT, VK_COLOR_SPACE_EXTENDED_SRGB_LINEAR_EXT });
|
||||||
|
|
||||||
|
// Followed by the HDR10 formats
|
||||||
|
preferred_formats.push_back({ VK_FORMAT_A2B10G10R10_UNORM_PACK32, VK_COLOR_SPACE_HDR10_ST2084_EXT });
|
||||||
|
preferred_formats.push_back({ VK_FORMAT_A2R10G10B10_UNORM_PACK32, VK_COLOR_SPACE_HDR10_ST2084_EXT });
|
||||||
|
} else {
|
||||||
|
// Otherwise add the HDR10 formats to the top.
|
||||||
|
preferred_formats.push_back({ VK_FORMAT_A2B10G10R10_UNORM_PACK32, VK_COLOR_SPACE_HDR10_ST2084_EXT });
|
||||||
|
preferred_formats.push_back({ VK_FORMAT_A2R10G10B10_UNORM_PACK32, VK_COLOR_SPACE_HDR10_ST2084_EXT });
|
||||||
|
|
||||||
|
// Followed by the high precision format for devices that don't support HDR 10.
|
||||||
|
preferred_formats.push_back({ VK_FORMAT_R16G16B16A16_SFLOAT, VK_COLOR_SPACE_EXTENDED_SRGB_LINEAR_EXT });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// These formats are always considered for SDR.
|
||||||
|
preferred_formats.push_back({ VK_FORMAT_B8G8R8A8_UNORM, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR });
|
||||||
|
preferred_formats.push_back({ VK_FORMAT_R8G8B8A8_UNORM, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR });
|
||||||
|
|
||||||
|
bool found = false;
|
||||||
|
for (const FormatCandidate &candidate : preferred_formats) {
|
||||||
|
for (uint32_t i = 0; i < format_count; i++) {
|
||||||
|
if (formats[i].format == candidate.format && formats[i].colorSpace == candidate.colorspace) {
|
||||||
|
r_format = formats[i].format;
|
||||||
|
r_color_space = formats[i].colorSpace;
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (found) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Warnings for when HDR capabilities are requested but not found.
|
||||||
|
if (hdr_output_requested) {
|
||||||
|
if (!colorspace_supported) {
|
||||||
|
WARN_PRINT("HDR output requested but the vulkan driver does not support VK_EXT_swapchain_colorspace, falling back to SDR.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (high_precision_requested && r_format != VK_FORMAT_R16G16B16A16_SFLOAT) {
|
||||||
|
WARN_PRINT("HDR output requested with high precision but no high precision format was found.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (r_color_space == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR) {
|
||||||
|
WARN_PRINT("HDR output requested but no HDR compatible format was found, falling back to SDR.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
|
||||||
void RenderingDeviceDriverVulkan::_swap_chain_release(SwapChain *swap_chain) {
|
void RenderingDeviceDriverVulkan::_swap_chain_release(SwapChain *swap_chain) {
|
||||||
// Destroy views and framebuffers associated to the swapchain's images.
|
// Destroy views and framebuffers associated to the swapchain's images.
|
||||||
for (FramebufferID framebuffer : swap_chain->framebuffers) {
|
for (FramebufferID framebuffer : swap_chain->framebuffers) {
|
||||||
|
|
@ -2890,6 +2983,11 @@ void RenderingDeviceDriverVulkan::_swap_chain_release(SwapChain *swap_chain) {
|
||||||
swap_chain->vk_swapchain = VK_NULL_HANDLE;
|
swap_chain->vk_swapchain = VK_NULL_HANDLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (swap_chain->render_pass.id != 0) {
|
||||||
|
vkDestroyRenderPass(vk_device, VkRenderPass(swap_chain->render_pass.id), VKC::get_allocation_callbacks(VK_OBJECT_TYPE_RENDER_PASS));
|
||||||
|
swap_chain->render_pass = RenderPassID();
|
||||||
|
}
|
||||||
|
|
||||||
for (uint32_t i = 0; i < swap_chain->command_queues_acquired.size(); i++) {
|
for (uint32_t i = 0; i < swap_chain->command_queues_acquired.size(); i++) {
|
||||||
_recreate_image_semaphore(swap_chain->command_queues_acquired[i], swap_chain->command_queues_acquired_semaphores[i], false);
|
_recreate_image_semaphore(swap_chain->command_queues_acquired[i], swap_chain->command_queues_acquired_semaphores[i], false);
|
||||||
}
|
}
|
||||||
|
|
@ -2901,81 +2999,9 @@ void RenderingDeviceDriverVulkan::_swap_chain_release(SwapChain *swap_chain) {
|
||||||
RenderingDeviceDriver::SwapChainID RenderingDeviceDriverVulkan::swap_chain_create(RenderingContextDriver::SurfaceID p_surface) {
|
RenderingDeviceDriver::SwapChainID RenderingDeviceDriverVulkan::swap_chain_create(RenderingContextDriver::SurfaceID p_surface) {
|
||||||
DEV_ASSERT(p_surface != 0);
|
DEV_ASSERT(p_surface != 0);
|
||||||
|
|
||||||
RenderingContextDriverVulkan::Surface *surface = (RenderingContextDriverVulkan::Surface *)(p_surface);
|
// Create an empty swap chain until it is resized.
|
||||||
const RenderingContextDriverVulkan::Functions &functions = context_driver->functions_get();
|
|
||||||
|
|
||||||
// Retrieve the formats supported by the surface.
|
|
||||||
uint32_t format_count = 0;
|
|
||||||
VkResult err = functions.GetPhysicalDeviceSurfaceFormatsKHR(physical_device, surface->vk_surface, &format_count, nullptr);
|
|
||||||
ERR_FAIL_COND_V(err != VK_SUCCESS, SwapChainID());
|
|
||||||
|
|
||||||
TightLocalVector<VkSurfaceFormatKHR> formats;
|
|
||||||
formats.resize(format_count);
|
|
||||||
err = functions.GetPhysicalDeviceSurfaceFormatsKHR(physical_device, surface->vk_surface, &format_count, formats.ptr());
|
|
||||||
ERR_FAIL_COND_V(err != VK_SUCCESS, SwapChainID());
|
|
||||||
|
|
||||||
VkFormat format = VK_FORMAT_UNDEFINED;
|
|
||||||
VkColorSpaceKHR color_space = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR;
|
|
||||||
if (format_count == 1 && formats[0].format == VK_FORMAT_UNDEFINED) {
|
|
||||||
// If the format list includes just one entry of VK_FORMAT_UNDEFINED, the surface has no preferred format.
|
|
||||||
format = VK_FORMAT_B8G8R8A8_UNORM;
|
|
||||||
color_space = formats[0].colorSpace;
|
|
||||||
} else if (format_count > 0) {
|
|
||||||
// Use one of the supported formats, prefer B8G8R8A8_UNORM.
|
|
||||||
const VkFormat preferred_format = VK_FORMAT_B8G8R8A8_UNORM;
|
|
||||||
const VkFormat second_format = VK_FORMAT_R8G8B8A8_UNORM;
|
|
||||||
for (uint32_t i = 0; i < format_count; i++) {
|
|
||||||
if (formats[i].format == preferred_format || formats[i].format == second_format) {
|
|
||||||
format = formats[i].format;
|
|
||||||
if (formats[i].format == preferred_format) {
|
|
||||||
// This is the preferred format, stop searching.
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// No formats are supported.
|
|
||||||
ERR_FAIL_COND_V_MSG(format == VK_FORMAT_UNDEFINED, SwapChainID(), "Surface did not return any valid formats.");
|
|
||||||
|
|
||||||
// Create the render pass for the chosen format.
|
|
||||||
VkAttachmentDescription2KHR attachment = {};
|
|
||||||
attachment.sType = VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2_KHR;
|
|
||||||
attachment.format = format;
|
|
||||||
attachment.samples = VK_SAMPLE_COUNT_1_BIT;
|
|
||||||
attachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
|
|
||||||
attachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
|
||||||
attachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
|
||||||
attachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
|
|
||||||
attachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
|
||||||
attachment.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
|
|
||||||
|
|
||||||
VkAttachmentReference2KHR color_reference = {};
|
|
||||||
color_reference.sType = VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2_KHR;
|
|
||||||
color_reference.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
|
||||||
|
|
||||||
VkSubpassDescription2KHR subpass = {};
|
|
||||||
subpass.sType = VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2_KHR;
|
|
||||||
subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
|
|
||||||
subpass.colorAttachmentCount = 1;
|
|
||||||
subpass.pColorAttachments = &color_reference;
|
|
||||||
|
|
||||||
VkRenderPassCreateInfo2KHR pass_info = {};
|
|
||||||
pass_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2_KHR;
|
|
||||||
pass_info.attachmentCount = 1;
|
|
||||||
pass_info.pAttachments = &attachment;
|
|
||||||
pass_info.subpassCount = 1;
|
|
||||||
pass_info.pSubpasses = &subpass;
|
|
||||||
|
|
||||||
VkRenderPass render_pass = VK_NULL_HANDLE;
|
|
||||||
err = _create_render_pass(vk_device, &pass_info, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_RENDER_PASS), &render_pass);
|
|
||||||
ERR_FAIL_COND_V(err != VK_SUCCESS, SwapChainID());
|
|
||||||
|
|
||||||
SwapChain *swap_chain = memnew(SwapChain);
|
SwapChain *swap_chain = memnew(SwapChain);
|
||||||
swap_chain->surface = p_surface;
|
swap_chain->surface = p_surface;
|
||||||
swap_chain->format = format;
|
|
||||||
swap_chain->color_space = color_space;
|
|
||||||
swap_chain->render_pass = RenderPassID(render_pass);
|
|
||||||
return SwapChainID(swap_chain);
|
return SwapChainID(swap_chain);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3109,6 +3135,16 @@ Error RenderingDeviceDriverVulkan::swap_chain_resize(CommandQueueID p_cmd_queue,
|
||||||
has_comp_alpha[(uint64_t)p_cmd_queue.id] = (composite_alpha != VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR);
|
has_comp_alpha[(uint64_t)p_cmd_queue.id] = (composite_alpha != VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Determine the format and color space for the swap chain.
|
||||||
|
VkFormat format = VK_FORMAT_UNDEFINED;
|
||||||
|
VkColorSpaceKHR color_space = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR;
|
||||||
|
if (!_determine_swap_chain_format(swap_chain->surface, format, color_space)) {
|
||||||
|
ERR_FAIL_V_MSG(ERR_CANT_CREATE, "Surface did not return any valid formats.");
|
||||||
|
} else {
|
||||||
|
swap_chain->format = format;
|
||||||
|
swap_chain->color_space = color_space;
|
||||||
|
}
|
||||||
|
|
||||||
VkSwapchainCreateInfoKHR swap_create_info = {};
|
VkSwapchainCreateInfoKHR swap_create_info = {};
|
||||||
swap_create_info.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
|
swap_create_info.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
|
||||||
swap_create_info.surface = surface->vk_surface;
|
swap_create_info.surface = surface->vk_surface;
|
||||||
|
|
@ -3207,9 +3243,45 @@ Error RenderingDeviceDriverVulkan::swap_chain_resize(CommandQueueID p_cmd_queue,
|
||||||
|
|
||||||
swap_chain->framebuffers.reserve(image_count);
|
swap_chain->framebuffers.reserve(image_count);
|
||||||
|
|
||||||
|
// Create the render pass for the chosen format.
|
||||||
|
VkAttachmentDescription2KHR attachment = {};
|
||||||
|
attachment.sType = VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2_KHR;
|
||||||
|
attachment.format = format;
|
||||||
|
attachment.samples = VK_SAMPLE_COUNT_1_BIT;
|
||||||
|
attachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
|
||||||
|
attachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
||||||
|
attachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
||||||
|
attachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
|
||||||
|
attachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||||
|
attachment.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
|
||||||
|
|
||||||
|
VkAttachmentReference2KHR color_reference = {};
|
||||||
|
color_reference.sType = VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2_KHR;
|
||||||
|
color_reference.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||||
|
|
||||||
|
VkSubpassDescription2KHR subpass = {};
|
||||||
|
subpass.sType = VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2_KHR;
|
||||||
|
subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
|
||||||
|
subpass.colorAttachmentCount = 1;
|
||||||
|
subpass.pColorAttachments = &color_reference;
|
||||||
|
|
||||||
|
VkRenderPassCreateInfo2KHR pass_info = {};
|
||||||
|
pass_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2_KHR;
|
||||||
|
pass_info.attachmentCount = 1;
|
||||||
|
pass_info.pAttachments = &attachment;
|
||||||
|
pass_info.subpassCount = 1;
|
||||||
|
pass_info.pSubpasses = &subpass;
|
||||||
|
|
||||||
|
VkRenderPass render_pass = VK_NULL_HANDLE;
|
||||||
|
err = _create_render_pass(vk_device, &pass_info, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_RENDER_PASS), &render_pass);
|
||||||
|
ERR_FAIL_COND_V(err != VK_SUCCESS, ERR_CANT_CREATE);
|
||||||
|
|
||||||
|
DEV_ASSERT(swap_chain->render_pass.id == 0);
|
||||||
|
swap_chain->render_pass = RenderPassID(render_pass);
|
||||||
|
|
||||||
VkFramebufferCreateInfo fb_create_info = {};
|
VkFramebufferCreateInfo fb_create_info = {};
|
||||||
fb_create_info.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
|
fb_create_info.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
|
||||||
fb_create_info.renderPass = VkRenderPass(swap_chain->render_pass.id);
|
fb_create_info.renderPass = render_pass;
|
||||||
fb_create_info.attachmentCount = 1;
|
fb_create_info.attachmentCount = 1;
|
||||||
fb_create_info.width = surface->width;
|
fb_create_info.width = surface->width;
|
||||||
fb_create_info.height = surface->height;
|
fb_create_info.height = surface->height;
|
||||||
|
|
@ -3322,6 +3394,12 @@ RDD::DataFormat RenderingDeviceDriverVulkan::swap_chain_get_format(SwapChainID p
|
||||||
return DATA_FORMAT_B8G8R8A8_UNORM;
|
return DATA_FORMAT_B8G8R8A8_UNORM;
|
||||||
case VK_FORMAT_R8G8B8A8_UNORM:
|
case VK_FORMAT_R8G8B8A8_UNORM:
|
||||||
return DATA_FORMAT_R8G8B8A8_UNORM;
|
return DATA_FORMAT_R8G8B8A8_UNORM;
|
||||||
|
case VK_FORMAT_A2B10G10R10_UNORM_PACK32:
|
||||||
|
return DATA_FORMAT_A2B10G10R10_UNORM_PACK32;
|
||||||
|
case VK_FORMAT_A2R10G10B10_UNORM_PACK32:
|
||||||
|
return DATA_FORMAT_A2R10G10B10_UNORM_PACK32;
|
||||||
|
case VK_FORMAT_R16G16B16A16_SFLOAT:
|
||||||
|
return DATA_FORMAT_R16G16B16A16_SFLOAT;
|
||||||
default:
|
default:
|
||||||
DEV_ASSERT(false && "Unknown swap chain format.");
|
DEV_ASSERT(false && "Unknown swap chain format.");
|
||||||
return DATA_FORMAT_MAX;
|
return DATA_FORMAT_MAX;
|
||||||
|
|
@ -3344,16 +3422,29 @@ void RenderingDeviceDriverVulkan::swap_chain_set_max_fps(SwapChainID p_swap_chai
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RDD::ColorSpace RenderingDeviceDriverVulkan::swap_chain_get_color_space(SwapChainID p_swap_chain) {
|
||||||
|
DEV_ASSERT(p_swap_chain.id != 0);
|
||||||
|
|
||||||
|
SwapChain *swap_chain = (SwapChain *)(p_swap_chain.id);
|
||||||
|
switch (swap_chain->color_space) {
|
||||||
|
case VK_COLOR_SPACE_SRGB_NONLINEAR_KHR:
|
||||||
|
return COLOR_SPACE_SRGB_NONLINEAR;
|
||||||
|
case VK_COLOR_SPACE_HDR10_ST2084_EXT:
|
||||||
|
return COLOR_SPACE_HDR10_ST2084;
|
||||||
|
case VK_COLOR_SPACE_EXTENDED_SRGB_LINEAR_EXT:
|
||||||
|
return COLOR_SPACE_SRGB_LINEAR;
|
||||||
|
default:
|
||||||
|
DEV_ASSERT(false && "Unknown swap chain color space.");
|
||||||
|
return COLOR_SPACE_MAX;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void RenderingDeviceDriverVulkan::swap_chain_free(SwapChainID p_swap_chain) {
|
void RenderingDeviceDriverVulkan::swap_chain_free(SwapChainID p_swap_chain) {
|
||||||
DEV_ASSERT(p_swap_chain.id != 0);
|
DEV_ASSERT(p_swap_chain.id != 0);
|
||||||
|
|
||||||
SwapChain *swap_chain = (SwapChain *)(p_swap_chain.id);
|
SwapChain *swap_chain = (SwapChain *)(p_swap_chain.id);
|
||||||
_swap_chain_release(swap_chain);
|
_swap_chain_release(swap_chain);
|
||||||
|
|
||||||
if (swap_chain->render_pass.id != 0) {
|
|
||||||
vkDestroyRenderPass(vk_device, VkRenderPass(swap_chain->render_pass.id), VKC::get_allocation_callbacks(VK_OBJECT_TYPE_RENDER_PASS));
|
|
||||||
}
|
|
||||||
|
|
||||||
memdelete(swap_chain);
|
memdelete(swap_chain);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -5951,6 +6042,8 @@ bool RenderingDeviceDriverVulkan::has_feature(Features p_feature) {
|
||||||
return true;
|
return true;
|
||||||
case SUPPORTS_BUFFER_DEVICE_ADDRESS:
|
case SUPPORTS_BUFFER_DEVICE_ADDRESS:
|
||||||
return buffer_device_address_support;
|
return buffer_device_address_support;
|
||||||
|
case SUPPORTS_HDR_OUTPUT:
|
||||||
|
return context_driver->is_colorspace_supported();
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -370,6 +370,7 @@ private:
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
bool _determine_swap_chain_format(RenderingContextDriver::SurfaceID p_surface, VkFormat &r_format, VkColorSpaceKHR &r_color_space);
|
||||||
void _swap_chain_release(SwapChain *p_swap_chain);
|
void _swap_chain_release(SwapChain *p_swap_chain);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
@ -380,6 +381,7 @@ public:
|
||||||
virtual int swap_chain_get_pre_rotation_degrees(SwapChainID p_swap_chain) override final;
|
virtual int swap_chain_get_pre_rotation_degrees(SwapChainID p_swap_chain) override final;
|
||||||
virtual DataFormat swap_chain_get_format(SwapChainID p_swap_chain) override final;
|
virtual DataFormat swap_chain_get_format(SwapChainID p_swap_chain) override final;
|
||||||
virtual void swap_chain_set_max_fps(SwapChainID p_swap_chain, int p_max_fps) override final;
|
virtual void swap_chain_set_max_fps(SwapChainID p_swap_chain, int p_max_fps) override final;
|
||||||
|
virtual ColorSpace swap_chain_get_color_space(SwapChainID p_swap_chain) override final;
|
||||||
virtual void swap_chain_free(SwapChainID p_swap_chain) override final;
|
virtual void swap_chain_free(SwapChainID p_swap_chain) override final;
|
||||||
|
|
||||||
/*********************/
|
/*********************/
|
||||||
|
|
|
||||||
|
|
@ -412,6 +412,27 @@ void EditorNode::_update_from_settings() {
|
||||||
scene_root->set_default_canvas_item_texture_repeat(tr);
|
scene_root->set_default_canvas_item_texture_repeat(tr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Enable HDR if requested and available.
|
||||||
|
if (DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_HDR) && RD::get_singleton()->has_feature(RD::Features::SUPPORTS_HDR_OUTPUT)) {
|
||||||
|
bool hdr_enabled = GLOBAL_GET("display/window/hdr/enabled");
|
||||||
|
bool prefer_high_precision = GLOBAL_GET("display/window/hdr/prefer_high_precision");
|
||||||
|
bool use_screen_luminance = GLOBAL_GET("display/window/hdr/use_screen_luminance");
|
||||||
|
|
||||||
|
DisplayServer::get_singleton()->window_set_hdr_output_enabled(hdr_enabled);
|
||||||
|
DisplayServer::get_singleton()->window_set_hdr_output_prefer_high_precision(prefer_high_precision);
|
||||||
|
DisplayServer::get_singleton()->window_set_hdr_output_use_screen_luminance(use_screen_luminance);
|
||||||
|
|
||||||
|
if (!use_screen_luminance) {
|
||||||
|
float reference_luminance = GLOBAL_GET("display/window/hdr/reference_luminance");
|
||||||
|
float min_luminance = GLOBAL_GET("display/window/hdr/min_luminance");
|
||||||
|
float max_luminance = GLOBAL_GET("display/window/hdr/max_luminance");
|
||||||
|
|
||||||
|
DisplayServer::get_singleton()->window_set_hdr_output_reference_luminance(reference_luminance);
|
||||||
|
DisplayServer::get_singleton()->window_set_hdr_output_min_luminance(min_luminance);
|
||||||
|
DisplayServer::get_singleton()->window_set_hdr_output_max_luminance(max_luminance);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
RS::DOFBokehShape dof_shape = RS::DOFBokehShape(int(GLOBAL_GET("rendering/camera/depth_of_field/depth_of_field_bokeh_shape")));
|
RS::DOFBokehShape dof_shape = RS::DOFBokehShape(int(GLOBAL_GET("rendering/camera/depth_of_field/depth_of_field_bokeh_shape")));
|
||||||
RS::get_singleton()->camera_attributes_set_dof_blur_bokeh_shape(dof_shape);
|
RS::get_singleton()->camera_attributes_set_dof_blur_bokeh_shape(dof_shape);
|
||||||
RS::DOFBlurQuality dof_quality = RS::DOFBlurQuality(int(GLOBAL_GET("rendering/camera/depth_of_field/depth_of_field_bokeh_quality")));
|
RS::DOFBlurQuality dof_quality = RS::DOFBlurQuality(int(GLOBAL_GET("rendering/camera/depth_of_field/depth_of_field_bokeh_quality")));
|
||||||
|
|
@ -470,6 +491,10 @@ void EditorNode::_update_from_settings() {
|
||||||
scene_root->set_use_hdr_2d(use_hdr_2d);
|
scene_root->set_use_hdr_2d(use_hdr_2d);
|
||||||
get_viewport()->set_use_hdr_2d(use_hdr_2d);
|
get_viewport()->set_use_hdr_2d(use_hdr_2d);
|
||||||
|
|
||||||
|
const bool tonemap_to_window = GLOBAL_GET("rendering/viewport/tonemap_to_window");
|
||||||
|
scene_root->set_tonemap_to_window(tonemap_to_window);
|
||||||
|
get_viewport()->set_tonemap_to_window(tonemap_to_window);
|
||||||
|
|
||||||
float mesh_lod_threshold = GLOBAL_GET("rendering/mesh_lod/lod_change/threshold_pixels");
|
float mesh_lod_threshold = GLOBAL_GET("rendering/mesh_lod/lod_change/threshold_pixels");
|
||||||
scene_root->set_mesh_lod_threshold(mesh_lod_threshold);
|
scene_root->set_mesh_lod_threshold(mesh_lod_threshold);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2875,6 +2875,9 @@ void Node3DEditorViewport::_project_settings_changed() {
|
||||||
const bool use_hdr_2d = GLOBAL_GET("rendering/viewport/hdr_2d");
|
const bool use_hdr_2d = GLOBAL_GET("rendering/viewport/hdr_2d");
|
||||||
viewport->set_use_hdr_2d(use_hdr_2d);
|
viewport->set_use_hdr_2d(use_hdr_2d);
|
||||||
|
|
||||||
|
const bool tonemap_to_window = GLOBAL_GET("rendering/viewport/tonemap_to_window");
|
||||||
|
viewport->set_tonemap_to_window(tonemap_to_window);
|
||||||
|
|
||||||
const bool use_debanding = GLOBAL_GET("rendering/anti_aliasing/quality/use_debanding");
|
const bool use_debanding = GLOBAL_GET("rendering/anti_aliasing/quality/use_debanding");
|
||||||
viewport->set_use_debanding(use_debanding);
|
viewport->set_use_debanding(use_debanding);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3237,6 +3237,27 @@ Error Main::setup2(bool p_show_boot_logo) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Enable HDR if requested and available.
|
||||||
|
if (DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_HDR) && RD::get_singleton()->has_feature(RD::Features::SUPPORTS_HDR_OUTPUT)) {
|
||||||
|
bool hdr_enabled = GLOBAL_GET("display/window/hdr/enabled");
|
||||||
|
bool prefer_high_precision = GLOBAL_GET("display/window/hdr/prefer_high_precision");
|
||||||
|
bool use_screen_luminance = GLOBAL_GET("display/window/hdr/use_screen_luminance");
|
||||||
|
|
||||||
|
DisplayServer::get_singleton()->window_set_hdr_output_enabled(hdr_enabled);
|
||||||
|
DisplayServer::get_singleton()->window_set_hdr_output_prefer_high_precision(prefer_high_precision);
|
||||||
|
DisplayServer::get_singleton()->window_set_hdr_output_use_screen_luminance(use_screen_luminance);
|
||||||
|
|
||||||
|
if (!use_screen_luminance) {
|
||||||
|
float reference_luminance = GLOBAL_GET("display/window/hdr/reference_luminance");
|
||||||
|
float min_luminance = GLOBAL_GET("display/window/hdr/min_luminance");
|
||||||
|
float max_luminance = GLOBAL_GET("display/window/hdr/max_luminance");
|
||||||
|
|
||||||
|
DisplayServer::get_singleton()->window_set_hdr_output_reference_luminance(reference_luminance);
|
||||||
|
DisplayServer::get_singleton()->window_set_hdr_output_min_luminance(min_luminance);
|
||||||
|
DisplayServer::get_singleton()->window_set_hdr_output_max_luminance(max_luminance);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Color clear = GLOBAL_DEF_BASIC("rendering/environment/defaults/default_clear_color", Color(0.3, 0.3, 0.3));
|
Color clear = GLOBAL_DEF_BASIC("rendering/environment/defaults/default_clear_color", Color(0.3, 0.3, 0.3));
|
||||||
RenderingServer::get_singleton()->set_default_clear_color(clear);
|
RenderingServer::get_singleton()->set_default_clear_color(clear);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -136,6 +136,7 @@ bool DisplayServerWindows::has_feature(Feature p_feature) const {
|
||||||
case FEATURE_WINDOW_EMBEDDING:
|
case FEATURE_WINDOW_EMBEDDING:
|
||||||
case FEATURE_WINDOW_DRAG:
|
case FEATURE_WINDOW_DRAG:
|
||||||
case FEATURE_SCREEN_EXCLUDE_FROM_CAPTURE:
|
case FEATURE_SCREEN_EXCLUDE_FROM_CAPTURE:
|
||||||
|
case FEATURE_HDR:
|
||||||
return true;
|
return true;
|
||||||
case FEATURE_EMOJI_AND_SYMBOL_PICKER:
|
case FEATURE_EMOJI_AND_SYMBOL_PICKER:
|
||||||
return (os_ver.dwBuildNumber >= 17134); // Windows 10 Redstone 4 (1803)+ only.
|
return (os_ver.dwBuildNumber >= 17134); // Windows 10 Redstone 4 (1803)+ only.
|
||||||
|
|
@ -1181,6 +1182,14 @@ typedef struct {
|
||||||
float rate;
|
float rate;
|
||||||
} EnumRefreshRateData;
|
} EnumRefreshRateData;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
Vector<DISPLAYCONFIG_PATH_INFO> paths;
|
||||||
|
Vector<DISPLAYCONFIG_MODE_INFO> modes;
|
||||||
|
int count;
|
||||||
|
int screen;
|
||||||
|
float sdrWhiteLevelInNits;
|
||||||
|
} EnumSdrWhiteLevelData;
|
||||||
|
|
||||||
static BOOL CALLBACK _MonitorEnumProcSize(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData) {
|
static BOOL CALLBACK _MonitorEnumProcSize(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData) {
|
||||||
EnumSizeData *data = (EnumSizeData *)dwData;
|
EnumSizeData *data = (EnumSizeData *)dwData;
|
||||||
if (data->count == data->screen) {
|
if (data->count == data->screen) {
|
||||||
|
|
@ -1491,6 +1500,172 @@ Ref<Image> DisplayServerWindows::screen_get_image_rect(const Rect2i &p_rect) con
|
||||||
return img;
|
return img;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef D3D12_ENABLED
|
||||||
|
static bool _get_screen_desc(int p_screen, DXGI_OUTPUT_DESC1 &r_Desc) {
|
||||||
|
ComPtr<IDXGIFactory4> dxgi_factory;
|
||||||
|
r_Desc = {};
|
||||||
|
|
||||||
|
if (FAILED(CreateDXGIFactory2(0, IID_PPV_ARGS(&dxgi_factory)))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Retrieve the current default adapter.
|
||||||
|
ComPtr<IDXGIAdapter1> dxgiAdapter;
|
||||||
|
if (FAILED(dxgi_factory->EnumAdapters1(0, &dxgiAdapter))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT i = 0;
|
||||||
|
ComPtr<IDXGIOutput> screenOutput;
|
||||||
|
while (dxgiAdapter->EnumOutputs(i, &screenOutput) != DXGI_ERROR_NOT_FOUND) {
|
||||||
|
if (i == (UINT)p_screen) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
ComPtr<IDXGIOutput6> output6;
|
||||||
|
if (FAILED(screenOutput.As(&output6))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
DXGI_OUTPUT_DESC1 desc1;
|
||||||
|
if (FAILED(output6->GetDesc1(&desc1))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
r_Desc = desc1;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
#endif // D3D12_ENABLED
|
||||||
|
|
||||||
|
bool DisplayServerWindows::screen_is_hdr_supported(int p_screen) const {
|
||||||
|
_THREAD_SAFE_METHOD_
|
||||||
|
|
||||||
|
p_screen = _get_screen_index(p_screen);
|
||||||
|
#ifdef D3D12_ENABLED
|
||||||
|
DXGI_OUTPUT_DESC1 desc1;
|
||||||
|
if (!_get_screen_desc(p_screen, desc1)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (desc1.ColorSpace == DXGI_COLOR_SPACE_RGB_FULL_G2084_NONE_P2020);
|
||||||
|
#else
|
||||||
|
return false;
|
||||||
|
#endif // D3D12_ENABLED
|
||||||
|
}
|
||||||
|
|
||||||
|
float DisplayServerWindows::screen_get_min_luminance(int p_screen) const {
|
||||||
|
_THREAD_SAFE_METHOD_
|
||||||
|
|
||||||
|
p_screen = _get_screen_index(p_screen);
|
||||||
|
#ifdef D3D12_ENABLED
|
||||||
|
DXGI_OUTPUT_DESC1 desc1;
|
||||||
|
if (!_get_screen_desc(p_screen, desc1)) {
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
return desc1.MinLuminance;
|
||||||
|
#else
|
||||||
|
return 0.0f;
|
||||||
|
#endif // D3D12_ENABLED
|
||||||
|
}
|
||||||
|
|
||||||
|
float DisplayServerWindows::screen_get_max_luminance(int p_screen) const {
|
||||||
|
_THREAD_SAFE_METHOD_
|
||||||
|
|
||||||
|
p_screen = _get_screen_index(p_screen);
|
||||||
|
#ifdef D3D12_ENABLED
|
||||||
|
DXGI_OUTPUT_DESC1 desc1;
|
||||||
|
if (!_get_screen_desc(p_screen, desc1)) {
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
return desc1.MaxLuminance;
|
||||||
|
#else
|
||||||
|
return 0.0f;
|
||||||
|
#endif // D3D12_ENABLED
|
||||||
|
}
|
||||||
|
|
||||||
|
float DisplayServerWindows::screen_get_max_average_luminance(int p_screen) const {
|
||||||
|
_THREAD_SAFE_METHOD_
|
||||||
|
|
||||||
|
p_screen = _get_screen_index(p_screen);
|
||||||
|
#ifdef D3D12_ENABLED
|
||||||
|
DXGI_OUTPUT_DESC1 desc1;
|
||||||
|
if (!_get_screen_desc(p_screen, desc1)) {
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
return desc1.MaxFullFrameLuminance;
|
||||||
|
#else
|
||||||
|
return 0.0f;
|
||||||
|
#endif // D3D12_ENABLED
|
||||||
|
}
|
||||||
|
|
||||||
|
static BOOL CALLBACK _MonitorEnumProcSdrWhiteLevel(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData) {
|
||||||
|
EnumSdrWhiteLevelData *data = (EnumSdrWhiteLevelData *)dwData;
|
||||||
|
if (data->count == data->screen) {
|
||||||
|
MONITORINFOEXW minfo;
|
||||||
|
memset(&minfo, 0, sizeof(minfo));
|
||||||
|
minfo.cbSize = sizeof(minfo);
|
||||||
|
GetMonitorInfoW(hMonitor, &minfo);
|
||||||
|
|
||||||
|
// First, find this screen's path.
|
||||||
|
for (const DISPLAYCONFIG_PATH_INFO &path : data->paths) {
|
||||||
|
DISPLAYCONFIG_SOURCE_DEVICE_NAME source_name;
|
||||||
|
memset(&source_name, 0, sizeof(source_name));
|
||||||
|
source_name.header.type = DISPLAYCONFIG_DEVICE_INFO_GET_SOURCE_NAME;
|
||||||
|
source_name.header.size = sizeof(source_name);
|
||||||
|
source_name.header.adapterId = path.sourceInfo.adapterId;
|
||||||
|
source_name.header.id = path.sourceInfo.id;
|
||||||
|
|
||||||
|
if (DisplayConfigGetDeviceInfo(&source_name.header) == ERROR_SUCCESS) {
|
||||||
|
if (wcscmp(minfo.szDevice, source_name.viewGdiDeviceName) == 0) {
|
||||||
|
// Found it, now we can query the SDR white level.
|
||||||
|
DISPLAYCONFIG_SDR_WHITE_LEVEL sdr_white_level;
|
||||||
|
memset(&sdr_white_level, 0, sizeof(sdr_white_level));
|
||||||
|
sdr_white_level.header.type = DISPLAYCONFIG_DEVICE_INFO_GET_SDR_WHITE_LEVEL;
|
||||||
|
sdr_white_level.header.size = sizeof(sdr_white_level);
|
||||||
|
sdr_white_level.header.adapterId = path.targetInfo.adapterId;
|
||||||
|
sdr_white_level.header.id = path.targetInfo.id;
|
||||||
|
|
||||||
|
LONG result = DisplayConfigGetDeviceInfo(&sdr_white_level.header);
|
||||||
|
if (result == ERROR_SUCCESS) {
|
||||||
|
data->sdrWhiteLevelInNits = (float)(sdr_white_level.SDRWhiteLevel / 1000) * 80;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
data->count++;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
float DisplayServerWindows::screen_get_sdr_white_level(int p_screen) const {
|
||||||
|
_THREAD_SAFE_METHOD_
|
||||||
|
|
||||||
|
p_screen = _get_screen_index(p_screen);
|
||||||
|
EnumSdrWhiteLevelData data = { Vector<DISPLAYCONFIG_PATH_INFO>(), Vector<DISPLAYCONFIG_MODE_INFO>(), 0, p_screen, 0.0f };
|
||||||
|
|
||||||
|
uint32_t path_count = 0;
|
||||||
|
uint32_t mode_count = 0;
|
||||||
|
if (GetDisplayConfigBufferSizes(QDC_ONLY_ACTIVE_PATHS, &path_count, &mode_count) == ERROR_SUCCESS) {
|
||||||
|
data.paths.resize(path_count);
|
||||||
|
data.modes.resize(mode_count);
|
||||||
|
if (QueryDisplayConfig(QDC_ONLY_ACTIVE_PATHS, &path_count, data.paths.ptrw(), &mode_count, data.modes.ptrw(), nullptr) != ERROR_SUCCESS) {
|
||||||
|
data.paths.clear();
|
||||||
|
data.modes.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
EnumDisplayMonitors(nullptr, nullptr, _MonitorEnumProcSdrWhiteLevel, (LPARAM)&data);
|
||||||
|
return data.sdrWhiteLevelInNits;
|
||||||
|
}
|
||||||
|
|
||||||
float DisplayServerWindows::screen_get_refresh_rate(int p_screen) const {
|
float DisplayServerWindows::screen_get_refresh_rate(int p_screen) const {
|
||||||
_THREAD_SAFE_METHOD_
|
_THREAD_SAFE_METHOD_
|
||||||
|
|
||||||
|
|
@ -2973,6 +3148,74 @@ HWND DisplayServerWindows::_find_window_from_process_id(OS::ProcessID p_pid, HWN
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get screen HDR capabilities for internal use only.
|
||||||
|
// Do not report values from this method to the user.
|
||||||
|
DisplayServerWindows::ScreenHdrData DisplayServerWindows::_get_screen_hdr_data(int p_screen) const {
|
||||||
|
ScreenHdrData data;
|
||||||
|
#ifdef D3D12_ENABLED
|
||||||
|
DXGI_OUTPUT_DESC1 desc;
|
||||||
|
if (_get_screen_desc(p_screen, desc)) {
|
||||||
|
data.hdr_supported = desc.ColorSpace == DXGI_COLOR_SPACE_RGB_FULL_G2084_NONE_P2020;
|
||||||
|
data.min_luminance = desc.MinLuminance;
|
||||||
|
data.max_luminance = desc.MaxLuminance;
|
||||||
|
data.max_average_luminance = desc.MaxFullFrameLuminance;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
// If we don't have D3D12, assume HDR is supported to avoid blocking Vulkan only builds.
|
||||||
|
data.hdr_supported = true;
|
||||||
|
data.min_luminance = 0.0f;
|
||||||
|
data.max_luminance = 0.0f;
|
||||||
|
data.max_average_luminance = 0.0f;
|
||||||
|
#endif // D3D12_ENABLED
|
||||||
|
|
||||||
|
data.sdr_white_level = screen_get_sdr_white_level(p_screen);
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DisplayServerWindows::_update_hdr_output_for_window(WindowID p_window, const WindowData &p_window_data, ScreenHdrData p_screen_data) {
|
||||||
|
#ifdef RD_ENABLED
|
||||||
|
if (rendering_context) {
|
||||||
|
bool current_hdr_enabled = rendering_context->window_get_hdr_output_enabled(p_window);
|
||||||
|
bool desired_hdr_enabled = p_window_data.hdr_output_requested && p_screen_data.hdr_supported;
|
||||||
|
|
||||||
|
if (current_hdr_enabled != desired_hdr_enabled) {
|
||||||
|
rendering_context->window_set_hdr_output_enabled(p_window, desired_hdr_enabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p_window_data.hdr_output_use_screen_luminance) {
|
||||||
|
if (p_screen_data.sdr_white_level > 0.0f) {
|
||||||
|
rendering_context->window_set_hdr_output_reference_luminance(p_window, p_screen_data.sdr_white_level);
|
||||||
|
}
|
||||||
|
if (p_screen_data.min_luminance > 0.0f) {
|
||||||
|
rendering_context->window_set_hdr_output_min_luminance(p_window, p_screen_data.min_luminance);
|
||||||
|
}
|
||||||
|
if (p_screen_data.max_luminance > 0.0f) {
|
||||||
|
rendering_context->window_set_hdr_output_max_luminance(p_window, p_screen_data.max_luminance);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif // RD_ENABLED
|
||||||
|
}
|
||||||
|
|
||||||
|
void DisplayServerWindows::_update_hdr_output_for_tracked_windows() {
|
||||||
|
HashMap<int, ScreenHdrData> outputs;
|
||||||
|
for (const KeyValue<WindowID, WindowData> &E : windows) {
|
||||||
|
if (E.value.hdr_output_requested) {
|
||||||
|
int screen = window_get_current_screen(E.key);
|
||||||
|
|
||||||
|
ScreenHdrData data;
|
||||||
|
if (!outputs.has(screen)) {
|
||||||
|
data = _get_screen_hdr_data(screen);
|
||||||
|
outputs.insert(screen, data);
|
||||||
|
} else {
|
||||||
|
data = outputs[screen];
|
||||||
|
}
|
||||||
|
|
||||||
|
_update_hdr_output_for_window(E.key, E.value, data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Error DisplayServerWindows::embed_process(WindowID p_window, OS::ProcessID p_pid, const Rect2i &p_rect, bool p_visible, bool p_grab_focus) {
|
Error DisplayServerWindows::embed_process(WindowID p_window, OS::ProcessID p_pid, const Rect2i &p_rect, bool p_visible, bool p_grab_focus) {
|
||||||
_THREAD_SAFE_METHOD_
|
_THREAD_SAFE_METHOD_
|
||||||
|
|
||||||
|
|
@ -4095,6 +4338,155 @@ DisplayServer::VSyncMode DisplayServerWindows::window_get_vsync_mode(WindowID p_
|
||||||
return DisplayServer::VSYNC_ENABLED;
|
return DisplayServer::VSYNC_ENABLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DisplayServerWindows::window_set_hdr_output_enabled(const bool p_enabled, WindowID p_window) {
|
||||||
|
_THREAD_SAFE_METHOD_
|
||||||
|
|
||||||
|
#if defined(RD_ENABLED)
|
||||||
|
ERR_FAIL_COND_MSG((rendering_device && rendering_device->has_feature(RenderingDevice::Features::SUPPORTS_HDR_OUTPUT)) == false, "HDR output is not supported by the rendering device.");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
WindowData &wd = windows[p_window];
|
||||||
|
wd.hdr_output_requested = p_enabled;
|
||||||
|
|
||||||
|
int screen = window_get_current_screen(p_window);
|
||||||
|
DisplayServerWindows::ScreenHdrData data = _get_screen_hdr_data(screen);
|
||||||
|
_update_hdr_output_for_window(p_window, wd, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DisplayServerWindows::window_is_hdr_output_enabled(WindowID p_window) const {
|
||||||
|
_THREAD_SAFE_METHOD_
|
||||||
|
#if defined(RD_ENABLED)
|
||||||
|
if (rendering_context) {
|
||||||
|
return rendering_context->window_get_hdr_output_enabled(p_window);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DisplayServerWindows::window_set_hdr_output_prefer_high_precision(const bool p_enabled, WindowID p_window) {
|
||||||
|
_THREAD_SAFE_METHOD_
|
||||||
|
#if defined(RD_ENABLED)
|
||||||
|
if (rendering_context) {
|
||||||
|
if (p_enabled == rendering_context->window_get_hdr_output_prefer_high_precision(p_window)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
rendering_context->window_set_hdr_output_prefer_high_precision(p_window, p_enabled);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DisplayServerWindows::window_is_hdr_output_preferring_high_precision(WindowID p_window) const {
|
||||||
|
_THREAD_SAFE_METHOD_
|
||||||
|
#if defined(RD_ENABLED)
|
||||||
|
if (rendering_context) {
|
||||||
|
return rendering_context->window_get_hdr_output_prefer_high_precision(p_window);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DisplayServerWindows::window_set_hdr_output_use_screen_luminance(const bool p_enabled, WindowID p_window) {
|
||||||
|
_THREAD_SAFE_METHOD_
|
||||||
|
|
||||||
|
WindowData &wd = windows[p_window];
|
||||||
|
wd.hdr_output_use_screen_luminance = p_enabled;
|
||||||
|
|
||||||
|
int screen = window_get_current_screen(p_window);
|
||||||
|
DisplayServerWindows::ScreenHdrData data = _get_screen_hdr_data(screen);
|
||||||
|
_update_hdr_output_for_window(p_window, wd, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DisplayServerWindows::window_is_hdr_output_using_screen_luminance(WindowID p_window) const {
|
||||||
|
_THREAD_SAFE_METHOD_
|
||||||
|
|
||||||
|
const WindowData &wd = windows[p_window];
|
||||||
|
return wd.hdr_output_use_screen_luminance;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DisplayServerWindows::window_set_hdr_output_reference_luminance(const float p_reference_luminance, WindowID p_window) {
|
||||||
|
_THREAD_SAFE_METHOD_
|
||||||
|
|
||||||
|
const WindowData &wd = windows[p_window];
|
||||||
|
if (wd.hdr_output_use_screen_luminance) {
|
||||||
|
WARN_PRINT("Reference luminance is ignored when using screen luminance.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(RD_ENABLED)
|
||||||
|
if (rendering_context) {
|
||||||
|
rendering_context->window_set_hdr_output_reference_luminance(p_window, p_reference_luminance);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
float DisplayServerWindows::window_get_hdr_output_reference_luminance(WindowID p_window) const {
|
||||||
|
_THREAD_SAFE_METHOD_
|
||||||
|
#if defined(RD_ENABLED)
|
||||||
|
if (rendering_context) {
|
||||||
|
return rendering_context->window_get_hdr_output_reference_luminance(p_window);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DisplayServerWindows::window_set_hdr_output_min_luminance(const float p_min_luminance, WindowID p_window) {
|
||||||
|
_THREAD_SAFE_METHOD_
|
||||||
|
|
||||||
|
const WindowData &wd = windows[p_window];
|
||||||
|
if (wd.hdr_output_use_screen_luminance) {
|
||||||
|
WARN_PRINT("Minimum luminance is ignored when using screen luminance.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(RD_ENABLED)
|
||||||
|
if (rendering_context) {
|
||||||
|
rendering_context->window_set_hdr_output_min_luminance(p_window, p_min_luminance);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
float DisplayServerWindows::window_get_hdr_output_min_luminance(WindowID p_window) const {
|
||||||
|
_THREAD_SAFE_METHOD_
|
||||||
|
#if defined(RD_ENABLED)
|
||||||
|
if (rendering_context) {
|
||||||
|
return rendering_context->window_get_hdr_output_min_luminance(p_window);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DisplayServerWindows::window_set_hdr_output_max_luminance(const float p_max_luminance, WindowID p_window) {
|
||||||
|
_THREAD_SAFE_METHOD_
|
||||||
|
|
||||||
|
const WindowData &wd = windows[p_window];
|
||||||
|
if (wd.hdr_output_use_screen_luminance) {
|
||||||
|
WARN_PRINT("Maximum luminance is ignored when using screen luminance.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(RD_ENABLED)
|
||||||
|
if (rendering_context) {
|
||||||
|
rendering_context->window_set_hdr_output_max_luminance(p_window, p_max_luminance);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
float DisplayServerWindows::window_get_hdr_output_max_luminance(WindowID p_window) const {
|
||||||
|
_THREAD_SAFE_METHOD_
|
||||||
|
#if defined(RD_ENABLED)
|
||||||
|
if (rendering_context) {
|
||||||
|
return rendering_context->window_get_hdr_output_max_luminance(p_window);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
void DisplayServerWindows::window_start_drag(WindowID p_window) {
|
void DisplayServerWindows::window_start_drag(WindowID p_window) {
|
||||||
_THREAD_SAFE_METHOD_
|
_THREAD_SAFE_METHOD_
|
||||||
|
|
||||||
|
|
@ -5561,6 +5953,10 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
case WM_DISPLAYCHANGE: {
|
||||||
|
_update_hdr_output_for_tracked_windows();
|
||||||
|
} break;
|
||||||
|
|
||||||
case WM_WINDOWPOSCHANGED: {
|
case WM_WINDOWPOSCHANGED: {
|
||||||
Rect2i window_client_rect;
|
Rect2i window_client_rect;
|
||||||
Rect2i window_rect;
|
Rect2i window_rect;
|
||||||
|
|
@ -5644,6 +6040,8 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
|
||||||
window.rect_changed_callback.call(Rect2i(window.last_pos.x, window.last_pos.y, window.width, window.height));
|
window.rect_changed_callback.call(Rect2i(window.last_pos.x, window.last_pos.y, window.width, window.height));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_update_hdr_output_for_tracked_windows();
|
||||||
|
|
||||||
// Update cursor clip region after window rect has changed.
|
// Update cursor clip region after window rect has changed.
|
||||||
if (mouse_mode == MOUSE_MODE_CAPTURED || mouse_mode == MOUSE_MODE_CONFINED || mouse_mode == MOUSE_MODE_CONFINED_HIDDEN) {
|
if (mouse_mode == MOUSE_MODE_CAPTURED || mouse_mode == MOUSE_MODE_CONFINED || mouse_mode == MOUSE_MODE_CONFINED_HIDDEN) {
|
||||||
RECT crect;
|
RECT crect;
|
||||||
|
|
|
||||||
|
|
@ -548,6 +548,10 @@ class DisplayServerWindows : public DisplayServer {
|
||||||
bool is_popup = false;
|
bool is_popup = false;
|
||||||
Rect2i parent_safe_rect;
|
Rect2i parent_safe_rect;
|
||||||
|
|
||||||
|
// HDR
|
||||||
|
bool hdr_output_requested = false;
|
||||||
|
bool hdr_output_use_screen_luminance = false;
|
||||||
|
|
||||||
bool initialized = false;
|
bool initialized = false;
|
||||||
|
|
||||||
HWND parent_hwnd = 0;
|
HWND parent_hwnd = 0;
|
||||||
|
|
@ -687,6 +691,17 @@ class DisplayServerWindows : public DisplayServer {
|
||||||
|
|
||||||
HWND _find_window_from_process_id(OS::ProcessID p_pid, HWND p_current_hwnd);
|
HWND _find_window_from_process_id(OS::ProcessID p_pid, HWND p_current_hwnd);
|
||||||
|
|
||||||
|
struct ScreenHdrData {
|
||||||
|
bool hdr_supported = false;
|
||||||
|
float min_luminance = 0.0f;
|
||||||
|
float max_luminance = 0.0f;
|
||||||
|
float max_average_luminance = 0.0f;
|
||||||
|
float sdr_white_level = 0.0f;
|
||||||
|
};
|
||||||
|
ScreenHdrData _get_screen_hdr_data(int p_screen) const;
|
||||||
|
void _update_hdr_output_for_window(WindowID p_window, const WindowData &p_window_data, ScreenHdrData p_screen_data);
|
||||||
|
void _update_hdr_output_for_tracked_windows();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
LRESULT WndProcFileDialog(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
LRESULT WndProcFileDialog(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
||||||
LRESULT WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
LRESULT WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
||||||
|
|
@ -747,6 +762,13 @@ public:
|
||||||
virtual Ref<Image> screen_get_image(int p_screen = SCREEN_OF_MAIN_WINDOW) const override;
|
virtual Ref<Image> screen_get_image(int p_screen = SCREEN_OF_MAIN_WINDOW) const override;
|
||||||
virtual Ref<Image> screen_get_image_rect(const Rect2i &p_rect) const override;
|
virtual Ref<Image> screen_get_image_rect(const Rect2i &p_rect) const override;
|
||||||
|
|
||||||
|
// Display capabilities for HDR.
|
||||||
|
virtual bool screen_is_hdr_supported(int p_screen = SCREEN_OF_MAIN_WINDOW) const override;
|
||||||
|
virtual float screen_get_min_luminance(int p_screen = SCREEN_OF_MAIN_WINDOW) const override;
|
||||||
|
virtual float screen_get_max_luminance(int p_screen = SCREEN_OF_MAIN_WINDOW) const override;
|
||||||
|
virtual float screen_get_max_average_luminance(int p_screen = SCREEN_OF_MAIN_WINDOW) const override;
|
||||||
|
virtual float screen_get_sdr_white_level(int p_screen = SCREEN_OF_MAIN_WINDOW) const override;
|
||||||
|
|
||||||
virtual void screen_set_keep_on(bool p_enable) override; //disable screensaver
|
virtual void screen_set_keep_on(bool p_enable) override; //disable screensaver
|
||||||
virtual bool screen_is_kept_on() const override;
|
virtual bool screen_is_kept_on() const override;
|
||||||
|
|
||||||
|
|
@ -827,6 +849,19 @@ public:
|
||||||
virtual void window_set_vsync_mode(DisplayServer::VSyncMode p_vsync_mode, WindowID p_window = MAIN_WINDOW_ID) override;
|
virtual void window_set_vsync_mode(DisplayServer::VSyncMode p_vsync_mode, WindowID p_window = MAIN_WINDOW_ID) override;
|
||||||
virtual DisplayServer::VSyncMode window_get_vsync_mode(WindowID p_vsync_mode) const override;
|
virtual DisplayServer::VSyncMode window_get_vsync_mode(WindowID p_vsync_mode) const override;
|
||||||
|
|
||||||
|
virtual void window_set_hdr_output_enabled(const bool p_enabled, WindowID p_window = MAIN_WINDOW_ID) override;
|
||||||
|
virtual bool window_is_hdr_output_enabled(WindowID p_window = MAIN_WINDOW_ID) const override;
|
||||||
|
virtual void window_set_hdr_output_prefer_high_precision(const bool p_enabled, WindowID p_window = MAIN_WINDOW_ID) override;
|
||||||
|
virtual bool window_is_hdr_output_preferring_high_precision(WindowID p_window = MAIN_WINDOW_ID) const override;
|
||||||
|
virtual void window_set_hdr_output_use_screen_luminance(const bool p_enabled, WindowID p_window = MAIN_WINDOW_ID) override;
|
||||||
|
virtual bool window_is_hdr_output_using_screen_luminance(WindowID p_window = MAIN_WINDOW_ID) const override;
|
||||||
|
virtual void window_set_hdr_output_reference_luminance(const float p_reference_luminance, WindowID p_window = MAIN_WINDOW_ID) override;
|
||||||
|
virtual float window_get_hdr_output_reference_luminance(WindowID p_window = MAIN_WINDOW_ID) const override;
|
||||||
|
virtual void window_set_hdr_output_min_luminance(const float p_min_luminance, WindowID p_window = MAIN_WINDOW_ID) override;
|
||||||
|
virtual float window_get_hdr_output_min_luminance(WindowID p_window = MAIN_WINDOW_ID) const override;
|
||||||
|
virtual void window_set_hdr_output_max_luminance(const float p_max_luminance, WindowID p_window = MAIN_WINDOW_ID) override;
|
||||||
|
virtual float window_get_hdr_output_max_luminance(WindowID p_window = MAIN_WINDOW_ID) const override;
|
||||||
|
|
||||||
virtual void window_start_drag(WindowID p_window = MAIN_WINDOW_ID) override;
|
virtual void window_start_drag(WindowID p_window = MAIN_WINDOW_ID) override;
|
||||||
virtual void window_start_resize(WindowResizeEdge p_edge, WindowID p_window = MAIN_WINDOW_ID) override;
|
virtual void window_start_resize(WindowResizeEdge p_edge, WindowID p_window = MAIN_WINDOW_ID) override;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1900,6 +1900,9 @@ SceneTree::SceneTree() {
|
||||||
const bool use_hdr_2d = GLOBAL_GET("rendering/viewport/hdr_2d");
|
const bool use_hdr_2d = GLOBAL_GET("rendering/viewport/hdr_2d");
|
||||||
root->set_use_hdr_2d(use_hdr_2d);
|
root->set_use_hdr_2d(use_hdr_2d);
|
||||||
|
|
||||||
|
const bool tonemap_to_window = GLOBAL_DEF("rendering/viewport/tonemap_to_window", true);
|
||||||
|
root->set_tonemap_to_window(tonemap_to_window);
|
||||||
|
|
||||||
const int ssaa_mode = GLOBAL_DEF_BASIC(PropertyInfo(Variant::INT, "rendering/anti_aliasing/quality/screen_space_aa", PROPERTY_HINT_ENUM, "Disabled (Fastest),FXAA (Fast)"), 0);
|
const int ssaa_mode = GLOBAL_DEF_BASIC(PropertyInfo(Variant::INT, "rendering/anti_aliasing/quality/screen_space_aa", PROPERTY_HINT_ENUM, "Disabled (Fastest),FXAA (Fast)"), 0);
|
||||||
root->set_screen_space_aa(Viewport::ScreenSpaceAA(ssaa_mode));
|
root->set_screen_space_aa(Viewport::ScreenSpaceAA(ssaa_mode));
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1206,6 +1206,17 @@ bool Viewport::is_using_hdr_2d() const {
|
||||||
return use_hdr_2d;
|
return use_hdr_2d;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Viewport::set_tonemap_to_window(bool p_enable) {
|
||||||
|
ERR_MAIN_THREAD_GUARD;
|
||||||
|
tonemap_to_window = p_enable;
|
||||||
|
RS::get_singleton()->viewport_set_tonemap_to_screen(viewport, p_enable);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Viewport::is_tonemapping_to_window() const {
|
||||||
|
ERR_READ_THREAD_GUARD_V(false);
|
||||||
|
return tonemap_to_window;
|
||||||
|
}
|
||||||
|
|
||||||
void Viewport::set_world_2d(const Ref<World2D> &p_world_2d) {
|
void Viewport::set_world_2d(const Ref<World2D> &p_world_2d) {
|
||||||
ERR_MAIN_THREAD_GUARD;
|
ERR_MAIN_THREAD_GUARD;
|
||||||
if (world_2d == p_world_2d) {
|
if (world_2d == p_world_2d) {
|
||||||
|
|
@ -4777,6 +4788,9 @@ void Viewport::_bind_methods() {
|
||||||
ClassDB::bind_method(D_METHOD("set_use_hdr_2d", "enable"), &Viewport::set_use_hdr_2d);
|
ClassDB::bind_method(D_METHOD("set_use_hdr_2d", "enable"), &Viewport::set_use_hdr_2d);
|
||||||
ClassDB::bind_method(D_METHOD("is_using_hdr_2d"), &Viewport::is_using_hdr_2d);
|
ClassDB::bind_method(D_METHOD("is_using_hdr_2d"), &Viewport::is_using_hdr_2d);
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("set_tonemap_to_window", "enable"), &Viewport::set_tonemap_to_window);
|
||||||
|
ClassDB::bind_method(D_METHOD("is_tonemapping_to_window"), &Viewport::is_tonemapping_to_window);
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("set_msaa_2d", "msaa"), &Viewport::set_msaa_2d);
|
ClassDB::bind_method(D_METHOD("set_msaa_2d", "msaa"), &Viewport::set_msaa_2d);
|
||||||
ClassDB::bind_method(D_METHOD("get_msaa_2d"), &Viewport::get_msaa_2d);
|
ClassDB::bind_method(D_METHOD("get_msaa_2d"), &Viewport::get_msaa_2d);
|
||||||
|
|
||||||
|
|
@ -4955,6 +4969,7 @@ void Viewport::_bind_methods() {
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "mesh_lod_threshold", PROPERTY_HINT_RANGE, "0,1024,0.1"), "set_mesh_lod_threshold", "get_mesh_lod_threshold");
|
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "mesh_lod_threshold", PROPERTY_HINT_RANGE, "0,1024,0.1"), "set_mesh_lod_threshold", "get_mesh_lod_threshold");
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "debug_draw", PROPERTY_HINT_ENUM, "Disabled,Unshaded,Lighting,Overdraw,Wireframe,Normal Buffer,VoxelGI Albedo,VoxelGI Lighting,VoxelGI Emission,Shadow Atlas,Directional Shadow Map,Scene Luminance,SSAO,SSIL,Directional Shadow Splits,Decal Atlas,SDFGI Cascades,SDFGI Probes,VoxelGI/SDFGI Buffer,Disable Mesh LOD,OmniLight3D Cluster,SpotLight3D Cluster,Decal Cluster,ReflectionProbe Cluster,Occlusion Culling Buffer,Motion Vectors,Internal Buffer"), "set_debug_draw", "get_debug_draw");
|
ADD_PROPERTY(PropertyInfo(Variant::INT, "debug_draw", PROPERTY_HINT_ENUM, "Disabled,Unshaded,Lighting,Overdraw,Wireframe,Normal Buffer,VoxelGI Albedo,VoxelGI Lighting,VoxelGI Emission,Shadow Atlas,Directional Shadow Map,Scene Luminance,SSAO,SSIL,Directional Shadow Splits,Decal Atlas,SDFGI Cascades,SDFGI Probes,VoxelGI/SDFGI Buffer,Disable Mesh LOD,OmniLight3D Cluster,SpotLight3D Cluster,Decal Cluster,ReflectionProbe Cluster,Occlusion Culling Buffer,Motion Vectors,Internal Buffer"), "set_debug_draw", "get_debug_draw");
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_hdr_2d"), "set_use_hdr_2d", "is_using_hdr_2d");
|
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_hdr_2d"), "set_use_hdr_2d", "is_using_hdr_2d");
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "tonemap_to_window"), "set_tonemap_to_window", "is_tonemapping_to_window");
|
||||||
|
|
||||||
#ifndef _3D_DISABLED
|
#ifndef _3D_DISABLED
|
||||||
ADD_GROUP("Scaling 3D", "");
|
ADD_GROUP("Scaling 3D", "");
|
||||||
|
|
|
||||||
|
|
@ -264,6 +264,7 @@ private:
|
||||||
bool transparent_bg = false;
|
bool transparent_bg = false;
|
||||||
bool use_hdr_2d = false;
|
bool use_hdr_2d = false;
|
||||||
bool gen_mipmaps = false;
|
bool gen_mipmaps = false;
|
||||||
|
bool tonemap_to_window = false;
|
||||||
|
|
||||||
bool snap_controls_to_pixels = true;
|
bool snap_controls_to_pixels = true;
|
||||||
bool snap_2d_transforms_to_pixel = false;
|
bool snap_2d_transforms_to_pixel = false;
|
||||||
|
|
@ -541,6 +542,9 @@ public:
|
||||||
void set_use_hdr_2d(bool p_enable);
|
void set_use_hdr_2d(bool p_enable);
|
||||||
bool is_using_hdr_2d() const;
|
bool is_using_hdr_2d() const;
|
||||||
|
|
||||||
|
void set_tonemap_to_window(bool p_enable);
|
||||||
|
bool is_tonemapping_to_window() const;
|
||||||
|
|
||||||
Ref<ViewportTexture> get_texture() const;
|
Ref<ViewportTexture> get_texture() const;
|
||||||
|
|
||||||
void set_positional_shadow_atlas_size(int p_size);
|
void set_positional_shadow_atlas_size(int p_size);
|
||||||
|
|
|
||||||
|
|
@ -578,6 +578,126 @@ bool Window::get_flag(Flags p_flag) const {
|
||||||
return flags[p_flag];
|
return flags[p_flag];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Window::set_hdr_output_enabled(bool p_enabled) {
|
||||||
|
ERR_MAIN_THREAD_GUARD;
|
||||||
|
|
||||||
|
hdr_output_enabled = p_enabled;
|
||||||
|
|
||||||
|
if (window_id != DisplayServer::INVALID_WINDOW_ID) {
|
||||||
|
DisplayServer::get_singleton()->window_set_hdr_output_enabled(hdr_output_enabled, window_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Window::is_hdr_output_enabled() const {
|
||||||
|
ERR_READ_THREAD_GUARD_V(false);
|
||||||
|
|
||||||
|
if (window_id != DisplayServer::INVALID_WINDOW_ID) {
|
||||||
|
hdr_output_enabled = DisplayServer::get_singleton()->window_is_hdr_output_enabled(window_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
return hdr_output_enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Window::set_hdr_output_prefer_high_precision(bool p_enabled) {
|
||||||
|
ERR_MAIN_THREAD_GUARD;
|
||||||
|
|
||||||
|
hdr_output_prefer_high_precision = p_enabled;
|
||||||
|
|
||||||
|
if (window_id != DisplayServer::INVALID_WINDOW_ID) {
|
||||||
|
DisplayServer::get_singleton()->window_set_hdr_output_prefer_high_precision(hdr_output_prefer_high_precision, window_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Window::is_hdr_output_preferring_high_precision() const {
|
||||||
|
ERR_READ_THREAD_GUARD_V(false);
|
||||||
|
|
||||||
|
if (window_id != DisplayServer::INVALID_WINDOW_ID) {
|
||||||
|
hdr_output_prefer_high_precision = DisplayServer::get_singleton()->window_is_hdr_output_preferring_high_precision(window_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
return hdr_output_prefer_high_precision;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Window::set_hdr_output_use_screen_luminance(bool p_enabled) {
|
||||||
|
ERR_MAIN_THREAD_GUARD;
|
||||||
|
|
||||||
|
hdr_output_use_screen_luminance = p_enabled;
|
||||||
|
|
||||||
|
if (window_id != DisplayServer::INVALID_WINDOW_ID) {
|
||||||
|
DisplayServer::get_singleton()->window_set_hdr_output_use_screen_luminance(hdr_output_use_screen_luminance, window_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Window::is_hdr_output_using_screen_luminance() const {
|
||||||
|
ERR_READ_THREAD_GUARD_V(false);
|
||||||
|
|
||||||
|
if (window_id != DisplayServer::INVALID_WINDOW_ID) {
|
||||||
|
hdr_output_use_screen_luminance = DisplayServer::get_singleton()->window_is_hdr_output_using_screen_luminance(window_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
return hdr_output_use_screen_luminance;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Window::set_hdr_output_reference_luminance(float p_reference_luminance) {
|
||||||
|
ERR_MAIN_THREAD_GUARD;
|
||||||
|
|
||||||
|
hdr_output_reference_luminance = p_reference_luminance;
|
||||||
|
|
||||||
|
if (window_id != DisplayServer::INVALID_WINDOW_ID) {
|
||||||
|
DisplayServer::get_singleton()->window_set_hdr_output_reference_luminance(hdr_output_reference_luminance, window_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
float Window::get_hdr_output_reference_luminance() const {
|
||||||
|
ERR_READ_THREAD_GUARD_V(0.0f);
|
||||||
|
|
||||||
|
if (window_id != DisplayServer::INVALID_WINDOW_ID) {
|
||||||
|
hdr_output_reference_luminance = DisplayServer::get_singleton()->window_get_hdr_output_reference_luminance(window_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
return hdr_output_reference_luminance;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Window::set_hdr_output_min_luminance(float p_min_luminance) {
|
||||||
|
ERR_MAIN_THREAD_GUARD;
|
||||||
|
|
||||||
|
hdr_output_min_luminance = p_min_luminance;
|
||||||
|
|
||||||
|
if (window_id != DisplayServer::INVALID_WINDOW_ID) {
|
||||||
|
DisplayServer::get_singleton()->window_set_hdr_output_min_luminance(hdr_output_min_luminance, window_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
float Window::get_hdr_output_min_luminance() const {
|
||||||
|
ERR_READ_THREAD_GUARD_V(0.0f);
|
||||||
|
|
||||||
|
if (window_id != DisplayServer::INVALID_WINDOW_ID) {
|
||||||
|
hdr_output_min_luminance = DisplayServer::get_singleton()->window_get_hdr_output_min_luminance(window_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
return hdr_output_min_luminance;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Window::set_hdr_output_max_luminance(float p_max_luminance) {
|
||||||
|
ERR_MAIN_THREAD_GUARD;
|
||||||
|
|
||||||
|
hdr_output_max_luminance = p_max_luminance;
|
||||||
|
|
||||||
|
if (window_id != DisplayServer::INVALID_WINDOW_ID) {
|
||||||
|
DisplayServer::get_singleton()->window_set_hdr_output_max_luminance(hdr_output_max_luminance, window_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
float Window::get_hdr_output_max_luminance() const {
|
||||||
|
ERR_READ_THREAD_GUARD_V(0.0f);
|
||||||
|
|
||||||
|
if (window_id != DisplayServer::INVALID_WINDOW_ID) {
|
||||||
|
hdr_output_max_luminance = DisplayServer::get_singleton()->window_get_hdr_output_max_luminance(window_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
return hdr_output_max_luminance;
|
||||||
|
}
|
||||||
|
|
||||||
bool Window::is_maximize_allowed() const {
|
bool Window::is_maximize_allowed() const {
|
||||||
ERR_READ_THREAD_GUARD_V(false);
|
ERR_READ_THREAD_GUARD_V(false);
|
||||||
if (window_id != DisplayServer::INVALID_WINDOW_ID) {
|
if (window_id != DisplayServer::INVALID_WINDOW_ID) {
|
||||||
|
|
@ -678,6 +798,16 @@ void Window::_make_window() {
|
||||||
DisplayServer::get_singleton()->window_set_title(tr_title, window_id);
|
DisplayServer::get_singleton()->window_set_title(tr_title, window_id);
|
||||||
DisplayServer::get_singleton()->window_attach_instance_id(get_instance_id(), window_id);
|
DisplayServer::get_singleton()->window_attach_instance_id(get_instance_id(), window_id);
|
||||||
|
|
||||||
|
// Set HDR output settings.
|
||||||
|
DisplayServer::get_singleton()->window_set_hdr_output_enabled(hdr_output_enabled, window_id);
|
||||||
|
DisplayServer::get_singleton()->window_set_hdr_output_prefer_high_precision(hdr_output_prefer_high_precision, window_id);
|
||||||
|
DisplayServer::get_singleton()->window_set_hdr_output_use_screen_luminance(hdr_output_use_screen_luminance, window_id);
|
||||||
|
if (!hdr_output_use_screen_luminance) {
|
||||||
|
DisplayServer::get_singleton()->window_set_hdr_output_reference_luminance(hdr_output_reference_luminance, window_id);
|
||||||
|
DisplayServer::get_singleton()->window_set_hdr_output_min_luminance(hdr_output_min_luminance, window_id);
|
||||||
|
DisplayServer::get_singleton()->window_set_hdr_output_max_luminance(hdr_output_max_luminance, window_id);
|
||||||
|
}
|
||||||
|
|
||||||
_update_window_size();
|
_update_window_size();
|
||||||
|
|
||||||
if (transient_parent) {
|
if (transient_parent) {
|
||||||
|
|
@ -1395,6 +1525,15 @@ void Window::_notification(int p_what) {
|
||||||
size = DisplayServer::get_singleton()->window_get_size(window_id);
|
size = DisplayServer::get_singleton()->window_get_size(window_id);
|
||||||
focused = DisplayServer::get_singleton()->window_is_focused(window_id);
|
focused = DisplayServer::get_singleton()->window_is_focused(window_id);
|
||||||
}
|
}
|
||||||
|
// Update HDR settings to reflect the current state of the main window.
|
||||||
|
{
|
||||||
|
hdr_output_enabled = DisplayServer::get_singleton()->window_is_hdr_output_enabled(window_id);
|
||||||
|
hdr_output_prefer_high_precision = DisplayServer::get_singleton()->window_is_hdr_output_preferring_high_precision(window_id);
|
||||||
|
hdr_output_use_screen_luminance = DisplayServer::get_singleton()->window_is_hdr_output_using_screen_luminance(window_id);
|
||||||
|
hdr_output_reference_luminance = DisplayServer::get_singleton()->window_get_hdr_output_reference_luminance(window_id);
|
||||||
|
hdr_output_min_luminance = DisplayServer::get_singleton()->window_get_hdr_output_min_luminance(window_id);
|
||||||
|
hdr_output_max_luminance = DisplayServer::get_singleton()->window_get_hdr_output_max_luminance(window_id);
|
||||||
|
}
|
||||||
_update_window_size(); // Inform DisplayServer of minimum and maximum size.
|
_update_window_size(); // Inform DisplayServer of minimum and maximum size.
|
||||||
_update_viewport_size(); // Then feed back to the viewport.
|
_update_viewport_size(); // Then feed back to the viewport.
|
||||||
_update_window_callbacks();
|
_update_window_callbacks();
|
||||||
|
|
@ -2916,6 +3055,24 @@ void Window::_bind_methods() {
|
||||||
ClassDB::bind_method(D_METHOD("set_flag", "flag", "enabled"), &Window::set_flag);
|
ClassDB::bind_method(D_METHOD("set_flag", "flag", "enabled"), &Window::set_flag);
|
||||||
ClassDB::bind_method(D_METHOD("get_flag", "flag"), &Window::get_flag);
|
ClassDB::bind_method(D_METHOD("get_flag", "flag"), &Window::get_flag);
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("set_hdr_output_enabled", "enabled"), &Window::set_hdr_output_enabled);
|
||||||
|
ClassDB::bind_method(D_METHOD("is_hdr_output_enabled"), &Window::is_hdr_output_enabled);
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("set_hdr_output_prefer_high_precision", "enabled"), &Window::set_hdr_output_prefer_high_precision);
|
||||||
|
ClassDB::bind_method(D_METHOD("is_hdr_output_preferring_high_precision"), &Window::is_hdr_output_preferring_high_precision);
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("set_hdr_output_use_screen_luminance", "enabled"), &Window::set_hdr_output_use_screen_luminance);
|
||||||
|
ClassDB::bind_method(D_METHOD("is_hdr_output_using_screen_luminance"), &Window::is_hdr_output_using_screen_luminance);
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("set_hdr_output_reference_luminance", "reference_luminance"), &Window::set_hdr_output_reference_luminance);
|
||||||
|
ClassDB::bind_method(D_METHOD("get_hdr_output_reference_luminance"), &Window::get_hdr_output_reference_luminance);
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("set_hdr_output_min_luminance", "min_luminance"), &Window::set_hdr_output_min_luminance);
|
||||||
|
ClassDB::bind_method(D_METHOD("get_hdr_output_min_luminance"), &Window::get_hdr_output_min_luminance);
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("set_hdr_output_max_luminance", "max_luminance"), &Window::set_hdr_output_max_luminance);
|
||||||
|
ClassDB::bind_method(D_METHOD("get_hdr_output_max_luminance"), &Window::get_hdr_output_max_luminance);
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("is_maximize_allowed"), &Window::is_maximize_allowed);
|
ClassDB::bind_method(D_METHOD("is_maximize_allowed"), &Window::is_maximize_allowed);
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("request_attention"), &Window::request_attention);
|
ClassDB::bind_method(D_METHOD("request_attention"), &Window::request_attention);
|
||||||
|
|
@ -3098,6 +3255,14 @@ void Window::_bind_methods() {
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "content_scale_stretch", PROPERTY_HINT_ENUM, "Fractional,Integer"), "set_content_scale_stretch", "get_content_scale_stretch");
|
ADD_PROPERTY(PropertyInfo(Variant::INT, "content_scale_stretch", PROPERTY_HINT_ENUM, "Fractional,Integer"), "set_content_scale_stretch", "get_content_scale_stretch");
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "content_scale_factor", PROPERTY_HINT_RANGE, "0.5,8.0,0.01"), "set_content_scale_factor", "get_content_scale_factor");
|
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "content_scale_factor", PROPERTY_HINT_RANGE, "0.5,8.0,0.01"), "set_content_scale_factor", "get_content_scale_factor");
|
||||||
|
|
||||||
|
ADD_GROUP("HDR Output", "hdr_output_");
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "hdr_output_enabled"), "set_hdr_output_enabled", "is_hdr_output_enabled");
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "hdr_output_prefer_high_precision"), "set_hdr_output_prefer_high_precision", "is_hdr_output_preferring_high_precision");
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "hdr_output_use_screen_luminance"), "set_hdr_output_use_screen_luminance", "is_hdr_output_using_screen_luminance");
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "hdr_output_reference_luminance", PROPERTY_HINT_RANGE, "0,2000,1,or_greater"), "set_hdr_output_reference_luminance", "get_hdr_output_reference_luminance");
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "hdr_output_min_luminance", PROPERTY_HINT_RANGE, "0,2000,1,or_greater"), "set_hdr_output_min_luminance", "get_hdr_output_min_luminance");
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "hdr_output_max_luminance", PROPERTY_HINT_RANGE, "0,2000,1,or_greater"), "set_hdr_output_max_luminance", "get_hdr_output_max_luminance");
|
||||||
|
|
||||||
#ifndef DISABLE_DEPRECATED
|
#ifndef DISABLE_DEPRECATED
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "auto_translate", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "set_auto_translate", "is_auto_translating");
|
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "auto_translate", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "set_auto_translate", "is_auto_translating");
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -3201,6 +3366,10 @@ Window::Window() {
|
||||||
|
|
||||||
theme_owner = memnew(ThemeOwner(this));
|
theme_owner = memnew(ThemeOwner(this));
|
||||||
RS::get_singleton()->viewport_set_update_mode(get_viewport_rid(), RS::VIEWPORT_UPDATE_DISABLED);
|
RS::get_singleton()->viewport_set_update_mode(get_viewport_rid(), RS::VIEWPORT_UPDATE_DISABLED);
|
||||||
|
|
||||||
|
// Tonemap the root viewport of this window by default.
|
||||||
|
tonemap_to_window = true;
|
||||||
|
RS::get_singleton()->viewport_set_tonemap_to_screen(get_viewport_rid(), tonemap_to_window);
|
||||||
}
|
}
|
||||||
|
|
||||||
Window::~Window() {
|
Window::~Window() {
|
||||||
|
|
|
||||||
|
|
@ -132,6 +132,13 @@ private:
|
||||||
WindowInitialPosition initial_position = WINDOW_INITIAL_POSITION_ABSOLUTE;
|
WindowInitialPosition initial_position = WINDOW_INITIAL_POSITION_ABSOLUTE;
|
||||||
bool force_native = false;
|
bool force_native = false;
|
||||||
|
|
||||||
|
mutable bool hdr_output_enabled = false;
|
||||||
|
mutable bool hdr_output_prefer_high_precision = false;
|
||||||
|
mutable bool hdr_output_use_screen_luminance = false;
|
||||||
|
mutable float hdr_output_reference_luminance = 80.0f;
|
||||||
|
mutable float hdr_output_min_luminance = 0.0f;
|
||||||
|
mutable float hdr_output_max_luminance = 1000.0f;
|
||||||
|
|
||||||
bool use_font_oversampling = false;
|
bool use_font_oversampling = false;
|
||||||
bool transient = false;
|
bool transient = false;
|
||||||
bool transient_to_focused = false;
|
bool transient_to_focused = false;
|
||||||
|
|
@ -311,6 +318,24 @@ public:
|
||||||
void set_flag(Flags p_flag, bool p_enabled);
|
void set_flag(Flags p_flag, bool p_enabled);
|
||||||
bool get_flag(Flags p_flag) const;
|
bool get_flag(Flags p_flag) const;
|
||||||
|
|
||||||
|
void set_hdr_output_enabled(bool p_enabled);
|
||||||
|
bool is_hdr_output_enabled() const;
|
||||||
|
|
||||||
|
void set_hdr_output_prefer_high_precision(bool p_enabled);
|
||||||
|
bool is_hdr_output_preferring_high_precision() const;
|
||||||
|
|
||||||
|
void set_hdr_output_use_screen_luminance(bool p_enabled);
|
||||||
|
bool is_hdr_output_using_screen_luminance() const;
|
||||||
|
|
||||||
|
void set_hdr_output_reference_luminance(float p_reference_luminance);
|
||||||
|
float get_hdr_output_reference_luminance() const;
|
||||||
|
|
||||||
|
void set_hdr_output_min_luminance(float p_min_luminance);
|
||||||
|
float get_hdr_output_min_luminance() const;
|
||||||
|
|
||||||
|
void set_hdr_output_max_luminance(float p_max_luminance);
|
||||||
|
float get_hdr_output_max_luminance() const;
|
||||||
|
|
||||||
bool is_maximize_allowed() const;
|
bool is_maximize_allowed() const;
|
||||||
|
|
||||||
void request_attention();
|
void request_attention();
|
||||||
|
|
|
||||||
|
|
@ -810,6 +810,54 @@ DisplayServer::VSyncMode DisplayServer::window_get_vsync_mode(WindowID p_window)
|
||||||
return VSyncMode::VSYNC_ENABLED;
|
return VSyncMode::VSYNC_ENABLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DisplayServer::window_set_hdr_output_enabled(const bool p_enabled, WindowID p_window) {
|
||||||
|
WARN_PRINT("HDR output is not supported by this display server.");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DisplayServer::window_is_hdr_output_enabled(WindowID p_window) const {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DisplayServer::window_set_hdr_output_prefer_high_precision(const bool p_enabled, WindowID p_window) {
|
||||||
|
WARN_PRINT("HDR output is not supported by this display server.");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DisplayServer::window_is_hdr_output_preferring_high_precision(WindowID p_window) const {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DisplayServer::window_set_hdr_output_use_screen_luminance(const bool p_enabled, WindowID p_window) {
|
||||||
|
WARN_PRINT("HDR output is not supported by this display server.");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DisplayServer::window_is_hdr_output_using_screen_luminance(WindowID p_window) const {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DisplayServer::window_set_hdr_output_reference_luminance(const float p_reference_luminance, WindowID p_window) {
|
||||||
|
WARN_PRINT("HDR output is not supported by this display server.");
|
||||||
|
}
|
||||||
|
|
||||||
|
float DisplayServer::window_get_hdr_output_reference_luminance(WindowID p_window) const {
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DisplayServer::window_set_hdr_output_min_luminance(const float p_min_luminance, WindowID p_window) {
|
||||||
|
WARN_PRINT("HDR output is not supported by this display server.");
|
||||||
|
}
|
||||||
|
|
||||||
|
float DisplayServer::window_get_hdr_output_min_luminance(WindowID p_window) const {
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DisplayServer::window_set_hdr_output_max_luminance(const float p_max_luminance, WindowID p_window) {
|
||||||
|
WARN_PRINT("HDR output is not supported by this display server.");
|
||||||
|
}
|
||||||
|
|
||||||
|
float DisplayServer::window_get_hdr_output_max_luminance(WindowID p_window) const {
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
DisplayServer::WindowID DisplayServer::get_focused_window() const {
|
DisplayServer::WindowID DisplayServer::get_focused_window() const {
|
||||||
return MAIN_WINDOW_ID; // Proper value for single windows.
|
return MAIN_WINDOW_ID; // Proper value for single windows.
|
||||||
}
|
}
|
||||||
|
|
@ -945,6 +993,12 @@ void DisplayServer::_bind_methods() {
|
||||||
ClassDB::bind_method(D_METHOD("screen_get_image", "screen"), &DisplayServer::screen_get_image, DEFVAL(SCREEN_OF_MAIN_WINDOW));
|
ClassDB::bind_method(D_METHOD("screen_get_image", "screen"), &DisplayServer::screen_get_image, DEFVAL(SCREEN_OF_MAIN_WINDOW));
|
||||||
ClassDB::bind_method(D_METHOD("screen_get_image_rect", "rect"), &DisplayServer::screen_get_image_rect);
|
ClassDB::bind_method(D_METHOD("screen_get_image_rect", "rect"), &DisplayServer::screen_get_image_rect);
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("screen_is_hdr_supported", "screen"), &DisplayServer::screen_is_hdr_supported, DEFVAL(SCREEN_OF_MAIN_WINDOW));
|
||||||
|
ClassDB::bind_method(D_METHOD("screen_get_min_luminance", "screen"), &DisplayServer::screen_get_min_luminance, DEFVAL(SCREEN_OF_MAIN_WINDOW));
|
||||||
|
ClassDB::bind_method(D_METHOD("screen_get_max_luminance", "screen"), &DisplayServer::screen_get_max_luminance, DEFVAL(SCREEN_OF_MAIN_WINDOW));
|
||||||
|
ClassDB::bind_method(D_METHOD("screen_get_max_average_luminance", "screen"), &DisplayServer::screen_get_max_average_luminance, DEFVAL(SCREEN_OF_MAIN_WINDOW));
|
||||||
|
ClassDB::bind_method(D_METHOD("screen_get_sdr_white_level", "screen"), &DisplayServer::screen_get_sdr_white_level, DEFVAL(SCREEN_OF_MAIN_WINDOW));
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("screen_set_orientation", "orientation", "screen"), &DisplayServer::screen_set_orientation, DEFVAL(SCREEN_OF_MAIN_WINDOW));
|
ClassDB::bind_method(D_METHOD("screen_set_orientation", "orientation", "screen"), &DisplayServer::screen_set_orientation, DEFVAL(SCREEN_OF_MAIN_WINDOW));
|
||||||
ClassDB::bind_method(D_METHOD("screen_get_orientation", "screen"), &DisplayServer::screen_get_orientation, DEFVAL(SCREEN_OF_MAIN_WINDOW));
|
ClassDB::bind_method(D_METHOD("screen_get_orientation", "screen"), &DisplayServer::screen_get_orientation, DEFVAL(SCREEN_OF_MAIN_WINDOW));
|
||||||
|
|
||||||
|
|
@ -1012,6 +1066,19 @@ void DisplayServer::_bind_methods() {
|
||||||
ClassDB::bind_method(D_METHOD("window_set_vsync_mode", "vsync_mode", "window_id"), &DisplayServer::window_set_vsync_mode, DEFVAL(MAIN_WINDOW_ID));
|
ClassDB::bind_method(D_METHOD("window_set_vsync_mode", "vsync_mode", "window_id"), &DisplayServer::window_set_vsync_mode, DEFVAL(MAIN_WINDOW_ID));
|
||||||
ClassDB::bind_method(D_METHOD("window_get_vsync_mode", "window_id"), &DisplayServer::window_get_vsync_mode, DEFVAL(MAIN_WINDOW_ID));
|
ClassDB::bind_method(D_METHOD("window_get_vsync_mode", "window_id"), &DisplayServer::window_get_vsync_mode, DEFVAL(MAIN_WINDOW_ID));
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("window_set_hdr_output_enabled", "enabled", "window_id"), &DisplayServer::window_set_hdr_output_enabled, DEFVAL(MAIN_WINDOW_ID));
|
||||||
|
ClassDB::bind_method(D_METHOD("window_is_hdr_output_enabled", "window_id"), &DisplayServer::window_is_hdr_output_enabled, DEFVAL(MAIN_WINDOW_ID));
|
||||||
|
ClassDB::bind_method(D_METHOD("window_set_hdr_output_prefer_high_precision", "enabled", "window_id"), &DisplayServer::window_set_hdr_output_prefer_high_precision, DEFVAL(MAIN_WINDOW_ID));
|
||||||
|
ClassDB::bind_method(D_METHOD("window_is_hdr_output_preferring_high_precision", "window_id"), &DisplayServer::window_is_hdr_output_preferring_high_precision, DEFVAL(MAIN_WINDOW_ID));
|
||||||
|
ClassDB::bind_method(D_METHOD("window_set_hdr_output_use_screen_luminance", "enabled", "window_id"), &DisplayServer::window_set_hdr_output_use_screen_luminance, DEFVAL(MAIN_WINDOW_ID));
|
||||||
|
ClassDB::bind_method(D_METHOD("window_is_hdr_output_using_screen_luminance", "window_id"), &DisplayServer::window_is_hdr_output_using_screen_luminance, DEFVAL(MAIN_WINDOW_ID));
|
||||||
|
ClassDB::bind_method(D_METHOD("window_set_hdr_output_reference_luminance", "reference_luminance", "window_id"), &DisplayServer::window_set_hdr_output_reference_luminance, DEFVAL(MAIN_WINDOW_ID));
|
||||||
|
ClassDB::bind_method(D_METHOD("window_get_hdr_output_reference_luminance", "window_id"), &DisplayServer::window_get_hdr_output_reference_luminance, DEFVAL(MAIN_WINDOW_ID));
|
||||||
|
ClassDB::bind_method(D_METHOD("window_set_hdr_output_min_luminance", "min_luminance", "window_id"), &DisplayServer::window_set_hdr_output_min_luminance, DEFVAL(MAIN_WINDOW_ID));
|
||||||
|
ClassDB::bind_method(D_METHOD("window_get_hdr_output_min_luminance", "window_id"), &DisplayServer::window_get_hdr_output_min_luminance, DEFVAL(MAIN_WINDOW_ID));
|
||||||
|
ClassDB::bind_method(D_METHOD("window_set_hdr_output_max_luminance", "max_luminance", "window_id"), &DisplayServer::window_set_hdr_output_max_luminance, DEFVAL(MAIN_WINDOW_ID));
|
||||||
|
ClassDB::bind_method(D_METHOD("window_get_hdr_output_max_luminance", "window_id"), &DisplayServer::window_get_hdr_output_max_luminance, DEFVAL(MAIN_WINDOW_ID));
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("window_is_maximize_allowed", "window_id"), &DisplayServer::window_is_maximize_allowed, DEFVAL(MAIN_WINDOW_ID));
|
ClassDB::bind_method(D_METHOD("window_is_maximize_allowed", "window_id"), &DisplayServer::window_is_maximize_allowed, DEFVAL(MAIN_WINDOW_ID));
|
||||||
ClassDB::bind_method(D_METHOD("window_maximize_on_title_dbl_click"), &DisplayServer::window_maximize_on_title_dbl_click);
|
ClassDB::bind_method(D_METHOD("window_maximize_on_title_dbl_click"), &DisplayServer::window_maximize_on_title_dbl_click);
|
||||||
ClassDB::bind_method(D_METHOD("window_minimize_on_title_dbl_click"), &DisplayServer::window_minimize_on_title_dbl_click);
|
ClassDB::bind_method(D_METHOD("window_minimize_on_title_dbl_click"), &DisplayServer::window_minimize_on_title_dbl_click);
|
||||||
|
|
@ -1113,6 +1180,7 @@ void DisplayServer::_bind_methods() {
|
||||||
BIND_ENUM_CONSTANT(FEATURE_WINDOW_EMBEDDING);
|
BIND_ENUM_CONSTANT(FEATURE_WINDOW_EMBEDDING);
|
||||||
BIND_ENUM_CONSTANT(FEATURE_NATIVE_DIALOG_FILE_MIME);
|
BIND_ENUM_CONSTANT(FEATURE_NATIVE_DIALOG_FILE_MIME);
|
||||||
BIND_ENUM_CONSTANT(FEATURE_EMOJI_AND_SYMBOL_PICKER);
|
BIND_ENUM_CONSTANT(FEATURE_EMOJI_AND_SYMBOL_PICKER);
|
||||||
|
BIND_ENUM_CONSTANT(FEATURE_HDR);
|
||||||
|
|
||||||
BIND_ENUM_CONSTANT(MOUSE_MODE_VISIBLE);
|
BIND_ENUM_CONSTANT(MOUSE_MODE_VISIBLE);
|
||||||
BIND_ENUM_CONSTANT(MOUSE_MODE_HIDDEN);
|
BIND_ENUM_CONSTANT(MOUSE_MODE_HIDDEN);
|
||||||
|
|
|
||||||
|
|
@ -162,6 +162,7 @@ public:
|
||||||
FEATURE_WINDOW_EMBEDDING,
|
FEATURE_WINDOW_EMBEDDING,
|
||||||
FEATURE_NATIVE_DIALOG_FILE_MIME,
|
FEATURE_NATIVE_DIALOG_FILE_MIME,
|
||||||
FEATURE_EMOJI_AND_SYMBOL_PICKER,
|
FEATURE_EMOJI_AND_SYMBOL_PICKER,
|
||||||
|
FEATURE_HDR,
|
||||||
};
|
};
|
||||||
|
|
||||||
virtual bool has_feature(Feature p_feature) const = 0;
|
virtual bool has_feature(Feature p_feature) const = 0;
|
||||||
|
|
@ -362,6 +363,13 @@ public:
|
||||||
virtual Ref<Image> screen_get_image_rect(const Rect2i &p_rect) const { return Ref<Image>(); }
|
virtual Ref<Image> screen_get_image_rect(const Rect2i &p_rect) const { return Ref<Image>(); }
|
||||||
virtual bool is_touchscreen_available() const;
|
virtual bool is_touchscreen_available() const;
|
||||||
|
|
||||||
|
// Display capabilities for HDR.
|
||||||
|
virtual bool screen_is_hdr_supported(int p_screen = SCREEN_OF_MAIN_WINDOW) const { return false; }
|
||||||
|
virtual float screen_get_min_luminance(int p_screen = SCREEN_OF_MAIN_WINDOW) const { return 0.0f; }
|
||||||
|
virtual float screen_get_max_luminance(int p_screen = SCREEN_OF_MAIN_WINDOW) const { return 0.0f; }
|
||||||
|
virtual float screen_get_max_average_luminance(int p_screen = SCREEN_OF_MAIN_WINDOW) const { return 0.0f; }
|
||||||
|
virtual float screen_get_sdr_white_level(int p_screen = SCREEN_OF_MAIN_WINDOW) const { return 0.0f; }
|
||||||
|
|
||||||
// Keep the ScreenOrientation enum values in sync with the `display/window/handheld/orientation`
|
// Keep the ScreenOrientation enum values in sync with the `display/window/handheld/orientation`
|
||||||
// project setting hint.
|
// project setting hint.
|
||||||
enum ScreenOrientation {
|
enum ScreenOrientation {
|
||||||
|
|
@ -483,6 +491,19 @@ public:
|
||||||
virtual void window_set_vsync_mode(VSyncMode p_vsync_mode, WindowID p_window = MAIN_WINDOW_ID);
|
virtual void window_set_vsync_mode(VSyncMode p_vsync_mode, WindowID p_window = MAIN_WINDOW_ID);
|
||||||
virtual VSyncMode window_get_vsync_mode(WindowID p_window) const;
|
virtual VSyncMode window_get_vsync_mode(WindowID p_window) const;
|
||||||
|
|
||||||
|
virtual void window_set_hdr_output_enabled(const bool p_enabled, WindowID p_window = MAIN_WINDOW_ID);
|
||||||
|
virtual bool window_is_hdr_output_enabled(WindowID p_window = MAIN_WINDOW_ID) const;
|
||||||
|
virtual void window_set_hdr_output_prefer_high_precision(const bool p_enabled, WindowID p_window = MAIN_WINDOW_ID);
|
||||||
|
virtual bool window_is_hdr_output_preferring_high_precision(WindowID p_window = MAIN_WINDOW_ID) const;
|
||||||
|
virtual void window_set_hdr_output_use_screen_luminance(const bool p_enabled, WindowID p_window = MAIN_WINDOW_ID);
|
||||||
|
virtual bool window_is_hdr_output_using_screen_luminance(WindowID p_window = MAIN_WINDOW_ID) const;
|
||||||
|
virtual void window_set_hdr_output_reference_luminance(const float p_reference_luminance, WindowID p_window = MAIN_WINDOW_ID);
|
||||||
|
virtual float window_get_hdr_output_reference_luminance(WindowID p_window = MAIN_WINDOW_ID) const;
|
||||||
|
virtual void window_set_hdr_output_min_luminance(const float p_min_luminance, WindowID p_window = MAIN_WINDOW_ID);
|
||||||
|
virtual float window_get_hdr_output_min_luminance(WindowID p_window = MAIN_WINDOW_ID) const;
|
||||||
|
virtual void window_set_hdr_output_max_luminance(const float p_max_luminance, WindowID p_window = MAIN_WINDOW_ID);
|
||||||
|
virtual float window_get_hdr_output_max_luminance(WindowID p_window = MAIN_WINDOW_ID) const;
|
||||||
|
|
||||||
virtual bool window_is_maximize_allowed(WindowID p_window = MAIN_WINDOW_ID) const = 0;
|
virtual bool window_is_maximize_allowed(WindowID p_window = MAIN_WINDOW_ID) const = 0;
|
||||||
|
|
||||||
virtual void window_set_flag(WindowFlags p_flag, bool p_enabled, WindowID p_window = MAIN_WINDOW_ID) = 0;
|
virtual void window_set_flag(WindowFlags p_flag, bool p_enabled, WindowID p_window = MAIN_WINDOW_ID) = 0;
|
||||||
|
|
|
||||||
|
|
@ -120,6 +120,13 @@ void ToneMapper::tonemapper(RID p_source_color, RID p_dst_framebuffer, const Ton
|
||||||
tonemap.push_constant.auto_exposure_scale = p_settings.auto_exposure_scale;
|
tonemap.push_constant.auto_exposure_scale = p_settings.auto_exposure_scale;
|
||||||
tonemap.push_constant.luminance_multiplier = p_settings.luminance_multiplier;
|
tonemap.push_constant.luminance_multiplier = p_settings.luminance_multiplier;
|
||||||
|
|
||||||
|
// Static values that work well in most cases
|
||||||
|
// Consider reading from the scene itself in the future.
|
||||||
|
tonemap.push_constant.source_min_value = 0.0f;
|
||||||
|
tonemap.push_constant.source_max_value = 16.0f;
|
||||||
|
tonemap.push_constant.dest_min_value = p_settings.min_value;
|
||||||
|
tonemap.push_constant.dest_max_value = p_settings.max_value;
|
||||||
|
|
||||||
tonemap.push_constant.flags |= p_settings.use_color_correction ? TONEMAP_FLAG_USE_COLOR_CORRECTION : 0;
|
tonemap.push_constant.flags |= p_settings.use_color_correction ? TONEMAP_FLAG_USE_COLOR_CORRECTION : 0;
|
||||||
|
|
||||||
tonemap.push_constant.flags |= p_settings.use_fxaa ? TONEMAP_FLAG_USE_FXAA : 0;
|
tonemap.push_constant.flags |= p_settings.use_fxaa ? TONEMAP_FLAG_USE_FXAA : 0;
|
||||||
|
|
@ -206,6 +213,13 @@ void ToneMapper::tonemapper(RD::DrawListID p_subpass_draw_list, RID p_source_col
|
||||||
tonemap.push_constant.white = p_settings.white;
|
tonemap.push_constant.white = p_settings.white;
|
||||||
tonemap.push_constant.auto_exposure_scale = p_settings.auto_exposure_scale;
|
tonemap.push_constant.auto_exposure_scale = p_settings.auto_exposure_scale;
|
||||||
|
|
||||||
|
// Static values that work well in most cases
|
||||||
|
// Consider reading from the scene itself in the future.
|
||||||
|
tonemap.push_constant.source_min_value = 0.0f;
|
||||||
|
tonemap.push_constant.source_max_value = 16.0f;
|
||||||
|
tonemap.push_constant.dest_min_value = p_settings.min_value;
|
||||||
|
tonemap.push_constant.dest_max_value = p_settings.max_value;
|
||||||
|
|
||||||
tonemap.push_constant.flags |= p_settings.use_color_correction ? TONEMAP_FLAG_USE_COLOR_CORRECTION : 0;
|
tonemap.push_constant.flags |= p_settings.use_color_correction ? TONEMAP_FLAG_USE_COLOR_CORRECTION : 0;
|
||||||
|
|
||||||
tonemap.push_constant.flags |= p_settings.use_debanding ? TONEMAP_FLAG_USE_DEBANDING : 0;
|
tonemap.push_constant.flags |= p_settings.use_debanding ? TONEMAP_FLAG_USE_DEBANDING : 0;
|
||||||
|
|
|
||||||
|
|
@ -87,6 +87,11 @@ private:
|
||||||
float white; // 4 - 88
|
float white; // 4 - 88
|
||||||
float auto_exposure_scale; // 4 - 92
|
float auto_exposure_scale; // 4 - 92
|
||||||
float luminance_multiplier; // 4 - 96
|
float luminance_multiplier; // 4 - 96
|
||||||
|
|
||||||
|
float source_min_value; // 4 - 100
|
||||||
|
float source_max_value; // 4 - 104
|
||||||
|
float dest_min_value; // 4 - 108
|
||||||
|
float dest_max_value; // 4 - 112
|
||||||
};
|
};
|
||||||
|
|
||||||
/* tonemap actually writes to a framebuffer, which is
|
/* tonemap actually writes to a framebuffer, which is
|
||||||
|
|
@ -126,6 +131,8 @@ public:
|
||||||
RS::EnvironmentToneMapper tonemap_mode = RS::ENV_TONE_MAPPER_LINEAR;
|
RS::EnvironmentToneMapper tonemap_mode = RS::ENV_TONE_MAPPER_LINEAR;
|
||||||
float exposure = 1.0;
|
float exposure = 1.0;
|
||||||
float white = 1.0;
|
float white = 1.0;
|
||||||
|
float min_value = 0.0;
|
||||||
|
float max_value = 1.0;
|
||||||
|
|
||||||
bool use_auto_exposure = false;
|
bool use_auto_exposure = false;
|
||||||
float auto_exposure_scale = 0.5;
|
float auto_exposure_scale = 0.5;
|
||||||
|
|
|
||||||
|
|
@ -43,9 +43,15 @@ void RendererCompositorRD::blit_render_targets_to_screen(DisplayServer::WindowID
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_ensure_blit_pipelines();
|
||||||
|
|
||||||
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin_for_screen(p_screen);
|
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin_for_screen(p_screen);
|
||||||
ERR_FAIL_COND(draw_list == RD::INVALID_ID);
|
ERR_FAIL_COND(draw_list == RD::INVALID_ID);
|
||||||
|
|
||||||
|
const RD::ColorSpace color_space = RD::get_singleton()->screen_get_color_space(p_screen);
|
||||||
|
const float reference_luminance = RD::get_singleton()->get_context_driver()->window_get_hdr_output_reference_luminance(p_screen);
|
||||||
|
const float reference_multiplier = _compute_reference_multiplier(color_space, reference_luminance);
|
||||||
|
|
||||||
for (int i = 0; i < p_amount; i++) {
|
for (int i = 0; i < p_amount; i++) {
|
||||||
RID rd_texture = texture_storage->render_target_get_rd_texture(p_render_targets[i].render_target);
|
RID rd_texture = texture_storage->render_target_get_rd_texture(p_render_targets[i].render_target);
|
||||||
ERR_CONTINUE(rd_texture.is_null());
|
ERR_CONTINUE(rd_texture.is_null());
|
||||||
|
|
@ -65,6 +71,7 @@ void RendererCompositorRD::blit_render_targets_to_screen(DisplayServer::WindowID
|
||||||
|
|
||||||
Size2 screen_size(RD::get_singleton()->screen_get_width(p_screen), RD::get_singleton()->screen_get_height(p_screen));
|
Size2 screen_size(RD::get_singleton()->screen_get_width(p_screen), RD::get_singleton()->screen_get_height(p_screen));
|
||||||
BlitMode mode = p_render_targets[i].lens_distortion.apply ? BLIT_MODE_LENS : (p_render_targets[i].multi_view.use_layer ? BLIT_MODE_USE_LAYER : BLIT_MODE_NORMAL);
|
BlitMode mode = p_render_targets[i].lens_distortion.apply ? BLIT_MODE_LENS : (p_render_targets[i].multi_view.use_layer ? BLIT_MODE_USE_LAYER : BLIT_MODE_NORMAL);
|
||||||
|
|
||||||
RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, blit.pipelines[mode]);
|
RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, blit.pipelines[mode]);
|
||||||
RD::get_singleton()->draw_list_bind_index_array(draw_list, blit.array);
|
RD::get_singleton()->draw_list_bind_index_array(draw_list, blit.array);
|
||||||
RD::get_singleton()->draw_list_bind_uniform_set(draw_list, render_target_descriptors[rd_texture], 0);
|
RD::get_singleton()->draw_list_bind_uniform_set(draw_list, render_target_descriptors[rd_texture], 0);
|
||||||
|
|
@ -94,7 +101,9 @@ void RendererCompositorRD::blit_render_targets_to_screen(DisplayServer::WindowID
|
||||||
blit.push_constant.k2 = p_render_targets[i].lens_distortion.k2;
|
blit.push_constant.k2 = p_render_targets[i].lens_distortion.k2;
|
||||||
blit.push_constant.upscale = p_render_targets[i].lens_distortion.upscale;
|
blit.push_constant.upscale = p_render_targets[i].lens_distortion.upscale;
|
||||||
blit.push_constant.aspect_ratio = p_render_targets[i].lens_distortion.aspect_ratio;
|
blit.push_constant.aspect_ratio = p_render_targets[i].lens_distortion.aspect_ratio;
|
||||||
blit.push_constant.convert_to_srgb = texture_storage->render_target_is_using_hdr(p_render_targets[i].render_target);
|
blit.push_constant.source_is_srgb = !texture_storage->render_target_is_using_hdr(p_render_targets[i].render_target);
|
||||||
|
blit.push_constant.target_color_space = color_space;
|
||||||
|
blit.push_constant.reference_multiplier = reference_multiplier;
|
||||||
|
|
||||||
RD::get_singleton()->draw_list_set_push_constant(draw_list, &blit.push_constant, sizeof(BlitPushConstant));
|
RD::get_singleton()->draw_list_set_push_constant(draw_list, &blit.push_constant, sizeof(BlitPushConstant));
|
||||||
RD::get_singleton()->draw_list_draw(draw_list, true);
|
RD::get_singleton()->draw_list_draw(draw_list, true);
|
||||||
|
|
@ -129,16 +138,8 @@ void RendererCompositorRD::initialize() {
|
||||||
blit_modes.push_back("\n");
|
blit_modes.push_back("\n");
|
||||||
|
|
||||||
blit.shader.initialize(blit_modes);
|
blit.shader.initialize(blit_modes);
|
||||||
|
|
||||||
blit.shader_version = blit.shader.version_create();
|
blit.shader_version = blit.shader.version_create();
|
||||||
|
|
||||||
for (int i = 0; i < BLIT_MODE_MAX; i++) {
|
|
||||||
blit.pipelines[i] = RD::get_singleton()->render_pipeline_create(blit.shader.version_get_shader(blit.shader_version, i), RD::get_singleton()->screen_get_framebuffer_format(DisplayServer::MAIN_WINDOW_ID), RD::INVALID_ID, RD::RENDER_PRIMITIVE_TRIANGLES, RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), RD::PipelineDepthStencilState(), i == BLIT_MODE_NORMAL_ALPHA ? RenderingDevice::PipelineColorBlendState::create_blend() : RenderingDevice::PipelineColorBlendState::create_disabled(), 0);
|
|
||||||
|
|
||||||
// Unload shader modules to save memory.
|
|
||||||
RD::get_singleton()->shader_destroy_modules(blit.shader.version_get_shader(blit.shader_version, i));
|
|
||||||
}
|
|
||||||
|
|
||||||
//create index array for copy shader
|
//create index array for copy shader
|
||||||
Vector<uint8_t> pv;
|
Vector<uint8_t> pv;
|
||||||
pv.resize(6 * 2);
|
pv.resize(6 * 2);
|
||||||
|
|
@ -178,6 +179,39 @@ void RendererCompositorRD::finalize() {
|
||||||
RD::get_singleton()->free(blit.sampler);
|
RD::get_singleton()->free(blit.sampler);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RendererCompositorRD::_ensure_blit_pipelines() {
|
||||||
|
RenderingDevice::FramebufferFormatID main_window_format = RD::get_singleton()->screen_get_framebuffer_format(DisplayServer::MAIN_WINDOW_ID);
|
||||||
|
if (main_window_format != prev_main_window_format) {
|
||||||
|
for (int i = 0; i < BLIT_MODE_MAX; i++) {
|
||||||
|
if (blit.pipelines[i].is_valid()) {
|
||||||
|
RD::get_singleton()->free(blit.pipelines[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
blit.pipelines[i] = RD::get_singleton()->render_pipeline_create(blit.shader.version_get_shader(blit.shader_version, i), main_window_format, RD::INVALID_ID, RD::RENDER_PRIMITIVE_TRIANGLES, RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), RD::PipelineDepthStencilState(), i == BLIT_MODE_NORMAL_ALPHA ? RenderingDevice::PipelineColorBlendState::create_blend() : RenderingDevice::PipelineColorBlendState::create_disabled(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
prev_main_window_format = main_window_format;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
float RendererCompositorRD::_compute_reference_multiplier(RD::ColorSpace p_color_space, const float p_reference_luminance) {
|
||||||
|
switch (p_color_space) {
|
||||||
|
case RD::COLOR_SPACE_HDR10_ST2084:
|
||||||
|
// Max brightness of ST2084 is 10000 nits, we output from 0 to 1.
|
||||||
|
return p_reference_luminance / 10000.0f;
|
||||||
|
case RD::COLOR_SPACE_SRGB_LINEAR:
|
||||||
|
#ifdef WINDOWS_ENABLED
|
||||||
|
// Windows expects multiples of 80 nits.
|
||||||
|
return p_reference_luminance / 80.0f;
|
||||||
|
#else
|
||||||
|
// Default to 100 nits.
|
||||||
|
return p_reference_luminance / 100.0f;
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
return 1.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void RendererCompositorRD::set_boot_image(const Ref<Image> &p_image, const Color &p_color, bool p_scale, bool p_use_filter) {
|
void RendererCompositorRD::set_boot_image(const Ref<Image> &p_image, const Color &p_color, bool p_scale, bool p_use_filter) {
|
||||||
if (p_image.is_null() || p_image->is_empty()) {
|
if (p_image.is_null() || p_image->is_empty()) {
|
||||||
return;
|
return;
|
||||||
|
|
@ -189,6 +223,8 @@ void RendererCompositorRD::set_boot_image(const Ref<Image> &p_image, const Color
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_ensure_blit_pipelines();
|
||||||
|
|
||||||
RID texture = texture_storage->texture_allocate();
|
RID texture = texture_storage->texture_allocate();
|
||||||
texture_storage->texture_2d_initialize(texture, p_image);
|
texture_storage->texture_2d_initialize(texture, p_image);
|
||||||
RID rd_texture = texture_storage->texture_get_rd_texture(texture, false);
|
RID rd_texture = texture_storage->texture_get_rd_texture(texture, false);
|
||||||
|
|
@ -225,6 +261,10 @@ void RendererCompositorRD::set_boot_image(const Ref<Image> &p_image, const Color
|
||||||
screenrect.position /= window_size;
|
screenrect.position /= window_size;
|
||||||
screenrect.size /= window_size;
|
screenrect.size /= window_size;
|
||||||
|
|
||||||
|
const RD::ColorSpace color_space = RD::get_singleton()->screen_get_color_space(DisplayServer::MAIN_WINDOW_ID);
|
||||||
|
const float reference_luminance = RD::get_singleton()->get_context_driver()->window_get_hdr_output_reference_luminance(DisplayServer::MAIN_WINDOW_ID);
|
||||||
|
const float reference_multiplier = _compute_reference_multiplier(color_space, reference_luminance);
|
||||||
|
|
||||||
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin_for_screen(DisplayServer::MAIN_WINDOW_ID, p_color);
|
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin_for_screen(DisplayServer::MAIN_WINDOW_ID, p_color);
|
||||||
|
|
||||||
RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, blit.pipelines[BLIT_MODE_NORMAL_ALPHA]);
|
RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, blit.pipelines[BLIT_MODE_NORMAL_ALPHA]);
|
||||||
|
|
@ -250,7 +290,9 @@ void RendererCompositorRD::set_boot_image(const Ref<Image> &p_image, const Color
|
||||||
blit.push_constant.k2 = 0;
|
blit.push_constant.k2 = 0;
|
||||||
blit.push_constant.upscale = 1.0;
|
blit.push_constant.upscale = 1.0;
|
||||||
blit.push_constant.aspect_ratio = 1.0;
|
blit.push_constant.aspect_ratio = 1.0;
|
||||||
blit.push_constant.convert_to_srgb = false;
|
blit.push_constant.source_is_srgb = true;
|
||||||
|
blit.push_constant.target_color_space = color_space;
|
||||||
|
blit.push_constant.reference_multiplier = reference_multiplier;
|
||||||
|
|
||||||
RD::get_singleton()->draw_list_set_push_constant(draw_list, &blit.push_constant, sizeof(BlitPushConstant));
|
RD::get_singleton()->draw_list_set_push_constant(draw_list, &blit.push_constant, sizeof(BlitPushConstant));
|
||||||
RD::get_singleton()->draw_list_draw(draw_list, true);
|
RD::get_singleton()->draw_list_draw(draw_list, true);
|
||||||
|
|
|
||||||
|
|
@ -69,21 +69,23 @@ protected:
|
||||||
};
|
};
|
||||||
|
|
||||||
struct BlitPushConstant {
|
struct BlitPushConstant {
|
||||||
float src_rect[4];
|
float src_rect[4]; // 16 - 16
|
||||||
float dst_rect[4];
|
float dst_rect[4]; // 16 - 32
|
||||||
|
|
||||||
float rotation_sin;
|
float rotation_sin; // 4 - 36
|
||||||
float rotation_cos;
|
float rotation_cos; // 4 - 40
|
||||||
float pad[2];
|
|
||||||
|
|
||||||
float eye_center[2];
|
float eye_center[2]; // 8 - 48
|
||||||
float k1;
|
float k1; // 4 - 52
|
||||||
float k2;
|
float k2; // 4 - 56
|
||||||
|
|
||||||
float upscale;
|
float upscale; // 4 - 60
|
||||||
float aspect_ratio;
|
float aspect_ratio; // 4 - 64
|
||||||
uint32_t layer;
|
uint32_t layer; // 4 - 68
|
||||||
uint32_t convert_to_srgb;
|
uint32_t source_is_srgb; // 4 - 72
|
||||||
|
|
||||||
|
uint32_t target_color_space; // 4 - 76
|
||||||
|
float reference_multiplier; // 4 - 80
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Blit {
|
struct Blit {
|
||||||
|
|
@ -104,6 +106,10 @@ protected:
|
||||||
static uint64_t frame;
|
static uint64_t frame;
|
||||||
static RendererCompositorRD *singleton;
|
static RendererCompositorRD *singleton;
|
||||||
|
|
||||||
|
RenderingDevice::FramebufferFormatID prev_main_window_format;
|
||||||
|
void _ensure_blit_pipelines();
|
||||||
|
float _compute_reference_multiplier(RD::ColorSpace p_color_space, const float p_reference_luminance);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
RendererUtilities *get_utilities() { return utilities; }
|
RendererUtilities *get_utilities() { return utilities; }
|
||||||
RendererLightStorage *get_light_storage() { return light_storage; }
|
RendererLightStorage *get_light_storage() { return light_storage; }
|
||||||
|
|
|
||||||
|
|
@ -630,6 +630,8 @@ void RendererSceneRenderRD::_render_buffers_post_process_and_tonemap(const Rende
|
||||||
tonemap.tonemap_mode = environment_get_tone_mapper(p_render_data->environment);
|
tonemap.tonemap_mode = environment_get_tone_mapper(p_render_data->environment);
|
||||||
tonemap.white = environment_get_white(p_render_data->environment);
|
tonemap.white = environment_get_white(p_render_data->environment);
|
||||||
tonemap.exposure = environment_get_exposure(p_render_data->environment);
|
tonemap.exposure = environment_get_exposure(p_render_data->environment);
|
||||||
|
tonemap.min_value = environment_get_min_value(p_render_data->environment);
|
||||||
|
tonemap.max_value = environment_get_max_value(p_render_data->environment);
|
||||||
}
|
}
|
||||||
|
|
||||||
tonemap.use_color_correction = false;
|
tonemap.use_color_correction = false;
|
||||||
|
|
@ -724,6 +726,8 @@ void RendererSceneRenderRD::_post_process_subpass(RID p_source_texture, RID p_fr
|
||||||
tonemap.tonemap_mode = environment_get_tone_mapper(p_render_data->environment);
|
tonemap.tonemap_mode = environment_get_tone_mapper(p_render_data->environment);
|
||||||
tonemap.exposure = environment_get_exposure(p_render_data->environment);
|
tonemap.exposure = environment_get_exposure(p_render_data->environment);
|
||||||
tonemap.white = environment_get_white(p_render_data->environment);
|
tonemap.white = environment_get_white(p_render_data->environment);
|
||||||
|
tonemap.min_value = environment_get_min_value(p_render_data->environment);
|
||||||
|
tonemap.max_value = environment_get_max_value(p_render_data->environment);
|
||||||
}
|
}
|
||||||
|
|
||||||
// We don't support glow or auto exposure here, if they are needed, don't use subpasses!
|
// We don't support glow or auto exposure here, if they are needed, don't use subpasses!
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,6 @@ layout(push_constant, std140) uniform Pos {
|
||||||
|
|
||||||
float rotation_sin;
|
float rotation_sin;
|
||||||
float rotation_cos;
|
float rotation_cos;
|
||||||
vec2 pad;
|
|
||||||
|
|
||||||
vec2 eye_center;
|
vec2 eye_center;
|
||||||
float k1;
|
float k1;
|
||||||
|
|
@ -19,7 +18,10 @@ layout(push_constant, std140) uniform Pos {
|
||||||
float upscale;
|
float upscale;
|
||||||
float aspect_ratio;
|
float aspect_ratio;
|
||||||
uint layer;
|
uint layer;
|
||||||
bool convert_to_srgb;
|
bool source_is_srgb;
|
||||||
|
|
||||||
|
uint target_color_space;
|
||||||
|
float reference_multiplier;
|
||||||
}
|
}
|
||||||
data;
|
data;
|
||||||
|
|
||||||
|
|
@ -50,7 +52,6 @@ layout(push_constant, std140) uniform Pos {
|
||||||
|
|
||||||
float rotation_sin;
|
float rotation_sin;
|
||||||
float rotation_cos;
|
float rotation_cos;
|
||||||
vec2 pad;
|
|
||||||
|
|
||||||
vec2 eye_center;
|
vec2 eye_center;
|
||||||
float k1;
|
float k1;
|
||||||
|
|
@ -59,7 +60,10 @@ layout(push_constant, std140) uniform Pos {
|
||||||
float upscale;
|
float upscale;
|
||||||
float aspect_ratio;
|
float aspect_ratio;
|
||||||
uint layer;
|
uint layer;
|
||||||
bool convert_to_srgb;
|
bool source_is_srgb;
|
||||||
|
|
||||||
|
uint target_color_space;
|
||||||
|
float reference_multiplier;
|
||||||
}
|
}
|
||||||
data;
|
data;
|
||||||
|
|
||||||
|
|
@ -73,6 +77,15 @@ layout(binding = 0) uniform sampler2DArray src_rt;
|
||||||
layout(binding = 0) uniform sampler2D src_rt;
|
layout(binding = 0) uniform sampler2D src_rt;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Keep in sync with RenderingDeviceCommons::ColorSpace
|
||||||
|
#define COLOR_SPACE_SRGB_LINEAR 0
|
||||||
|
#define COLOR_SPACE_SRGB_NONLINEAR 1
|
||||||
|
#define COLOR_SPACE_HDR10_ST2084 2
|
||||||
|
|
||||||
|
vec3 srgb_to_linear(vec3 color) {
|
||||||
|
return mix(pow((color.rgb + vec3(0.055)) * (1.0 / (1.0 + 0.055)), vec3(2.4)), color.rgb * (1.0 / 12.92), lessThan(color.rgb, vec3(0.04045)));
|
||||||
|
}
|
||||||
|
|
||||||
vec3 linear_to_srgb(vec3 color) {
|
vec3 linear_to_srgb(vec3 color) {
|
||||||
// If going to srgb, clamp from 0 to 1.
|
// If going to srgb, clamp from 0 to 1.
|
||||||
color = clamp(color, vec3(0.0), vec3(1.0));
|
color = clamp(color, vec3(0.0), vec3(1.0));
|
||||||
|
|
@ -80,6 +93,29 @@ vec3 linear_to_srgb(vec3 color) {
|
||||||
return mix((vec3(1.0f) + a) * pow(color.rgb, vec3(1.0f / 2.4f)) - a, 12.92f * color.rgb, lessThan(color.rgb, vec3(0.0031308f)));
|
return mix((vec3(1.0f) + a) * pow(color.rgb, vec3(1.0f / 2.4f)) - a, 12.92f * color.rgb, lessThan(color.rgb, vec3(0.0031308f)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vec3 rec709_to_rec2020(vec3 color) {
|
||||||
|
const mat3 conversion = mat3(
|
||||||
|
0.627402, 0.069095, 0.016394,
|
||||||
|
0.329292, 0.919544, 0.088028,
|
||||||
|
0.043306, 0.011360, 0.895578);
|
||||||
|
return conversion * color;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 linear_to_st2084(vec3 color) {
|
||||||
|
// Linear color should already be adjusted between 0 and 10,000 nits.
|
||||||
|
color = clamp(color, vec3(0.0), vec3(1.0));
|
||||||
|
|
||||||
|
// Apply ST2084 curve
|
||||||
|
const float c1 = 0.8359375;
|
||||||
|
const float c2 = 18.8515625;
|
||||||
|
const float c3 = 18.6875;
|
||||||
|
const float m1 = 0.1593017578125;
|
||||||
|
const float m2 = 78.84375;
|
||||||
|
vec3 cp = pow(abs(color), vec3(m1));
|
||||||
|
|
||||||
|
return pow((c1 + c2 * cp) / (1 + c3 * cp), vec3(m2));
|
||||||
|
}
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
#ifdef APPLY_LENS_DISTORTION
|
#ifdef APPLY_LENS_DISTORTION
|
||||||
vec2 coords = uv * 2.0 - 1.0;
|
vec2 coords = uv * 2.0 - 1.0;
|
||||||
|
|
@ -116,7 +152,33 @@ void main() {
|
||||||
color = texture(src_rt, uv);
|
color = texture(src_rt, uv);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (data.convert_to_srgb) {
|
// Colorspace conversion for final blit
|
||||||
color.rgb = linear_to_srgb(color.rgb); // Regular linear -> SRGB conversion.
|
if (data.target_color_space == COLOR_SPACE_SRGB_LINEAR) {
|
||||||
|
if (data.source_is_srgb == true) {
|
||||||
|
// sRGB -> linear conversion
|
||||||
|
color.rgb = srgb_to_linear(color.rgb);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Adjust brightness of SDR content to reference luminance
|
||||||
|
color.rgb *= data.reference_multiplier;
|
||||||
|
} else if (data.target_color_space == COLOR_SPACE_SRGB_NONLINEAR) {
|
||||||
|
if (data.source_is_srgb == false) {
|
||||||
|
// linear -> sRGB conversion
|
||||||
|
color.rgb = linear_to_srgb(color.rgb);
|
||||||
|
}
|
||||||
|
} else if (data.target_color_space == COLOR_SPACE_HDR10_ST2084) {
|
||||||
|
if (data.source_is_srgb == true) {
|
||||||
|
// sRGB -> linear conversion
|
||||||
|
color.rgb = srgb_to_linear(color.rgb);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert to Rec.2020 primaries
|
||||||
|
color.rgb = rec709_to_rec2020(color.rgb);
|
||||||
|
|
||||||
|
// Adjust brightness of SDR content to reference luminance
|
||||||
|
color.rgb *= data.reference_multiplier;
|
||||||
|
|
||||||
|
// Apply the ST2084 curve
|
||||||
|
color.rgb = linear_to_st2084(color.rgb);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -97,6 +97,11 @@ layout(push_constant, std430) uniform Params {
|
||||||
float white;
|
float white;
|
||||||
float auto_exposure_scale;
|
float auto_exposure_scale;
|
||||||
float luminance_multiplier;
|
float luminance_multiplier;
|
||||||
|
|
||||||
|
float source_min_value;
|
||||||
|
float source_max_value;
|
||||||
|
float dest_min_value;
|
||||||
|
float dest_max_value;
|
||||||
}
|
}
|
||||||
params;
|
params;
|
||||||
|
|
||||||
|
|
@ -344,6 +349,14 @@ vec3 linear_to_srgb(vec3 color) {
|
||||||
return mix((vec3(1.0f) + a) * pow(color.rgb, vec3(1.0f / 2.4f)) - a, 12.92f * color.rgb, lessThan(color.rgb, vec3(0.0031308f)));
|
return mix((vec3(1.0f) + a) * pow(color.rgb, vec3(1.0f / 2.4f)) - a, 12.92f * color.rgb, lessThan(color.rgb, vec3(0.0031308f)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vec3 normalize(vec3 value, vec3 min, vec3 max) {
|
||||||
|
return (value - min) / (max - min);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 denormalize(vec3 value, vec3 min, vec3 max) {
|
||||||
|
return value * (max - min) + min;
|
||||||
|
}
|
||||||
|
|
||||||
#define TONEMAPPER_LINEAR 0
|
#define TONEMAPPER_LINEAR 0
|
||||||
#define TONEMAPPER_REINHARD 1
|
#define TONEMAPPER_REINHARD 1
|
||||||
#define TONEMAPPER_FILMIC 2
|
#define TONEMAPPER_FILMIC 2
|
||||||
|
|
@ -353,17 +366,26 @@ vec3 linear_to_srgb(vec3 color) {
|
||||||
vec3 apply_tonemapping(vec3 color, float white) { // inputs are LINEAR
|
vec3 apply_tonemapping(vec3 color, float white) { // inputs are LINEAR
|
||||||
// Ensure color values passed to tonemappers are positive.
|
// Ensure color values passed to tonemappers are positive.
|
||||||
// They can be negative in the case of negative lights, which leads to undesired behavior.
|
// They can be negative in the case of negative lights, which leads to undesired behavior.
|
||||||
|
// Linear is special: it always passes through with no adjustments.
|
||||||
|
|
||||||
if (params.tonemapper == TONEMAPPER_LINEAR) {
|
if (params.tonemapper == TONEMAPPER_LINEAR) {
|
||||||
return color;
|
return color;
|
||||||
} else if (params.tonemapper == TONEMAPPER_REINHARD) {
|
} else if (params.tonemapper == TONEMAPPER_REINHARD) {
|
||||||
return tonemap_reinhard(max(vec3(0.0f), color), white);
|
color = tonemap_reinhard(max(vec3(0.0f), color), white);
|
||||||
} else if (params.tonemapper == TONEMAPPER_FILMIC) {
|
} else if (params.tonemapper == TONEMAPPER_FILMIC) {
|
||||||
return tonemap_filmic(max(vec3(0.0f), color), white);
|
color = tonemap_filmic(max(vec3(0.0f), color), white);
|
||||||
} else if (params.tonemapper == TONEMAPPER_ACES) {
|
} else if (params.tonemapper == TONEMAPPER_ACES) {
|
||||||
return tonemap_aces(max(vec3(0.0f), color), white);
|
color = tonemap_aces(max(vec3(0.0f), color), white);
|
||||||
} else { // TONEMAPPER_AGX
|
} else { // TONEMAPPER_AGX
|
||||||
return tonemap_agx(color);
|
color = tonemap_agx(color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Expand color to the target output range for HDR render targets.
|
||||||
|
if (!bool(params.flags & FLAG_CONVERT_TO_SRGB)) {
|
||||||
|
color = denormalize(color, vec3(params.dest_min_value), vec3(params.dest_max_value));
|
||||||
|
}
|
||||||
|
|
||||||
|
return color;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef USE_MULTIVIEW
|
#ifdef USE_MULTIVIEW
|
||||||
|
|
@ -410,14 +432,33 @@ vec3 gather_glow(sampler2D tex, vec2 uv) { // sample all selected glow levels
|
||||||
#define GLOW_MODE_REPLACE 3
|
#define GLOW_MODE_REPLACE 3
|
||||||
#define GLOW_MODE_MIX 4
|
#define GLOW_MODE_MIX 4
|
||||||
|
|
||||||
vec3 apply_glow(vec3 color, vec3 glow) { // apply glow using the selected blending mode
|
vec3 apply_glow(vec3 color, vec3 glow, bool hdrInput) { // apply glow using the selected blending mode
|
||||||
if (params.glow_mode == GLOW_MODE_ADD) {
|
if (params.glow_mode == GLOW_MODE_ADD) {
|
||||||
return color + glow;
|
return color + glow;
|
||||||
} else if (params.glow_mode == GLOW_MODE_SCREEN) {
|
} else if (params.glow_mode == GLOW_MODE_SCREEN) {
|
||||||
|
if (hdrInput) {
|
||||||
|
// Compress the color and glow from scene intensity to [0, 1] to avoid artifacts due to the color clamping.
|
||||||
|
color = normalize(color, vec3(params.source_min_value), vec3(params.source_max_value));
|
||||||
|
glow = normalize(glow, vec3(params.source_min_value), vec3(params.source_max_value));
|
||||||
|
}
|
||||||
|
|
||||||
// Needs color clamping.
|
// Needs color clamping.
|
||||||
glow.rgb = clamp(glow.rgb, vec3(0.0f), vec3(1.0f));
|
glow.rgb = clamp(glow.rgb, vec3(0.0f), vec3(1.0f));
|
||||||
return max((color + glow) - (color * glow), vec3(0.0));
|
color = max((color + glow) - (color * glow), vec3(0.0));
|
||||||
|
|
||||||
|
if (hdrInput) {
|
||||||
|
// Expand the color back to the original intensity range.
|
||||||
|
color = denormalize(color, vec3(params.source_min_value), vec3(params.source_max_value));
|
||||||
|
}
|
||||||
|
|
||||||
|
return color;
|
||||||
} else if (params.glow_mode == GLOW_MODE_SOFTLIGHT) {
|
} else if (params.glow_mode == GLOW_MODE_SOFTLIGHT) {
|
||||||
|
if (hdrInput) {
|
||||||
|
// Compress the color and glow from scene intensity to [0, 1] to avoid artifacts due to the color clamping.
|
||||||
|
color = normalize(color, vec3(params.source_min_value), vec3(params.source_max_value));
|
||||||
|
glow = normalize(glow, vec3(params.source_min_value), vec3(params.source_max_value));
|
||||||
|
}
|
||||||
|
|
||||||
// Needs color clamping.
|
// Needs color clamping.
|
||||||
glow.rgb = clamp(glow.rgb, vec3(0.0f), vec3(1.0f));
|
glow.rgb = clamp(glow.rgb, vec3(0.0f), vec3(1.0f));
|
||||||
glow = glow * vec3(0.5f) + vec3(0.5f);
|
glow = glow * vec3(0.5f) + vec3(0.5f);
|
||||||
|
|
@ -425,6 +466,12 @@ vec3 apply_glow(vec3 color, vec3 glow) { // apply glow using the selected blendi
|
||||||
color.r = (glow.r <= 0.5f) ? (color.r - (1.0f - 2.0f * glow.r) * color.r * (1.0f - color.r)) : (((glow.r > 0.5f) && (color.r <= 0.25f)) ? (color.r + (2.0f * glow.r - 1.0f) * (4.0f * color.r * (4.0f * color.r + 1.0f) * (color.r - 1.0f) + 7.0f * color.r)) : (color.r + (2.0f * glow.r - 1.0f) * (sqrt(color.r) - color.r)));
|
color.r = (glow.r <= 0.5f) ? (color.r - (1.0f - 2.0f * glow.r) * color.r * (1.0f - color.r)) : (((glow.r > 0.5f) && (color.r <= 0.25f)) ? (color.r + (2.0f * glow.r - 1.0f) * (4.0f * color.r * (4.0f * color.r + 1.0f) * (color.r - 1.0f) + 7.0f * color.r)) : (color.r + (2.0f * glow.r - 1.0f) * (sqrt(color.r) - color.r)));
|
||||||
color.g = (glow.g <= 0.5f) ? (color.g - (1.0f - 2.0f * glow.g) * color.g * (1.0f - color.g)) : (((glow.g > 0.5f) && (color.g <= 0.25f)) ? (color.g + (2.0f * glow.g - 1.0f) * (4.0f * color.g * (4.0f * color.g + 1.0f) * (color.g - 1.0f) + 7.0f * color.g)) : (color.g + (2.0f * glow.g - 1.0f) * (sqrt(color.g) - color.g)));
|
color.g = (glow.g <= 0.5f) ? (color.g - (1.0f - 2.0f * glow.g) * color.g * (1.0f - color.g)) : (((glow.g > 0.5f) && (color.g <= 0.25f)) ? (color.g + (2.0f * glow.g - 1.0f) * (4.0f * color.g * (4.0f * color.g + 1.0f) * (color.g - 1.0f) + 7.0f * color.g)) : (color.g + (2.0f * glow.g - 1.0f) * (sqrt(color.g) - color.g)));
|
||||||
color.b = (glow.b <= 0.5f) ? (color.b - (1.0f - 2.0f * glow.b) * color.b * (1.0f - color.b)) : (((glow.b > 0.5f) && (color.b <= 0.25f)) ? (color.b + (2.0f * glow.b - 1.0f) * (4.0f * color.b * (4.0f * color.b + 1.0f) * (color.b - 1.0f) + 7.0f * color.b)) : (color.b + (2.0f * glow.b - 1.0f) * (sqrt(color.b) - color.b)));
|
color.b = (glow.b <= 0.5f) ? (color.b - (1.0f - 2.0f * glow.b) * color.b * (1.0f - color.b)) : (((glow.b > 0.5f) && (color.b <= 0.25f)) ? (color.b + (2.0f * glow.b - 1.0f) * (4.0f * color.b * (4.0f * color.b + 1.0f) * (color.b - 1.0f) + 7.0f * color.b)) : (color.b + (2.0f * glow.b - 1.0f) * (sqrt(color.b) - color.b)));
|
||||||
|
|
||||||
|
if (hdrInput) {
|
||||||
|
// Expand the color back to the original intensity range.
|
||||||
|
color = denormalize(color, vec3(params.source_min_value), vec3(params.source_max_value));
|
||||||
|
}
|
||||||
|
|
||||||
return color;
|
return color;
|
||||||
} else { //replace
|
} else { //replace
|
||||||
return glow;
|
return glow;
|
||||||
|
|
@ -579,7 +626,7 @@ void main() {
|
||||||
glow = linear_to_srgb(glow);
|
glow = linear_to_srgb(glow);
|
||||||
}
|
}
|
||||||
|
|
||||||
color.rgb = apply_glow(color.rgb, glow);
|
color.rgb = apply_glow(color.rgb, glow, !bool(params.flags & FLAG_CONVERT_TO_SRGB));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1266,9 +1266,12 @@ public:
|
||||||
|
|
||||||
// Tonemap
|
// Tonemap
|
||||||
PASS4(environment_set_tonemap, RID, RS::EnvironmentToneMapper, float, float)
|
PASS4(environment_set_tonemap, RID, RS::EnvironmentToneMapper, float, float)
|
||||||
|
PASS3(environment_set_tonemap_range, RID, float, float)
|
||||||
PASS1RC(RS::EnvironmentToneMapper, environment_get_tone_mapper, RID)
|
PASS1RC(RS::EnvironmentToneMapper, environment_get_tone_mapper, RID)
|
||||||
PASS1RC(float, environment_get_exposure, RID)
|
PASS1RC(float, environment_get_exposure, RID)
|
||||||
PASS1RC(float, environment_get_white, RID)
|
PASS1RC(float, environment_get_white, RID)
|
||||||
|
PASS1RC(float, environment_get_min_value, RID)
|
||||||
|
PASS1RC(float, environment_get_max_value, RID)
|
||||||
|
|
||||||
// Fog
|
// Fog
|
||||||
PASS11(environment_set_fog, RID, bool, const Color &, float, float, float, float, float, float, float, RS::EnvironmentFogMode)
|
PASS11(environment_set_fog, RID, bool, const Color &, float, float, float, float, float, float, float, RS::EnvironmentFogMode)
|
||||||
|
|
|
||||||
|
|
@ -365,6 +365,10 @@ void RendererSceneRender::environment_set_tonemap(RID p_env, RS::EnvironmentTone
|
||||||
environment_storage.environment_set_tonemap(p_env, p_tone_mapper, p_exposure, p_white);
|
environment_storage.environment_set_tonemap(p_env, p_tone_mapper, p_exposure, p_white);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RendererSceneRender::environment_set_tonemap_range(RID p_env, float p_min_value, float p_max_value) {
|
||||||
|
environment_storage.environment_set_tonemap_range(p_env, p_min_value, p_max_value);
|
||||||
|
}
|
||||||
|
|
||||||
RS::EnvironmentToneMapper RendererSceneRender::environment_get_tone_mapper(RID p_env) const {
|
RS::EnvironmentToneMapper RendererSceneRender::environment_get_tone_mapper(RID p_env) const {
|
||||||
return environment_storage.environment_get_tone_mapper(p_env);
|
return environment_storage.environment_get_tone_mapper(p_env);
|
||||||
}
|
}
|
||||||
|
|
@ -377,6 +381,14 @@ float RendererSceneRender::environment_get_white(RID p_env) const {
|
||||||
return environment_storage.environment_get_white(p_env);
|
return environment_storage.environment_get_white(p_env);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float RendererSceneRender::environment_get_min_value(RID p_env) const {
|
||||||
|
return environment_storage.environment_get_min_value(p_env);
|
||||||
|
}
|
||||||
|
|
||||||
|
float RendererSceneRender::environment_get_max_value(RID p_env) const {
|
||||||
|
return environment_storage.environment_get_max_value(p_env);
|
||||||
|
}
|
||||||
|
|
||||||
// Fog
|
// Fog
|
||||||
|
|
||||||
void RendererSceneRender::environment_set_fog(RID p_env, bool p_enable, const Color &p_light_color, float p_light_energy, float p_sun_scatter, float p_density, float p_height, float p_height_density, float p_aerial_perspective, float p_sky_affect, RS::EnvironmentFogMode p_mode) {
|
void RendererSceneRender::environment_set_fog(RID p_env, bool p_enable, const Color &p_light_color, float p_light_energy, float p_sun_scatter, float p_density, float p_height, float p_height_density, float p_aerial_perspective, float p_sky_affect, RS::EnvironmentFogMode p_mode) {
|
||||||
|
|
|
||||||
|
|
@ -136,9 +136,12 @@ public:
|
||||||
|
|
||||||
// Tonemap
|
// Tonemap
|
||||||
void environment_set_tonemap(RID p_env, RS::EnvironmentToneMapper p_tone_mapper, float p_exposure, float p_white);
|
void environment_set_tonemap(RID p_env, RS::EnvironmentToneMapper p_tone_mapper, float p_exposure, float p_white);
|
||||||
|
void environment_set_tonemap_range(RID p_env, float p_min_value, float p_max_value);
|
||||||
RS::EnvironmentToneMapper environment_get_tone_mapper(RID p_env) const;
|
RS::EnvironmentToneMapper environment_get_tone_mapper(RID p_env) const;
|
||||||
float environment_get_exposure(RID p_env) const;
|
float environment_get_exposure(RID p_env) const;
|
||||||
float environment_get_white(RID p_env) const;
|
float environment_get_white(RID p_env) const;
|
||||||
|
float environment_get_min_value(RID p_env) const;
|
||||||
|
float environment_get_max_value(RID p_env) const;
|
||||||
|
|
||||||
// Fog
|
// Fog
|
||||||
void environment_set_fog(RID p_env, bool p_enable, const Color &p_light_color, float p_light_energy, float p_sun_scatter, float p_density, float p_height, float p_height_density, float p_aerial_perspective, float p_sky_affect, RS::EnvironmentFogMode p_mode);
|
void environment_set_fog(RID p_env, bool p_enable, const Color &p_light_color, float p_light_energy, float p_sun_scatter, float p_density, float p_height, float p_height_density, float p_aerial_perspective, float p_sky_affect, RS::EnvironmentFogMode p_mode);
|
||||||
|
|
|
||||||
|
|
@ -333,6 +333,27 @@ void RendererViewport::_draw_viewport(Viewport *p_viewport) {
|
||||||
// The scene renderer will still copy over the last frame, so we need to clear the render target.
|
// The scene renderer will still copy over the last frame, so we need to clear the render target.
|
||||||
force_clear_render_target = true;
|
force_clear_render_target = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check if the viewport is tonemapping to the screen.
|
||||||
|
if (p_viewport->tonemap_to_screen) {
|
||||||
|
DisplayServer::WindowID parent_window = _get_containing_window(p_viewport);
|
||||||
|
if (parent_window != DisplayServer::INVALID_WINDOW_ID) {
|
||||||
|
RenderingContextDriver *context_driver = RD::get_singleton()->get_context_driver();
|
||||||
|
|
||||||
|
if (context_driver->window_get_hdr_output_enabled(parent_window)) {
|
||||||
|
float min_luminance = context_driver->window_get_hdr_output_min_luminance(parent_window);
|
||||||
|
float max_luminance = context_driver->window_get_hdr_output_max_luminance(parent_window);
|
||||||
|
float reference_luminance = context_driver->window_get_hdr_output_reference_luminance(parent_window);
|
||||||
|
|
||||||
|
float min_value = MAX(min_luminance / MAX(reference_luminance, 1.0f), 0.0f);
|
||||||
|
float max_value = MAX(max_luminance / MAX(reference_luminance, 1.0f), 1.0f);
|
||||||
|
|
||||||
|
RSG::scene->environment_set_tonemap_range(environment, min_value, max_value);
|
||||||
|
} else {
|
||||||
|
RSG::scene->environment_set_tonemap_range(environment, 0.0f, 1.0f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -710,6 +731,21 @@ void RendererViewport::_draw_viewport(Viewport *p_viewport) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DisplayServer::WindowID RendererViewport::_get_containing_window(Viewport *p_viewport) {
|
||||||
|
if (p_viewport->viewport_to_screen != DisplayServer::INVALID_WINDOW_ID) {
|
||||||
|
return p_viewport->viewport_to_screen;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p_viewport->parent.is_valid()) {
|
||||||
|
Viewport *parent = viewport_owner.get_or_null(p_viewport->parent);
|
||||||
|
if (parent) {
|
||||||
|
return _get_containing_window(parent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return DisplayServer::INVALID_WINDOW_ID;
|
||||||
|
}
|
||||||
|
|
||||||
void RendererViewport::draw_viewports(bool p_swap_buffers) {
|
void RendererViewport::draw_viewports(bool p_swap_buffers) {
|
||||||
timestamp_vp_map.clear();
|
timestamp_vp_map.clear();
|
||||||
|
|
||||||
|
|
@ -1124,6 +1160,13 @@ void RendererViewport::viewport_set_render_direct_to_screen(RID p_viewport, bool
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RendererViewport::viewport_set_tonemap_to_screen(RID p_viewport, bool p_enable) {
|
||||||
|
Viewport *viewport = viewport_owner.get_or_null(p_viewport);
|
||||||
|
ERR_FAIL_NULL(viewport);
|
||||||
|
|
||||||
|
viewport->tonemap_to_screen = p_enable;
|
||||||
|
}
|
||||||
|
|
||||||
void RendererViewport::viewport_set_update_mode(RID p_viewport, RS::ViewportUpdateMode p_mode) {
|
void RendererViewport::viewport_set_update_mode(RID p_viewport, RS::ViewportUpdateMode p_mode) {
|
||||||
Viewport *viewport = viewport_owner.get_or_null(p_viewport);
|
Viewport *viewport = viewport_owner.get_or_null(p_viewport);
|
||||||
ERR_FAIL_NULL(viewport);
|
ERR_FAIL_NULL(viewport);
|
||||||
|
|
|
||||||
|
|
@ -87,6 +87,7 @@ public:
|
||||||
DisplayServer::WindowID viewport_to_screen;
|
DisplayServer::WindowID viewport_to_screen;
|
||||||
Rect2 viewport_to_screen_rect;
|
Rect2 viewport_to_screen_rect;
|
||||||
bool viewport_render_direct_to_screen;
|
bool viewport_render_direct_to_screen;
|
||||||
|
bool tonemap_to_screen;
|
||||||
|
|
||||||
bool disable_2d = false;
|
bool disable_2d = false;
|
||||||
RS::ViewportEnvironmentMode disable_environment = RS::VIEWPORT_ENVIRONMENT_INHERIT;
|
RS::ViewportEnvironmentMode disable_environment = RS::VIEWPORT_ENVIRONMENT_INHERIT;
|
||||||
|
|
@ -211,6 +212,7 @@ private:
|
||||||
void _configure_3d_render_buffers(Viewport *p_viewport);
|
void _configure_3d_render_buffers(Viewport *p_viewport);
|
||||||
void _draw_3d(Viewport *p_viewport);
|
void _draw_3d(Viewport *p_viewport);
|
||||||
void _draw_viewport(Viewport *p_viewport);
|
void _draw_viewport(Viewport *p_viewport);
|
||||||
|
DisplayServer::WindowID _get_containing_window(Viewport *p_viewport);
|
||||||
|
|
||||||
int occlusion_rays_per_thread = 512;
|
int occlusion_rays_per_thread = 512;
|
||||||
|
|
||||||
|
|
@ -226,6 +228,7 @@ public:
|
||||||
|
|
||||||
void viewport_attach_to_screen(RID p_viewport, const Rect2 &p_rect = Rect2(), DisplayServer::WindowID p_screen = DisplayServer::MAIN_WINDOW_ID);
|
void viewport_attach_to_screen(RID p_viewport, const Rect2 &p_rect = Rect2(), DisplayServer::WindowID p_screen = DisplayServer::MAIN_WINDOW_ID);
|
||||||
void viewport_set_render_direct_to_screen(RID p_viewport, bool p_enable);
|
void viewport_set_render_direct_to_screen(RID p_viewport, bool p_enable);
|
||||||
|
void viewport_set_tonemap_to_screen(RID p_viewport, bool p_enable);
|
||||||
|
|
||||||
void viewport_set_active(RID p_viewport, bool p_active);
|
void viewport_set_active(RID p_viewport, bool p_active);
|
||||||
void viewport_set_parent_viewport(RID p_viewport, RID p_parent_viewport);
|
void viewport_set_parent_viewport(RID p_viewport, RID p_parent_viewport);
|
||||||
|
|
|
||||||
|
|
@ -75,6 +75,86 @@ DisplayServer::VSyncMode RenderingContextDriver::window_get_vsync_mode(DisplaySe
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RenderingContextDriver::window_set_hdr_output_enabled(DisplayServer::WindowID p_window, bool p_enabled) {
|
||||||
|
SurfaceID surface = surface_get_from_window(p_window);
|
||||||
|
if (surface) {
|
||||||
|
surface_set_hdr_output_enabled(surface, p_enabled);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RenderingContextDriver::window_get_hdr_output_enabled(DisplayServer::WindowID p_window) const {
|
||||||
|
SurfaceID surface = surface_get_from_window(p_window);
|
||||||
|
if (surface) {
|
||||||
|
return surface_get_hdr_output_enabled(surface);
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RenderingContextDriver::window_set_hdr_output_prefer_high_precision(DisplayServer::WindowID p_window, bool p_enabled) {
|
||||||
|
SurfaceID surface = surface_get_from_window(p_window);
|
||||||
|
if (surface) {
|
||||||
|
surface_set_hdr_output_prefer_high_precision(surface, p_enabled);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RenderingContextDriver::window_get_hdr_output_prefer_high_precision(DisplayServer::WindowID p_window) const {
|
||||||
|
SurfaceID surface = surface_get_from_window(p_window);
|
||||||
|
if (surface) {
|
||||||
|
return surface_get_hdr_output_prefer_high_precision(surface);
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RenderingContextDriver::window_set_hdr_output_reference_luminance(DisplayServer::WindowID p_window, float p_reference_luminance) {
|
||||||
|
SurfaceID surface = surface_get_from_window(p_window);
|
||||||
|
if (surface) {
|
||||||
|
surface_set_hdr_output_reference_luminance(surface, p_reference_luminance);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
float RenderingContextDriver::window_get_hdr_output_reference_luminance(DisplayServer::WindowID p_window) const {
|
||||||
|
SurfaceID surface = surface_get_from_window(p_window);
|
||||||
|
if (surface) {
|
||||||
|
return surface_get_hdr_output_reference_luminance(surface);
|
||||||
|
} else {
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RenderingContextDriver::window_set_hdr_output_min_luminance(DisplayServer::WindowID p_window, float p_min_luminance) {
|
||||||
|
SurfaceID surface = surface_get_from_window(p_window);
|
||||||
|
if (surface) {
|
||||||
|
surface_set_hdr_output_min_luminance(surface, p_min_luminance);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
float RenderingContextDriver::window_get_hdr_output_min_luminance(DisplayServer::WindowID p_window) const {
|
||||||
|
SurfaceID surface = surface_get_from_window(p_window);
|
||||||
|
if (surface) {
|
||||||
|
return surface_get_hdr_output_min_luminance(surface);
|
||||||
|
} else {
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RenderingContextDriver::window_set_hdr_output_max_luminance(DisplayServer::WindowID p_window, float p_max_luminance) {
|
||||||
|
SurfaceID surface = surface_get_from_window(p_window);
|
||||||
|
if (surface) {
|
||||||
|
surface_set_hdr_output_max_luminance(surface, p_max_luminance);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
float RenderingContextDriver::window_get_hdr_output_max_luminance(DisplayServer::WindowID p_window) const {
|
||||||
|
SurfaceID surface = surface_get_from_window(p_window);
|
||||||
|
if (surface) {
|
||||||
|
return surface_get_hdr_output_max_luminance(surface);
|
||||||
|
} else {
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void RenderingContextDriver::window_destroy(DisplayServer::WindowID p_window) {
|
void RenderingContextDriver::window_destroy(DisplayServer::WindowID p_window) {
|
||||||
SurfaceID surface = surface_get_from_window(p_window);
|
SurfaceID surface = surface_get_from_window(p_window);
|
||||||
if (surface) {
|
if (surface) {
|
||||||
|
|
|
||||||
|
|
@ -48,6 +48,16 @@ public:
|
||||||
void window_set_size(DisplayServer::WindowID p_window, uint32_t p_width, uint32_t p_height);
|
void window_set_size(DisplayServer::WindowID p_window, uint32_t p_width, uint32_t p_height);
|
||||||
void window_set_vsync_mode(DisplayServer::WindowID p_window, DisplayServer::VSyncMode p_vsync_mode);
|
void window_set_vsync_mode(DisplayServer::WindowID p_window, DisplayServer::VSyncMode p_vsync_mode);
|
||||||
DisplayServer::VSyncMode window_get_vsync_mode(DisplayServer::WindowID p_window) const;
|
DisplayServer::VSyncMode window_get_vsync_mode(DisplayServer::WindowID p_window) const;
|
||||||
|
void window_set_hdr_output_enabled(DisplayServer::WindowID p_window, bool p_enabled);
|
||||||
|
bool window_get_hdr_output_enabled(DisplayServer::WindowID p_window) const;
|
||||||
|
void window_set_hdr_output_prefer_high_precision(DisplayServer::WindowID p_window, bool p_enabled);
|
||||||
|
bool window_get_hdr_output_prefer_high_precision(DisplayServer::WindowID p_window) const;
|
||||||
|
void window_set_hdr_output_reference_luminance(DisplayServer::WindowID p_window, float p_reference_luminance);
|
||||||
|
float window_get_hdr_output_reference_luminance(DisplayServer::WindowID p_window) const;
|
||||||
|
void window_set_hdr_output_min_luminance(DisplayServer::WindowID p_window, float p_min_luminance);
|
||||||
|
float window_get_hdr_output_min_luminance(DisplayServer::WindowID p_window) const;
|
||||||
|
void window_set_hdr_output_max_luminance(DisplayServer::WindowID p_window, float p_max_luminance);
|
||||||
|
float window_get_hdr_output_max_luminance(DisplayServer::WindowID p_window) const;
|
||||||
void window_destroy(DisplayServer::WindowID p_window);
|
void window_destroy(DisplayServer::WindowID p_window);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
@ -98,6 +108,16 @@ public:
|
||||||
virtual void surface_set_size(SurfaceID p_surface, uint32_t p_width, uint32_t p_height) = 0;
|
virtual void surface_set_size(SurfaceID p_surface, uint32_t p_width, uint32_t p_height) = 0;
|
||||||
virtual void surface_set_vsync_mode(SurfaceID p_surface, DisplayServer::VSyncMode p_vsync_mode) = 0;
|
virtual void surface_set_vsync_mode(SurfaceID p_surface, DisplayServer::VSyncMode p_vsync_mode) = 0;
|
||||||
virtual DisplayServer::VSyncMode surface_get_vsync_mode(SurfaceID p_surface) const = 0;
|
virtual DisplayServer::VSyncMode surface_get_vsync_mode(SurfaceID p_surface) const = 0;
|
||||||
|
virtual void surface_set_hdr_output_enabled(SurfaceID p_surface, bool p_enabled) = 0;
|
||||||
|
virtual bool surface_get_hdr_output_enabled(SurfaceID p_surface) const = 0;
|
||||||
|
virtual void surface_set_hdr_output_prefer_high_precision(SurfaceID p_surface, bool p_enabled) = 0;
|
||||||
|
virtual bool surface_get_hdr_output_prefer_high_precision(SurfaceID p_surface) const = 0;
|
||||||
|
virtual void surface_set_hdr_output_reference_luminance(SurfaceID p_surface, float p_reference_luminance) = 0;
|
||||||
|
virtual float surface_get_hdr_output_reference_luminance(SurfaceID p_surface) const = 0;
|
||||||
|
virtual void surface_set_hdr_output_min_luminance(SurfaceID p_surface, float p_min_luminance) = 0;
|
||||||
|
virtual float surface_get_hdr_output_min_luminance(SurfaceID p_surface) const = 0;
|
||||||
|
virtual void surface_set_hdr_output_max_luminance(SurfaceID p_surface, float p_max_luminance) = 0;
|
||||||
|
virtual float surface_get_hdr_output_max_luminance(SurfaceID p_surface) const = 0;
|
||||||
virtual uint32_t surface_get_width(SurfaceID p_surface) const = 0;
|
virtual uint32_t surface_get_width(SurfaceID p_surface) const = 0;
|
||||||
virtual uint32_t surface_get_height(SurfaceID p_surface) const = 0;
|
virtual uint32_t surface_get_height(SurfaceID p_surface) const = 0;
|
||||||
virtual void surface_set_needs_resize(SurfaceID p_surface, bool p_needs_resize) = 0;
|
virtual void surface_set_needs_resize(SurfaceID p_surface, bool p_needs_resize) = 0;
|
||||||
|
|
|
||||||
|
|
@ -4209,6 +4209,28 @@ RenderingDevice::FramebufferFormatID RenderingDevice::screen_get_framebuffer_for
|
||||||
return const_cast<RenderingDevice *>(this)->framebuffer_format_create(screen_attachment);
|
return const_cast<RenderingDevice *>(this)->framebuffer_format_create(screen_attachment);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RenderingDevice::DataFormat RenderingDevice::screen_get_color_format(DisplayServer::WindowID p_screen) const {
|
||||||
|
_THREAD_SAFE_METHOD_
|
||||||
|
|
||||||
|
HashMap<DisplayServer::WindowID, RDD::SwapChainID>::ConstIterator it = screen_swap_chains.find(p_screen);
|
||||||
|
ERR_FAIL_COND_V_MSG(it == screen_swap_chains.end(), DATA_FORMAT_MAX, "Screen was never prepared.");
|
||||||
|
|
||||||
|
DataFormat format = driver->swap_chain_get_format(it->value);
|
||||||
|
ERR_FAIL_COND_V_MSG(format == DATA_FORMAT_MAX, DATA_FORMAT_MAX, "Unknown format.");
|
||||||
|
return format;
|
||||||
|
}
|
||||||
|
|
||||||
|
RenderingDevice::ColorSpace RenderingDevice::screen_get_color_space(DisplayServer::WindowID p_screen) const {
|
||||||
|
_THREAD_SAFE_METHOD_
|
||||||
|
|
||||||
|
HashMap<DisplayServer::WindowID, RDD::SwapChainID>::ConstIterator it = screen_swap_chains.find(p_screen);
|
||||||
|
ERR_FAIL_COND_V_MSG(it == screen_swap_chains.end(), COLOR_SPACE_MAX, "Screen was never prepared.");
|
||||||
|
|
||||||
|
ColorSpace color_space = driver->swap_chain_get_color_space(it->value);
|
||||||
|
ERR_FAIL_COND_V_MSG(color_space == COLOR_SPACE_MAX, COLOR_SPACE_MAX, "Unknown color space.");
|
||||||
|
return color_space;
|
||||||
|
}
|
||||||
|
|
||||||
Error RenderingDevice::screen_free(DisplayServer::WindowID p_screen) {
|
Error RenderingDevice::screen_free(DisplayServer::WindowID p_screen) {
|
||||||
_THREAD_SAFE_METHOD_
|
_THREAD_SAFE_METHOD_
|
||||||
|
|
||||||
|
|
@ -7337,6 +7359,8 @@ void RenderingDevice::_bind_methods() {
|
||||||
ClassDB::bind_method(D_METHOD("screen_get_width", "screen"), &RenderingDevice::screen_get_width, DEFVAL(DisplayServer::MAIN_WINDOW_ID));
|
ClassDB::bind_method(D_METHOD("screen_get_width", "screen"), &RenderingDevice::screen_get_width, DEFVAL(DisplayServer::MAIN_WINDOW_ID));
|
||||||
ClassDB::bind_method(D_METHOD("screen_get_height", "screen"), &RenderingDevice::screen_get_height, DEFVAL(DisplayServer::MAIN_WINDOW_ID));
|
ClassDB::bind_method(D_METHOD("screen_get_height", "screen"), &RenderingDevice::screen_get_height, DEFVAL(DisplayServer::MAIN_WINDOW_ID));
|
||||||
ClassDB::bind_method(D_METHOD("screen_get_framebuffer_format", "screen"), &RenderingDevice::screen_get_framebuffer_format, DEFVAL(DisplayServer::MAIN_WINDOW_ID));
|
ClassDB::bind_method(D_METHOD("screen_get_framebuffer_format", "screen"), &RenderingDevice::screen_get_framebuffer_format, DEFVAL(DisplayServer::MAIN_WINDOW_ID));
|
||||||
|
ClassDB::bind_method(D_METHOD("screen_get_color_format", "screen"), &RenderingDevice::screen_get_color_format, DEFVAL(DisplayServer::MAIN_WINDOW_ID));
|
||||||
|
ClassDB::bind_method(D_METHOD("screen_get_color_space", "screen"), &RenderingDevice::screen_get_color_space, DEFVAL(DisplayServer::MAIN_WINDOW_ID));
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("draw_list_begin_for_screen", "screen", "clear_color"), &RenderingDevice::draw_list_begin_for_screen, DEFVAL(DisplayServer::MAIN_WINDOW_ID), DEFVAL(Color()));
|
ClassDB::bind_method(D_METHOD("draw_list_begin_for_screen", "screen", "clear_color"), &RenderingDevice::draw_list_begin_for_screen, DEFVAL(DisplayServer::MAIN_WINDOW_ID), DEFVAL(Color()));
|
||||||
|
|
||||||
|
|
@ -7682,6 +7706,11 @@ void RenderingDevice::_bind_methods() {
|
||||||
BIND_ENUM_CONSTANT(DATA_FORMAT_G16_B16_R16_3PLANE_444_UNORM);
|
BIND_ENUM_CONSTANT(DATA_FORMAT_G16_B16_R16_3PLANE_444_UNORM);
|
||||||
BIND_ENUM_CONSTANT(DATA_FORMAT_MAX);
|
BIND_ENUM_CONSTANT(DATA_FORMAT_MAX);
|
||||||
|
|
||||||
|
BIND_ENUM_CONSTANT(COLOR_SPACE_SRGB_LINEAR);
|
||||||
|
BIND_ENUM_CONSTANT(COLOR_SPACE_SRGB_NONLINEAR);
|
||||||
|
BIND_ENUM_CONSTANT(COLOR_SPACE_HDR10_ST2084);
|
||||||
|
BIND_ENUM_CONSTANT(COLOR_SPACE_MAX);
|
||||||
|
|
||||||
#ifndef DISABLE_DEPRECATED
|
#ifndef DISABLE_DEPRECATED
|
||||||
BIND_BITFIELD_FLAG(BARRIER_MASK_VERTEX);
|
BIND_BITFIELD_FLAG(BARRIER_MASK_VERTEX);
|
||||||
BIND_BITFIELD_FLAG(BARRIER_MASK_FRAGMENT);
|
BIND_BITFIELD_FLAG(BARRIER_MASK_FRAGMENT);
|
||||||
|
|
@ -7906,6 +7935,7 @@ void RenderingDevice::_bind_methods() {
|
||||||
BIND_ENUM_CONSTANT(PIPELINE_SPECIALIZATION_CONSTANT_TYPE_FLOAT);
|
BIND_ENUM_CONSTANT(PIPELINE_SPECIALIZATION_CONSTANT_TYPE_FLOAT);
|
||||||
|
|
||||||
BIND_ENUM_CONSTANT(SUPPORTS_BUFFER_DEVICE_ADDRESS);
|
BIND_ENUM_CONSTANT(SUPPORTS_BUFFER_DEVICE_ADDRESS);
|
||||||
|
BIND_ENUM_CONSTANT(SUPPORTS_HDR_OUTPUT);
|
||||||
|
|
||||||
BIND_ENUM_CONSTANT(LIMIT_MAX_BOUND_UNIFORM_SETS);
|
BIND_ENUM_CONSTANT(LIMIT_MAX_BOUND_UNIFORM_SETS);
|
||||||
BIND_ENUM_CONSTANT(LIMIT_MAX_FRAMEBUFFER_COLOR_ATTACHMENTS);
|
BIND_ENUM_CONSTANT(LIMIT_MAX_FRAMEBUFFER_COLOR_ATTACHMENTS);
|
||||||
|
|
|
||||||
|
|
@ -1159,6 +1159,8 @@ public:
|
||||||
int screen_get_height(DisplayServer::WindowID p_screen = DisplayServer::MAIN_WINDOW_ID) const;
|
int screen_get_height(DisplayServer::WindowID p_screen = DisplayServer::MAIN_WINDOW_ID) const;
|
||||||
int screen_get_pre_rotation_degrees(DisplayServer::WindowID p_screen = DisplayServer::MAIN_WINDOW_ID) const;
|
int screen_get_pre_rotation_degrees(DisplayServer::WindowID p_screen = DisplayServer::MAIN_WINDOW_ID) const;
|
||||||
FramebufferFormatID screen_get_framebuffer_format(DisplayServer::WindowID p_screen = DisplayServer::MAIN_WINDOW_ID) const;
|
FramebufferFormatID screen_get_framebuffer_format(DisplayServer::WindowID p_screen = DisplayServer::MAIN_WINDOW_ID) const;
|
||||||
|
DataFormat screen_get_color_format(DisplayServer::WindowID p_screen = DisplayServer::MAIN_WINDOW_ID) const;
|
||||||
|
ColorSpace screen_get_color_space(DisplayServer::WindowID p_screen = DisplayServer::MAIN_WINDOW_ID) const;
|
||||||
Error screen_free(DisplayServer::WindowID p_screen = DisplayServer::MAIN_WINDOW_ID);
|
Error screen_free(DisplayServer::WindowID p_screen = DisplayServer::MAIN_WINDOW_ID);
|
||||||
|
|
||||||
/*************************/
|
/*************************/
|
||||||
|
|
@ -1678,6 +1680,7 @@ VARIANT_ENUM_CAST(RenderingDevice::ShaderStage)
|
||||||
VARIANT_ENUM_CAST(RenderingDevice::ShaderLanguage)
|
VARIANT_ENUM_CAST(RenderingDevice::ShaderLanguage)
|
||||||
VARIANT_ENUM_CAST(RenderingDevice::CompareOperator)
|
VARIANT_ENUM_CAST(RenderingDevice::CompareOperator)
|
||||||
VARIANT_ENUM_CAST(RenderingDevice::DataFormat)
|
VARIANT_ENUM_CAST(RenderingDevice::DataFormat)
|
||||||
|
VARIANT_ENUM_CAST(RenderingDevice::ColorSpace)
|
||||||
VARIANT_ENUM_CAST(RenderingDevice::TextureType)
|
VARIANT_ENUM_CAST(RenderingDevice::TextureType)
|
||||||
VARIANT_ENUM_CAST(RenderingDevice::TextureSamples)
|
VARIANT_ENUM_CAST(RenderingDevice::TextureSamples)
|
||||||
VARIANT_BITFIELD_CAST(RenderingDevice::TextureUsageBits)
|
VARIANT_BITFIELD_CAST(RenderingDevice::TextureUsageBits)
|
||||||
|
|
|
||||||
|
|
@ -273,6 +273,13 @@ public:
|
||||||
DATA_FORMAT_MAX,
|
DATA_FORMAT_MAX,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum ColorSpace {
|
||||||
|
COLOR_SPACE_SRGB_LINEAR,
|
||||||
|
COLOR_SPACE_SRGB_NONLINEAR,
|
||||||
|
COLOR_SPACE_HDR10_ST2084,
|
||||||
|
COLOR_SPACE_MAX,
|
||||||
|
};
|
||||||
|
|
||||||
// Breadcrumb markers are useful for debugging GPU crashes (i.e. DEVICE_LOST). Internally
|
// Breadcrumb markers are useful for debugging GPU crashes (i.e. DEVICE_LOST). Internally
|
||||||
// they're just an uint32_t to "tag" a GPU command. These are only used for debugging and do not
|
// they're just an uint32_t to "tag" a GPU command. These are only used for debugging and do not
|
||||||
// (or at least shouldn't) alter the execution behavior in any way.
|
// (or at least shouldn't) alter the execution behavior in any way.
|
||||||
|
|
@ -887,6 +894,7 @@ public:
|
||||||
// If not supported, a fragment shader with only side effects (i.e., writes to buffers, but doesn't output to attachments), may be optimized down to no-op by the GPU driver.
|
// If not supported, a fragment shader with only side effects (i.e., writes to buffers, but doesn't output to attachments), may be optimized down to no-op by the GPU driver.
|
||||||
SUPPORTS_FRAGMENT_SHADER_WITH_ONLY_SIDE_EFFECTS,
|
SUPPORTS_FRAGMENT_SHADER_WITH_ONLY_SIDE_EFFECTS,
|
||||||
SUPPORTS_BUFFER_DEVICE_ADDRESS,
|
SUPPORTS_BUFFER_DEVICE_ADDRESS,
|
||||||
|
SUPPORTS_HDR_OUTPUT,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum SubgroupOperations {
|
enum SubgroupOperations {
|
||||||
|
|
|
||||||
|
|
@ -473,6 +473,9 @@ public:
|
||||||
// Android uses this with Swappy library. Some implementations or platforms may ignore this hint.
|
// Android uses this with Swappy library. Some implementations or platforms may ignore this hint.
|
||||||
virtual void swap_chain_set_max_fps(SwapChainID p_swap_chain, int p_max_fps) {}
|
virtual void swap_chain_set_max_fps(SwapChainID p_swap_chain, int p_max_fps) {}
|
||||||
|
|
||||||
|
// Retrieve the color space used by the swap chain's framebuffers.
|
||||||
|
virtual ColorSpace swap_chain_get_color_space(SwapChainID p_swap_chain) = 0;
|
||||||
|
|
||||||
// Wait until all rendering associated to the swap chain is finished before deleting it.
|
// Wait until all rendering associated to the swap chain is finished before deleting it.
|
||||||
virtual void swap_chain_free(SwapChainID p_swap_chain) = 0;
|
virtual void swap_chain_free(SwapChainID p_swap_chain) = 0;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -186,10 +186,13 @@ public:
|
||||||
|
|
||||||
// Tonemap
|
// Tonemap
|
||||||
virtual void environment_set_tonemap(RID p_env, RS::EnvironmentToneMapper p_tone_mapper, float p_exposure, float p_white) = 0;
|
virtual void environment_set_tonemap(RID p_env, RS::EnvironmentToneMapper p_tone_mapper, float p_exposure, float p_white) = 0;
|
||||||
|
virtual void environment_set_tonemap_range(RID p_env, float p_min_value, float p_max_value) = 0;
|
||||||
|
|
||||||
virtual RS::EnvironmentToneMapper environment_get_tone_mapper(RID p_env) const = 0;
|
virtual RS::EnvironmentToneMapper environment_get_tone_mapper(RID p_env) const = 0;
|
||||||
virtual float environment_get_exposure(RID p_env) const = 0;
|
virtual float environment_get_exposure(RID p_env) const = 0;
|
||||||
virtual float environment_get_white(RID p_env) const = 0;
|
virtual float environment_get_white(RID p_env) const = 0;
|
||||||
|
virtual float environment_get_min_value(RID p_env) const = 0;
|
||||||
|
virtual float environment_get_max_value(RID p_env) const = 0;
|
||||||
|
|
||||||
// Fog
|
// Fog
|
||||||
virtual void environment_set_fog(RID p_env, bool p_enable, const Color &p_light_color, float p_light_energy, float p_sun_scatter, float p_density, float p_height, float p_height_density, float p_aerial_perspective, float p_sky_affect, RS::EnvironmentFogMode p_mode = RS::EnvironmentFogMode::ENV_FOG_MODE_EXPONENTIAL) = 0;
|
virtual void environment_set_fog(RID p_env, bool p_enable, const Color &p_light_color, float p_light_energy, float p_sun_scatter, float p_density, float p_height, float p_height_density, float p_aerial_perspective, float p_sky_affect, RS::EnvironmentFogMode p_mode = RS::EnvironmentFogMode::ENV_FOG_MODE_EXPONENTIAL) = 0;
|
||||||
|
|
|
||||||
|
|
@ -690,6 +690,7 @@ public:
|
||||||
|
|
||||||
FUNC3(viewport_attach_to_screen, RID, const Rect2 &, int)
|
FUNC3(viewport_attach_to_screen, RID, const Rect2 &, int)
|
||||||
FUNC2(viewport_set_render_direct_to_screen, RID, bool)
|
FUNC2(viewport_set_render_direct_to_screen, RID, bool)
|
||||||
|
FUNC2(viewport_set_tonemap_to_screen, RID, bool)
|
||||||
|
|
||||||
FUNC2(viewport_set_scaling_3d_mode, RID, ViewportScaling3DMode)
|
FUNC2(viewport_set_scaling_3d_mode, RID, ViewportScaling3DMode)
|
||||||
FUNC2(viewport_set_scaling_3d_scale, RID, float)
|
FUNC2(viewport_set_scaling_3d_scale, RID, float)
|
||||||
|
|
@ -813,6 +814,7 @@ public:
|
||||||
FUNC1(environment_glow_set_use_bicubic_upscale, bool)
|
FUNC1(environment_glow_set_use_bicubic_upscale, bool)
|
||||||
|
|
||||||
FUNC4(environment_set_tonemap, RID, EnvironmentToneMapper, float, float)
|
FUNC4(environment_set_tonemap, RID, EnvironmentToneMapper, float, float)
|
||||||
|
FUNC3(environment_set_tonemap_range, RID, float, float)
|
||||||
|
|
||||||
FUNC7(environment_set_adjustment, RID, bool, float, float, float, bool, RID)
|
FUNC7(environment_set_adjustment, RID, bool, float, float, float, bool, RID)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -211,6 +211,14 @@ void RendererEnvironmentStorage::environment_set_tonemap(RID p_env, RS::Environm
|
||||||
env->white = p_white;
|
env->white = p_white;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RendererEnvironmentStorage::environment_set_tonemap_range(RID p_env, float p_min_value, float p_max_value) {
|
||||||
|
Environment *env = environment_owner.get_or_null(p_env);
|
||||||
|
ERR_FAIL_NULL(env);
|
||||||
|
ERR_FAIL_COND(p_min_value >= p_max_value);
|
||||||
|
env->min_value = p_min_value;
|
||||||
|
env->max_value = p_max_value;
|
||||||
|
}
|
||||||
|
|
||||||
RS::EnvironmentToneMapper RendererEnvironmentStorage::environment_get_tone_mapper(RID p_env) const {
|
RS::EnvironmentToneMapper RendererEnvironmentStorage::environment_get_tone_mapper(RID p_env) const {
|
||||||
Environment *env = environment_owner.get_or_null(p_env);
|
Environment *env = environment_owner.get_or_null(p_env);
|
||||||
ERR_FAIL_NULL_V(env, RS::ENV_TONE_MAPPER_LINEAR);
|
ERR_FAIL_NULL_V(env, RS::ENV_TONE_MAPPER_LINEAR);
|
||||||
|
|
@ -229,6 +237,18 @@ float RendererEnvironmentStorage::environment_get_white(RID p_env) const {
|
||||||
return env->white;
|
return env->white;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float RendererEnvironmentStorage::environment_get_min_value(RID p_env) const {
|
||||||
|
Environment *env = environment_owner.get_or_null(p_env);
|
||||||
|
ERR_FAIL_NULL_V(env, 0.0);
|
||||||
|
return env->min_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
float RendererEnvironmentStorage::environment_get_max_value(RID p_env) const {
|
||||||
|
Environment *env = environment_owner.get_or_null(p_env);
|
||||||
|
ERR_FAIL_NULL_V(env, 1.0);
|
||||||
|
return env->max_value;
|
||||||
|
}
|
||||||
|
|
||||||
// Fog
|
// Fog
|
||||||
|
|
||||||
void RendererEnvironmentStorage::environment_set_fog(RID p_env, bool p_enable, const Color &p_light_color, float p_light_energy, float p_sun_scatter, float p_density, float p_height, float p_height_density, float p_fog_aerial_perspective, float p_sky_affect, RS::EnvironmentFogMode p_mode) {
|
void RendererEnvironmentStorage::environment_set_fog(RID p_env, bool p_enable, const Color &p_light_color, float p_light_energy, float p_sun_scatter, float p_density, float p_height, float p_height_density, float p_fog_aerial_perspective, float p_sky_affect, RS::EnvironmentFogMode p_mode) {
|
||||||
|
|
|
||||||
|
|
@ -63,6 +63,8 @@ private:
|
||||||
RS::EnvironmentToneMapper tone_mapper;
|
RS::EnvironmentToneMapper tone_mapper;
|
||||||
float exposure = 1.0;
|
float exposure = 1.0;
|
||||||
float white = 1.0;
|
float white = 1.0;
|
||||||
|
float min_value = 0.0;
|
||||||
|
float max_value = 1.0;
|
||||||
|
|
||||||
// Fog
|
// Fog
|
||||||
bool fog_enabled = false;
|
bool fog_enabled = false;
|
||||||
|
|
@ -201,9 +203,12 @@ public:
|
||||||
|
|
||||||
// Tonemap
|
// Tonemap
|
||||||
void environment_set_tonemap(RID p_env, RS::EnvironmentToneMapper p_tone_mapper, float p_exposure, float p_white);
|
void environment_set_tonemap(RID p_env, RS::EnvironmentToneMapper p_tone_mapper, float p_exposure, float p_white);
|
||||||
|
void environment_set_tonemap_range(RID p_env, float p_min_value, float p_max_value);
|
||||||
RS::EnvironmentToneMapper environment_get_tone_mapper(RID p_env) const;
|
RS::EnvironmentToneMapper environment_get_tone_mapper(RID p_env) const;
|
||||||
float environment_get_exposure(RID p_env) const;
|
float environment_get_exposure(RID p_env) const;
|
||||||
float environment_get_white(RID p_env) const;
|
float environment_get_white(RID p_env) const;
|
||||||
|
float environment_get_min_value(RID p_env) const;
|
||||||
|
float environment_get_max_value(RID p_env) const;
|
||||||
|
|
||||||
// Fog
|
// Fog
|
||||||
void environment_set_fog(RID p_env, bool p_enable, const Color &p_light_color, float p_light_energy, float p_sun_scatter, float p_density, float p_height, float p_height_density, float p_aerial_perspective, float p_sky_affect, RS::EnvironmentFogMode p_mode);
|
void environment_set_fog(RID p_env, bool p_enable, const Color &p_light_color, float p_light_energy, float p_sun_scatter, float p_density, float p_height, float p_height_density, float p_aerial_perspective, float p_sky_affect, RS::EnvironmentFogMode p_mode);
|
||||||
|
|
|
||||||
|
|
@ -2810,6 +2810,7 @@ void RenderingServer::_bind_methods() {
|
||||||
ClassDB::bind_method(D_METHOD("viewport_set_parent_viewport", "viewport", "parent_viewport"), &RenderingServer::viewport_set_parent_viewport);
|
ClassDB::bind_method(D_METHOD("viewport_set_parent_viewport", "viewport", "parent_viewport"), &RenderingServer::viewport_set_parent_viewport);
|
||||||
ClassDB::bind_method(D_METHOD("viewport_attach_to_screen", "viewport", "rect", "screen"), &RenderingServer::viewport_attach_to_screen, DEFVAL(Rect2()), DEFVAL(DisplayServer::MAIN_WINDOW_ID));
|
ClassDB::bind_method(D_METHOD("viewport_attach_to_screen", "viewport", "rect", "screen"), &RenderingServer::viewport_attach_to_screen, DEFVAL(Rect2()), DEFVAL(DisplayServer::MAIN_WINDOW_ID));
|
||||||
ClassDB::bind_method(D_METHOD("viewport_set_render_direct_to_screen", "viewport", "enabled"), &RenderingServer::viewport_set_render_direct_to_screen);
|
ClassDB::bind_method(D_METHOD("viewport_set_render_direct_to_screen", "viewport", "enabled"), &RenderingServer::viewport_set_render_direct_to_screen);
|
||||||
|
ClassDB::bind_method(D_METHOD("viewport_set_tonemap_to_screen", "viewport", "enabled"), &RenderingServer::viewport_set_tonemap_to_screen);
|
||||||
ClassDB::bind_method(D_METHOD("viewport_set_canvas_cull_mask", "viewport", "canvas_cull_mask"), &RenderingServer::viewport_set_canvas_cull_mask);
|
ClassDB::bind_method(D_METHOD("viewport_set_canvas_cull_mask", "viewport", "canvas_cull_mask"), &RenderingServer::viewport_set_canvas_cull_mask);
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("viewport_set_scaling_3d_mode", "viewport", "scaling_3d_mode"), &RenderingServer::viewport_set_scaling_3d_mode);
|
ClassDB::bind_method(D_METHOD("viewport_set_scaling_3d_mode", "viewport", "scaling_3d_mode"), &RenderingServer::viewport_set_scaling_3d_mode);
|
||||||
|
|
@ -3022,6 +3023,7 @@ void RenderingServer::_bind_methods() {
|
||||||
ClassDB::bind_method(D_METHOD("environment_set_ambient_light", "env", "color", "ambient", "energy", "sky_contribution", "reflection_source"), &RenderingServer::environment_set_ambient_light, DEFVAL(RS::ENV_AMBIENT_SOURCE_BG), DEFVAL(1.0), DEFVAL(0.0), DEFVAL(RS::ENV_REFLECTION_SOURCE_BG));
|
ClassDB::bind_method(D_METHOD("environment_set_ambient_light", "env", "color", "ambient", "energy", "sky_contribution", "reflection_source"), &RenderingServer::environment_set_ambient_light, DEFVAL(RS::ENV_AMBIENT_SOURCE_BG), DEFVAL(1.0), DEFVAL(0.0), DEFVAL(RS::ENV_REFLECTION_SOURCE_BG));
|
||||||
ClassDB::bind_method(D_METHOD("environment_set_glow", "env", "enable", "levels", "intensity", "strength", "mix", "bloom_threshold", "blend_mode", "hdr_bleed_threshold", "hdr_bleed_scale", "hdr_luminance_cap", "glow_map_strength", "glow_map"), &RenderingServer::environment_set_glow);
|
ClassDB::bind_method(D_METHOD("environment_set_glow", "env", "enable", "levels", "intensity", "strength", "mix", "bloom_threshold", "blend_mode", "hdr_bleed_threshold", "hdr_bleed_scale", "hdr_luminance_cap", "glow_map_strength", "glow_map"), &RenderingServer::environment_set_glow);
|
||||||
ClassDB::bind_method(D_METHOD("environment_set_tonemap", "env", "tone_mapper", "exposure", "white"), &RenderingServer::environment_set_tonemap);
|
ClassDB::bind_method(D_METHOD("environment_set_tonemap", "env", "tone_mapper", "exposure", "white"), &RenderingServer::environment_set_tonemap);
|
||||||
|
ClassDB::bind_method(D_METHOD("environment_set_tonemap_range", "env", "min_value", "max_value"), &RenderingServer::environment_set_tonemap_range);
|
||||||
ClassDB::bind_method(D_METHOD("environment_set_adjustment", "env", "enable", "brightness", "contrast", "saturation", "use_1d_color_correction", "color_correction"), &RenderingServer::environment_set_adjustment);
|
ClassDB::bind_method(D_METHOD("environment_set_adjustment", "env", "enable", "brightness", "contrast", "saturation", "use_1d_color_correction", "color_correction"), &RenderingServer::environment_set_adjustment);
|
||||||
ClassDB::bind_method(D_METHOD("environment_set_ssr", "env", "enable", "max_steps", "fade_in", "fade_out", "depth_tolerance"), &RenderingServer::environment_set_ssr);
|
ClassDB::bind_method(D_METHOD("environment_set_ssr", "env", "enable", "max_steps", "fade_in", "fade_out", "depth_tolerance"), &RenderingServer::environment_set_ssr);
|
||||||
ClassDB::bind_method(D_METHOD("environment_set_ssao", "env", "enable", "radius", "intensity", "power", "detail", "horizon", "sharpness", "light_affect", "ao_channel_affect"), &RenderingServer::environment_set_ssao);
|
ClassDB::bind_method(D_METHOD("environment_set_ssao", "env", "enable", "radius", "intensity", "power", "detail", "horizon", "sharpness", "light_affect", "ao_channel_affect"), &RenderingServer::environment_set_ssao);
|
||||||
|
|
|
||||||
|
|
@ -966,6 +966,7 @@ public:
|
||||||
|
|
||||||
virtual void viewport_attach_to_screen(RID p_viewport, const Rect2 &p_rect = Rect2(), DisplayServer::WindowID p_screen = DisplayServer::MAIN_WINDOW_ID) = 0;
|
virtual void viewport_attach_to_screen(RID p_viewport, const Rect2 &p_rect = Rect2(), DisplayServer::WindowID p_screen = DisplayServer::MAIN_WINDOW_ID) = 0;
|
||||||
virtual void viewport_set_render_direct_to_screen(RID p_viewport, bool p_enable) = 0;
|
virtual void viewport_set_render_direct_to_screen(RID p_viewport, bool p_enable) = 0;
|
||||||
|
virtual void viewport_set_tonemap_to_screen(RID p_viewport, bool p_enable) = 0;
|
||||||
|
|
||||||
virtual void viewport_set_scaling_3d_mode(RID p_viewport, ViewportScaling3DMode p_scaling_3d_mode) = 0;
|
virtual void viewport_set_scaling_3d_mode(RID p_viewport, ViewportScaling3DMode p_scaling_3d_mode) = 0;
|
||||||
virtual void viewport_set_scaling_3d_scale(RID p_viewport, float p_scaling_3d_scale) = 0;
|
virtual void viewport_set_scaling_3d_scale(RID p_viewport, float p_scaling_3d_scale) = 0;
|
||||||
|
|
@ -1257,6 +1258,7 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
virtual void environment_set_tonemap(RID p_env, EnvironmentToneMapper p_tone_mapper, float p_exposure, float p_white) = 0;
|
virtual void environment_set_tonemap(RID p_env, EnvironmentToneMapper p_tone_mapper, float p_exposure, float p_white) = 0;
|
||||||
|
virtual void environment_set_tonemap_range(RID p_env, float p_min_value, float p_max_value) = 0;
|
||||||
virtual void environment_set_adjustment(RID p_env, bool p_enable, float p_brightness, float p_contrast, float p_saturation, bool p_use_1d_color_correction, RID p_color_correction) = 0;
|
virtual void environment_set_adjustment(RID p_env, bool p_enable, float p_brightness, float p_contrast, float p_saturation, bool p_use_1d_color_correction, RID p_color_correction) = 0;
|
||||||
|
|
||||||
virtual void environment_set_ssr(RID p_env, bool p_enable, int p_max_steps, float p_fade_in, float p_fade_out, float p_depth_tolerance) = 0;
|
virtual void environment_set_ssr(RID p_env, bool p_enable, int p_max_steps, float p_fade_in, float p_fade_out, float p_depth_tolerance) = 0;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue