[prev in list] [next in list] [prev in thread] [next in thread] 

List:       wine-devel
Subject:    [PATCH 3/5] wined3d: Add new functions to set and get maximum frame latency for the device.
From:       Henri Verbeet <hverbeet () codeweavers ! com>
Date:       2018-04-30 18:27:01
Message-ID: 20180430181503.30154-3-hverbeet () codeweavers ! com
[Download RAW message or body]

From: Nikolay Sivov <nsivov@codeweavers.com>

Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com>
Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com>
---
 dlls/wined3d/cs.c              |  5 ++---
 dlls/wined3d/device.c          | 19 +++++++++++++++++++
 dlls/wined3d/swapchain.c       |  7 +++++++
 dlls/wined3d/wined3d.spec      |  2 ++
 dlls/wined3d/wined3d_private.h |  4 ++++
 include/wine/wined3d.h         |  2 ++
 6 files changed, 36 insertions(+), 3 deletions(-)

diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c
index 173490d789a..e4a29406a4f 100644
--- a/dlls/wined3d/cs.c
+++ b/dlls/wined3d/cs.c
@@ -496,9 +496,8 @@ void wined3d_cs_emit_present(struct wined3d_cs *cs, struct \
wined3d_swapchain *sw  cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT);
 
     /* Limit input latency by limiting the number of presents that we can get
-     * ahead of the worker thread. We have a constant limit here, but
-     * IDXGIDevice1 allows tuning this. */
-    while (pending > 1)
+     * ahead of the worker thread. */
+    while (pending >= swapchain->max_frame_latency)
     {
         wined3d_pause();
         pending = InterlockedCompareExchange(&cs->pending_presents, 0, 0);
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index 86c36d5a266..c853b43440b 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -3081,6 +3081,23 @@ struct wined3d_unordered_access_view * CDECL \
                wined3d_device_get_unordered_access
     return wined3d_device_get_pipeline_unordered_access_view(device, \
WINED3D_PIPELINE_GRAPHICS, idx);  }
 
+void CDECL wined3d_device_set_max_frame_latency(struct wined3d_device *device, \
unsigned int latency) +{
+    unsigned int i;
+
+    if (!latency)
+        latency = 3;
+
+    device->max_frame_latency = latency;
+    for (i = 0; i < device->swapchain_count; ++i)
+        swapchain_set_max_frame_latency(device->swapchains[i], device);
+}
+
+unsigned int CDECL wined3d_device_get_max_frame_latency(const struct wined3d_device \
*device) +{
+    return device->max_frame_latency;
+}
+
 /* Context activation is done by the caller. */
 #define copy_and_next(dest, src, size) memcpy(dest, src, size); dest += (size)
 static HRESULT process_vertices_strided(const struct wined3d_device *device, DWORD \
dwDestIndex, DWORD dwCount, @@ -5225,6 +5242,8 @@ HRESULT device_init(struct \
wined3d_device *device, struct wined3d *wined3d,  &adapter->d3d_info, \
WINED3D_STATE_INIT_DEFAULT);  device->update_state = &device->state;
 
+    device->max_frame_latency = 3;
+
     if (!(device->cs = wined3d_cs_create(device)))
     {
         WARN("Failed to create command stream.\n");
diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c
index 2aec612018c..ea93212a24f 100644
--- a/dlls/wined3d/swapchain.c
+++ b/dlls/wined3d/swapchain.c
@@ -740,6 +740,12 @@ static void wined3d_swapchain_cs_init(void *object)
     context_release(swapchain->context[0]);
 }
 
+void swapchain_set_max_frame_latency(struct wined3d_swapchain *swapchain, const \
struct wined3d_device *device) +{
+    /* Subtract 1 for the implicit OpenGL latency. */
+    swapchain->max_frame_latency = device->max_frame_latency >= 2 ? \
device->max_frame_latency - 1 : 1; +}
+
 static HRESULT swapchain_init(struct wined3d_swapchain *swapchain, struct \
                wined3d_device *device,
         struct wined3d_swapchain_desc *desc, void *parent, const struct \
wined3d_parent_ops *parent_ops)  {
@@ -777,6 +783,7 @@ static HRESULT swapchain_init(struct wined3d_swapchain \
*swapchain, struct wined3  swapchain->win_handle = window;
     swapchain->device_window = window;
     swapchain->swap_interval = WINED3D_SWAP_INTERVAL_DEFAULT;
+    swapchain_set_max_frame_latency(swapchain, device);
 
     if (FAILED(hr = wined3d_get_adapter_display_mode(device->wined3d,
             adapter->ordinal, &swapchain->original_mode, NULL)))
diff --git a/dlls/wined3d/wined3d.spec b/dlls/wined3d/wined3d.spec
index 357b76ebac1..bf29e206b53 100644
--- a/dlls/wined3d/wined3d.spec
+++ b/dlls/wined3d/wined3d.spec
@@ -86,6 +86,7 @@
 @ cdecl wined3d_device_get_light(ptr long ptr)
 @ cdecl wined3d_device_get_light_enable(ptr long ptr)
 @ cdecl wined3d_device_get_material(ptr ptr)
+@ cdecl wined3d_device_get_max_frame_latency(ptr)
 @ cdecl wined3d_device_get_npatch_mode(ptr)
 @ cdecl wined3d_device_get_pixel_shader(ptr)
 @ cdecl wined3d_device_get_predication(ptr ptr)
@@ -161,6 +162,7 @@
 @ cdecl wined3d_device_set_light(ptr long ptr)
 @ cdecl wined3d_device_set_light_enable(ptr long long)
 @ cdecl wined3d_device_set_material(ptr ptr)
+@ cdecl wined3d_device_set_max_frame_latency(ptr long)
 @ cdecl wined3d_device_set_multithreaded(ptr)
 @ cdecl wined3d_device_set_npatch_mode(ptr float)
 @ cdecl wined3d_device_set_pixel_shader(ptr ptr)
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index ab13a29530a..b297799f821 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -2957,6 +2957,7 @@ struct wined3d_device
     struct wined3d_rendertarget_view *back_buffer_view;
     struct wined3d_swapchain **swapchains;
     UINT swapchain_count;
+    unsigned int max_frame_latency;
 
     struct list             resources; /* a linked list to track resources created \
                by the device */
     struct list             shaders;   /* a linked list to track shaders (pixel and \
vertex)      */ @@ -3821,6 +3822,7 @@ struct wined3d_swapchain
     struct wined3d_palette *palette;
     RECT front_buffer_update;
     unsigned int swap_interval;
+    unsigned int max_frame_latency;
 
     LONG prev_time, frames;   /* Performance tracking */
 
@@ -3841,6 +3843,8 @@ struct wined3d_context *swapchain_get_context(struct \
wined3d_swapchain *swapchai  void swapchain_destroy_contexts(struct wined3d_swapchain \
*swapchain) DECLSPEC_HIDDEN;  HDC swapchain_get_backup_dc(struct wined3d_swapchain \
*swapchain) DECLSPEC_HIDDEN;  void swapchain_update_draw_bindings(struct \
wined3d_swapchain *swapchain) DECLSPEC_HIDDEN; +void \
swapchain_set_max_frame_latency(struct wined3d_swapchain *swapchain, +        const \
struct wined3d_device *device) DECLSPEC_HIDDEN;  
 /*****************************************************************************
  * Utility function prototypes
diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h
index 13e83da6265..15e14e5c5f3 100644
--- a/include/wine/wined3d.h
+++ b/include/wine/wined3d.h
@@ -2281,6 +2281,7 @@ HRESULT __cdecl wined3d_device_get_light(const struct \
wined3d_device *device,  UINT light_idx, struct wined3d_light *light);
 HRESULT __cdecl wined3d_device_get_light_enable(const struct wined3d_device *device, \
UINT light_idx, BOOL *enable);  void __cdecl wined3d_device_get_material(const struct \
wined3d_device *device, struct wined3d_material *material); +unsigned int __cdecl \
wined3d_device_get_max_frame_latency(const struct wined3d_device *device);  float \
__cdecl wined3d_device_get_npatch_mode(const struct wined3d_device *device);  struct \
wined3d_shader * __cdecl wined3d_device_get_pixel_shader(const struct wined3d_device \
*device);  struct wined3d_query * __cdecl wined3d_device_get_predication(struct \
wined3d_device *device, BOOL *value); @@ -2402,6 +2403,7 @@ HRESULT __cdecl \
wined3d_device_set_light(struct wined3d_device *device,  UINT light_idx, const struct \
wined3d_light *light);  HRESULT __cdecl wined3d_device_set_light_enable(struct \
wined3d_device *device, UINT light_idx, BOOL enable);  void __cdecl \
wined3d_device_set_material(struct wined3d_device *device, const struct \
wined3d_material *material); +void __cdecl \
wined3d_device_set_max_frame_latency(struct wined3d_device *device, unsigned int \
max_frame_latency);  void __cdecl wined3d_device_set_multithreaded(struct \
wined3d_device *device);  HRESULT __cdecl wined3d_device_set_npatch_mode(struct \
wined3d_device *device, float segments);  void __cdecl \
wined3d_device_set_pixel_shader(struct wined3d_device *device, struct wined3d_shader \
                *shader);
-- 
2.11.0


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic