Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/doitsujin/dxvk.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilip Rebohle <philip.rebohle@tu-dortmund.de>2023-01-16 15:31:02 +0300
committerPhilip Rebohle <philip.rebohle@tu-dortmund.de>2023-01-16 21:03:06 +0300
commitd0c762fefc3775285eda557de99ffcacfa956886 (patch)
treed8d1f46f222a46704d7ef21d0f32ee1a62a88b2c
parent3efd6ec34aa49a98811b1e9deff9692308b2c99b (diff)
[hud] Support HDR color spaceshud-hdr
Blending is broken if we need to do encoding in the shader, but we cannot do much about that without changing the rendering process, so this will have to do for now.
-rw-r--r--src/dxvk/hud/dxvk_hud.cpp7
-rw-r--r--src/dxvk/hud/shaders/hud_frag_common.glsl68
-rw-r--r--src/dxvk/hud/shaders/hud_graph_frag.frag20
-rw-r--r--src/dxvk/hud/shaders/hud_text_frag.frag15
4 files changed, 83 insertions, 27 deletions
diff --git a/src/dxvk/hud/dxvk_hud.cpp b/src/dxvk/hud/dxvk_hud.cpp
index 5a1af3c3..752e514b 100644
--- a/src/dxvk/hud/dxvk_hud.cpp
+++ b/src/dxvk/hud/dxvk_hud.cpp
@@ -79,7 +79,10 @@ namespace dxvk::hud {
const Rc<DxvkContext>& ctx,
VkSurfaceFormatKHR surfaceFormat,
VkExtent2D surfaceSize) {
- bool isSrgb = lookupFormatInfo(surfaceFormat.format)->flags.test(DxvkFormatFlag::ColorSpaceSrgb);
+ VkColorSpaceKHR colorSpace = surfaceFormat.colorSpace;
+
+ if (lookupFormatInfo(surfaceFormat.format)->flags.test(DxvkFormatFlag::ColorSpaceSrgb))
+ colorSpace = VK_COLOR_SPACE_PASS_THROUGH_EXT;
VkViewport viewport;
viewport.x = 0.0f;
@@ -97,7 +100,7 @@ namespace dxvk::hud {
ctx->setRasterizerState(m_rsState);
ctx->setBlendMode(0, m_blendMode);
- ctx->setSpecConstant(VK_PIPELINE_BIND_POINT_GRAPHICS, 0, isSrgb);
+ ctx->setSpecConstant(VK_PIPELINE_BIND_POINT_GRAPHICS, 0, colorSpace);
m_renderer.beginFrame(ctx, surfaceSize, m_scale);
}
diff --git a/src/dxvk/hud/shaders/hud_frag_common.glsl b/src/dxvk/hud/shaders/hud_frag_common.glsl
new file mode 100644
index 00000000..20b51c53
--- /dev/null
+++ b/src/dxvk/hud/shaders/hud_frag_common.glsl
@@ -0,0 +1,68 @@
+#define VK_COLOR_SPACE_SRGB_NONLINEAR_KHR (0)
+#define VK_COLOR_SPACE_EXTENDED_SRGB_LINEAR_EXT (1000104002)
+#define VK_COLOR_SPACE_HDR10_ST2084_EXT (1000104008)
+#define VK_COLOR_SPACE_PASS_THROUGH_EXT (1000104013)
+
+#define HUD_NITS (203.0f)
+
+const mat3 rec709_to_xyz = mat3(
+ 0.4123908, 0.2126390, 0.0193308,
+ 0.3575843, 0.7151687, 0.1191948,
+ 0.1804808, 0.0721923, 0.9505322);
+
+const mat3 xyz_to_rec2020 = mat3(
+ 1.7166512, -0.6666844, 0.0176399,
+ -0.3556708, 1.6164812, -0.0427706,
+ -0.2533663, 0.0157685, 0.9421031);
+
+const mat3 rec709_to_rec2020 = xyz_to_rec2020 * rec709_to_xyz;
+
+// Spec constants must always default to
+// zero for DXVK to handle them properly
+layout(constant_id = 0) const uint hud_color_space = 0;
+
+vec3 encodeSrgb(vec3 linear) {
+ bvec3 isLo = lessThanEqual(linear, vec3(0.0031308f));
+
+ vec3 loPart = linear * 12.92f;
+ vec3 hiPart = pow(linear, vec3(5.0f / 12.0f)) * 1.055f - 0.055f;
+ return mix(hiPart, loPart, isLo);
+}
+
+vec3 encodePq(vec3 nits) {
+ const float c1 = 0.8359375f;
+ const float c2 = 18.8515625f;
+ const float c3 = 18.6875f;
+ const float m1 = 0.1593017578125f;
+ const float m2 = 78.84375f;
+
+ vec3 y = clamp(nits / 10000.0f, vec3(0.0f), vec3(1.0f));
+ vec3 y_m1 = pow(y, vec3(m1));
+
+ vec3 num = c1 + c2 * y_m1;
+ vec3 den = 1.0f + c3 * y_m1;
+
+ return pow(num / den, vec3(m2));
+}
+
+vec3 encodeScRgb(vec3 nits) {
+ return nits / 80.0f;
+}
+
+vec3 encodeOutput(vec3 linear) {
+ switch (hud_color_space) {
+ default:
+ return linear;
+
+ case VK_COLOR_SPACE_SRGB_NONLINEAR_KHR:
+ return encodeSrgb(linear);
+
+ case VK_COLOR_SPACE_HDR10_ST2084_EXT: {
+ vec3 rec2020 = rec709_to_rec2020 * linear;
+ return encodePq(rec2020 * HUD_NITS);
+ }
+
+ case VK_COLOR_SPACE_EXTENDED_SRGB_LINEAR_EXT:
+ return encodeScRgb(linear * HUD_NITS);
+ }
+}
diff --git a/src/dxvk/hud/shaders/hud_graph_frag.frag b/src/dxvk/hud/shaders/hud_graph_frag.frag
index 224eb061..6b1a22ef 100644
--- a/src/dxvk/hud/shaders/hud_graph_frag.frag
+++ b/src/dxvk/hud/shaders/hud_graph_frag.frag
@@ -1,6 +1,8 @@
#version 450
-layout(constant_id = 0) const bool srgbSwapchain = false;
+#extension GL_GOOGLE_include_directive : require
+
+#include "hud_frag_common.glsl"
layout(location = 0) in vec2 v_coord;
layout(location = 0) out vec4 o_color;
@@ -24,14 +26,6 @@ uniform push_data_t {
vec2 scale;
};
-vec3 linearToSrgb(vec3 color) {
- bvec3 isLo = lessThanEqual(color, vec3(0.0031308f));
-
- vec3 loPart = color * 12.92f;
- vec3 hiPart = pow(color, vec3(5.0f / 12.0f)) * 1.055f - 0.055f;
- return mix(hiPart, loPart, isLo);
-}
-
void main() {
float cx = v_coord.x * float(count);
float fx = fract(cx);
@@ -53,9 +47,7 @@ void main() {
o_color = mix(
unpackUnorm4x8(p0.color),
unpackUnorm4x8(p1.color), fx);
-
- if (!srgbSwapchain)
- o_color.rgb = linearToSrgb(o_color.rgb);
-
o_color *= alpha;
-} \ No newline at end of file
+
+ o_color.rgb = encodeOutput(o_color.rgb);
+}
diff --git a/src/dxvk/hud/shaders/hud_text_frag.frag b/src/dxvk/hud/shaders/hud_text_frag.frag
index 86d3a909..83e23dd4 100644
--- a/src/dxvk/hud/shaders/hud_text_frag.frag
+++ b/src/dxvk/hud/shaders/hud_text_frag.frag
@@ -1,6 +1,8 @@
#version 450
-layout(constant_id = 0) const bool srgbSwapchain = false;
+#extension GL_GOOGLE_include_directive : require
+
+#include "hud_frag_common.glsl"
layout(binding = 2) uniform sampler2D s_font;
@@ -9,14 +11,6 @@ layout(location = 1) in vec4 v_color;
layout(location = 0) out vec4 o_color;
-vec3 linearToSrgb(vec3 color) {
- bvec3 isLo = lessThanEqual(color, vec3(0.0031308f));
-
- vec3 loPart = color * 12.92f;
- vec3 hiPart = pow(color, vec3(5.0f / 12.0f)) * 1.055f - 0.055f;
- return mix(hiPart, loPart, isLo);
-}
-
float sampleAlpha(float alpha_bias, float dist_range) {
float value = textureLod(s_font, v_texcoord, 0).r + alpha_bias - 0.5f;
float dist = value * dot(vec2(dist_range, dist_range), 1.0f / fwidth(v_texcoord.xy));
@@ -34,6 +28,5 @@ void main() {
o_color.a = r_alpha_shadow * v_color.a;
o_color.rgb *= o_color.a;
- if (!srgbSwapchain)
- o_color.rgb = linearToSrgb(o_color.rgb);
+ o_color.rgb = encodeOutput(o_color.rgb);
}