From 2689204d744e3d27e2f4e7b5011e5df63c6326f2 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Fri, 13 Dec 2019 14:03:00 +0100 Subject: [PATCH] [hud] Enable manual sRGB conversion for non-sRGB swap chains We still blend in the wrong color space, but text should be a bit more readable in some games now. --- src/d3d11/d3d11_swapchain.cpp | 2 +- src/dxvk/hud/dxvk_hud.cpp | 20 +++++++++++++++++--- src/dxvk/hud/dxvk_hud.h | 9 +++++++-- src/dxvk/hud/shaders/hud_line_frag.frag | 13 +++++++++++++ src/dxvk/hud/shaders/hud_text_frag.frag | 14 ++++++++++++++ 5 files changed, 52 insertions(+), 6 deletions(-) diff --git a/src/d3d11/d3d11_swapchain.cpp b/src/d3d11/d3d11_swapchain.cpp index e4794163..98e107eb 100644 --- a/src/d3d11/d3d11_swapchain.cpp +++ b/src/d3d11/d3d11_swapchain.cpp @@ -335,7 +335,7 @@ namespace dxvk { m_context->draw(3, 1, 0, 0); if (m_hud != nullptr) - m_hud->render(m_context, info.imageExtent); + m_hud->render(m_context, info.format, info.imageExtent); if (i + 1 >= SyncInterval) m_context->signal(m_frameLatencySignal, frameId); diff --git a/src/dxvk/hud/dxvk_hud.cpp b/src/dxvk/hud/dxvk_hud.cpp index 26b4c46b..b6dfe793 100644 --- a/src/dxvk/hud/dxvk_hud.cpp +++ b/src/dxvk/hud/dxvk_hud.cpp @@ -53,13 +53,17 @@ namespace dxvk::hud { } - void Hud::render(const Rc& ctx, VkExtent2D surfaceSize) { + void Hud::render( + const Rc& ctx, + VkSurfaceFormatKHR surfaceFormat, + VkExtent2D surfaceSize) { m_uniformData.surfaceSize = surfaceSize; this->updateUniformBuffer(ctx, m_uniformData); - this->setupRendererState(ctx); + this->setupRendererState(ctx, surfaceFormat); this->renderHudElements(ctx); + this->resetRendererState(ctx); } @@ -68,17 +72,27 @@ namespace dxvk::hud { } - void Hud::setupRendererState(const Rc& ctx) { + void Hud::setupRendererState( + const Rc& ctx, + VkSurfaceFormatKHR surfaceFormat) { + bool isSrgb = imageFormatInfo(surfaceFormat.format)->flags.test(DxvkFormatFlag::ColorSpaceSrgb); + ctx->setRasterizerState(m_rsState); ctx->setBlendMode(0, m_blendMode); ctx->bindResourceBuffer(0, DxvkBufferSlice(m_uniformBuffer)); + ctx->setSpecConstant(VK_PIPELINE_BIND_POINT_GRAPHICS, 0, isSrgb); m_renderer.beginFrame(ctx, m_uniformData.surfaceSize); } + void Hud::resetRendererState(const Rc& ctx) { + ctx->setSpecConstant(VK_PIPELINE_BIND_POINT_GRAPHICS, 0, 0); + } + + void Hud::renderHudElements(const Rc& ctx) { m_hudItems.render(m_renderer); } diff --git a/src/dxvk/hud/dxvk_hud.h b/src/dxvk/hud/dxvk_hud.h index c5d07c77..0e0abef7 100644 --- a/src/dxvk/hud/dxvk_hud.h +++ b/src/dxvk/hud/dxvk_hud.h @@ -45,8 +45,9 @@ namespace dxvk::hud { * \param [in] surfaceSize Image size, in pixels */ void render( - const Rc& ctx, - VkExtent2D surfaceSize); + const Rc& ctx, + VkSurfaceFormatKHR surfaceFormat, + VkExtent2D surfaceSize); /** * \brief Adds a HUD item if enabled @@ -85,6 +86,10 @@ namespace dxvk::hud { HudItemSet m_hudItems; void setupRendererState( + const Rc& ctx, + VkSurfaceFormatKHR surfaceFormat); + + void resetRendererState( const Rc& ctx); void renderHudElements( diff --git a/src/dxvk/hud/shaders/hud_line_frag.frag b/src/dxvk/hud/shaders/hud_line_frag.frag index 7e4843ab..251b9ea0 100644 --- a/src/dxvk/hud/shaders/hud_line_frag.frag +++ b/src/dxvk/hud/shaders/hud_line_frag.frag @@ -1,10 +1,23 @@ #version 450 +layout(constant_id = 1249) const bool srgbSwapchain = false; + layout(location = 0) 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); +} + void main() { o_color = vec4( v_color.rgb * v_color.a, v_color.a); + + if (!srgbSwapchain) + o_color.rgb = linearToSrgb(o_color.rgb); } \ No newline at end of file diff --git a/src/dxvk/hud/shaders/hud_text_frag.frag b/src/dxvk/hud/shaders/hud_text_frag.frag index 875474f1..6d5fd907 100644 --- a/src/dxvk/hud/shaders/hud_text_frag.frag +++ b/src/dxvk/hud/shaders/hud_text_frag.frag @@ -1,5 +1,8 @@ #version 450 +layout(constant_id = 1249) const bool srgbSwapchain = false; + +layout(set = 0, binding = 0) uniform texture2D s_base; layout(set = 0, binding = 1) uniform sampler2D s_font; layout(location = 0) in vec2 v_texcoord; @@ -10,6 +13,14 @@ uniform push_data { vec4 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 = texture(s_font, v_texcoord).r + alpha_bias - 0.5f; float dist = value * dot(vec2(dist_range, dist_range), 1.0f / fwidth(v_texcoord.xy)); @@ -25,4 +36,7 @@ void main() { o_color = mix(r_shadow, r_center, r_alpha_center); o_color.rgb *= o_color.a; + + if (!srgbSwapchain) + o_color.rgb = linearToSrgb(o_color.rgb); } \ No newline at end of file