ddraw: Forbid setting viewport extents larger than the render target in SetViewport().

Signed-off-by: Matteo Bruni <mbruni@codeweavers.com>
Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Matteo Bruni 2018-04-20 00:55:40 +02:00 committed by Alexandre Julliard
parent ceba01e2ba
commit 700394f5ff
1 changed files with 32 additions and 7 deletions

View File

@ -299,7 +299,10 @@ static HRESULT WINAPI d3d_viewport_SetViewport(IDirect3DViewport3 *iface, D3DVIE
{ {
struct d3d_viewport *viewport = impl_from_IDirect3DViewport3(iface); struct d3d_viewport *viewport = impl_from_IDirect3DViewport3(iface);
struct d3d_device *device = viewport->active_device; struct d3d_device *device = viewport->active_device;
struct wined3d_sub_resource_desc rt_desc;
struct wined3d_rendertarget_view *rtv;
IDirect3DViewport3 *current_viewport; IDirect3DViewport3 *current_viewport;
struct ddraw_surface *surface;
TRACE("iface %p, vp %p.\n", iface, vp); TRACE("iface %p, vp %p.\n", iface, vp);
@ -312,8 +315,33 @@ static HRESULT WINAPI d3d_viewport_SetViewport(IDirect3DViewport3 *iface, D3DVIE
_dump_D3DVIEWPORT(vp); _dump_D3DVIEWPORT(vp);
} }
if (!device)
{
WARN("Viewport not bound to a device, returning D3DERR_VIEWPORTHASNODEVICE.\n");
return D3DERR_VIEWPORTHASNODEVICE;
}
wined3d_mutex_lock(); wined3d_mutex_lock();
if (device->version > 1)
{
if (!(rtv = wined3d_device_get_rendertarget_view(device->wined3d_device, 0)))
{
wined3d_mutex_unlock();
return DDERR_INVALIDCAPS;
}
surface = wined3d_rendertarget_view_get_sub_resource_parent(rtv);
wined3d_texture_get_sub_resource_desc(surface->wined3d_texture, surface->sub_resource_idx, &rt_desc);
if (vp->dwX > rt_desc.width || vp->dwWidth > rt_desc.width - vp->dwX
|| vp->dwY > rt_desc.height || vp->dwHeight > rt_desc.height - vp->dwY)
{
WARN("Invalid viewport, returning DDERR_INVALIDPARAMS.\n");
wined3d_mutex_unlock();
return DDERR_INVALIDPARAMS;
}
}
viewport->use_vp2 = 0; viewport->use_vp2 = 0;
memset(&viewport->viewports.vp1, 0, sizeof(viewport->viewports.vp1)); memset(&viewport->viewports.vp1, 0, sizeof(viewport->viewports.vp1));
memcpy(&viewport->viewports.vp1, vp, vp->dwSize); memcpy(&viewport->viewports.vp1, vp, vp->dwSize);
@ -323,15 +351,12 @@ static HRESULT WINAPI d3d_viewport_SetViewport(IDirect3DViewport3 *iface, D3DVIE
viewport->viewports.vp1.dvMinZ = 0.0; viewport->viewports.vp1.dvMinZ = 0.0;
viewport->viewports.vp1.dvMaxZ = 1.0; viewport->viewports.vp1.dvMaxZ = 1.0;
if (device)
{
if (SUCCEEDED(IDirect3DDevice3_GetCurrentViewport(&device->IDirect3DDevice3_iface, &current_viewport))) if (SUCCEEDED(IDirect3DDevice3_GetCurrentViewport(&device->IDirect3DDevice3_iface, &current_viewport)))
{ {
if (current_viewport == iface) if (current_viewport == iface)
viewport_activate(viewport, FALSE); viewport_activate(viewport, FALSE);
IDirect3DViewport3_Release(current_viewport); IDirect3DViewport3_Release(current_viewport);
} }
}
wined3d_mutex_unlock(); wined3d_mutex_unlock();