Apple: Support output to EDR (HDR) displays#106814
Apple: Support output to EDR (HDR) displays#106814akien-mga merged 1 commit intogodotengine:masterfrom
Conversation
351fe7a to
ec3f97b
Compare
|
There have been some upstream API changes (like splitting The primary useful point of data would be which of high/low precision is faster on macos (and that they both work, on wayland they used to not work until changes were made to the godot vulkan driver). |
There was a problem hiding this comment.
Tested locally with the MRP from #94496 (review), it works as expected (Metal and Vulkan).
Mac specifications
- MacBook Pro 16 2024
- SoC: M4 Max 16-core CPU, 40-core GPU
- RAM: 48 GB
- SSD: 1 TB
- OS: macOS 15.5
FSR2 works on Metal and MoltenVK, and MetalFX Temporal works on Metal when HDR is enabled (with no unintended effects). However, MetalFX Spatial is broken on my end, but I also encountered this issue with HDR disabled and even on 4.4.1.stable, so it's not related to this PR:
The Use Screen Luminance project setting seems to be working. When enabled, there's a perfect match for UI brightness between SDR and HDR (that's macOS advantage at play 😛). However, changing Max Luminance doesn't seem to do anything, even when Use Screen Luminance is unchecked and after restarting the editor.
When using Metal, Prefer High Precision impacts visuals significantly on bright highlights, especially red ones. Red highlights become orange-ish when the option is disabled, so having it enabled is more accurate to the tonemapped SDR presentation (except brighter). This shift in tone is not present when using MoltenVK (where both options look indistinguishable to the naked eye... with one exception I could spot below), even though there's still a performance difference in small window sizes.
| Off | On |
|---|---|
![]() |
![]() |
Notice the blue hue in the reflection being more present when Prefer High Precision is enabled. This difference is present in both Metal and MoltenVK. (Sorry for the tonemapped screenshots, but I couldn't figure out how to take a proper HDR screenshot on macOS.)
Lastly, I get this error on every startup:
ERROR: Not implemented
at: window_is_hdr_output_using_screen_luminance (platform/macos/display_server_macos.mm:3218)
I'm using Reinhard tonemapping with a whitepoint of 4.0 for all tests here, as it seems to provide comparable visuals to Reinhard tonemapping with a whitepoint of 1.0 when HDR is off (except with bright highlights actually being brighter on screen this time around).
Benchmark
Running the test project. I've tested each run at least twice as many of the results are unexpected, namely HDR off being slower than HDR on (with high precision disabled).
Also, HDR on with high precision is basically just as fast in this test project, especially at lower resolutions. In fullscreen, HDR on with high precision is faster than HDR on without high precision. This contrasts with the usual wisdom of "HDR output has a 5-10% performance cost on the GPU", which I've seen and experienced in many (Windows) games.
1152x648 window
| Backend | HDR off | HDR on | HDR on (prefer high precision) |
|---|---|---|---|
| Metal | 681 FPS (1.47 mspf) | 1443 FPS (0.69 mspf) | 688 FPS (1.45 mspf) |
| MoltenVK | 694 FPS (1.44 mspf) | 1439 FPS (0.69 mspf) | 705 FPS (1.42 mspf) |
Fullscreen
| Backend | HDR off | HDR on | HDR on (prefer high precision) |
|---|---|---|---|
| Metal | 385 FPS (2.60 mspf) | 360 FPS (2.78 mspf) | 374 FPS (2.67 mspf) |
| MoltenVK | 347 FPS (2.88 mspf) | 326 FPS (3.07 mspf) | 343 FPS (2.92 mspf) |
|
@Calinou Thanks for testing this on Mac. There's a chance that some of this is from old bugs that have since been since been fixed (this hasn't been rebased in a while) but most likely there's some very important performance considerations around high/low precision on mac that would be worth bringing up with allenwp. As for the hue shifts hopefully it's just a bug in the metal implemtation (the colorspaces chosen in metal say something about P3 which seems strange to me) but if there's also a bug in the vulkan implementation it's good to have caught it here. |
@ArchercatNEO absolutely! Just waiting for the upstream PR to stabilise and merge and I'll rework this PR. I'm very excited to add EDR support for Apple. |
I wonder if you would observe the same if you target a non-HDR display? Pure speculation, but is it possible that Apple's rendering / compositing pipeline on the MacBook Pro's built-in display is always HDR, so SDR content must be converted? Generally, I've seen all Metal literature indicate the default pixel format it BGRA8 for views. |
|
I think you can set the colorspace of the display to be SDR-only. |
|
any way to get a precompiled build of this PR (a github actions CI link with artifact?) to do some testing on a mac Mini M4 with HDR monitor? I have tested succesfully godot HDR Windows and Linux HDR support using artifacts.. but seems the current build has not Mac build artifact: |
I just looked into doing a rebase and pushing that, which would generate a new build artifact, but I'm having issues getting this PR working on my Mac when running a game project (before or after my rebase). We'll need to wait a bit longer to really test out Mac OS HDR output support. |
ec3f97b to
ca58450
Compare
|
Alright, it turns out my issues were just that I needed to run the game without the "Embed on next play" option selected in my Game workspace. Once I did this, it works fine. I pushed the rebase and updates to fix colour space issues, but this PR now fails checks due to |
a396ee6 to
187a9db
Compare
I'll have to add some availability checks to guard against running on older OSs |
9dc1f3f to
232a6dc
Compare
|
@stuartcarnie I've made changes to this PR to correct the way that Max/Reference luminance is handled. The rebase is going to be substantial, so please take note of the current state of the PR before the rebase; put simply, max luminance needs to be calculated as follows: And reference luminance can be calculated based on that and the current max value: |
@allenwp sounds good! Fortunately, GitHub makes it easy to compare between commits / rebases |
02c88ab to
6652ec2
Compare
allenwp
left a comment
There was a problem hiding this comment.
Thanks, Stuart, I think we're very close to finishing this!
In addition to my other suggestions, <constant name="FEATURE_HDR_OUTPUT" value="35" enum="Feature"> of doc/classes/DisplayServer.xml needs to be updated with supported platforms.
I've finished looking over the PR now; I expect I won't have any further review comments or suggestions.
4933a14 to
6207597
Compare
|
6207597 to
d5504ff
Compare
|
@allenwp I re-synced and pushed the |
allenwp
left a comment
There was a problem hiding this comment.
To me, this PR appears to be working well and is ready for merging! Thanks, Stuart!
Some notes worth mentioning:
- I have not tested visionOS changes so I cannot verify if they are implemented correctly.
- Vulkan support should probably be added as a followup PR, since we'll need to maintain Vulkan HDR output behaviour for Wayland and Android anyway. The implementation should be trivial (it might be just a matter of setting
hdr_linear_luminance_scaleto100.0on macOS and visionOS and... maybe203on iOS??) - I made a comment about
_THREAD_SAFE_METHOD_inDisplayServerAppleEmbedded::window...functions. I know basically nothing about threading in Godot, so I leave that to someone else to verify.
I'm really excited to see this out in the wild because macOS and iOS have the best HDR output implementations with the highest colour consistency and accuracy of all major platforms. Great work, Stuart!
|
I don't seem to be able to compile this PR on my MBP M4 Pro for some reason: Any idea why? |
|
@blueskythlikesclouds One time, I also had trouble compiling for Mac using Edit: I should clarify that this OS restart was due to applying a security patch for macOS Sequoia. But the end result was still that Mac builds started working again after the restart. |
|
No issue with basic |
I do not get this error on M4 Pro, with Xcode 26.3 (17C529). This property is documented as macOS 26+, but it's in https://developer.apple.com/documentation/appkit/nsscreen/cgdirectdisplayid-7uvhw?language=objc |
|
Hmm, odd. It doesn't compile from VSCode or the terminal but compiling within XCode works. For reference, my macOS version is Sequoia 15.7.3 |
It might be a mismatch of Xcode and command line tools, which sometimes happens:
|
|
@blueskythlikesclouds I was on a similar version of Sequoia when I ran into compilation issues. Then I upgraded to 15.7.4 and the compile succeeded. See if that fixes the issue for you. |
This works. |
|
Thanks! Amazing work from everyone involved! 🎉 |
|
getting a build failure on this post-merge: on m4 mac mini running 15.7.4 w/xcode 16.4, macos 15.5 sdk |
|
See the discussion above, I had the same problem. #106814 (comment) Make sure your Xcode is updated. |
i should've scrolled up, thanks! |


Add support for EDR displays to Apple platforms.
Depends on
Implements godotengine/godot-proposals#10817 for Apple platforms
Testing/Sample project: https://github.com/DarkKilauea/godot-hdr-output
Note
Apple's HDR Content page is also useful.
In particular, Understanding EDR Values:
Important
visionOS does not provide APIs to query the EDR headroom or maximum potential, so these are hard-coded to 100 nits and 200 nits maximum, which was learned from https://developer.apple.com/videos/play/wwdc2023/10089/?time=603