[PATCH 2/5] wined3d: Handle blits to Vulkan swapchains not matching the D3D swapchain.
Matteo Bruni
mbruni at codeweavers.com
Fri Mar 5 10:06:21 CST 2021
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=50119
Signed-off-by: Matteo Bruni <mbruni at codeweavers.com>
---
dlls/wined3d/swapchain.c | 32 ++++++++++++++++++++++++++++++--
dlls/wined3d/wined3d_private.h | 1 +
2 files changed, 31 insertions(+), 2 deletions(-)
diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c
index 72e17a6f833..ab04a771d68 100644
--- a/dlls/wined3d/swapchain.c
+++ b/dlls/wined3d/swapchain.c
@@ -998,6 +998,9 @@ static HRESULT wined3d_swapchain_vk_create_vulkan_swapchain(struct wined3d_swapc
goto fail;
}
+ swapchain_vk->width = width;
+ swapchain_vk->height = height;
+
return WINED3D_OK;
fail:
@@ -1043,12 +1046,17 @@ static void wined3d_swapchain_vk_blit(struct wined3d_swapchain_vk *swapchain_vk,
unsigned int present_idx;
VkImageLayout vk_layout;
uint32_t image_idx;
+ RECT dst_rect_tmp;
VkImageBlit blit;
+ VkFilter filter;
VkResult vr;
HRESULT hr;
static const VkPipelineStageFlags wait_stage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
+ TRACE("swapchain_vk %p, context_vk %p, src_rect %s, dst_rect %s, swap_interval %u.\n",
+ swapchain_vk, context_vk, wine_dbgstr_rect(src_rect), wine_dbgstr_rect(dst_rect), swap_interval);
+
wined3d_swapchain_vk_set_swap_interval(swapchain_vk, swap_interval);
present_idx = swapchain_vk->current++ % swapchain_vk->image_count;
@@ -1071,6 +1079,18 @@ static void wined3d_swapchain_vk_blit(struct wined3d_swapchain_vk *swapchain_vk,
return;
}
+ if (dst_rect->right >= swapchain_vk->width || dst_rect->bottom >= swapchain_vk->height)
+ {
+ dst_rect_tmp = *dst_rect;
+ if (dst_rect->right >= swapchain_vk->width)
+ dst_rect_tmp.right = swapchain_vk->width - 1;
+ if (dst_rect->bottom >= swapchain_vk->height)
+ dst_rect_tmp.bottom = swapchain_vk->height - 1;
+ dst_rect = &dst_rect_tmp;
+ }
+ filter = src_rect->right - src_rect->left != dst_rect->right - dst_rect->left
+ || src_rect->bottom - src_rect->top != dst_rect->bottom - dst_rect->top
+ ? VK_FILTER_LINEAR : VK_FILTER_NEAREST;
vk_command_buffer = wined3d_context_vk_get_command_buffer(context_vk);
wined3d_context_vk_end_current_render_pass(context_vk);
@@ -1108,7 +1128,7 @@ static void wined3d_swapchain_vk_blit(struct wined3d_swapchain_vk *swapchain_vk,
VK_CALL(vkCmdBlitImage(vk_command_buffer,
back_buffer_vk->vk_image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
swapchain_vk->vk_images[image_idx], VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
- 1, &blit, VK_FILTER_NEAREST));
+ 1, &blit, filter));
wined3d_context_vk_reference_texture(context_vk, back_buffer_vk);
wined3d_context_vk_image_barrier(context_vk, vk_command_buffer,
@@ -1142,8 +1162,16 @@ static void wined3d_swapchain_vk_blit(struct wined3d_swapchain_vk *swapchain_vk,
present_desc.pSwapchains = &swapchain_vk->vk_swapchain;
present_desc.pImageIndices = &image_idx;
present_desc.pResults = NULL;
- if ((vr = VK_CALL(vkQueuePresentKHR(device_vk->vk_queue, &present_desc))))
+ vr = VK_CALL(vkQueuePresentKHR(device_vk->vk_queue, &present_desc));
+ if (vr == VK_ERROR_OUT_OF_DATE_KHR)
+ {
+ if (FAILED(hr = wined3d_swapchain_vk_recreate(swapchain_vk)))
+ ERR("Failed to recreate swapchain, hr %#x.\n", hr);
+ }
+ else if (vr)
+ {
ERR("Present returned vr %s.\n", wined3d_debug_vkresult(vr));
+ }
}
static void wined3d_swapchain_vk_rotate(struct wined3d_swapchain *swapchain, struct wined3d_context_vk *context_vk)
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 56d3ef8fea2..349a1766fba 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -5280,6 +5280,7 @@ struct wined3d_swapchain_vk
uint64_t command_buffer_id;
} *vk_semaphores;
unsigned int current, image_count;
+ unsigned int width, height;
};
static inline struct wined3d_swapchain_vk *wined3d_swapchain_vk(struct wined3d_swapchain *swapchain)
--
2.26.2
More information about the wine-devel
mailing list