[PATCH 2/7] wined3d: Implement floating-point viewports.

Józef Kucia jkucia at codeweavers.com
Wed May 10 08:54:04 CDT 2017


Signed-off-by: Józef Kucia <jkucia at codeweavers.com>
---
 dlls/d3d11/device.c    |  6 ------
 dlls/d3d8/device.c     | 22 ++++++++++++++++++----
 dlls/d3d9/device.c     | 22 ++++++++++++++++++----
 dlls/ddraw/device.c    | 22 ++++++++++++++++++----
 dlls/wined3d/device.c  |  4 ++--
 dlls/wined3d/state.c   |  9 ++++++---
 include/wine/wined3d.h |  8 ++++----
 7 files changed, 66 insertions(+), 27 deletions(-)

diff --git a/dlls/d3d11/device.c b/dlls/d3d11/device.c
index 4284a59..df18375 100644
--- a/dlls/d3d11/device.c
+++ b/dlls/d3d11/device.c
@@ -927,12 +927,6 @@ static void STDMETHODCALLTYPE d3d11_immediate_context_RSSetViewports(ID3D11Devic
     if (!viewport_count)
         return;
 
-    if (viewports[0].TopLeftX != (UINT)viewports[0].TopLeftX
-            || viewports[0].TopLeftY != (UINT)viewports[0].TopLeftY
-            || viewports[0].Width != (UINT)viewports[0].Width
-            || viewports[0].Height != (UINT)viewports[0].Height)
-        FIXME("Floating-point viewports not implemented.\n");
-
     wined3d_vp.x = viewports[0].TopLeftX;
     wined3d_vp.y = viewports[0].TopLeftY;
     wined3d_vp.width = viewports[0].Width;
diff --git a/dlls/d3d8/device.c b/dlls/d3d8/device.c
index e255392..f7d05cc 100644
--- a/dlls/d3d8/device.c
+++ b/dlls/d3d8/device.c
@@ -1471,12 +1471,19 @@ static HRESULT WINAPI d3d8_device_MultiplyTransform(IDirect3DDevice8 *iface,
 static HRESULT WINAPI d3d8_device_SetViewport(IDirect3DDevice8 *iface, const D3DVIEWPORT8 *viewport)
 {
     struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
+    struct wined3d_viewport vp;
 
     TRACE("iface %p, viewport %p.\n", iface, viewport);
 
-    /* Note: D3DVIEWPORT8 is compatible with struct wined3d_viewport. */
+    vp.x = viewport->X;
+    vp.y = viewport->Y;
+    vp.width = viewport->Width;
+    vp.height = viewport->Height;
+    vp.min_z = viewport->MinZ;
+    vp.max_z = viewport->MaxZ;
+
     wined3d_mutex_lock();
-    wined3d_device_set_viewport(device->wined3d_device, (const struct wined3d_viewport *)viewport);
+    wined3d_device_set_viewport(device->wined3d_device, &vp);
     wined3d_mutex_unlock();
 
     return D3D_OK;
@@ -1485,14 +1492,21 @@ static HRESULT WINAPI d3d8_device_SetViewport(IDirect3DDevice8 *iface, const D3D
 static HRESULT WINAPI d3d8_device_GetViewport(IDirect3DDevice8 *iface, D3DVIEWPORT8 *viewport)
 {
     struct d3d8_device *device = impl_from_IDirect3DDevice8(iface);
+    struct wined3d_viewport wined3d_viewport;
 
     TRACE("iface %p, viewport %p.\n", iface, viewport);
 
-    /* Note: D3DVIEWPORT8 is compatible with struct wined3d_viewport. */
     wined3d_mutex_lock();
-    wined3d_device_get_viewport(device->wined3d_device, (struct wined3d_viewport *)viewport);
+    wined3d_device_get_viewport(device->wined3d_device, &wined3d_viewport);
     wined3d_mutex_unlock();
 
+    viewport->X = wined3d_viewport.x;
+    viewport->Y = wined3d_viewport.y;
+    viewport->Width = wined3d_viewport.width;
+    viewport->Height = wined3d_viewport.height;
+    viewport->MinZ = wined3d_viewport.min_z;
+    viewport->MaxZ = wined3d_viewport.max_z;
+
     return D3D_OK;
 }
 
diff --git a/dlls/d3d9/device.c b/dlls/d3d9/device.c
index 0cec419..cea1c9d 100644
--- a/dlls/d3d9/device.c
+++ b/dlls/d3d9/device.c
@@ -1885,12 +1885,19 @@ static HRESULT WINAPI d3d9_device_MultiplyTransform(IDirect3DDevice9Ex *iface,
 static HRESULT WINAPI d3d9_device_SetViewport(IDirect3DDevice9Ex *iface, const D3DVIEWPORT9 *viewport)
 {
     struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+    struct wined3d_viewport vp;
 
     TRACE("iface %p, viewport %p.\n", iface, viewport);
 
-    /* Note: D3DVIEWPORT9 is compatible with struct wined3d_viewport. */
+    vp.x = viewport->X;
+    vp.y = viewport->Y;
+    vp.width = viewport->Width;
+    vp.height = viewport->Height;
+    vp.min_z = viewport->MinZ;
+    vp.max_z = viewport->MaxZ;
+
     wined3d_mutex_lock();
-    wined3d_device_set_viewport(device->wined3d_device, (const struct wined3d_viewport *)viewport);
+    wined3d_device_set_viewport(device->wined3d_device, &vp);
     wined3d_mutex_unlock();
 
     return D3D_OK;
@@ -1899,14 +1906,21 @@ static HRESULT WINAPI d3d9_device_SetViewport(IDirect3DDevice9Ex *iface, const D
 static HRESULT WINAPI d3d9_device_GetViewport(IDirect3DDevice9Ex *iface, D3DVIEWPORT9 *viewport)
 {
     struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
+    struct wined3d_viewport wined3d_viewport;
 
     TRACE("iface %p, viewport %p.\n", iface, viewport);
 
-    /* Note: D3DVIEWPORT9 is compatible with struct wined3d_viewport. */
     wined3d_mutex_lock();
-    wined3d_device_get_viewport(device->wined3d_device, (struct wined3d_viewport *)viewport);
+    wined3d_device_get_viewport(device->wined3d_device, &wined3d_viewport);
     wined3d_mutex_unlock();
 
+    viewport->X = wined3d_viewport.x;
+    viewport->Y = wined3d_viewport.y;
+    viewport->Width = wined3d_viewport.width;
+    viewport->Height = wined3d_viewport.height;
+    viewport->MinZ = wined3d_viewport.min_z;
+    viewport->MaxZ = wined3d_viewport.max_z;
+
     return D3D_OK;
 }
 
diff --git a/dlls/ddraw/device.c b/dlls/ddraw/device.c
index 772ce3e..6a6c19c 100644
--- a/dlls/ddraw/device.c
+++ b/dlls/ddraw/device.c
@@ -5303,15 +5303,22 @@ static HRESULT WINAPI d3d_device7_Clear_FPUPreserve(IDirect3DDevice7 *iface, DWO
 static HRESULT d3d_device7_SetViewport(IDirect3DDevice7 *iface, D3DVIEWPORT7 *viewport)
 {
     struct d3d_device *device = impl_from_IDirect3DDevice7(iface);
+    struct wined3d_viewport vp;
 
     TRACE("iface %p, viewport %p.\n", iface, viewport);
 
     if (!viewport)
         return DDERR_INVALIDPARAMS;
 
-    /* Note: D3DVIEWPORT7 is compatible with struct wined3d_viewport. */
+    vp.x = viewport->dwX;
+    vp.y = viewport->dwY;
+    vp.width = viewport->dwWidth;
+    vp.height = viewport->dwHeight;
+    vp.min_z = viewport->dvMinZ;
+    vp.max_z = viewport->dvMaxZ;
+
     wined3d_mutex_lock();
-    wined3d_device_set_viewport(device->wined3d_device, (struct wined3d_viewport *)viewport);
+    wined3d_device_set_viewport(device->wined3d_device, &vp);
     wined3d_mutex_unlock();
 
     return D3D_OK;
@@ -5352,17 +5359,24 @@ static HRESULT WINAPI d3d_device7_SetViewport_FPUPreserve(IDirect3DDevice7 *ifac
 static HRESULT d3d_device7_GetViewport(IDirect3DDevice7 *iface, D3DVIEWPORT7 *viewport)
 {
     struct d3d_device *device = impl_from_IDirect3DDevice7(iface);
+    struct wined3d_viewport wined3d_viewport;
 
     TRACE("iface %p, viewport %p.\n", iface, viewport);
 
     if (!viewport)
         return DDERR_INVALIDPARAMS;
 
-    /* Note: D3DVIEWPORT7 is compatible with struct wined3d_viewport. */
     wined3d_mutex_lock();
-    wined3d_device_get_viewport(device->wined3d_device, (struct wined3d_viewport *)viewport);
+    wined3d_device_get_viewport(device->wined3d_device, &wined3d_viewport);
     wined3d_mutex_unlock();
 
+    viewport->dwX = wined3d_viewport.x;
+    viewport->dwY = wined3d_viewport.y;
+    viewport->dwWidth = wined3d_viewport.width;
+    viewport->dwHeight = wined3d_viewport.height;
+    viewport->dvMinZ = wined3d_viewport.min_z;
+    viewport->dvMaxZ = wined3d_viewport.max_z;
+
     return D3D_OK;
 }
 
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index 2637411..9aea4f2 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -1887,7 +1887,7 @@ INT CDECL wined3d_device_get_base_vertex_index(const struct wined3d_device *devi
 void CDECL wined3d_device_set_viewport(struct wined3d_device *device, const struct wined3d_viewport *viewport)
 {
     TRACE("device %p, viewport %p.\n", device, viewport);
-    TRACE("x %u, y %u, w %u, h %u, min_z %.8e, max_z %.8e.\n",
+    TRACE("x %.8e, y %.8e, w %.8e, h %.8e, min_z %.8e, max_z %.8e.\n",
           viewport->x, viewport->y, viewport->width, viewport->height, viewport->min_z, viewport->max_z);
 
     device->update_state->viewport = *viewport;
@@ -3082,7 +3082,7 @@ static HRESULT process_vertices_strided(const struct wined3d_device *device, DWO
 
     /* Get the viewport */
     wined3d_device_get_viewport(device, &vp);
-    TRACE("viewport  x %u, y %u, width %u, height %u, min_z %.8e, max_z %.8e.\n",
+    TRACE("viewport  x %.8e, y %.8e, width %.8e, height %.8e, min_z %.8e, max_z %.8e.\n",
           vp.x, vp.y, vp.width, vp.height, vp.min_z, vp.max_z);
 
     multiply_matrix(&mat,&view_mat,&world_mat);
diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c
index b36c0fd..ad063fe 100644
--- a/dlls/wined3d/state.c
+++ b/dlls/wined3d/state.c
@@ -4598,6 +4598,7 @@ static void viewport_miscpart(struct wined3d_context *context, const struct wine
     const struct wined3d_gl_info *gl_info = context->gl_info;
     struct wined3d_viewport vp = state->viewport;
     unsigned int width, height;
+    float y;
 
     if (target)
     {
@@ -4623,10 +4624,12 @@ static void viewport_miscpart(struct wined3d_context *context, const struct wine
     checkGLcall("glDepthRange");
     /* Note: GL requires lower left, DirectX supplies upper left. This is
      * reversed when using offscreen rendering. */
-    if (context->render_offscreen)
-        gl_info->gl_ops.gl.p_glViewport(vp.x, vp.y, vp.width, vp.height);
+    y = context->render_offscreen ? vp.y : height - (vp.y + vp.height);
+
+    if (gl_info->supported[ARB_VIEWPORT_ARRAY])
+        GL_EXTCALL(glViewportIndexedf(0, vp.x, y, vp.width, vp.height));
     else
-        gl_info->gl_ops.gl.p_glViewport(vp.x, (height - (vp.y + vp.height)), vp.width, vp.height);
+        gl_info->gl_ops.gl.p_glViewport(vp.x, y, vp.width, vp.height);
     checkGLcall("glViewport");
 }
 
diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h
index 0bf3e55..2966d5e 100644
--- a/include/wine/wined3d.h
+++ b/include/wine/wined3d.h
@@ -1619,10 +1619,10 @@ struct wined3d_material
 
 struct wined3d_viewport
 {
-    UINT x;
-    UINT y;
-    UINT width;
-    UINT height;
+    float x;
+    float y;
+    float width;
+    float height;
     float min_z;
     float max_z;
 };
-- 
2.10.2




More information about the wine-patches mailing list