[PATCH v4 0/3] MR10567: wined3d: fix vk swapchain rendering too dark by supporting UNORM to SRGB...
wined3d: fix vk swapchain rendering too dark by supporting UNORM to SRGB conversion for brightness similar to gl This merge request addresses: https://bugs.winehq.org/show_bug.cgi?id=45364 Frostpunk is very dark Very dark rendering issues for Frostpunk seem to match the same problem for Vulkan renderer for "Against the Storm": - https://bugs.winehq.org/show_bug.cgi?id=58632 - https://bugs.winehq.org/attachment.cgi?id=80656 Running both games with gl renderer seems to fix excessive darkness: - https://bugs.winehq.org/attachment.cgi?id=80654 - https://bugs.winehq.org/attachment.cgi?id=80690 Vulkan renderer seems to be missing SRGB conversion handling availiable for GL renderer. GL renderer can be forced to render darker the same as Vulkan by bypassing EXT_TEXTURE_SRGB support for ./dlls/wined3d/utils.c: ``` @@ -3133,7 +3146,7 @@ static BOOL init_format_texture_info(struct wined3d_adapter *adapter, struct win continue; copy_format(adapter, &srgb_format->f, &format->f); +#if 000 if (gl_info->supported[EXT_TEXTURE_SRGB] && !(adapter->d3d_info.wined3d_creation_flags & WINED3D_SRGB_READ_WRITE_CONTROL)) { @@ -3142,6 +3155,7 @@ static BOOL init_format_texture_info(struct wined3d_adapter *adapter, struct win format_set_caps(&srgb_format->f, WINED3D_FORMAT_CAP_SRGB_READ | WINED3D_FORMAT_CAP_SRGB_WRITE); query_internal_format(adapter, srgb_format, &format_texture_info[i], gl_info, TRUE); } +#endif } ``` This merge request patch allows Vulkan renderer to perform SRGB conversion for wined3d_swapchain_vk_select_vk_format() to mimic the GL capability. Changing VkSwapchainCreateInfoKHR imageColorSpace from VK_COLOR_SPACE_SRGB_NONLINEAR_KHR for `wined3d_swapchain_vk_create_vulkan_swapchain()` had no effect despite enabling VK_EXT_swapchain_colorspace for dlls/win32u/vulkan.c `convert_instance_create_info():` https://docs.vulkan.org/refpages/latest/refpages/source/VkColorSpaceKHR.html Therefore converting UNORM to SRGB was chosen similar to how the GL renderer seems to handle it: ``` static const struct wined3d_format_srgb_info format_srgb_info[] = { {WINED3DFMT_R8G8B8A8_UNORM_SRGB, WINED3DFMT_R8G8B8A8_UNORM}, {WINED3DFMT_BC1_UNORM_SRGB, WINED3DFMT_BC1_UNORM}, {WINED3DFMT_BC2_UNORM_SRGB, WINED3DFMT_BC2_UNORM}, {WINED3DFMT_BC3_UNORM_SRGB, WINED3DFMT_BC3_UNORM}, {WINED3DFMT_B8G8R8A8_UNORM_SRGB, WINED3DFMT_B8G8R8A8_UNORM}, {WINED3DFMT_B8G8R8X8_UNORM_SRGB, WINED3DFMT_B8G8R8X8_UNORM}, {WINED3DFMT_BC7_UNORM_SRGB, WINED3DFMT_BC7_UNORM}, }; ``` Its unclear whether SRGB conversion should always happen or only for particular games so the patch leaves the Vulkan renderer without SRGB conversion by default. Therefore the patch adds a new WINE_D3D_CONFIG flag named "vk_swap_srgb" to force the Vulkan renderer to perform SRGB conversion for the swapchain. By default vk_swap_srgb is set to FALSE or 0: `WINE_D3D_CONFIG=vk_swap_srgb=0,renderer=vulkan` To force vk_swap_srgb to TRUE or 1: `WINE_D3D_CONFIG=vk_swap_srgb=1,renderer=vulkan` For example, launching Frostpunk via the following after the patch fixes the dark rendering for Vulkan and appears brighter similar to the GL renderer: `WINEDEBUG=-all mangohud --dlsym WINE_D3D_CONFIG=csmt=0x1,renderer=vulkan,vk_swap_srgb=1 WINEPREFIX=/home/any/wine_stianlow_wow64_new_pfx ~/tmp/wine_stianlow_wow64_new_install/bin/wine /home/any/wine_stianlow_wow64_new_pfx/drive_c/GOG\ Games/Frostpunk/Frostpunk.exe` Some SRGB handling was added several years ago but not for mapping UNORM to SRGB that this patch adds: ``` 6f55c8d1c56 * wined3d: Use an sRGB fallback format for sRGB formats in wined3d_swapchain_vk_select_vk_format(). Author: Henri Verbeet <hverbeet@codeweavers.com> CommitDate: Wed Dec 9 16:29:28 2020 +0100 ``` If UNORM to SRGB should be enabled by default then this patch may be changed so that vk_swap_srgb defaults to TRUE. -- v4: wined3d: fix vk swapchain rendering too dark by supporting rtvs for swapchain back_buffers > 1 Revert "wined3d: fix vk swapchain rendering too dark by supporting UNORM to SRGB conversion for brightness similar to gl" wined3d: fix vk swapchain rendering too dark by supporting UNORM to SRGB conversion for brightness similar to gl https://gitlab.winehq.org/wine/wine/-/merge_requests/10567
From: Stian Low <wineryyyyy@gmail.com> --- dlls/wined3d/swapchain.c | 11 ++++++++--- dlls/wined3d/utils.c | 13 +++++++++++++ dlls/wined3d/wined3d_main.c | 6 ++++++ dlls/wined3d/wined3d_private.h | 2 ++ 4 files changed, 29 insertions(+), 3 deletions(-) diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c index 4c20587b81d..ac61a6b64a0 100644 --- a/dlls/wined3d/swapchain.c +++ b/dlls/wined3d/swapchain.c @@ -755,6 +755,7 @@ static VkFormat wined3d_swapchain_vk_select_vk_format(struct wined3d_swapchain_v { struct wined3d_device_vk *device_vk = wined3d_device_vk(swapchain_vk->s.device); const struct wined3d_swapchain_desc *desc = &swapchain_vk->s.state.desc; + enum wined3d_format_id backbuffer_format; const struct wined3d_vk_info *vk_info; struct wined3d_adapter_vk *adapter_vk; const struct wined3d_format *format; @@ -768,7 +769,11 @@ static VkFormat wined3d_swapchain_vk_select_vk_format(struct wined3d_swapchain_v vk_physical_device = adapter_vk->physical_device; vk_info = &adapter_vk->vk_info; - if ((format = wined3d_get_format(&adapter_vk->a, desc->backbuffer_format, WINED3D_BIND_RENDER_TARGET))) + backbuffer_format = desc->backbuffer_format; + if (wined3d_settings.vk_swap_srgb) + backbuffer_format = wined3d_get_format_srgb(desc->backbuffer_format); + + if ((format = wined3d_get_format(&adapter_vk->a, backbuffer_format, WINED3D_BIND_RENDER_TARGET))) vk_format = wined3d_format_vk(format)->vk_format; else vk_format = VK_FORMAT_B8G8R8A8_UNORM; @@ -800,7 +805,7 @@ static VkFormat wined3d_swapchain_vk_select_vk_format(struct wined3d_swapchain_v { /* Try to create a swapchain with format conversion. */ vk_format = get_swapchain_fallback_format(vk_format); - WARN("Failed to find Vulkan swapchain format for %s.\n", debug_d3dformat(desc->backbuffer_format)); + WARN("Failed to find Vulkan swapchain format for %s.\n", debug_d3dformat(backbuffer_format)); for (i = 0; i < format_count; ++i) { if (vk_formats[i].format == vk_format && vk_formats[i].colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR) @@ -810,7 +815,7 @@ static VkFormat wined3d_swapchain_vk_select_vk_format(struct wined3d_swapchain_v free(vk_formats); if (i == format_count) { - FIXME("Failed to find Vulkan swapchain format for %s.\n", debug_d3dformat(desc->backbuffer_format)); + FIXME("Failed to find Vulkan swapchain format for %s.\n", debug_d3dformat(backbuffer_format)); return VK_FORMAT_UNDEFINED; } diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c index 0fb90ba3f18..1e2a3f09240 100644 --- a/dlls/wined3d/utils.c +++ b/dlls/wined3d/utils.c @@ -1803,6 +1803,19 @@ static const struct wined3d_format_srgb_info format_srgb_info[] = {WINED3DFMT_BC7_UNORM_SRGB, WINED3DFMT_BC7_UNORM}, }; +enum wined3d_format_id wined3d_get_format_srgb(enum wined3d_format_id format_id) +{ + unsigned int i; + for (i = 0; i < ARRAY_SIZE(format_srgb_info); ++i) + { + if (format_srgb_info[i].base_format_id == format_id) + { + return format_srgb_info[i].srgb_format_id; + } + } + return format_id; +} + static inline int get_format_idx(enum wined3d_format_id format_id) { unsigned int i; diff --git a/dlls/wined3d/wined3d_main.c b/dlls/wined3d/wined3d_main.c index 91d8dd567ff..402051ae2c3 100644 --- a/dlls/wined3d/wined3d_main.c +++ b/dlls/wined3d/wined3d_main.c @@ -129,6 +129,7 @@ struct wined3d_settings wined3d_settings = .max_sm_cs = UINT_MAX, .renderer = WINED3D_RENDERER_AUTO, .shader_backend = WINED3D_SHADER_BACKEND_AUTO, + .vk_swap_srgb = FALSE, }; enum wined3d_renderer CDECL wined3d_get_renderer(void) @@ -468,6 +469,11 @@ static BOOL wined3d_dll_init(HINSTANCE hInstDLL) ERR_(winediag)("Using the HLSL-based FFP backend.\n"); wined3d_settings.ffp_hlsl = tmpvalue; } + if (!get_config_key_dword(hkey, appkey, env, "vk_swap_srgb", &tmpvalue) && tmpvalue) + { + TRACE("Forcing Vulkan Swapchain SRGB conversions.\n"); + wined3d_settings.vk_swap_srgb = TRUE; + } } if (appkey) RegCloseKey( appkey ); diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index fa758c53cc1..5997a1d0ea4 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -485,6 +485,7 @@ struct wined3d_settings bool check_float_constants; bool cb_access_map_w; bool ffp_hlsl; + bool vk_swap_srgb; }; extern struct wined3d_settings wined3d_settings; @@ -4627,6 +4628,7 @@ struct wined3d_format enum wined3d_format_id typeless_id; }; +enum wined3d_format_id wined3d_get_format_srgb(enum wined3d_format_id format_id); const struct wined3d_format *wined3d_get_format(const struct wined3d_adapter *adapter, enum wined3d_format_id format_id, unsigned int bind_flags); enum wined3d_format_id wined3d_get_typed_format_id(const struct wined3d_adapter *adapter, -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10567
From: Stian Low <wineryyyyy@gmail.com> This reverts commit cb7eb79780f633bddb75e4969300d2c921739213. --- dlls/wined3d/swapchain.c | 11 +++-------- dlls/wined3d/utils.c | 13 ------------- dlls/wined3d/wined3d_main.c | 6 ------ dlls/wined3d/wined3d_private.h | 2 -- 4 files changed, 3 insertions(+), 29 deletions(-) diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c index ac61a6b64a0..4c20587b81d 100644 --- a/dlls/wined3d/swapchain.c +++ b/dlls/wined3d/swapchain.c @@ -755,7 +755,6 @@ static VkFormat wined3d_swapchain_vk_select_vk_format(struct wined3d_swapchain_v { struct wined3d_device_vk *device_vk = wined3d_device_vk(swapchain_vk->s.device); const struct wined3d_swapchain_desc *desc = &swapchain_vk->s.state.desc; - enum wined3d_format_id backbuffer_format; const struct wined3d_vk_info *vk_info; struct wined3d_adapter_vk *adapter_vk; const struct wined3d_format *format; @@ -769,11 +768,7 @@ static VkFormat wined3d_swapchain_vk_select_vk_format(struct wined3d_swapchain_v vk_physical_device = adapter_vk->physical_device; vk_info = &adapter_vk->vk_info; - backbuffer_format = desc->backbuffer_format; - if (wined3d_settings.vk_swap_srgb) - backbuffer_format = wined3d_get_format_srgb(desc->backbuffer_format); - - if ((format = wined3d_get_format(&adapter_vk->a, backbuffer_format, WINED3D_BIND_RENDER_TARGET))) + if ((format = wined3d_get_format(&adapter_vk->a, desc->backbuffer_format, WINED3D_BIND_RENDER_TARGET))) vk_format = wined3d_format_vk(format)->vk_format; else vk_format = VK_FORMAT_B8G8R8A8_UNORM; @@ -805,7 +800,7 @@ static VkFormat wined3d_swapchain_vk_select_vk_format(struct wined3d_swapchain_v { /* Try to create a swapchain with format conversion. */ vk_format = get_swapchain_fallback_format(vk_format); - WARN("Failed to find Vulkan swapchain format for %s.\n", debug_d3dformat(backbuffer_format)); + WARN("Failed to find Vulkan swapchain format for %s.\n", debug_d3dformat(desc->backbuffer_format)); for (i = 0; i < format_count; ++i) { if (vk_formats[i].format == vk_format && vk_formats[i].colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR) @@ -815,7 +810,7 @@ static VkFormat wined3d_swapchain_vk_select_vk_format(struct wined3d_swapchain_v free(vk_formats); if (i == format_count) { - FIXME("Failed to find Vulkan swapchain format for %s.\n", debug_d3dformat(backbuffer_format)); + FIXME("Failed to find Vulkan swapchain format for %s.\n", debug_d3dformat(desc->backbuffer_format)); return VK_FORMAT_UNDEFINED; } diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c index 1e2a3f09240..0fb90ba3f18 100644 --- a/dlls/wined3d/utils.c +++ b/dlls/wined3d/utils.c @@ -1803,19 +1803,6 @@ static const struct wined3d_format_srgb_info format_srgb_info[] = {WINED3DFMT_BC7_UNORM_SRGB, WINED3DFMT_BC7_UNORM}, }; -enum wined3d_format_id wined3d_get_format_srgb(enum wined3d_format_id format_id) -{ - unsigned int i; - for (i = 0; i < ARRAY_SIZE(format_srgb_info); ++i) - { - if (format_srgb_info[i].base_format_id == format_id) - { - return format_srgb_info[i].srgb_format_id; - } - } - return format_id; -} - static inline int get_format_idx(enum wined3d_format_id format_id) { unsigned int i; diff --git a/dlls/wined3d/wined3d_main.c b/dlls/wined3d/wined3d_main.c index 402051ae2c3..91d8dd567ff 100644 --- a/dlls/wined3d/wined3d_main.c +++ b/dlls/wined3d/wined3d_main.c @@ -129,7 +129,6 @@ struct wined3d_settings wined3d_settings = .max_sm_cs = UINT_MAX, .renderer = WINED3D_RENDERER_AUTO, .shader_backend = WINED3D_SHADER_BACKEND_AUTO, - .vk_swap_srgb = FALSE, }; enum wined3d_renderer CDECL wined3d_get_renderer(void) @@ -469,11 +468,6 @@ static BOOL wined3d_dll_init(HINSTANCE hInstDLL) ERR_(winediag)("Using the HLSL-based FFP backend.\n"); wined3d_settings.ffp_hlsl = tmpvalue; } - if (!get_config_key_dword(hkey, appkey, env, "vk_swap_srgb", &tmpvalue) && tmpvalue) - { - TRACE("Forcing Vulkan Swapchain SRGB conversions.\n"); - wined3d_settings.vk_swap_srgb = TRUE; - } } if (appkey) RegCloseKey( appkey ); diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 5997a1d0ea4..fa758c53cc1 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -485,7 +485,6 @@ struct wined3d_settings bool check_float_constants; bool cb_access_map_w; bool ffp_hlsl; - bool vk_swap_srgb; }; extern struct wined3d_settings wined3d_settings; @@ -4628,7 +4627,6 @@ struct wined3d_format enum wined3d_format_id typeless_id; }; -enum wined3d_format_id wined3d_get_format_srgb(enum wined3d_format_id format_id); const struct wined3d_format *wined3d_get_format(const struct wined3d_adapter *adapter, enum wined3d_format_id format_id, unsigned int bind_flags); enum wined3d_format_id wined3d_get_typed_format_id(const struct wined3d_adapter *adapter, -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10567
From: Stian Low <wineryyyyy@gmail.com> --- dlls/wined3d/swapchain.c | 13 +++++++++---- dlls/wined3d/view.c | 12 ------------ 2 files changed, 9 insertions(+), 16 deletions(-) diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c index 4c20587b81d..d2f540c547e 100644 --- a/dlls/wined3d/swapchain.c +++ b/dlls/wined3d/swapchain.c @@ -645,8 +645,10 @@ static void swapchain_gl_present(struct wined3d_swapchain *swapchain, wined3d_texture_load_location(back_buffer, 0, context, back_buffer->resource.draw_binding); - swapchain_blit(swapchain, context, src_rect, dst_rect); + if (gl_info->supported[ARB_FRAMEBUFFER_SRGB]) + gl_info->gl_ops.gl.p_glDisable(GL_FRAMEBUFFER_SRGB); + swapchain_blit(swapchain, context, src_rect, dst_rect); if (swapchain->device->context_count > 1) { WARN_(d3d_perf)("Multiple contexts, calling glFinish() to enforce ordering.\n"); @@ -660,7 +662,9 @@ static void swapchain_gl_present(struct wined3d_swapchain *swapchain, if (context->d3d_info->fences) wined3d_context_gl_submit_command_fence(context_gl); - wined3d_swapchain_gl_rotate(swapchain, context); + /* Skip wined3d_swapchain_gl_rotate() to fix flickering for swapchain buffer_count > 1 + * required for support of DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL 0x3 + * https://gitlab.winehq.org/wine/wine/-/merge_requests/10567 */ TRACE("SwapBuffers called, Starting new frame\n"); @@ -1286,8 +1290,9 @@ static void swapchain_vk_present(struct wined3d_swapchain *swapchain, const RECT } } - wined3d_swapchain_vk_rotate(swapchain, context_vk); - + /* Skip wined3d_swapchain_vk_rotate() to fix flickering for swapchain buffer_count > 1 + * required for support of DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL 0x3 + * https://gitlab.winehq.org/wine/wine/-/merge_requests/10567 */ wined3d_texture_validate_location(swapchain->front_buffer, 0, WINED3D_LOCATION_DRAWABLE); wined3d_texture_invalidate_location(swapchain->front_buffer, 0, ~WINED3D_LOCATION_DRAWABLE); diff --git a/dlls/wined3d/view.c b/dlls/wined3d/view.c index a506b0c6f18..79e06e706ae 100644 --- a/dlls/wined3d/view.c +++ b/dlls/wined3d/view.c @@ -620,12 +620,6 @@ static void wined3d_render_target_view_gl_cs_init(void *object) debug_d3dformat(resource->format->id), debug_d3dformat(view_gl->v.format->id)); return; } - if (texture_gl->t.swapchain && texture_gl->t.swapchain->state.desc.backbuffer_count > 1) - { - FIXME("Swapchain views not supported.\n"); - return; - } - create_texture_view(&view_gl->gl_view, texture_gl->target, desc, texture_gl, view_gl->v.format); } } @@ -930,12 +924,6 @@ static void wined3d_render_target_view_vk_cs_init(void *object) return; } - if (texture_vk->t.swapchain && texture_vk->t.swapchain->state.desc.backbuffer_count > 1) - { - FIXME("Swapchain views not supported.\n"); - return; - } - if (resource->bind_flags & WINED3D_BIND_RENDER_TARGET) vk_usage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; if (resource->bind_flags & WINED3D_BIND_DEPTH_STENCIL) -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10567
participants (2)
-
Stian Low -
Stian Low (@stianlow)