Allow arbitrary viewports for d3d11 in wined3d Accepted

Revisions: 

Revision 2

user image Michael Müller Author
17 Aug. 17

The current wined3d implementation restricts the viewport size based on the d3d9 behavior. Direct3D11 does no longer have these restrictions, so the patch makes the check conditionally. I assume that the same applies for d3d10, but a test wouldn't hurt.

v2: I accidentally attached an old version of the patch (fixed flag handling in ddraw)

Single files Merged diff Tar archive
You have unsaved changes. Press CTRL + ENTER in a text field to submit your comments.

0001-wined3d-Allow-arbitrary-viewports-for-d3d11.patch

From 0264af12758152fbd9c4fdbc6a2f279e6cd592a8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
Date: Thu, 17 Aug 2017 19:29:30 +0200
Subject: wined3d: Allow arbitrary viewports for d3d11.
---
dlls/d3d11/tests/d3d11.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++
dlls/d3d8/directx.c | 2 +-
dlls/d3d9/directx.c | 2 +-
dlls/ddraw/ddraw_private.h | 2 +-
dlls/wined3d/state.c | 23 +++++++++++--------
include/wine/wined3d.h | 1 +
6 files changed, 73 insertions(+), 12 deletions(-)
diff --git a/dlls/d3d11/tests/d3d11.c b/dlls/d3d11/tests/d3d11.c
index fe6bb03bac..e3314cec26 100644
--- a/dlls/d3d11/tests/d3d11.c
+++ b/dlls/d3d11/tests/d3d11.c
@@ -21727,6 +21727,60 @@ static void test_fractional_viewports(void)
release_test_context(&test_context);
}
+static void test_negative_viewports(void)
+{
+ struct d3d11_test_context test_context;
+ ID3D11DeviceContext *context;
+ D3D11_VIEWPORT vp;
+ DWORD color;
+
+ static const float red[] = {1.0f, 0.0f, 0.0f, 1.0f};
+ static const struct vec4 white = {1.0f, 1.0f, 1.0f, 1.0f};
+
+ if (!init_test_context(&test_context, NULL))
+ return;
+
+ context = test_context.immediate_context;
+
+ ID3D11DeviceContext_ClearRenderTargetView(context, test_context.backbuffer_rtv, red);
+ draw_color_quad(&test_context, &white);
+ color = get_texture_color(test_context.backbuffer, 320, 240);
+ ok(compare_color(color, 0xffffffff, 1), "Got unexpected color 0x%08x.\n", color);
+
+ vp.TopLeftX = -640;
+ vp.TopLeftY = 0;
+ vp.Width = 640 * 2;
+ vp.Height = 480;
+ vp.MinDepth = 0.0f;
+ vp.MaxDepth = 1.0f;
+ ID3D11DeviceContext_RSSetViewports(context, 1, &vp);
+
+ ID3D11DeviceContext_ClearRenderTargetView(context, test_context.backbuffer_rtv, red);
+ draw_color_quad(&test_context, &white);
+ color = get_texture_color(test_context.backbuffer, 320, 240);
+ ok(compare_color(color, 0xffffffff, 1), "Got unexpected color 0x%08x.\n", color);
+
+ vp.Width = 640;
+ ID3D11DeviceContext_RSSetViewports(context, 1, &vp);
+
+ ID3D11DeviceContext_ClearRenderTargetView(context, test_context.backbuffer_rtv, red);
+ draw_color_quad(&test_context, &white);
+ color = get_texture_color(test_context.backbuffer, 320, 240);
+ ok(compare_color(color, 0xff0000ff, 1), "Got unexpected color 0x%08x.\n", color);
+
+ vp.Width = 640 + 320;
+ ID3D11DeviceContext_RSSetViewports(context, 1, &vp);
+
+ ID3D11DeviceContext_ClearRenderTargetView(context, test_context.backbuffer_rtv, red);
+ draw_color_quad(&test_context, &white);
+ color = get_texture_color(test_context.backbuffer, 320, 240);
+ ok(compare_color(color, 0xff0000ff, 1), "Got unexpected color 0x%08x.\n", color);
+ color = get_texture_color(test_context.backbuffer, 319, 240);
+ ok(compare_color(color, 0xffffffff, 1), "Got unexpected color 0x%08x.\n", color);
+
+ release_test_context(&test_context);
+}
+
static void test_early_depth_stencil(void)
{
ID3D11DepthStencilState *depth_stencil_state;
@@ -21948,5 +22002,6 @@ START_TEST(d3d11)
test_gather();
test_gather_c();
test_fractional_viewports();
+ test_negative_viewports();
test_early_depth_stencil();
}
diff --git a/dlls/d3d8/directx.c b/dlls/d3d8/directx.c
index 24bd831598..491efea31e 100644
--- a/dlls/d3d8/directx.c
+++ b/dlls/d3d8/directx.c
@@ -418,7 +418,7 @@ BOOL d3d8_init(struct d3d8 *d3d8)
DWORD flags = WINED3D_LEGACY_DEPTH_BIAS | WINED3D_VIDMEM_ACCOUNTING
| WINED3D_HANDLE_RESTORE | WINED3D_PIXEL_CENTER_INTEGER
| WINED3D_LEGACY_UNBOUND_RESOURCE_COLOR | WINED3D_NO_PRIMITIVE_RESTART
- | WINED3D_LEGACY_CUBEMAP_FILTERING;
+ | WINED3D_LEGACY_CUBEMAP_FILTERING | WINED3D_LIMIT_VIEWPORT;
d3d8->IDirect3D8_iface.lpVtbl = &d3d8_vtbl;
d3d8->refcount = 1;
diff --git a/dlls/d3d9/directx.c b/dlls/d3d9/directx.c
index fe7163fa88..c138952958 100644
--- a/dlls/d3d9/directx.c
+++ b/dlls/d3d9/directx.c
@@ -580,7 +580,7 @@ BOOL d3d9_init(struct d3d9 *d3d9, BOOL extended)
{
DWORD flags = WINED3D_PRESENT_CONVERSION | WINED3D_HANDLE_RESTORE | WINED3D_PIXEL_CENTER_INTEGER
| WINED3D_SRGB_READ_WRITE_CONTROL | WINED3D_LEGACY_UNBOUND_RESOURCE_COLOR
- | WINED3D_NO_PRIMITIVE_RESTART | WINED3D_LEGACY_CUBEMAP_FILTERING;
+ | WINED3D_NO_PRIMITIVE_RESTART | WINED3D_LEGACY_CUBEMAP_FILTERING | WINED3D_LIMIT_VIEWPORT;
if (!extended)
flags |= WINED3D_VIDMEM_ACCOUNTING;
diff --git a/dlls/ddraw/ddraw_private.h b/dlls/ddraw/ddraw_private.h
index c693135e84..912e8b6f53 100644
--- a/dlls/ddraw/ddraw_private.h
+++ b/dlls/ddraw/ddraw_private.h
@@ -63,7 +63,7 @@ struct FvfToDecl
#define DDRAW_WINED3D_FLAGS (WINED3D_LEGACY_DEPTH_BIAS | WINED3D_VIDMEM_ACCOUNTING \
| WINED3D_RESTORE_MODE_ON_ACTIVATE | WINED3D_FOCUS_MESSAGES | WINED3D_PIXEL_CENTER_INTEGER \
| WINED3D_LEGACY_UNBOUND_RESOURCE_COLOR | WINED3D_NO_PRIMITIVE_RESTART \
- | WINED3D_LEGACY_CUBEMAP_FILTERING)
+ | WINED3D_LEGACY_CUBEMAP_FILTERING | WINED3D_LIMIT_VIEWPORT)
enum ddraw_device_state
{
diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c
index a5a1a4bf90..4424da4e85 100644
--- a/dlls/wined3d/state.c
+++ b/dlls/wined3d/state.c
@@ -4629,11 +4629,13 @@ static void viewport_miscpart(struct wined3d_context *context, const struct wine
if (target)
{
- if (vp.width > target->width)
- vp.width = target->width;
- if (vp.height > target->height)
- vp.height = target->height;
-
+ if (context->d3d_info->wined3d_creation_flags & WINED3D_LIMIT_VIEWPORT)
+ {
+ if (vp.width > target->width)
+ vp.width = target->width;
+ if (vp.height > target->height)
+ vp.height = target->height;
+ }
wined3d_rendertarget_view_get_drawable_size(target, context, &width, &height);
}
else if (depth_stencil)
@@ -4675,10 +4677,13 @@ static void viewport_miscpart_cc(struct wined3d_context *context,
if (target)
{
- if (vp.width > target->width)
- vp.width = target->width;
- if (vp.height > target->height)
- vp.height = target->height;
+ if (context->d3d_info->wined3d_creation_flags & WINED3D_LIMIT_VIEWPORT)
+ {
+ if (vp.width > target->width)
+ vp.width = target->width;
+ if (vp.height > target->height)
+ vp.height = target->height;
+ }
wined3d_rendertarget_view_get_drawable_size(target, context, &width, &height);
}
diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h
index b8fb5503e5..c9cdf8dd1d 100644
--- a/include/wine/wined3d.h
+++ b/include/wine/wined3d.h
@@ -1325,6 +1325,7 @@ enum wined3d_shader_byte_code_format
#define WINED3D_LEGACY_CUBEMAP_FILTERING 0x00001000
#define WINED3D_FORWARD_DEPTH_BIAS 0x00002000
#define WINED3D_REQUEST_D3D10 0x00004000
+#define WINED3D_LIMIT_VIEWPORT 0x00008000
#define WINED3D_RESZ_CODE 0x7fa05000
--
2.13.2