[v2 PATCH] dxgi: Added support for DXGI_SWAP_CHAIN_FLAG_GDI_COMPATIBLE

Nikolay Sivov nsivov at codeweavers.com
Wed Feb 8 16:45:44 CST 2017


Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
 dlls/d3d11/device.c      | 16 +++++++++++++---
 dlls/d3d8/device.c       | 12 +++++++-----
 dlls/d3d9/d3d9_private.h |  2 +-
 dlls/d3d9/device.c       | 32 ++++++++++++++++----------------
 dlls/d3d9/texture.c      |  4 ++--
 dlls/ddraw/ddraw.c       |  9 +++++----
 dlls/dxgi/device.c       |  2 +-
 dlls/dxgi/tests/device.c |  1 -
 dlls/dxgi/utils.c        | 12 ++++++++++++
 dlls/wined3d/device.c    |  6 +++++-
 dlls/wined3d/swapchain.c | 10 +++++++---
 include/wine/wined3d.h   |  3 ++-
 12 files changed, 71 insertions(+), 38 deletions(-)

diff --git a/dlls/d3d11/device.c b/dlls/d3d11/device.c
index 85f84fe719..32c1d284ac 100644
--- a/dlls/d3d11/device.c
+++ b/dlls/d3d11/device.c
@@ -5275,7 +5275,7 @@ static HRESULT CDECL device_parent_sub_resource_created(struct wined3d_device_pa
 }
 
 static HRESULT CDECL device_parent_create_swapchain_texture(struct wined3d_device_parent *device_parent,
-        void *container_parent, const struct wined3d_resource_desc *wined3d_desc,
+        void *container_parent, const struct wined3d_resource_desc *wined3d_desc, DWORD texture_flags,
         struct wined3d_texture **wined3d_texture)
 {
     struct d3d_device *device = device_from_wined3d_device_parent(device_parent);
@@ -5284,8 +5284,9 @@ static HRESULT CDECL device_parent_create_swapchain_texture(struct wined3d_devic
     D3D10_TEXTURE2D_DESC desc;
     HRESULT hr;
 
-    FIXME("device_parent %p, container_parent %p, wined3d_desc %p, wined3d_texture %p partial stub!\n",
-            device_parent, container_parent, wined3d_desc, wined3d_texture);
+    FIXME("device_parent %p, container_parent %p, wined3d_desc %p, texture flags %#x, "
+            "wined3d_texture %p partial stub!\n", device_parent, container_parent,
+            wined3d_desc, texture_flags, wined3d_texture);
 
     FIXME("Implement DXGI<->wined3d usage conversion.\n");
 
@@ -5301,6 +5302,15 @@ static HRESULT CDECL device_parent_create_swapchain_texture(struct wined3d_devic
     desc.CPUAccessFlags = 0;
     desc.MiscFlags = 0;
 
+    if (texture_flags & WINED3D_TEXTURE_CREATE_GET_DC)
+    {
+        desc.MiscFlags |= D3D10_RESOURCE_MISC_GDI_COMPATIBLE;
+        texture_flags &= ~WINED3D_TEXTURE_CREATE_GET_DC;
+    }
+
+    if (texture_flags)
+        FIXME("Unhandled flags %#x.\n", texture_flags);
+
     if (FAILED(hr = d3d10_device_CreateTexture2D(&device->ID3D10Device1_iface,
             &desc, NULL, &texture_iface)))
     {
diff --git a/dlls/d3d8/device.c b/dlls/d3d8/device.c
index 805694b853..edf51b0893 100644
--- a/dlls/d3d8/device.c
+++ b/dlls/d3d8/device.c
@@ -3036,17 +3036,19 @@ static HRESULT CDECL device_parent_volume_created(struct wined3d_device_parent *
 }
 
 static HRESULT CDECL device_parent_create_swapchain_texture(struct wined3d_device_parent *device_parent,
-        void *container_parent, const struct wined3d_resource_desc *desc, struct wined3d_texture **texture)
+        void *container_parent, const struct wined3d_resource_desc *desc, DWORD texture_flags,
+        struct wined3d_texture **texture)
 {
     struct d3d8_device *device = device_from_device_parent(device_parent);
     struct d3d8_surface *d3d_surface;
     HRESULT hr;
 
-    TRACE("device_parent %p, container_parent %p, desc %p, texture %p.\n",
-            device_parent, container_parent, desc, texture);
+    TRACE("device_parent %p, container_parent %p, desc %p, texture flags %#x, texture %p.\n",
+            device_parent, container_parent, desc, texture_flags, texture);
 
-    if (FAILED(hr = wined3d_texture_create(device->wined3d_device, desc, 1, 1, WINED3D_TEXTURE_CREATE_MAPPABLE,
-            NULL, &device->IDirect3DDevice8_iface, &d3d8_null_wined3d_parent_ops, texture)))
+    if (FAILED(hr = wined3d_texture_create(device->wined3d_device, desc, 1, 1,
+            texture_flags | WINED3D_TEXTURE_CREATE_MAPPABLE,  NULL, &device->IDirect3DDevice8_iface,
+            &d3d8_null_wined3d_parent_ops, texture)))
     {
         WARN("Failed to create texture, hr %#x.\n", hr);
         return hr;
diff --git a/dlls/d3d9/d3d9_private.h b/dlls/d3d9/d3d9_private.h
index c8558e79a3..941ef386ac 100644
--- a/dlls/d3d9/d3d9_private.h
+++ b/dlls/d3d9/d3d9_private.h
@@ -43,7 +43,7 @@
 
 extern HRESULT vdecl_convert_fvf(DWORD FVF, D3DVERTEXELEMENT9 **ppVertexElements) DECLSPEC_HIDDEN;
 D3DFORMAT d3dformat_from_wined3dformat(enum wined3d_format_id format) DECLSPEC_HIDDEN;
-BOOL is_gdi_compat_format(D3DFORMAT format) DECLSPEC_HIDDEN;
+BOOL is_gdi_compat_wined3dformat(enum wined3d_format_id format) DECLSPEC_HIDDEN;
 enum wined3d_format_id wined3dformat_from_d3dformat(D3DFORMAT format) DECLSPEC_HIDDEN;
 void present_parameters_from_wined3d_swapchain_desc(D3DPRESENT_PARAMETERS *present_parameters,
         const struct wined3d_swapchain_desc *swapchain_desc) DECLSPEC_HIDDEN;
diff --git a/dlls/d3d9/device.c b/dlls/d3d9/device.c
index e646cb76c7..5875095217 100644
--- a/dlls/d3d9/device.c
+++ b/dlls/d3d9/device.c
@@ -239,6 +239,8 @@ static BOOL wined3d_swapchain_desc_from_present_parameters(struct wined3d_swapch
             = wined3dformat_from_d3dformat(present_parameters->AutoDepthStencilFormat);
     swapchain_desc->flags
             = (present_parameters->Flags & D3DPRESENTFLAGS_MASK) | WINED3D_SWAPCHAIN_ALLOW_MODE_SWITCH;
+    if (is_gdi_compat_wined3dformat(swapchain_desc->backbuffer_format))
+        swapchain_desc->flags |= WINED3D_SWAPCHAIN_GDI_COMPATIBLE;
     swapchain_desc->refresh_rate = present_parameters->FullScreen_RefreshRateInHz;
     swapchain_desc->swap_interval = present_parameters->PresentationInterval;
     swapchain_desc->auto_restore_display_mode = TRUE;
@@ -1123,7 +1125,7 @@ static HRESULT d3d9_device_create_surface(struct d3d9_device *device, UINT width
     desc.depth = 1;
     desc.size = 0;
 
-    if (is_gdi_compat_format(format))
+    if (is_gdi_compat_wined3dformat(desc.format))
         flags |= WINED3D_TEXTURE_CREATE_GET_DC;
 
     wined3d_mutex_lock();
@@ -1154,16 +1156,16 @@ static HRESULT d3d9_device_create_surface(struct d3d9_device *device, UINT width
     return D3D_OK;
 }
 
-BOOL is_gdi_compat_format(D3DFORMAT format)
+BOOL is_gdi_compat_wined3dformat(enum wined3d_format_id format)
 {
     switch (format)
     {
-        case D3DFMT_A8R8G8B8:
-        case D3DFMT_X8R8G8B8:
-        case D3DFMT_R5G6B5:
-        case D3DFMT_X1R5G5B5:
-        case D3DFMT_A1R5G5B5:
-        case D3DFMT_R8G8B8:
+        case WINED3DFMT_B8G8R8A8_UNORM:
+        case WINED3DFMT_B8G8R8X8_UNORM:
+        case WINED3DFMT_B5G6R5_UNORM:
+        case WINED3DFMT_B5G5R5X1_UNORM:
+        case WINED3DFMT_B5G5R5A1_UNORM:
+        case WINED3DFMT_B8G8R8_UNORM:
             return TRUE;
         default:
             return FALSE;
@@ -3746,24 +3748,22 @@ static HRESULT CDECL device_parent_volume_created(struct wined3d_device_parent *
 }
 
 static HRESULT CDECL device_parent_create_swapchain_texture(struct wined3d_device_parent *device_parent,
-        void *container_parent, const struct wined3d_resource_desc *desc, struct wined3d_texture **texture)
+        void *container_parent, const struct wined3d_resource_desc *desc, DWORD texture_flags,
+        struct wined3d_texture **texture)
 {
     struct d3d9_device *device = device_from_device_parent(device_parent);
-    DWORD flags = WINED3D_TEXTURE_CREATE_MAPPABLE;
     struct d3d9_surface *d3d_surface;
     HRESULT hr;
 
-    TRACE("device_parent %p, container_parent %p, desc %p, texture %p.\n",
-            device_parent, container_parent, desc, texture);
+    TRACE("device_parent %p, container_parent %p, desc %p, texture flags %#x, texture %p.\n",
+            device_parent, container_parent, desc, texture_flags, texture);
 
     if (container_parent == device_parent)
         container_parent = &device->IDirect3DDevice9Ex_iface;
 
-    if (is_gdi_compat_format(d3dformat_from_wined3dformat(desc->format)))
-        flags |= WINED3D_TEXTURE_CREATE_GET_DC;
-
     if (FAILED(hr = wined3d_texture_create(device->wined3d_device, desc, 1, 1,
-            flags, NULL, container_parent, &d3d9_null_wined3d_parent_ops, texture)))
+            texture_flags | WINED3D_TEXTURE_CREATE_MAPPABLE, NULL, container_parent,
+            &d3d9_null_wined3d_parent_ops, texture)))
     {
         WARN("Failed to create texture, hr %#x.\n", hr);
         return hr;
diff --git a/dlls/d3d9/texture.c b/dlls/d3d9/texture.c
index 46e42180fc..f5f268e948 100644
--- a/dlls/d3d9/texture.c
+++ b/dlls/d3d9/texture.c
@@ -1257,7 +1257,7 @@ HRESULT texture_init(struct d3d9_texture *texture, struct d3d9_device *device,
     if (pool != D3DPOOL_DEFAULT || (usage & D3DUSAGE_DYNAMIC))
         flags |= WINED3D_TEXTURE_CREATE_MAPPABLE;
 
-    if (is_gdi_compat_format(format))
+    if (is_gdi_compat_wined3dformat(desc.format))
         flags |= WINED3D_TEXTURE_CREATE_GET_DC;
 
     if (!levels)
@@ -1310,7 +1310,7 @@ HRESULT cubetexture_init(struct d3d9_texture *texture, struct d3d9_device *devic
     if (pool != D3DPOOL_DEFAULT || (usage & D3DUSAGE_DYNAMIC))
         flags |= WINED3D_TEXTURE_CREATE_MAPPABLE;
 
-    if (is_gdi_compat_format(format))
+    if (is_gdi_compat_wined3dformat(desc.format))
         flags |= WINED3D_TEXTURE_CREATE_GET_DC;
 
     if (!levels)
diff --git a/dlls/ddraw/ddraw.c b/dlls/ddraw/ddraw.c
index a0865c0c96..254dae70eb 100644
--- a/dlls/ddraw/ddraw.c
+++ b/dlls/ddraw/ddraw.c
@@ -4877,13 +4877,14 @@ static const struct wined3d_parent_ops ddraw_frontbuffer_parent_ops =
 };
 
 static HRESULT CDECL device_parent_create_swapchain_texture(struct wined3d_device_parent *device_parent,
-        void *container_parent, const struct wined3d_resource_desc *desc, struct wined3d_texture **texture)
+        void *container_parent, const struct wined3d_resource_desc *desc, DWORD texture_flags,
+        struct wined3d_texture **texture)
 {
     struct ddraw *ddraw = ddraw_from_device_parent(device_parent);
     HRESULT hr;
 
-    TRACE("device_parent %p, container_parent %p, desc %p, texture %p.\n",
-            device_parent, container_parent, desc, texture);
+    TRACE("device_parent %p, container_parent %p, desc %p, texture flags %#x, texture %p.\n",
+            device_parent, container_parent, desc, texture_flags, texture);
 
     if (ddraw->wined3d_frontbuffer)
     {
@@ -4892,7 +4893,7 @@ static HRESULT CDECL device_parent_create_swapchain_texture(struct wined3d_devic
     }
 
     if (FAILED(hr = wined3d_texture_create(ddraw->wined3d_device, desc, 1, 1,
-            WINED3D_TEXTURE_CREATE_MAPPABLE, NULL, ddraw, &ddraw_frontbuffer_parent_ops, texture)))
+            texture_flags | WINED3D_TEXTURE_CREATE_MAPPABLE, NULL, ddraw, &ddraw_frontbuffer_parent_ops, texture)))
     {
         WARN("Failed to create texture, hr %#x.\n", hr);
         return hr;
diff --git a/dlls/dxgi/device.c b/dlls/dxgi/device.c
index f548ca2ce6..268b6f08be 100644
--- a/dlls/dxgi/device.c
+++ b/dlls/dxgi/device.c
@@ -201,7 +201,7 @@ static HRESULT STDMETHODCALLTYPE dxgi_device_CreateSurface(IWineDXGIDevice *ifac
         IUnknown *parent;
 
         if (FAILED(hr = device_parent->ops->create_swapchain_texture(device_parent,
-                NULL, &surface_desc, &wined3d_texture)))
+                NULL, &surface_desc, 0, &wined3d_texture)))
         {
             ERR("Failed to create surface, hr %#x.\n", hr);
             goto fail;
diff --git a/dlls/dxgi/tests/device.c b/dlls/dxgi/tests/device.c
index b092d5eff1..2bc0ff4071 100644
--- a/dlls/dxgi/tests/device.c
+++ b/dlls/dxgi/tests/device.c
@@ -1039,7 +1039,6 @@ static void test_create_swapchain(void)
         ok(SUCCEEDED(hr), "Failed to get front buffer, hr %#x.\n", hr);
 
         hr = IDXGISurface1_GetDC(surface, FALSE, &hdc);
-    todo_wine
         ok(SUCCEEDED(hr), "Expected GetDC() to succeed, %#x\n", hr);
         IDXGISurface1_ReleaseDC(surface, NULL);
 
diff --git a/dlls/dxgi/utils.c b/dlls/dxgi/utils.c
index f41b0a89c7..db74a487f2 100644
--- a/dlls/dxgi/utils.c
+++ b/dlls/dxgi/utils.c
@@ -468,6 +468,12 @@ unsigned int dxgi_swapchain_flags_from_wined3d(unsigned int wined3d_flags)
         flags |= DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
     }
 
+    if (wined3d_flags & WINED3D_SWAPCHAIN_GDI_COMPATIBLE)
+    {
+        wined3d_flags &= ~WINED3D_SWAPCHAIN_GDI_COMPATIBLE;
+        flags |= DXGI_SWAP_CHAIN_FLAG_GDI_COMPATIBLE;
+    }
+
     if (wined3d_flags)
         FIXME("Unhandled flags %#x.\n", flags);
 
@@ -484,6 +490,12 @@ unsigned int wined3d_swapchain_flags_from_dxgi(unsigned int flags)
         wined3d_flags |= WINED3D_SWAPCHAIN_ALLOW_MODE_SWITCH;
     }
 
+    if (flags & DXGI_SWAP_CHAIN_FLAG_GDI_COMPATIBLE)
+    {
+        flags &= ~DXGI_SWAP_CHAIN_FLAG_GDI_COMPATIBLE;
+        wined3d_flags |= WINED3D_SWAPCHAIN_GDI_COMPATIBLE;
+    }
+
     if (flags)
         FIXME("Unhandled flags %#x.\n", flags);
 
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index 03d4069857..002eed3086 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -4749,6 +4749,7 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device,
     {
         struct wined3d_resource_desc texture_desc;
         struct wined3d_texture *texture;
+        DWORD flags = 0;
 
         TRACE("Creating the depth stencil buffer.\n");
 
@@ -4763,8 +4764,11 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device,
         texture_desc.depth = 1;
         texture_desc.size = 0;
 
+        if (swapchain_desc->flags & WINED3D_SWAPCHAIN_GDI_COMPATIBLE)
+            flags |= WINED3D_TEXTURE_CREATE_GET_DC;
+
         if (FAILED(hr = device->device_parent->ops->create_swapchain_texture(device->device_parent,
-                device->device_parent, &texture_desc, &texture)))
+                device->device_parent, &texture_desc, flags, &texture)))
         {
             ERR("Failed to create the auto depth/stencil surface, hr %#x.\n", hr);
             return WINED3DERR_INVALIDCALL;
diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c
index 62589c1410..56646e7b14 100644
--- a/dlls/wined3d/swapchain.c
+++ b/dlls/wined3d/swapchain.c
@@ -784,6 +784,7 @@ static HRESULT swapchain_init(struct wined3d_swapchain *swapchain, struct wined3
     const struct wined3d_adapter *adapter = device->adapter;
     struct wined3d_resource_desc texture_desc;
     BOOL displaymode_set = FALSE;
+    DWORD texture_flags = 0;
     RECT client_rect;
     HWND window;
     HRESULT hr;
@@ -856,8 +857,11 @@ static HRESULT swapchain_init(struct wined3d_swapchain *swapchain, struct wined3
     texture_desc.depth = 1;
     texture_desc.size = 0;
 
+    if (swapchain->desc.flags & WINED3D_SWAPCHAIN_GDI_COMPATIBLE)
+        texture_flags |= WINED3D_TEXTURE_CREATE_GET_DC;
+
     if (FAILED(hr = device->device_parent->ops->create_swapchain_texture(device->device_parent,
-            parent, &texture_desc, &swapchain->front_buffer)))
+            parent, &texture_desc, texture_flags, &swapchain->front_buffer)))
     {
         WARN("Failed to create front buffer, hr %#x.\n", hr);
         goto err;
@@ -972,7 +976,7 @@ static HRESULT swapchain_init(struct wined3d_swapchain *swapchain, struct wined3
         {
             TRACE("Creating back buffer %u.\n", i);
             if (FAILED(hr = device->device_parent->ops->create_swapchain_texture(device->device_parent,
-                    parent, &texture_desc, &swapchain->back_buffers[i])))
+                    parent, &texture_desc, texture_flags, &swapchain->back_buffers[i])))
             {
                 WARN("Failed to create back buffer %u, hr %#x.\n", i, hr);
                 swapchain->desc.backbuffer_count = i;
@@ -995,7 +999,7 @@ static HRESULT swapchain_init(struct wined3d_swapchain *swapchain, struct wined3
             texture_desc.usage = WINED3DUSAGE_DEPTHSTENCIL;
 
             if (FAILED(hr = device->device_parent->ops->create_swapchain_texture(device->device_parent,
-                    device->device_parent, &texture_desc, &ds)))
+                    device->device_parent, &texture_desc, texture_flags, &ds)))
             {
                 WARN("Failed to create the auto depth/stencil surface, hr %#x.\n", hr);
                 goto err;
diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h
index 7788e903f6..7763543ed9 100644
--- a/include/wine/wined3d.h
+++ b/include/wine/wined3d.h
@@ -834,6 +834,7 @@ enum wined3d_display_rotation
 #define WINED3D_SWAPCHAIN_ALLOW_MODE_SWITCH                     0x00001000u
 #define WINED3D_SWAPCHAIN_USE_CLOSEST_MATCHING_MODE             0x00002000u
 #define WINED3D_SWAPCHAIN_RESTORE_WINDOW_RECT                   0x00004000u
+#define WINED3D_SWAPCHAIN_GDI_COMPATIBLE                        0x00008000u
 
 #define WINED3DDP_MAXTEXCOORD                                   8
 
@@ -2030,7 +2031,7 @@ struct wined3d_device_parent_ops
             struct wined3d_texture *wined3d_texture, unsigned int sub_resource_idx,
             void **parent, const struct wined3d_parent_ops **parent_ops);
     HRESULT (__cdecl *create_swapchain_texture)(struct wined3d_device_parent *device_parent, void *parent,
-            const struct wined3d_resource_desc *desc, struct wined3d_texture **texture);
+            const struct wined3d_resource_desc *desc, DWORD texture_flags, struct wined3d_texture **texture);
     HRESULT (__cdecl *create_swapchain)(struct wined3d_device_parent *device_parent,
             struct wined3d_swapchain_desc *desc, struct wined3d_swapchain **swapchain);
 };
-- 
2.11.0




More information about the wine-patches mailing list