Jan Sikorski : wined3d: Set render targets and UAVs atomically in wined3d.

Alexandre Julliard julliard at winehq.org
Fri Oct 15 15:40:05 CDT 2021


Module: wine
Branch: master
Commit: 3f4e6673dcafcc30a6b6286203fe3a11043c32de
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=3f4e6673dcafcc30a6b6286203fe3a11043c32de

Author: Jan Sikorski <jsikorski at codeweavers.com>
Date:   Fri Oct 15 14:25:58 2021 +0200

wined3d: Set render targets and UAVs atomically in wined3d.

Signed-off-by: Jan Sikorski <jsikorski at codeweavers.com>
Signed-off-by: Henri Verbeet <hverbeet at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/d3d11/device.c       | 42 ++++++++++++++++++++++++++++--------------
 dlls/wined3d/device.c     | 31 +++++++++++++++++++++++++++++++
 dlls/wined3d/wined3d.spec |  1 +
 include/wine/wined3d.h    |  4 ++++
 4 files changed, 64 insertions(+), 14 deletions(-)

diff --git a/dlls/d3d11/device.c b/dlls/d3d11/device.c
index 68b0333604f..31c68f62e68 100644
--- a/dlls/d3d11/device.c
+++ b/dlls/d3d11/device.c
@@ -1140,7 +1140,11 @@ static void STDMETHODCALLTYPE d3d11_device_context_OMSetRenderTargetsAndUnordere
         ID3D11DepthStencilView *depth_stencil_view, UINT uav_start_idx, UINT uav_count,
         ID3D11UnorderedAccessView *const *uavs, const UINT *initial_counts)
 {
+    struct d3d_depthstencil_view *dsv = unsafe_impl_from_ID3D11DepthStencilView(depth_stencil_view);
+    struct wined3d_rendertarget_view *wined3d_rtvs[D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT] = {0};
+    struct wined3d_unordered_access_view *wined3d_uavs[D3D11_PS_CS_UAV_REGISTER_COUNT] = {0};
     struct d3d11_device_context *context = impl_from_ID3D11DeviceContext1(iface);
+    unsigned int wined3d_initial_counts[D3D11_PS_CS_UAV_REGISTER_COUNT];
     unsigned int i;
 
     TRACE("iface %p, render_target_view_count %u, render_target_views %p, depth_stencil_view %p, "
@@ -1148,18 +1152,29 @@ static void STDMETHODCALLTYPE d3d11_device_context_OMSetRenderTargetsAndUnordere
             iface, render_target_view_count, render_target_views, depth_stencil_view,
             uav_start_idx, uav_count, uavs, initial_counts);
 
-    if (render_target_view_count != D3D11_KEEP_RENDER_TARGETS_AND_DEPTH_STENCIL)
+    if (render_target_view_count == D3D11_KEEP_RENDER_TARGETS_AND_DEPTH_STENCIL)
+        render_target_view_count = ~0u;
+    else
     {
-        d3d11_device_context_OMSetRenderTargets(iface, render_target_view_count, render_target_views,
-                depth_stencil_view);
+        if (render_target_view_count > ARRAY_SIZE(wined3d_rtvs))
+        {
+            WARN("View count %u exceeds limit.\n", render_target_view_count);
+            render_target_view_count = ARRAY_SIZE(wined3d_rtvs);
+        }
+
+        for (i = 0; i < render_target_view_count; ++i)
+        {
+            struct d3d_rendertarget_view *rtv = unsafe_impl_from_ID3D11RenderTargetView(render_target_views[i]);
+
+            wined3d_rtvs[i] = rtv ? rtv->wined3d_view : NULL;
+        }
     }
 
-    if (uav_count != D3D11_KEEP_UNORDERED_ACCESS_VIEWS)
+    if (uav_count == D3D11_KEEP_UNORDERED_ACCESS_VIEWS)
+        uav_count = ~0u;
+    else
     {
-        struct wined3d_unordered_access_view *wined3d_views[D3D11_PS_CS_UAV_REGISTER_COUNT] = {0};
-        unsigned int wined3d_initial_counts[D3D11_PS_CS_UAV_REGISTER_COUNT];
-
-        if (!wined3d_bound_range(uav_start_idx, uav_count, ARRAY_SIZE(wined3d_views)))
+        if (!wined3d_bound_range(uav_start_idx, uav_count, ARRAY_SIZE(wined3d_uavs)))
         {
             WARN("View count %u exceeds limit; ignoring call.\n", uav_count);
             return;
@@ -1172,15 +1187,14 @@ static void STDMETHODCALLTYPE d3d11_device_context_OMSetRenderTargetsAndUnordere
             struct d3d11_unordered_access_view *view =
                     unsafe_impl_from_ID3D11UnorderedAccessView(uavs[i]);
 
-            wined3d_views[uav_start_idx + i] = view ? view->wined3d_view : NULL;
+            wined3d_uavs[uav_start_idx + i] = view ? view->wined3d_view : NULL;
             wined3d_initial_counts[uav_start_idx + i] = initial_counts ? initial_counts[i] : ~0u;
         }
-
-        wined3d_mutex_lock();
-        wined3d_device_context_set_unordered_access_views(context->wined3d_context, WINED3D_PIPELINE_GRAPHICS,
-                0, ARRAY_SIZE(wined3d_views), wined3d_views, wined3d_initial_counts);
-        wined3d_mutex_unlock();
     }
+
+    wined3d_device_context_set_render_targets_and_unordered_access_views(context->wined3d_context, ARRAY_SIZE(wined3d_rtvs),
+            wined3d_rtvs, dsv ? dsv->wined3d_view : NULL, ARRAY_SIZE(wined3d_uavs), wined3d_uavs,
+            wined3d_initial_counts);
 }
 
 static void STDMETHODCALLTYPE d3d11_device_context_OMSetBlendState(ID3D11DeviceContext1 *iface,
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index 6b2f18c6996..86945485e20 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -2110,6 +2110,37 @@ out:
     wined3d_mutex_unlock();
 }
 
+void CDECL wined3d_device_context_set_render_targets_and_unordered_access_views(struct wined3d_device_context *context,
+        unsigned int rtv_count, struct wined3d_rendertarget_view *const *render_target_views,
+        struct wined3d_rendertarget_view *depth_stencil_view, UINT uav_count,
+        struct wined3d_unordered_access_view *const *unordered_access_views, const unsigned int *initial_counts)
+{
+    wined3d_mutex_lock();
+    if (rtv_count != ~0u)
+    {
+        if (depth_stencil_view && !(depth_stencil_view->resource->bind_flags & WINED3D_BIND_DEPTH_STENCIL))
+        {
+            WARN("View resource %p has incompatible %s bind flags.\n",
+                    depth_stencil_view->resource, wined3d_debug_bind_flags(depth_stencil_view->resource->bind_flags));
+            goto out;
+        }
+
+        if (FAILED(wined3d_device_context_set_rendertarget_views(context, 0, rtv_count,
+                render_target_views, FALSE)))
+            goto out;
+
+        wined3d_device_context_set_depth_stencil_view(context, depth_stencil_view);
+    }
+
+    if (uav_count != ~0u)
+    {
+        wined3d_device_context_set_unordered_access_views(context, WINED3D_PIPELINE_GRAPHICS, 0, uav_count,
+                unordered_access_views, initial_counts);
+    }
+out:
+    wined3d_mutex_unlock();
+}
+
 static void wined3d_device_context_unbind_srv_for_rtv(struct wined3d_device_context *context,
         const struct wined3d_rendertarget_view *view, BOOL dsv)
 {
diff --git a/dlls/wined3d/wined3d.spec b/dlls/wined3d/wined3d.spec
index 1bce4def265..48bea5980ff 100644
--- a/dlls/wined3d/wined3d.spec
+++ b/dlls/wined3d/wined3d.spec
@@ -139,6 +139,7 @@
 @ cdecl wined3d_device_context_set_stream_outputs(ptr ptr)
 @ cdecl wined3d_device_context_set_stream_sources(ptr long long ptr)
 @ cdecl wined3d_device_context_set_unordered_access_views(ptr long long long ptr ptr)
+@ cdecl wined3d_device_context_set_render_targets_and_unordered_access_views(ptr long ptr ptr long ptr ptr)
 @ cdecl wined3d_device_context_set_vertex_declaration(ptr ptr)
 @ cdecl wined3d_device_context_set_viewports(ptr long ptr)
 @ cdecl wined3d_device_context_unmap(ptr ptr long)
diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h
index 7be893b8f21..7a6588ea4f4 100644
--- a/include/wine/wined3d.h
+++ b/include/wine/wined3d.h
@@ -2544,6 +2544,10 @@ HRESULT __cdecl wined3d_device_context_set_stream_sources(struct wined3d_device_
 void __cdecl wined3d_device_context_set_unordered_access_views(struct wined3d_device_context *context,
         enum wined3d_pipeline pipeline, unsigned int start_idx, unsigned int count,
         struct wined3d_unordered_access_view *const *uavs, const unsigned int *initial_counts);
+void __cdecl wined3d_device_context_set_render_targets_and_unordered_access_views(struct wined3d_device_context *context,
+        unsigned int rtv_count, struct wined3d_rendertarget_view *const *render_target_views,
+        struct wined3d_rendertarget_view *depth_stencil_view, UINT uav_count,
+        struct wined3d_unordered_access_view *const *unordered_access_views, const unsigned int *initial_counts);
 void __cdecl wined3d_device_context_set_vertex_declaration(struct wined3d_device_context *context,
         struct wined3d_vertex_declaration *declaration);
 void __cdecl wined3d_device_context_set_viewports(struct wined3d_device_context *context, unsigned int viewport_count,




More information about the wine-cvs mailing list