[PATCH 1/8] d3d8: Call IDirect3DSwapChain8::Present in IDirect3DDevice8::Present.

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


The immediate purpose this time is to have one place where we call the
wined3d method and have to update pointers after rotating through
buffers. But while I'm at it I am implementing the behavior fraps wants
to display its overlay in d3d8 games.
---
 dlls/d3d8/d3d8_private.h |  4 ++++
 dlls/d3d8/device.c       | 23 +++++++++++++----------
 2 files changed, 17 insertions(+), 10 deletions(-)

diff --git a/dlls/d3d8/d3d8_private.h b/dlls/d3d8/d3d8_private.h
index 6283c8d..447719a 100644
--- a/dlls/d3d8/d3d8_private.h
+++ b/dlls/d3d8/d3d8_private.h
@@ -176,6 +176,10 @@ struct d3d8_device
     LONG device_state;
     /* Avoids recursion with nested ReleaseRef to 0 */
     BOOL                    inDestruction;
+
+    /* The d3d8 API supports only one implicit swapchain (no D3DCREATE_ADAPTERGROUP_DEVICE,
+     * no GetSwapchain, GetBackBuffer doesn't accept a swapchain number). */
+    IDirect3DSwapChain8     *implicit_swapchain;
 };
 
 HRESULT device_init(struct d3d8_device *device, struct d3d8 *parent, struct wined3d *wined3d, UINT adapter,
diff --git a/dlls/d3d8/device.c b/dlls/d3d8/device.c
index e899b34..6c66267 100644
--- a/dlls/d3d8/device.c
+++ b/dlls/d3d8/device.c
@@ -704,20 +704,17 @@ static HRESULT WINAPI d3d8_device_Present(IDirect3DDevice8 *iface, const RECT *s
         const RECT *dst_rect, HWND dst_window_override, const RGNDATA *dirty_region)
 {
     struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
-    HRESULT hr;
 
     TRACE("iface %p, src_rect %s, dst_rect %s, dst_window_override %p, dirty_region %p.\n",
             iface, wine_dbgstr_rect(src_rect), wine_dbgstr_rect(dst_rect), dst_window_override, dirty_region);
 
-    if (device->device_state != D3D8_DEVICE_STATE_OK)
-        return D3DERR_DEVICELOST;
-
-    wined3d_mutex_lock();
-    hr = wined3d_device_present(device->wined3d_device, src_rect, dst_rect,
-            dst_window_override, dirty_region, 0);
-    wined3d_mutex_unlock();
-
-    return hr;
+    /* Fraps does not hook IDirect3DDevice8::Present regardless of the hotpatch
+     * attribute. It only hooks IDirect3DSwapChain8::Present. Yet it properly
+     * 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,
+            dst_rect, dst_window_override, dirty_region);
 }
 
 static HRESULT WINAPI d3d8_device_GetBackBuffer(IDirect3DDevice8 *iface,
@@ -3113,6 +3110,8 @@ HRESULT device_init(struct d3d8_device *device, struct d3d8 *parent, struct wine
         D3DDEVTYPE device_type, HWND focus_window, DWORD flags, D3DPRESENT_PARAMETERS *parameters)
 {
     struct wined3d_swapchain_desc swapchain_desc;
+    struct wined3d_swapchain *wined3d_swapchain;
+    struct d3d8_swapchain *swapchain_impl;
     HRESULT hr;
 
     device->IDirect3DDevice8_iface.lpVtbl = &d3d8_device_vtbl;
@@ -3199,6 +3198,10 @@ HRESULT device_init(struct d3d8_device *device, struct d3d8 *parent, struct wine
         goto err;
     }
 
+    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->d3d_parent = &parent->IDirect3D8_iface;
     IDirect3D8_AddRef(device->d3d_parent);
 
-- 
2.4.6




More information about the wine-patches mailing list