wined3d: Introduce a backup path for swapchain presents using GDI.
Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
9e69aca6d1
commit
70418f69dd
|
@ -400,6 +400,73 @@ HRESULT CDECL wined3d_swapchain_get_gamma_ramp(const struct wined3d_swapchain *s
|
||||||
return WINED3D_OK;
|
return WINED3D_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* The is a fallback for cases where we e.g. can't create a GL context or
|
||||||
|
* Vulkan swapchain for the swapchain window. */
|
||||||
|
static void swapchain_blit_gdi(struct wined3d_swapchain *swapchain,
|
||||||
|
struct wined3d_context *context, const RECT *src_rect, const RECT *dst_rect)
|
||||||
|
{
|
||||||
|
struct wined3d_texture *back_buffer = swapchain->back_buffers[0];
|
||||||
|
D3DKMT_DESTROYDCFROMMEMORY destroy_desc;
|
||||||
|
D3DKMT_CREATEDCFROMMEMORY create_desc;
|
||||||
|
const struct wined3d_format *format;
|
||||||
|
unsigned int row_pitch, slice_pitch;
|
||||||
|
HDC src_dc, dst_dc;
|
||||||
|
NTSTATUS status;
|
||||||
|
HBITMAP bitmap;
|
||||||
|
|
||||||
|
static unsigned int once;
|
||||||
|
|
||||||
|
TRACE("swapchain %p, context %p, src_rect %s, dst_rect %s.\n",
|
||||||
|
swapchain, context, wine_dbgstr_rect(src_rect), wine_dbgstr_rect(dst_rect));
|
||||||
|
|
||||||
|
if (!once++)
|
||||||
|
FIXME("Using GDI present.\n");
|
||||||
|
|
||||||
|
format = back_buffer->resource.format;
|
||||||
|
if (!format->ddi_format)
|
||||||
|
{
|
||||||
|
WARN("Cannot create a DC for format %s.\n", debug_d3dformat(format->id));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
wined3d_texture_load_location(back_buffer, 0, context, WINED3D_LOCATION_SYSMEM);
|
||||||
|
wined3d_texture_get_pitch(back_buffer, 0, &row_pitch, &slice_pitch);
|
||||||
|
|
||||||
|
create_desc.pMemory = back_buffer->resource.heap_memory;
|
||||||
|
create_desc.Format = format->ddi_format;
|
||||||
|
create_desc.Width = wined3d_texture_get_level_width(back_buffer, 0);
|
||||||
|
create_desc.Height = wined3d_texture_get_level_height(back_buffer, 0);
|
||||||
|
create_desc.Pitch = row_pitch;
|
||||||
|
create_desc.hDeviceDc = CreateCompatibleDC(NULL);
|
||||||
|
create_desc.pColorTable = NULL;
|
||||||
|
|
||||||
|
status = D3DKMTCreateDCFromMemory(&create_desc);
|
||||||
|
DeleteDC(create_desc.hDeviceDc);
|
||||||
|
if (status)
|
||||||
|
{
|
||||||
|
WARN("Failed to create DC, status %#x.\n", status);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
src_dc = create_desc.hDc;
|
||||||
|
bitmap = create_desc.hBitmap;
|
||||||
|
|
||||||
|
TRACE("Created source DC %p, bitmap %p for backbuffer %p.\n", src_dc, bitmap, back_buffer);
|
||||||
|
|
||||||
|
if (!(dst_dc = GetDCEx(swapchain->win_handle, 0, DCX_USESTYLE | DCX_CACHE)))
|
||||||
|
ERR("Failed to get destination DC.\n");
|
||||||
|
|
||||||
|
if (!BitBlt(dst_dc, dst_rect->left, dst_rect->top, dst_rect->right - dst_rect->left,
|
||||||
|
dst_rect->bottom - dst_rect->top, src_dc, src_rect->left, src_rect->top, SRCCOPY))
|
||||||
|
ERR("Failed to blit.\n");
|
||||||
|
|
||||||
|
ReleaseDC(swapchain->win_handle, dst_dc);
|
||||||
|
destroy_desc.hDc = src_dc;
|
||||||
|
destroy_desc.hBitmap = bitmap;
|
||||||
|
if ((status = D3DKMTDestroyDCFromMemory(&destroy_desc)))
|
||||||
|
ERR("Failed to destroy src dc, status %#x.\n", status);
|
||||||
|
}
|
||||||
|
|
||||||
/* A GL context is provided by the caller */
|
/* A GL context is provided by the caller */
|
||||||
static void swapchain_blit(const struct wined3d_swapchain *swapchain,
|
static void swapchain_blit(const struct wined3d_swapchain *swapchain,
|
||||||
struct wined3d_context *context, const RECT *src_rect, const RECT *dst_rect)
|
struct wined3d_context *context, const RECT *src_rect, const RECT *dst_rect)
|
||||||
|
@ -523,6 +590,9 @@ static void swapchain_gl_present(struct wined3d_swapchain *swapchain,
|
||||||
|
|
||||||
TRACE("Presenting DC %p.\n", context_gl->dc);
|
TRACE("Presenting DC %p.\n", context_gl->dc);
|
||||||
|
|
||||||
|
if (context_gl->dc == swapchain_gl->backup_dc)
|
||||||
|
swapchain_blit_gdi(swapchain, context, src_rect, dst_rect);
|
||||||
|
|
||||||
if (!(render_to_fbo = swapchain->render_to_fbo)
|
if (!(render_to_fbo = swapchain->render_to_fbo)
|
||||||
&& (src_rect->left || src_rect->top
|
&& (src_rect->left || src_rect->top
|
||||||
|| src_rect->right != desc->backbuffer_width
|
|| src_rect->right != desc->backbuffer_width
|
||||||
|
@ -1152,6 +1222,8 @@ static void swapchain_vk_present(struct wined3d_swapchain *swapchain, const RECT
|
||||||
|
|
||||||
if (swapchain_vk->vk_swapchain)
|
if (swapchain_vk->vk_swapchain)
|
||||||
wined3d_swapchain_vk_blit(swapchain_vk, context_vk, src_rect, dst_rect, swap_interval);
|
wined3d_swapchain_vk_blit(swapchain_vk, context_vk, src_rect, dst_rect, swap_interval);
|
||||||
|
else
|
||||||
|
swapchain_blit_gdi(swapchain, &context_vk->c, src_rect, dst_rect);
|
||||||
|
|
||||||
wined3d_swapchain_vk_rotate(swapchain, context_vk);
|
wined3d_swapchain_vk_rotate(swapchain, context_vk);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue