Skip to content

Commit

Permalink
PerceptualHDR + Metal HDR Support
Browse files Browse the repository at this point in the history
  • Loading branch information
Sam-Belliveau committed Mar 9, 2024
1 parent 5a81916 commit 3a37bcf
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 2 deletions.
72 changes: 72 additions & 0 deletions Data/Sys/Shaders/PerceptualHDR.glsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/*
[configuration]
[OptionRangeFloat]
GUIName = Desaturation
OptionName = DESATURATION
MinValue = 0.0
MaxValue = 1.0
StepAmount = 0.1
DefaultValue = 0.0
[/configuration]
*/

/***** Linear <--> Oklab *****/

const mat4 RGBtoLMS = mat4(
0.4122214708, 0.2119034982, 0.0883024619, 0.0000000000,
0.5363325363, 0.6806995451, 0.2817188376, 0.0000000000,
0.0514459929, 0.1073969566, 0.6299787005, 0.0000000000,
0.0000000000, 0.0000000000, 0.0000000000, 1.0000000000);

const mat4 LMStoOklab = mat4(
0.2104542553, 1.9779984951, 0.0259040371, 0.0000000000,
0.7936177850, -2.4285922050, 0.7827717662, 0.0000000000,
-0.0040720468, 0.4505937099, -0.8086757660, 0.0000000000,
0.0000000000, 0.0000000000, 0.0000000000, 1.0000000000);

float4 LinearRGBToOklab(float4 c)
{
return LMStoOklab * pow(RGBtoLMS * c, float4(1.0 / 3.0));
}

const mat4 OklabtoLMS = mat4(
1.0000000000, 1.0000000000, 1.0000000000, 0.0000000000,
0.3963377774, -0.1055613458, -0.0894841775, 0.0000000000,
0.2158037573, -0.0638541728, -1.2914855480, 0.0000000000,
0.0000000000, 0.0000000000, 0.0000000000, 1.0000000000);

const mat4 LMStoRGB = mat4(
4.0767416621, -1.2684380046, -0.0041960863, 0.0000000000,
-3.3077115913, 2.6097574011, -0.7034186147, 0.0000000000,
0.2309699292, -0.3413193965, 1.7076147010, 0.0000000000,
0.0000000000, 0.0000000000, 0.0000000000, 1.0000000000);

float4 OklabToLinearRGB(float4 c)
{
return max(LMStoRGB * pow(OklabtoLMS * c, float4(3.0)), 0.0);
}

void main()
{
float4 color = Sample();

// Nothing to do here, we are in SDR
if (!OptionEnabled(hdr_output) || !OptionEnabled(linear_space_output)) {
SetOutput(color);
return;
}

const float hdr_paper_white = hdr_paper_white_nits / hdr_sdr_white_nits;
color.rgb /= hdr_paper_white;

float4 oklab_color = LinearRGBToOklab(color);

float lum = oklab_color.x;
oklab_color.z *= pow(hdr_paper_white, pow(oklab_color.x, DESATURATION) / 3.0);
oklab_color.y *= pow(hdr_paper_white, pow(oklab_color.x, DESATURATION) / 3.0);
oklab_color.x *= pow(hdr_paper_white, pow(oklab_color.x, 1.0) / 3.0);

SetOutput(OklabToLinearRGB(oklab_color));
}
9 changes: 7 additions & 2 deletions Source/Core/VideoBackends/Metal/MTLMain.mm
Original file line number Diff line number Diff line change
Expand Up @@ -119,8 +119,13 @@ static bool WindowSystemTypeSupportsMetal(WindowSystemType type)

MRCOwned<CAMetalLayer*> layer = MRCRetain(static_cast<CAMetalLayer*>(wsi.render_surface));
[layer setDevice:adapter];
if (Util::ToAbstract([layer pixelFormat]) == AbstractTextureFormat::Undefined)
[layer setPixelFormat:MTLPixelFormatBGRA8Unorm];
[layer setWantsExtendedDynamicRangeContent:YES];
[layer setPixelFormat:MTLPixelFormatRGBA16Float];

const CFStringRef name = kCGColorSpaceExtendedLinearSRGB;
CGColorSpaceRef colorspace = CGColorSpaceCreateWithName(name);
[layer setColorspace:colorspace];
CGColorSpaceRelease(colorspace);

ObjectCache::Initialize(std::move(adapter));
g_state_tracker = std::make_unique<StateTracker>();
Expand Down
1 change: 1 addition & 0 deletions Source/Core/VideoBackends/Metal/MTLUtil.mm
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@
config->backend_info.bSupportsPartialMultisampleResolve = false;
config->backend_info.bSupportsDynamicVertexLoader = true;
config->backend_info.bSupportsVSLinePointExpand = true;
config->backend_info.bSupportsHDROutput = true;
}

void Metal::Util::PopulateBackendInfoAdapters(VideoConfig* config,
Expand Down

0 comments on commit 3a37bcf

Please sign in to comment.