Skip to content

Conversation

tebjan
Copy link
Member

@tebjan tebjan commented Apr 12, 2025

PR Details

This PR introduces support for rendering to High Dynamic Range (HDR) displays by enabling configuration of the swap chain's output color space and pixel format.

Key Changes:

  1. ColorSpaceType Enum: Added a new Stride.Graphics.ColorSpaceType enum (in ColorSpace.cs) which mirrors the DXGI_COLOR_SPACE_TYPE values.
  2. GraphicsPresenter.SetOutputColorSpace Method: Added a new public method GraphicsPresenter.SetOutputColorSpace(ColorSpaceType colorSpace, PixelFormat format). This is the primary way for users to configure the desired output. Calling this method will:
    • Update the presenter's description.
    • Recreate the underlying swap chain (using IDXGISwapChain3::SetColorSpace1 on D3D11/12) with the specified color space.
    • Resize back buffer and depth stencil buffers accordingly.
  3. Integration:
    • PresentationParameters now includes an OutputColorSpace property.
    • GameWindowRenderer uses this property and allows setting PreferredOutputColorSpace to trigger a presenter update.
    • The Direct3D SwapChainGraphicsPresenter applies the OutputColorSpace when creating/recreating the swap chain.
    • Comments added to clarify which PixelFormat and ColorSpaceType combinations are intended for specific HDR standards (scRGB, HDR10).

How to Use HDR Output:

To enable HDR rendering, you need to get the Game.GraphicsDevice.Presenter and call the new SetOutputColorSpace method with the appropriate ColorSpaceType and PixelFormat. This should typically be done after the game has started and the graphics device is initialized, for example, within a game script's Start or Update method.

Common combinations include:

  • HDR10 / BT.2100 PQ: Use ColorSpaceType.RgbFullG2084NoneP2020 with PixelFormat.R10G10B10A2_UNorm. This requires the rendering pipeline to output colors matching the PQ transfer function and Rec.2020 primaries.
  • scRGB (Linear): Use ColorSpaceType.RgbFullG10NoneP709 with PixelFormat.R16G16B16A16_Float. This allows for linear rendering in a wider gamut, relying on the Windows Desktop Window Manager (DWM) for final conversion to the display.
  • Standard SDR with gamma 2.2: Use ColorSpaceType.RgbFullG22NoneP709 with an 8-bit format like PixelFormat.R8G8B8A8_UNorm_SRgb.

Example Script:

using Stride.Engine;
using Stride.Graphics;
using Stride.Core.Diagnostics;
using System; 

namespace MyGameNamespace;

public class SetHdrOnStart : StartupScript
{
    public override void Start()
    {
        try
        {
            Game.GraphicsDevice.Presenter.SetOutputColorSpace(
                ColorSpaceType.RgbFullG10NoneP709,
                PixelFormat.R16G16B16A16_Float
            );
        }
        catch (Exception ex)
        {
            Log.Error($"Failed to set HDR color space: {ex.Message}", ex);
        }
    }
}

Important Considerations:

  • Hardware/OS Support: HDR output requires a compatible display, GPU, drivers, and OS configuration (e.g., "Use HDR" enabled in Windows display settings). The SetOutputColorSpace call may fail if the combination is not supported. Error handling is recommended.
  • Rendering Pipeline: When using HDR output (especially HDR10/PQ), the game's rendering pipeline (lighting, tonemapping, color grading) needs to be adjusted to correctly produce colors within the target color space and dynamic range. Using scRGB allows for a more traditional linear rendering workflow, with the OS handling the final tone mapping.
  • Performance: Using higher bit-depth formats like R16G16B16A16_Float increases memory bandwidth usage compared to standard 8-bit formats.

See also Microsoft's documentation on HDR with DirectX:

Types of changes

  • Docs change / refactoring / dependency upgrade
  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)

Checklist

  • My change requires a change to the documentation.
  • I have added tests to cover my changes.
  • All new and existing tests passed.
  • I have built and run the editor to try this change out.

Copy link

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.

Comments suppressed due to low confidence (1)

sources/engine/Stride/Graphics/ColorSpace.cs:159

  • [nitpick] The enum member 'YcbcrStudioGhlgTopleftP2020' deviates from the usual gamma notation pattern; please confirm if 'Ghlg' is intentional or if it should be 'G22'.
YcbcrStudioGhlgTopleftP2020 = 18,

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
@Eideren
Copy link
Collaborator

Eideren commented Apr 26, 2025

Would be nice to mention in the crossplatform classes like the window and presenter that this is only supported on directx, looks like you disabled edits from maintainers so I can't take care of this for you.

@Kryptos-FR
Copy link
Member

Should the new type and code be guarded against some #define so that if someone builds the engine for OpenGL only, they don't appear at all?

@Eideren
Copy link
Collaborator

Eideren commented Apr 30, 2025

For crossplatform purposes, I would rather we avoid compile-time checks wherever possible to ensure we have the least amount of friction with how user build their games, I would rather we notify user of the lack of support than force them to setup a compile time branch for such a simple feature. That's what we're already doing for most missing features between graphics apis actually, so it would make sense to continue in the same direction for this one I think.

@tebjan
Copy link
Member Author

tebjan commented May 3, 2025

Would be nice to mention in the crossplatform classes like the window and presenter that this is only supported on directx, looks like you disabled edits from maintainers so I can't take care of this for you.

I'll enable this, was not intentional. Thanks!

tebjan added 2 commits May 3, 2025 12:40
…com/vvvv/stride into dev/tebjan/add-hdr-10bit-backbuffer

# Conflicts:
#	sources/engine/Stride.Graphics/GraphicsPresenter.cs
@tebjan
Copy link
Member Author

tebjan commented May 3, 2025

It looks like I can't enable it because I am not the repo's owner. But I've added the info to the public properties.

@Eideren Eideren merged commit 5b7d76e into stride3d:master May 3, 2025
2 checks passed
@Eideren Eideren changed the title [Graphics] Enable rendering to HDR displays on DirectX/Windows feat: Enable rendering to HDR displays on DirectX/Windows May 3, 2025
@Eideren
Copy link
Collaborator

Eideren commented May 3, 2025

Thanks !

@tebjan tebjan deleted the dev/tebjan/add-hdr-10bit-backbuffer branch May 4, 2025 09:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants