[PATCH 4/8] d3d8: Update swapchain surfaces after presenting.

Stefan Dösinger stefan at codeweavers.com
Mon Sep 14 12:17:48 CDT 2015


---
 dlls/d3d8/d3d8_private.h |  8 +++++++-
 dlls/d3d8/device.c       |  8 +++++---
 dlls/d3d8/swapchain.c    | 42 ++++++++++++++++++++++++++++++++++++++++--
 3 files changed, 52 insertions(+), 6 deletions(-)

diff --git a/dlls/d3d8/d3d8_private.h b/dlls/d3d8/d3d8_private.h
index 447719a..484a551 100644
--- a/dlls/d3d8/d3d8_private.h
+++ b/dlls/d3d8/d3d8_private.h
@@ -179,7 +179,7 @@ struct d3d8_device
 
     /* The d3d8 API supports only one implicit swapchain (no D3DCREATE_ADAPTERGROUP_DEVICE,
      * no GetSwapchain, GetBackBuffer doesn't accept a swapchain number). */
-    IDirect3DSwapChain8     *implicit_swapchain;
+    struct d3d8_swapchain   *implicit_swapchain;
 };
 
 HRESULT device_init(struct d3d8_device *device, struct d3d8 *parent, struct wined3d *wined3d, UINT adapter,
@@ -215,16 +215,22 @@ struct d3d8_volume
 void volume_init(struct d3d8_volume *volume, struct d3d8_texture *texture,
         struct wined3d_volume *wined3d_volume, const struct wined3d_parent_ops **parent_ops) DECLSPEC_HIDDEN;
 
+#define D3D8_MAX_BACK_BUFFERS 3
+
 struct d3d8_swapchain
 {
     IDirect3DSwapChain8 IDirect3DSwapChain8_iface;
     LONG refcount;
     struct wined3d_swapchain *wined3d_swapchain;
     IDirect3DDevice8 *parent_device;
+
+    UINT num_back_buffers;
+    struct d3d8_surface *back_buffers[D3D8_MAX_BACK_BUFFERS];
 };
 
 HRESULT d3d8_swapchain_create(struct d3d8_device *device, struct wined3d_swapchain_desc *desc,
         struct d3d8_swapchain **swapchain) DECLSPEC_HIDDEN;
+void d3d8_swapchain_get_back_buffers(struct d3d8_swapchain *swapchain) DECLSPEC_HIDDEN;
 
 struct d3d8_surface
 {
diff --git a/dlls/d3d8/device.c b/dlls/d3d8/device.c
index 6c66267..d0ab2a5 100644
--- a/dlls/d3d8/device.c
+++ b/dlls/d3d8/device.c
@@ -196,7 +196,7 @@ static BOOL wined3d_swapchain_desc_from_present_parameters(struct wined3d_swapch
         WARN("Invalid swap effect %u passed.\n", present_parameters->SwapEffect);
         return FALSE;
     }
-    if (present_parameters->BackBufferCount > 3
+    if (present_parameters->BackBufferCount > D3D8_MAX_BACK_BUFFERS
             || (present_parameters->SwapEffect == D3DSWAPEFFECT_COPY
             && present_parameters->BackBufferCount > 1))
     {
@@ -690,6 +690,8 @@ static HRESULT WINAPI d3d8_device_Reset(IDirect3DDevice8 *iface,
         present_parameters->BackBufferCount = swapchain_desc.backbuffer_count;
         wined3d_device_set_render_state(device->wined3d_device, WINED3D_RS_POINTSIZE_MIN, 0);
         device->device_state = D3D8_DEVICE_STATE_OK;
+
+        d3d8_swapchain_get_back_buffers(device->implicit_swapchain);
     }
     else
     {
@@ -713,7 +715,7 @@ static HRESULT WINAPI d3d8_device_Present(IDirect3DDevice8 *iface, const RECT *s
      * shows a framerate on Windows in applications that only call the device
      * method, like e.g. the dx8 sdk samples. The conclusion is that native
      * calls the swapchain's public method from the device. */
-    return IDirect3DSwapChain8_Present(device->implicit_swapchain, src_rect,
+    return IDirect3DSwapChain8_Present(&device->implicit_swapchain->IDirect3DSwapChain8_iface, src_rect,
             dst_rect, dst_window_override, dirty_region);
 }
 
@@ -3200,7 +3202,7 @@ HRESULT device_init(struct d3d8_device *device, struct d3d8 *parent, struct wine
 
     wined3d_swapchain = wined3d_device_get_swapchain(device->wined3d_device, 0);
     swapchain_impl = wined3d_swapchain_get_parent(wined3d_swapchain);
-    device->implicit_swapchain = &swapchain_impl->IDirect3DSwapChain8_iface;
+    device->implicit_swapchain = swapchain_impl;
 
     device->d3d_parent = &parent->IDirect3D8_iface;
     IDirect3D8_AddRef(device->d3d_parent);
diff --git a/dlls/d3d8/swapchain.c b/dlls/d3d8/swapchain.c
index 8efdd0a..5da75b3 100644
--- a/dlls/d3d8/swapchain.c
+++ b/dlls/d3d8/swapchain.c
@@ -92,6 +92,10 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH d3d8_swapchain_Present(IDirect3DSwapChai
 {
     struct d3d8_swapchain *swapchain = impl_from_IDirect3DSwapChain8(iface);
     struct d3d8_device *device = impl_from_IDirect3DDevice8(swapchain->parent_device);
+    UINT i;
+    struct wined3d_texture *texture;
+    struct wined3d_resource *resource;
+    struct wined3d_surface *surface;
     HRESULT hr;
 
     TRACE("iface %p, src_rect %s, dst_rect %s, dst_window_override %p, dirty_region %p.\n",
@@ -101,8 +105,23 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH d3d8_swapchain_Present(IDirect3DSwapChai
         return D3DERR_DEVICELOST;
 
     wined3d_mutex_lock();
-    hr = wined3d_swapchain_present(swapchain->wined3d_swapchain, src_rect,
-            dst_rect, dst_window_override, dirty_region, 0);
+    if (FAILED(hr = wined3d_swapchain_present(swapchain->wined3d_swapchain, src_rect,
+            dst_rect, dst_window_override, dirty_region, 0)))
+    {
+        wined3d_mutex_unlock();
+        return hr;
+    }
+
+    for (i = 0; i < swapchain->num_back_buffers; ++i)
+    {
+        texture = wined3d_swapchain_get_back_buffer(swapchain->wined3d_swapchain, i);
+        resource = wined3d_texture_get_sub_resource(texture, 0);
+        surface = wined3d_surface_from_resource(resource);
+
+        swapchain->back_buffers[i]->wined3d_surface = surface;
+        wined3d_resource_set_parent(resource, swapchain->back_buffers[i]);
+    }
+
     wined3d_mutex_unlock();
 
     return hr;
@@ -165,6 +184,23 @@ static const struct wined3d_parent_ops d3d8_swapchain_wined3d_parent_ops =
     d3d8_swapchain_wined3d_object_released,
 };
 
+void d3d8_swapchain_get_back_buffers(struct d3d8_swapchain *swapchain)
+{
+    UINT i;
+    struct wined3d_swapchain_desc desc;
+    struct wined3d_texture *texture;
+    struct wined3d_resource *resource;
+
+    wined3d_swapchain_get_desc(swapchain->wined3d_swapchain, &desc);
+    for (i = 0; i < desc.backbuffer_count; ++i)
+    {
+        texture = wined3d_swapchain_get_back_buffer(swapchain->wined3d_swapchain, i);
+        resource = wined3d_texture_get_sub_resource(texture, 0);
+        swapchain->back_buffers[i] = wined3d_resource_get_parent(resource);
+    }
+    swapchain->num_back_buffers = desc.backbuffer_count;
+}
+
 static HRESULT swapchain_init(struct d3d8_swapchain *swapchain, struct d3d8_device *device,
         struct wined3d_swapchain_desc *desc)
 {
@@ -187,6 +223,8 @@ static HRESULT swapchain_init(struct d3d8_swapchain *swapchain, struct d3d8_devi
     swapchain->parent_device = &device->IDirect3DDevice8_iface;
     IDirect3DDevice8_AddRef(swapchain->parent_device);
 
+    d3d8_swapchain_get_back_buffers(swapchain);
+
     return D3D_OK;
 }
 
-- 
2.4.6




More information about the wine-patches mailing list