Signed-off-by: Matteo Bruni mbruni@codeweavers.com --- dlls/d3drm/viewport.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/dlls/d3drm/viewport.c b/dlls/d3drm/viewport.c index 37c70c8db20..5c0e24bc429 100644 --- a/dlls/d3drm/viewport.c +++ b/dlls/d3drm/viewport.c @@ -339,6 +339,9 @@ static HRESULT WINAPI d3drm_viewport2_Init(IDirect3DRMViewport2 *iface, IDirect3 if (FAILED(hr = IDirect3D_CreateViewport(d3d1, &viewport->d3d_viewport, NULL))) goto cleanup;
+ if (FAILED(hr = IDirect3DDevice_AddViewport(d3d_device, viewport->d3d_viewport))) + goto cleanup; + vp.dwSize = sizeof(vp); vp.dwWidth = width; vp.dwHeight = height; @@ -355,9 +358,6 @@ static HRESULT WINAPI d3drm_viewport2_Init(IDirect3DRMViewport2 *iface, IDirect3 if (FAILED(hr = IDirect3DViewport_SetViewport(viewport->d3d_viewport, &vp))) goto cleanup;
- if (FAILED(hr = IDirect3DDevice_AddViewport(d3d_device, viewport->d3d_viewport))) - goto cleanup; - if (FAILED(hr = IDirect3DRMFrame3_QueryInterface(camera, &IID_IDirect3DRMFrame, (void **)&viewport->camera))) goto cleanup;
Signed-off-by: Matteo Bruni mbruni@codeweavers.com --- dlls/ddraw/viewport.c | 39 ++++++++++++++++++++++++++++++++------- 1 file changed, 32 insertions(+), 7 deletions(-)
diff --git a/dlls/ddraw/viewport.c b/dlls/ddraw/viewport.c index 0bc746e974f..fad079f1edb 100644 --- a/dlls/ddraw/viewport.c +++ b/dlls/ddraw/viewport.c @@ -299,7 +299,10 @@ static HRESULT WINAPI d3d_viewport_SetViewport(IDirect3DViewport3 *iface, D3DVIE { struct d3d_viewport *viewport = impl_from_IDirect3DViewport3(iface); struct d3d_device *device = viewport->active_device; + struct wined3d_sub_resource_desc rt_desc; + struct wined3d_rendertarget_view *rtv; IDirect3DViewport3 *current_viewport; + struct ddraw_surface *surface;
TRACE("iface %p, vp %p.\n", iface, vp);
@@ -312,8 +315,33 @@ static HRESULT WINAPI d3d_viewport_SetViewport(IDirect3DViewport3 *iface, D3DVIE _dump_D3DVIEWPORT(vp); }
+ if (!device) + { + WARN("Viewport not bound to a device, returning D3DERR_VIEWPORTHASNODEVICE.\n"); + return D3DERR_VIEWPORTHASNODEVICE; + } + 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; memset(&viewport->viewports.vp1, 0, sizeof(viewport->viewports.vp1)); memcpy(&viewport->viewports.vp1, vp, vp->dwSize); @@ -323,14 +351,11 @@ static HRESULT WINAPI d3d_viewport_SetViewport(IDirect3DViewport3 *iface, D3DVIE viewport->viewports.vp1.dvMinZ = 0.0; viewport->viewports.vp1.dvMaxZ = 1.0;
- if (device) + if (SUCCEEDED(IDirect3DDevice3_GetCurrentViewport(&device->IDirect3DDevice3_iface, ¤t_viewport))) { - if (SUCCEEDED(IDirect3DDevice3_GetCurrentViewport(&device->IDirect3DDevice3_iface, ¤t_viewport))) - { - if (current_viewport == iface) - viewport_activate(viewport, FALSE); - IDirect3DViewport3_Release(current_viewport); - } + if (current_viewport == iface) + viewport_activate(viewport, FALSE); + IDirect3DViewport3_Release(current_viewport); }
wined3d_mutex_unlock();
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
Signed-off-by: Matteo Bruni mbruni@codeweavers.com --- dlls/ddraw/tests/ddraw2.c | 243 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 241 insertions(+), 2 deletions(-)
diff --git a/dlls/ddraw/tests/ddraw2.c b/dlls/ddraw/tests/ddraw2.c index 3bfb1b5785a..c2b438cf2ae 100644 --- a/dlls/ddraw/tests/ddraw2.c +++ b/dlls/ddraw/tests/ddraw2.c @@ -35,6 +35,11 @@ static HRESULT (WINAPI *pDwmIsCompositionEnabled)(BOOL *); #define ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0])) #endif
+struct vec2 +{ + float x, y; +}; + struct vec4 { float x, y, z, w; @@ -260,6 +265,45 @@ static D3DCOLOR get_surface_color(IDirectDrawSurface *surface, UINT x, UINT y) return color; }
+static void check_rect(IDirectDrawSurface *surface, RECT r, const char *message) +{ + LONG x_coords[2][2] = + { + {r.left - 1, r.left + 1}, + {r.right + 1, r.right - 1}, + }; + LONG y_coords[2][2] = + { + {r.top - 1, r.top + 1}, + {r.bottom + 1, r.bottom - 1} + }; + unsigned int i, j, x_side, y_side; + DWORD color; + LONG x, y; + + for (i = 0; i < 2; ++i) + { + for (j = 0; j < 2; ++j) + { + for (x_side = 0; x_side < 2; ++x_side) + { + for (y_side = 0; y_side < 2; ++y_side) + { + DWORD expected = (x_side == 1 && y_side == 1) ? 0x00ffffff : 0x00000000; + + x = x_coords[i][x_side]; + y = y_coords[j][y_side]; + if (x < 0 || x >= 640 || y < 0 || y >= 480) + continue; + color = get_surface_color(surface, x, y); + ok(color == expected, "%s: Pixel (%d, %d) has color %08x, expected %08x\n", + message, x, y, color, expected); + } + } + } + } +} + static DWORD get_device_z_depth(IDirect3DDevice2 *device) { DDSCAPS caps = {DDSCAPS_ZBUFFER}; @@ -1333,7 +1377,7 @@ static ULONG get_refcount(IUnknown *test_iface) return IUnknown_Release(test_iface); }
-static void test_viewport(void) +static void test_viewport_object(void) { IDirectDraw2 *ddraw; IDirect3D2 *d3d; @@ -12633,6 +12677,200 @@ static void test_enum_surfaces(void) IDirectDraw2_Release(ddraw); }
+static void test_viewport(void) +{ + static struct + { + D3DVIEWPORT7 vp; + RECT expected_rect; + const char *message; + } + tests[] = + { + {{ 0, 0, 640, 480}, { 0, 120, 479, 359}, "Viewport (0, 0) - (640, 480)"}, + {{ 0, 0, 320, 240}, { 0, 60, 239, 179}, "Viewport (0, 0) - (320, 240)"}, + {{ 0, 0, 1280, 960}, { 0, 240, 639, 479}, "Viewport (0, 0) - (1280, 960)"}, + {{ 0, 0, 2000, 1600}, { 0, 400, 639, 479}, "Viewport (0, 0) - (2000, 1600)"}, + {{100, 100, 640, 480}, {100, 220, 579, 459}, "Viewport (100, 100) - (640, 480)"}, + {{ 0, 0, 8192, 8192}, {-10, -10, -10, -10}, "Viewport (0, 0) - (8192, 8192)"}, + }; + static const struct vec2 rt_sizes[] = + { + {640, 480}, {1280, 960}, {320, 240}, {800, 600}, + }; + static D3DMATRIX mat = + { + 1.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 1.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 1.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f, + }; + static D3DLVERTEX quad[] = + { + {{-1.5f}, {-0.5f}, {0.1f}, 0, {0xffffffff}}, + {{-1.5f}, { 0.5f}, {0.1f}, 0, {0xffffffff}}, + {{ 0.5f}, {-0.5f}, {0.1f}, 0, {0xffffffff}}, + {{ 0.5f}, { 0.5f}, {0.1f}, 0, {0xffffffff}}, + }; + IDirect3DViewport2 *viewport, *full_viewport; + IDirect3DMaterial2 *black_background; + IDirectDrawSurface *rt, *ds; + DDSURFACEDESC surface_desc; + IDirect3DDevice2 *device; + BOOL expected_failure; + IDirectDraw2 *ddraw; + DDPIXELFORMAT z_fmt; + D3DRECT clear_rect; + unsigned int i, j; + IDirect3D2 *d3d; + D3DVIEWPORT vp; + ULONG refcount; + HWND window; + HRESULT hr; + + window = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW, + 0, 0, 640, 480, NULL, NULL, NULL, NULL); + ddraw = create_ddraw(); + ok(!!ddraw, "Failed to create a ddraw object.\n"); + if (!(device = create_device(ddraw, window, DDSCL_NORMAL))) + { + skip("Failed to create a 3D device, skipping test.\n"); + IDirectDraw2_Release(ddraw); + DestroyWindow(window); + return; + } + + hr = IDirect3DDevice2_GetDirect3D(device, &d3d); + ok(SUCCEEDED(hr), "Failed to get Direct3D2 interface, hr %#x.\n", hr); + + hr = IDirect3DDevice2_SetRenderState(device, D3DRENDERSTATE_ZENABLE, D3DZB_FALSE); + ok(SUCCEEDED(hr), "Failed to disable depth test, hr %#x.\n", hr); + hr = IDirect3DDevice2_SetRenderState(device, D3DRENDERSTATE_CULLMODE, D3DCULL_NONE); + ok(SUCCEEDED(hr), "Failed to disable culling, hr %#x.\n", hr); + + hr = IDirect3DDevice2_SetTransform(device, D3DTRANSFORMSTATE_WORLD, &mat); + ok(SUCCEEDED(hr), "Failed to set world transform, hr %#x.\n", hr); + hr = IDirect3DDevice2_SetTransform(device, D3DTRANSFORMSTATE_VIEW, &mat); + ok(SUCCEEDED(hr), "Failed to set view transform, hr %#x.\n", hr); + hr = IDirect3DDevice2_SetTransform(device, D3DTRANSFORMSTATE_PROJECTION, &mat); + ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr); + + black_background = create_diffuse_material(device, 0.0f, 0.0f, 0.0f, 0.0f); + + ds = get_depth_stencil(device); + memset(&surface_desc, 0, sizeof(surface_desc)); + surface_desc.dwSize = sizeof(surface_desc); + hr = IDirectDrawSurface_GetSurfaceDesc(ds, &surface_desc); + z_fmt = U4(surface_desc).ddpfPixelFormat; + + for (i = 0; i < ARRAY_SIZE(rt_sizes); ++i) + { + if (i) + { + memset(&surface_desc, 0, sizeof(surface_desc)); + surface_desc.dwSize = sizeof(surface_desc); + surface_desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT; + surface_desc.dwWidth = rt_sizes[i].x; + surface_desc.dwHeight = rt_sizes[i].y; + surface_desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE; + hr = IDirectDraw2_CreateSurface(ddraw, &surface_desc, &rt, NULL); + ok(SUCCEEDED(hr), "Failed to create render target, hr %#x (i %u).\n", hr, i); + + surface_desc.dwFlags = DDSD_CAPS | DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT; + surface_desc.ddsCaps.dwCaps = DDSCAPS_ZBUFFER; + U4(surface_desc).ddpfPixelFormat = z_fmt; + hr = IDirectDraw2_CreateSurface(ddraw, &surface_desc, &ds, NULL); + ok(SUCCEEDED(hr), "Failed to create depth buffer, hr %#x (i %u).\n", hr, i); + hr = IDirectDrawSurface_AddAttachedSurface(rt, ds); + ok(SUCCEEDED(hr), "Failed to attach depth buffer, hr %#x (i %u).\n", hr, i); + + hr = IDirect3DDevice2_SetRenderTarget(device, rt, 0); + ok(SUCCEEDED(hr), "Failed to set render target, hr %#x (i %u).\n", hr, i); + } + else + { + hr = IDirect3DDevice2_GetRenderTarget(device, &rt); + ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr); + } + + full_viewport = create_viewport(device, 0, 0, rt_sizes[i].x, rt_sizes[i].y); + viewport_set_background(device, full_viewport, black_background); + + U1(clear_rect).x1 = U2(clear_rect).y1 = 0; + U3(clear_rect).x2 = rt_sizes[i].x; + U4(clear_rect).y2 = rt_sizes[i].y; + + for (j = 0; j < ARRAY_SIZE(tests); ++j) + { + expected_failure = tests[j].vp.dwX + tests[j].vp.dwWidth > rt_sizes[i].x + || tests[j].vp.dwY + tests[j].vp.dwHeight > rt_sizes[i].y; + + hr = IDirect3DViewport2_Clear(full_viewport, 1, &clear_rect, D3DCLEAR_TARGET); + ok(SUCCEEDED(hr), "Failed to clear viewport, hr %#x (i %u, j %u).\n", hr, i, j); + + hr = IDirect3D2_CreateViewport(d3d, &viewport, NULL); + ok(SUCCEEDED(hr), "Failed to create viewport, hr %#x (i %u, j %u).\n", hr, i, j); + hr = IDirect3DViewport2_SetViewport2(viewport, NULL); + ok(hr == E_INVALIDARG, "Setting NULL viewport data returned unexpected hr %#x (i %u, j %u).\n", + hr, i, j); + memset(&vp, 0, sizeof(vp)); + vp.dwSize = sizeof(vp); + vp.dwX = tests[j].vp.dwX; + vp.dwY = tests[j].vp.dwY; + vp.dwWidth = tests[j].vp.dwWidth; + vp.dwHeight = tests[j].vp.dwHeight; + vp.dvScaleX = tests[j].vp.dwWidth / 2.0f; + vp.dvScaleY = tests[j].vp.dwHeight / 2.0f; + vp.dvMinZ = 0.0f; + vp.dvMaxZ = 1.0f; + hr = IDirect3DViewport2_SetViewport(viewport, &vp); + ok(hr == D3DERR_VIEWPORTHASNODEVICE, + "Setting viewport data returned unexpected hr %#x (i %u, j %u).\n", hr, i, j); + hr = IDirect3DDevice2_AddViewport(device, viewport); + ok(SUCCEEDED(hr), "Failed to add viewport, hr %#x (i %u, j %u).\n", hr, i, j); + hr = IDirect3DViewport2_SetViewport(viewport, &vp); + if (expected_failure) + ok(hr == E_INVALIDARG, "Setting viewport data returned unexpected hr %#x (i %u, j %u).\n", + hr, i, j); + else + ok(SUCCEEDED(hr), "Failed to set viewport data, hr %#x (i %u, j %u).\n", hr, i, j); + + hr = IDirect3DDevice2_SetCurrentViewport(device, viewport); + ok(SUCCEEDED(hr), "Failed to set the viewport, hr %#x (i %u, j %u).\n", hr, i, j); + if (expected_failure) + { + destroy_viewport(device, viewport); + continue; + } + + hr = IDirect3DDevice2_BeginScene(device); + ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x (i %u, j %u).\n", hr, i, j); + hr = IDirect3DDevice2_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, D3DVT_LVERTEX, quad, 4, 0); + ok(SUCCEEDED(hr), "Got unexpected hr %#x (i %u, j %u).\n", hr, i, j); + hr = IDirect3DDevice2_EndScene(device); + ok(SUCCEEDED(hr), "Failed to end scene, hr %#x (i %u, j %u).\n", hr, i, j); + + check_rect(rt, tests[j].expected_rect, tests[j].message); + + destroy_viewport(device, viewport); + } + + destroy_viewport(device, full_viewport); + + hr = IDirectDrawSurface_DeleteAttachedSurface(rt, 0, ds); + ok(SUCCEEDED(hr), "Failed to detach surface, hr %#x (i %u).\n", hr, i); + IDirectDrawSurface_Release(ds); + + IDirectDrawSurface_Release(rt); + } + + destroy_material(black_background); + refcount = IDirect3DDevice2_Release(device); + IDirect3D2_Release(d3d); + ok(!refcount, "Device has %u references left.\n", refcount); + DestroyWindow(window); +} + START_TEST(ddraw2) { DDDEVICEIDENTIFIER identifier; @@ -12678,7 +12916,7 @@ START_TEST(ddraw2) test_coop_level_threaded(); test_depth_blit(); test_texture_load_ckey(); - test_viewport(); + test_viewport_object(); test_zenable(); test_ck_rgba(); test_ck_default(); @@ -12743,4 +12981,5 @@ START_TEST(ddraw2) test_depth_readback(); test_clear(); test_enum_surfaces(); + test_viewport(); }
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
Signed-off-by: Matteo Bruni mbruni@codeweavers.com --- dlls/ddraw/tests/ddraw1.c | 223 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 221 insertions(+), 2 deletions(-)
diff --git a/dlls/ddraw/tests/ddraw1.c b/dlls/ddraw/tests/ddraw1.c index 4c2e703a994..fb0858f253b 100644 --- a/dlls/ddraw/tests/ddraw1.c +++ b/dlls/ddraw/tests/ddraw1.c @@ -33,6 +33,11 @@ static HRESULT (WINAPI *pDwmIsCompositionEnabled)(BOOL *); #define ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0])) #endif
+struct vec2 +{ + float x, y; +}; + struct vec4 { float x, y, z, w; @@ -263,6 +268,45 @@ static D3DCOLOR get_surface_color(IDirectDrawSurface *surface, UINT x, UINT y) return color; }
+static void check_rect(IDirectDrawSurface *surface, RECT r, const char *message) +{ + LONG x_coords[2][2] = + { + {r.left - 1, r.left + 1}, + {r.right + 1, r.right - 1}, + }; + LONG y_coords[2][2] = + { + {r.top - 1, r.top + 1}, + {r.bottom + 1, r.bottom - 1} + }; + unsigned int i, j, x_side, y_side; + DWORD color; + LONG x, y; + + for (i = 0; i < 2; ++i) + { + for (j = 0; j < 2; ++j) + { + for (x_side = 0; x_side < 2; ++x_side) + { + for (y_side = 0; y_side < 2; ++y_side) + { + DWORD expected = (x_side == 1 && y_side == 1) ? 0x00ffffff : 0x00000000; + + x = x_coords[i][x_side]; + y = y_coords[j][y_side]; + if (x < 0 || x >= 640 || y < 0 || y >= 480) + continue; + color = get_surface_color(surface, x, y); + ok(color == expected, "%s: Pixel (%d, %d) has color %08x, expected %08x\n", + message, x, y, color, expected); + } + } + } + } +} + static void emit_process_vertices(void **ptr, DWORD flags, WORD base_idx, DWORD vertex_count) { D3DINSTRUCTION *inst = *ptr; @@ -1165,7 +1209,7 @@ static ULONG get_refcount(IUnknown *test_iface) return IUnknown_Release(test_iface); }
-static void test_viewport(void) +static void test_viewport_object(void) { IDirectDraw *ddraw; IDirect3D *d3d; @@ -11371,6 +11415,180 @@ static void test_execute_data(void) DestroyWindow(window); }
+static void test_viewport(void) +{ + static struct + { + D3DVIEWPORT7 vp; + RECT expected_rect; + const char *message; + } + tests[] = + { + {{ 0, 0, 640, 480}, { 0, 120, 479, 359}, "(0, 0) - (640, 480) viewport"}, + {{ 0, 0, 320, 240}, { 0, 60, 239, 179}, "(0, 0) - (320, 240) viewport"}, + {{ 0, 0, 1280, 960}, {-10, -10, -1, -1}, "(0, 0) - (1280, 960) viewport"}, + {{ 0, 0, 2000, 1600}, {-10, -10, -1, -1}, "(0, 0) - (2000, 1600) viewport"}, + {{100, 100, 640, 480}, {-10, -10, -1, -1}, "(100, 100) - (640, 480) viewport"}, + {{ 0, 0, 8192, 8192}, {-10, -10, -1, -1}, "(0, 0) - (8192, 8192) viewport"}, + }; + static D3DMATRIX mat = + { + 1.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 1.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 1.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f, + }; + static D3DLVERTEX quad[] = + { + {{-1.5f}, {-0.5f}, {0.1f}, 0, {0xffffffff}}, + {{-1.5f}, { 0.5f}, {0.1f}, 0, {0xffffffff}}, + {{ 0.5f}, {-0.5f}, {0.1f}, 0, {0xffffffff}}, + {{ 0.5f}, { 0.5f}, {0.1f}, 0, {0xffffffff}}, + }; + D3DMATRIXHANDLE world_handle, view_handle, proj_handle; + IDirect3DViewport *viewport, *full_viewport; + IDirect3DExecuteBuffer *execute_buffer; + IDirect3DMaterial *black_background; + D3DEXECUTEBUFFERDESC exec_desc; + IDirect3DDevice *device; + IDirectDrawSurface *rt; + IDirectDraw *ddraw; + D3DRECT clear_rect; + UINT inst_length; + unsigned int j; + IDirect3D *d3d; + D3DVIEWPORT vp; + ULONG refcount; + HWND window; + HRESULT hr; + void *ptr; + + window = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW, + 0, 0, 640, 480, 0, 0, 0, 0); + ddraw = create_ddraw(); + ok(!!ddraw, "Failed to create a ddraw object.\n"); + if (!(device = create_device(ddraw, window, DDSCL_NORMAL))) + { + skip("Failed to create a 3D device, skipping test.\n"); + IDirectDraw_Release(ddraw); + DestroyWindow(window); + return; + } + + hr = IDirect3DDevice_QueryInterface(device, &IID_IDirectDrawSurface, (void **)&rt); + ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr); + + hr = IDirect3DDevice_GetDirect3D(device, &d3d); + ok(SUCCEEDED(hr), "Failed to get Direct3D3 interface, hr %#x.\n", hr); + + black_background = create_diffuse_material(device, 0.0f, 0.0f, 0.0f, 0.0f); + + hr = IDirect3DDevice_CreateMatrix(device, &world_handle); + ok(SUCCEEDED(hr), "Creating a matrix object failed, hr %#x.\n", hr); + hr = IDirect3DDevice_SetMatrix(device, world_handle, &mat); + ok(SUCCEEDED(hr), "Setting a matrix object failed, hr %#x.\n", hr); + hr = IDirect3DDevice_CreateMatrix(device, &view_handle); + ok(SUCCEEDED(hr), "Creating a matrix object failed, hr %#x.\n", hr); + hr = IDirect3DDevice_SetMatrix(device, view_handle, &mat); + ok(SUCCEEDED(hr), "Setting a matrix object failed, hr %#x.\n", hr); + hr = IDirect3DDevice_CreateMatrix(device, &proj_handle); + ok(SUCCEEDED(hr), "Creating a matrix object failed, hr %#x.\n", hr); + hr = IDirect3DDevice_SetMatrix(device, proj_handle, &mat); + ok(SUCCEEDED(hr), "Setting a matrix object failed, hr %#x.\n", hr); + + memset(&exec_desc, 0, sizeof(exec_desc)); + exec_desc.dwSize = sizeof(exec_desc); + exec_desc.dwFlags = D3DDEB_BUFSIZE | D3DDEB_CAPS; + exec_desc.dwBufferSize = 1024; + exec_desc.dwCaps = D3DDEBCAPS_SYSTEMMEMORY; + + hr = IDirect3DDevice_CreateExecuteBuffer(device, &exec_desc, &execute_buffer, NULL); + ok(SUCCEEDED(hr), "Failed to create execute buffer, hr %#x.\n", hr); + + hr = IDirect3DExecuteBuffer_Lock(execute_buffer, &exec_desc); + ok(SUCCEEDED(hr), "Failed to lock execute buffer, hr %#x.\n", hr); + + memcpy(exec_desc.lpData, quad, sizeof(quad)); + ptr = ((BYTE *)exec_desc.lpData) + sizeof(quad); + emit_set_ts(&ptr, D3DTRANSFORMSTATE_WORLD, world_handle); + emit_set_ts(&ptr, D3DTRANSFORMSTATE_VIEW, view_handle); + emit_set_ts(&ptr, D3DTRANSFORMSTATE_PROJECTION, proj_handle); + emit_set_rs(&ptr, D3DRENDERSTATE_ZENABLE, FALSE); + emit_set_rs(&ptr, D3DRENDERSTATE_FOGENABLE, FALSE); + emit_set_rs(&ptr, D3DRENDERSTATE_CULLMODE, D3DCULL_NONE); + emit_process_vertices(&ptr, D3DPROCESSVERTICES_TRANSFORM, 0, 4); + emit_tquad(&ptr, 0); + emit_end(&ptr); + inst_length = (BYTE *)ptr - (BYTE *)exec_desc.lpData; + inst_length -= sizeof(quad); + + hr = IDirect3DExecuteBuffer_Unlock(execute_buffer); + ok(SUCCEEDED(hr), "Failed to unlock execute buffer, hr %#x.\n", hr); + + full_viewport = create_viewport(device, 0, 0, 640, 480); + viewport_set_background(device, full_viewport, black_background); + + U1(clear_rect).x1 = U2(clear_rect).y1 = 0; + U3(clear_rect).x2 = 640; + U4(clear_rect).y2 = 480; + + for (j = 0; j < ARRAY_SIZE(tests); ++j) + { + hr = IDirect3DViewport_Clear(full_viewport, 1, &clear_rect, D3DCLEAR_TARGET); + ok(SUCCEEDED(hr), "Failed to clear viewport, hr %#x (j %u).\n", hr, j); + + hr = IDirect3D_CreateViewport(d3d, &viewport, NULL); + ok(SUCCEEDED(hr), "Failed to create viewport, hr %#x (j %u).\n", hr, j); + memset(&vp, 0, sizeof(vp)); + vp.dwSize = sizeof(vp); + vp.dwX = tests[j].vp.dwX; + vp.dwY = tests[j].vp.dwY; + vp.dwWidth = tests[j].vp.dwWidth; + vp.dwHeight = tests[j].vp.dwHeight; + vp.dvScaleX = tests[j].vp.dwWidth / 2.0f; + vp.dvScaleY = tests[j].vp.dwHeight / 2.0f; + vp.dvMaxX = 1.0f; + vp.dvMaxY = 1.0f; + vp.dvMinZ = 0.0f; + vp.dvMaxZ = 1.0f; + hr = IDirect3DViewport_SetViewport(viewport, &vp); + ok(hr == D3DERR_VIEWPORTHASNODEVICE, + "Setting viewport data returned unexpected hr %#x (j %u).\n", hr, j); + hr = IDirect3DDevice_AddViewport(device, viewport); + ok(SUCCEEDED(hr), "Failed to add viewport, hr %#x (j %u).\n", hr, j); + hr = IDirect3DViewport_SetViewport(viewport, &vp); + ok(SUCCEEDED(hr), "Failed to set viewport data, hr %#x (j %u).\n", hr, j); + + hr = IDirect3DDevice_BeginScene(device); + ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x (j %u).\n", hr, j); + + set_execute_data(execute_buffer, 4, sizeof(quad), inst_length); + hr = IDirect3DDevice_Execute(device, execute_buffer, viewport, D3DEXECUTE_CLIPPED); + ok(SUCCEEDED(hr), "Failed to execute exec buffer, hr %#x (j %u).\n", hr, j); + + hr = IDirect3DDevice_EndScene(device); + ok(SUCCEEDED(hr), "Failed to end scene, hr %#x (j %u).\n", hr, j); + + check_rect(rt, tests[j].expected_rect, tests[j].message); + + destroy_viewport(device, viewport); + } + + destroy_viewport(device, full_viewport); + IDirectDrawSurface_Release(rt); + + IDirect3DExecuteBuffer_Release(execute_buffer); + IDirect3DDevice_DeleteMatrix(device, world_handle); + IDirect3DDevice_DeleteMatrix(device, view_handle); + IDirect3DDevice_DeleteMatrix(device, proj_handle); + destroy_material(black_background); + refcount = IDirect3DDevice_Release(device); + IDirect3D2_Release(d3d); + ok(!refcount, "Device has %u references left.\n", refcount); + DestroyWindow(window); +} + START_TEST(ddraw1) { DDDEVICEIDENTIFIER identifier; @@ -11414,7 +11632,7 @@ START_TEST(ddraw1) test_coop_level_d3d_state(); test_surface_interface_mismatch(); test_coop_level_threaded(); - test_viewport(); + test_viewport_object(); test_zenable(); test_ck_rgba(); test_ck_default(); @@ -11473,4 +11691,5 @@ START_TEST(ddraw1) test_clear(); test_enum_surfaces(); test_execute_data(); + test_viewport(); }
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
Signed-off-by: Matteo Bruni mbruni@codeweavers.com --- dlls/wined3d/device.c | 2 +- dlls/wined3d/state.c | 16 ++-------------- 2 files changed, 3 insertions(+), 15 deletions(-)
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index 8d4f4cde0e0..108e291f3de 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -3147,7 +3147,7 @@ static HRESULT process_vertices_strided(const struct wined3d_device *device, DWO
/* Get the viewport */ wined3d_device_get_viewports(device, NULL, &vp); - TRACE("viewport x %.8e, y %.8e, width %.8e, height %.8e, 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 3563b4b0fdd..0d69724237b 100644 --- a/dlls/wined3d/state.c +++ b/dlls/wined3d/state.c @@ -4002,22 +4002,10 @@ static void get_viewports(struct wined3d_context *context, const struct wined3d_ unsigned int width, height, i;
for (i = 0; i < viewport_count; ++i) - { viewports[i] = state->viewports[i];
- if (target) - { - if (viewports[i].width > target->width) - viewports[i].width = target->width; - if (viewports[i].height > target->height) - viewports[i].height = target->height; - } - } - - /* - * Note: GL requires lower left, DirectX supplies upper left. This is - * reversed when using offscreen rendering. - */ + /* Note: GL uses a lower left origin while DirectX uses upper left. This + * is reversed when using offscreen rendering. */ if (context->render_offscreen) return;
On 20 April 2018 at 00:55, Matteo Bruni mbruni@codeweavers.com wrote:
dlls/wined3d/device.c | 2 +- dlls/wined3d/state.c | 16 ++-------------- 2 files changed, 3 insertions(+), 15 deletions(-)
This fails here:
../../../../../src/wine-git/tools/runtest -q -P wine -T ../../.. -M d3d9.dll -p d3d9_test.exe.so visual && touch visual.ok visual.c:10058: Tests skipped: Card has unconditional NP2 support, skipping conditional NP2 tests visual.c:13956: Test failed: viewport test: (162,122) has color 00ff0000 visual.c:13959: Test failed: viewport test: (478,358 has color 00ff0000 visual.c:14219: Tests skipped: No NVDB (depth bounds test) support, skipping tests. visual.c:17739: Tests skipped: DXT5 volume textures are not supported, skipping test. visual.c:20494: Tests skipped: Volume ATI2N textures are not supported, skipping some tests. Makefile:341: recipe for target 'visual.ok' failed