[PATCH 1/2] d3d11: Allow setting multiple viewports

Nikolay Sivov nsivov at codeweavers.com
Mon Apr 16 18:16:53 CDT 2018


Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
 dlls/d3d11/device.c      | 25 +++++++++++++------------
 dlls/d3d11/tests/d3d11.c | 28 ++++++++++++++++++++++++----
 2 files changed, 37 insertions(+), 16 deletions(-)

diff --git a/dlls/d3d11/device.c b/dlls/d3d11/device.c
index 659b33c101..9f1533b8df 100644
--- a/dlls/d3d11/device.c
+++ b/dlls/d3d11/device.c
@@ -961,25 +961,26 @@ static void STDMETHODCALLTYPE d3d11_immediate_context_RSSetViewports(ID3D11Devic
         UINT viewport_count, const D3D11_VIEWPORT *viewports)
 {
     struct d3d_device *device = device_from_immediate_ID3D11DeviceContext(iface);
-    struct wined3d_viewport wined3d_vp;
+    struct wined3d_viewport wined3d_vp[WINED3D_MAX_VIEWPORTS];
+    unsigned int i;
 
     TRACE("iface %p, viewport_count %u, viewports %p.\n", iface, viewport_count, viewports);
 
-    if (viewport_count > 1)
-        FIXME("Multiple viewports not implemented.\n");
-
-    if (!viewport_count)
+    if (viewport_count > ARRAY_SIZE(wined3d_vp))
         return;
 
-    wined3d_vp.x = viewports[0].TopLeftX;
-    wined3d_vp.y = viewports[0].TopLeftY;
-    wined3d_vp.width = viewports[0].Width;
-    wined3d_vp.height = viewports[0].Height;
-    wined3d_vp.min_z = viewports[0].MinDepth;
-    wined3d_vp.max_z = viewports[0].MaxDepth;
+    for (i = 0; i < viewport_count; ++i)
+    {
+        wined3d_vp[i].x = viewports[i].TopLeftX;
+        wined3d_vp[i].y = viewports[i].TopLeftY;
+        wined3d_vp[i].width = viewports[i].Width;
+        wined3d_vp[i].height = viewports[i].Height;
+        wined3d_vp[i].min_z = viewports[i].MinDepth;
+        wined3d_vp[i].max_z = viewports[i].MaxDepth;
+    }
 
     wined3d_mutex_lock();
-    wined3d_device_set_viewports(device->wined3d_device, 1, &wined3d_vp);
+    wined3d_device_set_viewports(device->wined3d_device, viewport_count, wined3d_vp);
     wined3d_mutex_unlock();
 }
 
diff --git a/dlls/d3d11/tests/d3d11.c b/dlls/d3d11/tests/d3d11.c
index b3597ad1b3..770ab0af34 100644
--- a/dlls/d3d11/tests/d3d11.c
+++ b/dlls/d3d11/tests/d3d11.c
@@ -10578,7 +10578,6 @@ static void test_clear_state(void)
     ID3D11DeviceContext_RSGetViewports(context, &count, tmp_viewport);
     for (i = 0; i < D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE; ++i)
     {
-        todo_wine_if(!i)
         ok(!tmp_viewport[i].TopLeftX && !tmp_viewport[i].TopLeftY && !tmp_viewport[i].Width
                 && !tmp_viewport[i].Height && !tmp_viewport[i].MinDepth && !tmp_viewport[i].MaxDepth,
                 "Got unexpected viewport {%.8e, %.8e, %.8e, %.8e, %.8e, %.8e} in slot %u.\n",
@@ -25927,6 +25926,7 @@ static void test_multiple_viewports(void)
         unsigned int draw_id;
         unsigned int padding[3];
     } constant;
+    D3D11_VIEWPORT vp[D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE + 1];
     struct d3d11_test_context test_context;
     D3D11_TEXTURE2D_DESC texture_desc;
     ID3D11DeviceContext *context;
@@ -26014,7 +26014,7 @@ static void test_multiple_viewports(void)
         {0.0f, 1.0f}, {1.0f, 1.0f}, {0.0f, 2.0f}, {0.5f, 0.5f}, {0.5f, 0.5f},
     };
     static const float clear_color[] = {0.5f, 0.5f, 0.0f, 0.0f};
-    D3D11_VIEWPORT vp[2];
+    unsigned int count, i;
     RECT rect;
     int width;
 
@@ -26078,7 +26078,6 @@ static void test_multiple_viewports(void)
     SetRect(&rect, 0, 0, width - 1, texture_desc.Height - 1);
     check_texture_sub_resource_vec4(texture, 0, &rect, &expected_values[0], 1);
     SetRect(&rect, width, 0, 2 * width - 1, texture_desc.Height - 1);
-todo_wine
     check_texture_sub_resource_vec4(texture, 0, &rect, &expected_values[1], 1);
 
     /* One viewport. */
@@ -26098,9 +26097,30 @@ todo_wine
     constant.draw_id = 3;
     ID3D11DeviceContext_UpdateSubresource(context, (ID3D11Resource *)cb, 0, NULL, &constant, 0, 0);
     draw_quad(&test_context);
-todo_wine
     check_texture_sub_resource_vec4(texture, 0, NULL, &expected_values[4], 1);
 
+    /* Viewport count exceeding maximum value. */
+    ID3D11DeviceContext_RSSetViewports(context, 1, vp);
+
+    vp[0].TopLeftX = 1.0f;
+    vp[0].TopLeftY = 0.0f;
+    vp[0].Width = width;
+    vp[0].Height = texture_desc.Height;
+    vp[0].MinDepth = 0.0f;
+    vp[0].MaxDepth = 1.0f;
+    for (i = 1; i < ARRAY_SIZE(vp); ++i)
+    {
+        vp[i] = vp[0];
+    }
+    ID3D11DeviceContext_RSSetViewports(context, ARRAY_SIZE(vp), vp);
+
+    count = ARRAY_SIZE(vp);
+    memset(vp, 0, sizeof(vp));
+    ID3D11DeviceContext_RSGetViewports(context, &count, vp);
+todo_wine
+    ok(count == 1, "Unexpected viewport count %d.\n", count);
+    ok(vp[0].TopLeftX == 0.0f && vp[0].Width == width, "Unexpected viewport.\n");
+
     ID3D11RenderTargetView_Release(rtv);
     ID3D11Texture2D_Release(texture);
 
-- 
2.17.0




More information about the wine-devel mailing list