From 134d3f51fbbbca4a097b90bf7595e92d02f0c46d Mon Sep 17 00:00:00 2001 From: Nikolay Sivov Date: Wed, 18 Apr 2018 12:50:47 +0300 Subject: [PATCH] d3d10: Add support for returning multiple viewports. Signed-off-by: Nikolay Sivov Signed-off-by: Henri Verbeet Signed-off-by: Alexandre Julliard --- dlls/d3d10core/tests/device.c | 11 ++++++---- dlls/d3d11/device.c | 39 ++++++++++++++++++++--------------- 2 files changed, 29 insertions(+), 21 deletions(-) diff --git a/dlls/d3d10core/tests/device.c b/dlls/d3d10core/tests/device.c index 140ffe6b3af..26218bf8e05 100644 --- a/dlls/d3d10core/tests/device.c +++ b/dlls/d3d10core/tests/device.c @@ -4934,7 +4934,7 @@ float4 main(float4 color : COLOR) : SV_TARGET "Got unexpected scissor rect %s in slot %u.\n", wine_dbgstr_rect(&tmp_rect[i]), i); } ID3D10Device_RSGetViewports(device, &count, NULL); - todo_wine ok(!count, "Got unexpected viewport count %u.\n", count); + ok(!count, "Got unexpected viewport count %u.\n", count); memset(tmp_viewport, 0x55, sizeof(tmp_viewport)); count = D3D10_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE; ID3D10Device_RSGetViewports(device, &count, tmp_viewport); @@ -5329,7 +5329,7 @@ float4 main(float4 color : COLOR) : SV_TARGET "Got unexpected scissor rect %s in slot %u.\n", wine_dbgstr_rect(&tmp_rect[i]), i); } ID3D10Device_RSGetViewports(device, &count, NULL); - todo_wine ok(count == D3D10_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE, + ok(count == D3D10_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE, "Got unexpected viewport count %u.\n", count); memset(tmp_viewport, 0x55, sizeof(tmp_viewport)); ID3D10Device_RSGetViewports(device, &count, tmp_viewport); @@ -5467,7 +5467,7 @@ float4 main(float4 color : COLOR) : SV_TARGET wine_dbgstr_rect(&tmp_rect[i]), i); } ID3D10Device_RSGetViewports(device, &count, NULL); - todo_wine ok(!count, "Got unexpected viewport count %u.\n", count); + ok(!count, "Got unexpected viewport count %u.\n", count); memset(tmp_viewport, 0x55, sizeof(tmp_viewport)); count = D3D10_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE; ID3D10Device_RSGetViewports(device, &count, tmp_viewport); @@ -16330,6 +16330,10 @@ static void test_multiple_viewports(void) vp[1].Width = width; ID3D10Device_RSSetViewports(device, 2, vp); + count = ARRAY_SIZE(vp); + ID3D10Device_RSGetViewports(device, &count, vp); + ok(count == 2, "Unexpected viewport count %d.\n", count); + constant.draw_id = 0; ID3D10Device_UpdateSubresource(device, (ID3D10Resource *)cb, 0, NULL, &constant, 0, 0); draw_quad(&test_context); @@ -16379,7 +16383,6 @@ static void test_multiple_viewports(void) count = ARRAY_SIZE(vp); memset(vp, 0, sizeof(vp)); ID3D10Device_RSGetViewports(device, &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"); diff --git a/dlls/d3d11/device.c b/dlls/d3d11/device.c index d47dfc9e9b6..73779520360 100644 --- a/dlls/d3d11/device.c +++ b/dlls/d3d11/device.c @@ -4900,32 +4900,37 @@ static void STDMETHODCALLTYPE d3d10_device_RSGetViewports(ID3D10Device1 *iface, UINT *viewport_count, D3D10_VIEWPORT *viewports) { struct d3d_device *device = impl_from_ID3D10Device(iface); - struct wined3d_viewport wined3d_vp; + struct wined3d_viewport wined3d_vp[WINED3D_MAX_VIEWPORTS]; + unsigned int actual_count = ARRAY_SIZE(wined3d_vp), i; TRACE("iface %p, viewport_count %p, viewports %p.\n", iface, viewport_count, viewports); - if (!viewports) - { - *viewport_count = 1; - return; - } - - if (!*viewport_count) + if (!viewport_count) return; wined3d_mutex_lock(); - wined3d_device_get_viewports(device->wined3d_device, NULL, &wined3d_vp); + wined3d_device_get_viewports(device->wined3d_device, &actual_count, viewports ? wined3d_vp : NULL); wined3d_mutex_unlock(); - viewports[0].TopLeftX = wined3d_vp.x; - viewports[0].TopLeftY = wined3d_vp.y; - viewports[0].Width = wined3d_vp.width; - viewports[0].Height = wined3d_vp.height; - viewports[0].MinDepth = wined3d_vp.min_z; - viewports[0].MaxDepth = wined3d_vp.max_z; + if (!viewports) + { + *viewport_count = actual_count; + return; + } - if (*viewport_count > 1) - memset(&viewports[1], 0, (*viewport_count - 1) * sizeof(*viewports)); + if (*viewport_count > actual_count) + memset(&viewports[actual_count], 0, (*viewport_count - actual_count) * sizeof(*viewports)); + + *viewport_count = min(actual_count, *viewport_count); + for (i = 0; i < *viewport_count; ++i) + { + viewports[i].TopLeftX = wined3d_vp[i].x; + viewports[i].TopLeftY = wined3d_vp[i].y; + viewports[i].Width = wined3d_vp[i].width; + viewports[i].Height = wined3d_vp[i].height; + viewports[i].MinDepth = wined3d_vp[i].min_z; + viewports[i].MaxDepth = wined3d_vp[i].max_z; + } } static void STDMETHODCALLTYPE d3d10_device_RSGetScissorRects(ID3D10Device1 *iface, UINT *rect_count, D3D10_RECT *rects)