2 * Copyright (C) 2006 Vitaliy Margolen
3 * Copyright (C) 2006 Chris Robinson
4 * Copyright (C) 2006 Louis Lenders
5 * Copyright 2006-2007 Henri Verbeet
6 * Copyright 2006-2007, 2011-2013 Stefan Dösinger for CodeWeavers
7 * Copyright 2013 Henri Verbeet for CodeWeavers
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
28 #include "wine/test.h"
35 #define CREATE_DEVICE_FULLSCREEN 0x01
36 #define CREATE_DEVICE_FPU_PRESERVE 0x02
37 #define CREATE_DEVICE_SWVP_ONLY 0x04
38 #define CREATE_DEVICE_LOCKABLE_BACKBUFFER 0x08
42 unsigned int adapter_ordinal
;
49 #define GET_X_LPARAM(lp) ((int)(short)LOWORD(lp))
50 #define GET_Y_LPARAM(lp) ((int)(short)HIWORD(lp))
52 static DEVMODEW registry_mode
;
54 static HRESULT (WINAPI
*ValidateVertexShader
)(const DWORD
*, const DWORD
*, const D3DCAPS8
*, BOOL
, char **);
55 static HRESULT (WINAPI
*ValidatePixelShader
)(const DWORD
*, const D3DCAPS8
*, BOOL
, char **);
57 static const DWORD simple_vs
[] = {0xFFFE0101, /* vs_1_1 */
58 0x00000009, 0xC0010000, 0x90E40000, 0xA0E40000, /* dp4 oPos.x, v0, c0 */
59 0x00000009, 0xC0020000, 0x90E40000, 0xA0E40001, /* dp4 oPos.y, v0, c1 */
60 0x00000009, 0xC0040000, 0x90E40000, 0xA0E40002, /* dp4 oPos.z, v0, c2 */
61 0x00000009, 0xC0080000, 0x90E40000, 0xA0E40003, /* dp4 oPos.w, v0, c3 */
62 0x0000FFFF}; /* END */
63 static const DWORD simple_ps
[] = {0xFFFF0101, /* ps_1_1 */
64 0x00000051, 0xA00F0001, 0x3F800000, 0x00000000, 0x00000000, 0x00000000, /* def c1 = 1.0, 0.0, 0.0, 0.0 */
65 0x00000042, 0xB00F0000, /* tex t0 */
66 0x00000008, 0x800F0000, 0xA0E40001, 0xA0E40000, /* dp3 r0, c1, c0 */
67 0x00000005, 0x800F0000, 0x90E40000, 0x80E40000, /* mul r0, v0, r0 */
68 0x00000005, 0x800F0000, 0xB0E40000, 0x80E40000, /* mul r0, t0, r0 */
69 0x0000FFFF}; /* END */
71 static int get_refcount(IUnknown
*object
)
73 IUnknown_AddRef( object
);
74 return IUnknown_Release( object
);
77 static void get_virtual_rect(RECT
*rect
)
79 rect
->left
= GetSystemMetrics(SM_XVIRTUALSCREEN
);
80 rect
->top
= GetSystemMetrics(SM_YVIRTUALSCREEN
);
81 rect
->right
= rect
->left
+ GetSystemMetrics(SM_CXVIRTUALSCREEN
);
82 rect
->bottom
= rect
->top
+ GetSystemMetrics(SM_CYVIRTUALSCREEN
);
85 static HWND
create_window(void)
87 RECT r
= {0, 0, 640, 480};
89 AdjustWindowRect(&r
, WS_OVERLAPPEDWINDOW
| WS_VISIBLE
, FALSE
);
91 return CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
92 0, 0, r
.right
- r
.left
, r
.bottom
- r
.top
, NULL
, NULL
, NULL
, NULL
);
95 /* try to make sure pending X events have been processed before continuing */
96 static void flush_events(void)
100 int min_timeout
= 100;
101 DWORD time
= GetTickCount() + diff
;
105 if (MsgWaitForMultipleObjects( 0, NULL
, FALSE
, min_timeout
, QS_ALLINPUT
) == WAIT_TIMEOUT
) break;
106 while (PeekMessageA(&msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessageA(&msg
);
107 diff
= time
- GetTickCount();
111 static BOOL
adapter_is_warp(const D3DADAPTER_IDENTIFIER8
*identifier
)
113 return !strcmp(identifier
->Driver
, "d3d10warp.dll");
116 static BOOL
equal_mode_rect(const DEVMODEW
*mode1
, const DEVMODEW
*mode2
)
118 return mode1
->dmPosition
.x
== mode2
->dmPosition
.x
119 && mode1
->dmPosition
.y
== mode2
->dmPosition
.y
120 && mode1
->dmPelsWidth
== mode2
->dmPelsWidth
121 && mode1
->dmPelsHeight
== mode2
->dmPelsHeight
;
124 /* Free original_modes after finished using it */
125 static BOOL
save_display_modes(DEVMODEW
**original_modes
, unsigned int *display_count
)
127 unsigned int number
, size
= 2, count
= 0, index
= 0;
128 DISPLAY_DEVICEW display_device
;
129 DEVMODEW
*modes
, *tmp
;
131 if (!(modes
= malloc(size
* sizeof(*modes
))))
134 display_device
.cb
= sizeof(display_device
);
135 while (EnumDisplayDevicesW(NULL
, index
++, &display_device
, 0))
137 /* Skip software devices */
138 if (swscanf(display_device
.DeviceName
, L
"\\\\.\\DISPLAY%u", &number
) != 1)
141 if (!(display_device
.StateFlags
& DISPLAY_DEVICE_ATTACHED_TO_DESKTOP
))
147 if (!(tmp
= realloc(modes
, size
* sizeof(*modes
))))
155 memset(&modes
[count
], 0, sizeof(modes
[count
]));
156 modes
[count
].dmSize
= sizeof(modes
[count
]);
157 if (!EnumDisplaySettingsW(display_device
.DeviceName
, ENUM_CURRENT_SETTINGS
, &modes
[count
]))
163 lstrcpyW(modes
[count
++].dmDeviceName
, display_device
.DeviceName
);
166 *original_modes
= modes
;
167 *display_count
= count
;
171 static BOOL
restore_display_modes(DEVMODEW
*modes
, unsigned int count
)
176 for (index
= 0; index
< count
; ++index
)
178 ret
= ChangeDisplaySettingsExW(modes
[index
].dmDeviceName
, &modes
[index
], NULL
,
179 CDS_UPDATEREGISTRY
| CDS_NORESET
, NULL
);
180 if (ret
!= DISP_CHANGE_SUCCESSFUL
)
183 ret
= ChangeDisplaySettingsExW(NULL
, NULL
, NULL
, 0, NULL
);
184 return ret
== DISP_CHANGE_SUCCESSFUL
;
187 static IDirect3DDevice8
*create_device(IDirect3D8
*d3d8
, HWND focus_window
, const struct device_desc
*desc
)
189 D3DPRESENT_PARAMETERS present_parameters
= {0};
190 unsigned int adapter_ordinal
;
191 IDirect3DDevice8
*device
;
192 DWORD behavior_flags
= D3DCREATE_HARDWARE_VERTEXPROCESSING
;
194 adapter_ordinal
= D3DADAPTER_DEFAULT
;
195 present_parameters
.BackBufferWidth
= 640;
196 present_parameters
.BackBufferHeight
= 480;
197 present_parameters
.BackBufferFormat
= D3DFMT_A8R8G8B8
;
198 present_parameters
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
199 present_parameters
.hDeviceWindow
= focus_window
;
200 present_parameters
.Windowed
= TRUE
;
201 present_parameters
.EnableAutoDepthStencil
= TRUE
;
202 present_parameters
.AutoDepthStencilFormat
= D3DFMT_D24S8
;
206 adapter_ordinal
= desc
->adapter_ordinal
;
207 present_parameters
.BackBufferWidth
= desc
->width
;
208 present_parameters
.BackBufferHeight
= desc
->height
;
209 present_parameters
.hDeviceWindow
= desc
->device_window
;
210 present_parameters
.Windowed
= !(desc
->flags
& CREATE_DEVICE_FULLSCREEN
);
211 if (desc
->flags
& CREATE_DEVICE_LOCKABLE_BACKBUFFER
)
212 present_parameters
.Flags
|= D3DPRESENTFLAG_LOCKABLE_BACKBUFFER
;
213 if (desc
->flags
& CREATE_DEVICE_SWVP_ONLY
)
214 behavior_flags
= D3DCREATE_SOFTWARE_VERTEXPROCESSING
;
215 if (desc
->flags
& CREATE_DEVICE_FPU_PRESERVE
)
216 behavior_flags
|= D3DCREATE_FPU_PRESERVE
;
219 if (SUCCEEDED(IDirect3D8_CreateDevice(d3d8
, adapter_ordinal
, D3DDEVTYPE_HAL
, focus_window
,
220 behavior_flags
, &present_parameters
, &device
)))
223 present_parameters
.AutoDepthStencilFormat
= D3DFMT_D16
;
224 if (SUCCEEDED(IDirect3D8_CreateDevice(d3d8
, adapter_ordinal
, D3DDEVTYPE_HAL
, focus_window
,
225 behavior_flags
, &present_parameters
, &device
)))
228 if (desc
&& desc
->flags
& CREATE_DEVICE_SWVP_ONLY
)
230 behavior_flags
^= (D3DCREATE_HARDWARE_VERTEXPROCESSING
| D3DCREATE_SOFTWARE_VERTEXPROCESSING
);
232 if (SUCCEEDED(IDirect3D8_CreateDevice(d3d8
, adapter_ordinal
, D3DDEVTYPE_HAL
, focus_window
,
233 behavior_flags
, &present_parameters
, &device
)))
239 static HRESULT
reset_device(IDirect3DDevice8
*device
, const struct device_desc
*desc
)
241 D3DPRESENT_PARAMETERS present_parameters
= {0};
243 present_parameters
.BackBufferWidth
= 640;
244 present_parameters
.BackBufferHeight
= 480;
245 present_parameters
.BackBufferFormat
= D3DFMT_A8R8G8B8
;
246 present_parameters
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
247 present_parameters
.hDeviceWindow
= NULL
;
248 present_parameters
.Windowed
= TRUE
;
249 present_parameters
.EnableAutoDepthStencil
= TRUE
;
250 present_parameters
.AutoDepthStencilFormat
= D3DFMT_D24S8
;
254 present_parameters
.BackBufferWidth
= desc
->width
;
255 present_parameters
.BackBufferHeight
= desc
->height
;
256 present_parameters
.hDeviceWindow
= desc
->device_window
;
257 present_parameters
.Windowed
= !(desc
->flags
& CREATE_DEVICE_FULLSCREEN
);
260 return IDirect3DDevice8_Reset(device
, &present_parameters
);
263 #define CHECK_CALL(r,c,d,rc) \
265 int tmp1 = get_refcount( (IUnknown *)d ); \
267 ok(tmp1 == rc_new, "Invalid refcount. Expected %d got %d\n", rc_new, tmp1); \
269 trace("%s failed: %#08lx\n", c, r); \
272 #define CHECK_RELEASE(obj,d,rc) \
274 int tmp1, rc_new = rc; \
275 IUnknown_Release( (IUnknown*)obj ); \
276 tmp1 = get_refcount( (IUnknown *)d ); \
277 ok(tmp1 == rc_new, "Invalid refcount. Expected %d got %d\n", rc_new, tmp1); \
280 #define CHECK_REFCOUNT(obj,rc) \
283 int count = get_refcount( (IUnknown *)obj ); \
284 ok(count == rc_new, "Invalid refcount. Expected %d got %d\n", rc_new, count); \
287 #define CHECK_RELEASE_REFCOUNT(obj,rc) \
290 int count = IUnknown_Release( (IUnknown *)obj ); \
291 ok(count == rc_new, "Invalid refcount. Expected %d got %d\n", rc_new, count); \
294 #define CHECK_ADDREF_REFCOUNT(obj,rc) \
297 int count = IUnknown_AddRef( (IUnknown *)obj ); \
298 ok(count == rc_new, "Invalid refcount. Expected %d got %d\n", rc_new, count); \
301 #define CHECK_SURFACE_CONTAINER(obj,iid,expected) \
303 void *container_ptr = (void *)0x1337c0d3; \
304 hr = IDirect3DSurface8_GetContainer(obj, &iid, &container_ptr); \
305 ok(SUCCEEDED(hr) && container_ptr == expected, "GetContainer returned: hr %#08lx, container_ptr %p. " \
306 "Expected hr %#08lx, container_ptr %p\n", hr, container_ptr, S_OK, expected); \
307 if (container_ptr && container_ptr != (void *)0x1337c0d3) IUnknown_Release((IUnknown *)container_ptr); \
310 static void check_mipmap_levels(IDirect3DDevice8
*device
, UINT width
, UINT height
, UINT count
)
312 IDirect3DBaseTexture8
* texture
= NULL
;
313 HRESULT hr
= IDirect3DDevice8_CreateTexture( device
, width
, height
, 0, 0,
314 D3DFMT_X8R8G8B8
, D3DPOOL_DEFAULT
, (IDirect3DTexture8
**) &texture
);
317 DWORD levels
= IDirect3DBaseTexture8_GetLevelCount(texture
);
318 ok(levels
== count
, "Invalid level count. Expected %d got %lu\n", count
, levels
);
320 trace("CreateTexture failed: %#08lx\n", hr
);
322 if (texture
) IDirect3DBaseTexture8_Release( texture
);
325 static void test_mipmap_levels(void)
327 IDirect3DDevice8
*device
;
332 window
= create_window();
333 ok(!!window
, "Failed to create a window.\n");
334 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
335 ok(!!d3d
, "Failed to create a D3D object.\n");
336 if (!(device
= create_device(d3d
, window
, NULL
)))
338 skip("Failed to create a 3D device, skipping test.\n");
342 check_mipmap_levels(device
, 32, 32, 6);
343 check_mipmap_levels(device
, 256, 1, 9);
344 check_mipmap_levels(device
, 1, 256, 9);
345 check_mipmap_levels(device
, 1, 1, 1);
347 refcount
= IDirect3DDevice8_Release(device
);
348 ok(!refcount
, "Device has %lu references left.\n", refcount
);
350 IDirect3D8_Release(d3d
);
351 DestroyWindow(window
);
354 static void test_swapchain(void)
356 IDirect3DSwapChain8
*swapchain1
;
357 IDirect3DSwapChain8
*swapchain2
;
358 IDirect3DSwapChain8
*swapchain3
;
359 IDirect3DSurface8
*backbuffer
, *stereo_buffer
;
360 D3DPRESENT_PARAMETERS d3dpp
;
361 IDirect3DDevice8
*device
;
364 HWND window
, window2
;
366 struct device_desc device_desc
;
368 window
= create_window();
369 ok(!!window
, "Failed to create a window.\n");
370 window2
= create_window();
371 ok(!!window2
, "Failed to create a window.\n");
372 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
373 ok(!!d3d
, "Failed to create a D3D object.\n");
374 if (!(device
= create_device(d3d
, window
, NULL
)))
376 skip("Failed to create a 3D device, skipping test.\n");
380 backbuffer
= (void *)0xdeadbeef;
381 /* IDirect3DDevice8::GetBackBuffer crashes if a NULL output pointer is passed. */
382 hr
= IDirect3DDevice8_GetBackBuffer(device
, 1, D3DBACKBUFFER_TYPE_MONO
, &backbuffer
);
383 ok(hr
== D3DERR_INVALIDCALL
, "Got unexpected hr %#lx.\n", hr
);
384 ok(!backbuffer
, "The back buffer pointer is %p, expected NULL.\n", backbuffer
);
386 hr
= IDirect3DDevice8_GetBackBuffer(device
, 0, D3DBACKBUFFER_TYPE_MONO
, &backbuffer
);
387 ok(SUCCEEDED(hr
), "Failed to get back buffer, hr %#lx.\n", hr
);
388 IDirect3DSurface8_Release(backbuffer
);
390 /* The back buffer type value is ignored. */
391 hr
= IDirect3DDevice8_GetBackBuffer(device
, 0, D3DBACKBUFFER_TYPE_LEFT
, &stereo_buffer
);
392 ok(SUCCEEDED(hr
), "Failed to get the back buffer, hr %#lx.\n", hr
);
393 ok(stereo_buffer
== backbuffer
, "Expected left back buffer = %p, got %p.\n", backbuffer
, stereo_buffer
);
394 IDirect3DSurface8_Release(stereo_buffer
);
395 hr
= IDirect3DDevice8_GetBackBuffer(device
, 0, D3DBACKBUFFER_TYPE_RIGHT
, &stereo_buffer
);
396 ok(SUCCEEDED(hr
), "Failed to get the back buffer, hr %#lx.\n", hr
);
397 ok(stereo_buffer
== backbuffer
, "Expected right back buffer = %p, got %p.\n", backbuffer
, stereo_buffer
);
398 IDirect3DSurface8_Release(stereo_buffer
);
399 hr
= IDirect3DDevice8_GetBackBuffer(device
, 0, (D3DBACKBUFFER_TYPE
)0xdeadbeef, &stereo_buffer
);
400 ok(SUCCEEDED(hr
), "Failed to get the back buffer, hr %#lx.\n", hr
);
401 ok(stereo_buffer
== backbuffer
, "Expected unknown buffer = %p, got %p.\n", backbuffer
, stereo_buffer
);
402 IDirect3DSurface8_Release(stereo_buffer
);
404 memset(&d3dpp
, 0, sizeof(d3dpp
));
405 d3dpp
.Windowed
= TRUE
;
406 d3dpp
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
407 d3dpp
.BackBufferFormat
= D3DFMT_A8R8G8B8
;
409 /* Create a bunch of swapchains */
410 d3dpp
.BackBufferCount
= 0;
411 hr
= IDirect3DDevice8_CreateAdditionalSwapChain(device
, &d3dpp
, &swapchain1
);
412 ok(SUCCEEDED(hr
), "Got hr %#lx.\n", hr
);
413 ok(!d3dpp
.BackBufferWidth
, "Got unexpected BackBufferWidth %u.\n", d3dpp
.BackBufferWidth
);
414 ok(!d3dpp
.BackBufferHeight
, "Got unexpected BackBufferHeight %u.\n", d3dpp
.BackBufferHeight
);
415 ok(d3dpp
.BackBufferFormat
== D3DFMT_A8R8G8B8
, "Got unexpected BackBufferFormat %#x.\n", d3dpp
.BackBufferFormat
);
416 ok(d3dpp
.BackBufferCount
== 1, "Got unexpected BackBufferCount %u.\n", d3dpp
.BackBufferCount
);
417 ok(!d3dpp
.hDeviceWindow
, "Got unexpected hDeviceWindow %p.\n", d3dpp
.hDeviceWindow
);
419 d3dpp
.hDeviceWindow
= NULL
;
420 d3dpp
.BackBufferCount
= 1;
421 hr
= IDirect3DDevice8_CreateAdditionalSwapChain(device
, &d3dpp
, &swapchain2
);
422 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
424 d3dpp
.BackBufferCount
= 2;
425 hr
= IDirect3DDevice8_CreateAdditionalSwapChain(device
, &d3dpp
, &swapchain3
);
426 ok(SUCCEEDED(hr
), "Got hr %#lx.\n", hr
);
428 /* Swapchain 3, created with backbuffercount 2 */
429 hr
= IDirect3DSwapChain8_GetBackBuffer(swapchain3
, 0, 0, NULL
);
430 ok(hr
== D3DERR_INVALIDCALL
, "Got unexpected hr %#lx.\n", hr
);
432 backbuffer
= (void *) 0xdeadbeef;
433 hr
= IDirect3DSwapChain8_GetBackBuffer(swapchain3
, 0, 0, &backbuffer
);
434 ok(SUCCEEDED(hr
), "Got hr %#lx.\n", hr
);
435 ok(backbuffer
!= NULL
&& backbuffer
!= (void *) 0xdeadbeef, "The back buffer is %p\n", backbuffer
);
436 if(backbuffer
&& backbuffer
!= (void *) 0xdeadbeef) IDirect3DSurface8_Release(backbuffer
);
438 /* The back buffer type value is ignored. */
439 hr
= IDirect3DSwapChain8_GetBackBuffer(swapchain3
, 0, D3DBACKBUFFER_TYPE_LEFT
, &stereo_buffer
);
440 ok(SUCCEEDED(hr
), "Failed to get the back buffer, hr %#lx.\n", hr
);
441 ok(stereo_buffer
== backbuffer
, "Expected left back buffer = %p, got %p.\n", backbuffer
, stereo_buffer
);
442 IDirect3DSurface8_Release(stereo_buffer
);
443 hr
= IDirect3DSwapChain8_GetBackBuffer(swapchain3
, 0, D3DBACKBUFFER_TYPE_RIGHT
, &stereo_buffer
);
444 ok(SUCCEEDED(hr
), "Failed to get the back buffer, hr %#lx.\n", hr
);
445 ok(stereo_buffer
== backbuffer
, "Expected right back buffer = %p, got %p.\n", backbuffer
, stereo_buffer
);
446 IDirect3DSurface8_Release(stereo_buffer
);
447 hr
= IDirect3DSwapChain8_GetBackBuffer(swapchain3
, 0, (D3DBACKBUFFER_TYPE
)0xdeadbeef, &stereo_buffer
);
448 ok(SUCCEEDED(hr
), "Failed to get the back buffer, hr %#lx.\n", hr
);
449 ok(stereo_buffer
== backbuffer
, "Expected unknown buffer = %p, got %p.\n", backbuffer
, stereo_buffer
);
450 IDirect3DSurface8_Release(stereo_buffer
);
452 backbuffer
= (void *) 0xdeadbeef;
453 hr
= IDirect3DSwapChain8_GetBackBuffer(swapchain3
, 1, 0, &backbuffer
);
454 ok(SUCCEEDED(hr
), "Got hr %#lx.\n", hr
);
455 ok(backbuffer
!= NULL
&& backbuffer
!= (void *) 0xdeadbeef, "The back buffer is %p\n", backbuffer
);
456 if(backbuffer
&& backbuffer
!= (void *) 0xdeadbeef) IDirect3DSurface8_Release(backbuffer
);
458 backbuffer
= (void *) 0xdeadbeef;
459 hr
= IDirect3DSwapChain8_GetBackBuffer(swapchain3
, 2, 0, &backbuffer
);
460 ok(hr
== D3DERR_INVALIDCALL
, "Got hr %#lx.\n", hr
);
461 ok(backbuffer
== (void *) 0xdeadbeef, "The back buffer pointer was modified (%p)\n", backbuffer
);
462 if(backbuffer
&& backbuffer
!= (void *) 0xdeadbeef) IDirect3DSurface8_Release(backbuffer
);
464 backbuffer
= (void *) 0xdeadbeef;
465 hr
= IDirect3DSwapChain8_GetBackBuffer(swapchain3
, 3, 0, &backbuffer
);
466 ok(FAILED(hr
), "Got hr %#lx.\n", hr
);
467 ok(backbuffer
== (void *) 0xdeadbeef, "The back buffer pointer was modified (%p)\n", backbuffer
);
468 if(backbuffer
&& backbuffer
!= (void *) 0xdeadbeef) IDirect3DSurface8_Release(backbuffer
);
471 /* Check the back buffers of the swapchains */
472 /* Swapchain 1, created with backbuffercount 0 */
473 hr
= IDirect3DSwapChain8_GetBackBuffer(swapchain1
, 0, D3DBACKBUFFER_TYPE_MONO
, &backbuffer
);
474 ok(SUCCEEDED(hr
), "Got hr %#lx.\n", hr
);
475 ok(!!backbuffer
, "Expected a non-NULL backbuffer.\n");
476 if(backbuffer
) IDirect3DSurface8_Release(backbuffer
);
478 backbuffer
= (void *) 0xdeadbeef;
479 hr
= IDirect3DSwapChain8_GetBackBuffer(swapchain1
, 1, 0, &backbuffer
);
480 ok(FAILED(hr
), "Got hr %#lx.\n", hr
);
481 ok(backbuffer
== (void *) 0xdeadbeef, "The back buffer pointer was modified (%p)\n", backbuffer
);
482 if(backbuffer
&& backbuffer
!= (void *) 0xdeadbeef) IDirect3DSurface8_Release(backbuffer
);
484 /* Swapchain 2 - created with backbuffercount 1 */
485 backbuffer
= (void *) 0xdeadbeef;
486 hr
= IDirect3DSwapChain8_GetBackBuffer(swapchain2
, 0, 0, &backbuffer
);
487 ok(SUCCEEDED(hr
), "Got hr %#lx.\n", hr
);
488 ok(backbuffer
!= NULL
&& backbuffer
!= (void *) 0xdeadbeef, "The back buffer is %p\n", backbuffer
);
489 if(backbuffer
&& backbuffer
!= (void *) 0xdeadbeef) IDirect3DSurface8_Release(backbuffer
);
491 backbuffer
= (void *) 0xdeadbeef;
492 hr
= IDirect3DSwapChain8_GetBackBuffer(swapchain2
, 1, 0, &backbuffer
);
493 ok(hr
== D3DERR_INVALIDCALL
, "Got hr %#lx.\n", hr
);
494 ok(backbuffer
== (void *) 0xdeadbeef, "The back buffer pointer was modified (%p)\n", backbuffer
);
495 if(backbuffer
&& backbuffer
!= (void *) 0xdeadbeef) IDirect3DSurface8_Release(backbuffer
);
497 backbuffer
= (void *) 0xdeadbeef;
498 hr
= IDirect3DSwapChain8_GetBackBuffer(swapchain2
, 2, 0, &backbuffer
);
499 ok(FAILED(hr
), "Got hr %#lx.\n", hr
);
500 ok(backbuffer
== (void *) 0xdeadbeef, "The back buffer pointer was modified (%p)\n", backbuffer
);
501 if(backbuffer
&& backbuffer
!= (void *) 0xdeadbeef) IDirect3DSurface8_Release(backbuffer
);
503 IDirect3DSwapChain8_Release(swapchain3
);
504 IDirect3DSwapChain8_Release(swapchain2
);
505 IDirect3DSwapChain8_Release(swapchain1
);
507 d3dpp
.Windowed
= FALSE
;
508 d3dpp
.hDeviceWindow
= window
;
509 d3dpp
.BackBufferCount
= 1;
510 hr
= IDirect3DDevice8_CreateAdditionalSwapChain(device
, &d3dpp
, &swapchain1
);
511 ok(hr
== D3DERR_INVALIDCALL
, "Got unexpected hr %#lx\n", hr
);
512 d3dpp
.hDeviceWindow
= window2
;
513 hr
= IDirect3DDevice8_CreateAdditionalSwapChain(device
, &d3dpp
, &swapchain1
);
514 ok(hr
== D3DERR_INVALIDCALL
, "Got unexpected hr %#lx\n", hr
);
516 device_desc
.width
= registry_mode
.dmPelsWidth
;
517 device_desc
.height
= registry_mode
.dmPelsHeight
;
518 device_desc
.device_window
= window
;
519 device_desc
.flags
= CREATE_DEVICE_FULLSCREEN
;
520 hr
= reset_device(device
, &device_desc
);
521 ok(SUCCEEDED(hr
), "Failed to reset device, hr %#lx.\n", hr
);
523 d3dpp
.hDeviceWindow
= window
;
524 hr
= IDirect3DDevice8_CreateAdditionalSwapChain(device
, &d3dpp
, &swapchain1
);
525 ok(hr
== D3DERR_INVALIDCALL
, "Got unexpected hr %#lx\n", hr
);
526 d3dpp
.hDeviceWindow
= window2
;
527 hr
= IDirect3DDevice8_CreateAdditionalSwapChain(device
, &d3dpp
, &swapchain1
);
528 ok(hr
== D3DERR_INVALIDCALL
, "Got unexpected hr %#lx\n", hr
);
529 d3dpp
.Windowed
= TRUE
;
530 d3dpp
.hDeviceWindow
= window
;
531 hr
= IDirect3DDevice8_CreateAdditionalSwapChain(device
, &d3dpp
, &swapchain1
);
532 ok(hr
== D3DERR_INVALIDCALL
, "Got unexpected hr %#lx\n", hr
);
533 d3dpp
.hDeviceWindow
= window2
;
534 hr
= IDirect3DDevice8_CreateAdditionalSwapChain(device
, &d3dpp
, &swapchain1
);
535 ok(hr
== D3DERR_INVALIDCALL
, "Got unexpected hr %#lx\n", hr
);
537 refcount
= IDirect3DDevice8_Release(device
);
538 ok(!refcount
, "Device has %lu references left.\n", refcount
);
540 IDirect3D8_Release(d3d
);
541 DestroyWindow(window2
);
542 DestroyWindow(window
);
545 static void test_refcount(void)
547 IDirect3DVertexBuffer8
*pVertexBuffer
= NULL
;
548 IDirect3DIndexBuffer8
*pIndexBuffer
= NULL
;
549 DWORD dVertexShader
= -1;
550 DWORD dPixelShader
= -1;
551 IDirect3DCubeTexture8
*pCubeTexture
= NULL
;
552 IDirect3DTexture8
*pTexture
= NULL
;
553 IDirect3DVolumeTexture8
*pVolumeTexture
= NULL
;
554 IDirect3DVolume8
*pVolumeLevel
= NULL
;
555 IDirect3DSurface8
*pStencilSurface
= NULL
;
556 IDirect3DSurface8
*pImageSurface
= NULL
;
557 IDirect3DSurface8
*pRenderTarget
= NULL
;
558 IDirect3DSurface8
*pRenderTarget2
= NULL
;
559 IDirect3DSurface8
*pRenderTarget3
= NULL
;
560 IDirect3DSurface8
*pTextureLevel
= NULL
;
561 IDirect3DSurface8
*pBackBuffer
= NULL
;
562 DWORD dStateBlock
= -1;
563 IDirect3DSwapChain8
*pSwapChain
= NULL
;
565 D3DPRESENT_PARAMETERS d3dpp
;
566 IDirect3DDevice8
*device
= NULL
;
567 ULONG refcount
= 0, tmp
;
568 IDirect3D8
*d3d
, *d3d2
;
575 D3DVSD_REG(D3DVSDE_POSITION
, D3DVSDT_FLOAT3
), /* D3DVSDE_POSITION, Register v0 */
576 D3DVSD_REG(D3DVSDE_DIFFUSE
, D3DVSDT_D3DCOLOR
), /* D3DVSDE_DIFFUSE, Register v5 */
580 window
= create_window();
581 ok(!!window
, "Failed to create a window.\n");
582 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
583 ok(!!d3d
, "Failed to create a D3D object.\n");
585 CHECK_REFCOUNT(d3d
, 1);
587 if (!(device
= create_device(d3d
, window
, NULL
)))
589 skip("Failed to create a 3D device, skipping test.\n");
593 IDirect3DDevice8_GetDeviceCaps(device
, &caps
);
595 refcount
= get_refcount((IUnknown
*)device
);
596 ok(refcount
== 1, "Got unexpected refcount %lu.\n", refcount
);
598 CHECK_REFCOUNT(d3d
, 2);
600 hr
= IDirect3DDevice8_GetDirect3D(device
, &d3d2
);
601 CHECK_CALL(hr
, "GetDirect3D", device
, refcount
);
603 ok(d3d2
== d3d
, "Expected IDirect3D8 pointers to be equal.\n");
604 CHECK_REFCOUNT(d3d
, 3);
605 CHECK_RELEASE_REFCOUNT(d3d
, 2);
608 * Check refcount of implicit surfaces. Findings:
609 * - the container is the device
610 * - they hold a reference to the device
611 * - they are created with a refcount of 0 (Get/Release returns original refcount)
612 * - they are not freed if refcount reaches 0.
613 * - the refcount is not forwarded to the container.
615 hr
= IDirect3DDevice8_GetRenderTarget(device
, &pRenderTarget
);
616 CHECK_CALL(hr
, "GetRenderTarget", device
, ++refcount
);
619 CHECK_SURFACE_CONTAINER(pRenderTarget
, IID_IDirect3DDevice8
, device
);
620 CHECK_REFCOUNT(pRenderTarget
, 1);
622 CHECK_ADDREF_REFCOUNT(pRenderTarget
, 2);
623 CHECK_REFCOUNT(device
, refcount
);
624 CHECK_RELEASE_REFCOUNT(pRenderTarget
, 1);
625 CHECK_REFCOUNT(device
, refcount
);
627 hr
= IDirect3DDevice8_GetRenderTarget(device
, &pRenderTarget
);
628 CHECK_CALL(hr
, "GetRenderTarget", device
, refcount
);
629 CHECK_REFCOUNT(pRenderTarget
, 2);
630 CHECK_RELEASE_REFCOUNT( pRenderTarget
, 1);
631 CHECK_RELEASE_REFCOUNT( pRenderTarget
, 0);
632 CHECK_REFCOUNT(device
, --refcount
);
634 /* The render target is released with the device, so AddRef with refcount=0 is fine here. */
635 CHECK_ADDREF_REFCOUNT(pRenderTarget
, 1);
636 CHECK_REFCOUNT(device
, ++refcount
);
637 CHECK_RELEASE_REFCOUNT(pRenderTarget
, 0);
638 CHECK_REFCOUNT(device
, --refcount
);
639 CHECK_RELEASE_REFCOUNT(pRenderTarget
, 0);
640 CHECK_RELEASE_REFCOUNT(pRenderTarget
, 0);
643 /* Render target and back buffer are identical. */
644 hr
= IDirect3DDevice8_GetBackBuffer(device
, 0, 0, &pBackBuffer
);
645 CHECK_CALL(hr
, "GetBackBuffer", device
, ++refcount
);
648 CHECK_RELEASE_REFCOUNT(pBackBuffer
, 0);
649 ok(pRenderTarget
== pBackBuffer
, "RenderTarget=%p and BackBuffer=%p should be the same.\n",
650 pRenderTarget
, pBackBuffer
);
651 CHECK_RELEASE_REFCOUNT(pBackBuffer
, 0);
652 CHECK_RELEASE_REFCOUNT(pBackBuffer
, 0);
655 CHECK_REFCOUNT(device
, --refcount
);
657 hr
= IDirect3DDevice8_GetDepthStencilSurface(device
, &pStencilSurface
);
658 CHECK_CALL(hr
, "GetDepthStencilSurface", device
, ++refcount
);
661 CHECK_SURFACE_CONTAINER(pStencilSurface
, IID_IDirect3DDevice8
, device
);
662 CHECK_REFCOUNT(pStencilSurface
, 1);
664 CHECK_ADDREF_REFCOUNT(pStencilSurface
, 2);
665 CHECK_REFCOUNT(device
, refcount
);
666 CHECK_RELEASE_REFCOUNT(pStencilSurface
, 1);
667 CHECK_REFCOUNT(device
, refcount
);
669 CHECK_RELEASE_REFCOUNT( pStencilSurface
, 0);
670 CHECK_REFCOUNT(device
, --refcount
);
672 /* The stencil surface is released with the device, so AddRef with refcount=0 is fine here. */
673 CHECK_ADDREF_REFCOUNT(pStencilSurface
, 1);
674 CHECK_REFCOUNT(device
, ++refcount
);
675 CHECK_RELEASE_REFCOUNT(pStencilSurface
, 0);
676 CHECK_REFCOUNT(device
, --refcount
);
677 CHECK_RELEASE_REFCOUNT(pStencilSurface
, 0);
678 CHECK_RELEASE_REFCOUNT(pStencilSurface
, 0);
679 pStencilSurface
= NULL
;
683 hr
= IDirect3DDevice8_CreateIndexBuffer(device
, 16, 0, D3DFMT_INDEX32
, D3DPOOL_DEFAULT
, &pIndexBuffer
);
684 CHECK_CALL(hr
, "CreateIndexBuffer", device
, ++refcount
);
687 tmp
= get_refcount( (IUnknown
*)pIndexBuffer
);
689 hr
= IDirect3DDevice8_SetIndices(device
, pIndexBuffer
, 0);
690 CHECK_CALL( hr
, "SetIndices", pIndexBuffer
, tmp
);
691 hr
= IDirect3DDevice8_SetIndices(device
, NULL
, 0);
692 CHECK_CALL( hr
, "SetIndices", pIndexBuffer
, tmp
);
695 hr
= IDirect3DDevice8_CreateVertexBuffer(device
, 16, 0, D3DFVF_XYZ
, D3DPOOL_DEFAULT
, &pVertexBuffer
);
696 CHECK_CALL(hr
, "CreateVertexBuffer", device
, ++refcount
);
699 IDirect3DVertexBuffer8
*pVBuf
= (void*)~0;
702 tmp
= get_refcount( (IUnknown
*)pVertexBuffer
);
704 hr
= IDirect3DDevice8_SetStreamSource(device
, 0, pVertexBuffer
, 3 * sizeof(float));
705 CHECK_CALL( hr
, "SetStreamSource", pVertexBuffer
, tmp
);
706 hr
= IDirect3DDevice8_SetStreamSource(device
, 0, NULL
, 0);
707 CHECK_CALL( hr
, "SetStreamSource", pVertexBuffer
, tmp
);
709 hr
= IDirect3DDevice8_GetStreamSource(device
, 0, &pVBuf
, &stride
);
710 ok(SUCCEEDED(hr
), "GetStreamSource did not succeed with NULL stream!\n");
711 ok(pVBuf
==NULL
, "pVBuf not NULL (%p)!\n", pVBuf
);
712 ok(stride
==3*sizeof(float), "stride not 3 floats (got %u)!\n", stride
);
716 hr
= IDirect3DDevice8_CreateVertexShader(device
, decl
, simple_vs
, &dVertexShader
, 0);
717 CHECK_CALL(hr
, "CreateVertexShader", device
, refcount
);
718 if (caps
.PixelShaderVersion
>= D3DPS_VERSION(1, 0))
720 hr
= IDirect3DDevice8_CreatePixelShader(device
, simple_ps
, &dPixelShader
);
721 CHECK_CALL(hr
, "CreatePixelShader", device
, refcount
);
724 hr
= IDirect3DDevice8_CreateTexture(device
, 32, 32, 3, 0, D3DFMT_X8R8G8B8
, D3DPOOL_DEFAULT
, &pTexture
);
725 CHECK_CALL(hr
, "CreateTexture", device
, ++refcount
);
728 tmp
= get_refcount( (IUnknown
*)pTexture
);
730 /* SetTexture should not increase refcounts */
731 hr
= IDirect3DDevice8_SetTexture(device
, 0, (IDirect3DBaseTexture8
*) pTexture
);
732 CHECK_CALL( hr
, "SetTexture", pTexture
, tmp
);
733 hr
= IDirect3DDevice8_SetTexture(device
, 0, NULL
);
734 CHECK_CALL( hr
, "SetTexture", pTexture
, tmp
);
736 /* This should not increment device refcount */
737 hr
= IDirect3DTexture8_GetSurfaceLevel( pTexture
, 1, &pTextureLevel
);
738 CHECK_CALL(hr
, "GetSurfaceLevel", device
, refcount
);
739 /* But should increment texture's refcount */
740 CHECK_REFCOUNT( pTexture
, tmp
+1 );
741 /* Because the texture and surface refcount are identical */
744 CHECK_REFCOUNT ( pTextureLevel
, tmp
+1 );
745 CHECK_ADDREF_REFCOUNT ( pTextureLevel
, tmp
+2 );
746 CHECK_REFCOUNT ( pTexture
, tmp
+2 );
747 CHECK_RELEASE_REFCOUNT( pTextureLevel
, tmp
+1 );
748 CHECK_REFCOUNT ( pTexture
, tmp
+1 );
749 CHECK_RELEASE_REFCOUNT( pTexture
, tmp
);
750 CHECK_REFCOUNT ( pTextureLevel
, tmp
);
753 if(caps
.TextureCaps
& D3DPTEXTURECAPS_CUBEMAP
)
755 hr
= IDirect3DDevice8_CreateCubeTexture(device
, 32, 0, 0, D3DFMT_X8R8G8B8
, D3DPOOL_DEFAULT
, &pCubeTexture
);
756 CHECK_CALL(hr
, "CreateCubeTexture", device
, ++refcount
);
760 skip("Cube textures not supported\n");
762 if(caps
.TextureCaps
& D3DPTEXTURECAPS_VOLUMEMAP
)
764 hr
= IDirect3DDevice8_CreateVolumeTexture(device
, 32, 32, 2, 0, 0,
765 D3DFMT_X8R8G8B8
, D3DPOOL_DEFAULT
, &pVolumeTexture
);
766 CHECK_CALL(hr
, "CreateVolumeTexture", device
, ++refcount
);
770 skip("Volume textures not supported\n");
775 tmp
= get_refcount( (IUnknown
*)pVolumeTexture
);
777 /* This should not increment device refcount */
778 hr
= IDirect3DVolumeTexture8_GetVolumeLevel(pVolumeTexture
, 0, &pVolumeLevel
);
779 CHECK_CALL(hr
, "GetVolumeLevel", device
, refcount
);
780 /* But should increment volume texture's refcount */
781 CHECK_REFCOUNT( pVolumeTexture
, tmp
+1 );
782 /* Because the volume texture and volume refcount are identical */
785 CHECK_REFCOUNT ( pVolumeLevel
, tmp
+1 );
786 CHECK_ADDREF_REFCOUNT ( pVolumeLevel
, tmp
+2 );
787 CHECK_REFCOUNT ( pVolumeTexture
, tmp
+2 );
788 CHECK_RELEASE_REFCOUNT( pVolumeLevel
, tmp
+1 );
789 CHECK_REFCOUNT ( pVolumeTexture
, tmp
+1 );
790 CHECK_RELEASE_REFCOUNT( pVolumeTexture
, tmp
);
791 CHECK_REFCOUNT ( pVolumeLevel
, tmp
);
795 hr
= IDirect3DDevice8_CreateDepthStencilSurface(device
, 32, 32,
796 D3DFMT_D16
, D3DMULTISAMPLE_NONE
, &pStencilSurface
);
797 CHECK_CALL(hr
, "CreateDepthStencilSurface", device
, ++refcount
);
798 CHECK_REFCOUNT( pStencilSurface
, 1);
799 hr
= IDirect3DDevice8_CreateImageSurface(device
, 32, 32,
800 D3DFMT_X8R8G8B8
, &pImageSurface
);
801 CHECK_CALL(hr
, "CreateImageSurface", device
, ++refcount
);
802 CHECK_REFCOUNT( pImageSurface
, 1);
803 hr
= IDirect3DDevice8_CreateRenderTarget(device
, 32, 32,
804 D3DFMT_X8R8G8B8
, D3DMULTISAMPLE_NONE
, TRUE
, &pRenderTarget3
);
805 CHECK_CALL(hr
, "CreateRenderTarget", device
, ++refcount
);
806 CHECK_REFCOUNT( pRenderTarget3
, 1);
808 hr
= IDirect3DDevice8_CreateStateBlock(device
, D3DSBT_ALL
, &dStateBlock
);
809 CHECK_CALL(hr
, "CreateStateBlock", device
, refcount
);
811 memset(&d3dpp
, 0, sizeof(d3dpp
));
812 d3dpp
.Windowed
= TRUE
;
813 d3dpp
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
814 d3dpp
.BackBufferFormat
= D3DFMT_A8R8G8B8
;
815 d3dpp
.EnableAutoDepthStencil
= TRUE
;
816 d3dpp
.AutoDepthStencilFormat
= D3DFMT_D16
;
817 hr
= IDirect3DDevice8_CreateAdditionalSwapChain(device
, &d3dpp
, &pSwapChain
);
818 CHECK_CALL(hr
, "CreateAdditionalSwapChain", device
, ++refcount
);
821 /* check implicit back buffer */
822 hr
= IDirect3DSwapChain8_GetBackBuffer(pSwapChain
, 0, 0, &pBackBuffer
);
823 CHECK_CALL(hr
, "GetBackBuffer", device
, ++refcount
);
824 CHECK_REFCOUNT( pSwapChain
, 1);
827 CHECK_SURFACE_CONTAINER(pBackBuffer
, IID_IDirect3DDevice8
, device
);
828 CHECK_REFCOUNT( pBackBuffer
, 1);
829 CHECK_RELEASE_REFCOUNT( pBackBuffer
, 0);
830 CHECK_REFCOUNT(device
, --refcount
);
832 /* The back buffer is released with the swapchain, so AddRef with refcount=0 is fine here. */
833 CHECK_ADDREF_REFCOUNT(pBackBuffer
, 1);
834 CHECK_REFCOUNT(device
, ++refcount
);
835 CHECK_RELEASE_REFCOUNT(pBackBuffer
, 0);
836 CHECK_REFCOUNT(device
, --refcount
);
837 CHECK_RELEASE_REFCOUNT(pBackBuffer
, 0);
838 CHECK_RELEASE_REFCOUNT(pBackBuffer
, 0);
841 CHECK_REFCOUNT( pSwapChain
, 1);
847 /* Vertex buffers can be locked multiple times */
848 hr
= IDirect3DVertexBuffer8_Lock(pVertexBuffer
, 0, 0, &data
, 0);
849 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
850 hr
= IDirect3DVertexBuffer8_Lock(pVertexBuffer
, 0, 0, &data
, 0);
851 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
852 hr
= IDirect3DVertexBuffer8_Unlock(pVertexBuffer
);
853 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
854 hr
= IDirect3DVertexBuffer8_Unlock(pVertexBuffer
);
855 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
858 /* The implicit render target is not freed if refcount reaches 0.
859 * Otherwise GetRenderTarget would re-allocate it and the pointer would change.*/
860 hr
= IDirect3DDevice8_GetRenderTarget(device
, &pRenderTarget2
);
861 CHECK_CALL(hr
, "GetRenderTarget", device
, ++refcount
);
864 CHECK_RELEASE_REFCOUNT(pRenderTarget2
, 0);
865 ok(pRenderTarget
== pRenderTarget2
, "RenderTarget=%p and RenderTarget2=%p should be the same.\n",
866 pRenderTarget
, pRenderTarget2
);
867 CHECK_REFCOUNT(device
, --refcount
);
868 CHECK_RELEASE_REFCOUNT(pRenderTarget2
, 0);
869 CHECK_RELEASE_REFCOUNT(pRenderTarget2
, 0);
870 pRenderTarget2
= NULL
;
872 pRenderTarget
= NULL
;
875 CHECK_RELEASE(device
, device
, --refcount
);
878 CHECK_RELEASE(pVertexBuffer
, device
, --refcount
);
879 CHECK_RELEASE(pIndexBuffer
, device
, --refcount
);
881 if (dVertexShader
!= ~0u)
882 IDirect3DDevice8_DeleteVertexShader(device
, dVertexShader
);
883 if (dPixelShader
!= ~0u)
884 IDirect3DDevice8_DeletePixelShader(device
, dPixelShader
);
886 CHECK_RELEASE(pTexture
, device
, --refcount
);
887 CHECK_RELEASE(pCubeTexture
, device
, --refcount
);
888 CHECK_RELEASE(pVolumeTexture
, device
, --refcount
);
890 CHECK_RELEASE(pStencilSurface
, device
, --refcount
);
891 CHECK_RELEASE(pImageSurface
, device
, --refcount
);
892 CHECK_RELEASE(pRenderTarget3
, device
, --refcount
);
894 if (dStateBlock
!= ~0u)
895 IDirect3DDevice8_DeleteStateBlock(device
, dStateBlock
);
896 /* This will destroy device - cannot check the refcount here */
898 CHECK_RELEASE_REFCOUNT(pSwapChain
, 0);
899 CHECK_RELEASE_REFCOUNT(d3d
, 0);
900 DestroyWindow(window
);
903 static void test_checkdevicemultisampletype(void)
909 window
= create_window();
910 ok(!!window
, "Failed to create a window.\n");
911 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
912 ok(!!d3d
, "Failed to create a D3D object.\n");
914 if (IDirect3D8_CheckDeviceMultiSampleType(d3d
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
,
915 D3DFMT_X8R8G8B8
, TRUE
, D3DMULTISAMPLE_2_SAMPLES
) == D3DERR_NOTAVAILABLE
)
917 skip("Multisampling not supported for D3DFMT_X8R8G8B8, skipping test.\n");
921 hr
= IDirect3D8_CheckDeviceMultiSampleType(d3d
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
,
922 D3DFMT_UNKNOWN
, TRUE
, D3DMULTISAMPLE_NONE
);
923 ok(hr
== D3DERR_INVALIDCALL
, "Got unexpected hr %#lx.\n", hr
);
924 hr
= IDirect3D8_CheckDeviceMultiSampleType(d3d
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
,
925 65536, TRUE
, D3DMULTISAMPLE_NONE
);
926 todo_wine
ok(SUCCEEDED(hr
), "Got unexpected hr %#lx.\n", hr
);
928 hr
= IDirect3D8_CheckDeviceMultiSampleType(d3d
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
,
929 D3DFMT_X8R8G8B8
, TRUE
, D3DMULTISAMPLE_NONE
);
930 ok(SUCCEEDED(hr
), "Got unexpected hr %#lx.\n", hr
);
931 hr
= IDirect3D8_CheckDeviceMultiSampleType(d3d
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
,
932 D3DFMT_X8R8G8B8
, FALSE
, D3DMULTISAMPLE_NONE
);
933 ok(SUCCEEDED(hr
), "Got unexpected hr %#lx.\n", hr
);
935 hr
= IDirect3D8_CheckDeviceMultiSampleType(d3d
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
,
936 D3DFMT_X8R8G8B8
, TRUE
, D3DMULTISAMPLE_2_SAMPLES
);
937 ok(SUCCEEDED(hr
), "Got unexpected hr %#lx.\n", hr
);
939 /* We assume D3DMULTISAMPLE_15_SAMPLES is never supported in practice. */
940 hr
= IDirect3D8_CheckDeviceMultiSampleType(d3d
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
,
941 D3DFMT_X8R8G8B8
, TRUE
, D3DMULTISAMPLE_15_SAMPLES
);
942 ok(hr
== D3DERR_NOTAVAILABLE
, "Got unexpected hr %#lx.\n", hr
);
944 hr
= IDirect3D8_CheckDeviceMultiSampleType(d3d
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
,
945 D3DFMT_X8R8G8B8
, TRUE
, 65536);
946 ok(hr
== D3DERR_INVALIDCALL
, "Got unexpected hr %#lx.\n", hr
);
948 hr
= IDirect3D8_CheckDeviceMultiSampleType(d3d
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
,
949 D3DFMT_DXT5
, TRUE
, D3DMULTISAMPLE_2_SAMPLES
);
950 ok(hr
== D3DERR_NOTAVAILABLE
, "Got unexpected hr %#lx.\n", hr
);
953 IDirect3D8_Release(d3d
);
954 DestroyWindow(window
);
957 static void test_invalid_multisample(void)
959 IDirect3DDevice8
*device
;
960 IDirect3DSurface8
*rt
;
967 window
= create_window();
968 ok(!!window
, "Failed to create a window.\n");
969 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
970 ok(!!d3d
, "Failed to create a D3D object.\n");
972 if (!(device
= create_device(d3d
, window
, NULL
)))
974 skip("Failed to create a 3D device, skipping test.\n");
978 available
= SUCCEEDED(IDirect3D8_CheckDeviceMultiSampleType(d3d
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
,
979 D3DFMT_X8R8G8B8
, TRUE
, D3DMULTISAMPLE_2_SAMPLES
));
981 hr
= IDirect3DDevice8_CreateRenderTarget(device
, 128, 128,
982 D3DFMT_X8R8G8B8
, D3DMULTISAMPLE_2_SAMPLES
, FALSE
, &rt
);
985 ok(SUCCEEDED(hr
), "Got unexpected hr %#lx.\n", hr
);
986 IDirect3DSurface8_Release(rt
);
990 ok(hr
== D3DERR_NOTAVAILABLE
, "Got unexpected hr %#lx.\n", hr
);
993 /* We assume D3DMULTISAMPLE_15_SAMPLES is never supported in practice. */
994 available
= SUCCEEDED(IDirect3D8_CheckDeviceMultiSampleType(d3d
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
,
995 D3DFMT_X8R8G8B8
, TRUE
, D3DMULTISAMPLE_15_SAMPLES
));
996 hr
= IDirect3DDevice8_CreateRenderTarget(device
, 128, 128,
997 D3DFMT_X8R8G8B8
, D3DMULTISAMPLE_15_SAMPLES
, FALSE
, &rt
);
1000 ok(SUCCEEDED(hr
), "Got unexpected hr %#lx.\n", hr
);
1001 IDirect3DSurface8_Release(rt
);
1005 ok(hr
== D3DERR_NOTAVAILABLE
, "Got unexpected hr %#lx.\n", hr
);
1008 refcount
= IDirect3DDevice8_Release(device
);
1009 ok(!refcount
, "Device has %lu references left.\n", refcount
);
1011 IDirect3D8_Release(d3d
);
1012 DestroyWindow(window
);
1015 static void test_cursor(void)
1017 unsigned int adapter_idx
, adapter_count
, test_idx
;
1018 IDirect3DSurface8
*cursor
= NULL
;
1019 struct device_desc device_desc
;
1020 unsigned int width
, height
;
1021 IDirect3DDevice8
*device
;
1022 HRESULT expected_hr
, hr
;
1023 D3DDISPLAYMODE mode
;
1031 static const DWORD device_flags
[] = {0, CREATE_DEVICE_FULLSCREEN
};
1032 static const SIZE cursor_sizes
[] =
1041 window
= create_window();
1042 ok(!!window
, "Failed to create a window.\n");
1044 ret
= SetCursorPos(50, 50);
1045 ok(ret
, "Failed to set cursor position.\n");
1048 memset(&info
, 0, sizeof(info
));
1049 info
.cbSize
= sizeof(info
);
1050 ok(GetCursorInfo(&info
), "GetCursorInfo failed\n");
1053 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
1054 ok(!!d3d
, "Failed to create a D3D object.\n");
1055 if (!(device
= create_device(d3d
, window
, NULL
)))
1057 skip("Failed to create a 3D device, skipping test.\n");
1061 hr
= IDirect3DDevice8_CreateImageSurface(device
, 32, 32, D3DFMT_A8R8G8B8
, &cursor
);
1062 ok(SUCCEEDED(hr
), "Failed to create cursor surface, hr %#lx.\n", hr
);
1064 /* Initially hidden */
1065 ret
= IDirect3DDevice8_ShowCursor(device
, TRUE
);
1066 ok(!ret
, "IDirect3DDevice8_ShowCursor returned %d\n", ret
);
1068 /* Not enabled without a surface*/
1069 ret
= IDirect3DDevice8_ShowCursor(device
, TRUE
);
1070 ok(!ret
, "IDirect3DDevice8_ShowCursor returned %d\n", ret
);
1073 hr
= IDirect3DDevice8_SetCursorProperties(device
, 0, 0, NULL
);
1074 ok(hr
== D3DERR_INVALIDCALL
, "Got hr %#lx.\n", hr
);
1076 hr
= IDirect3DDevice8_SetCursorProperties(device
, 0, 0, cursor
);
1077 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
1079 IDirect3DSurface8_Release(cursor
);
1081 /* On the testbot the cursor handle does not behave as expected in rare situations,
1082 * leading to random test failures. Either the cursor handle changes before we expect
1083 * it to, or it doesn't change afterwards (or already changed before we read the
1084 * initial handle?). I was not able to reproduce this on my own machines. Moving the
1085 * mouse outside the window results in similar behavior. However, I tested various
1086 * obvious failure causes: Was the mouse moved? Was the window hidden or moved? Is
1087 * the window in the background? Neither of those applies. Making the window topmost
1088 * or using a fullscreen device doesn't improve the test's reliability either. */
1089 memset(&info
, 0, sizeof(info
));
1090 info
.cbSize
= sizeof(info
);
1091 ok(GetCursorInfo(&info
), "GetCursorInfo failed\n");
1092 ok(info
.flags
& (CURSOR_SHOWING
| CURSOR_SUPPRESSED
), "Got cursor flags %#lx.\n", info
.flags
);
1093 ok(info
.hCursor
== cur
|| broken(1), "The cursor handle is %p\n", info
.hCursor
); /* unchanged */
1096 ret
= IDirect3DDevice8_ShowCursor(device
, TRUE
);
1097 ok(!ret
, "IDirect3DDevice8_ShowCursor returned %d\n", ret
);
1100 ret
= IDirect3DDevice8_ShowCursor(device
, TRUE
);
1101 ok(ret
, "IDirect3DDevice8_ShowCursor returned %d\n", ret
);
1103 memset(&info
, 0, sizeof(info
));
1104 info
.cbSize
= sizeof(info
);
1105 ok(GetCursorInfo(&info
), "GetCursorInfo failed\n");
1106 ok(info
.flags
& (CURSOR_SHOWING
| CURSOR_SUPPRESSED
), "Got cursor flags %#lx.\n", info
.flags
);
1107 ok(info
.hCursor
!= cur
|| broken(1), "The cursor handle is %p\n", info
.hCursor
);
1109 /* Cursor dimensions must all be powers of two */
1110 for (test_idx
= 0; test_idx
< ARRAY_SIZE(cursor_sizes
); ++test_idx
)
1112 width
= cursor_sizes
[test_idx
].cx
;
1113 height
= cursor_sizes
[test_idx
].cy
;
1114 hr
= IDirect3DDevice8_CreateImageSurface(device
, width
, height
, D3DFMT_A8R8G8B8
, &cursor
);
1115 ok(hr
== D3D_OK
, "Test %u: CreateImageSurface failed, hr %#lx.\n", test_idx
, hr
);
1116 hr
= IDirect3DDevice8_SetCursorProperties(device
, 0, 0, cursor
);
1117 if (width
&& !(width
& (width
- 1)) && height
&& !(height
& (height
- 1)))
1118 expected_hr
= D3D_OK
;
1120 expected_hr
= D3DERR_INVALIDCALL
;
1121 ok(hr
== expected_hr
, "Test %u: Expect SetCursorProperties return %#lx, got %#lx.\n",
1122 test_idx
, expected_hr
, hr
);
1123 IDirect3DSurface8_Release(cursor
);
1126 refcount
= IDirect3DDevice8_Release(device
);
1127 ok(!refcount
, "Device has %lu references left.\n", refcount
);
1129 /* Cursor dimensions must not exceed adapter display mode */
1130 device_desc
.device_window
= window
;
1131 device_desc
.width
= 640;
1132 device_desc
.height
= 480;
1134 adapter_count
= IDirect3D8_GetAdapterCount(d3d
);
1135 for (adapter_idx
= 0; adapter_idx
< adapter_count
; ++adapter_idx
)
1137 for (test_idx
= 0; test_idx
< ARRAY_SIZE(device_flags
); ++test_idx
)
1139 device_desc
.adapter_ordinal
= adapter_idx
;
1140 device_desc
.flags
= device_flags
[test_idx
];
1141 if (!(device
= create_device(d3d
, window
, &device_desc
)))
1143 skip("Adapter %u test %u: Failed to create a D3D device.\n", adapter_idx
, test_idx
);
1147 hr
= IDirect3D8_GetAdapterDisplayMode(d3d
, adapter_idx
, &mode
);
1148 ok(hr
== D3D_OK
, "Adapter %u test %u: GetAdapterDisplayMode failed, hr %#lx.\n",
1149 adapter_idx
, test_idx
, hr
);
1151 /* Find the largest width and height that are powers of two and less than the display mode */
1154 while (width
* 2 <= mode
.Width
)
1156 while (height
* 2 <= mode
.Height
)
1159 hr
= IDirect3DDevice8_CreateImageSurface(device
, width
, height
, D3DFMT_A8R8G8B8
, &cursor
);
1160 ok(hr
== D3D_OK
, "Adapter %u test %u: CreateImageSurface failed, hr %#lx.\n",
1161 adapter_idx
, test_idx
, hr
);
1162 hr
= IDirect3DDevice8_SetCursorProperties(device
, 0, 0, cursor
);
1163 ok(hr
== D3D_OK
, "Adapter %u test %u: SetCursorProperties failed, hr %#lx.\n",
1164 adapter_idx
, test_idx
, hr
);
1165 IDirect3DSurface8_Release(cursor
);
1167 hr
= IDirect3DDevice8_CreateImageSurface(device
, width
* 2, height
, D3DFMT_A8R8G8B8
,
1169 ok(hr
== D3D_OK
, "Adapter %u test %u: CreateImageSurface failed, hr %#lx.\n",
1170 adapter_idx
, test_idx
, hr
);
1171 hr
= IDirect3DDevice8_SetCursorProperties(device
, 0, 0, cursor
);
1172 ok(hr
== D3DERR_INVALIDCALL
, "Adapter %u test %u: Got hr %#lx.\n", adapter_idx
, test_idx
, hr
);
1173 IDirect3DSurface8_Release(cursor
);
1175 hr
= IDirect3DDevice8_CreateImageSurface(device
, width
, height
* 2, D3DFMT_A8R8G8B8
,
1177 ok(hr
== D3D_OK
, "Adapter %u test %u: CreateImageSurface failed, hr %#lx.\n",
1178 adapter_idx
, test_idx
, hr
);
1179 hr
= IDirect3DDevice8_SetCursorProperties(device
, 0, 0, cursor
);
1180 ok(hr
== D3DERR_INVALIDCALL
, "Adapter %u test %u: Got hr %#lx.\n", adapter_idx
, test_idx
, hr
);
1181 IDirect3DSurface8_Release(cursor
);
1183 refcount
= IDirect3DDevice8_Release(device
);
1184 ok(!refcount
, "Adapter %u: Device has %lu references left.\n", adapter_idx
, refcount
);
1188 IDirect3D8_Release(d3d
);
1189 DestroyWindow(window
);
1192 static const POINT
*expect_pos
;
1194 static LRESULT CALLBACK
test_cursor_proc(HWND window
, UINT message
, WPARAM wparam
, LPARAM lparam
)
1196 if (message
== WM_MOUSEMOVE
)
1198 if (expect_pos
&& expect_pos
->x
&& expect_pos
->y
)
1200 POINT p
= {GET_X_LPARAM(lparam
), GET_Y_LPARAM(lparam
)};
1202 ClientToScreen(window
, &p
);
1203 if (expect_pos
->x
== p
.x
&& expect_pos
->y
== p
.y
)
1208 return DefWindowProcA(window
, message
, wparam
, lparam
);
1211 static void test_cursor_pos(void)
1213 IDirect3DSurface8
*cursor
;
1214 IDirect3DDevice8
*device
;
1223 /* Note that we don't check for movement we're not supposed to receive.
1224 * That's because it's hard to distinguish from the user accidentally
1225 * moving the mouse. */
1226 static const POINT points
[] =
1239 /* Windows 10 1709 is unreliable. One or more of the cursor movements we
1240 * expect don't show up. Moving the mouse to a defined position beforehand
1241 * seems to get it into better shape - only the final 150x150 move we do
1242 * below is missing - it looks as if this Windows version filters redundant
1243 * SetCursorPos calls on the user32 level, although I am not entirely sure.
1245 * The weird thing is that the previous test leaves the cursor position
1246 * reliably at 512x384 on the testbot. So the 50x50 mouse move shouldn't
1247 * be stripped away anyway, but it might be a difference between moving the
1248 * cursor through SetCursorPos vs moving it by changing the display mode. */
1249 ret
= SetCursorPos(99, 99);
1250 ok(ret
, "Failed to set cursor position.\n");
1253 /* Check if we can move the cursor. If we're running in a virtual desktop
1254 * that does not have focus or the mouse is outside the desktop window, some
1255 * window managers (e.g. kwin) will refuse to let us steal the pointer. That
1256 * is reasonable, but breaks the test. */
1257 ret
= GetCursorPos(&pt
);
1258 ok(ret
, "Failed to get cursor position.\n");
1259 if (pt
.x
!= 99 || pt
.y
!= 99)
1261 skip("Could not warp the cursor (cur pos %ld,%ld), skipping test.\n", pt
.x
, pt
.y
);
1265 wc
.lpfnWndProc
= test_cursor_proc
;
1266 wc
.lpszClassName
= "d3d8_test_cursor_wc";
1267 ok(RegisterClassA(&wc
), "Failed to register window class.\n");
1268 window
= CreateWindowA("d3d8_test_cursor_wc", "d3d8_test", WS_POPUP
| WS_SYSMENU
,
1269 0, 0, 320, 240, NULL
, NULL
, NULL
, NULL
);
1270 ShowWindow(window
, SW_SHOW
);
1271 d3d8
= Direct3DCreate8(D3D_SDK_VERSION
);
1272 ok(!!d3d8
, "Failed to create a D3D object.\n");
1274 if (!(device
= create_device(d3d8
, window
, NULL
)))
1276 skip("Failed to create a D3D device, skipping tests.\n");
1280 hr
= IDirect3DDevice8_CreateImageSurface(device
, 32, 32, D3DFMT_A8R8G8B8
, &cursor
);
1281 ok(SUCCEEDED(hr
), "Failed to create cursor surface, hr %#lx.\n", hr
);
1282 hr
= IDirect3DDevice8_SetCursorProperties(device
, 0, 0, cursor
);
1283 ok(SUCCEEDED(hr
), "Failed to set cursor properties, hr %#lx.\n", hr
);
1284 IDirect3DSurface8_Release(cursor
);
1285 ret
= IDirect3DDevice8_ShowCursor(device
, TRUE
);
1286 ok(!ret
, "Failed to show cursor, hr %#x.\n", ret
);
1289 expect_pos
= points
;
1291 ret
= SetCursorPos(50, 50);
1292 ok(ret
, "Failed to set cursor position.\n");
1295 IDirect3DDevice8_SetCursorPosition(device
, 75, 75, 0);
1297 /* SetCursorPosition() eats duplicates. FIXME: Since we accept unexpected
1298 * mouse moves the test doesn't actually demonstrate that. */
1299 IDirect3DDevice8_SetCursorPosition(device
, 75, 75, 0);
1302 ret
= SetCursorPos(100, 100);
1303 ok(ret
, "Failed to set cursor position.\n");
1305 /* Even if the position was set with SetCursorPos(). */
1306 IDirect3DDevice8_SetCursorPosition(device
, 100, 100, 0);
1309 IDirect3DDevice8_SetCursorPosition(device
, 125, 125, 0);
1311 ret
= SetCursorPos(150, 150);
1312 ok(ret
, "Failed to set cursor position.\n");
1314 IDirect3DDevice8_SetCursorPosition(device
, 125, 125, 0);
1317 IDirect3DDevice8_SetCursorPosition(device
, 150, 150, 0);
1319 /* SetCursorPos() doesn't. Except for Win10 1709. */
1320 ret
= SetCursorPos(150, 150);
1321 ok(ret
, "Failed to set cursor position.\n");
1324 ok((!expect_pos
->x
&& !expect_pos
->y
) || broken(expect_pos
- points
== 7),
1325 "Didn't receive MOUSEMOVE %u (%ld, %ld).\n",
1326 (unsigned)(expect_pos
- points
), expect_pos
->x
, expect_pos
->y
);
1328 refcount
= IDirect3DDevice8_Release(device
);
1329 ok(!refcount
, "Device has %u references left.\n", refcount
);
1331 DestroyWindow(window
);
1332 UnregisterClassA("d3d8_test_cursor_wc", GetModuleHandleA(NULL
));
1333 IDirect3D8_Release(d3d8
);
1336 static void test_states(void)
1338 IDirect3DDevice8
*device
;
1344 window
= create_window();
1345 ok(!!window
, "Failed to create a window.\n");
1346 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
1347 ok(!!d3d
, "Failed to create a D3D object.\n");
1348 if (!(device
= create_device(d3d
, window
, NULL
)))
1350 skip("Failed to create a 3D device, skipping test.\n");
1354 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZVISIBLE
, TRUE
);
1355 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
1356 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_ZVISIBLE
, FALSE
);
1357 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
1359 refcount
= IDirect3DDevice8_Release(device
);
1360 ok(!refcount
, "Device has %lu references left.\n", refcount
);
1362 IDirect3D8_Release(d3d
);
1363 DestroyWindow(window
);
1366 static void test_shader_versions(void)
1372 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
1373 ok(!!d3d
, "Failed to create a D3D object.\n");
1375 hr
= IDirect3D8_GetDeviceCaps(d3d
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
, &caps
);
1376 ok(SUCCEEDED(hr
) || hr
== D3DERR_NOTAVAILABLE
, "Failed to get device caps, hr %#lx.\n", hr
);
1377 IDirect3D8_Release(d3d
);
1380 skip("No Direct3D support, skipping test.\n");
1384 ok(caps
.VertexShaderVersion
<= D3DVS_VERSION(1,1),
1385 "Got unexpected VertexShaderVersion %#lx.\n", caps
.VertexShaderVersion
);
1386 ok(caps
.PixelShaderVersion
<= D3DPS_VERSION(1,4),
1387 "Got unexpected PixelShaderVersion %#lx.\n", caps
.PixelShaderVersion
);
1390 static void test_display_formats(void)
1392 D3DDEVTYPE device_type
= D3DDEVTYPE_HAL
;
1393 unsigned int backbuffer
, display
;
1394 unsigned int windowed
, i
;
1395 D3DDISPLAYMODE mode
;
1405 D3DFORMAT alpha_format
;
1411 {"D3DFMT_R5G6B5", D3DFMT_R5G6B5
, 0, TRUE
, TRUE
},
1412 {"D3DFMT_X1R5G5B5", D3DFMT_X1R5G5B5
, D3DFMT_A1R5G5B5
, TRUE
, TRUE
},
1413 {"D3DFMT_A1R5G5B5", D3DFMT_A1R5G5B5
, D3DFMT_A1R5G5B5
, FALSE
, FALSE
},
1414 {"D3DFMT_X8R8G8B8", D3DFMT_X8R8G8B8
, D3DFMT_A8R8G8B8
, TRUE
, TRUE
},
1415 {"D3DFMT_A8R8G8B8", D3DFMT_A8R8G8B8
, D3DFMT_A8R8G8B8
, FALSE
, FALSE
},
1416 {"D3DFMT_UNKNOWN", D3DFMT_UNKNOWN
, 0, FALSE
, FALSE
},
1419 d3d8
= Direct3DCreate8(D3D_SDK_VERSION
);
1420 ok(!!d3d8
, "Failed to create a D3D object.\n");
1422 for (display
= 0; display
< ARRAY_SIZE(formats
); ++display
)
1424 for (i
= 0, has_modes
= FALSE
; SUCCEEDED(IDirect3D8_EnumAdapterModes(d3d8
, D3DADAPTER_DEFAULT
, i
, &mode
)); ++i
)
1426 if (mode
.Format
== formats
[display
].format
)
1433 for (windowed
= 0; windowed
<= 1; ++windowed
)
1435 for (backbuffer
= 0; backbuffer
< ARRAY_SIZE(formats
); ++backbuffer
)
1437 should_pass
= FALSE
;
1439 if (formats
[display
].display
&& (formats
[display
].windowed
|| !windowed
) && (has_modes
|| windowed
))
1441 D3DFORMAT backbuffer_format
;
1443 if (windowed
&& formats
[backbuffer
].format
== D3DFMT_UNKNOWN
)
1444 backbuffer_format
= formats
[display
].format
;
1446 backbuffer_format
= formats
[backbuffer
].format
;
1448 hr
= IDirect3D8_CheckDeviceFormat(d3d8
, D3DADAPTER_DEFAULT
, device_type
, formats
[display
].format
,
1449 D3DUSAGE_RENDERTARGET
, D3DRTYPE_SURFACE
, backbuffer_format
);
1450 should_pass
= (hr
== D3D_OK
) && (formats
[display
].format
== formats
[backbuffer
].format
1451 || (formats
[display
].alpha_format
1452 && formats
[display
].alpha_format
== formats
[backbuffer
].alpha_format
));
1455 hr
= IDirect3D8_CheckDeviceType(d3d8
, D3DADAPTER_DEFAULT
, device_type
,
1456 formats
[display
].format
, formats
[backbuffer
].format
, windowed
);
1457 ok(SUCCEEDED(hr
) == should_pass
|| broken(SUCCEEDED(hr
) && !has_modes
) /* Win8 64-bit */,
1458 "Got unexpected hr %#lx for %s / %s, windowed %#x, should_pass %#x.\n",
1459 hr
, formats
[display
].name
, formats
[backbuffer
].name
, windowed
, should_pass
);
1464 IDirect3D8_Release(d3d8
);
1467 /* Test adapter display modes */
1468 static void test_display_modes(void)
1471 D3DDISPLAYMODE dmode
;
1475 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
1476 ok(!!d3d
, "Failed to create a D3D object.\n");
1478 max_modes
= IDirect3D8_GetAdapterModeCount(d3d
, D3DADAPTER_DEFAULT
);
1480 broken(max_modes
== 0), /* VMware */
1481 "GetAdapterModeCount(D3DADAPTER_DEFAULT) returned 0!\n");
1483 for (i
= 0; i
< max_modes
; ++i
)
1485 res
= IDirect3D8_EnumAdapterModes(d3d
, D3DADAPTER_DEFAULT
, i
, &dmode
);
1486 ok(res
==D3D_OK
, "EnumAdapterModes returned %#08lx for mode %u!\n", res
, i
);
1490 ok(dmode
.Format
==D3DFMT_X8R8G8B8
|| dmode
.Format
==D3DFMT_R5G6B5
,
1491 "Unexpected display mode returned for mode %u: %#x\n", i
, dmode
.Format
);
1494 IDirect3D8_Release(d3d
);
1503 static int compare_mode(const void *a
, const void *b
)
1505 const struct mode
*mode_a
= a
;
1506 const struct mode
*mode_b
= b
;
1507 int w
= mode_a
->w
- mode_b
->w
;
1508 int h
= mode_a
->h
- mode_b
->h
;
1509 return abs(w
) >= abs(h
) ? -w
: -h
;
1512 static void test_reset(void)
1514 UINT width
, orig_width
= GetSystemMetrics(SM_CXSCREEN
);
1515 UINT height
, orig_height
= GetSystemMetrics(SM_CYSCREEN
);
1516 IDirect3DDevice8
*device1
= NULL
;
1517 IDirect3DDevice8
*device2
= NULL
;
1518 struct device_desc device_desc
;
1519 D3DDISPLAYMODE d3ddm
, d3ddm2
;
1520 D3DSURFACE_DESC surface_desc
;
1521 D3DPRESENT_PARAMETERS d3dpp
;
1522 IDirect3DSurface8
*surface
;
1523 IDirect3DTexture8
*texture
;
1524 IDirect3DVertexBuffer8
*vb
;
1525 IDirect3DIndexBuffer8
*ib
;
1526 UINT adapter_mode_count
;
1527 D3DLOCKED_RECT lockrect
;
1528 UINT mode_count
= 0;
1531 RECT winrect
, client_rect
;
1542 static const DWORD decl
[] =
1545 D3DVSD_REG(D3DVSDE_POSITION
, D3DVSDT_FLOAT4
),
1549 struct mode
*modes
= NULL
;
1551 window
= CreateWindowA("d3d8_test_wc", "d3d8_test", WS_OVERLAPPEDWINDOW
,
1552 100, 100, 160, 160, NULL
, NULL
, NULL
, NULL
);
1553 ok(!!window
, "Failed to create a window.\n");
1554 d3d8
= Direct3DCreate8(D3D_SDK_VERSION
);
1555 ok(!!d3d8
, "Failed to create a D3D object.\n");
1557 hr
= IDirect3D8_GetAdapterDisplayMode(d3d8
, D3DADAPTER_DEFAULT
, &d3ddm
);
1558 ok(SUCCEEDED(hr
), "GetAdapterDisplayMode failed, hr %#lx.\n", hr
);
1559 adapter_mode_count
= IDirect3D8_GetAdapterModeCount(d3d8
, D3DADAPTER_DEFAULT
);
1560 modes
= malloc(sizeof(*modes
) * adapter_mode_count
);
1561 for (i
= 0; i
< adapter_mode_count
; ++i
)
1565 memset(&d3ddm2
, 0, sizeof(d3ddm2
));
1566 hr
= IDirect3D8_EnumAdapterModes(d3d8
, D3DADAPTER_DEFAULT
, i
, &d3ddm2
);
1567 ok(SUCCEEDED(hr
), "EnumAdapterModes failed, hr %#lx.\n", hr
);
1569 if (d3ddm2
.Format
!= d3ddm
.Format
)
1572 for (j
= 0; j
< mode_count
; ++j
)
1574 if (modes
[j
].w
== d3ddm2
.Width
&& modes
[j
].h
== d3ddm2
.Height
)
1577 if (j
== mode_count
)
1579 modes
[j
].w
= d3ddm2
.Width
;
1580 modes
[j
].h
= d3ddm2
.Height
;
1584 /* We use them as invalid modes. */
1585 if ((d3ddm2
.Width
== 801 && d3ddm2
.Height
== 600)
1586 || (d3ddm2
.Width
== 32 && d3ddm2
.Height
== 32))
1588 skip("This system supports a screen resolution of %dx%d, not running mode tests.\n",
1589 d3ddm2
.Width
, d3ddm2
.Height
);
1596 skip("Less than 2 modes supported, skipping mode tests.\n");
1600 /* Prefer higher resolutions. */
1601 qsort(modes
, mode_count
, sizeof(*modes
), compare_mode
);
1604 if (modes
[i
].w
== orig_width
&& modes
[i
].h
== orig_height
) ++i
;
1606 device_desc
.adapter_ordinal
= D3DADAPTER_DEFAULT
;
1607 device_desc
.width
= modes
[i
].w
;
1608 device_desc
.height
= modes
[i
].h
;
1609 device_desc
.device_window
= window
;
1610 device_desc
.flags
= CREATE_DEVICE_FULLSCREEN
| CREATE_DEVICE_SWVP_ONLY
;
1611 if (!(device1
= create_device(d3d8
, window
, &device_desc
)))
1613 skip("Failed to create a D3D device, skipping tests.\n");
1616 hr
= IDirect3DDevice8_TestCooperativeLevel(device1
);
1617 /* This skips the test on testbot Win 8 VMs. */
1618 if (hr
== D3DERR_DEVICELOST
)
1620 skip("Device is lost.\n");
1623 ok(SUCCEEDED(hr
), "TestCooperativeLevel failed, hr %#lx.\n", hr
);
1625 hr
= IDirect3DDevice8_GetDeviceCaps(device1
, &caps
);
1626 ok(SUCCEEDED(hr
), "GetDeviceCaps failed, hr %#lx.\n", hr
);
1628 width
= GetSystemMetrics(SM_CXSCREEN
);
1629 height
= GetSystemMetrics(SM_CYSCREEN
);
1630 ok(width
== modes
[i
].w
, "Screen width is %u, expected %u.\n", width
, modes
[i
].w
);
1631 ok(height
== modes
[i
].h
, "Screen height is %u, expected %u.\n", height
, modes
[i
].h
);
1633 hr
= IDirect3DDevice8_GetViewport(device1
, &vp
);
1634 ok(SUCCEEDED(hr
), "GetViewport failed, hr %#lx.\n", hr
);
1635 ok(vp
.X
== 0, "D3DVIEWPORT->X = %lu, expected 0.\n", vp
.X
);
1636 ok(vp
.Y
== 0, "D3DVIEWPORT->Y = %lu, expected 0.\n", vp
.Y
);
1637 ok(vp
.Width
== modes
[i
].w
, "D3DVIEWPORT->Width = %lu, expected %u.\n", vp
.Width
, modes
[i
].w
);
1638 ok(vp
.Height
== modes
[i
].h
, "D3DVIEWPORT->Height = %lu, expected %u.\n", vp
.Height
, modes
[i
].h
);
1639 ok(vp
.MinZ
== 0, "D3DVIEWPORT->MinZ = %.8e, expected 0.\n", vp
.MinZ
);
1640 ok(vp
.MaxZ
== 1, "D3DVIEWPORT->MaxZ = %.8e, expected 1.\n", vp
.MaxZ
);
1645 vp
.Width
= modes
[i
].w
/ 2;
1646 vp
.Height
= modes
[i
].h
/ 2;
1649 hr
= IDirect3DDevice8_SetViewport(device1
, &vp
);
1650 ok(SUCCEEDED(hr
), "SetViewport failed, hr %#lx.\n", hr
);
1652 hr
= IDirect3DDevice8_GetRenderState(device1
, D3DRS_LIGHTING
, &value
);
1653 ok(SUCCEEDED(hr
), "Failed to get render state, hr %#lx.\n", hr
);
1654 ok(!!value
, "Got unexpected value %#lx for D3DRS_LIGHTING.\n", value
);
1655 hr
= IDirect3DDevice8_SetRenderState(device1
, D3DRS_LIGHTING
, FALSE
);
1656 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#lx.\n", hr
);
1658 memset(&d3dpp
, 0, sizeof(d3dpp
));
1659 d3dpp
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
1660 d3dpp
.Windowed
= FALSE
;
1661 d3dpp
.BackBufferWidth
= modes
[i
].w
;
1662 d3dpp
.BackBufferHeight
= modes
[i
].h
;
1663 d3dpp
.BackBufferFormat
= d3ddm
.Format
;
1664 hr
= IDirect3DDevice8_Reset(device1
, &d3dpp
);
1665 ok(SUCCEEDED(hr
), "Reset failed, hr %#lx.\n", hr
);
1666 hr
= IDirect3DDevice8_TestCooperativeLevel(device1
);
1667 ok(SUCCEEDED(hr
), "TestCooperativeLevel failed, hr %#lx.\n", hr
);
1669 hr
= IDirect3DDevice8_GetRenderState(device1
, D3DRS_LIGHTING
, &value
);
1670 ok(SUCCEEDED(hr
), "Failed to get render state, hr %#lx.\n", hr
);
1671 ok(!!value
, "Got unexpected value %#lx for D3DRS_LIGHTING.\n", value
);
1673 memset(&vp
, 0, sizeof(vp
));
1674 hr
= IDirect3DDevice8_GetViewport(device1
, &vp
);
1675 ok(SUCCEEDED(hr
), "GetViewport failed, hr %#lx.\n", hr
);
1676 ok(vp
.X
== 0, "D3DVIEWPORT->X = %lu, expected 0.\n", vp
.X
);
1677 ok(vp
.Y
== 0, "D3DVIEWPORT->Y = %lu, expected 0.\n", vp
.Y
);
1678 ok(vp
.Width
== modes
[i
].w
, "D3DVIEWPORT->Width = %lu, expected %u.\n", vp
.Width
, modes
[i
].w
);
1679 ok(vp
.Height
== modes
[i
].h
, "D3DVIEWPORT->Height = %lu, expected %u.\n", vp
.Height
, modes
[i
].h
);
1680 ok(vp
.MinZ
== 0, "D3DVIEWPORT->MinZ = %.8e, expected 0.\n", vp
.MinZ
);
1681 ok(vp
.MaxZ
== 1, "D3DVIEWPORT->MaxZ = %.8e, expected 1.\n", vp
.MaxZ
);
1683 width
= GetSystemMetrics(SM_CXSCREEN
);
1684 height
= GetSystemMetrics(SM_CYSCREEN
);
1685 ok(width
== modes
[i
].w
, "Screen width is %u, expected %u.\n", width
, modes
[i
].w
);
1686 ok(height
== modes
[i
].h
, "Screen height is %u, expected %u.\n", height
, modes
[i
].h
);
1688 hr
= IDirect3DDevice8_GetRenderTarget(device1
, &surface
);
1689 ok(SUCCEEDED(hr
), "GetRenderTarget failed, hr %#lx.\n", hr
);
1690 hr
= IDirect3DSurface8_GetDesc(surface
, &surface_desc
);
1691 ok(hr
== D3D_OK
, "GetDesc failed, hr %#lx.\n", hr
);
1692 ok(surface_desc
.Width
== modes
[i
].w
, "Back buffer width is %u, expected %u.\n",
1693 surface_desc
.Width
, modes
[i
].w
);
1694 ok(surface_desc
.Height
== modes
[i
].h
, "Back buffer height is %u, expected %u.\n",
1695 surface_desc
.Height
, modes
[i
].h
);
1696 IDirect3DSurface8_Release(surface
);
1698 memset(&d3dpp
, 0, sizeof(d3dpp
));
1699 d3dpp
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
1700 d3dpp
.Windowed
= TRUE
;
1701 d3dpp
.BackBufferWidth
= 400;
1702 d3dpp
.BackBufferHeight
= 300;
1703 d3dpp
.BackBufferFormat
= D3DFMT_A8R8G8B8
;
1704 hr
= IDirect3DDevice8_Reset(device1
, &d3dpp
);
1705 ok(SUCCEEDED(hr
), "Reset failed, hr %#lx.\n", hr
);
1706 hr
= IDirect3DDevice8_TestCooperativeLevel(device1
);
1707 ok(SUCCEEDED(hr
), "TestCooperativeLevel failed, hr %#lx.\n", hr
);
1709 memset(&vp
, 0, sizeof(vp
));
1710 hr
= IDirect3DDevice8_GetViewport(device1
, &vp
);
1711 ok(SUCCEEDED(hr
), "GetViewport failed, hr %#lx.\n", hr
);
1712 ok(vp
.X
== 0, "D3DVIEWPORT->X = %lu, expected 0.\n", vp
.X
);
1713 ok(vp
.Y
== 0, "D3DVIEWPORT->Y = %lu, expected 0.\n", vp
.Y
);
1714 ok(vp
.Width
== 400, "D3DVIEWPORT->Width = %lu, expected 400.\n", vp
.Width
);
1715 ok(vp
.Height
== 300, "D3DVIEWPORT->Height = %lu, expected 300.\n", vp
.Height
);
1716 ok(vp
.MinZ
== 0, "D3DVIEWPORT->MinZ = %.8e, expected 0.\n", vp
.MinZ
);
1717 ok(vp
.MaxZ
== 1, "D3DVIEWPORT->MaxZ = %.8e, expected 1.\n", vp
.MaxZ
);
1719 width
= GetSystemMetrics(SM_CXSCREEN
);
1720 height
= GetSystemMetrics(SM_CYSCREEN
);
1721 ok(width
== orig_width
, "Screen width is %u, expected %u.\n", width
, orig_width
);
1722 ok(height
== orig_height
, "Screen height is %u, expected %u.\n", height
, orig_height
);
1724 hr
= IDirect3DDevice8_GetRenderTarget(device1
, &surface
);
1725 ok(SUCCEEDED(hr
), "GetRenderTarget failed, hr %#lx.\n", hr
);
1726 hr
= IDirect3DSurface8_GetDesc(surface
, &surface_desc
);
1727 ok(hr
== D3D_OK
, "GetDesc failed, hr %#lx.\n", hr
);
1728 ok(surface_desc
.Width
== 400, "Back buffer width is %u, expected 400.\n",
1729 surface_desc
.Width
);
1730 ok(surface_desc
.Height
== 300, "Back buffer height is %u, expected 300.\n",
1731 surface_desc
.Height
);
1732 IDirect3DSurface8_Release(surface
);
1734 memset(&devmode
, 0, sizeof(devmode
));
1735 devmode
.dmSize
= sizeof(devmode
);
1736 devmode
.dmFields
= DM_PELSWIDTH
| DM_PELSHEIGHT
;
1737 devmode
.dmPelsWidth
= modes
[1].w
;
1738 devmode
.dmPelsHeight
= modes
[1].h
;
1739 ret
= ChangeDisplaySettingsW(&devmode
, CDS_FULLSCREEN
);
1740 ok(ret
== DISP_CHANGE_SUCCESSFUL
, "Failed to change display mode, ret %#lx.\n", ret
);
1741 width
= GetSystemMetrics(SM_CXSCREEN
);
1742 height
= GetSystemMetrics(SM_CYSCREEN
);
1743 ok(width
== modes
[1].w
, "Screen width is %u, expected %u.\n", width
, modes
[1].w
);
1744 ok(height
== modes
[1].h
, "Screen height is %u, expected %u.\n", height
, modes
[1].h
);
1746 d3dpp
.BackBufferWidth
= 500;
1747 d3dpp
.BackBufferHeight
= 400;
1748 d3dpp
.BackBufferFormat
= D3DFMT_A8R8G8B8
;
1749 hr
= IDirect3DDevice8_Reset(device1
, &d3dpp
);
1750 ok(SUCCEEDED(hr
), "Reset failed, hr %#lx.\n", hr
);
1751 hr
= IDirect3DDevice8_TestCooperativeLevel(device1
);
1752 ok(SUCCEEDED(hr
), "TestCooperativeLevel failed, hr %#lx.\n", hr
);
1754 width
= GetSystemMetrics(SM_CXSCREEN
);
1755 height
= GetSystemMetrics(SM_CYSCREEN
);
1756 ok(width
== modes
[1].w
, "Screen width is %u, expected %u.\n", width
, modes
[1].w
);
1757 ok(height
== modes
[1].h
, "Screen height is %u, expected %u.\n", height
, modes
[1].h
);
1759 ZeroMemory(&vp
, sizeof(vp
));
1760 hr
= IDirect3DDevice8_GetViewport(device1
, &vp
);
1761 ok(SUCCEEDED(hr
), "GetViewport failed, hr %#lx.\n", hr
);
1762 ok(vp
.X
== 0, "D3DVIEWPORT->X = %ld.\n", vp
.X
);
1763 ok(vp
.Y
== 0, "D3DVIEWPORT->Y = %ld.\n", vp
.Y
);
1764 ok(vp
.Width
== 500, "D3DVIEWPORT->Width = %ld.\n", vp
.Width
);
1765 ok(vp
.Height
== 400, "D3DVIEWPORT->Height = %ld.\n", vp
.Height
);
1766 ok(vp
.MinZ
== 0, "D3DVIEWPORT->MinZ = %f.\n", vp
.MinZ
);
1767 ok(vp
.MaxZ
== 1, "D3DVIEWPORT->MaxZ = %f.\n", vp
.MaxZ
);
1769 hr
= IDirect3DDevice8_GetRenderTarget(device1
, &surface
);
1770 ok(SUCCEEDED(hr
), "GetRenderTarget failed, hr %#lx.\n", hr
);
1771 hr
= IDirect3DSurface8_GetDesc(surface
, &surface_desc
);
1772 ok(hr
== D3D_OK
, "GetDesc failed, hr %#lx.\n", hr
);
1773 ok(surface_desc
.Width
== 500, "Back buffer width is %u, expected 500.\n",
1774 surface_desc
.Width
);
1775 ok(surface_desc
.Height
== 400, "Back buffer height is %u, expected 400.\n",
1776 surface_desc
.Height
);
1777 IDirect3DSurface8_Release(surface
);
1779 devmode
.dmFields
= DM_PELSWIDTH
| DM_PELSHEIGHT
;
1780 devmode
.dmPelsWidth
= orig_width
;
1781 devmode
.dmPelsHeight
= orig_height
;
1782 ret
= ChangeDisplaySettingsW(&devmode
, CDS_FULLSCREEN
);
1783 ok(ret
== DISP_CHANGE_SUCCESSFUL
, "Failed to change display mode, ret %#lx.\n", ret
);
1784 width
= GetSystemMetrics(SM_CXSCREEN
);
1785 height
= GetSystemMetrics(SM_CYSCREEN
);
1786 ok(width
== orig_width
, "Got screen width %u, expected %u.\n", width
, orig_width
);
1787 ok(height
== orig_height
, "Got screen height %u, expected %u.\n", height
, orig_height
);
1791 winrect
.right
= 200;
1792 winrect
.bottom
= 150;
1793 ok(AdjustWindowRect(&winrect
, WS_OVERLAPPEDWINDOW
, FALSE
), "AdjustWindowRect failed\n");
1794 ok(SetWindowPos(window
, NULL
, 0, 0,
1795 winrect
.right
-winrect
.left
,
1796 winrect
.bottom
-winrect
.top
,
1797 SWP_NOMOVE
|SWP_NOZORDER
),
1798 "SetWindowPos failed\n");
1800 /* Windows 10 gives us a different size than we requested with some DPI scaling settings (e.g. 172%). */
1801 GetClientRect(window
, &client_rect
);
1803 memset(&d3dpp
, 0, sizeof(d3dpp
));
1804 d3dpp
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
1805 d3dpp
.Windowed
= TRUE
;
1806 d3dpp
.BackBufferWidth
= 0;
1807 d3dpp
.BackBufferHeight
= 0;
1808 d3dpp
.BackBufferFormat
= d3ddm
.Format
;
1809 hr
= IDirect3DDevice8_Reset(device1
, &d3dpp
);
1810 ok(SUCCEEDED(hr
), "Reset failed, hr %#lx.\n", hr
);
1811 hr
= IDirect3DDevice8_TestCooperativeLevel(device1
);
1812 ok(SUCCEEDED(hr
), "TestCooperativeLevel failed, hr %#lx.\n", hr
);
1814 ok(!d3dpp
.BackBufferWidth
, "Got unexpected BackBufferWidth %u.\n", d3dpp
.BackBufferWidth
);
1815 ok(!d3dpp
.BackBufferHeight
, "Got unexpected BackBufferHeight %u.\n", d3dpp
.BackBufferHeight
);
1816 ok(d3dpp
.BackBufferFormat
== d3ddm
.Format
, "Got unexpected BackBufferFormat %#x, expected %#x.\n",
1817 d3dpp
.BackBufferFormat
, d3ddm
.Format
);
1818 ok(d3dpp
.BackBufferCount
== 1, "Got unexpected BackBufferCount %u.\n", d3dpp
.BackBufferCount
);
1819 ok(!d3dpp
.MultiSampleType
, "Got unexpected MultiSampleType %u.\n", d3dpp
.MultiSampleType
);
1820 ok(d3dpp
.SwapEffect
== D3DSWAPEFFECT_DISCARD
, "Got unexpected SwapEffect %#x.\n", d3dpp
.SwapEffect
);
1821 ok(!d3dpp
.hDeviceWindow
, "Got unexpected hDeviceWindow %p.\n", d3dpp
.hDeviceWindow
);
1822 ok(d3dpp
.Windowed
, "Got unexpected Windowed %#x.\n", d3dpp
.Windowed
);
1823 ok(!d3dpp
.EnableAutoDepthStencil
, "Got unexpected EnableAutoDepthStencil %#x.\n", d3dpp
.EnableAutoDepthStencil
);
1824 ok(!d3dpp
.AutoDepthStencilFormat
, "Got unexpected AutoDepthStencilFormat %#x.\n", d3dpp
.AutoDepthStencilFormat
);
1825 ok(!d3dpp
.Flags
, "Got unexpected Flags %#lx.\n", d3dpp
.Flags
);
1826 ok(!d3dpp
.FullScreen_RefreshRateInHz
, "Got unexpected FullScreen_RefreshRateInHz %u.\n",
1827 d3dpp
.FullScreen_RefreshRateInHz
);
1828 ok(!d3dpp
.FullScreen_PresentationInterval
, "Got unexpected FullScreen_PresentationInterval %#x.\n",
1829 d3dpp
.FullScreen_PresentationInterval
);
1831 memset(&vp
, 0, sizeof(vp
));
1832 hr
= IDirect3DDevice8_GetViewport(device1
, &vp
);
1833 ok(SUCCEEDED(hr
), "GetViewport failed, hr %#lx.\n", hr
);
1836 ok(vp
.X
== 0, "D3DVIEWPORT->X = %lu, expected 0.\n", vp
.X
);
1837 ok(vp
.Y
== 0, "D3DVIEWPORT->Y = %lu, expected 0.\n", vp
.Y
);
1838 ok(vp
.Width
== client_rect
.right
, "D3DVIEWPORT->Width = %ld, expected %ld.\n",
1839 vp
.Width
, client_rect
.right
);
1840 ok(vp
.Height
== client_rect
.bottom
, "D3DVIEWPORT->Height = %ld, expected %ld.\n",
1841 vp
.Height
, client_rect
.bottom
);
1842 ok(vp
.MinZ
== 0, "D3DVIEWPORT->MinZ = %.8e, expected 0.\n", vp
.MinZ
);
1843 ok(vp
.MaxZ
== 1, "D3DVIEWPORT->MaxZ = %.8e, expected 1.\n", vp
.MaxZ
);
1846 hr
= IDirect3DDevice8_GetRenderTarget(device1
, &surface
);
1847 ok(SUCCEEDED(hr
), "GetRenderTarget failed, hr %#lx.\n", hr
);
1848 hr
= IDirect3DSurface8_GetDesc(surface
, &surface_desc
);
1849 ok(hr
== D3D_OK
, "GetDesc failed, hr %#lx.\n", hr
);
1850 ok(surface_desc
.Format
== d3ddm
.Format
, "Got unexpected Format %#x, expected %#x.\n",
1851 surface_desc
.Format
, d3ddm
.Format
);
1852 ok(!surface_desc
.MultiSampleType
, "Got unexpected MultiSampleType %u.\n", d3dpp
.MultiSampleType
);
1853 ok(surface_desc
.Width
== client_rect
.right
,
1854 "Back buffer width is %u, expected %ld.\n", surface_desc
.Width
, client_rect
.right
);
1855 ok(surface_desc
.Height
== client_rect
.bottom
,
1856 "Back buffer height is %u, expected %ld.\n", surface_desc
.Height
, client_rect
.bottom
);
1857 IDirect3DSurface8_Release(surface
);
1859 memset(&d3dpp
, 0, sizeof(d3dpp
));
1860 d3dpp
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
1861 d3dpp
.Windowed
= TRUE
;
1862 d3dpp
.BackBufferWidth
= 400;
1863 d3dpp
.BackBufferHeight
= 300;
1864 d3dpp
.BackBufferFormat
= d3ddm
.Format
;
1866 /* Reset fails if there is a resource in the default pool. */
1867 hr
= IDirect3DDevice8_CreateTexture(device1
, 16, 16, 1, 0, D3DFMT_R5G6B5
, D3DPOOL_DEFAULT
, &texture
);
1868 ok(SUCCEEDED(hr
), "CreateTexture failed, hr %#lx.\n", hr
);
1869 hr
= IDirect3DDevice8_Reset(device1
, &d3dpp
);
1870 ok(hr
== D3DERR_DEVICELOST
, "Got hr %#lx.\n", hr
);
1871 hr
= IDirect3DDevice8_TestCooperativeLevel(device1
);
1872 ok(hr
== D3DERR_DEVICENOTRESET
, "Got hr %#lx.\n", hr
);
1873 IDirect3DTexture8_Release(texture
);
1874 /* Reset again to get the device out of the lost state. */
1875 hr
= IDirect3DDevice8_Reset(device1
, &d3dpp
);
1876 ok(SUCCEEDED(hr
), "Reset failed, hr %#lx.\n", hr
);
1877 hr
= IDirect3DDevice8_TestCooperativeLevel(device1
);
1878 ok(SUCCEEDED(hr
), "TestCooperativeLevel failed, hr %#lx.\n", hr
);
1880 if (caps
.TextureCaps
& D3DPTEXTURECAPS_VOLUMEMAP
)
1882 IDirect3DVolumeTexture8
*volume_texture
;
1884 hr
= IDirect3DDevice8_CreateVolumeTexture(device1
, 16, 16, 4, 1, 0,
1885 D3DFMT_R5G6B5
, D3DPOOL_DEFAULT
, &volume_texture
);
1886 ok(SUCCEEDED(hr
), "CreateVolumeTexture failed, hr %#lx.\n", hr
);
1887 hr
= IDirect3DDevice8_Reset(device1
, &d3dpp
);
1888 ok(hr
== D3DERR_DEVICELOST
, "Got hr %#lx.\n", hr
);
1889 hr
= IDirect3DDevice8_TestCooperativeLevel(device1
);
1890 ok(hr
== D3DERR_DEVICENOTRESET
, "Got hr %#lx.\n", hr
);
1891 IDirect3DVolumeTexture8_Release(volume_texture
);
1892 hr
= IDirect3DDevice8_Reset(device1
, &d3dpp
);
1893 ok(SUCCEEDED(hr
), "Reset failed, hr %#lx.\n", hr
);
1894 hr
= IDirect3DDevice8_TestCooperativeLevel(device1
);
1895 ok(SUCCEEDED(hr
), "TestCooperativeLevel failed, hr %#lx.\n", hr
);
1899 skip("Volume textures not supported.\n");
1902 /* Test with DEFAULT pool resources bound but otherwise not referenced. */
1903 hr
= IDirect3DDevice8_CreateVertexBuffer(device1
, 16, 0,
1904 D3DFVF_XYZ
, D3DPOOL_DEFAULT
, &vb
);
1905 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
1906 hr
= IDirect3DDevice8_SetStreamSource(device1
, 0, vb
, 16);
1907 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
1908 refcount
= IDirect3DVertexBuffer8_Release(vb
);
1909 ok(!refcount
, "Unexpected refcount %lu.\n", refcount
);
1910 hr
= IDirect3DDevice8_CreateIndexBuffer(device1
, 16, 0,
1911 D3DFMT_INDEX16
, D3DPOOL_DEFAULT
, &ib
);
1912 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
1913 hr
= IDirect3DDevice8_SetIndices(device1
, ib
, 0);
1914 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
1915 refcount
= IDirect3DIndexBuffer8_Release(ib
);
1916 ok(!refcount
, "Unexpected refcount %lu.\n", refcount
);
1917 hr
= IDirect3DDevice8_CreateTexture(device1
, 16, 16, 0, 0,
1918 D3DFMT_X8R8G8B8
, D3DPOOL_DEFAULT
, &texture
);
1919 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
1920 hr
= IDirect3DDevice8_SetTexture(device1
, i
, (IDirect3DBaseTexture8
*)texture
);
1921 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
1923 hr
= IDirect3DDevice8_Reset(device1
, &d3dpp
);
1924 ok(hr
== D3DERR_DEVICELOST
, "Got unexpected hr %#lx.\n", hr
);
1925 hr
= IDirect3DDevice8_TestCooperativeLevel(device1
);
1926 ok(hr
== D3DERR_DEVICENOTRESET
, "Got unexpected hr %#lx.\n", hr
);
1928 /* Crashes on Windows. */
1931 hr
= IDirect3DDevice8_GetIndices(device1
, &ib
, &i
);
1932 todo_wine
ok(hr
== D3DERR_INVALIDCALL
, "Got unexpected hr %#lx.\n", hr
);
1934 refcount
= IDirect3DTexture8_Release(texture
);
1935 ok(!refcount
, "Unexpected refcount %lu.\n", refcount
);
1937 hr
= IDirect3DDevice8_Reset(device1
, &d3dpp
);
1938 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
1939 hr
= IDirect3DDevice8_TestCooperativeLevel(device1
);
1940 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
1942 /* Scratch, sysmem and managed pool resources are fine. */
1943 hr
= IDirect3DDevice8_CreateTexture(device1
, 16, 16, 1, 0, D3DFMT_R5G6B5
, D3DPOOL_SCRATCH
, &texture
);
1944 ok(SUCCEEDED(hr
), "CreateTexture failed, hr %#lx.\n", hr
);
1945 hr
= IDirect3DDevice8_Reset(device1
, &d3dpp
);
1946 ok(SUCCEEDED(hr
), "Reset failed, hr %#lx.\n", hr
);
1947 hr
= IDirect3DDevice8_TestCooperativeLevel(device1
);
1948 ok(SUCCEEDED(hr
), "TestCooperativeLevel failed, hr %#lx.\n", hr
);
1949 IDirect3DTexture8_Release(texture
);
1951 hr
= IDirect3DDevice8_CreateTexture(device1
, 16, 16, 1, 0, D3DFMT_R5G6B5
, D3DPOOL_SYSTEMMEM
, &texture
);
1952 ok(SUCCEEDED(hr
), "CreateTexture failed, hr %#lx.\n", hr
);
1953 hr
= IDirect3DDevice8_Reset(device1
, &d3dpp
);
1954 ok(SUCCEEDED(hr
), "Reset failed, hr %#lx.\n", hr
);
1955 hr
= IDirect3DDevice8_TestCooperativeLevel(device1
);
1956 ok(SUCCEEDED(hr
), "TestCooperativeLevel failed, hr %#lx.\n", hr
);
1957 IDirect3DTexture8_Release(texture
);
1959 hr
= IDirect3DDevice8_CreateVertexBuffer(device1
, 16, 0,
1960 D3DFVF_XYZ
, D3DPOOL_SYSTEMMEM
, &vb
);
1961 ok(hr
== D3D_OK
, "Failed to create vertex buffer, hr %#lx.\n", hr
);
1962 hr
= IDirect3DDevice8_Reset(device1
, &d3dpp
);
1963 ok(hr
== D3D_OK
, "Failed to reset device, hr %#lx.\n", hr
);
1964 IDirect3DVertexBuffer8_Release(vb
);
1966 hr
= IDirect3DDevice8_CreateIndexBuffer(device1
, 16, 0,
1967 D3DFMT_INDEX16
, D3DPOOL_SYSTEMMEM
, &ib
);
1968 ok(hr
== D3D_OK
, "Failed to create index buffer, hr %#lx.\n", hr
);
1969 hr
= IDirect3DDevice8_Reset(device1
, &d3dpp
);
1970 ok(hr
== D3D_OK
, "Failed to reset device, hr %#lx.\n", hr
);
1971 IDirect3DIndexBuffer8_Release(ib
);
1973 /* The depth stencil should get reset to the auto depth stencil when present. */
1974 hr
= IDirect3DDevice8_SetRenderTarget(device1
, NULL
, NULL
);
1975 ok(SUCCEEDED(hr
), "SetRenderTarget failed, hr %#lx.\n", hr
);
1977 hr
= IDirect3DDevice8_GetDepthStencilSurface(device1
, &surface
);
1978 ok(hr
== D3DERR_NOTFOUND
, "Got hr %#lx.\n", hr
);
1979 ok(!surface
, "Depth / stencil buffer should be NULL.\n");
1981 d3dpp
.EnableAutoDepthStencil
= TRUE
;
1982 d3dpp
.AutoDepthStencilFormat
= D3DFMT_D24S8
;
1983 hr
= IDirect3DDevice8_Reset(device1
, &d3dpp
);
1984 ok(SUCCEEDED(hr
), "Reset failed, hr %#lx.\n", hr
);
1986 hr
= IDirect3DDevice8_GetDepthStencilSurface(device1
, &surface
);
1987 ok(SUCCEEDED(hr
), "GetDepthStencilSurface failed, hr %#lx.\n", hr
);
1988 ok(!!surface
, "Depth / stencil buffer should not be NULL.\n");
1989 if (surface
) IDirect3DSurface8_Release(surface
);
1991 d3dpp
.EnableAutoDepthStencil
= FALSE
;
1992 hr
= IDirect3DDevice8_Reset(device1
, &d3dpp
);
1993 ok(SUCCEEDED(hr
), "Reset failed, hr %#lx.\n", hr
);
1995 hr
= IDirect3DDevice8_GetDepthStencilSurface(device1
, &surface
);
1996 ok(hr
== D3DERR_NOTFOUND
, "Got hr %#lx.\n", hr
);
1997 ok(!surface
, "Depth / stencil buffer should be NULL.\n");
1999 /* Will a sysmem or scratch resource survive while locked? */
2000 hr
= IDirect3DDevice8_CreateTexture(device1
, 16, 16, 1, 0, D3DFMT_R5G6B5
, D3DPOOL_SYSTEMMEM
, &texture
);
2001 ok(SUCCEEDED(hr
), "CreateTexture failed, hr %#lx.\n", hr
);
2002 hr
= IDirect3DTexture8_LockRect(texture
, 0, &lockrect
, NULL
, D3DLOCK_DISCARD
);
2003 ok(SUCCEEDED(hr
), "LockRect failed, hr %#lx.\n", hr
);
2004 hr
= IDirect3DDevice8_Reset(device1
, &d3dpp
);
2005 ok(SUCCEEDED(hr
), "Reset failed, hr %#lx.\n", hr
);
2006 hr
= IDirect3DDevice8_TestCooperativeLevel(device1
);
2007 ok(SUCCEEDED(hr
), "TestCooperativeLevel failed, hr %#lx.\n", hr
);
2008 IDirect3DTexture8_UnlockRect(texture
, 0);
2009 IDirect3DTexture8_Release(texture
);
2011 hr
= IDirect3DDevice8_CreateTexture(device1
, 16, 16, 1, 0, D3DFMT_R5G6B5
, D3DPOOL_SCRATCH
, &texture
);
2012 ok(SUCCEEDED(hr
), "CreateTexture failed, hr %#lx.\n", hr
);
2013 hr
= IDirect3DTexture8_LockRect(texture
, 0, &lockrect
, NULL
, D3DLOCK_DISCARD
);
2014 ok(SUCCEEDED(hr
), "LockRect failed, hr %#lx.\n", hr
);
2015 hr
= IDirect3DDevice8_Reset(device1
, &d3dpp
);
2016 ok(SUCCEEDED(hr
), "Reset failed, hr %#lx.\n", hr
);
2017 hr
= IDirect3DDevice8_TestCooperativeLevel(device1
);
2018 ok(SUCCEEDED(hr
), "TestCooperativeLevel failed, hr %#lx.\n", hr
);
2019 IDirect3DTexture8_UnlockRect(texture
, 0);
2020 IDirect3DTexture8_Release(texture
);
2022 hr
= IDirect3DDevice8_CreateTexture(device1
, 16, 16, 1, 0, D3DFMT_R5G6B5
, D3DPOOL_MANAGED
, &texture
);
2023 ok(SUCCEEDED(hr
), "CreateTexture failed, hr %#lx.\n", hr
);
2024 hr
= IDirect3DDevice8_Reset(device1
, &d3dpp
);
2025 ok(SUCCEEDED(hr
), "Reset failed, hr %#lx.\n", hr
);
2026 hr
= IDirect3DDevice8_TestCooperativeLevel(device1
);
2027 ok(SUCCEEDED(hr
), "TestCooperativeLevel failed, hr %#lx.\n", hr
);
2028 IDirect3DTexture8_Release(texture
);
2030 /* A reference held to an implicit surface causes failures as well. */
2031 hr
= IDirect3DDevice8_GetBackBuffer(device1
, 0, D3DBACKBUFFER_TYPE_MONO
, &surface
);
2032 ok(SUCCEEDED(hr
), "GetBackBuffer failed, hr %#lx.\n", hr
);
2033 hr
= IDirect3DDevice8_Reset(device1
, &d3dpp
);
2034 ok(hr
== D3DERR_DEVICELOST
, "Got hr %#lx.\n", hr
);
2035 hr
= IDirect3DDevice8_TestCooperativeLevel(device1
);
2036 ok(hr
== D3DERR_DEVICENOTRESET
, "Got hr %#lx.\n", hr
);
2037 IDirect3DSurface8_Release(surface
);
2038 hr
= IDirect3DDevice8_Reset(device1
, &d3dpp
);
2039 ok(SUCCEEDED(hr
), "Reset failed, hr %#lx.\n", hr
);
2040 hr
= IDirect3DDevice8_TestCooperativeLevel(device1
);
2041 ok(SUCCEEDED(hr
), "TestCooperativeLevel failed, hr %#lx.\n", hr
);
2043 /* Shaders are fine as well. */
2044 hr
= IDirect3DDevice8_CreateVertexShader(device1
, decl
, simple_vs
, &shader
, 0);
2045 ok(SUCCEEDED(hr
), "CreateVertexShader failed, hr %#lx.\n", hr
);
2046 hr
= IDirect3DDevice8_Reset(device1
, &d3dpp
);
2047 ok(SUCCEEDED(hr
), "Reset failed, hr %#lx.\n", hr
);
2048 hr
= IDirect3DDevice8_DeleteVertexShader(device1
, shader
);
2049 ok(SUCCEEDED(hr
), "DeleteVertexShader failed, hr %#lx.\n", hr
);
2051 /* Try setting invalid modes. */
2052 memset(&d3dpp
, 0, sizeof(d3dpp
));
2053 d3dpp
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
2054 d3dpp
.Windowed
= FALSE
;
2055 d3dpp
.BackBufferWidth
= 32;
2056 d3dpp
.BackBufferHeight
= 32;
2057 d3dpp
.BackBufferFormat
= d3ddm
.Format
;
2058 hr
= IDirect3DDevice8_Reset(device1
, &d3dpp
);
2059 ok(hr
== D3DERR_INVALIDCALL
, "Got hr %#lx.\n", hr
);
2060 hr
= IDirect3DDevice8_TestCooperativeLevel(device1
);
2061 ok(hr
== D3DERR_DEVICENOTRESET
, "Got hr %#lx.\n", hr
);
2063 memset(&d3dpp
, 0, sizeof(d3dpp
));
2064 d3dpp
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
2065 d3dpp
.Windowed
= FALSE
;
2066 d3dpp
.BackBufferWidth
= 801;
2067 d3dpp
.BackBufferHeight
= 600;
2068 d3dpp
.BackBufferFormat
= d3ddm
.Format
;
2069 hr
= IDirect3DDevice8_Reset(device1
, &d3dpp
);
2070 ok(hr
== D3DERR_INVALIDCALL
, "Got hr %#lx.\n", hr
);
2071 hr
= IDirect3DDevice8_TestCooperativeLevel(device1
);
2072 ok(hr
== D3DERR_DEVICENOTRESET
, "Got hr %#lx.\n", hr
);
2074 memset(&d3dpp
, 0, sizeof(d3dpp
));
2075 d3dpp
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
2076 d3dpp
.Windowed
= FALSE
;
2077 d3dpp
.BackBufferWidth
= 0;
2078 d3dpp
.BackBufferHeight
= 0;
2079 d3dpp
.BackBufferFormat
= d3ddm
.Format
;
2080 hr
= IDirect3DDevice8_Reset(device1
, &d3dpp
);
2081 ok(hr
== D3DERR_INVALIDCALL
, "Got hr %#lx.\n", hr
);
2082 hr
= IDirect3DDevice8_TestCooperativeLevel(device1
);
2083 ok(hr
== D3DERR_DEVICENOTRESET
, "Got hr %#lx.\n", hr
);
2085 hr
= IDirect3D8_GetAdapterDisplayMode(d3d8
, D3DADAPTER_DEFAULT
, &d3ddm
);
2086 ok(SUCCEEDED(hr
), "GetAdapterDisplayMode failed, hr %#lx.\n", hr
);
2088 memset(&d3dpp
, 0, sizeof(d3dpp
));
2089 d3dpp
.Windowed
= TRUE
;
2090 d3dpp
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
2091 d3dpp
.BackBufferFormat
= d3ddm
.Format
;
2092 d3dpp
.EnableAutoDepthStencil
= FALSE
;
2093 d3dpp
.AutoDepthStencilFormat
= D3DFMT_D24S8
;
2095 hr
= IDirect3D8_CreateDevice(d3d8
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
,
2096 window
, D3DCREATE_SOFTWARE_VERTEXPROCESSING
, &d3dpp
, &device2
);
2099 skip("Failed to create device, hr %#lx.\n", hr
);
2103 hr
= IDirect3DDevice8_TestCooperativeLevel(device2
);
2104 ok(SUCCEEDED(hr
), "TestCooperativeLevel failed, hr %#lx.\n", hr
);
2106 d3dpp
.Windowed
= TRUE
;
2107 d3dpp
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
2108 d3dpp
.BackBufferWidth
= 400;
2109 d3dpp
.BackBufferHeight
= 300;
2110 d3dpp
.BackBufferFormat
= d3ddm
.Format
;
2111 d3dpp
.EnableAutoDepthStencil
= TRUE
;
2112 d3dpp
.AutoDepthStencilFormat
= D3DFMT_D24S8
;
2114 hr
= IDirect3DDevice8_Reset(device2
, &d3dpp
);
2115 ok(SUCCEEDED(hr
), "Reset failed, hr %#lx.\n", hr
);
2119 hr
= IDirect3DDevice8_GetDepthStencilSurface(device2
, &surface
);
2120 ok(SUCCEEDED(hr
), "GetDepthStencilSurface failed, hr %#lx.\n", hr
);
2121 ok(!!surface
, "Depth / stencil buffer should not be NULL.\n");
2123 IDirect3DSurface8_Release(surface
);
2128 IDirect3DDevice8_Release(device2
);
2130 IDirect3DDevice8_Release(device1
);
2131 IDirect3D8_Release(d3d8
);
2132 DestroyWindow(window
);
2135 static void test_scene(void)
2137 IDirect3DDevice8
*device
;
2143 window
= create_window();
2144 ok(!!window
, "Failed to create a window.\n");
2145 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
2146 ok(!!d3d
, "Failed to create a D3D object.\n");
2147 if (!(device
= create_device(d3d
, window
, NULL
)))
2149 skip("Failed to create a 3D device, skipping test.\n");
2153 /* Test an EndScene without BeginScene. Should return an error */
2154 hr
= IDirect3DDevice8_EndScene(device
);
2155 ok(hr
== D3DERR_INVALIDCALL
, "Got hr %#lx.\n", hr
);
2157 /* Test a normal BeginScene / EndScene pair, this should work */
2158 hr
= IDirect3DDevice8_BeginScene(device
);
2159 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
2160 hr
= IDirect3DDevice8_EndScene(device
);
2161 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
2163 /* Test another EndScene without having begun a new scene. Should return an error */
2164 hr
= IDirect3DDevice8_EndScene(device
);
2165 ok(hr
== D3DERR_INVALIDCALL
, "Got hr %#lx.\n", hr
);
2167 /* Two nested BeginScene and EndScene calls */
2168 hr
= IDirect3DDevice8_BeginScene(device
);
2169 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
2170 hr
= IDirect3DDevice8_BeginScene(device
);
2171 ok(hr
== D3DERR_INVALIDCALL
, "Got hr %#lx.\n", hr
);
2172 hr
= IDirect3DDevice8_EndScene(device
);
2173 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
2174 hr
= IDirect3DDevice8_EndScene(device
);
2175 ok(hr
== D3DERR_INVALIDCALL
, "Got hr %#lx.\n", hr
);
2177 /* StretchRect does not exit in Direct3D8, so no equivalent to the d3d9 stretchrect tests */
2179 refcount
= IDirect3DDevice8_Release(device
);
2180 ok(!refcount
, "Device has %lu references left.\n", refcount
);
2182 IDirect3D8_Release(d3d
);
2183 DestroyWindow(window
);
2186 static void test_shader(void)
2188 DWORD hPixelShader
= 0, hVertexShader
= 0;
2189 DWORD hPixelShader2
= 0, hVertexShader2
= 0;
2192 DWORD fvf
= D3DFVF_XYZ
| D3DFVF_DIFFUSE
;
2193 IDirect3DDevice8
*device
;
2201 static DWORD dwVertexDecl
[] =
2204 D3DVSD_REG(D3DVSDE_POSITION
, D3DVSDT_FLOAT3
),
2207 DWORD decl_normal_float2
[] =
2210 D3DVSD_REG(D3DVSDE_POSITION
, D3DVSDT_FLOAT3
), /* D3DVSDE_POSITION, Register v0 */
2211 D3DVSD_REG(D3DVSDE_NORMAL
, D3DVSDT_FLOAT2
), /* D3DVSDE_NORMAL, Register v1 */
2214 DWORD decl_normal_float4
[] =
2217 D3DVSD_REG(D3DVSDE_POSITION
, D3DVSDT_FLOAT3
), /* D3DVSDE_POSITION, Register v0 */
2218 D3DVSD_REG(D3DVSDE_NORMAL
, D3DVSDT_FLOAT4
), /* D3DVSDE_NORMAL, Register v1 */
2221 DWORD decl_normal_d3dcolor
[] =
2224 D3DVSD_REG(D3DVSDE_POSITION
, D3DVSDT_FLOAT3
), /* D3DVSDE_POSITION, Register v0 */
2225 D3DVSD_REG(D3DVSDE_NORMAL
, D3DVSDT_D3DCOLOR
),/* D3DVSDE_NORMAL, Register v1 */
2228 const DWORD vertex_decl_size
= sizeof(dwVertexDecl
);
2229 const DWORD simple_vs_size
= sizeof(simple_vs
);
2230 const DWORD simple_ps_size
= sizeof(simple_ps
);
2232 window
= create_window();
2233 ok(!!window
, "Failed to create a window.\n");
2234 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
2235 ok(!!d3d
, "Failed to create a D3D object.\n");
2236 if (!(device
= create_device(d3d
, window
, NULL
)))
2238 skip("Failed to create a 3D device, skipping test.\n");
2242 IDirect3DDevice8_GetDeviceCaps(device
, &caps
);
2244 /* Test setting and retrieving a FVF */
2245 hr
= IDirect3DDevice8_SetVertexShader(device
, fvf
);
2246 ok(SUCCEEDED(hr
), "Got hr %#lx.\n", hr
);
2247 hr
= IDirect3DDevice8_GetVertexShader(device
, &hTempHandle
);
2248 ok(SUCCEEDED(hr
), "Got hr %#lx.\n", hr
);
2249 ok(hTempHandle
== fvf
, "Got vertex shader %#lx, expected %#lx.\n", hTempHandle
, fvf
);
2251 /* First create a vertex shader */
2252 hr
= IDirect3DDevice8_SetVertexShader(device
, 0);
2253 ok(SUCCEEDED(hr
), "Got hr %#lx.\n", hr
);
2254 hr
= IDirect3DDevice8_CreateVertexShader(device
, dwVertexDecl
, simple_vs
, &hVertexShader
, 0);
2255 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
2256 /* Msdn says that the new vertex shader is set immediately. This is wrong, apparently */
2257 hr
= IDirect3DDevice8_GetVertexShader(device
, &hTempHandle
);
2258 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
2259 ok(!hTempHandle
, "Got vertex shader %#lx.\n", hTempHandle
);
2260 /* Assign the shader, then verify that GetVertexShader works */
2261 hr
= IDirect3DDevice8_SetVertexShader(device
, hVertexShader
);
2262 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
2263 hr
= IDirect3DDevice8_GetVertexShader(device
, &hTempHandle
);
2264 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
2265 ok(hTempHandle
== hVertexShader
, "Got vertex shader %#lx, expected %#lx.\n", hTempHandle
, hVertexShader
);
2266 /* Verify that we can retrieve the declaration */
2267 hr
= IDirect3DDevice8_GetVertexShaderDeclaration(device
, hVertexShader
, NULL
, &data_size
);
2268 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
2269 ok(data_size
== vertex_decl_size
, "Got data_size %lu, expected %lu.\n", data_size
, vertex_decl_size
);
2270 data
= malloc(vertex_decl_size
);
2272 hr
= IDirect3DDevice8_GetVertexShaderDeclaration(device
, hVertexShader
, data
, &data_size
);
2273 ok(hr
== D3DERR_INVALIDCALL
, "Got hr %#lx.\n", hr
);
2274 ok(data_size
== 1, "Got data_size %lu.\n", data_size
);
2275 data_size
= vertex_decl_size
;
2276 hr
= IDirect3DDevice8_GetVertexShaderDeclaration(device
, hVertexShader
, data
, &data_size
);
2277 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
2278 ok(data_size
== vertex_decl_size
, "Got data_size %lu, expected %lu.\n", data_size
, vertex_decl_size
);
2279 ok(!memcmp(data
, dwVertexDecl
, vertex_decl_size
), "data not equal to shader declaration\n");
2281 /* Verify that we can retrieve the shader function */
2282 hr
= IDirect3DDevice8_GetVertexShaderFunction(device
, hVertexShader
, NULL
, &data_size
);
2283 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
2284 ok(data_size
== simple_vs_size
, "Got data_size %lu, expected %lu.\n", data_size
, simple_vs_size
);
2285 data
= malloc(simple_vs_size
);
2287 hr
= IDirect3DDevice8_GetVertexShaderFunction(device
, hVertexShader
, data
, &data_size
);
2288 ok(hr
== D3DERR_INVALIDCALL
, "Got hr %#lx.\n", hr
);
2289 ok(data_size
== 1, "Got data_size %lu.\n", data_size
);
2290 data_size
= simple_vs_size
;
2291 hr
= IDirect3DDevice8_GetVertexShaderFunction(device
, hVertexShader
, data
, &data_size
);
2292 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
2293 ok(data_size
== simple_vs_size
, "Got data_size %lu, expected %lu.\n", data_size
, simple_vs_size
);
2294 ok(!memcmp(data
, simple_vs
, simple_vs_size
), "data not equal to shader function\n");
2296 /* Delete the assigned shader. This is supposed to work */
2297 hr
= IDirect3DDevice8_DeleteVertexShader(device
, hVertexShader
);
2298 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
2299 /* The shader should be unset now */
2300 hr
= IDirect3DDevice8_GetVertexShader(device
, &hTempHandle
);
2301 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
2302 ok(!hTempHandle
, "Got vertex shader %#lx.\n", hTempHandle
);
2304 /* Test a broken declaration. 3DMark2001 tries to use normals with 2 components
2305 * First try the fixed function shader function, then a custom one
2307 hr
= IDirect3DDevice8_CreateVertexShader(device
, decl_normal_float2
, 0, &hVertexShader
, 0);
2308 ok(hr
== D3DERR_INVALIDCALL
, "Got hr %#lx.\n", hr
);
2309 hr
= IDirect3DDevice8_CreateVertexShader(device
, decl_normal_float4
, 0, &hVertexShader
, 0);
2310 ok(hr
== D3DERR_INVALIDCALL
, "Got hr %#lx.\n", hr
);
2311 hr
= IDirect3DDevice8_CreateVertexShader(device
, decl_normal_d3dcolor
, 0, &hVertexShader
, 0);
2312 ok(hr
== D3DERR_INVALIDCALL
, "Got hr %#lx.\n", hr
);
2314 hr
= IDirect3DDevice8_CreateVertexShader(device
, decl_normal_float2
, simple_vs
, &hVertexShader
, 0);
2315 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
2316 IDirect3DDevice8_DeleteVertexShader(device
, hVertexShader
);
2318 if (caps
.PixelShaderVersion
>= D3DPS_VERSION(1, 0))
2320 /* The same with a pixel shader */
2321 hr
= IDirect3DDevice8_CreatePixelShader(device
, simple_ps
, &hPixelShader
);
2322 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
2323 /* Msdn says that the new pixel shader is set immediately. This is wrong, apparently */
2324 hr
= IDirect3DDevice8_GetPixelShader(device
, &hTempHandle
);
2325 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
2326 ok(!hTempHandle
, "Got pixel shader %#lx.\n", hTempHandle
);
2327 /* Assign the shader, then verify that GetPixelShader works */
2328 hr
= IDirect3DDevice8_SetPixelShader(device
, hPixelShader
);
2329 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
2330 hr
= IDirect3DDevice8_GetPixelShader(device
, &hTempHandle
);
2331 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
2332 ok(hTempHandle
== hPixelShader
, "Got pixel shader %#lx, expected %#lx.\n", hTempHandle
, hPixelShader
);
2333 /* Verify that we can retrieve the shader function */
2334 hr
= IDirect3DDevice8_GetPixelShaderFunction(device
, hPixelShader
, NULL
, &data_size
);
2335 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
2336 ok(data_size
== simple_ps_size
, "Got data_size %lu, expected %lu.\n", data_size
, simple_ps_size
);
2337 data
= malloc(simple_ps_size
);
2339 hr
= IDirect3DDevice8_GetPixelShaderFunction(device
, hPixelShader
, data
, &data_size
);
2340 ok(hr
== D3DERR_INVALIDCALL
, "Got hr %#lx.\n", hr
);
2341 ok(data_size
== 1, "Got data_size %lu.\n", data_size
);
2342 data_size
= simple_ps_size
;
2343 hr
= IDirect3DDevice8_GetPixelShaderFunction(device
, hPixelShader
, data
, &data_size
);
2344 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
2345 ok(data_size
== simple_ps_size
, "Got data_size %lu, expected %lu.\n", data_size
, simple_ps_size
);
2346 ok(!memcmp(data
, simple_ps
, simple_ps_size
), "data not equal to shader function\n");
2348 /* Delete the assigned shader. This is supposed to work */
2349 hr
= IDirect3DDevice8_DeletePixelShader(device
, hPixelShader
);
2350 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
2351 /* The shader should be unset now */
2352 hr
= IDirect3DDevice8_GetPixelShader(device
, &hTempHandle
);
2353 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
2354 ok(!hTempHandle
, "Got pixel shader %#lx.\n", hTempHandle
);
2356 /* What happens if a non-bound shader is deleted? */
2357 hr
= IDirect3DDevice8_CreatePixelShader(device
, simple_ps
, &hPixelShader
);
2358 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
2359 hr
= IDirect3DDevice8_CreatePixelShader(device
, simple_ps
, &hPixelShader2
);
2360 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
2362 hr
= IDirect3DDevice8_SetPixelShader(device
, hPixelShader
);
2363 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
2364 hr
= IDirect3DDevice8_DeletePixelShader(device
, hPixelShader2
);
2365 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
2366 hr
= IDirect3DDevice8_GetPixelShader(device
, &hTempHandle
);
2367 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
2368 ok(hTempHandle
== hPixelShader
, "Got pixel shader %#lx, expected %#lx.\n", hTempHandle
, hPixelShader
);
2369 hr
= IDirect3DDevice8_DeletePixelShader(device
, hPixelShader
);
2370 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
2372 /* Check for double delete. */
2373 hr
= IDirect3DDevice8_DeletePixelShader(device
, hPixelShader2
);
2374 ok(hr
== D3DERR_INVALIDCALL
|| broken(hr
== D3D_OK
), "Got hr %#lx.\n", hr
);
2375 hr
= IDirect3DDevice8_DeletePixelShader(device
, hPixelShader
);
2376 ok(hr
== D3DERR_INVALIDCALL
|| broken(hr
== D3D_OK
), "Got hr %#lx.\n", hr
);
2380 skip("Pixel shaders not supported\n");
2383 /* What happens if a non-bound shader is deleted? */
2384 hr
= IDirect3DDevice8_CreateVertexShader(device
, dwVertexDecl
, NULL
, &hVertexShader
, 0);
2385 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
2386 hr
= IDirect3DDevice8_CreateVertexShader(device
, dwVertexDecl
, NULL
, &hVertexShader2
, 0);
2387 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
2389 hr
= IDirect3DDevice8_SetVertexShader(device
, hVertexShader
);
2390 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
2391 hr
= IDirect3DDevice8_DeleteVertexShader(device
, hVertexShader2
);
2392 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
2393 hr
= IDirect3DDevice8_GetVertexShader(device
, &hTempHandle
);
2394 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
2395 ok(hTempHandle
== hVertexShader
, "Got vertex shader %#lx, expected %#lx.\n", hTempHandle
, hVertexShader
);
2396 hr
= IDirect3DDevice8_DeleteVertexShader(device
, hVertexShader
);
2397 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
2399 /* Check for double delete. */
2400 hr
= IDirect3DDevice8_DeleteVertexShader(device
, hVertexShader2
);
2401 ok(hr
== D3DERR_INVALIDCALL
, "Got hr %#lx.\n", hr
);
2402 hr
= IDirect3DDevice8_DeleteVertexShader(device
, hVertexShader
);
2403 ok(hr
== D3DERR_INVALIDCALL
, "Got hr %#lx.\n", hr
);
2405 refcount
= IDirect3DDevice8_Release(device
);
2406 ok(!refcount
, "Device has %lu references left.\n", refcount
);
2408 IDirect3D8_Release(d3d
);
2409 DestroyWindow(window
);
2412 static void test_limits(void)
2414 IDirect3DTexture8
*texture
;
2415 IDirect3DDevice8
*device
;
2422 window
= create_window();
2423 ok(!!window
, "Failed to create a window.\n");
2424 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
2425 ok(!!d3d
, "Failed to create a D3D object.\n");
2426 if (!(device
= create_device(d3d
, window
, NULL
)))
2428 skip("Failed to create a 3D device, skipping test.\n");
2432 hr
= IDirect3DDevice8_CreateTexture(device
, 16, 16, 1, 0, D3DFMT_A8R8G8B8
, D3DPOOL_MANAGED
, &texture
);
2433 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
2435 /* There are 8 texture stages. We should be able to access all of them */
2436 for (i
= 0; i
< 8; ++i
)
2438 hr
= IDirect3DDevice8_SetTexture(device
, i
, (IDirect3DBaseTexture8
*)texture
);
2439 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
2440 hr
= IDirect3DDevice8_SetTexture(device
, i
, NULL
);
2441 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
2442 hr
= IDirect3DDevice8_SetTextureStageState(device
, i
, D3DTSS_COLOROP
, D3DTOP_ADD
);
2443 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
2446 /* Investigations show that accessing higher textures stage states does
2447 * not return an error either. Writing to too high texture stages
2448 * (approximately texture 40) causes memory corruption in windows, so
2449 * there is no bounds checking. */
2450 IDirect3DTexture8_Release(texture
);
2451 refcount
= IDirect3DDevice8_Release(device
);
2452 ok(!refcount
, "Device has %lu references left.\n", refcount
);
2454 IDirect3D8_Release(d3d
);
2455 DestroyWindow(window
);
2458 static void test_lights(void)
2460 IDirect3DDevice8
*device
;
2469 window
= create_window();
2470 ok(!!window
, "Failed to create a window.\n");
2471 d3d8
= Direct3DCreate8(D3D_SDK_VERSION
);
2472 ok(!!d3d8
, "Failed to create a D3D object.\n");
2473 if (!(device
= create_device(d3d8
, window
, NULL
)))
2475 skip("Failed to create a 3D device, skipping test.\n");
2479 memset(&caps
, 0, sizeof(caps
));
2480 hr
= IDirect3DDevice8_GetDeviceCaps(device
, &caps
);
2481 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
2483 for(i
= 1; i
<= caps
.MaxActiveLights
; i
++) {
2484 hr
= IDirect3DDevice8_LightEnable(device
, i
, TRUE
);
2485 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
2486 hr
= IDirect3DDevice8_GetLightEnable(device
, i
, &enabled
);
2487 ok(hr
== D3D_OK
|| broken(hr
== D3DERR_INVALIDCALL
), "Got hr %#lx.\n", hr
);
2488 ok(enabled
, "Light %d is %s\n", i
, enabled
? "enabled" : "disabled");
2491 /* TODO: Test the rendering results in this situation */
2492 hr
= IDirect3DDevice8_LightEnable(device
, i
+ 1, TRUE
);
2493 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
2494 hr
= IDirect3DDevice8_GetLightEnable(device
, i
+ 1, &enabled
);
2495 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
2496 ok(enabled
, "Light %d is %s\n", i
+ 1, enabled
? "enabled" : "disabled");
2497 hr
= IDirect3DDevice8_LightEnable(device
, i
+ 1, FALSE
);
2498 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
2500 for(i
= 1; i
<= caps
.MaxActiveLights
; i
++) {
2501 hr
= IDirect3DDevice8_LightEnable(device
, i
, FALSE
);
2502 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
2505 refcount
= IDirect3DDevice8_Release(device
);
2506 ok(!refcount
, "Device has %lu references left.\n", refcount
);
2508 IDirect3D8_Release(d3d8
);
2509 DestroyWindow(window
);
2512 static void test_set_stream_source(void)
2514 IDirect3DVertexBuffer8
*vb
, *current_vb
;
2515 IDirect3DDevice8
*device
;
2516 unsigned int stride
;
2522 window
= create_window();
2523 ok(!!window
, "Failed to create a window.\n");
2524 d3d8
= Direct3DCreate8(D3D_SDK_VERSION
);
2525 ok(!!d3d8
, "Failed to create a D3D object.\n");
2526 if (!(device
= create_device(d3d8
, window
, NULL
)))
2528 skip("Failed to create a 3D device, skipping test.\n");
2532 hr
= IDirect3DDevice8_CreateVertexBuffer(device
, 512, 0, 0, D3DPOOL_DEFAULT
, &vb
);
2533 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
2535 hr
= IDirect3DDevice8_SetStreamSource(device
, 0, vb
, 32);
2536 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
2538 hr
= IDirect3DDevice8_SetStreamSource(device
, 0, NULL
, 0);
2539 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
2540 hr
= IDirect3DDevice8_GetStreamSource(device
, 0, ¤t_vb
, &stride
);
2541 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
2542 ok(!current_vb
, "Got unexpected vb %p.\n", current_vb
);
2543 ok(stride
== 32, "Got unexpected stride %u.\n", stride
);
2545 hr
= IDirect3DDevice8_SetStreamSource(device
, 0, vb
, 0);
2546 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
2547 hr
= IDirect3DDevice8_GetStreamSource(device
, 0, ¤t_vb
, &stride
);
2548 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
2549 ok(current_vb
== vb
, "Got unexpected vb %p.\n", current_vb
);
2550 IDirect3DVertexBuffer8_Release(current_vb
);
2551 ok(!stride
, "Got unexpected stride %u.\n", stride
);
2553 IDirect3DVertexBuffer8_Release(vb
);
2554 refcount
= IDirect3DDevice8_Release(device
);
2555 ok(!refcount
, "Device has %lu references left.\n", refcount
);
2557 IDirect3D8_Release(d3d8
);
2558 DestroyWindow(window
);
2561 static void test_render_zero_triangles(void)
2563 IDirect3DDevice8
*device
;
2571 struct vec3 position
;
2577 {{0.0f
, -1.0f
, 0.1f
}, {1.0f
, 1.0f
, 1.0f
}, 0xff0000ff},
2578 {{0.0f
, 0.0f
, 0.1f
}, {1.0f
, 1.0f
, 1.0f
}, 0xff0000ff},
2579 {{1.0f
, 0.0f
, 0.1f
}, {1.0f
, 1.0f
, 1.0f
}, 0xff0000ff},
2580 {{1.0f
, -1.0f
, 0.1f
}, {1.0f
, 1.0f
, 1.0f
}, 0xff0000ff},
2583 window
= create_window();
2584 ok(!!window
, "Failed to create a window.\n");
2585 d3d8
= Direct3DCreate8(D3D_SDK_VERSION
);
2586 ok(!!d3d8
, "Failed to create a D3D object.\n");
2587 if (!(device
= create_device(d3d8
, window
, NULL
)))
2589 skip("Failed to create a 3D device, skipping test.\n");
2593 hr
= IDirect3DDevice8_SetVertexShader(device
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
);
2594 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
2596 hr
= IDirect3DDevice8_BeginScene(device
);
2597 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#lx.\n", hr
);
2598 hr
= IDirect3DDevice8_DrawIndexedPrimitiveUP(device
, D3DPT_TRIANGLELIST
, 0 /* MinIndex */, 0 /* NumVerts */,
2599 0 /* PrimCount */, NULL
, D3DFMT_INDEX16
, quad
, sizeof(quad
[0]));
2600 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
2601 hr
= IDirect3DDevice8_EndScene(device
);
2602 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#lx.\n", hr
);
2604 IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
2606 refcount
= IDirect3DDevice8_Release(device
);
2607 ok(!refcount
, "Device has %lu references left.\n", refcount
);
2609 IDirect3D8_Release(d3d8
);
2610 DestroyWindow(window
);
2613 static void test_depth_stencil_reset(void)
2615 D3DPRESENT_PARAMETERS present_parameters
;
2616 D3DDISPLAYMODE display_mode
;
2617 IDirect3DSurface8
*surface
, *orig_rt
;
2618 IDirect3DDevice8
*device
= NULL
;
2624 hwnd
= CreateWindowA("d3d8_test_wc", "d3d8_test", WS_OVERLAPPEDWINDOW
,
2625 100, 100, 160, 160, NULL
, NULL
, NULL
, NULL
);
2626 ok(!!hwnd
, "Failed to create a window.\n");
2627 d3d8
= Direct3DCreate8(D3D_SDK_VERSION
);
2628 ok(!!d3d8
, "Failed to create a D3D object.\n");
2630 IDirect3D8_GetAdapterDisplayMode(d3d8
, D3DADAPTER_DEFAULT
, &display_mode
);
2631 memset(&present_parameters
, 0, sizeof(present_parameters
));
2632 present_parameters
.Windowed
= TRUE
;
2633 present_parameters
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
2634 present_parameters
.BackBufferFormat
= display_mode
.Format
;
2635 present_parameters
.EnableAutoDepthStencil
= TRUE
;
2636 present_parameters
.AutoDepthStencilFormat
= D3DFMT_D24S8
;
2638 hr
= IDirect3D8_CreateDevice(d3d8
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
, hwnd
,
2639 D3DCREATE_SOFTWARE_VERTEXPROCESSING
, &present_parameters
, &device
);
2642 skip("Failed to create device, hr %#lx.\n", hr
);
2646 hr
= IDirect3DDevice8_GetRenderTarget(device
, &orig_rt
);
2647 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
2649 hr
= IDirect3DDevice8_TestCooperativeLevel(device
);
2650 ok(SUCCEEDED(hr
), "Got hr %#lx.\n", hr
);
2652 hr
= IDirect3DDevice8_SetRenderTarget(device
, NULL
, NULL
);
2653 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
2655 hr
= IDirect3DDevice8_GetRenderTarget(device
, &surface
);
2656 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
2657 ok(surface
== orig_rt
, "Render target is %p, should be %p\n", surface
, orig_rt
);
2658 if (surface
) IDirect3DSurface8_Release(surface
);
2659 IDirect3DSurface8_Release(orig_rt
);
2661 hr
= IDirect3DDevice8_GetDepthStencilSurface(device
, &surface
);
2662 ok(hr
== D3DERR_NOTFOUND
, "Got hr %#lx.\n", hr
);
2663 ok(surface
== NULL
, "Depth stencil should be NULL\n");
2665 present_parameters
.EnableAutoDepthStencil
= TRUE
;
2666 present_parameters
.AutoDepthStencilFormat
= D3DFMT_D24S8
;
2667 hr
= IDirect3DDevice8_Reset(device
, &present_parameters
);
2668 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
2670 hr
= IDirect3DDevice8_GetDepthStencilSurface(device
, &surface
);
2671 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
2672 ok(surface
!= NULL
, "Depth stencil should not be NULL\n");
2673 if (surface
) IDirect3DSurface8_Release(surface
);
2675 present_parameters
.EnableAutoDepthStencil
= FALSE
;
2676 hr
= IDirect3DDevice8_Reset(device
, &present_parameters
);
2677 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
2679 hr
= IDirect3DDevice8_GetDepthStencilSurface(device
, &surface
);
2680 ok(hr
== D3DERR_NOTFOUND
, "Got hr %#lx.\n", hr
);
2681 ok(surface
== NULL
, "Depth stencil should be NULL\n");
2683 refcount
= IDirect3DDevice8_Release(device
);
2684 ok(!refcount
, "Device has %u references left.\n", refcount
);
2687 IDirect3D8_GetAdapterDisplayMode( d3d8
, D3DADAPTER_DEFAULT
, &display_mode
);
2689 ZeroMemory( &present_parameters
, sizeof(present_parameters
) );
2690 present_parameters
.Windowed
= TRUE
;
2691 present_parameters
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
2692 present_parameters
.BackBufferFormat
= display_mode
.Format
;
2693 present_parameters
.EnableAutoDepthStencil
= FALSE
;
2694 present_parameters
.AutoDepthStencilFormat
= D3DFMT_D24S8
;
2696 hr
= IDirect3D8_CreateDevice( d3d8
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
, hwnd
,
2697 D3DCREATE_SOFTWARE_VERTEXPROCESSING
, &present_parameters
, &device
);
2701 skip("Failed to create device, hr %#lx.\n", hr
);
2705 hr
= IDirect3DDevice8_TestCooperativeLevel(device
);
2706 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
2708 present_parameters
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
2709 present_parameters
.Windowed
= TRUE
;
2710 present_parameters
.BackBufferWidth
= 400;
2711 present_parameters
.BackBufferHeight
= 300;
2712 present_parameters
.EnableAutoDepthStencil
= TRUE
;
2713 present_parameters
.AutoDepthStencilFormat
= D3DFMT_D24S8
;
2715 hr
= IDirect3DDevice8_Reset(device
, &present_parameters
);
2716 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
2718 if (FAILED(hr
)) goto cleanup
;
2720 hr
= IDirect3DDevice8_GetDepthStencilSurface(device
, &surface
);
2721 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
2722 ok(surface
!= NULL
, "Depth stencil should not be NULL\n");
2723 if (surface
) IDirect3DSurface8_Release(surface
);
2728 refcount
= IDirect3DDevice8_Release(device
);
2729 ok(!refcount
, "Device has %u references left.\n", refcount
);
2731 IDirect3D8_Release(d3d8
);
2732 DestroyWindow(hwnd
);
2735 static HWND filter_messages
;
2746 enum message_window window
;
2748 WPARAM expect_wparam
;
2749 HRESULT device_state
;
2750 WINDOWPOS
*store_wp
;
2753 static const struct message
*expect_messages
;
2754 static HWND device_window
, focus_window
;
2755 static LONG windowposchanged_received
, syscommand_received
;
2756 static IDirect3DDevice8
*focus_test_device
;
2758 struct wndproc_thread_param
2761 HANDLE window_created
;
2762 HANDLE test_finished
;
2763 BOOL running_in_foreground
;
2766 static LRESULT CALLBACK
test_proc(HWND hwnd
, UINT message
, WPARAM wparam
, LPARAM lparam
)
2770 if (filter_messages
&& filter_messages
== hwnd
)
2772 if (message
!= WM_DISPLAYCHANGE
&& message
!= WM_IME_NOTIFY
)
2773 todo_wine
ok(0, "Received unexpected message %#x for window %p.\n", message
, hwnd
);
2776 if (expect_messages
)
2780 switch (expect_messages
->window
)
2795 if (hwnd
== w
&& expect_messages
->message
== message
)
2797 if (expect_messages
->check_wparam
)
2798 ok(wparam
== expect_messages
->expect_wparam
,
2799 "Got unexpected wparam %#Ix for message %#x, expected %#Ix.\n",
2800 wparam
, message
, expect_messages
->expect_wparam
);
2802 if (expect_messages
->store_wp
)
2803 *expect_messages
->store_wp
= *(WINDOWPOS
*)lparam
;
2805 if (focus_test_device
)
2807 hr
= IDirect3DDevice8_TestCooperativeLevel(focus_test_device
);
2808 /* Wined3d marks the device lost earlier than Windows (it follows ddraw
2809 * behavior. See test_wndproc before the focus_loss_messages sequence
2810 * about the D3DERR_DEVICENOTRESET behavior, */
2811 todo_wine_if(message
!= WM_ACTIVATEAPP
|| hr
== D3D_OK
)
2812 ok(hr
== expect_messages
->device_state
,
2813 "Got device state %#lx on message %#x, expected %#lx.\n",
2814 hr
, message
, expect_messages
->device_state
);
2821 /* KDE randomly does something with the hidden window during the
2822 * mode change that sometimes generates a WM_WINDOWPOSCHANGING
2823 * message. A WM_WINDOWPOSCHANGED message is not generated, so
2824 * just flag WM_WINDOWPOSCHANGED as bad. */
2825 if (message
== WM_WINDOWPOSCHANGED
)
2826 InterlockedIncrement(&windowposchanged_received
);
2827 else if (message
== WM_SYSCOMMAND
)
2828 InterlockedIncrement(&syscommand_received
);
2830 return DefWindowProcA(hwnd
, message
, wparam
, lparam
);
2833 static DWORD WINAPI
wndproc_thread(void *param
)
2835 struct wndproc_thread_param
*p
= param
;
2839 p
->dummy_window
= CreateWindowA("d3d8_test_wndproc_wc", "d3d8_test",
2840 WS_MAXIMIZE
| WS_VISIBLE
| WS_CAPTION
, 0, 0, registry_mode
.dmPelsWidth
,
2841 registry_mode
.dmPelsHeight
, 0, 0, 0, 0);
2842 p
->running_in_foreground
= SetForegroundWindow(p
->dummy_window
);
2844 ret
= SetEvent(p
->window_created
);
2845 ok(ret
, "SetEvent failed, last error %#lx.\n", GetLastError());
2851 while (PeekMessageA(&msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessageA(&msg
);
2852 res
= WaitForSingleObject(p
->test_finished
, 100);
2853 if (res
== WAIT_OBJECT_0
) break;
2854 if (res
!= WAIT_TIMEOUT
)
2856 ok(0, "Wait failed (%#lx), last error %#lx.\n", res
, GetLastError());
2861 DestroyWindow(p
->dummy_window
);
2866 static void test_wndproc(void)
2868 unsigned int adapter_mode_count
, i
, d3d_width
= 0, d3d_height
= 0, user32_width
= 0, user32_height
= 0;
2869 struct wndproc_thread_param thread_params
;
2870 struct device_desc device_desc
;
2871 static WINDOWPOS windowpos
;
2872 IDirect3DDevice8
*device
;
2881 D3DDISPLAYMODE d3ddm
;
2883 LONG change_ret
, device_style
;
2886 static const struct message create_messages
[] =
2888 {WM_WINDOWPOSCHANGING
, FOCUS_WINDOW
, FALSE
, 0},
2889 /* Do not test wparam here. If device creation succeeds,
2890 * wparam is WA_ACTIVE. If device creation fails (testbot)
2891 * wparam is set to WA_INACTIVE on some Windows versions. */
2892 {WM_ACTIVATE
, FOCUS_WINDOW
, FALSE
, 0},
2893 {WM_SETFOCUS
, FOCUS_WINDOW
, FALSE
, 0},
2894 {WM_WINDOWPOSCHANGING
, DEVICE_WINDOW
, FALSE
, 0},
2895 {WM_MOVE
, DEVICE_WINDOW
, FALSE
, 0},
2896 {WM_SIZE
, DEVICE_WINDOW
, FALSE
, 0},
2899 static const struct message focus_loss_messages
[] =
2901 /* WM_ACTIVATE (wparam = WA_INACTIVE) is sent on Windows. It is
2902 * not reliable on X11 WMs. When the window focus follows the
2903 * mouse pointer the message is not sent.
2904 * {WM_ACTIVATE, FOCUS_WINDOW, TRUE, WA_INACTIVE}, */
2905 {WM_DISPLAYCHANGE
, DEVICE_WINDOW
, FALSE
, 0, D3DERR_DEVICENOTRESET
},
2906 /* WM_DISPLAYCHANGE is sent to the focus window too, but the order is
2907 * not deterministic. */
2908 {WM_WINDOWPOSCHANGING
, DEVICE_WINDOW
, FALSE
, 0, D3DERR_DEVICENOTRESET
},
2909 /* Windows sends WM_ACTIVATE to the device window, indicating that
2910 * SW_SHOWMINIMIZED is used instead of SW_MINIMIZE. Yet afterwards
2911 * the foreground and focus window are NULL. On Wine SW_SHOWMINIMIZED
2912 * leaves the device window active, breaking re-activation in the
2914 * {WM_ACTIVATE, DEVICE_WINDOW, TRUE, 0x200000 | WA_ACTIVE}, */
2915 {WM_WINDOWPOSCHANGED
, DEVICE_WINDOW
, FALSE
, 0, D3DERR_DEVICENOTRESET
},
2916 {WM_SIZE
, DEVICE_WINDOW
, TRUE
, SIZE_MINIMIZED
,
2917 D3DERR_DEVICENOTRESET
},
2918 {WM_ACTIVATEAPP
, FOCUS_WINDOW
, TRUE
, FALSE
, D3DERR_DEVICELOST
},
2919 /* WM_ACTIVATEAPP is sent to the device window too, but the order is
2920 * not deterministic. It may be sent after the focus window handling
2922 {0, 0, FALSE
, 0, 0},
2924 static const struct message reactivate_messages
[] =
2926 {WM_WINDOWPOSCHANGING
, DEVICE_WINDOW
, FALSE
, 0},
2927 {WM_WINDOWPOSCHANGED
, DEVICE_WINDOW
, FALSE
, 0},
2928 {WM_ACTIVATEAPP
, FOCUS_WINDOW
, TRUE
, TRUE
},
2931 static const struct message focus_loss_messages_hidden
[] =
2933 {WM_DISPLAYCHANGE
, DEVICE_WINDOW
, FALSE
, 0},
2934 {WM_ACTIVATEAPP
, FOCUS_WINDOW
, TRUE
, FALSE
},
2937 static const struct message focus_loss_messages_filtered
[] =
2939 /* WM_ACTIVATE is delivered to the window proc because it is
2940 * generated by SetForegroundWindow before the d3d routine
2941 * starts it work. Don't check for it due to focus-follows-mouse
2943 {WM_DISPLAYCHANGE
, FOCUS_WINDOW
, FALSE
, 0},
2944 {WM_ACTIVATEAPP
, FOCUS_WINDOW
, TRUE
, FALSE
},
2947 static const struct message reactivate_messages_filtered
[] =
2949 {WM_ACTIVATEAPP
, FOCUS_WINDOW
, TRUE
, TRUE
},
2952 static const struct message sc_restore_messages
[] =
2954 /* WM_SYSCOMMAND is delivered only once, after d3d has already
2955 * processed it. Our wndproc has no way to prevent d3d from
2956 * handling the message. The second DefWindowProc call done by
2957 * our wndproc doesn't do any changes to the window because it
2958 * is already restored due to d3d's handling. */
2959 {WM_WINDOWPOSCHANGING
, FOCUS_WINDOW
, FALSE
, 0},
2960 {WM_WINDOWPOSCHANGED
, FOCUS_WINDOW
, FALSE
, 0},
2961 {WM_SIZE
, FOCUS_WINDOW
, TRUE
, SIZE_RESTORED
},
2962 {WM_SYSCOMMAND
, FOCUS_WINDOW
, TRUE
, SC_RESTORE
},
2965 static const struct message sc_minimize_messages
[] =
2967 {WM_SYSCOMMAND
, FOCUS_WINDOW
, TRUE
, SC_MINIMIZE
},
2968 {WM_WINDOWPOSCHANGING
, FOCUS_WINDOW
, FALSE
, 0},
2969 {WM_WINDOWPOSCHANGED
, FOCUS_WINDOW
, FALSE
, 0},
2970 {WM_MOVE
, FOCUS_WINDOW
, FALSE
, 0},
2971 {WM_SIZE
, FOCUS_WINDOW
, TRUE
, SIZE_MINIMIZED
},
2974 static const struct message sc_maximize_messages
[] =
2976 {WM_SYSCOMMAND
, FOCUS_WINDOW
, TRUE
, SC_MAXIMIZE
},
2977 {WM_WINDOWPOSCHANGING
, FOCUS_WINDOW
, FALSE
, 0},
2978 {WM_WINDOWPOSCHANGED
, FOCUS_WINDOW
, FALSE
, 0},
2979 /* Windows always sends WM_MOVE here.
2981 * In the first case, we are maximizing from a minimized state, and
2982 * hence the client rect moves from the minimized position to (0, 0).
2984 * In the second case, we are maximizing from an on-screen restored
2985 * state. The window is at (0, 0), but it has a caption, so the client
2986 * rect is offset, and the *client* will move to (0, 0) when maximized.
2988 * Wine doesn't send WM_MOVE here because it messes with the window
2989 * styles when switching to fullscreen, and hence the client rect is
2990 * already at (0, 0). Obviously Wine shouldn't do this, but it's hard to
2991 * fix, and the WM_MOVE is not particularly interesting, so just ignore
2993 {WM_SIZE
, FOCUS_WINDOW
, TRUE
, SIZE_MAXIMIZED
},
2996 static const struct message mode_change_messages
[] =
2998 {WM_WINDOWPOSCHANGING
, DEVICE_WINDOW
, FALSE
, 0},
2999 {WM_WINDOWPOSCHANGED
, DEVICE_WINDOW
, FALSE
, 0},
3000 {WM_SIZE
, DEVICE_WINDOW
, FALSE
, 0},
3001 /* TODO: WM_DISPLAYCHANGE is sent to the focus window too, but the order is
3002 * differs between Wine and Windows. */
3003 /* TODO 2: Windows sends a second WM_WINDOWPOSCHANGING(SWP_NOMOVE | SWP_NOSIZE
3004 * | SWP_NOACTIVATE) in this situation, suggesting a difference in their ShowWindow
3005 * implementation. This SetWindowPos call could in theory affect the Z order. Wine's
3006 * ShowWindow does not send such a message because the window is already visible. */
3009 static const struct message mode_change_messages_hidden
[] =
3011 {WM_WINDOWPOSCHANGING
, DEVICE_WINDOW
, FALSE
, 0},
3012 {WM_WINDOWPOSCHANGED
, DEVICE_WINDOW
, FALSE
, 0},
3013 {WM_SIZE
, DEVICE_WINDOW
, FALSE
, 0},
3014 {WM_SHOWWINDOW
, DEVICE_WINDOW
, FALSE
, 0},
3015 {WM_WINDOWPOSCHANGING
, DEVICE_WINDOW
, FALSE
, 0, ~0U, &windowpos
},
3016 {WM_WINDOWPOSCHANGED
, DEVICE_WINDOW
, FALSE
, 0},
3017 /* TODO: WM_DISPLAYCHANGE is sent to the focus window too, but the order is
3018 * differs between Wine and Windows. */
3022 d3d8
= Direct3DCreate8(D3D_SDK_VERSION
);
3023 ok(!!d3d8
, "Failed to create a D3D object.\n");
3025 adapter_mode_count
= IDirect3D8_GetAdapterModeCount(d3d8
, D3DADAPTER_DEFAULT
);
3026 for (i
= 0; i
< adapter_mode_count
; ++i
)
3028 hr
= IDirect3D8_EnumAdapterModes(d3d8
, D3DADAPTER_DEFAULT
, i
, &d3ddm
);
3029 ok(SUCCEEDED(hr
), "Failed to enumerate display mode, hr %#lx.\n", hr
);
3031 if (d3ddm
.Format
!= D3DFMT_X8R8G8B8
)
3033 if (d3ddm
.Width
== registry_mode
.dmPelsWidth
&& d3ddm
.Height
== registry_mode
.dmPelsHeight
)
3035 /* The r200 driver on Windows XP enumerates modes like 320x200 and 320x240 but
3036 * refuses to create a device at these sizes. */
3037 if (d3ddm
.Width
< 640 || d3ddm
.Height
< 480)
3042 user32_width
= d3ddm
.Width
;
3043 user32_height
= d3ddm
.Height
;
3047 /* Make sure the d3d mode is smaller in width or height and at most
3048 * equal in the other dimension than the mode passed to
3049 * ChangeDisplaySettings. Otherwise Windows shrinks the window to
3050 * the ChangeDisplaySettings parameters + 12. */
3051 if (d3ddm
.Width
== user32_width
&& d3ddm
.Height
== user32_height
)
3053 if (d3ddm
.Width
<= user32_width
&& d3ddm
.Height
<= user32_height
)
3055 d3d_width
= d3ddm
.Width
;
3056 d3d_height
= d3ddm
.Height
;
3059 if (user32_width
<= d3ddm
.Width
&& user32_height
<= d3ddm
.Height
)
3061 d3d_width
= user32_width
;
3062 d3d_height
= user32_height
;
3063 user32_width
= d3ddm
.Width
;
3064 user32_height
= d3ddm
.Height
;
3071 skip("Could not find adequate modes, skipping mode tests.\n");
3072 IDirect3D8_Release(d3d8
);
3076 filter_messages
= NULL
;
3077 expect_messages
= NULL
;
3079 wc
.lpfnWndProc
= test_proc
;
3080 wc
.lpszClassName
= "d3d8_test_wndproc_wc";
3081 ok(RegisterClassA(&wc
), "Failed to register window class.\n");
3083 thread_params
.window_created
= CreateEventA(NULL
, FALSE
, FALSE
, NULL
);
3084 ok(!!thread_params
.window_created
, "CreateEvent failed, last error %#lx.\n", GetLastError());
3085 thread_params
.test_finished
= CreateEventA(NULL
, FALSE
, FALSE
, NULL
);
3086 ok(!!thread_params
.test_finished
, "CreateEvent failed, last error %#lx.\n", GetLastError());
3088 memset(&devmode
, 0, sizeof(devmode
));
3089 devmode
.dmSize
= sizeof(devmode
);
3090 devmode
.dmFields
= DM_PELSWIDTH
| DM_PELSHEIGHT
;
3091 devmode
.dmPelsWidth
= user32_width
;
3092 devmode
.dmPelsHeight
= user32_height
;
3093 change_ret
= ChangeDisplaySettingsW(&devmode
, CDS_FULLSCREEN
);
3094 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "Failed to change display mode, ret %#lx.\n", change_ret
);
3096 focus_window
= CreateWindowA("d3d8_test_wndproc_wc", "d3d8_test",
3097 WS_MAXIMIZE
| WS_VISIBLE
| WS_CAPTION
, 0, 0, user32_width
, user32_height
, 0, 0, 0, 0);
3098 device_window
= CreateWindowA("d3d8_test_wndproc_wc", "d3d8_test",
3099 WS_MAXIMIZE
| WS_VISIBLE
| WS_CAPTION
, 0, 0, user32_width
, user32_height
, 0, 0, 0, 0);
3100 thread
= CreateThread(NULL
, 0, wndproc_thread
, &thread_params
, 0, &tid
);
3101 ok(!!thread
, "Failed to create thread, last error %#lx.\n", GetLastError());
3103 res
= WaitForSingleObject(thread_params
.window_created
, INFINITE
);
3104 ok(res
== WAIT_OBJECT_0
, "Wait failed (%#lx), last error %#lx.\n", res
, GetLastError());
3106 proc
= GetWindowLongPtrA(device_window
, GWLP_WNDPROC
);
3107 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#Ix, got %#Ix.\n",
3108 (LONG_PTR
)test_proc
, proc
);
3109 proc
= GetWindowLongPtrA(focus_window
, GWLP_WNDPROC
);
3110 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#Ix, got %#Ix.\n",
3111 (LONG_PTR
)test_proc
, proc
);
3113 trace("device_window %p, focus_window %p, dummy_window %p.\n",
3114 device_window
, focus_window
, thread_params
.dummy_window
);
3117 ok(tmp
== device_window
, "Expected focus %p, got %p.\n", device_window
, tmp
);
3118 if (thread_params
.running_in_foreground
)
3120 tmp
= GetForegroundWindow();
3121 ok(tmp
== thread_params
.dummy_window
, "Expected foreground window %p, got %p.\n",
3122 thread_params
.dummy_window
, tmp
);
3125 skip("Not running in foreground, skip foreground window test\n");
3129 expect_messages
= create_messages
;
3131 device_desc
.adapter_ordinal
= D3DADAPTER_DEFAULT
;
3132 device_desc
.device_window
= device_window
;
3133 device_desc
.width
= d3d_width
;
3134 device_desc
.height
= d3d_height
;
3135 device_desc
.flags
= CREATE_DEVICE_FULLSCREEN
;
3136 if (!(device
= create_device(d3d8
, focus_window
, &device_desc
)))
3138 skip("Failed to create a D3D device, skipping tests.\n");
3142 ok(!expect_messages
->message
, "Expected message %#x for window %#x, but didn't receive it.\n",
3143 expect_messages
->message
, expect_messages
->window
);
3144 expect_messages
= NULL
;
3146 if (0) /* Disabled until we can make this work in a reliable way on Wine. */
3149 ok(tmp
== focus_window
, "Expected focus %p, got %p.\n", focus_window
, tmp
);
3150 tmp
= GetForegroundWindow();
3151 ok(tmp
== focus_window
, "Expected foreground window %p, got %p.\n", focus_window
, tmp
);
3153 SetForegroundWindow(focus_window
);
3156 proc
= GetWindowLongPtrA(device_window
, GWLP_WNDPROC
);
3157 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#Ix, got %#Ix.\n",
3158 (LONG_PTR
)test_proc
, proc
);
3160 proc
= GetWindowLongPtrA(focus_window
, GWLP_WNDPROC
);
3161 ok(proc
!= (LONG_PTR
)test_proc
, "Expected wndproc != %#Ix.\n", (LONG_PTR
)test_proc
);
3163 /* Change the mode while the device is in use and then drop focus. */
3164 devmode
.dmFields
= DM_PELSWIDTH
| DM_PELSHEIGHT
;
3165 devmode
.dmPelsWidth
= user32_width
;
3166 devmode
.dmPelsHeight
= user32_height
;
3167 change_ret
= ChangeDisplaySettingsW(&devmode
, CDS_FULLSCREEN
);
3168 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "Failed to change display mode, ret %#lx, i=%u.\n", change_ret
, i
);
3170 /* Wine doesn't (yet) mark the device not reset when the mode is changed, thus the todo_wine.
3171 * But sometimes focus-follows-mouse WMs also temporarily drop window focus, which makes
3172 * mark the device lost, then not reset, causing the test to succeed for the wrong reason. */
3173 hr
= IDirect3DDevice8_TestCooperativeLevel(device
);
3174 todo_wine_if (hr
!= D3DERR_DEVICENOTRESET
)
3175 ok(hr
== D3DERR_DEVICENOTRESET
, "Got unexpected hr %#lx.\n", hr
);
3177 expect_messages
= focus_loss_messages
;
3178 focus_test_device
= device
;
3179 /* SetForegroundWindow is a poor replacement for the user pressing alt-tab or
3180 * manually changing the focus. It generates the same messages, but the task
3181 * bar still shows the previous foreground window as active, and the window has
3182 * an inactive titlebar if reactivated with SetForegroundWindow. Reactivating
3183 * the device is difficult, see below. */
3184 SetForegroundWindow(GetDesktopWindow());
3185 ok(!expect_messages
->message
, "Expected message %#x for window %#x, but didn't receive it.\n",
3186 expect_messages
->message
, expect_messages
->window
);
3187 expect_messages
= NULL
;
3189 ok(tmp
!= device_window
, "The device window is active.\n");
3190 ok(tmp
!= focus_window
, "The focus window is active.\n");
3191 focus_test_device
= NULL
;
3193 /* The Present call is necessary to make native realize the device is lost. */
3194 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
3195 ok(hr
== D3DERR_DEVICELOST
, "Got unexpected hr %#lx.\n", hr
);
3196 hr
= IDirect3DDevice8_TestCooperativeLevel(device
);
3197 /* Focus-follows-mouse WMs prematurely reactivate our window. */
3198 todo_wine_if (hr
== D3DERR_DEVICENOTRESET
)
3199 ok(hr
== D3DERR_DEVICELOST
, "Got unexpected hr %#lx.\n", hr
);
3201 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode
);
3202 ok(ret
, "Failed to get display mode.\n");
3203 ok(devmode
.dmPelsWidth
== registry_mode
.dmPelsWidth
3204 && devmode
.dmPelsHeight
== registry_mode
.dmPelsHeight
, "Got unexpected screen size %lux%lu.\n",
3205 devmode
.dmPelsWidth
, devmode
.dmPelsHeight
);
3207 /* I have to minimize and restore the focus window, otherwise native d3d8 fails
3208 * device::reset with D3DERR_DEVICELOST. This does not happen when the window
3209 * restore is triggered by the user.
3211 * fvwm randomly sends a focus loss notification when we minimize, so do it
3212 * before checking the incoming messages. It might match WM_ACTIVATEAPP but has
3213 * a wrong WPARAM. Use SW_SHOWMINNOACTIVE to make sure we don't accidentally
3214 * activate the window at this point and miss our WM_ACTIVATEAPP(wparam=1). */
3215 ShowWindow(focus_window
, SW_SHOWMINNOACTIVE
);
3217 expect_messages
= reactivate_messages
;
3218 ShowWindow(focus_window
, SW_RESTORE
);
3219 /* Set focus twice to make KDE and fvwm in focus-follows-mouse mode happy. */
3220 SetForegroundWindow(focus_window
);
3222 SetForegroundWindow(focus_window
);
3223 flush_events(); /* WM_WINDOWPOSCHANGING etc arrive after SetForegroundWindow returns. */
3224 ok(!expect_messages
->message
, "Expected message %#x for window %#x, but didn't receive it, i=%u.\n",
3225 expect_messages
->message
, expect_messages
->window
, i
);
3226 expect_messages
= NULL
;
3228 hr
= IDirect3DDevice8_TestCooperativeLevel(device
);
3229 ok(hr
== D3DERR_DEVICENOTRESET
, "Got unexpected hr %#lx.\n", hr
);
3231 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode
);
3232 ok(ret
, "Failed to get display mode.\n");
3233 ok(devmode
.dmPelsWidth
== registry_mode
.dmPelsWidth
3234 && devmode
.dmPelsHeight
== registry_mode
.dmPelsHeight
, "Got unexpected screen size %lux%lu.\n",
3235 devmode
.dmPelsWidth
, devmode
.dmPelsHeight
);
3237 hr
= reset_device(device
, &device_desc
);
3238 ok(SUCCEEDED(hr
), "Failed to reset device, hr %#lx.\n", hr
);
3240 /* Remove the WS_VISIBLE flag to test hidden windows. This is enough to trigger d3d's hidden
3241 * window codepath, but does not actually hide the window without a SetWindowPos(SWP_FRAMECHANGED)
3242 * call. This way we avoid focus changes and random failures on focus follows mouse WMs. */
3243 device_style
= GetWindowLongA(device_window
, GWL_STYLE
);
3244 SetWindowLongA(device_window
, GWL_STYLE
, device_style
& ~WS_VISIBLE
);
3247 expect_messages
= focus_loss_messages_hidden
;
3248 windowposchanged_received
= 0;
3249 SetForegroundWindow(GetDesktopWindow());
3250 ok(!expect_messages
->message
, "Expected message %#x for window %#x, but didn't receive it.\n",
3251 expect_messages
->message
, expect_messages
->window
);
3253 /* kwin sometimes resizes hidden windows. The d3d8 version of this test has been reliable on
3254 * Windows so far, but the d3d9 equivalent rarely fails since Windows 8. */
3256 ok(!windowposchanged_received
, "Received WM_WINDOWPOSCHANGED but did not expect it.\n");
3258 expect_messages
= NULL
;
3261 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode
);
3262 ok(ret
, "Failed to get display mode.\n");
3263 ok(devmode
.dmPelsWidth
== registry_mode
.dmPelsWidth
, "Got unexpected width %lu.\n", devmode
.dmPelsWidth
);
3264 ok(devmode
.dmPelsHeight
== registry_mode
.dmPelsHeight
, "Got unexpected height %lu.\n", devmode
.dmPelsHeight
);
3266 /* SW_SHOWMINNOACTIVE is needed to make FVWM happy. SW_SHOWNOACTIVATE is needed to make windows
3267 * send SIZE_RESTORED after ShowWindow(SW_SHOWMINNOACTIVE). */
3268 ShowWindow(focus_window
, SW_SHOWNOACTIVATE
);
3269 ShowWindow(focus_window
, SW_SHOWMINNOACTIVE
);
3272 syscommand_received
= 0;
3273 expect_messages
= sc_restore_messages
;
3274 SendMessageA(focus_window
, WM_SYSCOMMAND
, SC_RESTORE
, 0);
3275 ok(!expect_messages
->message
, "Expected message %#x for window %#x, but didn't receive it.\n",
3276 expect_messages
->message
, expect_messages
->window
);
3277 ok(syscommand_received
== 1, "Got %lu WM_SYSCOMMAND messages.\n", syscommand_received
);
3278 expect_messages
= NULL
;
3281 expect_messages
= sc_minimize_messages
;
3282 SendMessageA(focus_window
, WM_SYSCOMMAND
, SC_MINIMIZE
, 0);
3283 ok(!expect_messages
->message
, "Expected message %#x for window %#x, but didn't receive it.\n",
3284 expect_messages
->message
, expect_messages
->window
);
3285 expect_messages
= NULL
;
3288 expect_messages
= sc_maximize_messages
;
3289 SendMessageA(focus_window
, WM_SYSCOMMAND
, SC_MAXIMIZE
, 0);
3290 ok(!expect_messages
->message
, "Expected message %#x for window %#x, but didn't receive it.\n",
3291 expect_messages
->message
, expect_messages
->window
);
3292 expect_messages
= NULL
;
3295 SetForegroundWindow(GetDesktopWindow());
3296 ShowWindow(device_window
, SW_MINIMIZE
);
3297 ShowWindow(focus_window
, SW_MINIMIZE
);
3298 ShowWindow(focus_window
, SW_RESTORE
);
3299 SetForegroundWindow(focus_window
);
3302 /* Releasing a device in lost state breaks follow-up tests on native. */
3303 hr
= reset_device(device
, &device_desc
);
3304 ok(SUCCEEDED(hr
), "Failed to reset device, hr %#lx.\n", hr
);
3306 filter_messages
= focus_window
;
3307 ref
= IDirect3DDevice8_Release(device
);
3308 ok(!ref
, "Got unexpected refcount %lu.\n", ref
);
3310 /* Fix up the mode until Wine's device release behavior is fixed. */
3311 change_ret
= ChangeDisplaySettingsW(NULL
, CDS_FULLSCREEN
);
3312 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "Failed to change display mode, ret %#lx.\n", change_ret
);
3314 proc
= GetWindowLongPtrA(focus_window
, GWLP_WNDPROC
);
3315 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#Ix, got %#Ix.\n",
3316 (LONG_PTR
)test_proc
, proc
);
3318 /* Hide the device window. It prevents WM_ACTIVATEAPP messages from being sent
3319 * on native in the test below. It isn't needed anyways. Creating the third
3320 * device will show it again. */
3321 filter_messages
= NULL
;
3322 ShowWindow(device_window
, SW_HIDE
);
3323 /* Remove the maximized state from the SYSCOMMAND test while we're not
3324 * interfering with a device. */
3325 ShowWindow(focus_window
, SW_SHOWNORMAL
);
3327 /* On Windows 10 style change messages are delivered on device
3329 device_desc
.device_window
= focus_window
;
3330 if (!(device
= create_device(d3d8
, focus_window
, &device_desc
)))
3332 skip("Failed to create a D3D device, skipping tests.\n");
3335 SetForegroundWindow(focus_window
); /* make sure that the window has focus */
3337 filter_messages
= NULL
;
3339 expect_messages
= focus_loss_messages_filtered
;
3340 windowposchanged_received
= 0;
3341 SetForegroundWindow(GetDesktopWindow());
3342 ok(!expect_messages
->message
, "Expected message %#x for window %#x, but didn't receive it.\n",
3343 expect_messages
->message
, expect_messages
->window
);
3344 expect_messages
= NULL
;
3346 /* The window is iconic even though no message was sent. */
3347 ok(IsIconic(focus_window
), "The focus window is not iconic.\n");
3349 hr
= IDirect3DDevice8_TestCooperativeLevel(device
);
3350 ok(hr
== D3DERR_DEVICELOST
, "Got unexpected hr %#lx.\n", hr
);
3352 syscommand_received
= 0;
3353 expect_messages
= sc_restore_messages
;
3354 SendMessageA(focus_window
, WM_SYSCOMMAND
, SC_RESTORE
, 0);
3355 ok(!expect_messages
->message
, "Expected message %#x for window %#x, but didn't receive it.\n",
3356 expect_messages
->message
, expect_messages
->window
);
3357 ok(syscommand_received
== 1, "Got %lu WM_SYSCOMMAND messages.\n", syscommand_received
);
3358 expect_messages
= NULL
;
3362 ShowWindow(focus_window
, SW_RESTORE
);
3365 expect_messages
= sc_minimize_messages
;
3366 SendMessageA(focus_window
, WM_SYSCOMMAND
, SC_MINIMIZE
, 0);
3367 ok(!expect_messages
->message
, "Expected message %#x for window %#x, but didn't receive it.\n",
3368 expect_messages
->message
, expect_messages
->window
);
3369 expect_messages
= NULL
;
3370 /* Needed to make the next test reliably send WM_SIZE(SIZE_MAXIMIZED). Without
3371 * this call it sends WM_SIZE(SIZE_RESTORED). */
3372 ShowWindow(focus_window
, SW_RESTORE
);
3375 expect_messages
= sc_maximize_messages
;
3376 SendMessageA(focus_window
, WM_SYSCOMMAND
, SC_MAXIMIZE
, 0);
3377 ok(!expect_messages
->message
, "Expected message %#x for window %#x, but didn't receive it.\n",
3378 expect_messages
->message
, expect_messages
->window
);
3379 expect_messages
= NULL
;
3381 SetForegroundWindow(GetDesktopWindow());
3384 /* ShowWindow(SW_RESTORE); SetForegroundWindow(desktop); SetForegroundWindow(focus);
3385 * results in the second SetForegroundWindow call failing and the device not being
3386 * restored on native. Directly using ShowWindow(SW_RESTORE) works, but it means
3387 * we cannot test for the absence of WM_WINDOWPOSCHANGED messages. */
3388 expect_messages
= reactivate_messages_filtered
;
3389 ShowWindow(focus_window
, SW_RESTORE
);
3390 SetForegroundWindow(focus_window
);
3392 ok(!expect_messages
->message
, "Expected message %#x for window %#x, but didn't receive it\n",
3393 expect_messages
->message
, expect_messages
->window
);
3394 expect_messages
= NULL
;
3396 filter_messages
= focus_window
;
3397 hr
= IDirect3DDevice8_TestCooperativeLevel(device
);
3398 ok(hr
== D3DERR_DEVICENOTRESET
, "Got unexpected hr %#lx.\n", hr
);
3400 filter_messages
= NULL
;
3401 hr
= reset_device(device
, &device_desc
);
3402 ok(SUCCEEDED(hr
), "Failed to reset device, hr %#lx.\n", hr
);
3404 ref
= IDirect3DDevice8_Release(device
);
3405 ok(!ref
, "Got unexpected refcount %lu.\n", ref
);
3406 filter_messages
= NULL
;
3408 ShowWindow(device_window
, SW_RESTORE
);
3409 SetForegroundWindow(focus_window
);
3412 filter_messages
= focus_window
;
3413 device_desc
.device_window
= device_window
;
3414 if (!(device
= create_device(d3d8
, focus_window
, &device_desc
)))
3416 skip("Failed to create a D3D device, skipping tests.\n");
3419 filter_messages
= NULL
;
3422 device_desc
.width
= user32_width
;
3423 device_desc
.height
= user32_height
;
3425 expect_messages
= mode_change_messages
;
3426 filter_messages
= focus_window
;
3427 hr
= reset_device(device
, &device_desc
);
3428 ok(SUCCEEDED(hr
), "Failed to reset device, hr %#lx.\n", hr
);
3429 filter_messages
= NULL
;
3432 ok(!expect_messages
->message
, "Expected message %#x for window %#x, but didn't receive it, i=%u.\n",
3433 expect_messages
->message
, expect_messages
->window
, i
);
3434 expect_messages
= NULL
;
3436 /* World of Warplanes hides the window by removing WS_VISIBLE and expects Reset() to show it again. */
3437 device_style
= GetWindowLongA(device_window
, GWL_STYLE
);
3438 SetWindowLongA(device_window
, GWL_STYLE
, device_style
& ~WS_VISIBLE
);
3441 device_desc
.width
= d3d_width
;
3442 device_desc
.height
= d3d_height
;
3443 memset(&windowpos
, 0, sizeof(windowpos
));
3445 expect_messages
= mode_change_messages_hidden
;
3446 filter_messages
= focus_window
;
3447 hr
= reset_device(device
, &device_desc
);
3448 ok(SUCCEEDED(hr
), "Failed to reset device, hr %#lx.\n", hr
);
3449 filter_messages
= NULL
;
3452 ok(!expect_messages
->message
, "Expected message %#x for window %#x, but didn't receive it.\n",
3453 expect_messages
->message
, expect_messages
->window
);
3454 expect_messages
= NULL
;
3456 ok(windowpos
.hwnd
== device_window
&& !windowpos
.hwndInsertAfter
3457 && !windowpos
.x
&& !windowpos
.y
&& !windowpos
.cx
&& !windowpos
.cy
3458 && windowpos
.flags
== (SWP_SHOWWINDOW
| SWP_NOMOVE
| SWP_NOSIZE
),
3459 "Got unexpected WINDOWPOS hwnd=%p, insertAfter=%p, x=%d, y=%d, cx=%d, cy=%d, flags=%x\n",
3460 windowpos
.hwnd
, windowpos
.hwndInsertAfter
, windowpos
.x
, windowpos
.y
, windowpos
.cx
,
3461 windowpos
.cy
, windowpos
.flags
);
3463 device_style
= GetWindowLongA(device_window
, GWL_STYLE
);
3464 ok(device_style
& WS_VISIBLE
, "Expected the device window to be visible.\n");
3466 proc
= SetWindowLongPtrA(focus_window
, GWLP_WNDPROC
, (LONG_PTR
)DefWindowProcA
);
3467 ok(proc
!= (LONG_PTR
)test_proc
, "Expected wndproc != %#Ix.\n", (LONG_PTR
)test_proc
);
3469 ref
= IDirect3DDevice8_Release(device
);
3470 ok(!ref
, "Got unexpected refcount %lu.\n", ref
);
3472 proc
= GetWindowLongPtrA(focus_window
, GWLP_WNDPROC
);
3473 ok(proc
== (LONG_PTR
)DefWindowProcA
, "Expected wndproc %#Ix, got %#Ix.\n",
3474 (LONG_PTR
)DefWindowProcA
, proc
);
3477 filter_messages
= NULL
;
3478 expect_messages
= NULL
;
3479 IDirect3D8_Release(d3d8
);
3481 SetEvent(thread_params
.test_finished
);
3482 WaitForSingleObject(thread
, INFINITE
);
3483 CloseHandle(thread_params
.test_finished
);
3484 CloseHandle(thread_params
.window_created
);
3485 CloseHandle(thread
);
3487 DestroyWindow(device_window
);
3488 DestroyWindow(focus_window
);
3489 UnregisterClassA("d3d8_test_wndproc_wc", GetModuleHandleA(NULL
));
3490 change_ret
= ChangeDisplaySettingsExW(NULL
, NULL
, NULL
, 0, NULL
);
3491 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "ChangeDisplaySettingsExW failed with %ld.\n", change_ret
);
3494 static void test_wndproc_windowed(void)
3496 struct wndproc_thread_param thread_params
;
3497 struct device_desc device_desc
;
3498 IDirect3DDevice8
*device
;
3508 d3d8
= Direct3DCreate8(D3D_SDK_VERSION
);
3509 ok(!!d3d8
, "Failed to create a D3D object.\n");
3511 filter_messages
= NULL
;
3512 expect_messages
= NULL
;
3514 wc
.lpfnWndProc
= test_proc
;
3515 wc
.lpszClassName
= "d3d8_test_wndproc_wc";
3516 ok(RegisterClassA(&wc
), "Failed to register window class.\n");
3518 thread_params
.window_created
= CreateEventA(NULL
, FALSE
, FALSE
, NULL
);
3519 ok(!!thread_params
.window_created
, "CreateEvent failed, last error %#lx.\n", GetLastError());
3520 thread_params
.test_finished
= CreateEventA(NULL
, FALSE
, FALSE
, NULL
);
3521 ok(!!thread_params
.test_finished
, "CreateEvent failed, last error %#lx.\n", GetLastError());
3523 focus_window
= CreateWindowA("d3d8_test_wndproc_wc", "d3d8_test",
3524 WS_MAXIMIZE
| WS_VISIBLE
| WS_CAPTION
, 0, 0, registry_mode
.dmPelsWidth
,
3525 registry_mode
.dmPelsHeight
, 0, 0, 0, 0);
3526 device_window
= CreateWindowA("d3d8_test_wndproc_wc", "d3d8_test",
3527 WS_MAXIMIZE
| WS_VISIBLE
| WS_CAPTION
, 0, 0, registry_mode
.dmPelsWidth
,
3528 registry_mode
.dmPelsHeight
, 0, 0, 0, 0);
3529 thread
= CreateThread(NULL
, 0, wndproc_thread
, &thread_params
, 0, &tid
);
3530 ok(!!thread
, "Failed to create thread, last error %#lx.\n", GetLastError());
3532 res
= WaitForSingleObject(thread_params
.window_created
, INFINITE
);
3533 ok(res
== WAIT_OBJECT_0
, "Wait failed (%#lx), last error %#lx.\n", res
, GetLastError());
3535 proc
= GetWindowLongPtrA(device_window
, GWLP_WNDPROC
);
3536 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#Ix, got %#Ix.\n",
3537 (LONG_PTR
)test_proc
, proc
);
3538 proc
= GetWindowLongPtrA(focus_window
, GWLP_WNDPROC
);
3539 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#Ix, got %#Ix.\n",
3540 (LONG_PTR
)test_proc
, proc
);
3542 trace("device_window %p, focus_window %p, dummy_window %p.\n",
3543 device_window
, focus_window
, thread_params
.dummy_window
);
3546 ok(tmp
== device_window
, "Expected focus %p, got %p.\n", device_window
, tmp
);
3547 if (thread_params
.running_in_foreground
)
3549 tmp
= GetForegroundWindow();
3550 ok(tmp
== thread_params
.dummy_window
, "Expected foreground window %p, got %p.\n",
3551 thread_params
.dummy_window
, tmp
);
3554 skip("Not running in foreground, skip foreground window test\n");
3556 filter_messages
= focus_window
;
3558 device_desc
.adapter_ordinal
= D3DADAPTER_DEFAULT
;
3559 device_desc
.device_window
= device_window
;
3560 device_desc
.width
= registry_mode
.dmPelsWidth
;
3561 device_desc
.height
= registry_mode
.dmPelsHeight
;
3562 device_desc
.flags
= 0;
3563 if (!(device
= create_device(d3d8
, focus_window
, &device_desc
)))
3565 skip("Failed to create a D3D device, skipping tests.\n");
3570 ok(tmp
== device_window
, "Expected focus %p, got %p.\n", device_window
, tmp
);
3571 tmp
= GetForegroundWindow();
3572 ok(tmp
== thread_params
.dummy_window
, "Expected foreground window %p, got %p.\n",
3573 thread_params
.dummy_window
, tmp
);
3575 proc
= GetWindowLongPtrA(device_window
, GWLP_WNDPROC
);
3576 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#Ix, got %#Ix.\n",
3577 (LONG_PTR
)test_proc
, proc
);
3579 proc
= GetWindowLongPtrA(focus_window
, GWLP_WNDPROC
);
3580 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#Ix, got %#Ix.\n",
3581 (LONG_PTR
)test_proc
, proc
);
3583 filter_messages
= NULL
;
3585 device_desc
.flags
= CREATE_DEVICE_FULLSCREEN
;
3586 hr
= reset_device(device
, &device_desc
);
3587 ok(SUCCEEDED(hr
), "Failed to reset device, hr %#lx.\n", hr
);
3589 proc
= GetWindowLongPtrA(device_window
, GWLP_WNDPROC
);
3590 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#Ix, got %#Ix.\n",
3591 (LONG_PTR
)test_proc
, proc
);
3593 proc
= GetWindowLongPtrA(focus_window
, GWLP_WNDPROC
);
3594 ok(proc
!= (LONG_PTR
)test_proc
, "Expected wndproc != %#Ix.\n", (LONG_PTR
)test_proc
);
3596 device_desc
.flags
= 0;
3597 hr
= reset_device(device
, &device_desc
);
3598 ok(SUCCEEDED(hr
), "Failed to reset device, hr %#lx.\n", hr
);
3600 proc
= GetWindowLongPtrA(device_window
, GWLP_WNDPROC
);
3601 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#Ix, got %#Ix.\n",
3602 (LONG_PTR
)test_proc
, proc
);
3604 proc
= GetWindowLongPtrA(focus_window
, GWLP_WNDPROC
);
3605 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#Ix, got %#Ix.\n",
3606 (LONG_PTR
)test_proc
, proc
);
3608 filter_messages
= focus_window
;
3610 ref
= IDirect3DDevice8_Release(device
);
3611 ok(!ref
, "Got unexpected refcount %lu.\n", ref
);
3613 filter_messages
= device_window
;
3615 device_desc
.device_window
= focus_window
;
3616 if (!(device
= create_device(d3d8
, focus_window
, &device_desc
)))
3618 skip("Failed to create a D3D device, skipping tests.\n");
3622 filter_messages
= NULL
;
3624 device_desc
.flags
= CREATE_DEVICE_FULLSCREEN
;
3625 hr
= reset_device(device
, &device_desc
);
3626 ok(SUCCEEDED(hr
), "Failed to reset device, hr %#lx.\n", hr
);
3628 proc
= GetWindowLongPtrA(device_window
, GWLP_WNDPROC
);
3629 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#Ix, got %#Ix.\n",
3630 (LONG_PTR
)test_proc
, proc
);
3632 proc
= GetWindowLongPtrA(focus_window
, GWLP_WNDPROC
);
3633 ok(proc
!= (LONG_PTR
)test_proc
, "Expected wndproc != %#Ix.\n", (LONG_PTR
)test_proc
);
3635 device_desc
.flags
= 0;
3636 hr
= reset_device(device
, &device_desc
);
3637 ok(SUCCEEDED(hr
), "Failed to reset device, hr %#lx.\n", hr
);
3639 proc
= GetWindowLongPtrA(device_window
, GWLP_WNDPROC
);
3640 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#Ix, got %#Ix.\n",
3641 (LONG_PTR
)test_proc
, proc
);
3643 proc
= GetWindowLongPtrA(focus_window
, GWLP_WNDPROC
);
3644 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#Ix, got %#Ix.\n",
3645 (LONG_PTR
)test_proc
, proc
);
3647 filter_messages
= device_window
;
3649 ref
= IDirect3DDevice8_Release(device
);
3650 ok(!ref
, "Got unexpected refcount %lu.\n", ref
);
3652 device_desc
.device_window
= device_window
;
3653 if (!(device
= create_device(d3d8
, focus_window
, &device_desc
)))
3655 skip("Failed to create a D3D device, skipping tests.\n");
3659 filter_messages
= NULL
;
3661 device_desc
.flags
= CREATE_DEVICE_FULLSCREEN
;
3662 hr
= reset_device(device
, &device_desc
);
3663 ok(SUCCEEDED(hr
), "Failed to reset device, hr %#lx.\n", hr
);
3665 proc
= GetWindowLongPtrA(device_window
, GWLP_WNDPROC
);
3666 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#Ix, got %#Ix.\n",
3667 (LONG_PTR
)test_proc
, proc
);
3669 proc
= GetWindowLongPtrA(focus_window
, GWLP_WNDPROC
);
3670 ok(proc
!= (LONG_PTR
)test_proc
, "Expected wndproc != %#Ix.\n", (LONG_PTR
)test_proc
);
3672 device_desc
.flags
= 0;
3673 hr
= reset_device(device
, &device_desc
);
3674 ok(SUCCEEDED(hr
), "Failed to reset device, hr %#lx.\n", hr
);
3676 proc
= GetWindowLongPtrA(device_window
, GWLP_WNDPROC
);
3677 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#Ix, got %#Ix.\n",
3678 (LONG_PTR
)test_proc
, proc
);
3680 proc
= GetWindowLongPtrA(focus_window
, GWLP_WNDPROC
);
3681 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#Ix, got %#Ix.\n",
3682 (LONG_PTR
)test_proc
, proc
);
3684 filter_messages
= device_window
;
3686 ref
= IDirect3DDevice8_Release(device
);
3687 ok(!ref
, "Got unexpected refcount %lu.\n", ref
);
3690 filter_messages
= NULL
;
3691 IDirect3D8_Release(d3d8
);
3693 SetEvent(thread_params
.test_finished
);
3694 WaitForSingleObject(thread
, INFINITE
);
3695 CloseHandle(thread_params
.test_finished
);
3696 CloseHandle(thread_params
.window_created
);
3697 CloseHandle(thread
);
3699 DestroyWindow(device_window
);
3700 DestroyWindow(focus_window
);
3701 UnregisterClassA("d3d8_test_wndproc_wc", GetModuleHandleA(NULL
));
3704 static const GUID d3d8_private_data_test_guid
=
3709 {0xa3,0x7f,0x9b,0x1d,0xf4,0x88,0xc5,0xfc}
3712 #if defined(__i386__) || (defined(__x86_64__) && !defined(__arm64ec__) && (defined(__GNUC__) || defined(__clang__)))
3714 static inline void set_fpu_cw(WORD cw
)
3716 #if defined(_MSC_VER) && defined(__i386__)
3720 __asm__
volatile ("fnclex");
3721 __asm__
volatile ("fldcw %0" : : "m" (cw
));
3725 static inline WORD
get_fpu_cw(void)
3728 #if defined(_MSC_VER) && defined(__i386__)
3731 __asm__
volatile ("fnstcw %0" : "=m" (cw
));
3736 static WORD callback_cw
, callback_set_cw
;
3737 static DWORD callback_tid
;
3739 static HRESULT WINAPI
dummy_object_QueryInterface(IUnknown
*iface
, REFIID riid
, void **out
)
3742 return E_NOINTERFACE
;
3745 static ULONG WINAPI
dummy_object_AddRef(IUnknown
*iface
)
3747 callback_cw
= get_fpu_cw();
3748 set_fpu_cw(callback_set_cw
);
3749 callback_tid
= GetCurrentThreadId();
3753 static ULONG WINAPI
dummy_object_Release(IUnknown
*iface
)
3755 callback_cw
= get_fpu_cw();
3756 set_fpu_cw(callback_set_cw
);
3757 callback_tid
= GetCurrentThreadId();
3761 static const IUnknownVtbl dummy_object_vtbl
=
3763 dummy_object_QueryInterface
,
3764 dummy_object_AddRef
,
3765 dummy_object_Release
,
3768 static void test_fpu_setup(void)
3770 struct device_desc device_desc
;
3771 IDirect3DDevice8
*device
;
3776 IDirect3DSurface8
*surface
;
3777 IUnknown dummy_object
= {&dummy_object_vtbl
};
3779 window
= create_window();
3780 ok(!!window
, "Failed to create a window.\n");
3781 d3d8
= Direct3DCreate8(D3D_SDK_VERSION
);
3782 ok(!!d3d8
, "Failed to create a D3D object.\n");
3784 device_desc
.adapter_ordinal
= D3DADAPTER_DEFAULT
;
3785 device_desc
.device_window
= window
;
3786 device_desc
.width
= 640;
3787 device_desc
.height
= 480;
3788 device_desc
.flags
= 0;
3792 ok(cw
== 0xf60, "cw is %#x, expected 0xf60.\n", cw
);
3794 if (!(device
= create_device(d3d8
, window
, &device_desc
)))
3796 skip("Failed to create a 3D device, skipping test.\n");
3802 ok(cw
== 0x7f, "cw is %#x, expected 0x7f.\n", cw
);
3804 hr
= IDirect3DDevice8_GetRenderTarget(device
, &surface
);
3805 ok(SUCCEEDED(hr
), "Failed to get render target surface, hr %#lx.\n", hr
);
3807 callback_set_cw
= 0xf60;
3808 hr
= IDirect3DSurface8_SetPrivateData(surface
, &d3d8_private_data_test_guid
,
3809 &dummy_object
, sizeof(IUnknown
*), D3DSPD_IUNKNOWN
);
3810 ok(SUCCEEDED(hr
), "Failed to set private data, hr %#lx.\n", hr
);
3811 ok(callback_cw
== 0x7f, "Callback cw is %#x, expected 0x7f.\n", callback_cw
);
3812 ok(callback_tid
== GetCurrentThreadId(), "Got unexpected thread id.\n");
3814 ok(cw
== 0xf60, "cw is %#x, expected 0xf60.\n", cw
);
3817 hr
= IDirect3DSurface8_SetPrivateData(surface
, &d3d8_private_data_test_guid
,
3818 &dummy_object
, sizeof(IUnknown
*), D3DSPD_IUNKNOWN
);
3819 ok(SUCCEEDED(hr
), "Failed to set private data, hr %#lx.\n", hr
);
3820 ok(callback_cw
== 0xf60, "Callback cw is %#x, expected 0xf60.\n", callback_cw
);
3821 ok(callback_tid
== GetCurrentThreadId(), "Got unexpected thread id.\n");
3823 callback_set_cw
= 0x7f;
3826 IDirect3DSurface8_Release(surface
);
3829 IDirect3DDevice8_Release(device
);
3830 ok(callback_cw
== 0x7f, "Callback cw is %#x, expected 0x7f.\n", callback_cw
);
3831 ok(callback_tid
== GetCurrentThreadId(), "Got unexpected thread id.\n");
3834 ok(cw
== 0x7f, "cw is %#x, expected 0x7f.\n", cw
);
3837 ok(cw
== 0xf60, "cw is %#x, expected 0xf60.\n", cw
);
3839 device_desc
.flags
= CREATE_DEVICE_FPU_PRESERVE
;
3840 device
= create_device(d3d8
, window
, &device_desc
);
3841 ok(!!device
, "CreateDevice failed.\n");
3844 ok(cw
== 0xf60, "cw is %#x, expected 0xf60.\n", cw
);
3846 hr
= IDirect3DDevice8_GetRenderTarget(device
, &surface
);
3847 ok(SUCCEEDED(hr
), "Failed to get render target surface, hr %#lx.\n", hr
);
3850 callback_set_cw
= 0x37f;
3851 hr
= IDirect3DSurface8_SetPrivateData(surface
, &d3d8_private_data_test_guid
,
3852 &dummy_object
, sizeof(IUnknown
*), D3DSPD_IUNKNOWN
);
3853 ok(SUCCEEDED(hr
), "Failed to set private data, hr %#lx.\n", hr
);
3854 ok(callback_cw
== 0xf60, "Callback cw is %#x, expected 0xf60.\n", callback_cw
);
3855 ok(callback_tid
== GetCurrentThreadId(), "Got unexpected thread id.\n");
3857 ok(cw
== 0x37f, "cw is %#x, expected 0x37f.\n", cw
);
3859 IDirect3DSurface8_Release(surface
);
3862 IDirect3DDevice8_Release(device
);
3863 ok(callback_cw
== 0x37f, "Callback cw is %#x, expected 0x37f.\n", callback_cw
);
3864 ok(callback_tid
== GetCurrentThreadId(), "Got unexpected thread id.\n");
3867 DestroyWindow(window
);
3868 IDirect3D8_Release(d3d8
);
3873 static void test_fpu_setup(void)
3879 static void test_ApplyStateBlock(void)
3881 IDirect3DDevice8
*device
;
3885 DWORD received
, token
;
3887 window
= create_window();
3888 ok(!!window
, "Failed to create a window.\n");
3889 d3d8
= Direct3DCreate8(D3D_SDK_VERSION
);
3890 ok(!!d3d8
, "Failed to create a D3D object.\n");
3891 if (!(device
= create_device(d3d8
, window
, NULL
)))
3893 skip("Failed to create a 3D device, skipping test.\n");
3897 IDirect3DDevice8_BeginStateBlock(device
);
3898 IDirect3DDevice8_SetRenderState(device
, D3DRS_ZENABLE
, TRUE
);
3899 IDirect3DDevice8_EndStateBlock(device
, &token
);
3900 ok(token
, "Received zero stateblock handle.\n");
3901 IDirect3DDevice8_SetRenderState(device
, D3DRS_ZENABLE
, FALSE
);
3903 hr
= IDirect3DDevice8_GetRenderState(device
, D3DRS_ZENABLE
, &received
);
3904 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
3905 ok(!received
, "Expected = FALSE, received TRUE.\n");
3907 hr
= IDirect3DDevice8_ApplyStateBlock(device
, 0);
3908 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
3909 hr
= IDirect3DDevice8_GetRenderState(device
, D3DRS_ZENABLE
, &received
);
3910 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
3911 ok(!received
, "Expected FALSE, received TRUE.\n");
3913 hr
= IDirect3DDevice8_ApplyStateBlock(device
, token
);
3914 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
3915 hr
= IDirect3DDevice8_GetRenderState(device
, D3DRS_ZENABLE
, &received
);
3916 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
3917 ok(received
, "Expected TRUE, received FALSE.\n");
3919 IDirect3DDevice8_DeleteStateBlock(device
, token
);
3920 IDirect3DDevice8_Release(device
);
3922 IDirect3D8_Release(d3d8
);
3923 DestroyWindow(window
);
3926 static void test_depth_stencil_size(void)
3928 IDirect3DDevice8
*device
;
3929 IDirect3DSurface8
*ds
, *rt
, *ds_bigger
, *ds_bigger2
;
3930 IDirect3DSurface8
*surf
;
3935 hwnd
= CreateWindowA("d3d8_test_wc", "d3d8_test", WS_OVERLAPPEDWINDOW
,
3936 100, 100, 160, 160, NULL
, NULL
, NULL
, NULL
);
3937 ok(!!hwnd
, "Failed to create a window.\n");
3938 d3d8
= Direct3DCreate8(D3D_SDK_VERSION
);
3939 ok(!!d3d8
, "Failed to create a D3D object.\n");
3941 if (!(device
= create_device(d3d8
, hwnd
, NULL
)))
3943 skip("Failed to create a 3D device, skipping test.\n");
3947 hr
= IDirect3DDevice8_CreateRenderTarget(device
, 64, 64, D3DFMT_A8R8G8B8
, D3DMULTISAMPLE_NONE
, FALSE
, &rt
);
3948 ok(SUCCEEDED(hr
), "IDirect3DDevice8_CreateRenderTarget failed, hr %#lx.\n", hr
);
3949 hr
= IDirect3DDevice8_CreateDepthStencilSurface(device
, 32, 32, D3DFMT_D24X8
, D3DMULTISAMPLE_NONE
, &ds
);
3950 ok(SUCCEEDED(hr
), "IDirect3DDevice8_CreateDepthStencilSurface failed, hr %#lx.\n", hr
);
3951 hr
= IDirect3DDevice8_CreateDepthStencilSurface(device
, 128, 128, D3DFMT_D24X8
, D3DMULTISAMPLE_NONE
, &ds_bigger
);
3952 ok(SUCCEEDED(hr
), "IDirect3DDevice8_CreateDepthStencilSurface failed, hr %#lx.\n", hr
);
3953 hr
= IDirect3DDevice8_CreateDepthStencilSurface(device
, 128, 128, D3DFMT_D24X8
, D3DMULTISAMPLE_NONE
, &ds_bigger2
);
3954 ok(SUCCEEDED(hr
), "IDirect3DDevice8_CreateDepthStencilSurface failed, hr %#lx.\n", hr
);
3956 hr
= IDirect3DDevice8_SetRenderTarget(device
, rt
, ds
);
3957 ok(hr
== D3DERR_INVALIDCALL
, "Got hr %#lx.\n", hr
);
3958 hr
= IDirect3DDevice8_SetRenderTarget(device
, rt
, ds_bigger
);
3959 ok(SUCCEEDED(hr
), "IDirect3DDevice8_SetRenderTarget failed, hr %#lx.\n", hr
);
3961 /* try to set the small ds without changing the render target at the same time */
3962 hr
= IDirect3DDevice8_SetRenderTarget(device
, NULL
, ds
);
3963 ok(hr
== D3DERR_INVALIDCALL
, "Got hr %#lx.\n", hr
);
3964 hr
= IDirect3DDevice8_SetRenderTarget(device
, NULL
, ds_bigger2
);
3965 ok(SUCCEEDED(hr
), "IDirect3DDevice8_SetRenderTarget failed, hr %#lx.\n", hr
);
3967 hr
= IDirect3DDevice8_GetRenderTarget(device
, &surf
);
3968 ok(hr
== D3D_OK
, "IDirect3DDevice8_GetRenderTarget failed, hr %#lx.\n", hr
);
3969 ok(surf
== rt
, "The render target is %p, expected %p\n", surf
, rt
);
3970 IDirect3DSurface8_Release(surf
);
3971 hr
= IDirect3DDevice8_GetDepthStencilSurface(device
, &surf
);
3972 ok(hr
== D3D_OK
, "IDirect3DDevice8_GetDepthStencilSurface failed, hr %#lx.\n", hr
);
3973 ok(surf
== ds_bigger2
, "The depth stencil is %p, expected %p\n", surf
, ds_bigger2
);
3974 IDirect3DSurface8_Release(surf
);
3976 hr
= IDirect3DDevice8_SetRenderTarget(device
, NULL
, NULL
);
3977 ok(SUCCEEDED(hr
), "IDirect3DDevice8_SetRenderTarget failed, hr %#lx.\n", hr
);
3978 hr
= IDirect3DDevice8_GetDepthStencilSurface(device
, &surf
);
3979 ok(FAILED(hr
), "IDirect3DDevice8_GetDepthStencilSurface should have failed, hr %#lx.\n", hr
);
3980 ok(surf
== NULL
, "The depth stencil is %p, expected NULL\n", surf
);
3981 if (surf
) IDirect3DSurface8_Release(surf
);
3983 IDirect3DSurface8_Release(rt
);
3984 IDirect3DSurface8_Release(ds
);
3985 IDirect3DSurface8_Release(ds_bigger
);
3986 IDirect3DSurface8_Release(ds_bigger2
);
3989 IDirect3D8_Release(d3d8
);
3990 DestroyWindow(hwnd
);
3993 static void test_window_style(void)
3995 RECT focus_rect
, fullscreen_rect
, r
;
3996 LONG device_style
, device_exstyle
;
3997 LONG focus_style
, focus_exstyle
;
3998 struct device_desc device_desc
;
3999 LONG style
, expected_style
;
4000 IDirect3DDevice8
*device
;
4006 focus_window
= CreateWindowA("d3d8_test_wc", "d3d8_test", WS_OVERLAPPEDWINDOW
,
4007 0, 0, registry_mode
.dmPelsWidth
/ 2, registry_mode
.dmPelsHeight
/ 2, 0, 0, 0, 0);
4008 device_window
= CreateWindowA("d3d8_test_wc", "d3d8_test", WS_OVERLAPPEDWINDOW
,
4009 0, 0, registry_mode
.dmPelsWidth
/ 2, registry_mode
.dmPelsHeight
/ 2, 0, 0, 0, 0);
4010 d3d8
= Direct3DCreate8(D3D_SDK_VERSION
);
4011 ok(!!d3d8
, "Failed to create a D3D object.\n");
4013 device_style
= GetWindowLongA(device_window
, GWL_STYLE
);
4014 device_exstyle
= GetWindowLongA(device_window
, GWL_EXSTYLE
);
4015 focus_style
= GetWindowLongA(focus_window
, GWL_STYLE
);
4016 focus_exstyle
= GetWindowLongA(focus_window
, GWL_EXSTYLE
);
4018 SetRect(&fullscreen_rect
, 0, 0, registry_mode
.dmPelsWidth
, registry_mode
.dmPelsHeight
);
4019 GetWindowRect(focus_window
, &focus_rect
);
4021 device_desc
.adapter_ordinal
= D3DADAPTER_DEFAULT
;
4022 device_desc
.device_window
= device_window
;
4023 device_desc
.width
= registry_mode
.dmPelsWidth
;
4024 device_desc
.height
= registry_mode
.dmPelsHeight
;
4025 device_desc
.flags
= CREATE_DEVICE_FULLSCREEN
;
4026 if (!(device
= create_device(d3d8
, focus_window
, &device_desc
)))
4028 skip("Failed to create a D3D device, skipping tests.\n");
4032 style
= GetWindowLongA(device_window
, GWL_STYLE
);
4033 expected_style
= device_style
| WS_VISIBLE
;
4034 todo_wine
ok(style
== expected_style
|| broken(style
== (expected_style
& ~WS_OVERLAPPEDWINDOW
)) /* w1064v1809 */,
4035 "Expected device window style %#lx, got %#lx.\n",
4036 expected_style
, style
);
4037 style
= GetWindowLongA(device_window
, GWL_EXSTYLE
);
4038 expected_style
= device_exstyle
| WS_EX_TOPMOST
;
4039 todo_wine
ok(style
== expected_style
|| broken(style
== (expected_style
& ~WS_EX_OVERLAPPEDWINDOW
)) /* w1064v1809 */,
4040 "Expected device window extended style %#lx, got %#lx.\n",
4041 expected_style
, style
);
4043 style
= GetWindowLongA(focus_window
, GWL_STYLE
);
4044 ok(style
== focus_style
, "Expected focus window style %#lx, got %#lx.\n",
4045 focus_style
, style
);
4046 style
= GetWindowLongA(focus_window
, GWL_EXSTYLE
);
4047 ok(style
== focus_exstyle
, "Expected focus window extended style %#lx, got %#lx.\n",
4048 focus_exstyle
, style
);
4050 GetWindowRect(device_window
, &r
);
4051 ok(EqualRect(&r
, &fullscreen_rect
), "Expected %s, got %s.\n",
4052 wine_dbgstr_rect(&fullscreen_rect
), wine_dbgstr_rect(&r
));
4053 GetClientRect(device_window
, &r
);
4054 todo_wine
ok(!EqualRect(&r
, &fullscreen_rect
) || broken(!(style
& WS_THICKFRAME
)) /* w1064v1809 */,
4055 "Client rect and window rect are equal.\n");
4056 GetWindowRect(focus_window
, &r
);
4057 ok(EqualRect(&r
, &focus_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(&focus_rect
),
4058 wine_dbgstr_rect(&r
));
4060 device_desc
.flags
= 0;
4061 hr
= reset_device(device
, &device_desc
);
4062 ok(SUCCEEDED(hr
), "Failed to reset device, hr %#lx.\n", hr
);
4064 style
= GetWindowLongA(device_window
, GWL_STYLE
);
4065 expected_style
= device_style
| WS_VISIBLE
;
4066 ok(style
== expected_style
, "Expected device window style %#lx, got %#lx.\n",
4067 expected_style
, style
);
4068 style
= GetWindowLongA(device_window
, GWL_EXSTYLE
);
4069 expected_style
= device_exstyle
| WS_EX_TOPMOST
;
4070 ok(style
== expected_style
, "Expected device window extended style %#lx, got %#lx.\n",
4071 expected_style
, style
);
4073 style
= GetWindowLongA(focus_window
, GWL_STYLE
);
4074 ok(style
== focus_style
, "Expected focus window style %#lx, got %#lx.\n",
4075 focus_style
, style
);
4076 style
= GetWindowLongA(focus_window
, GWL_EXSTYLE
);
4077 ok(style
== focus_exstyle
, "Expected focus window extended style %#lx, got %#lx.\n",
4078 focus_exstyle
, style
);
4080 device_desc
.flags
= CREATE_DEVICE_FULLSCREEN
;
4081 hr
= reset_device(device
, &device_desc
);
4082 ok(SUCCEEDED(hr
), "Failed to reset device, hr %#lx.\n", hr
);
4083 ret
= SetForegroundWindow(GetDesktopWindow());
4084 ok(ret
, "Failed to set foreground window.\n");
4086 style
= GetWindowLongA(device_window
, GWL_STYLE
);
4087 expected_style
= device_style
| WS_MINIMIZE
| WS_VISIBLE
;
4088 todo_wine
ok(style
== expected_style
, "Expected device window style %#lx, got %#lx.\n",
4089 expected_style
, style
);
4090 style
= GetWindowLongA(device_window
, GWL_EXSTYLE
);
4091 expected_style
= device_exstyle
| WS_EX_TOPMOST
;
4092 todo_wine
ok(style
== expected_style
, "Expected device window extended style %#lx, got %#lx.\n",
4093 expected_style
, style
);
4095 style
= GetWindowLongA(focus_window
, GWL_STYLE
);
4096 ok(style
== focus_style
, "Expected focus window style %#lx, got %#lx.\n",
4097 focus_style
, style
);
4098 style
= GetWindowLongA(focus_window
, GWL_EXSTYLE
);
4099 ok(style
== focus_exstyle
, "Expected focus window extended style %#lx, got %#lx.\n",
4100 focus_exstyle
, style
);
4102 /* Follow-up tests fail on native if the device is destroyed while lost. */
4103 ShowWindow(focus_window
, SW_MINIMIZE
);
4104 ShowWindow(focus_window
, SW_RESTORE
);
4105 ret
= SetForegroundWindow(focus_window
);
4106 ok(ret
, "Failed to set foreground window.\n");
4108 hr
= reset_device(device
, &device_desc
);
4109 ok(SUCCEEDED(hr
), "Failed to reset device, hr %#lx.\n", hr
);
4111 ref
= IDirect3DDevice8_Release(device
);
4112 ok(!ref
, "Got unexpected refcount %lu.\n", ref
);
4115 IDirect3D8_Release(d3d8
);
4117 DestroyWindow(device_window
);
4118 DestroyWindow(focus_window
);
4121 static void test_unsupported_shaders(void)
4123 IDirect3DDevice8
*device
;
4131 static const DWORD vs_2_0
[] =
4133 0xfffe0200, /* vs_2_0 */
4134 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4135 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4136 0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
4137 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4138 0x0000ffff /* end */
4140 static const DWORD ps_2_0
[] =
4142 0xffff0200, /* ps_2_0 */
4143 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
4144 0x03000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
4145 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
4146 0x0000ffff /* end */
4151 def c255
, 1.0, 1.0, 1.0, 1.0
4155 static const DWORD vs_1_255
[] =
4158 0x0000001f, 0x80000000, 0x900f0000,
4159 0x00000051, 0xa00f00ff, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000,
4160 0x00000002, 0x800f0000, 0x90e40000, 0xa0e400ff,
4161 0x00000001, 0xc00f0000, 0x80e40000,
4167 def c256
, 1.0, 1.0, 1.0, 1.0
4171 static const DWORD vs_1_256
[] =
4174 0x0000001f, 0x80000000, 0x900f0000,
4175 0x00000051, 0xa00f0100, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000,
4176 0x00000002, 0x800f0000, 0x90e40000, 0xa0e40100,
4177 0x00000001, 0xc00f0000, 0x80e40000,
4181 static const DWORD decl
[] =
4184 D3DVSD_REG(D3DVSDE_POSITION
, D3DVSDT_FLOAT3
),
4188 window
= create_window();
4189 ok(!!window
, "Failed to create a window.\n");
4190 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
4191 ok(!!d3d
, "Failed to create a D3D object.\n");
4192 if (!(device
= create_device(d3d
, window
, NULL
)))
4194 skip("Failed to create a D3D device, skipping tests.\n");
4195 IDirect3D8_Release(d3d
);
4196 DestroyWindow(window
);
4200 hr
= IDirect3DDevice8_CreateVertexShader(device
, decl
, simple_ps
, &vs
, 0);
4201 ok(hr
== D3DERR_INVALIDCALL
, "Got hr %#lx.\n", hr
);
4203 hr
= IDirect3DDevice8_CreatePixelShader(device
, simple_vs
, &ps
);
4204 ok(hr
== D3DERR_INVALIDCALL
, "Got hr %#lx.\n", hr
);
4206 hr
= IDirect3DDevice8_CreateVertexShader(device
, decl
, vs_2_0
, &vs
, 0);
4207 ok(hr
== D3DERR_INVALIDCALL
, "Got hr %#lx.\n", hr
);
4209 hr
= IDirect3DDevice8_CreatePixelShader(device
, ps_2_0
, &ps
);
4210 ok(hr
== D3DERR_INVALIDCALL
, "Got hr %#lx.\n", hr
);
4212 hr
= IDirect3DDevice8_GetDeviceCaps(device
, &caps
);
4213 ok(SUCCEEDED(hr
), "Failed to get device caps, hr %#lx.\n", hr
);
4214 if (caps
.MaxVertexShaderConst
< 256)
4216 hr
= IDirect3DDevice8_CreateVertexShader(device
, decl
, vs_1_255
, &vs
, 0);
4217 ok(hr
== D3DERR_INVALIDCALL
, "Got unexpected hr %#lx.\n", hr
);
4221 hr
= IDirect3DDevice8_CreateVertexShader(device
, decl
, vs_1_255
, &vs
, 0);
4222 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
4223 hr
= IDirect3DDevice8_DeleteVertexShader(device
, vs
);
4224 ok(hr
== D3D_OK
, "Got hr %#lx.\n", hr
);
4225 hr
= IDirect3DDevice8_CreateVertexShader(device
, decl
, vs_1_256
, &vs
, 0);
4226 ok(hr
== D3DERR_INVALIDCALL
, "Got unexpected hr %#lx.\n", hr
);
4229 refcount
= IDirect3DDevice8_Release(device
);
4230 ok(!refcount
, "Device has %lu references left.\n", refcount
);
4231 IDirect3D8_Release(d3d
);
4232 DestroyWindow(window
);
4235 static void test_mode_change(void)
4237 unsigned int display_count
= 0, d3d_width
= 0, d3d_height
= 0, user32_width
= 0, user32_height
= 0;
4238 DEVMODEW old_devmode
, devmode
, devmode2
, *original_modes
= NULL
;
4239 struct device_desc device_desc
, device_desc2
;
4240 WCHAR second_monitor_name
[CCHDEVICENAME
];
4241 IDirect3DDevice8
*device
, *device2
;
4242 RECT d3d_rect
, focus_rect
, r
;
4243 IDirect3DSurface8
*backbuffer
;
4244 MONITORINFOEXW monitor_info
;
4245 HMONITOR second_monitor
;
4246 D3DSURFACE_DESC desc
;
4249 UINT adapter_mode_count
, i
;
4253 D3DDISPLAYMODE d3ddm
;
4255 memset(&devmode
, 0, sizeof(devmode
));
4256 devmode
.dmSize
= sizeof(devmode
);
4257 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode
);
4258 ok(ret
, "EnumDisplaySettingsW failed, error %#lx.\n", GetLastError());
4259 ok(equal_mode_rect(&devmode
, ®istry_mode
), "Got a different mode.\n");
4260 ret
= EnumDisplaySettingsW(NULL
, ENUM_REGISTRY_SETTINGS
, &devmode
);
4261 ok(ret
, "EnumDisplaySettingsW failed, error %#lx.\n", GetLastError());
4262 ok(equal_mode_rect(&devmode
, ®istry_mode
), "Got a different mode.\n");
4264 d3d8
= Direct3DCreate8(D3D_SDK_VERSION
);
4265 ok(!!d3d8
, "Failed to create a D3D object.\n");
4267 adapter_mode_count
= IDirect3D8_GetAdapterModeCount(d3d8
, D3DADAPTER_DEFAULT
);
4268 for (i
= 0; i
< adapter_mode_count
; ++i
)
4270 hr
= IDirect3D8_EnumAdapterModes(d3d8
, D3DADAPTER_DEFAULT
, i
, &d3ddm
);
4271 ok(SUCCEEDED(hr
), "Failed to enumerate display mode, hr %#lx.\n", hr
);
4273 if (d3ddm
.Format
!= D3DFMT_X8R8G8B8
)
4275 if (d3ddm
.Width
== registry_mode
.dmPelsWidth
&& d3ddm
.Height
== registry_mode
.dmPelsHeight
)
4277 /* The r200 driver on Windows XP enumerates modes like 320x200 and 320x240 but
4278 * refuses to create a device at these sizes. */
4279 if (d3ddm
.Width
< 640 || d3ddm
.Height
< 480)
4284 user32_width
= d3ddm
.Width
;
4285 user32_height
= d3ddm
.Height
;
4289 /* Make sure the d3d mode is smaller in width or height and at most
4290 * equal in the other dimension than the mode passed to
4291 * ChangeDisplaySettings. Otherwise Windows shrinks the window to
4292 * the ChangeDisplaySettings parameters + 12. */
4293 if (d3ddm
.Width
== user32_width
&& d3ddm
.Height
== user32_height
)
4295 if (d3ddm
.Width
<= user32_width
&& d3ddm
.Height
<= user32_height
)
4297 d3d_width
= d3ddm
.Width
;
4298 d3d_height
= d3ddm
.Height
;
4301 if (user32_width
<= d3ddm
.Width
&& user32_height
<= d3ddm
.Height
)
4303 d3d_width
= user32_width
;
4304 d3d_height
= user32_height
;
4305 user32_width
= d3ddm
.Width
;
4306 user32_height
= d3ddm
.Height
;
4313 skip("Could not find adequate modes, skipping mode tests.\n");
4314 IDirect3D8_Release(d3d8
);
4318 ret
= save_display_modes(&original_modes
, &display_count
);
4319 ok(ret
, "Failed to save original display modes.\n");
4321 memset(&devmode
, 0, sizeof(devmode
));
4322 devmode
.dmSize
= sizeof(devmode
);
4323 devmode
.dmFields
= DM_PELSWIDTH
| DM_PELSHEIGHT
;
4324 devmode
.dmPelsWidth
= user32_width
;
4325 devmode
.dmPelsHeight
= user32_height
;
4326 change_ret
= ChangeDisplaySettingsW(&devmode
, CDS_FULLSCREEN
);
4327 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "Failed to change display mode, ret %#lx.\n", change_ret
);
4329 /* Make the windows visible, otherwise device::release does not restore the mode if
4330 * the application is not in foreground like on the testbot. */
4331 focus_window
= CreateWindowA("d3d8_test_wc", "d3d8_test", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
4332 0, 0, user32_width
/ 2, user32_height
/ 2, 0, 0, 0, 0);
4333 device_window
= CreateWindowA("d3d8_test_wc", "d3d8_test", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
4334 0, 0, user32_width
/ 2, user32_height
/ 2, 0, 0, 0, 0);
4336 SetRect(&d3d_rect
, 0, 0, d3d_width
, d3d_height
);
4337 GetWindowRect(focus_window
, &focus_rect
);
4339 device_desc
.adapter_ordinal
= D3DADAPTER_DEFAULT
;
4340 device_desc
.device_window
= device_window
;
4341 device_desc
.width
= d3d_width
;
4342 device_desc
.height
= d3d_height
;
4343 device_desc
.flags
= CREATE_DEVICE_FULLSCREEN
;
4344 if (!(device
= create_device(d3d8
, focus_window
, &device_desc
)))
4346 skip("Failed to create a D3D device, skipping tests.\n");
4350 devmode
.dmPelsWidth
= user32_width
;
4351 devmode
.dmPelsHeight
= user32_height
;
4352 change_ret
= ChangeDisplaySettingsW(&devmode
, CDS_FULLSCREEN
);
4353 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "Failed to change display mode, ret %#lx.\n", change_ret
);
4355 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode
);
4356 ok(ret
, "Failed to get display mode.\n");
4357 ok(devmode
.dmPelsWidth
== user32_width
&& devmode
.dmPelsHeight
== user32_height
,
4358 "Expected resolution %ux%u, got %lux%lu.\n",
4359 user32_width
, user32_height
, devmode
.dmPelsWidth
, devmode
.dmPelsHeight
);
4361 GetWindowRect(device_window
, &r
);
4362 ok(EqualRect(&r
, &d3d_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(&d3d_rect
),
4363 wine_dbgstr_rect(&r
));
4364 GetWindowRect(focus_window
, &r
);
4365 ok(EqualRect(&r
, &focus_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(&focus_rect
),
4366 wine_dbgstr_rect(&r
));
4368 hr
= IDirect3DDevice8_GetBackBuffer(device
, 0, D3DBACKBUFFER_TYPE_MONO
, &backbuffer
);
4369 ok(SUCCEEDED(hr
), "Failed to get backbuffer, hr %#lx.\n", hr
);
4370 hr
= IDirect3DSurface8_GetDesc(backbuffer
, &desc
);
4371 ok(SUCCEEDED(hr
), "Failed to get backbuffer desc, hr %#lx.\n", hr
);
4372 ok(desc
.Width
== d3d_width
, "Got unexpected backbuffer width %u, expected %u.\n",
4373 desc
.Width
, d3d_width
);
4374 ok(desc
.Height
== d3d_height
, "Got unexpected backbuffer height %u, expected %u.\n",
4375 desc
.Height
, d3d_height
);
4376 IDirect3DSurface8_Release(backbuffer
);
4378 refcount
= IDirect3DDevice8_Release(device
);
4379 ok(!refcount
, "Device has %lu references left.\n", refcount
);
4381 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode
);
4382 ok(ret
, "Failed to get display mode.\n");
4383 ok(devmode
.dmPelsWidth
== registry_mode
.dmPelsWidth
4384 && devmode
.dmPelsHeight
== registry_mode
.dmPelsHeight
,
4385 "Expected resolution %lux%lu, got %lux%lu.\n",
4386 registry_mode
.dmPelsWidth
, registry_mode
.dmPelsHeight
, devmode
.dmPelsWidth
, devmode
.dmPelsHeight
);
4388 change_ret
= ChangeDisplaySettingsW(NULL
, CDS_FULLSCREEN
);
4389 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "Failed to change display mode, ret %#lx.\n", change_ret
);
4391 /* The mode restore also happens when the device was created at the original screen size. */
4393 device_desc
.adapter_ordinal
= D3DADAPTER_DEFAULT
;
4394 device_desc
.device_window
= device_window
;
4395 device_desc
.width
= registry_mode
.dmPelsWidth
;
4396 device_desc
.height
= registry_mode
.dmPelsHeight
;
4397 device_desc
.flags
= CREATE_DEVICE_FULLSCREEN
;
4398 ok(!!(device
= create_device(d3d8
, focus_window
, &device_desc
)), "Failed to create a D3D device.\n");
4400 devmode
.dmFields
= DM_PELSWIDTH
| DM_PELSHEIGHT
;
4401 devmode
.dmPelsWidth
= user32_width
;
4402 devmode
.dmPelsHeight
= user32_height
;
4403 change_ret
= ChangeDisplaySettingsW(&devmode
, CDS_FULLSCREEN
);
4404 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "Failed to change display mode, ret %#lx.\n", change_ret
);
4406 refcount
= IDirect3DDevice8_Release(device
);
4407 ok(!refcount
, "Device has %lu references left.\n", refcount
);
4409 memset(&devmode2
, 0, sizeof(devmode2
));
4410 devmode2
.dmSize
= sizeof(devmode2
);
4411 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode2
);
4412 ok(ret
, "Failed to get display mode.\n");
4413 ok(devmode2
.dmPelsWidth
== registry_mode
.dmPelsWidth
4414 && devmode2
.dmPelsHeight
== registry_mode
.dmPelsHeight
,
4415 "Expected resolution %lux%lu, got %lux%lu.\n", registry_mode
.dmPelsWidth
,
4416 registry_mode
.dmPelsHeight
, devmode2
.dmPelsWidth
, devmode2
.dmPelsHeight
);
4417 ret
= restore_display_modes(original_modes
, display_count
);
4418 ok(ret
, "Failed to restore display modes.\n");
4420 /* Test that no mode restorations if no mode changes happened */
4421 change_ret
= ChangeDisplaySettingsW(&devmode
, CDS_UPDATEREGISTRY
| CDS_NORESET
);
4422 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "ChangeDisplaySettingsW failed with %ld.\n", change_ret
);
4424 device_desc
.adapter_ordinal
= D3DADAPTER_DEFAULT
;
4425 device_desc
.device_window
= device_window
;
4426 device_desc
.width
= d3d_width
;
4427 device_desc
.height
= d3d_height
;
4428 device_desc
.flags
= 0;
4429 device
= create_device(d3d8
, device_window
, &device_desc
);
4430 ok(!!device
, "Failed to create a D3D device.\n");
4431 refcount
= IDirect3DDevice8_Release(device
);
4432 ok(!refcount
, "Device has %lu references left.\n", refcount
);
4434 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode2
);
4435 ok(ret
, "EnumDisplaySettingsW failed, error %#lx.\n", GetLastError());
4436 ok(equal_mode_rect(&devmode2
, ®istry_mode
), "Got a different mode.\n");
4437 ret
= restore_display_modes(original_modes
, display_count
);
4438 ok(ret
, "Failed to restore display modes.\n");
4440 /* Test that mode restorations use display settings in the registry with a fullscreen device */
4441 change_ret
= ChangeDisplaySettingsW(&devmode
, CDS_UPDATEREGISTRY
| CDS_NORESET
);
4442 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "ChangeDisplaySettingsW failed with %ld.\n", change_ret
);
4444 device_desc
.adapter_ordinal
= D3DADAPTER_DEFAULT
;
4445 device_desc
.device_window
= device_window
;
4446 device_desc
.width
= registry_mode
.dmPelsWidth
;
4447 device_desc
.height
= registry_mode
.dmPelsHeight
;
4448 device_desc
.flags
= CREATE_DEVICE_FULLSCREEN
;
4449 device
= create_device(d3d8
, device_window
, &device_desc
);
4450 ok(!!device
, "Failed to create a D3D device.\n");
4451 refcount
= IDirect3DDevice8_Release(device
);
4452 ok(!refcount
, "Device has %lu references left.\n", refcount
);
4454 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode2
);
4455 ok(ret
, "EnumDisplaySettingsW failed, error %#lx.\n", GetLastError());
4456 ok(equal_mode_rect(&devmode2
, &devmode
), "Got a different mode.\n");
4457 ret
= EnumDisplaySettingsW(NULL
, ENUM_REGISTRY_SETTINGS
, &devmode2
);
4458 ok(ret
, "EnumDisplaySettingsW failed, error %#lx.\n", GetLastError());
4459 ok(equal_mode_rect(&devmode2
, &devmode
), "Got a different mode.\n");
4460 ret
= restore_display_modes(original_modes
, display_count
);
4461 ok(ret
, "Failed to restore display modes.\n");
4463 /* Test that mode restorations use display settings in the registry with a fullscreen device
4464 * having the same display mode and then reset to a different mode */
4465 change_ret
= ChangeDisplaySettingsW(&devmode
, CDS_UPDATEREGISTRY
| CDS_NORESET
);
4466 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "ChangeDisplaySettingsW failed with %ld.\n", change_ret
);
4468 device_desc
.adapter_ordinal
= D3DADAPTER_DEFAULT
;
4469 device_desc
.device_window
= device_window
;
4470 device_desc
.width
= registry_mode
.dmPelsWidth
;
4471 device_desc
.height
= registry_mode
.dmPelsHeight
;
4472 device_desc
.flags
= CREATE_DEVICE_FULLSCREEN
;
4473 device
= create_device(d3d8
, device_window
, &device_desc
);
4474 ok(!!device
, "Failed to create a D3D device.\n");
4476 device_desc
.width
= d3d_width
;
4477 device_desc
.height
= d3d_height
;
4478 hr
= reset_device(device
, &device_desc
);
4479 ok(hr
== D3D_OK
, "Failed to reset device, hr %#lx.\n", hr
);
4480 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode2
);
4481 ok(ret
, "EnumDisplaySettingsW failed, error %#lx.\n", GetLastError());
4482 ok(devmode2
.dmPelsWidth
== d3d_width
&& devmode2
.dmPelsHeight
== d3d_height
,
4483 "Expected resolution %ux%u, got %lux%lu.\n", d3d_width
, d3d_height
,
4484 devmode2
.dmPelsWidth
, devmode2
.dmPelsHeight
);
4486 refcount
= IDirect3DDevice8_Release(device
);
4487 ok(!refcount
, "Device has %lu references left.\n", refcount
);
4489 ret
= EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, &devmode2
);
4490 ok(ret
, "EnumDisplaySettingsW failed, error %#lx.\n", GetLastError());
4491 ok(equal_mode_rect(&devmode2
, &devmode
), "Got a different mode.\n");
4492 ret
= EnumDisplaySettingsW(NULL
, ENUM_REGISTRY_SETTINGS
, &devmode2
);
4493 ok(ret
, "EnumDisplaySettingsW failed, error %#lx.\n", GetLastError());
4494 ok(equal_mode_rect(&devmode2
, &devmode
), "Got a different mode.\n");
4495 ret
= restore_display_modes(original_modes
, display_count
);
4496 ok(ret
, "Failed to restore display modes.\n");
4498 if (IDirect3D8_GetAdapterCount(d3d8
) < 2)
4500 skip("Following tests require two adapters.\n");
4504 second_monitor
= IDirect3D8_GetAdapterMonitor(d3d8
, 1);
4505 monitor_info
.cbSize
= sizeof(monitor_info
);
4506 ret
= GetMonitorInfoW(second_monitor
, (MONITORINFO
*)&monitor_info
);
4507 ok(ret
, "GetMonitorInfoW failed, error %#lx.\n", GetLastError());
4508 lstrcpyW(second_monitor_name
, monitor_info
.szDevice
);
4510 memset(&old_devmode
, 0, sizeof(old_devmode
));
4511 old_devmode
.dmSize
= sizeof(old_devmode
);
4512 ret
= EnumDisplaySettingsW(second_monitor_name
, ENUM_CURRENT_SETTINGS
, &old_devmode
);
4513 ok(ret
, "EnumDisplaySettingsW failed, error %#lx.\n", GetLastError());
4520 while (EnumDisplaySettingsW(second_monitor_name
, i
++, &devmode
))
4522 if (devmode
.dmPelsWidth
== old_devmode
.dmPelsWidth
4523 && devmode
.dmPelsHeight
== old_devmode
.dmPelsHeight
)
4526 if (!d3d_width
&& !d3d_height
)
4528 d3d_width
= devmode
.dmPelsWidth
;
4529 d3d_height
= devmode
.dmPelsHeight
;
4533 if (devmode
.dmPelsWidth
== d3d_width
&& devmode
.dmPelsHeight
== d3d_height
)
4536 user32_width
= devmode
.dmPelsWidth
;
4537 user32_height
= devmode
.dmPelsHeight
;
4540 if (!user32_width
|| !user32_height
)
4542 skip("Failed to find three different display modes for the second monitor.\n");
4546 /* Test that mode restorations also happen for non-primary monitors on device resets */
4547 device_desc
.adapter_ordinal
= D3DADAPTER_DEFAULT
;
4548 device_desc
.device_window
= device_window
;
4549 device_desc
.width
= registry_mode
.dmPelsWidth
;
4550 device_desc
.height
= registry_mode
.dmPelsHeight
;
4551 device_desc
.flags
= CREATE_DEVICE_FULLSCREEN
;
4552 device
= create_device(d3d8
, device_window
, &device_desc
);
4553 ok(!!device
, "Failed to create a D3D device.\n");
4555 change_ret
= ChangeDisplaySettingsExW(second_monitor_name
, &devmode
, NULL
, CDS_RESET
, NULL
);
4556 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "ChangeDisplaySettingsExW failed with %ld.\n", change_ret
);
4557 ret
= EnumDisplaySettingsW(second_monitor_name
, ENUM_CURRENT_SETTINGS
, &devmode2
);
4558 ok(ret
, "EnumDisplaySettingsW failed, error %#lx.\n", GetLastError());
4559 if (devmode2
.dmPelsWidth
== old_devmode
.dmPelsWidth
4560 && devmode2
.dmPelsHeight
== old_devmode
.dmPelsHeight
)
4562 skip("Failed to change display settings of the second monitor.\n");
4563 refcount
= IDirect3DDevice8_Release(device
);
4564 ok(!refcount
, "Device has %lu references left.\n", refcount
);
4568 device_desc
.flags
= 0;
4569 hr
= reset_device(device
, &device_desc
);
4570 ok(hr
== D3D_OK
, "Failed to reset device, hr %#lx.\n", hr
);
4572 ret
= EnumDisplaySettingsW(second_monitor_name
, ENUM_CURRENT_SETTINGS
, &devmode2
);
4573 ok(ret
, "EnumDisplaySettingsW failed, error %#lx.\n", GetLastError());
4574 ok(equal_mode_rect(&devmode2
, &old_devmode
), "Got a different mode.\n");
4575 ret
= EnumDisplaySettingsW(second_monitor_name
, ENUM_REGISTRY_SETTINGS
, &devmode2
);
4576 ok(ret
, "EnumDisplaySettingsW failed, error %#lx.\n", GetLastError());
4577 ok(equal_mode_rect(&devmode2
, &old_devmode
), "Got a different mode.\n");
4578 hr
= IDirect3D8_GetAdapterDisplayMode(d3d8
, 1, &d3ddm
);
4579 ok(hr
== S_OK
, "GetAdapterDisplayMode failed, hr %#lx.\n", hr
);
4580 ok(d3ddm
.Width
== old_devmode
.dmPelsWidth
, "Expected width %lu, got %u.\n",
4581 old_devmode
.dmPelsWidth
, d3ddm
.Width
);
4582 ok(d3ddm
.Height
== old_devmode
.dmPelsHeight
, "Expected height %lu, got %u.\n",
4583 old_devmode
.dmPelsHeight
, d3ddm
.Height
);
4585 refcount
= IDirect3DDevice8_Release(device
);
4586 ok(!refcount
, "Device has %lu references left.\n", refcount
);
4587 ret
= restore_display_modes(original_modes
, display_count
);
4588 ok(ret
, "Failed to restore display modes.\n");
4590 /* Test that mode restorations happen for non-primary monitors on device releases */
4591 device_desc
.adapter_ordinal
= D3DADAPTER_DEFAULT
;
4592 device_desc
.device_window
= device_window
;
4593 device_desc
.width
= registry_mode
.dmPelsWidth
;
4594 device_desc
.height
= registry_mode
.dmPelsHeight
;
4595 device_desc
.flags
= CREATE_DEVICE_FULLSCREEN
;
4596 device
= create_device(d3d8
, device_window
, &device_desc
);
4597 ok(!!device
, "Failed to create a D3D device.\n");
4599 change_ret
= ChangeDisplaySettingsExW(second_monitor_name
, &devmode
, NULL
, CDS_RESET
, NULL
);
4600 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "ChangeDisplaySettingsExW failed with %ld.\n", change_ret
);
4602 refcount
= IDirect3DDevice8_Release(device
);
4603 ok(!refcount
, "Device has %lu references left.\n", refcount
);
4605 ret
= EnumDisplaySettingsW(second_monitor_name
, ENUM_CURRENT_SETTINGS
, &devmode2
);
4606 ok(ret
, "EnumDisplaySettingsW failed, error %#lx.\n", GetLastError());
4607 ok(equal_mode_rect(&devmode2
, &old_devmode
), "Got a different mode.\n");
4608 ret
= EnumDisplaySettingsW(second_monitor_name
, ENUM_REGISTRY_SETTINGS
, &devmode2
);
4609 ok(ret
, "EnumDisplaySettingsW failed, error %#lx.\n", GetLastError());
4610 ok(equal_mode_rect(&devmode2
, &old_devmode
), "Got a different mode.\n");
4611 hr
= IDirect3D8_GetAdapterDisplayMode(d3d8
, 1, &d3ddm
);
4612 ok(hr
== S_OK
, "GetAdapterDisplayMode failed, hr %#lx.\n", hr
);
4613 ok(d3ddm
.Width
== old_devmode
.dmPelsWidth
, "Expected width %lu, got %u.\n",
4614 old_devmode
.dmPelsWidth
, d3ddm
.Width
);
4615 ok(d3ddm
.Height
== old_devmode
.dmPelsHeight
, "Expected height %lu, got %u.\n",
4616 old_devmode
.dmPelsHeight
, d3ddm
.Height
);
4617 ret
= restore_display_modes(original_modes
, display_count
);
4618 ok(ret
, "Failed to restore display modes.\n");
4620 /* Test that mode restorations for non-primary monitors use display settings in the registry */
4621 device
= create_device(d3d8
, device_window
, &device_desc
);
4622 ok(!!device
, "Failed to create a D3D device.\n");
4624 change_ret
= ChangeDisplaySettingsExW(second_monitor_name
, &devmode
, NULL
,
4625 CDS_UPDATEREGISTRY
| CDS_NORESET
, NULL
);
4626 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "ChangeDisplaySettingsExW failed with %ld.\n", change_ret
);
4628 refcount
= IDirect3DDevice8_Release(device
);
4629 ok(!refcount
, "Device has %lu references left.\n", refcount
);
4631 ret
= EnumDisplaySettingsW(second_monitor_name
, ENUM_CURRENT_SETTINGS
, &devmode2
);
4632 ok(ret
, "EnumDisplaySettingsW failed, error %#lx.\n", GetLastError());
4633 ok(devmode2
.dmPelsWidth
== devmode
.dmPelsWidth
&& devmode2
.dmPelsHeight
== devmode
.dmPelsHeight
,
4634 "Expected resolution %lux%lu, got %lux%lu.\n", devmode
.dmPelsWidth
, devmode
.dmPelsHeight
,
4635 devmode2
.dmPelsWidth
, devmode2
.dmPelsHeight
);
4636 ret
= EnumDisplaySettingsW(second_monitor_name
, ENUM_REGISTRY_SETTINGS
, &devmode2
);
4637 ok(ret
, "EnumDisplaySettingsW failed, error %#lx.\n", GetLastError());
4638 ok(devmode2
.dmPelsWidth
== devmode
.dmPelsWidth
&& devmode2
.dmPelsHeight
== devmode
.dmPelsHeight
,
4639 "Expected resolution %lux%lu, got %lux%lu.\n", devmode
.dmPelsWidth
, devmode
.dmPelsHeight
,
4640 devmode2
.dmPelsWidth
, devmode2
.dmPelsHeight
);
4641 hr
= IDirect3D8_GetAdapterDisplayMode(d3d8
, 1, &d3ddm
);
4642 ok(hr
== S_OK
, "GetAdapterDisplayMode failed, hr %#lx.\n", hr
);
4643 ok(d3ddm
.Width
== devmode
.dmPelsWidth
&& d3ddm
.Height
== devmode
.dmPelsHeight
,
4644 "Expected resolution %lux%lu, got %ux%u.\n", devmode
.dmPelsWidth
, devmode
.dmPelsHeight
,
4645 d3ddm
.Width
, d3ddm
.Height
);
4646 ret
= restore_display_modes(original_modes
, display_count
);
4647 ok(ret
, "Failed to restore display modes.\n");
4649 /* Test mode restorations when there are two fullscreen devices and one of them got reset */
4650 device
= create_device(d3d8
, focus_window
, &device_desc
);
4651 ok(!!device
, "Failed to create a D3D device.\n");
4653 device_desc2
.adapter_ordinal
= 1;
4654 device_desc2
.device_window
= device_window
;
4655 device_desc2
.width
= d3d_width
;
4656 device_desc2
.height
= d3d_height
;
4657 device_desc2
.flags
= CREATE_DEVICE_FULLSCREEN
;
4658 device2
= create_device(d3d8
, focus_window
, &device_desc2
);
4659 ok(!!device2
, "Failed to create a D3D device.\n");
4661 change_ret
= ChangeDisplaySettingsExW(second_monitor_name
, &devmode
, NULL
, CDS_RESET
, NULL
);
4662 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "ChangeDisplaySettingsExW failed with %ld.\n", change_ret
);
4664 device_desc
.flags
= 0;
4665 hr
= reset_device(device
, &device_desc
);
4666 ok(hr
== D3D_OK
, "Failed to reset device, hr %#lx.\n", hr
);
4668 ret
= EnumDisplaySettingsW(second_monitor_name
, ENUM_CURRENT_SETTINGS
, &devmode2
);
4669 ok(ret
, "EnumDisplaySettingsW failed, error %#lx.\n", GetLastError());
4670 ok(equal_mode_rect(&devmode2
, &old_devmode
), "Got a different mode.\n");
4671 ret
= EnumDisplaySettingsW(second_monitor_name
, ENUM_REGISTRY_SETTINGS
, &devmode2
);
4672 ok(ret
, "EnumDisplaySettingsW failed, error %#lx.\n", GetLastError());
4673 ok(equal_mode_rect(&devmode2
, &old_devmode
), "Got a different mode.\n");
4674 hr
= IDirect3D8_GetAdapterDisplayMode(d3d8
, 1, &d3ddm
);
4675 ok(hr
== S_OK
, "GetAdapterDisplayMode failed, hr %#lx.\n", hr
);
4676 ok(d3ddm
.Width
== old_devmode
.dmPelsWidth
&& d3ddm
.Height
== old_devmode
.dmPelsHeight
,
4677 "Expected resolution %lux%lu, got %ux%u.\n", old_devmode
.dmPelsWidth
,
4678 old_devmode
.dmPelsHeight
, d3ddm
.Width
, d3ddm
.Height
);
4680 refcount
= IDirect3DDevice8_Release(device2
);
4681 ok(!refcount
, "Device has %lu references left.\n", refcount
);
4682 refcount
= IDirect3DDevice8_Release(device
);
4683 ok(!refcount
, "Device has %lu references left.\n", refcount
);
4684 ret
= restore_display_modes(original_modes
, display_count
);
4685 ok(ret
, "Failed to restore display modes.\n");
4687 /* Test mode restoration when there are two fullscreen devices and one of them got released */
4688 device_desc
.flags
= CREATE_DEVICE_FULLSCREEN
;
4689 device
= create_device(d3d8
, focus_window
, &device_desc
);
4690 ok(!!device
, "Failed to create a D3D device.\n");
4691 device2
= create_device(d3d8
, focus_window
, &device_desc2
);
4692 ok(!!device2
, "Failed to create a D3D device.\n");
4694 change_ret
= ChangeDisplaySettingsExW(second_monitor_name
, &devmode
, NULL
, CDS_RESET
, NULL
);
4695 ok(change_ret
== DISP_CHANGE_SUCCESSFUL
, "ChangeDisplaySettingsExW failed with %ld.\n", change_ret
);
4697 refcount
= IDirect3DDevice8_Release(device
);
4698 ok(!refcount
, "Device has %lu references left.\n", refcount
);
4700 ret
= EnumDisplaySettingsW(second_monitor_name
, ENUM_CURRENT_SETTINGS
, &devmode2
);
4701 ok(ret
, "EnumDisplaySettingsW failed, error %#lx.\n", GetLastError());
4702 ok(equal_mode_rect(&devmode2
, &old_devmode
), "Got a different mode.\n");
4703 ret
= EnumDisplaySettingsW(second_monitor_name
, ENUM_REGISTRY_SETTINGS
, &devmode2
);
4704 ok(ret
, "EnumDisplaySettingsW failed, error %#lx.\n", GetLastError());
4705 ok(equal_mode_rect(&devmode2
, &old_devmode
), "Got a different mode.\n");
4706 hr
= IDirect3D8_GetAdapterDisplayMode(d3d8
, 1, &d3ddm
);
4707 ok(hr
== S_OK
, "GetAdapterDisplayMode failed, hr %#lx.\n", hr
);
4708 ok(d3ddm
.Width
== old_devmode
.dmPelsWidth
&& d3ddm
.Height
== old_devmode
.dmPelsHeight
,
4709 "Expected resolution %lux%lu, got %ux%u.\n", old_devmode
.dmPelsWidth
,
4710 old_devmode
.dmPelsHeight
, d3ddm
.Width
, d3ddm
.Height
);
4712 refcount
= IDirect3DDevice8_Release(device2
);
4713 ok(!refcount
, "Device has %lu references left.\n", refcount
);
4716 DestroyWindow(device_window
);
4717 DestroyWindow(focus_window
);
4718 IDirect3D8_Release(d3d8
);
4719 ret
= restore_display_modes(original_modes
, display_count
);
4720 ok(ret
, "Failed to restore display modes.\n");
4721 free(original_modes
);
4724 static void test_device_window_reset(void)
4726 RECT fullscreen_rect
, device_rect
, r
;
4727 struct device_desc device_desc
;
4728 IDirect3DDevice8
*device
;
4735 filter_messages
= NULL
;
4736 expect_messages
= NULL
;
4738 wc
.lpfnWndProc
= test_proc
;
4739 wc
.lpszClassName
= "d3d8_test_wndproc_wc";
4740 ok(RegisterClassA(&wc
), "Failed to register window class.\n");
4742 focus_window
= CreateWindowA("d3d8_test_wndproc_wc", "d3d8_test", WS_OVERLAPPEDWINDOW
,
4743 0, 0, registry_mode
.dmPelsWidth
/ 2, registry_mode
.dmPelsHeight
/ 2, 0, 0, 0, 0);
4744 device_window
= CreateWindowA("d3d8_test_wndproc_wc", "d3d8_test", WS_OVERLAPPEDWINDOW
,
4745 0, 0, registry_mode
.dmPelsWidth
/ 2, registry_mode
.dmPelsHeight
/ 2, 0, 0, 0, 0);
4746 d3d8
= Direct3DCreate8(D3D_SDK_VERSION
);
4747 ok(!!d3d8
, "Failed to create a D3D object.\n");
4749 SetRect(&fullscreen_rect
, 0, 0, registry_mode
.dmPelsWidth
, registry_mode
.dmPelsHeight
);
4750 GetWindowRect(device_window
, &device_rect
);
4752 proc
= GetWindowLongPtrA(device_window
, GWLP_WNDPROC
);
4753 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#Ix, got %#Ix.\n",
4754 (LONG_PTR
)test_proc
, proc
);
4755 proc
= GetWindowLongPtrA(focus_window
, GWLP_WNDPROC
);
4756 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#Ix, got %#Ix.\n",
4757 (LONG_PTR
)test_proc
, proc
);
4759 device_desc
.adapter_ordinal
= D3DADAPTER_DEFAULT
;
4760 device_desc
.device_window
= NULL
;
4761 device_desc
.width
= registry_mode
.dmPelsWidth
;
4762 device_desc
.height
= registry_mode
.dmPelsHeight
;
4763 device_desc
.flags
= CREATE_DEVICE_FULLSCREEN
;
4764 if (!(device
= create_device(d3d8
, focus_window
, &device_desc
)))
4766 skip("Failed to create a D3D device, skipping tests.\n");
4770 GetWindowRect(focus_window
, &r
);
4771 ok(EqualRect(&r
, &fullscreen_rect
), "Expected %s, got %s.\n",
4772 wine_dbgstr_rect(&fullscreen_rect
), wine_dbgstr_rect(&r
));
4773 GetWindowRect(device_window
, &r
);
4774 ok(EqualRect(&r
, &device_rect
), "Expected %s, got %s.\n", wine_dbgstr_rect(&device_rect
),
4775 wine_dbgstr_rect(&r
));
4777 proc
= GetWindowLongPtrA(device_window
, GWLP_WNDPROC
);
4778 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#Ix, got %#Ix.\n",
4779 (LONG_PTR
)test_proc
, proc
);
4780 proc
= GetWindowLongPtrA(focus_window
, GWLP_WNDPROC
);
4781 ok(proc
!= (LONG_PTR
)test_proc
, "Expected wndproc != %#Ix.\n", (LONG_PTR
)test_proc
);
4783 device_desc
.device_window
= device_window
;
4784 hr
= reset_device(device
, &device_desc
);
4785 ok(SUCCEEDED(hr
), "Failed to reset device.\n");
4787 GetWindowRect(focus_window
, &r
);
4788 ok(EqualRect(&r
, &fullscreen_rect
), "Expected %s, got %s.\n",
4789 wine_dbgstr_rect(&fullscreen_rect
), wine_dbgstr_rect(&r
));
4790 GetWindowRect(device_window
, &r
);
4791 ok(EqualRect(&r
, &fullscreen_rect
), "Expected %s, got %s.\n",
4792 wine_dbgstr_rect(&fullscreen_rect
), wine_dbgstr_rect(&r
));
4794 proc
= GetWindowLongPtrA(device_window
, GWLP_WNDPROC
);
4795 ok(proc
== (LONG_PTR
)test_proc
, "Expected wndproc %#Ix, got %#Ix.\n",
4796 (LONG_PTR
)test_proc
, proc
);
4797 proc
= GetWindowLongPtrA(focus_window
, GWLP_WNDPROC
);
4798 ok(proc
!= (LONG_PTR
)test_proc
, "Expected wndproc != %#Ix.\n", (LONG_PTR
)test_proc
);
4800 ref
= IDirect3DDevice8_Release(device
);
4801 ok(!ref
, "Got unexpected refcount %lu.\n", ref
);
4804 IDirect3D8_Release(d3d8
);
4805 DestroyWindow(device_window
);
4806 DestroyWindow(focus_window
);
4807 UnregisterClassA("d3d8_test_wndproc_wc", GetModuleHandleA(NULL
));
4810 static void depth_blit_test(void)
4812 IDirect3DDevice8
*device
= NULL
;
4813 IDirect3DSurface8
*backbuffer
, *ds1
, *ds2
, *ds3
;
4815 const POINT dst_point
= {0, 0};
4820 hwnd
= CreateWindowA("d3d8_test_wc", "d3d8_test", WS_OVERLAPPEDWINDOW
,
4821 100, 100, 160, 160, NULL
, NULL
, NULL
, NULL
);
4822 ok(!!hwnd
, "Failed to create a window.\n");
4823 d3d8
= Direct3DCreate8(D3D_SDK_VERSION
);
4824 ok(!!d3d8
, "Failed to create a D3D object.\n");
4826 if (!(device
= create_device(d3d8
, hwnd
, NULL
)))
4828 skip("Failed to create a D3D device, skipping tests.\n");
4832 hr
= IDirect3DDevice8_GetRenderTarget(device
, &backbuffer
);
4833 ok(SUCCEEDED(hr
), "GetRenderTarget failed, hr %#lx.\n", hr
);
4834 hr
= IDirect3DDevice8_GetDepthStencilSurface(device
, &ds1
);
4835 ok(SUCCEEDED(hr
), "GetDepthStencilSurface failed, hr %#lx.\n", hr
);
4836 hr
= IDirect3DDevice8_CreateDepthStencilSurface(device
, 640, 480, D3DFMT_D24S8
, D3DMULTISAMPLE_NONE
, &ds2
);
4837 ok(SUCCEEDED(hr
), "CreateDepthStencilSurface failed, hr %#lx.\n", hr
);
4838 hr
= IDirect3DDevice8_CreateDepthStencilSurface(device
, 640, 480, D3DFMT_D24S8
, D3DMULTISAMPLE_NONE
, &ds3
);
4839 ok(SUCCEEDED(hr
), "CreateDepthStencilSurface failed, hr %#lx.\n", hr
);
4841 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_ZBUFFER
, 0, 0.0f
, 0);
4842 ok(SUCCEEDED(hr
), "Clear failed, hr %#lx.\n", hr
);
4845 SetRect(&src_rect
, 0, 0, 320, 240);
4846 hr
= IDirect3DDevice8_CopyRects(device
, ds1
, &src_rect
, 1, ds2
, &dst_point
);
4847 ok(hr
== D3DERR_INVALIDCALL
, "Got hr %#lx.\n", hr
);
4849 SetRect(&src_rect
, 0, 480, 640, 0);
4850 hr
= IDirect3DDevice8_CopyRects(device
, ds1
, &src_rect
, 1, ds2
, &dst_point
);
4851 ok(hr
== D3DERR_INVALIDCALL
, "Got hr %#lx.\n", hr
);
4852 /* Full, explicit. */
4853 SetRect(&src_rect
, 0, 0, 640, 480);
4854 hr
= IDirect3DDevice8_CopyRects(device
, ds1
, &src_rect
, 1, ds2
, &dst_point
);
4855 ok(hr
== D3DERR_INVALIDCALL
, "Got hr %#lx.\n", hr
);
4856 /* Depth -> color blit.*/
4857 hr
= IDirect3DDevice8_CopyRects(device
, ds1
, &src_rect
, 1, backbuffer
, &dst_point
);
4858 ok(hr
== D3DERR_INVALIDCALL
, "Got hr %#lx.\n", hr
);
4859 /* Full, NULL rects, current depth stencil -> unbound depth stencil */
4860 hr
= IDirect3DDevice8_CopyRects(device
, ds1
, NULL
, 0, ds2
, NULL
);
4861 ok(hr
== D3DERR_INVALIDCALL
, "Got hr %#lx.\n", hr
);
4862 /* Full, NULL rects, unbound depth stencil -> current depth stencil */
4863 hr
= IDirect3DDevice8_CopyRects(device
, ds2
, NULL
, 0, ds1
, NULL
);
4864 ok(hr
== D3DERR_INVALIDCALL
, "Got hr %#lx.\n", hr
);
4865 /* Full, NULL rects, unbound depth stencil -> unbound depth stencil */
4866 hr
= IDirect3DDevice8_CopyRects(device
, ds2
, NULL
, 0, ds3
, NULL
);
4867 ok(hr
== D3DERR_INVALIDCALL
, "Got hr %#lx.\n", hr
);
4869 IDirect3DSurface8_Release(backbuffer
);
4870 IDirect3DSurface8_Release(ds3
);
4871 IDirect3DSurface8_Release(ds2
);
4872 IDirect3DSurface8_Release(ds1
);
4875 if (device
) IDirect3DDevice8_Release(device
);
4876 IDirect3D8_Release(d3d8
);
4877 DestroyWindow(hwnd
);
4880 static void test_reset_resources(void)
4882 IDirect3DSurface8
*surface
, *rt
;
4883 IDirect3DTexture8
*texture
;
4884 IDirect3DDevice8
*device
;
4890 window
= create_window();
4891 d3d8
= Direct3DCreate8(D3D_SDK_VERSION
);
4892 ok(!!d3d8
, "Failed to create a D3D object.\n");
4894 if (!(device
= create_device(d3d8
, window
, NULL
)))
4896 skip("Failed to create a D3D device, skipping tests.\n");
4900 hr
= IDirect3DDevice8_CreateDepthStencilSurface(device
, 128, 128, D3DFMT_D24S8
,
4901 D3DMULTISAMPLE_NONE
, &surface
);
4902 ok(SUCCEEDED(hr
), "Failed to create depth/stencil surface, hr %#lx.\n", hr
);
4904 hr
= IDirect3DDevice8_CreateTexture(device
, 128, 128, 1, D3DUSAGE_RENDERTARGET
,
4905 D3DFMT_A8R8G8B8
, D3DPOOL_DEFAULT
, &texture
);
4906 ok(SUCCEEDED(hr
), "Failed to create render target texture, hr %#lx.\n", hr
);
4907 hr
= IDirect3DTexture8_GetSurfaceLevel(texture
, 0, &rt
);
4908 ok(SUCCEEDED(hr
), "Failed to get surface, hr %#lx.\n", hr
);
4909 IDirect3DTexture8_Release(texture
);
4911 hr
= IDirect3DDevice8_SetRenderTarget(device
, rt
, surface
);
4912 ok(SUCCEEDED(hr
), "Failed to set render target surface, hr %#lx.\n", hr
);
4913 IDirect3DSurface8_Release(rt
);
4914 IDirect3DSurface8_Release(surface
);
4916 hr
= reset_device(device
, NULL
);
4917 ok(SUCCEEDED(hr
), "Failed to reset device.\n");
4919 hr
= IDirect3DDevice8_GetBackBuffer(device
, 0, D3DBACKBUFFER_TYPE_MONO
, &rt
);
4920 ok(SUCCEEDED(hr
), "Failed to get back buffer, hr %#lx.\n", hr
);
4921 hr
= IDirect3DDevice8_GetRenderTarget(device
, &surface
);
4922 ok(SUCCEEDED(hr
), "Failed to get render target surface, hr %#lx.\n", hr
);
4923 ok(surface
== rt
, "Got unexpected surface %p for render target.\n", surface
);
4924 IDirect3DSurface8_Release(surface
);
4925 IDirect3DSurface8_Release(rt
);
4927 ref
= IDirect3DDevice8_Release(device
);
4928 ok(!ref
, "Got unexpected refcount %lu.\n", ref
);
4931 IDirect3D8_Release(d3d8
);
4932 DestroyWindow(window
);
4935 static void test_set_rt_vp_scissor(void)
4937 IDirect3DDevice8
*device
;
4938 IDirect3DSurface8
*rt
;
4946 window
= create_window();
4947 d3d8
= Direct3DCreate8(D3D_SDK_VERSION
);
4948 ok(!!d3d8
, "Failed to create a D3D object.\n");
4949 if (!(device
= create_device(d3d8
, window
, NULL
)))
4951 skip("Failed to create a D3D device, skipping tests.\n");
4952 IDirect3D8_Release(d3d8
);
4953 DestroyWindow(window
);
4957 hr
= IDirect3DDevice8_CreateRenderTarget(device
, 128, 128, D3DFMT_A8R8G8B8
,
4958 D3DMULTISAMPLE_NONE
, FALSE
, &rt
);
4959 ok(SUCCEEDED(hr
), "Failed to create render target, hr %#lx.\n", hr
);
4961 hr
= IDirect3DDevice8_GetViewport(device
, &vp
);
4962 ok(SUCCEEDED(hr
), "Failed to get viewport, hr %#lx.\n", hr
);
4963 ok(!vp
.X
, "Got unexpected vp.X %lu.\n", vp
.X
);
4964 ok(!vp
.Y
, "Got unexpected vp.Y %lu.\n", vp
.Y
);
4965 ok(vp
.Width
== 640, "Got unexpected vp.Width %lu.\n", vp
.Width
);
4966 ok(vp
.Height
== 480, "Got unexpected vp.Height %lu.\n", vp
.Height
);
4967 ok(vp
.MinZ
== 0.0f
, "Got unexpected vp.MinZ %.8e.\n", vp
.MinZ
);
4968 ok(vp
.MaxZ
== 1.0f
, "Got unexpected vp.MaxZ %.8e.\n", vp
.MaxZ
);
4970 hr
= IDirect3DDevice8_BeginStateBlock(device
);
4971 ok(SUCCEEDED(hr
), "Failed to begin stateblock, hr %#lx.\n", hr
);
4973 hr
= IDirect3DDevice8_SetRenderTarget(device
, rt
, NULL
);
4974 ok(SUCCEEDED(hr
), "Failed to set render target, hr %#lx.\n", hr
);
4976 hr
= IDirect3DDevice8_EndStateBlock(device
, &stateblock
);
4977 ok(SUCCEEDED(hr
), "Failed to end stateblock, hr %#lx.\n", hr
);
4978 hr
= IDirect3DDevice8_DeleteStateBlock(device
, stateblock
);
4979 ok(SUCCEEDED(hr
), "Failed to delete stateblock, hr %#lx.\n", hr
);
4981 hr
= IDirect3DDevice8_GetViewport(device
, &vp
);
4982 ok(SUCCEEDED(hr
), "Failed to get viewport, hr %#lx.\n", hr
);
4983 ok(!vp
.X
, "Got unexpected vp.X %lu.\n", vp
.X
);
4984 ok(!vp
.Y
, "Got unexpected vp.Y %lu.\n", vp
.Y
);
4985 ok(vp
.Width
== 128, "Got unexpected vp.Width %lu.\n", vp
.Width
);
4986 ok(vp
.Height
== 128, "Got unexpected vp.Height %lu.\n", vp
.Height
);
4987 ok(vp
.MinZ
== 0.0f
, "Got unexpected vp.MinZ %.8e.\n", vp
.MinZ
);
4988 ok(vp
.MaxZ
== 1.0f
, "Got unexpected vp.MaxZ %.8e.\n", vp
.MaxZ
);
4990 hr
= IDirect3DDevice8_SetRenderTarget(device
, rt
, NULL
);
4991 ok(SUCCEEDED(hr
), "Failed to set render target, hr %#lx.\n", hr
);
4999 hr
= IDirect3DDevice8_SetViewport(device
, &vp
);
5000 ok(SUCCEEDED(hr
), "Failed to set viewport, hr %#lx.\n", hr
);
5002 hr
= IDirect3DDevice8_SetRenderTarget(device
, rt
, NULL
);
5003 ok(SUCCEEDED(hr
), "Failed to set render target, hr %#lx.\n", hr
);
5005 hr
= IDirect3DDevice8_GetViewport(device
, &vp
);
5006 ok(SUCCEEDED(hr
), "Failed to get viewport, hr %#lx.\n", hr
);
5007 ok(!vp
.X
, "Got unexpected vp.X %lu.\n", vp
.X
);
5008 ok(!vp
.Y
, "Got unexpected vp.Y %lu.\n", vp
.Y
);
5009 ok(vp
.Width
== 128, "Got unexpected vp.Width %lu.\n", vp
.Width
);
5010 ok(vp
.Height
== 128, "Got unexpected vp.Height %lu.\n", vp
.Height
);
5011 ok(vp
.MinZ
== 0.0f
, "Got unexpected vp.MinZ %.8e.\n", vp
.MinZ
);
5012 ok(vp
.MaxZ
== 1.0f
, "Got unexpected vp.MaxZ %.8e.\n", vp
.MaxZ
);
5014 IDirect3DSurface8_Release(rt
);
5015 refcount
= IDirect3DDevice8_Release(device
);
5016 ok(!refcount
, "Device has %u references left.\n", refcount
);
5017 IDirect3D8_Release(d3d8
);
5018 DestroyWindow(window
);
5021 static void test_validate_vs(void)
5023 static DWORD vs_code
[] =
5025 0xfffe0101, /* vs_1_1 */
5026 0x00000009, 0xc0010000, 0x90e40000, 0xa0e40000, /* dp4 oPos.x, v0, c0 */
5027 0x00000009, 0xc0020000, 0x90e40000, 0xa0e40001, /* dp4 oPos.y, v0, c1 */
5028 0x00000009, 0xc0040000, 0x90e40000, 0xa0e40002, /* dp4 oPos.z, v0, c2 */
5029 0x00000009, 0xc0080000, 0x90e40000, 0xa0e40003, /* dp4 oPos.w, v0, c3 */
5030 0x0000ffff, /* end */
5036 static DWORD declaration_valid1
[] =
5039 D3DVSD_REG(D3DVSDE_POSITION
, D3DVSDT_FLOAT4
),
5042 static DWORD declaration_valid2
[] =
5045 D3DVSD_REG(D3DVSDE_POSITION
, D3DVSDT_FLOAT2
),
5048 static DWORD declaration_invalid
[] =
5051 D3DVSD_REG(D3DVSDE_NORMAL
, D3DVSDT_FLOAT4
),
5055 hr
= ValidateVertexShader(NULL
, NULL
, NULL
, FALSE
, NULL
);
5056 ok(hr
== E_FAIL
, "Got unexpected hr %#lx.\n", hr
);
5057 hr
= ValidateVertexShader(NULL
, NULL
, NULL
, TRUE
, NULL
);
5058 ok(hr
== E_FAIL
, "Got unexpected hr %#lx.\n", hr
);
5059 hr
= ValidateVertexShader(NULL
, NULL
, NULL
, FALSE
, &errors
);
5060 ok(hr
== E_FAIL
, "Got unexpected hr %#lx.\n", hr
);
5061 ok(!*errors
, "Got unexpected string \"%s\".\n", errors
);
5062 HeapFree(GetProcessHeap(), 0, errors
);
5063 hr
= ValidateVertexShader(NULL
, NULL
, NULL
, TRUE
, &errors
);
5064 ok(hr
== E_FAIL
, "Got unexpected hr %#lx.\n", hr
);
5065 ok(!!*errors
, "Got unexpected empty string.\n");
5066 HeapFree(GetProcessHeap(), 0, errors
);
5068 hr
= ValidateVertexShader(vs_code
, NULL
, NULL
, FALSE
, NULL
);
5069 ok(hr
== S_OK
, "Got unexpected hr %#lx.\n", hr
);
5070 hr
= ValidateVertexShader(vs_code
, NULL
, NULL
, TRUE
, NULL
);
5071 ok(hr
== S_OK
, "Got unexpected hr %#lx.\n", hr
);
5072 hr
= ValidateVertexShader(vs_code
, NULL
, NULL
, TRUE
, &errors
);
5073 ok(hr
== S_OK
, "Got unexpected hr %#lx.\n", hr
);
5074 ok(!*errors
, "Got unexpected string \"%s\".\n", errors
);
5075 HeapFree(GetProcessHeap(), 0, errors
);
5077 hr
= ValidateVertexShader(vs_code
, declaration_valid1
, NULL
, FALSE
, NULL
);
5078 ok(hr
== S_OK
, "Got unexpected hr %#lx.\n", hr
);
5079 hr
= ValidateVertexShader(vs_code
, declaration_valid2
, NULL
, FALSE
, NULL
);
5080 ok(hr
== S_OK
, "Got unexpected hr %#lx.\n", hr
);
5081 hr
= ValidateVertexShader(vs_code
, declaration_invalid
, NULL
, FALSE
, NULL
);
5082 todo_wine
ok(hr
== E_FAIL
, "Got unexpected hr %#lx.\n", hr
);
5084 memset(&caps
, 0, sizeof(caps
));
5085 caps
.VertexShaderVersion
= D3DVS_VERSION(1, 1);
5086 caps
.MaxVertexShaderConst
= 4;
5087 hr
= ValidateVertexShader(vs_code
, NULL
, &caps
, FALSE
, NULL
);
5088 ok(hr
== S_OK
, "Got unexpected hr %#lx.\n", hr
);
5089 caps
.VertexShaderVersion
= D3DVS_VERSION(1, 0);
5090 hr
= ValidateVertexShader(vs_code
, NULL
, &caps
, FALSE
, NULL
);
5091 ok(hr
== E_FAIL
, "Got unexpected hr %#lx.\n", hr
);
5092 caps
.VertexShaderVersion
= D3DVS_VERSION(1, 2);
5093 hr
= ValidateVertexShader(vs_code
, NULL
, &caps
, FALSE
, NULL
);
5094 ok(hr
== S_OK
, "Got unexpected hr %#lx.\n", hr
);
5095 caps
.VertexShaderVersion
= D3DVS_VERSION(8, 8);
5096 hr
= ValidateVertexShader(vs_code
, NULL
, &caps
, FALSE
, NULL
);
5097 ok(hr
== S_OK
, "Got unexpected hr %#lx.\n", hr
);
5098 caps
.VertexShaderVersion
= D3DVS_VERSION(1, 1);
5099 caps
.MaxVertexShaderConst
= 3;
5100 hr
= ValidateVertexShader(vs_code
, NULL
, &caps
, FALSE
, NULL
);
5101 todo_wine
ok(hr
== E_FAIL
, "Got unexpected hr %#lx.\n", hr
);
5103 *vs_code
= D3DVS_VERSION(1, 0);
5104 hr
= ValidateVertexShader(vs_code
, NULL
, NULL
, FALSE
, NULL
);
5105 ok(hr
== S_OK
, "Got unexpected hr %#lx.\n", hr
);
5106 *vs_code
= D3DVS_VERSION(1, 2);
5107 hr
= ValidateVertexShader(vs_code
, NULL
, NULL
, TRUE
, NULL
);
5108 ok(hr
== E_FAIL
, "Got unexpected hr %#lx.\n", hr
);
5109 hr
= ValidateVertexShader(vs_code
, NULL
, NULL
, FALSE
, &errors
);
5110 ok(hr
== E_FAIL
, "Got unexpected hr %#lx.\n", hr
);
5111 ok(!*errors
, "Got unexpected string \"%s\".\n", errors
);
5112 HeapFree(GetProcessHeap(), 0, errors
);
5113 hr
= ValidateVertexShader(vs_code
, NULL
, NULL
, TRUE
, &errors
);
5114 ok(hr
== E_FAIL
, "Got unexpected hr %#lx.\n", hr
);
5115 ok(!!*errors
, "Got unexpected empty string.\n");
5116 HeapFree(GetProcessHeap(), 0, errors
);
5119 static void test_validate_ps(void)
5121 static DWORD ps_1_1_code
[] =
5123 0xffff0101, /* ps_1_1 */
5124 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
5125 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
5126 0x0000ffff /* end */
5128 static const DWORD ps_2_0_code
[] =
5130 0xffff0200, /* ps_2_0 */
5131 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
5132 0x03000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
5133 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
5134 0x0000ffff /* end */
5140 hr
= ValidatePixelShader(NULL
, NULL
, FALSE
, NULL
);
5141 ok(hr
== E_FAIL
, "Got unexpected hr %#lx.\n", hr
);
5142 hr
= ValidatePixelShader(NULL
, NULL
, TRUE
, NULL
);
5143 ok(hr
== E_FAIL
, "Got unexpected hr %#lx.\n", hr
);
5144 errors
= (void *)0xcafeface;
5145 hr
= ValidatePixelShader(NULL
, NULL
, FALSE
, &errors
);
5146 ok(hr
== E_FAIL
, "Got unexpected hr %#lx.\n", hr
);
5147 ok(errors
== (void *)0xcafeface, "Got unexpected errors %p.\n", errors
);
5148 errors
= (void *)0xcafeface;
5149 hr
= ValidatePixelShader(NULL
, NULL
, TRUE
, &errors
);
5150 ok(hr
== E_FAIL
, "Got unexpected hr %#lx.\n", hr
);
5151 ok(errors
== (void *)0xcafeface, "Got unexpected errors %p.\n", errors
);
5153 hr
= ValidatePixelShader(ps_1_1_code
, NULL
, FALSE
, NULL
);
5154 ok(hr
== S_OK
, "Got unexpected hr %#lx.\n", hr
);
5155 hr
= ValidatePixelShader(ps_1_1_code
, NULL
, TRUE
, NULL
);
5156 ok(hr
== S_OK
, "Got unexpected hr %#lx.\n", hr
);
5157 hr
= ValidatePixelShader(ps_1_1_code
, NULL
, TRUE
, &errors
);
5158 ok(hr
== S_OK
, "Got unexpected hr %#lx.\n", hr
);
5159 ok(!*errors
, "Got unexpected string \"%s\".\n", errors
);
5160 HeapFree(GetProcessHeap(), 0, errors
);
5162 memset(&caps
, 0, sizeof(caps
));
5163 caps
.PixelShaderVersion
= D3DPS_VERSION(1, 1);
5164 hr
= ValidatePixelShader(ps_1_1_code
, &caps
, FALSE
, NULL
);
5165 ok(hr
== S_OK
, "Got unexpected hr %#lx.\n", hr
);
5166 caps
.PixelShaderVersion
= D3DPS_VERSION(1, 0);
5167 hr
= ValidatePixelShader(ps_1_1_code
, &caps
, FALSE
, NULL
);
5168 ok(hr
== E_FAIL
, "Got unexpected hr %#lx.\n", hr
);
5169 caps
.PixelShaderVersion
= D3DPS_VERSION(1, 2);
5170 hr
= ValidatePixelShader(ps_1_1_code
, &caps
, FALSE
, NULL
);
5171 ok(hr
== S_OK
, "Got unexpected hr %#lx.\n", hr
);
5172 caps
.PixelShaderVersion
= D3DPS_VERSION(8, 8);
5173 hr
= ValidatePixelShader(ps_1_1_code
, &caps
, FALSE
, NULL
);
5174 ok(hr
== S_OK
, "Got unexpected hr %#lx.\n", hr
);
5176 *ps_1_1_code
= D3DPS_VERSION(1, 0);
5177 hr
= ValidatePixelShader(ps_1_1_code
, NULL
, FALSE
, NULL
);
5178 ok(hr
== S_OK
, "Got unexpected hr %#lx.\n", hr
);
5179 *ps_1_1_code
= D3DPS_VERSION(1, 4);
5180 hr
= ValidatePixelShader(ps_1_1_code
, NULL
, FALSE
, NULL
);
5181 ok(hr
== S_OK
, "Got unexpected hr %#lx.\n", hr
);
5182 hr
= ValidatePixelShader(ps_2_0_code
, NULL
, FALSE
, NULL
);
5183 ok(hr
== E_FAIL
, "Got unexpected hr %#lx.\n", hr
);
5184 *ps_1_1_code
= D3DPS_VERSION(1, 5);
5185 hr
= ValidatePixelShader(ps_1_1_code
, NULL
, TRUE
, NULL
);
5186 ok(hr
== E_FAIL
, "Got unexpected hr %#lx.\n", hr
);
5187 hr
= ValidatePixelShader(ps_1_1_code
, NULL
, FALSE
, &errors
);
5188 ok(hr
== E_FAIL
, "Got unexpected hr %#lx.\n", hr
);
5189 ok(!*errors
, "Got unexpected string \"%s\".\n", errors
);
5190 HeapFree(GetProcessHeap(), 0, errors
);
5191 hr
= ValidatePixelShader(ps_1_1_code
, NULL
, TRUE
, &errors
);
5192 ok(hr
== E_FAIL
, "Got unexpected hr %#lx.\n", hr
);
5193 ok(!!*errors
, "Got unexpected empty string.\n");
5194 HeapFree(GetProcessHeap(), 0, errors
);
5197 static void test_volume_get_container(void)
5199 IDirect3DVolumeTexture8
*texture
= NULL
;
5200 IDirect3DVolume8
*volume
= NULL
;
5201 IDirect3DDevice8
*device
;
5202 IUnknown
*container
;
5209 window
= create_window();
5210 d3d8
= Direct3DCreate8(D3D_SDK_VERSION
);
5211 ok(!!d3d8
, "Failed to create a D3D object.\n");
5212 if (!(device
= create_device(d3d8
, window
, NULL
)))
5214 skip("Failed to create a D3D device, skipping tests.\n");
5215 IDirect3D8_Release(d3d8
);
5216 DestroyWindow(window
);
5220 hr
= IDirect3DDevice8_GetDeviceCaps(device
, &caps
);
5221 ok(SUCCEEDED(hr
), "Failed to get device caps, hr %#lx.\n", hr
);
5222 if (!(caps
.TextureCaps
& D3DPTEXTURECAPS_VOLUMEMAP
))
5224 skip("No volume texture support, skipping tests.\n");
5225 IDirect3DDevice8_Release(device
);
5226 IDirect3D8_Release(d3d8
);
5227 DestroyWindow(window
);
5231 hr
= IDirect3DDevice8_CreateVolumeTexture(device
, 128, 128, 128, 1, 0,
5232 D3DFMT_A8R8G8B8
, D3DPOOL_DEFAULT
, &texture
);
5233 ok(SUCCEEDED(hr
), "Failed to create volume texture, hr %#lx.\n", hr
);
5234 ok(!!texture
, "Got unexpected texture %p.\n", texture
);
5236 hr
= IDirect3DVolumeTexture8_GetVolumeLevel(texture
, 0, &volume
);
5237 ok(SUCCEEDED(hr
), "Failed to get volume level, hr %#lx.\n", hr
);
5238 ok(!!volume
, "Got unexpected volume %p.\n", volume
);
5240 /* These should work... */
5242 hr
= IDirect3DVolume8_GetContainer(volume
, &IID_IUnknown
, (void **)&container
);
5243 ok(SUCCEEDED(hr
), "Failed to get volume container, hr %#lx.\n", hr
);
5244 ok(container
== (IUnknown
*)texture
, "Got unexpected container %p, expected %p.\n", container
, texture
);
5245 IUnknown_Release(container
);
5248 hr
= IDirect3DVolume8_GetContainer(volume
, &IID_IDirect3DResource8
, (void **)&container
);
5249 ok(SUCCEEDED(hr
), "Failed to get volume container, hr %#lx.\n", hr
);
5250 ok(container
== (IUnknown
*)texture
, "Got unexpected container %p, expected %p.\n", container
, texture
);
5251 IUnknown_Release(container
);
5254 hr
= IDirect3DVolume8_GetContainer(volume
, &IID_IDirect3DBaseTexture8
, (void **)&container
);
5255 ok(SUCCEEDED(hr
), "Failed to get volume container, hr %#lx.\n", hr
);
5256 ok(container
== (IUnknown
*)texture
, "Got unexpected container %p, expected %p.\n", container
, texture
);
5257 IUnknown_Release(container
);
5260 hr
= IDirect3DVolume8_GetContainer(volume
, &IID_IDirect3DVolumeTexture8
, (void **)&container
);
5261 ok(SUCCEEDED(hr
), "Failed to get volume container, hr %#lx.\n", hr
);
5262 ok(container
== (IUnknown
*)texture
, "Got unexpected container %p, expected %p.\n", container
, texture
);
5263 IUnknown_Release(container
);
5265 /* ...and this one shouldn't. This should return E_NOINTERFACE and set container to NULL. */
5266 hr
= IDirect3DVolume8_GetContainer(volume
, &IID_IDirect3DVolume8
, (void **)&container
);
5267 ok(hr
== E_NOINTERFACE
, "Got unexpected hr %#lx.\n", hr
);
5268 ok(!container
, "Got unexpected container %p.\n", container
);
5270 IDirect3DVolume8_Release(volume
);
5271 IDirect3DVolumeTexture8_Release(texture
);
5272 refcount
= IDirect3DDevice8_Release(device
);
5273 ok(!refcount
, "Device has %lu references left.\n", refcount
);
5274 IDirect3D8_Release(d3d8
);
5275 DestroyWindow(window
);
5278 static void test_vb_lock_flags(void)
5283 const char *debug_string
;
5288 {D3DLOCK_READONLY
, "D3DLOCK_READONLY", D3D_OK
},
5289 {D3DLOCK_DISCARD
, "D3DLOCK_DISCARD", D3D_OK
},
5290 {D3DLOCK_NOOVERWRITE
, "D3DLOCK_NOOVERWRITE", D3D_OK
},
5291 {D3DLOCK_NOOVERWRITE
| D3DLOCK_DISCARD
, "D3DLOCK_NOOVERWRITE | D3DLOCK_DISCARD", D3D_OK
},
5292 {D3DLOCK_NOOVERWRITE
| D3DLOCK_READONLY
, "D3DLOCK_NOOVERWRITE | D3DLOCK_READONLY", D3D_OK
},
5293 {D3DLOCK_READONLY
| D3DLOCK_DISCARD
, "D3DLOCK_READONLY | D3DLOCK_DISCARD", D3D_OK
},
5294 /* Completely bogus flags aren't an error. */
5295 {0xdeadbeef, "0xdeadbeef", D3D_OK
},
5297 IDirect3DVertexBuffer8
*buffer
;
5298 IDirect3DDevice8
*device
;
5306 window
= create_window();
5307 d3d8
= Direct3DCreate8(D3D_SDK_VERSION
);
5308 ok(!!d3d8
, "Failed to create a D3D object.\n");
5309 if (!(device
= create_device(d3d8
, window
, NULL
)))
5311 skip("Failed to create a D3D device, skipping tests.\n");
5312 IDirect3D8_Release(d3d8
);
5313 DestroyWindow(window
);
5317 hr
= IDirect3DDevice8_CreateVertexBuffer(device
, 1024, D3DUSAGE_DYNAMIC
| D3DUSAGE_WRITEONLY
,
5318 0, D3DPOOL_DEFAULT
, &buffer
);
5319 ok(SUCCEEDED(hr
), "Failed to create vertex buffer, hr %#lx.\n", hr
);
5321 for (i
= 0; i
< ARRAY_SIZE(test_data
); ++i
)
5323 hr
= IDirect3DVertexBuffer8_Lock(buffer
, 0, 0, &data
, test_data
[i
].flags
);
5324 ok(hr
== test_data
[i
].result
, "Got unexpected hr %#lx for %s.\n",
5325 hr
, test_data
[i
].debug_string
);
5328 ok(!!data
, "Got unexpected data %p.\n", data
);
5329 hr
= IDirect3DVertexBuffer8_Unlock(buffer
);
5330 ok(SUCCEEDED(hr
), "Failed to unlock vertex buffer, hr %#lx.\n", hr
);
5334 IDirect3DVertexBuffer8_Release(buffer
);
5335 refcount
= IDirect3DDevice8_Release(device
);
5336 ok(!refcount
, "Device has %lu references left.\n", refcount
);
5337 IDirect3D8_Release(d3d8
);
5338 DestroyWindow(window
);
5341 /* Test the default texture stage state values */
5342 static void test_texture_stage_states(void)
5344 IDirect3DDevice8
*device
;
5353 window
= create_window();
5354 d3d8
= Direct3DCreate8(D3D_SDK_VERSION
);
5355 ok(!!d3d8
, "Failed to create a D3D object.\n");
5356 if (!(device
= create_device(d3d8
, window
, NULL
)))
5358 skip("Failed to create a D3D device, skipping tests.\n");
5359 IDirect3D8_Release(d3d8
);
5360 DestroyWindow(window
);
5364 hr
= IDirect3DDevice8_GetDeviceCaps(device
, &caps
);
5365 ok(SUCCEEDED(hr
), "Failed to get device caps, hr %#lx.\n", hr
);
5367 for (i
= 0; i
< caps
.MaxTextureBlendStages
; ++i
)
5369 hr
= IDirect3DDevice8_GetTextureStageState(device
, i
, D3DTSS_COLOROP
, &value
);
5370 ok(SUCCEEDED(hr
), "Failed to get texture stage state, hr %#lx.\n", hr
);
5371 ok(value
== (i
? D3DTOP_DISABLE
: D3DTOP_MODULATE
),
5372 "Got unexpected value %#lx for D3DTSS_COLOROP, stage %u.\n", value
, i
);
5373 hr
= IDirect3DDevice8_GetTextureStageState(device
, i
, D3DTSS_COLORARG1
, &value
);
5374 ok(SUCCEEDED(hr
), "Failed to get texture stage state, hr %#lx.\n", hr
);
5375 ok(value
== D3DTA_TEXTURE
, "Got unexpected value %#lx for D3DTSS_COLORARG1, stage %u.\n", value
, i
);
5376 hr
= IDirect3DDevice8_GetTextureStageState(device
, i
, D3DTSS_COLORARG2
, &value
);
5377 ok(SUCCEEDED(hr
), "Failed to get texture stage state, hr %#lx.\n", hr
);
5378 ok(value
== D3DTA_CURRENT
, "Got unexpected value %#lx for D3DTSS_COLORARG2, stage %u.\n", value
, i
);
5379 hr
= IDirect3DDevice8_GetTextureStageState(device
, i
, D3DTSS_ALPHAOP
, &value
);
5380 ok(SUCCEEDED(hr
), "Failed to get texture stage state, hr %#lx.\n", hr
);
5381 ok(value
== (i
? D3DTOP_DISABLE
: D3DTOP_SELECTARG1
),
5382 "Got unexpected value %#lx for D3DTSS_ALPHAOP, stage %u.\n", value
, i
);
5383 hr
= IDirect3DDevice8_GetTextureStageState(device
, i
, D3DTSS_ALPHAARG1
, &value
);
5384 ok(SUCCEEDED(hr
), "Failed to get texture stage state, hr %#lx.\n", hr
);
5385 ok(value
== D3DTA_TEXTURE
, "Got unexpected value %#lx for D3DTSS_ALPHAARG1, stage %u.\n", value
, i
);
5386 hr
= IDirect3DDevice8_GetTextureStageState(device
, i
, D3DTSS_ALPHAARG2
, &value
);
5387 ok(SUCCEEDED(hr
), "Failed to get texture stage state, hr %#lx.\n", hr
);
5388 ok(value
== D3DTA_CURRENT
, "Got unexpected value %#lx for D3DTSS_ALPHAARG2, stage %u.\n", value
, i
);
5389 hr
= IDirect3DDevice8_GetTextureStageState(device
, i
, D3DTSS_BUMPENVMAT00
, &value
);
5390 ok(SUCCEEDED(hr
), "Failed to get texture stage state, hr %#lx.\n", hr
);
5391 ok(!value
, "Got unexpected value %#lx for D3DTSS_BUMPENVMAT00, stage %u.\n", value
, i
);
5392 hr
= IDirect3DDevice8_GetTextureStageState(device
, i
, D3DTSS_BUMPENVMAT01
, &value
);
5393 ok(SUCCEEDED(hr
), "Failed to get texture stage state, hr %#lx.\n", hr
);
5394 ok(!value
, "Got unexpected value %#lx for D3DTSS_BUMPENVMAT01, stage %u.\n", value
, i
);
5395 hr
= IDirect3DDevice8_GetTextureStageState(device
, i
, D3DTSS_BUMPENVMAT10
, &value
);
5396 ok(SUCCEEDED(hr
), "Failed to get texture stage state, hr %#lx.\n", hr
);
5397 ok(!value
, "Got unexpected value %#lx for D3DTSS_BUMPENVMAT10, stage %u.\n", value
, i
);
5398 hr
= IDirect3DDevice8_GetTextureStageState(device
, i
, D3DTSS_BUMPENVMAT11
, &value
);
5399 ok(SUCCEEDED(hr
), "Failed to get texture stage state, hr %#lx.\n", hr
);
5400 ok(!value
, "Got unexpected value %#lx for D3DTSS_BUMPENVMAT11, stage %u.\n", value
, i
);
5401 hr
= IDirect3DDevice8_GetTextureStageState(device
, i
, D3DTSS_TEXCOORDINDEX
, &value
);
5402 ok(SUCCEEDED(hr
), "Failed to get texture stage state, hr %#lx.\n", hr
);
5403 ok(value
== i
, "Got unexpected value %#lx for D3DTSS_TEXCOORDINDEX, stage %u.\n", value
, i
);
5404 hr
= IDirect3DDevice8_GetTextureStageState(device
, i
, D3DTSS_BUMPENVLSCALE
, &value
);
5405 ok(SUCCEEDED(hr
), "Failed to get texture stage state, hr %#lx.\n", hr
);
5406 ok(!value
, "Got unexpected value %#lx for D3DTSS_BUMPENVLSCALE, stage %u.\n", value
, i
);
5407 hr
= IDirect3DDevice8_GetTextureStageState(device
, i
, D3DTSS_BUMPENVLOFFSET
, &value
);
5408 ok(SUCCEEDED(hr
), "Failed to get texture stage state, hr %#lx.\n", hr
);
5409 ok(!value
, "Got unexpected value %#lx for D3DTSS_BUMPENVLOFFSET, stage %u.\n", value
, i
);
5410 hr
= IDirect3DDevice8_GetTextureStageState(device
, i
, D3DTSS_TEXTURETRANSFORMFLAGS
, &value
);
5411 ok(SUCCEEDED(hr
), "Failed to get texture stage state, hr %#lx.\n", hr
);
5412 ok(value
== D3DTTFF_DISABLE
,
5413 "Got unexpected value %#lx for D3DTSS_TEXTURETRANSFORMFLAGS, stage %u.\n", value
, i
);
5414 hr
= IDirect3DDevice8_GetTextureStageState(device
, i
, D3DTSS_COLORARG0
, &value
);
5415 ok(SUCCEEDED(hr
), "Failed to get texture stage state, hr %#lx.\n", hr
);
5416 ok(value
== D3DTA_CURRENT
, "Got unexpected value %#lx for D3DTSS_COLORARG0, stage %u.\n", value
, i
);
5417 hr
= IDirect3DDevice8_GetTextureStageState(device
, i
, D3DTSS_ALPHAARG0
, &value
);
5418 ok(SUCCEEDED(hr
), "Failed to get texture stage state, hr %#lx.\n", hr
);
5419 ok(value
== D3DTA_CURRENT
, "Got unexpected value %#lx for D3DTSS_ALPHAARG0, stage %u.\n", value
, i
);
5420 hr
= IDirect3DDevice8_GetTextureStageState(device
, i
, D3DTSS_RESULTARG
, &value
);
5421 ok(SUCCEEDED(hr
), "Failed to get texture stage state, hr %#lx.\n", hr
);
5422 ok(value
== D3DTA_CURRENT
, "Got unexpected value %#lx for D3DTSS_RESULTARG, stage %u.\n", value
, i
);
5425 refcount
= IDirect3DDevice8_Release(device
);
5426 ok(!refcount
, "Device has %lu references left.\n", refcount
);
5427 IDirect3D8_Release(d3d8
);
5428 DestroyWindow(window
);
5431 static void test_cube_textures(void)
5433 IDirect3DCubeTexture8
*texture
;
5434 IDirect3DDevice8
*device
;
5441 window
= create_window();
5442 d3d8
= Direct3DCreate8(D3D_SDK_VERSION
);
5443 ok(!!d3d8
, "Failed to create a D3D object.\n");
5444 if (!(device
= create_device(d3d8
, window
, NULL
)))
5446 skip("Failed to create a D3D device, skipping tests.\n");
5447 IDirect3D8_Release(d3d8
);
5448 DestroyWindow(window
);
5452 hr
= IDirect3DDevice8_GetDeviceCaps(device
, &caps
);
5453 ok(SUCCEEDED(hr
), "Failed to get device caps, hr %#lx.\n", hr
);
5455 if (caps
.TextureCaps
& D3DPTEXTURECAPS_CUBEMAP
)
5457 hr
= IDirect3DDevice8_CreateCubeTexture(device
, 512, 1, 0, D3DFMT_X8R8G8B8
, D3DPOOL_DEFAULT
, &texture
);
5458 ok(hr
== D3D_OK
, "Failed to create D3DPOOL_DEFAULT cube texture, hr %#lx.\n", hr
);
5459 IDirect3DCubeTexture8_Release(texture
);
5460 hr
= IDirect3DDevice8_CreateCubeTexture(device
, 512, 1, 0, D3DFMT_X8R8G8B8
, D3DPOOL_MANAGED
, &texture
);
5461 ok(hr
== D3D_OK
, "Failed to create D3DPOOL_MANAGED cube texture, hr %#lx.\n", hr
);
5462 IDirect3DCubeTexture8_Release(texture
);
5463 hr
= IDirect3DDevice8_CreateCubeTexture(device
, 512, 1, 0, D3DFMT_X8R8G8B8
, D3DPOOL_SYSTEMMEM
, &texture
);
5464 ok(hr
== D3D_OK
, "Failed to create D3DPOOL_SYSTEMMEM cube texture, hr %#lx.\n", hr
);
5465 IDirect3DCubeTexture8_Release(texture
);
5469 hr
= IDirect3DDevice8_CreateCubeTexture(device
, 512, 1, 0, D3DFMT_X8R8G8B8
, D3DPOOL_DEFAULT
, &texture
);
5470 ok(hr
== D3DERR_INVALIDCALL
, "Got unexpected hr %#lx for D3DPOOL_DEFAULT cube texture.\n", hr
);
5471 hr
= IDirect3DDevice8_CreateCubeTexture(device
, 512, 1, 0, D3DFMT_X8R8G8B8
, D3DPOOL_MANAGED
, &texture
);
5472 ok(hr
== D3DERR_INVALIDCALL
, "Got unexpected hr %#lx for D3DPOOL_MANAGED cube texture.\n", hr
);
5473 hr
= IDirect3DDevice8_CreateCubeTexture(device
, 512, 1, 0, D3DFMT_X8R8G8B8
, D3DPOOL_SYSTEMMEM
, &texture
);
5474 ok(hr
== D3DERR_INVALIDCALL
, "Got unexpected hr %#lx for D3DPOOL_SYSTEMMEM cube texture.\n", hr
);
5476 hr
= IDirect3DDevice8_CreateCubeTexture(device
, 512, 1, 0, D3DFMT_X8R8G8B8
, D3DPOOL_SCRATCH
, &texture
);
5477 ok(hr
== D3D_OK
, "Failed to create D3DPOOL_SCRATCH cube texture, hr %#lx.\n", hr
);
5478 IDirect3DCubeTexture8_Release(texture
);
5480 refcount
= IDirect3DDevice8_Release(device
);
5481 ok(!refcount
, "Device has %lu references left.\n", refcount
);
5482 IDirect3D8_Release(d3d8
);
5483 DestroyWindow(window
);
5486 static void test_get_set_texture(void)
5488 const IDirect3DBaseTexture8Vtbl
*texture_vtbl
;
5489 IDirect3DBaseTexture8
*texture
;
5490 IDirect3DDevice8
*device
;
5496 window
= create_window();
5497 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
5498 ok(!!d3d
, "Failed to create a D3D object.\n");
5499 if (!(device
= create_device(d3d
, window
, NULL
)))
5501 skip("Failed to create a D3D device, skipping tests.\n");
5502 IDirect3D8_Release(d3d
);
5503 DestroyWindow(window
);
5507 texture
= (IDirect3DBaseTexture8
*)0xdeadbeef;
5508 hr
= IDirect3DDevice8_SetTexture(device
, 0, NULL
);
5509 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
5510 hr
= IDirect3DDevice8_GetTexture(device
, 0, &texture
);
5511 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
5512 ok(!texture
, "Got unexpected texture %p.\n", texture
);
5514 hr
= IDirect3DDevice8_CreateTexture(device
, 16, 16, 1, 0, D3DFMT_A8R8G8B8
,
5515 D3DPOOL_MANAGED
, (IDirect3DTexture8
**)&texture
);
5516 ok(SUCCEEDED(hr
), "Failed to create texture, hr %#lx.\n", hr
);
5517 texture_vtbl
= texture
->lpVtbl
;
5518 texture
->lpVtbl
= (IDirect3DBaseTexture8Vtbl
*)0xdeadbeef;
5519 hr
= IDirect3DDevice8_SetTexture(device
, 0, texture
);
5520 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#lx.\n", hr
);
5521 hr
= IDirect3DDevice8_SetTexture(device
, 0, NULL
);
5522 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#lx.\n", hr
);
5523 texture
->lpVtbl
= NULL
;
5524 hr
= IDirect3DDevice8_SetTexture(device
, 0, texture
);
5525 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#lx.\n", hr
);
5526 hr
= IDirect3DDevice8_SetTexture(device
, 0, NULL
);
5527 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#lx.\n", hr
);
5528 texture
->lpVtbl
= texture_vtbl
;
5529 IDirect3DBaseTexture8_Release(texture
);
5531 refcount
= IDirect3DDevice8_Release(device
);
5532 ok(!refcount
, "Device has %lu references left.\n", refcount
);
5533 IDirect3D8_Release(d3d
);
5534 DestroyWindow(window
);
5537 /* Test the behaviour of the IDirect3DDevice8::CreateImageSurface() method.
5539 * The expected behaviour (as documented in the original DX8 docs) is that the
5540 * call returns a surface in the SYSTEMMEM pool. Games like Max Payne 1 and 2
5541 * depend on this behaviour.
5543 * A short remark in the DX9 docs however states that the pool of the returned
5544 * surface object is D3DPOOL_SCRATCH. This is misinformation and would result
5545 * in screenshots not appearing in the savegame loading menu of both games
5546 * mentioned above (engine tries to display a texture from the scratch pool).
5548 * This test verifies that the behaviour described in the original d3d8 docs
5549 * is the correct one. For more information about this issue, see the MSDN:
5550 * d3d9 docs: "Converting to Direct3D 9"
5551 * d3d9 reference: "IDirect3DDevice9::CreateOffscreenPlainSurface"
5552 * d3d8 reference: "IDirect3DDevice8::CreateImageSurface" */
5553 static void test_image_surface_pool(void)
5555 IDirect3DSurface8
*surface
;
5556 IDirect3DDevice8
*device
;
5557 D3DSURFACE_DESC desc
;
5563 window
= create_window();
5564 d3d8
= Direct3DCreate8(D3D_SDK_VERSION
);
5565 ok(!!d3d8
, "Failed to create a D3D object.\n");
5566 if (!(device
= create_device(d3d8
, window
, NULL
)))
5568 skip("Failed to create a D3D device, skipping tests.\n");
5569 IDirect3D8_Release(d3d8
);
5570 DestroyWindow(window
);
5574 hr
= IDirect3DDevice8_CreateImageSurface(device
, 128, 128, D3DFMT_A8R8G8B8
, &surface
);
5575 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
5576 hr
= IDirect3DSurface8_GetDesc(surface
, &desc
);
5577 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
5578 ok(desc
.Pool
== D3DPOOL_SYSTEMMEM
, "Got unexpected pool %#x.\n", desc
.Pool
);
5579 IDirect3DSurface8_Release(surface
);
5581 refcount
= IDirect3DDevice8_Release(device
);
5582 ok(!refcount
, "Device has %lu references left.\n", refcount
);
5583 IDirect3D8_Release(d3d8
);
5584 DestroyWindow(window
);
5587 static void test_surface_get_container(void)
5589 IDirect3DTexture8
*texture
= NULL
;
5590 IDirect3DSurface8
*surface
= NULL
;
5591 IDirect3DDevice8
*device
;
5592 IUnknown
*container
;
5598 window
= create_window();
5599 d3d8
= Direct3DCreate8(D3D_SDK_VERSION
);
5600 ok(!!d3d8
, "Failed to create a D3D object.\n");
5601 if (!(device
= create_device(d3d8
, window
, NULL
)))
5603 skip("Failed to create a D3D device, skipping tests.\n");
5604 IDirect3D8_Release(d3d8
);
5605 DestroyWindow(window
);
5609 hr
= IDirect3DDevice8_CreateTexture(device
, 128, 128, 1, 0,
5610 D3DFMT_A8R8G8B8
, D3DPOOL_DEFAULT
, &texture
);
5611 ok(SUCCEEDED(hr
), "Failed to create texture, hr %#lx.\n", hr
);
5612 ok(!!texture
, "Got unexpected texture %p.\n", texture
);
5614 hr
= IDirect3DTexture8_GetSurfaceLevel(texture
, 0, &surface
);
5615 ok(SUCCEEDED(hr
), "Failed to get surface level, hr %#lx.\n", hr
);
5616 ok(!!surface
, "Got unexpected surface %p.\n", surface
);
5618 /* These should work... */
5620 hr
= IDirect3DSurface8_GetContainer(surface
, &IID_IUnknown
, (void **)&container
);
5621 ok(SUCCEEDED(hr
), "Failed to get surface container, hr %#lx.\n", hr
);
5622 ok(container
== (IUnknown
*)texture
, "Got unexpected container %p, expected %p.\n", container
, texture
);
5623 IUnknown_Release(container
);
5626 hr
= IDirect3DSurface8_GetContainer(surface
, &IID_IDirect3DResource8
, (void **)&container
);
5627 ok(SUCCEEDED(hr
), "Failed to get surface container, hr %#lx.\n", hr
);
5628 ok(container
== (IUnknown
*)texture
, "Got unexpected container %p, expected %p.\n", container
, texture
);
5629 IUnknown_Release(container
);
5632 hr
= IDirect3DSurface8_GetContainer(surface
, &IID_IDirect3DBaseTexture8
, (void **)&container
);
5633 ok(SUCCEEDED(hr
), "Failed to get surface container, hr %#lx.\n", hr
);
5634 ok(container
== (IUnknown
*)texture
, "Got unexpected container %p, expected %p.\n", container
, texture
);
5635 IUnknown_Release(container
);
5638 hr
= IDirect3DSurface8_GetContainer(surface
, &IID_IDirect3DTexture8
, (void **)&container
);
5639 ok(SUCCEEDED(hr
), "Failed to get surface container, hr %#lx.\n", hr
);
5640 ok(container
== (IUnknown
*)texture
, "Got unexpected container %p, expected %p.\n", container
, texture
);
5641 IUnknown_Release(container
);
5643 /* ...and this one shouldn't. This should return E_NOINTERFACE and set container to NULL. */
5644 hr
= IDirect3DSurface8_GetContainer(surface
, &IID_IDirect3DSurface8
, (void **)&container
);
5645 ok(hr
== E_NOINTERFACE
, "Got unexpected hr %#lx.\n", hr
);
5646 ok(!container
, "Got unexpected container %p.\n", container
);
5648 IDirect3DSurface8_Release(surface
);
5649 IDirect3DTexture8_Release(texture
);
5650 refcount
= IDirect3DDevice8_Release(device
);
5651 ok(!refcount
, "Device has %lu references left.\n", refcount
);
5652 IDirect3D8_Release(d3d8
);
5653 DestroyWindow(window
);
5656 static void test_lockrect_invalid(void)
5658 static const RECT valid
[] =
5664 static const RECT invalid
[] =
5666 {60, 60, 60, 68}, /* 0 height */
5667 {60, 60, 68, 60}, /* 0 width */
5668 {68, 60, 60, 68}, /* left > right */
5669 {60, 68, 68, 60}, /* top > bottom */
5670 {-8, 60, 0, 68}, /* left < surface */
5671 {60, -8, 68, 0}, /* top < surface */
5672 {-16, 60, -8, 68}, /* right < surface */
5673 {60, -16, 68, -8}, /* bottom < surface */
5674 {60, 60, 136, 68}, /* right > surface */
5675 {60, 60, 68, 136}, /* bottom > surface */
5676 {136, 60, 144, 68}, /* left > surface */
5677 {60, 136, 68, 144}, /* top > surface */
5679 IDirect3DSurface8
*surface
;
5680 IDirect3DTexture8
*texture
;
5681 IDirect3DCubeTexture8
*cube_texture
;
5682 D3DLOCKED_RECT locked_rect
;
5683 IDirect3DDevice8
*device
;
5684 HRESULT hr
, expected_hr
;
5690 unsigned int offset
, expected_offset
;
5693 D3DRESOURCETYPE type
;
5696 BOOL validate
, clear
;
5700 {D3DRTYPE_SURFACE
, D3DPOOL_SCRATCH
, "scratch surface", TRUE
, TRUE
},
5701 {D3DRTYPE_TEXTURE
, D3DPOOL_MANAGED
, "managed texture", FALSE
, FALSE
},
5702 {D3DRTYPE_TEXTURE
, D3DPOOL_SYSTEMMEM
, "sysmem texture", FALSE
, FALSE
},
5703 {D3DRTYPE_TEXTURE
, D3DPOOL_SCRATCH
, "scratch texture", FALSE
, FALSE
},
5704 {D3DRTYPE_CUBETEXTURE
, D3DPOOL_MANAGED
, "default cube texture", TRUE
, TRUE
},
5705 {D3DRTYPE_CUBETEXTURE
, D3DPOOL_SYSTEMMEM
, "sysmem cube texture", TRUE
, TRUE
},
5706 {D3DRTYPE_CUBETEXTURE
, D3DPOOL_SCRATCH
, "scratch cube texture", TRUE
, TRUE
},
5709 window
= create_window();
5710 d3d8
= Direct3DCreate8(D3D_SDK_VERSION
);
5711 ok(!!d3d8
, "Failed to create a D3D object.\n");
5712 if (!(device
= create_device(d3d8
, window
, NULL
)))
5714 skip("Failed to create a D3D device, skipping tests.\n");
5715 IDirect3D8_Release(d3d8
);
5716 DestroyWindow(window
);
5720 for (r
= 0; r
< ARRAY_SIZE(resources
); ++r
)
5723 cube_texture
= NULL
;
5724 switch (resources
[r
].type
)
5726 case D3DRTYPE_SURFACE
:
5727 hr
= IDirect3DDevice8_CreateImageSurface(device
, 128, 128, D3DFMT_A8R8G8B8
, &surface
);
5728 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx, type %s.\n", hr
, resources
[r
].name
);
5731 case D3DRTYPE_TEXTURE
:
5732 hr
= IDirect3DDevice8_CreateTexture(device
, 128, 128, 1, 0, D3DFMT_A8R8G8B8
,
5733 resources
[r
].pool
, &texture
);
5734 ok(SUCCEEDED(hr
), "Failed to create texture, hr %#lx, type %s.\n", hr
, resources
[r
].name
);
5735 hr
= IDirect3DTexture8_GetSurfaceLevel(texture
, 0, &surface
);
5736 ok(SUCCEEDED(hr
), "Failed to get surface level, hr %#lx, type %s.\n", hr
, resources
[r
].name
);
5739 case D3DRTYPE_CUBETEXTURE
:
5740 hr
= IDirect3DDevice8_CreateCubeTexture(device
, 128, 1, 0, D3DFMT_A8R8G8B8
,
5741 resources
[r
].pool
, &cube_texture
);
5742 ok(SUCCEEDED(hr
), "Failed to create cube texture, hr %#lx, type %s.\n", hr
, resources
[r
].name
);
5743 hr
= IDirect3DCubeTexture8_GetCubeMapSurface(cube_texture
, D3DCUBEMAP_FACE_NEGATIVE_X
, 0, &surface
);
5744 ok(SUCCEEDED(hr
), "Failed to get surface level, hr %#lx, type %s.\n", hr
, resources
[r
].name
);
5751 hr
= IDirect3DSurface8_LockRect(surface
, &locked_rect
, NULL
, 0);
5752 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx, type %s.\n", hr
, resources
[r
].name
);
5753 base
= locked_rect
.pBits
;
5754 hr
= IDirect3DSurface8_UnlockRect(surface
);
5755 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx, type %s.\n", hr
, resources
[r
].name
);
5756 expected_hr
= resources
[r
].type
== D3DRTYPE_TEXTURE
? D3D_OK
: D3DERR_INVALIDCALL
;
5757 hr
= IDirect3DSurface8_UnlockRect(surface
);
5758 ok(hr
== expected_hr
, "Got hr %#lx, expected %#lx, type %s.\n", hr
, expected_hr
, resources
[r
].name
);
5760 for (i
= 0; i
< ARRAY_SIZE(valid
); ++i
)
5762 const RECT
*rect
= &valid
[i
];
5764 locked_rect
.pBits
= (BYTE
*)0xdeadbeef;
5765 locked_rect
.Pitch
= 0xdeadbeef;
5767 hr
= IDirect3DSurface8_LockRect(surface
, &locked_rect
, rect
, 0);
5768 ok(SUCCEEDED(hr
), "Failed to lock surface with rect %s, hr %#lx, type %s.\n",
5769 wine_dbgstr_rect(rect
), hr
, resources
[r
].name
);
5771 offset
= (BYTE
*)locked_rect
.pBits
- base
;
5772 expected_offset
= rect
->top
* locked_rect
.Pitch
+ rect
->left
* 4;
5773 ok(offset
== expected_offset
,
5774 "Got unexpected offset %u (expected %u) for rect %s, type %s.\n",
5775 offset
, expected_offset
, wine_dbgstr_rect(rect
), resources
[r
].name
);
5777 hr
= IDirect3DSurface8_UnlockRect(surface
);
5778 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx, type %s\n", hr
, resources
[r
].name
);
5782 hr
= IDirect3DTexture8_LockRect(texture
, 0, &locked_rect
, rect
, 0);
5783 ok(SUCCEEDED(hr
), "Failed to lock surface with rect %s, hr %#lx, type %s.\n",
5784 wine_dbgstr_rect(rect
), hr
, resources
[r
].name
);
5786 offset
= (BYTE
*)locked_rect
.pBits
- base
;
5787 ok(offset
== expected_offset
,
5788 "Got unexpected offset %u (expected %u) for rect %s, type %s.\n",
5789 offset
, expected_offset
, wine_dbgstr_rect(rect
), resources
[r
].name
);
5791 hr
= IDirect3DTexture8_UnlockRect(texture
, 0);
5792 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx, type %s.\n", hr
, resources
[r
].name
);
5796 hr
= IDirect3DCubeTexture8_LockRect(cube_texture
, D3DCUBEMAP_FACE_NEGATIVE_X
, 0, &locked_rect
, rect
, 0);
5797 ok(SUCCEEDED(hr
), "Failed to lock surface with rect %s, hr %#lx, type %s.\n",
5798 wine_dbgstr_rect(rect
), hr
, resources
[r
].name
);
5800 offset
= (BYTE
*)locked_rect
.pBits
- base
;
5801 ok(offset
== expected_offset
,
5802 "Got unexpected offset %u (expected %u) for rect %s, type %s.\n",
5803 offset
, expected_offset
, wine_dbgstr_rect(rect
), resources
[r
].name
);
5805 hr
= IDirect3DCubeTexture8_UnlockRect(cube_texture
, D3DCUBEMAP_FACE_NEGATIVE_X
, 0);
5806 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx, type %s.\n", hr
, resources
[r
].name
);
5810 for (i
= 0; i
< ARRAY_SIZE(invalid
); ++i
)
5812 const RECT
*rect
= &invalid
[i
];
5814 locked_rect
.pBits
= (void *)0xdeadbeef;
5815 locked_rect
.Pitch
= 1;
5816 hr
= IDirect3DSurface8_LockRect(surface
, &locked_rect
, rect
, 0);
5817 if (resources
[r
].validate
)
5818 ok(hr
== D3DERR_INVALIDCALL
, "Got unexpected hr %#lx for rect %s, type %s.\n",
5819 hr
, wine_dbgstr_rect(rect
), resources
[r
].name
);
5821 ok(SUCCEEDED(hr
), "Got unexpected hr %#lx for rect %s, type %s.\n",
5822 hr
, wine_dbgstr_rect(rect
), resources
[r
].name
);
5826 offset
= (BYTE
*)locked_rect
.pBits
- base
;
5827 expected_offset
= rect
->top
* locked_rect
.Pitch
+ rect
->left
* 4;
5828 ok(offset
== expected_offset
,
5829 "Got unexpected offset %u (expected %u) for rect %s, type %s.\n",
5830 offset
, expected_offset
,wine_dbgstr_rect(rect
), resources
[r
].name
);
5832 hr
= IDirect3DSurface8_UnlockRect(surface
);
5833 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx, type %s.\n", hr
, resources
[r
].name
);
5837 ok(!locked_rect
.pBits
, "Got unexpected pBits %p, type %s.\n",
5838 locked_rect
.pBits
, resources
[r
].name
);
5839 ok(!locked_rect
.Pitch
, "Got unexpected Pitch %u, type %s.\n",
5840 locked_rect
.Pitch
, resources
[r
].name
);
5844 hr
= IDirect3DSurface8_LockRect(surface
, &locked_rect
, NULL
, 0);
5845 ok(SUCCEEDED(hr
), "Failed to lock surface with rect NULL, hr %#lx, type %s.\n",
5846 hr
, resources
[r
].name
);
5847 locked_rect
.pBits
= (void *)0xdeadbeef;
5848 locked_rect
.Pitch
= 1;
5849 hr
= IDirect3DSurface8_LockRect(surface
, &locked_rect
, NULL
, 0);
5850 ok(hr
== D3DERR_INVALIDCALL
, "Got unexpected hr %#lx, type %s.\n", hr
, resources
[r
].name
);
5851 if (resources
[r
].clear
)
5853 ok(!locked_rect
.pBits
, "Got unexpected pBits %p, type %s.\n",
5854 locked_rect
.pBits
, resources
[r
].name
);
5855 ok(!locked_rect
.Pitch
, "Got unexpected Pitch %u, type %s.\n",
5856 locked_rect
.Pitch
, resources
[r
].name
);
5860 ok(locked_rect
.pBits
== (void *)0xdeadbeef, "Got unexpected pBits %p, type %s.\n",
5861 locked_rect
.pBits
, resources
[r
].name
);
5862 ok(locked_rect
.Pitch
== 1, "Got unexpected Pitch %u, type %s.\n",
5863 locked_rect
.Pitch
, resources
[r
].name
);
5865 hr
= IDirect3DSurface8_UnlockRect(surface
);
5866 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx, type %s.\n", hr
, resources
[r
].name
);
5868 hr
= IDirect3DSurface8_LockRect(surface
, &locked_rect
, &valid
[0], 0);
5869 ok(hr
== D3D_OK
, "Got unexpected hr %#lx for rect %s, type %s.\n",
5870 hr
, wine_dbgstr_rect(&valid
[0]), resources
[r
].name
);
5871 hr
= IDirect3DSurface8_LockRect(surface
, &locked_rect
, &valid
[0], 0);
5872 ok(hr
== D3DERR_INVALIDCALL
, "Got unexpected hr %#lx for rect %s, type %s.\n",
5873 hr
, wine_dbgstr_rect(&valid
[0]), resources
[r
].name
);
5874 hr
= IDirect3DSurface8_LockRect(surface
, &locked_rect
, &valid
[1], 0);
5875 ok(hr
== D3DERR_INVALIDCALL
, "Got unexpected hr %#lx for rect %s, type %s.\n",
5876 hr
, wine_dbgstr_rect(&valid
[1]), resources
[r
].name
);
5877 hr
= IDirect3DSurface8_UnlockRect(surface
);
5878 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx, type %s.\n", hr
, resources
[r
].name
);
5880 IDirect3DSurface8_Release(surface
);
5883 hr
= IDirect3DTexture8_LockRect(texture
, 0, &locked_rect
, NULL
, 0);
5884 ok(SUCCEEDED(hr
), "Failed to lock texture with rect NULL, hr %#lx, type %s.\n",
5885 hr
, resources
[r
].name
);
5886 locked_rect
.pBits
= (void *)0xdeadbeef;
5887 locked_rect
.Pitch
= 1;
5888 hr
= IDirect3DTexture8_LockRect(texture
, 0, &locked_rect
, NULL
, 0);
5889 ok(hr
== D3DERR_INVALIDCALL
, "Got unexpected hr %#lx, type %s.\n", hr
, resources
[r
].name
);
5890 ok(locked_rect
.pBits
== (void *)0xdeadbeef, "Got unexpected pBits %p, type %s.\n",
5891 locked_rect
.pBits
, resources
[r
].name
);
5892 ok(locked_rect
.Pitch
== 1, "Got unexpected Pitch %u, type %s.\n",
5893 locked_rect
.Pitch
, resources
[r
].name
);
5894 hr
= IDirect3DSurface8_LockRect(surface
, &locked_rect
, NULL
, 0);
5895 ok(hr
== D3DERR_INVALIDCALL
, "Got unexpected hr %#lx, type %s.\n", hr
, resources
[r
].name
);
5896 hr
= IDirect3DTexture8_UnlockRect(texture
, 0);
5897 ok(SUCCEEDED(hr
), "Failed to unlock texture, hr %#lx, type %s.\n", hr
, resources
[r
].name
);
5898 hr
= IDirect3DTexture8_UnlockRect(texture
, 0);
5899 ok(hr
== D3D_OK
, "Got unexpected hr %#lx, type %s.\n", hr
, resources
[r
].name
);
5901 hr
= IDirect3DTexture8_LockRect(texture
, 0, &locked_rect
, &valid
[0], 0);
5902 ok(hr
== D3D_OK
, "Got unexpected hr %#lx for rect %s, type %s.\n",
5903 hr
, wine_dbgstr_rect(&valid
[0]), resources
[r
].name
);
5904 hr
= IDirect3DTexture8_LockRect(texture
, 0, &locked_rect
, &valid
[0], 0);
5905 ok(hr
== D3DERR_INVALIDCALL
, "Got unexpected hr %#lx for rect %s, type %s.\n",
5906 hr
, wine_dbgstr_rect(&valid
[0]), resources
[r
].name
);
5907 hr
= IDirect3DTexture8_LockRect(texture
, 0, &locked_rect
, &valid
[1], 0);
5908 ok(hr
== D3DERR_INVALIDCALL
, "Got unexpected hr %#lx for rect %s, type %s.\n",
5909 hr
, wine_dbgstr_rect(&valid
[1]), resources
[r
].name
);
5910 hr
= IDirect3DTexture8_UnlockRect(texture
, 0);
5911 ok(SUCCEEDED(hr
), "Failed to unlock texture, hr %#lx, type %s.\n", hr
, resources
[r
].name
);
5913 IDirect3DTexture8_Release(texture
);
5915 hr
= IDirect3DDevice8_CreateTexture(device
, 128, 128, 1, D3DUSAGE_WRITEONLY
,
5916 D3DFMT_A8R8G8B8
, resources
[r
].pool
, &texture
);
5917 ok(hr
== D3DERR_INVALIDCALL
, "Got unexpected hr %#lx for type %s.\n",
5918 hr
, resources
[r
].name
);
5923 hr
= IDirect3DCubeTexture8_LockRect(cube_texture
, D3DCUBEMAP_FACE_NEGATIVE_X
, 0,
5924 &locked_rect
, NULL
, 0);
5925 ok(SUCCEEDED(hr
), "Failed to lock texture with rect NULL, hr %#lx, type %s.\n",
5926 hr
, resources
[r
].name
);
5927 locked_rect
.pBits
= (void *)0xdeadbeef;
5928 locked_rect
.Pitch
= 1;
5929 hr
= IDirect3DCubeTexture8_LockRect(cube_texture
, D3DCUBEMAP_FACE_NEGATIVE_X
, 0,
5930 &locked_rect
, NULL
, 0);
5931 ok(hr
== D3DERR_INVALIDCALL
, "Got unexpected hr %#lx, type %s.\n", hr
, resources
[r
].name
);
5932 ok(!locked_rect
.pBits
, "Got unexpected pBits %p, type %s.\n",
5933 locked_rect
.pBits
, resources
[r
].name
);
5934 ok(!locked_rect
.Pitch
, "Got unexpected Pitch %u, type %s.\n",
5935 locked_rect
.Pitch
, resources
[r
].name
);
5936 hr
= IDirect3DSurface8_LockRect(surface
, &locked_rect
, NULL
, 0);
5937 ok(hr
== D3DERR_INVALIDCALL
, "Got unexpected hr %#lx, type %s.\n", hr
, resources
[r
].name
);
5938 hr
= IDirect3DCubeTexture8_UnlockRect(cube_texture
, D3DCUBEMAP_FACE_NEGATIVE_X
, 0);
5939 ok(SUCCEEDED(hr
), "Failed to unlock texture, hr %#lx, type %s.\n", hr
, resources
[r
].name
);
5940 hr
= IDirect3DCubeTexture8_UnlockRect(cube_texture
, D3DCUBEMAP_FACE_NEGATIVE_X
, 0);
5941 ok(hr
== D3DERR_INVALIDCALL
, "Got unexpected hr %#lx, type %s.\n", hr
, resources
[r
].name
);
5943 hr
= IDirect3DCubeTexture8_LockRect(cube_texture
, D3DCUBEMAP_FACE_NEGATIVE_X
, 0,
5944 &locked_rect
, &valid
[0], 0);
5945 ok(hr
== D3D_OK
, "Got unexpected hr %#lx for rect %s, type %s.\n",
5946 hr
, wine_dbgstr_rect(&valid
[0]), resources
[r
].name
);
5947 hr
= IDirect3DCubeTexture8_LockRect(cube_texture
, D3DCUBEMAP_FACE_NEGATIVE_X
, 0,
5948 &locked_rect
, &valid
[0], 0);
5949 ok(hr
== D3DERR_INVALIDCALL
, "Got unexpected hr %#lx for rect %s, type %s.\n",
5950 hr
, wine_dbgstr_rect(&valid
[0]), resources
[r
].name
);
5951 hr
= IDirect3DCubeTexture8_LockRect(cube_texture
, D3DCUBEMAP_FACE_NEGATIVE_X
, 0,
5952 &locked_rect
, &valid
[1], 0);
5953 ok(hr
== D3DERR_INVALIDCALL
, "Got unexpected hr %#lx for rect %s, type %s.\n",
5954 hr
, wine_dbgstr_rect(&valid
[1]), resources
[r
].name
);
5955 hr
= IDirect3DCubeTexture8_UnlockRect(cube_texture
, D3DCUBEMAP_FACE_NEGATIVE_X
, 0);
5956 ok(SUCCEEDED(hr
), "Failed to unlock texture, hr %#lx, type %s.\n", hr
, resources
[r
].name
);
5958 IDirect3DTexture8_Release(cube_texture
);
5960 hr
= IDirect3DDevice8_CreateCubeTexture(device
, 128, 1, D3DUSAGE_WRITEONLY
, D3DFMT_A8R8G8B8
,
5961 resources
[r
].pool
, &cube_texture
);
5962 ok(hr
== D3DERR_INVALIDCALL
, "Got unexpected hr %#lx for type %s.\n",
5963 hr
, resources
[r
].name
);
5967 refcount
= IDirect3DDevice8_Release(device
);
5968 ok(!refcount
, "Device has %lu references left.\n", refcount
);
5969 IDirect3D8_Release(d3d8
);
5970 DestroyWindow(window
);
5973 static void test_private_data(void)
5975 ULONG refcount
, expected_refcount
;
5976 IDirect3DTexture8
*texture
;
5977 IDirect3DSurface8
*surface
, *surface2
;
5978 IDirect3DDevice8
*device
;
5984 DWORD data
[4] = {1, 2, 3, 4};
5985 static const GUID d3d8_private_data_test_guid2
=
5990 {0x9b,0x4b,0x89,0xd7,0xd1,0x12,0xe7,0x2b}
5993 window
= create_window();
5994 d3d8
= Direct3DCreate8(D3D_SDK_VERSION
);
5995 ok(!!d3d8
, "Failed to create a D3D object.\n");
5996 if (!(device
= create_device(d3d8
, window
, NULL
)))
5998 skip("Failed to create a D3D device, skipping tests.\n");
5999 IDirect3D8_Release(d3d8
);
6000 DestroyWindow(window
);
6004 hr
= IDirect3DDevice8_CreateImageSurface(device
, 4, 4, D3DFMT_A8R8G8B8
, &surface
);
6005 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
6007 hr
= IDirect3DSurface8_SetPrivateData(surface
, &d3d8_private_data_test_guid
,
6008 device
, 0, D3DSPD_IUNKNOWN
);
6009 ok(hr
== D3DERR_INVALIDCALL
, "Got unexpected hr %#lx.\n", hr
);
6010 hr
= IDirect3DSurface8_SetPrivateData(surface
, &d3d8_private_data_test_guid
,
6011 device
, 5, D3DSPD_IUNKNOWN
);
6012 ok(hr
== D3DERR_INVALIDCALL
, "Got unexpected hr %#lx.\n", hr
);
6013 hr
= IDirect3DSurface8_SetPrivateData(surface
, &d3d8_private_data_test_guid
,
6014 device
, sizeof(IUnknown
*) * 2, D3DSPD_IUNKNOWN
);
6015 ok(hr
== D3DERR_INVALIDCALL
, "Got unexpected hr %#lx.\n", hr
);
6017 /* A failing SetPrivateData call does not clear the old data with the same tag. */
6018 hr
= IDirect3DSurface8_SetPrivateData(surface
, &d3d8_private_data_test_guid
, device
,
6019 sizeof(device
), D3DSPD_IUNKNOWN
);
6020 ok(SUCCEEDED(hr
), "Failed to set private data, hr %#lx.\n", hr
);
6021 hr
= IDirect3DSurface8_SetPrivateData(surface
, &d3d8_private_data_test_guid
, device
,
6022 sizeof(device
) * 2, D3DSPD_IUNKNOWN
);
6023 ok(hr
== D3DERR_INVALIDCALL
, "Got unexpected hr %#lx.\n", hr
);
6025 hr
= IDirect3DSurface8_GetPrivateData(surface
, &d3d8_private_data_test_guid
, &ptr
, &size
);
6026 ok(SUCCEEDED(hr
), "Failed to get private data, hr %#lx.\n", hr
);
6027 IUnknown_Release(ptr
);
6028 hr
= IDirect3DSurface8_FreePrivateData(surface
, &d3d8_private_data_test_guid
);
6029 ok(SUCCEEDED(hr
), "Failed to free private data, hr %#lx.\n", hr
);
6031 refcount
= get_refcount((IUnknown
*)device
);
6032 hr
= IDirect3DSurface8_SetPrivateData(surface
, &d3d8_private_data_test_guid
,
6033 device
, sizeof(IUnknown
*), D3DSPD_IUNKNOWN
);
6034 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
6035 expected_refcount
= refcount
+ 1;
6036 refcount
= get_refcount((IUnknown
*)device
);
6037 ok(refcount
== expected_refcount
, "Got unexpected refcount %lu, expected %lu.\n", refcount
, expected_refcount
);
6038 hr
= IDirect3DSurface8_FreePrivateData(surface
, &d3d8_private_data_test_guid
);
6039 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
6040 expected_refcount
= refcount
- 1;
6041 refcount
= get_refcount((IUnknown
*)device
);
6042 ok(refcount
== expected_refcount
, "Got unexpected refcount %lu, expected %lu.\n", refcount
, expected_refcount
);
6044 hr
= IDirect3DSurface8_SetPrivateData(surface
, &d3d8_private_data_test_guid
,
6045 device
, sizeof(IUnknown
*), D3DSPD_IUNKNOWN
);
6046 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
6047 hr
= IDirect3DSurface8_SetPrivateData(surface
, &d3d8_private_data_test_guid
,
6048 surface
, sizeof(IUnknown
*), D3DSPD_IUNKNOWN
);
6049 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
6050 refcount
= get_refcount((IUnknown
*)device
);
6051 ok(refcount
== expected_refcount
, "Got unexpected refcount %lu, expected %lu.\n", refcount
, expected_refcount
);
6053 hr
= IDirect3DSurface8_SetPrivateData(surface
, &d3d8_private_data_test_guid
,
6054 device
, sizeof(IUnknown
*), D3DSPD_IUNKNOWN
);
6055 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
6056 size
= 2 * sizeof(ptr
);
6057 hr
= IDirect3DSurface8_GetPrivateData(surface
, &d3d8_private_data_test_guid
, &ptr
, &size
);
6058 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
6059 ok(size
== sizeof(device
), "Got unexpected size %lu.\n", size
);
6060 expected_refcount
= refcount
+ 2;
6061 refcount
= get_refcount((IUnknown
*)device
);
6062 ok(refcount
== expected_refcount
, "Got unexpected refcount %lu, expected %lu.\n", refcount
, expected_refcount
);
6063 ok(ptr
== (IUnknown
*)device
, "Got unexpected ptr %p, expected %p.\n", ptr
, device
);
6064 IUnknown_Release(ptr
);
6065 expected_refcount
--;
6067 ptr
= (IUnknown
*)0xdeadbeef;
6069 hr
= IDirect3DSurface8_GetPrivateData(surface
, &d3d8_private_data_test_guid
, NULL
, &size
);
6070 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
6071 ok(size
== sizeof(device
), "Got unexpected size %lu.\n", size
);
6072 size
= 2 * sizeof(ptr
);
6073 hr
= IDirect3DSurface8_GetPrivateData(surface
, &d3d8_private_data_test_guid
, NULL
, &size
);
6074 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
6075 ok(size
== sizeof(device
), "Got unexpected size %lu.\n", size
);
6076 refcount
= get_refcount((IUnknown
*)device
);
6077 ok(refcount
== expected_refcount
, "Got unexpected refcount %lu, expected %lu.\n", refcount
, expected_refcount
);
6079 hr
= IDirect3DSurface8_GetPrivateData(surface
, &d3d8_private_data_test_guid
, &ptr
, &size
);
6080 ok(hr
== D3DERR_MOREDATA
, "Got unexpected hr %#lx.\n", hr
);
6081 ok(size
== sizeof(device
), "Got unexpected size %lu.\n", size
);
6082 ok(ptr
== (IUnknown
*)0xdeadbeef, "Got unexpected pointer %p.\n", ptr
);
6083 hr
= IDirect3DSurface8_GetPrivateData(surface
, &d3d8_private_data_test_guid2
, NULL
, NULL
);
6084 ok(hr
== D3DERR_NOTFOUND
, "Got unexpected hr %#lx.\n", hr
);
6086 hr
= IDirect3DSurface8_GetPrivateData(surface
, &d3d8_private_data_test_guid2
, &ptr
, &size
);
6087 ok(hr
== D3DERR_NOTFOUND
, "Got unexpected hr %#lx.\n", hr
);
6088 ok(ptr
== (IUnknown
*)0xdeadbeef, "Got unexpected pointer %p.\n", ptr
);
6089 ok(size
== 0xdeadbabe, "Got unexpected size %lu.\n", size
);
6090 /* GetPrivateData with size = NULL causes an access violation on Windows if the
6091 * requested data exists. */
6093 /* Destroying the surface frees the held reference. */
6094 IDirect3DSurface8_Release(surface
);
6095 expected_refcount
= refcount
- 2;
6096 refcount
= get_refcount((IUnknown
*)device
);
6097 ok(refcount
== expected_refcount
, "Got unexpected refcount %lu, expected %lu.\n", refcount
, expected_refcount
);
6099 hr
= IDirect3DDevice8_CreateTexture(device
, 4, 4, 2, 0, D3DFMT_A8R8G8B8
, D3DPOOL_SCRATCH
, &texture
);
6100 ok(SUCCEEDED(hr
), "Failed to create texture, hr %#lx.\n", hr
);
6101 hr
= IDirect3DTexture8_GetSurfaceLevel(texture
, 0, &surface
);
6102 ok(SUCCEEDED(hr
), "Failed to get texture level 0, hr %#lx.\n", hr
);
6103 hr
= IDirect3DTexture8_GetSurfaceLevel(texture
, 1, &surface2
);
6104 ok(SUCCEEDED(hr
), "Failed to get texture level 1, hr %#lx.\n", hr
);
6106 hr
= IDirect3DTexture8_SetPrivateData(texture
, &d3d8_private_data_test_guid
, data
, sizeof(data
), 0);
6107 ok(SUCCEEDED(hr
), "Failed to set private data, hr %#lx.\n", hr
);
6109 memset(data
, 0, sizeof(data
));
6110 size
= sizeof(data
);
6111 hr
= IDirect3DSurface8_GetPrivateData(surface
, &d3d8_private_data_test_guid
, data
, &size
);
6112 ok(hr
== D3DERR_NOTFOUND
, "Got unexpected hr %#lx.\n", hr
);
6113 hr
= IDirect3DTexture8_GetPrivateData(texture
, &d3d8_private_data_test_guid
, data
, &size
);
6114 ok(SUCCEEDED(hr
), "Failed to get private data, hr %#lx.\n", hr
);
6115 ok(data
[0] == 1 && data
[1] == 2 && data
[2] == 3 && data
[3] == 4,
6116 "Got unexpected private data: %lu, %lu, %lu, %lu.\n", data
[0], data
[1], data
[2], data
[3]);
6118 hr
= IDirect3DTexture8_FreePrivateData(texture
, &d3d8_private_data_test_guid
);
6119 ok(SUCCEEDED(hr
), "Failed to free private data, hr %#lx.\n", hr
);
6121 hr
= IDirect3DSurface8_SetPrivateData(surface
, &d3d8_private_data_test_guid
, data
, sizeof(data
), 0);
6122 ok(SUCCEEDED(hr
), "Failed to set private data, hr %#lx.\n", hr
);
6123 hr
= IDirect3DSurface8_GetPrivateData(surface2
, &d3d8_private_data_test_guid
, data
, &size
);
6124 ok(hr
== D3DERR_NOTFOUND
, "Got unexpected hr %#lx.\n", hr
);
6125 hr
= IDirect3DSurface8_FreePrivateData(surface
, &d3d8_private_data_test_guid
);
6126 ok(SUCCEEDED(hr
), "Failed to free private data, hr %#lx.\n", hr
);
6128 IDirect3DSurface8_Release(surface2
);
6129 IDirect3DSurface8_Release(surface
);
6130 IDirect3DTexture8_Release(texture
);
6132 refcount
= IDirect3DDevice8_Release(device
);
6133 ok(!refcount
, "Device has %lu references left.\n", refcount
);
6134 IDirect3D8_Release(d3d8
);
6135 DestroyWindow(window
);
6138 static void test_surface_dimensions(void)
6140 IDirect3DSurface8
*surface
;
6141 IDirect3DDevice8
*device
;
6147 window
= create_window();
6148 d3d8
= Direct3DCreate8(D3D_SDK_VERSION
);
6149 ok(!!d3d8
, "Failed to create a D3D object.\n");
6150 if (!(device
= create_device(d3d8
, window
, NULL
)))
6152 skip("Failed to create a D3D device, skipping tests.\n");
6153 IDirect3D8_Release(d3d8
);
6154 DestroyWindow(window
);
6158 hr
= IDirect3DDevice8_CreateImageSurface(device
, 0, 1, D3DFMT_A8R8G8B8
, &surface
);
6159 ok(hr
== D3DERR_INVALIDCALL
, "Got unexpected hr %#lx.\n", hr
);
6160 hr
= IDirect3DDevice8_CreateImageSurface(device
, 1, 0, D3DFMT_A8R8G8B8
, &surface
);
6161 ok(hr
== D3DERR_INVALIDCALL
, "Got unexpected hr %#lx.\n", hr
);
6163 refcount
= IDirect3DDevice8_Release(device
);
6164 ok(!refcount
, "Device has %lu references left.\n", refcount
);
6165 IDirect3D8_Release(d3d8
);
6166 DestroyWindow(window
);
6169 static void test_surface_format_null(void)
6171 static const D3DFORMAT D3DFMT_NULL
= MAKEFOURCC('N','U','L','L');
6172 IDirect3DTexture8
*texture
;
6173 IDirect3DSurface8
*surface
;
6174 IDirect3DSurface8
*rt
, *ds
;
6175 D3DLOCKED_RECT locked_rect
;
6176 IDirect3DDevice8
*device
;
6177 D3DSURFACE_DESC desc
;
6183 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
6184 ok(!!d3d
, "Failed to create a D3D object.\n");
6186 hr
= IDirect3D8_CheckDeviceFormat(d3d
, 0, D3DDEVTYPE_HAL
, D3DFMT_X8R8G8B8
,
6187 D3DUSAGE_RENDERTARGET
, D3DRTYPE_SURFACE
, D3DFMT_NULL
);
6190 skip("No D3DFMT_NULL support, skipping test.\n");
6191 IDirect3D8_Release(d3d
);
6195 window
= create_window();
6196 if (!(device
= create_device(d3d
, window
, NULL
)))
6198 skip("Failed to create a D3D device, skipping tests.\n");
6199 IDirect3D8_Release(d3d
);
6200 DestroyWindow(window
);
6204 hr
= IDirect3D8_CheckDeviceFormat(d3d
, 0, D3DDEVTYPE_HAL
, D3DFMT_X8R8G8B8
,
6205 D3DUSAGE_RENDERTARGET
, D3DRTYPE_TEXTURE
, D3DFMT_NULL
);
6206 ok(hr
== D3D_OK
, "D3DFMT_NULL should be supported for render target textures, hr %#lx.\n", hr
);
6208 hr
= IDirect3D8_CheckDepthStencilMatch(d3d
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
, D3DFMT_X8R8G8B8
,
6209 D3DFMT_NULL
, D3DFMT_D24S8
);
6210 ok(SUCCEEDED(hr
), "Depth stencil match failed for D3DFMT_NULL, hr %#lx.\n", hr
);
6212 hr
= IDirect3DDevice8_CreateRenderTarget(device
, 128, 128, D3DFMT_NULL
,
6213 D3DMULTISAMPLE_NONE
, TRUE
, &surface
);
6214 ok(SUCCEEDED(hr
), "Failed to create render target, hr %#lx.\n", hr
);
6216 hr
= IDirect3DDevice8_GetRenderTarget(device
, &rt
);
6217 ok(SUCCEEDED(hr
), "Failed to get original render target, hr %#lx.\n", hr
);
6219 hr
= IDirect3DDevice8_GetDepthStencilSurface(device
, &ds
);
6220 ok(SUCCEEDED(hr
), "Failed to get original depth/stencil, hr %#lx.\n", hr
);
6222 hr
= IDirect3DDevice8_SetRenderTarget(device
, surface
, NULL
);
6223 ok(SUCCEEDED(hr
), "Failed to set render target, hr %#lx.\n", hr
);
6225 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0x00000000, 0.0f
, 0);
6226 ok(SUCCEEDED(hr
), "Clear failed, hr %#lx.\n", hr
);
6228 hr
= IDirect3DDevice8_SetRenderTarget(device
, rt
, ds
);
6229 ok(SUCCEEDED(hr
), "Failed to set render target, hr %#lx.\n", hr
);
6231 IDirect3DSurface8_Release(rt
);
6232 IDirect3DSurface8_Release(ds
);
6234 hr
= IDirect3DSurface8_GetDesc(surface
, &desc
);
6235 ok(SUCCEEDED(hr
), "Failed to get surface desc, hr %#lx.\n", hr
);
6236 ok(desc
.Width
== 128, "Expected width 128, got %u.\n", desc
.Width
);
6237 ok(desc
.Height
== 128, "Expected height 128, got %u.\n", desc
.Height
);
6239 hr
= IDirect3DSurface8_LockRect(surface
, &locked_rect
, NULL
, 0);
6240 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
6241 ok(locked_rect
.Pitch
, "Expected non-zero pitch, got %u.\n", locked_rect
.Pitch
);
6242 ok(!!locked_rect
.pBits
, "Expected non-NULL pBits, got %p.\n", locked_rect
.pBits
);
6244 hr
= IDirect3DSurface8_UnlockRect(surface
);
6245 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
6247 IDirect3DSurface8_Release(surface
);
6249 hr
= IDirect3DDevice8_CreateTexture(device
, 128, 128, 0, D3DUSAGE_RENDERTARGET
,
6250 D3DFMT_NULL
, D3DPOOL_DEFAULT
, &texture
);
6251 ok(SUCCEEDED(hr
), "Failed to create texture, hr %#lx.\n", hr
);
6252 IDirect3DTexture8_Release(texture
);
6254 refcount
= IDirect3DDevice8_Release(device
);
6255 ok(!refcount
, "Device has %lu references left.\n", refcount
);
6256 IDirect3D8_Release(d3d
);
6257 DestroyWindow(window
);
6260 static void test_surface_double_unlock(void)
6262 static const D3DPOOL pools
[] =
6267 IDirect3DSurface8
*surface
;
6268 IDirect3DDevice8
*device
;
6276 window
= create_window();
6277 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
6278 ok(!!d3d
, "Failed to create a D3D object.\n");
6279 if (!(device
= create_device(d3d
, window
, NULL
)))
6281 skip("Failed to create a D3D device, skipping tests.\n");
6282 IDirect3D8_Release(d3d
);
6283 DestroyWindow(window
);
6287 for (i
= 0; i
< ARRAY_SIZE(pools
); ++i
)
6291 case D3DPOOL_DEFAULT
:
6292 hr
= IDirect3D8_CheckDeviceFormat(d3d
, 0, D3DDEVTYPE_HAL
, D3DFMT_X8R8G8B8
,
6293 D3DUSAGE_RENDERTARGET
, D3DRTYPE_SURFACE
, D3DFMT_X8R8G8B8
);
6296 skip("D3DFMT_X8R8G8B8 render targets not supported, skipping double unlock DEFAULT pool test.\n");
6300 hr
= IDirect3DDevice8_CreateRenderTarget(device
, 64, 64, D3DFMT_X8R8G8B8
,
6301 D3DMULTISAMPLE_NONE
, TRUE
, &surface
);
6302 ok(SUCCEEDED(hr
), "Failed to create render target, hr %#lx.\n", hr
);
6305 case D3DPOOL_SYSTEMMEM
:
6306 hr
= IDirect3DDevice8_CreateImageSurface(device
, 64, 64, D3DFMT_X8R8G8B8
, &surface
);
6307 ok(SUCCEEDED(hr
), "Failed to create image surface, hr %#lx.\n", hr
);
6314 hr
= IDirect3DSurface8_UnlockRect(surface
);
6315 ok(hr
== D3DERR_INVALIDCALL
, "Got unexpected hr %#lx, for surface in pool %#x.\n", hr
, pools
[i
]);
6316 hr
= IDirect3DSurface8_LockRect(surface
, &lr
, NULL
, 0);
6317 ok(SUCCEEDED(hr
), "Failed to lock surface in pool %#x, hr %#lx.\n", pools
[i
], hr
);
6318 hr
= IDirect3DSurface8_UnlockRect(surface
);
6319 ok(SUCCEEDED(hr
), "Failed to unlock surface in pool %#x, hr %#lx.\n", pools
[i
], hr
);
6320 hr
= IDirect3DSurface8_UnlockRect(surface
);
6321 ok(hr
== D3DERR_INVALIDCALL
, "Got unexpected hr %#lx, for surface in pool %#x.\n", hr
, pools
[i
]);
6323 IDirect3DSurface8_Release(surface
);
6326 refcount
= IDirect3DDevice8_Release(device
);
6327 ok(!refcount
, "Device has %lu references left.\n", refcount
);
6328 IDirect3D8_Release(d3d
);
6329 DestroyWindow(window
);
6332 static void test_surface_blocks(void)
6338 unsigned int block_width
;
6339 unsigned int block_height
;
6341 BOOL create_size_checked
, core_fmt
;
6345 {D3DFMT_DXT1
, "D3DFMT_DXT1", 4, 4, FALSE
, TRUE
, TRUE
},
6346 {D3DFMT_DXT2
, "D3DFMT_DXT2", 4, 4, FALSE
, TRUE
, TRUE
},
6347 {D3DFMT_DXT3
, "D3DFMT_DXT3", 4, 4, FALSE
, TRUE
, TRUE
},
6348 {D3DFMT_DXT4
, "D3DFMT_DXT4", 4, 4, FALSE
, TRUE
, TRUE
},
6349 {D3DFMT_DXT5
, "D3DFMT_DXT5", 4, 4, FALSE
, TRUE
, TRUE
},
6350 /* ATI1N and ATI2N have 2x2 blocks on all AMD cards and Geforce 7 cards,
6351 * which doesn't match the format spec. On newer Nvidia cards
6352 * they have the correct 4x4 block size */
6353 {MAKEFOURCC('A','T','I','1'), "ATI1N", 4, 4, TRUE
, FALSE
, FALSE
},
6354 {MAKEFOURCC('A','T','I','2'), "ATI2N", 4, 4, TRUE
, FALSE
, FALSE
},
6355 /* Windows drivers generally enforce block-aligned locks for
6356 * YUY2 and UYVY. The notable exception is the AMD r500 driver
6357 * in d3d8. The same driver checks the sizes in d3d9. */
6358 {D3DFMT_YUY2
, "D3DFMT_YUY2", 2, 1, TRUE
, FALSE
, TRUE
},
6359 {D3DFMT_UYVY
, "D3DFMT_UYVY", 2, 1, TRUE
, FALSE
, TRUE
},
6365 /* Don't check the return value, Nvidia returns D3DERR_INVALIDCALL for some formats
6366 * and E_INVALIDARG/DDERR_INVALIDPARAMS for others. */
6371 {D3DPOOL_DEFAULT
, "D3DPOOL_DEFAULT", FALSE
},
6372 {D3DPOOL_SCRATCH
, "D3DPOOL_SCRATCH", TRUE
},
6373 {D3DPOOL_SYSTEMMEM
, "D3DPOOL_SYSTEMMEM",TRUE
},
6374 {D3DPOOL_MANAGED
, "D3DPOOL_MANAGED", TRUE
},
6378 D3DRESOURCETYPE rtype
;
6379 const char *type_name
;
6381 const char *pool_name
;
6382 BOOL need_driver_support
, need_runtime_support
;
6386 /* D3d8 only supports sysmem surfaces, which are created via CreateImageSurface. Other tests confirm
6387 * that they are D3DPOOL_SYSTEMMEM surfaces, but their creation restriction behaves like the scratch
6389 {D3DRTYPE_SURFACE
, "D3DRTYPE_SURFACE", D3DPOOL_SYSTEMMEM
, "D3DPOOL_SYSTEMMEM", FALSE
, TRUE
},
6391 {D3DRTYPE_TEXTURE
, "D3DRTYPE_TEXTURE", D3DPOOL_DEFAULT
, "D3DPOOL_DEFAULT", TRUE
, FALSE
},
6392 {D3DRTYPE_TEXTURE
, "D3DRTYPE_TEXTURE", D3DPOOL_SYSTEMMEM
, "D3DPOOL_SYSTEMMEM", TRUE
, FALSE
},
6393 {D3DRTYPE_TEXTURE
, "D3DRTYPE_TEXTURE", D3DPOOL_MANAGED
, "D3DPOOL_MANAGED", TRUE
, FALSE
},
6394 {D3DRTYPE_TEXTURE
, "D3DRTYPE_TEXTURE", D3DPOOL_SCRATCH
, "D3DPOOL_SCRATCH", FALSE
, TRUE
},
6396 {D3DRTYPE_CUBETEXTURE
, "D3DRTYPE_CUBETEXTURE", D3DPOOL_DEFAULT
, "D3DPOOL_DEFAULT", TRUE
, FALSE
},
6397 {D3DRTYPE_CUBETEXTURE
, "D3DRTYPE_CUBETEXTURE", D3DPOOL_SYSTEMMEM
, "D3DPOOL_SYSTEMMEM", TRUE
, FALSE
},
6398 {D3DRTYPE_CUBETEXTURE
, "D3DRTYPE_CUBETEXTURE", D3DPOOL_MANAGED
, "D3DPOOL_MANAGED", TRUE
, FALSE
},
6399 {D3DRTYPE_CUBETEXTURE
, "D3DRTYPE_CUBETEXTURE", D3DPOOL_SCRATCH
, "D3DPOOL_SCRATCH", FALSE
, TRUE
},
6401 IDirect3DTexture8
*texture
;
6402 IDirect3DCubeTexture8
*cube_texture
;
6403 IDirect3DSurface8
*surface
;
6404 D3DLOCKED_RECT locked_rect
;
6405 IDirect3DDevice8
*device
;
6406 unsigned int i
, j
, k
, w
, h
;
6412 BOOL tex_pow2
, cube_pow2
;
6414 static const RECT invalid
[] =
6416 {60, 60, 60, 68}, /* 0 height */
6417 {60, 60, 68, 60}, /* 0 width */
6418 {68, 60, 60, 68}, /* left > right */
6419 {60, 68, 68, 60}, /* top > bottom */
6420 {-8, 60, 0, 68}, /* left < surface */
6421 {60, -8, 68, 0}, /* top < surface */
6422 {-16, 60, -8, 68}, /* right < surface */
6423 {60, -16, 68, -8}, /* bottom < surface */
6424 {60, 60, 136, 68}, /* right > surface */
6425 {60, 60, 68, 136}, /* bottom > surface */
6426 {136, 60, 144, 68}, /* left > surface */
6427 {60, 136, 68, 144}, /* top > surface */
6430 window
= create_window();
6431 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
6432 ok(!!d3d
, "Failed to create a D3D object.\n");
6433 if (!(device
= create_device(d3d
, window
, NULL
)))
6435 skip("Failed to create a D3D device, skipping tests.\n");
6436 IDirect3D8_Release(d3d
);
6437 DestroyWindow(window
);
6441 hr
= IDirect3DDevice8_GetDeviceCaps(device
, &caps
);
6442 ok(SUCCEEDED(hr
), "Failed to get caps, hr %#lx.\n", hr
);
6443 tex_pow2
= caps
.TextureCaps
& D3DPTEXTURECAPS_POW2
;
6445 tex_pow2
= !(caps
.TextureCaps
& D3DPTEXTURECAPS_NONPOW2CONDITIONAL
);
6446 cube_pow2
= !!(caps
.TextureCaps
& D3DPTEXTURECAPS_CUBEMAP_POW2
);
6448 for (i
= 0; i
< ARRAY_SIZE(formats
); ++i
)
6450 BOOL tex_support
, cube_support
, surface_support
, format_known
;
6452 hr
= IDirect3D8_CheckDeviceFormat(d3d
, 0, D3DDEVTYPE_HAL
, D3DFMT_X8R8G8B8
,
6453 0, D3DRTYPE_TEXTURE
, formats
[i
].fmt
);
6454 tex_support
= SUCCEEDED(hr
);
6455 hr
= IDirect3D8_CheckDeviceFormat(d3d
, 0, D3DDEVTYPE_HAL
, D3DFMT_X8R8G8B8
,
6456 0, D3DRTYPE_CUBETEXTURE
, formats
[i
].fmt
);
6457 cube_support
= SUCCEEDED(hr
);
6458 hr
= IDirect3D8_CheckDeviceFormat(d3d
, 0, D3DDEVTYPE_HAL
, D3DFMT_X8R8G8B8
,
6459 0, D3DRTYPE_SURFACE
, formats
[i
].fmt
);
6460 surface_support
= SUCCEEDED(hr
);
6462 /* Scratch pool in general allows texture creation even if the driver does
6463 * not support the format. If the format is an extension format that is not
6464 * known to the runtime, like ATI2N, some driver support is required for
6467 * It is also possible that Windows Vista and Windows 7 d3d8 runtimes know
6468 * about ATI2N. I cannot check this because all my Vista+ machines support
6469 * ATI2N in hardware, but none of my WinXP machines do. */
6470 format_known
= tex_support
|| cube_support
|| surface_support
;
6472 for (w
= 1; w
<= 8; w
++)
6474 for (h
= 1; h
<= 8; h
++)
6476 BOOL block_aligned
= TRUE
;
6479 if (w
& (formats
[i
].block_width
- 1) || h
& (formats
[i
].block_height
- 1))
6480 block_aligned
= FALSE
;
6482 size_is_pow2
= !(w
& (w
- 1) || h
& (h
- 1));
6484 for (j
= 0; j
< ARRAY_SIZE(create_tests
); j
++)
6488 BOOL may_succeed
= FALSE
;
6489 IUnknown
**check_null
;
6491 if (!formats
[i
].core_fmt
)
6493 /* AMD warns against creating ATI2N textures smaller than
6494 * the block size because the runtime cannot calculate the
6495 * correct texture size. Generalize this for all extension
6497 if (w
< formats
[i
].block_width
|| h
< formats
[i
].block_height
)
6501 texture
= (IDirect3DTexture8
*)0xdeadbeef;
6502 cube_texture
= (IDirect3DCubeTexture8
*)0xdeadbeef;
6503 surface
= (IDirect3DSurface8
*)0xdeadbeef;
6505 switch (create_tests
[j
].rtype
)
6507 case D3DRTYPE_TEXTURE
:
6508 check_null
= (IUnknown
**)&texture
;
6509 hr
= IDirect3DDevice8_CreateTexture(device
, w
, h
, 1, 0,
6510 formats
[i
].fmt
, create_tests
[j
].pool
, &texture
);
6511 support
= tex_support
;
6515 case D3DRTYPE_CUBETEXTURE
:
6518 check_null
= (IUnknown
**)&cube_texture
;
6519 hr
= IDirect3DDevice8_CreateCubeTexture(device
, w
, 1, 0,
6520 formats
[i
].fmt
, create_tests
[j
].pool
, &cube_texture
);
6521 support
= cube_support
;
6525 case D3DRTYPE_SURFACE
:
6526 check_null
= (IUnknown
**)&surface
;
6527 hr
= IDirect3DDevice8_CreateImageSurface(device
, w
, h
,
6528 formats
[i
].fmt
, &surface
);
6529 support
= surface_support
;
6540 if (create_tests
[j
].need_driver_support
&& !support
)
6541 expect_hr
= D3DERR_INVALIDCALL
;
6542 else if (create_tests
[j
].need_runtime_support
&& !formats
[i
].core_fmt
&& !format_known
)
6543 expect_hr
= D3DERR_INVALIDCALL
;
6544 else if (formats
[i
].create_size_checked
&& !block_aligned
)
6545 expect_hr
= D3DERR_INVALIDCALL
;
6546 else if (pow2
&& !size_is_pow2
&& create_tests
[j
].need_driver_support
)
6547 expect_hr
= D3DERR_INVALIDCALL
;
6551 if (!formats
[i
].core_fmt
&& !format_known
&& FAILED(expect_hr
))
6554 /* Wine knows about ATI2N and happily creates a scratch resource even if GL
6555 * does not support it. Accept scratch creation of extension formats on
6556 * Windows as well if it occurs. We don't really care if e.g. a Windows 7
6557 * on an r200 GPU creates scratch ATI2N texture even though the card doesn't
6559 ok(hr
== expect_hr
|| ((SUCCEEDED(hr
) && may_succeed
)),
6560 "Got unexpected hr %#lx for format %s, pool %s, type %s, size %ux%u.\n",
6561 hr
, formats
[i
].name
, create_tests
[j
].pool_name
, create_tests
[j
].type_name
, w
, h
);
6564 ok(*check_null
== NULL
, "Got object ptr %p, expected NULL.\n", *check_null
);
6566 IUnknown_Release(*check_null
);
6571 hr
= IDirect3D8_CheckDeviceFormat(d3d
, 0, D3DDEVTYPE_HAL
, D3DFMT_X8R8G8B8
,
6572 D3DUSAGE_DYNAMIC
, D3DRTYPE_TEXTURE
, formats
[i
].fmt
);
6575 skip("Format %s not supported, skipping lockrect offset tests.\n", formats
[i
].name
);
6579 for (j
= 0; j
< ARRAY_SIZE(pools
); ++j
)
6581 hr
= IDirect3DDevice8_CreateTexture(device
, 128, 128, 1,
6582 pools
[j
].pool
== D3DPOOL_DEFAULT
? D3DUSAGE_DYNAMIC
: 0,
6583 formats
[i
].fmt
, pools
[j
].pool
, &texture
);
6584 ok(SUCCEEDED(hr
), "Failed to create texture, hr %#lx.\n", hr
);
6585 hr
= IDirect3DTexture8_GetSurfaceLevel(texture
, 0, &surface
);
6586 ok(SUCCEEDED(hr
), "Failed to get surface level, hr %#lx.\n", hr
);
6587 IDirect3DTexture8_Release(texture
);
6589 if (formats
[i
].block_width
> 1)
6591 SetRect(&rect
, formats
[i
].block_width
>> 1, 0, formats
[i
].block_width
, formats
[i
].block_height
);
6592 hr
= IDirect3DSurface8_LockRect(surface
, &locked_rect
, &rect
, 0);
6593 ok(FAILED(hr
) == !pools
[j
].success
|| broken(formats
[i
].broken
),
6594 "Partial block lock %s, expected %s, format %s, pool %s.\n",
6595 SUCCEEDED(hr
) ? "succeeded" : "failed",
6596 pools
[j
].success
? "success" : "failure", formats
[i
].name
, pools
[j
].name
);
6599 hr
= IDirect3DSurface8_UnlockRect(surface
);
6600 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
6603 SetRect(&rect
, 0, 0, formats
[i
].block_width
>> 1, formats
[i
].block_height
);
6604 hr
= IDirect3DSurface8_LockRect(surface
, &locked_rect
, &rect
, 0);
6605 ok(FAILED(hr
) == !pools
[j
].success
|| broken(formats
[i
].broken
),
6606 "Partial block lock %s, expected %s, format %s, pool %s.\n",
6607 SUCCEEDED(hr
) ? "succeeded" : "failed",
6608 pools
[j
].success
? "success" : "failure", formats
[i
].name
, pools
[j
].name
);
6611 hr
= IDirect3DSurface8_UnlockRect(surface
);
6612 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
6616 if (formats
[i
].block_height
> 1)
6618 SetRect(&rect
, 0, formats
[i
].block_height
>> 1, formats
[i
].block_width
, formats
[i
].block_height
);
6619 hr
= IDirect3DSurface8_LockRect(surface
, &locked_rect
, &rect
, 0);
6620 ok(FAILED(hr
) == !pools
[j
].success
|| broken(formats
[i
].broken
),
6621 "Partial block lock %s, expected %s, format %s, pool %s.\n",
6622 SUCCEEDED(hr
) ? "succeeded" : "failed",
6623 pools
[j
].success
? "success" : "failure", formats
[i
].name
, pools
[j
].name
);
6626 hr
= IDirect3DSurface8_UnlockRect(surface
);
6627 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
6630 SetRect(&rect
, 0, 0, formats
[i
].block_width
, formats
[i
].block_height
>> 1);
6631 hr
= IDirect3DSurface8_LockRect(surface
, &locked_rect
, &rect
, 0);
6632 ok(FAILED(hr
) == !pools
[j
].success
|| broken(formats
[i
].broken
),
6633 "Partial block lock %s, expected %s, format %s, pool %s.\n",
6634 SUCCEEDED(hr
) ? "succeeded" : "failed",
6635 pools
[j
].success
? "success" : "failure", formats
[i
].name
, pools
[j
].name
);
6638 hr
= IDirect3DSurface8_UnlockRect(surface
);
6639 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
6643 for (k
= 0; k
< ARRAY_SIZE(invalid
); ++k
)
6645 hr
= IDirect3DSurface8_LockRect(surface
, &locked_rect
, &invalid
[k
], 0);
6646 ok(FAILED(hr
) == !pools
[j
].success
, "Got hr %#lx, format %s, pool %s, case %u.\n",
6647 hr
, formats
[i
].name
, pools
[j
].name
, k
);
6650 hr
= IDirect3DSurface8_UnlockRect(surface
);
6651 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
6655 SetRect(&rect
, 0, 0, formats
[i
].block_width
, formats
[i
].block_height
);
6656 hr
= IDirect3DSurface8_LockRect(surface
, &locked_rect
, &rect
, 0);
6657 ok(hr
== D3D_OK
, "Got unexpected hr %#lx for format %s, pool %s.\n", hr
, formats
[i
].name
, pools
[j
].name
);
6658 hr
= IDirect3DSurface8_UnlockRect(surface
);
6659 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
6661 IDirect3DSurface8_Release(surface
);
6664 if (formats
[i
].block_width
== 1 && formats
[i
].block_height
== 1)
6666 if (!formats
[i
].core_fmt
)
6669 hr
= IDirect3DDevice8_CreateTexture(device
, formats
[i
].block_width
, formats
[i
].block_height
, 2,
6670 D3DUSAGE_DYNAMIC
, formats
[i
].fmt
, D3DPOOL_DEFAULT
, &texture
);
6671 ok(SUCCEEDED(hr
), "Failed to create texture, hr %#lx, format %s.\n", hr
, formats
[i
].name
);
6673 hr
= IDirect3DTexture8_LockRect(texture
, 1, &locked_rect
, NULL
, 0);
6674 ok(SUCCEEDED(hr
), "Failed lock texture, hr %#lx.\n", hr
);
6675 hr
= IDirect3DTexture8_UnlockRect(texture
, 1);
6676 ok(SUCCEEDED(hr
), "Failed lock texture, hr %#lx.\n", hr
);
6680 rect
.right
= formats
[i
].block_width
== 1 ? 1 : formats
[i
].block_width
>> 1;
6681 rect
.bottom
= formats
[i
].block_height
== 1 ? 1 : formats
[i
].block_height
>> 1;
6682 hr
= IDirect3DTexture8_LockRect(texture
, 1, &locked_rect
, &rect
, 0);
6683 ok(SUCCEEDED(hr
), "Failed lock texture, hr %#lx.\n", hr
);
6684 hr
= IDirect3DTexture8_UnlockRect(texture
, 1);
6685 ok(SUCCEEDED(hr
), "Failed lock texture, hr %#lx.\n", hr
);
6687 rect
.right
= formats
[i
].block_width
;
6688 rect
.bottom
= formats
[i
].block_height
;
6689 hr
= IDirect3DTexture8_LockRect(texture
, 1, &locked_rect
, &rect
, 0);
6690 ok(hr
== D3DERR_INVALIDCALL
, "Got unexpected hr %#lx.\n", hr
);
6692 IDirect3DTexture8_UnlockRect(texture
, 1);
6694 IDirect3DTexture8_Release(texture
);
6697 refcount
= IDirect3DDevice8_Release(device
);
6698 ok(!refcount
, "Device has %lu references left.\n", refcount
);
6699 IDirect3D8_Release(d3d
);
6700 DestroyWindow(window
);
6703 static void test_set_palette(void)
6705 IDirect3DDevice8
*device
;
6710 PALETTEENTRY pal
[256];
6714 window
= create_window();
6715 d3d8
= Direct3DCreate8(D3D_SDK_VERSION
);
6716 ok(!!d3d8
, "Failed to create a D3D object.\n");
6717 if (!(device
= create_device(d3d8
, window
, NULL
)))
6719 skip("Failed to create a D3D device, skipping tests.\n");
6720 IDirect3D8_Release(d3d8
);
6721 DestroyWindow(window
);
6725 for (i
= 0; i
< ARRAY_SIZE(pal
); i
++)
6730 pal
[i
].peFlags
= 0xff;
6732 hr
= IDirect3DDevice8_SetPaletteEntries(device
, 0, pal
);
6733 ok(SUCCEEDED(hr
), "Failed to set palette entries, hr %#lx.\n", hr
);
6735 hr
= IDirect3DDevice8_GetDeviceCaps(device
, &caps
);
6736 ok(SUCCEEDED(hr
), "Failed to get device caps, hr %#lx.\n", hr
);
6737 for (i
= 0; i
< ARRAY_SIZE(pal
); i
++)
6744 if (caps
.TextureCaps
& D3DPTEXTURECAPS_ALPHAPALETTE
)
6746 hr
= IDirect3DDevice8_SetPaletteEntries(device
, 0, pal
);
6747 ok(SUCCEEDED(hr
), "Failed to set palette entries, hr %#lx.\n", hr
);
6751 hr
= IDirect3DDevice8_SetPaletteEntries(device
, 0, pal
);
6752 ok(hr
== D3DERR_INVALIDCALL
, "Got hr %#lx.\n", hr
);
6755 refcount
= IDirect3DDevice8_Release(device
);
6756 ok(!refcount
, "Device has %u references left.\n", refcount
);
6757 IDirect3D8_Release(d3d8
);
6758 DestroyWindow(window
);
6761 static void test_pinned_buffers(void)
6771 {CREATE_DEVICE_SWVP_ONLY
, D3DUSAGE_DYNAMIC
| D3DUSAGE_WRITEONLY
, D3DPOOL_DEFAULT
},
6772 {0, 0, D3DPOOL_MANAGED
},
6773 {0, 0, D3DPOOL_SYSTEMMEM
},
6775 static const unsigned int vertex_count
= 1024;
6776 struct device_desc device_desc
;
6777 IDirect3DVertexBuffer8
*buffer
;
6778 D3DVERTEXBUFFER_DESC desc
;
6779 IDirect3DDevice8
*device
;
6780 struct vec3
*ptr
, *ptr2
;
6781 unsigned int i
, test
;
6787 window
= create_window();
6788 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
6789 ok(!!d3d
, "Failed to create a D3D object.\n");
6791 for (test
= 0; test
< ARRAY_SIZE(tests
); ++test
)
6793 device_desc
.adapter_ordinal
= D3DADAPTER_DEFAULT
;
6794 device_desc
.device_window
= window
;
6795 device_desc
.width
= 640;
6796 device_desc
.height
= 480;
6797 device_desc
.flags
= tests
[test
].device_flags
;
6798 if (!(device
= create_device(d3d
, window
, &device_desc
)))
6800 skip("Test %u: failed to create a D3D device.\n", test
);
6804 hr
= IDirect3DDevice8_CreateVertexBuffer(device
, vertex_count
* sizeof(*ptr
),
6805 tests
[test
].usage
, 0, tests
[test
].pool
, &buffer
);
6806 ok(hr
== D3D_OK
, "Test %u: got unexpected hr %#lx.\n", test
, hr
);
6807 hr
= IDirect3DVertexBuffer8_GetDesc(buffer
, &desc
);
6808 ok(hr
== D3D_OK
, "Test %u: got unexpected hr %#lx.\n", test
, hr
);
6809 ok(desc
.Pool
== tests
[test
].pool
, "Test %u: got unexpected pool %#x.\n", test
, desc
.Pool
);
6810 ok(desc
.Usage
== tests
[test
].usage
, "Test %u: got unexpected usage %#lx.\n", test
, desc
.Usage
);
6812 hr
= IDirect3DVertexBuffer8_Lock(buffer
, 0, vertex_count
* sizeof(*ptr
), (BYTE
**)&ptr
, D3DLOCK_DISCARD
);
6813 ok(hr
== D3D_OK
, "Test %u: got unexpected hr %#lx.\n", test
, hr
);
6814 for (i
= 0; i
< vertex_count
; ++i
)
6816 ptr
[i
].x
= i
* 1.0f
;
6817 ptr
[i
].y
= i
* 2.0f
;
6818 ptr
[i
].z
= i
* 3.0f
;
6820 hr
= IDirect3DVertexBuffer8_Unlock(buffer
);
6821 ok(hr
== D3D_OK
, "Test %u: got unexpected hr %#lx.\n", test
, hr
);
6823 hr
= IDirect3DDevice8_SetVertexShader(device
, D3DFVF_XYZ
);
6824 ok(hr
== D3D_OK
, "Test %u: got unexpected hr %#lx.\n", test
, hr
);
6825 hr
= IDirect3DDevice8_SetStreamSource(device
, 0, buffer
, sizeof(*ptr
));
6826 ok(hr
== D3D_OK
, "Test %u: got unexpected hr %#lx.\n", test
, hr
);
6827 hr
= IDirect3DDevice8_BeginScene(device
);
6828 ok(hr
== D3D_OK
, "Test %u: got unexpected hr %#lx.\n", test
, hr
);
6829 hr
= IDirect3DDevice8_DrawPrimitive(device
, D3DPT_TRIANGLELIST
, 0, 2);
6830 ok(hr
== D3D_OK
, "Test %u: got unexpected hr %#lx.\n", test
, hr
);
6831 hr
= IDirect3DDevice8_EndScene(device
);
6832 ok(hr
== D3D_OK
, "Test %u: got unexpected hr %#lx.\n", test
, hr
);
6834 hr
= IDirect3DVertexBuffer8_Lock(buffer
, 0, vertex_count
* sizeof(*ptr2
), (BYTE
**)&ptr2
, D3DLOCK_DISCARD
);
6835 ok(hr
== D3D_OK
, "Test %u: got unexpected hr %#lx.\n", test
, hr
);
6836 ok(ptr2
== ptr
, "Test %u: got unexpected ptr2 %p, expected %p.\n", test
, ptr2
, ptr
);
6837 for (i
= 0; i
< vertex_count
; ++i
)
6839 if (ptr2
[i
].x
!= i
* 1.0f
|| ptr2
[i
].y
!= i
* 2.0f
|| ptr2
[i
].z
!= i
* 3.0f
)
6841 ok(FALSE
, "Test %u: got unexpected vertex %u {%.8e, %.8e, %.8e}, expected {%.8e, %.8e, %.8e}.\n",
6842 test
, i
, ptr2
[i
].x
, ptr2
[i
].y
, ptr2
[i
].z
, i
* 1.0f
, i
* 2.0f
, i
* 3.0f
);
6846 hr
= IDirect3DVertexBuffer8_Unlock(buffer
);
6847 ok(hr
== D3D_OK
, "Test %u: got unexpected hr %#lx.\n", test
, hr
);
6849 IDirect3DVertexBuffer8_Release(buffer
);
6850 refcount
= IDirect3DDevice8_Release(device
);
6851 ok(!refcount
, "Test %u: device has %u references left.\n", test
, refcount
);
6853 IDirect3D8_Release(d3d
);
6854 DestroyWindow(window
);
6857 static void test_npot_textures(void)
6859 IDirect3DDevice8
*device
= NULL
;
6865 IDirect3DTexture8
*texture
;
6866 IDirect3DCubeTexture8
*cube_texture
;
6867 IDirect3DVolumeTexture8
*volume_texture
;
6871 const char *pool_name
;
6876 { D3DPOOL_DEFAULT
, "D3DPOOL_DEFAULT", D3DERR_INVALIDCALL
},
6877 { D3DPOOL_MANAGED
, "D3DPOOL_MANAGED", D3DERR_INVALIDCALL
},
6878 { D3DPOOL_SYSTEMMEM
, "D3DPOOL_SYSTEMMEM", D3DERR_INVALIDCALL
},
6879 { D3DPOOL_SCRATCH
, "D3DPOOL_SCRATCH", D3D_OK
},
6881 unsigned int i
, levels
;
6882 BOOL tex_pow2
, cube_pow2
, vol_pow2
;
6884 window
= create_window();
6885 d3d8
= Direct3DCreate8(D3D_SDK_VERSION
);
6886 ok(!!d3d8
, "Failed to create a D3D object.\n");
6887 if (!(device
= create_device(d3d8
, window
, NULL
)))
6889 skip("Failed to create a D3D device, skipping tests.\n");
6893 hr
= IDirect3DDevice8_GetDeviceCaps(device
, &caps
);
6894 ok(SUCCEEDED(hr
), "Failed to get caps, hr %#lx.\n", hr
);
6895 tex_pow2
= !!(caps
.TextureCaps
& D3DPTEXTURECAPS_POW2
);
6896 cube_pow2
= !!(caps
.TextureCaps
& D3DPTEXTURECAPS_CUBEMAP_POW2
);
6897 vol_pow2
= !!(caps
.TextureCaps
& D3DPTEXTURECAPS_VOLUMEMAP_POW2
);
6898 ok(cube_pow2
== tex_pow2
, "Cube texture and 2d texture pow2 restrictions mismatch.\n");
6899 ok(vol_pow2
== tex_pow2
, "Volume texture and 2d texture pow2 restrictions mismatch.\n");
6901 for (i
= 0; i
< ARRAY_SIZE(pools
); i
++)
6903 for (levels
= 0; levels
<= 2; levels
++)
6907 hr
= IDirect3DDevice8_CreateTexture(device
, 10, 10, levels
, 0, D3DFMT_X8R8G8B8
,
6908 pools
[i
].pool
, &texture
);
6913 else if (caps
.TextureCaps
& D3DPTEXTURECAPS_NONPOW2CONDITIONAL
)
6918 expected
= pools
[i
].hr
;
6922 expected
= pools
[i
].hr
;
6924 ok(hr
== expected
, "CreateTexture(w=h=10, %s, levels=%u) returned hr %#lx, expected %#lx.\n",
6925 pools
[i
].pool_name
, levels
, hr
, expected
);
6928 IDirect3DTexture8_Release(texture
);
6931 hr
= IDirect3DDevice8_CreateCubeTexture(device
, 3, 1, 0, D3DFMT_X8R8G8B8
,
6932 pools
[i
].pool
, &cube_texture
);
6935 ok(hr
== pools
[i
].hr
, "CreateCubeTexture(EdgeLength=3, %s) returned hr %#lx.\n", pools
[i
].pool_name
, hr
);
6939 ok(SUCCEEDED(hr
), "CreateCubeTexture(EdgeLength=3, %s) returned hr %#lx.\n", pools
[i
].pool_name
, hr
);
6943 IDirect3DCubeTexture8_Release(cube_texture
);
6945 hr
= IDirect3DDevice8_CreateVolumeTexture(device
, 2, 2, 3, 1, 0, D3DFMT_X8R8G8B8
,
6946 pools
[i
].pool
, &volume_texture
);
6949 ok(hr
== pools
[i
].hr
, "CreateVolumeTextur(Depth=3, %s) returned hr %#lx.\n", pools
[i
].pool_name
, hr
);
6953 ok(SUCCEEDED(hr
), "CreateVolumeTextur(Depth=3, %s) returned hr %#lx.\n", pools
[i
].pool_name
, hr
);
6957 IDirect3DVolumeTexture8_Release(volume_texture
);
6963 refcount
= IDirect3DDevice8_Release(device
);
6964 ok(!refcount
, "Device has %lu references left.\n", refcount
);
6966 IDirect3D8_Release(d3d8
);
6967 DestroyWindow(window
);
6971 static void test_volume_locking(void)
6973 IDirect3DDevice8
*device
;
6977 IDirect3DVolumeTexture8
*texture
;
6979 D3DLOCKED_BOX locked_box
;
6986 HRESULT create_hr
, lock_hr
;
6990 { D3DPOOL_DEFAULT
, 0, D3D_OK
, D3DERR_INVALIDCALL
},
6991 { D3DPOOL_DEFAULT
, D3DUSAGE_DYNAMIC
, D3D_OK
, D3D_OK
},
6992 { D3DPOOL_SYSTEMMEM
, 0, D3D_OK
, D3D_OK
},
6993 { D3DPOOL_SYSTEMMEM
, D3DUSAGE_DYNAMIC
, D3D_OK
, D3D_OK
},
6994 { D3DPOOL_MANAGED
, 0, D3D_OK
, D3D_OK
},
6995 { D3DPOOL_MANAGED
, D3DUSAGE_DYNAMIC
, D3DERR_INVALIDCALL
, D3D_OK
},
6996 { D3DPOOL_SCRATCH
, 0, D3D_OK
, D3D_OK
},
6997 { D3DPOOL_SCRATCH
, D3DUSAGE_DYNAMIC
, D3DERR_INVALIDCALL
, D3D_OK
},
7000 window
= create_window();
7001 d3d8
= Direct3DCreate8(D3D_SDK_VERSION
);
7002 ok(!!d3d8
, "Failed to create a D3D object.\n");
7003 if (!(device
= create_device(d3d8
, window
, NULL
)))
7005 skip("Failed to create a D3D device, skipping tests.\n");
7006 IDirect3D8_Release(d3d8
);
7007 DestroyWindow(window
);
7011 hr
= IDirect3DDevice8_GetDeviceCaps(device
, &caps
);
7012 ok(SUCCEEDED(hr
), "Failed to get caps, hr %#lx.\n", hr
);
7013 if (!(caps
.TextureCaps
& D3DPTEXTURECAPS_VOLUMEMAP
))
7015 skip("Volume textures not supported, skipping test.\n");
7019 for (i
= 0; i
< ARRAY_SIZE(tests
); i
++)
7021 hr
= IDirect3DDevice8_CreateVolumeTexture(device
, 4, 4, 4, 1, tests
[i
].usage
,
7022 D3DFMT_A8R8G8B8
, tests
[i
].pool
, &texture
);
7023 ok(hr
== tests
[i
].create_hr
, "Creating volume texture pool=%u, usage=%#lx returned %#lx, expected %#lx.\n",
7024 tests
[i
].pool
, tests
[i
].usage
, hr
, tests
[i
].create_hr
);
7028 locked_box
.pBits
= (void *)0xdeadbeef;
7029 hr
= IDirect3DVolumeTexture8_LockBox(texture
, 0, &locked_box
, NULL
, 0);
7030 ok(hr
== tests
[i
].lock_hr
, "Lock returned %#lx, expected %#lx.\n", hr
, tests
[i
].lock_hr
);
7033 hr
= IDirect3DVolumeTexture8_UnlockBox(texture
, 0);
7034 ok(SUCCEEDED(hr
), "Failed to unlock volume texture, hr %#lx.\n", hr
);
7038 ok (locked_box
.pBits
== NULL
, "Failed lock set pBits = %p, expected NULL.\n", locked_box
.pBits
);
7040 IDirect3DVolumeTexture8_Release(texture
);
7044 refcount
= IDirect3DDevice8_Release(device
);
7045 ok(!refcount
, "Device has %lu references left.\n", refcount
);
7046 IDirect3D8_Release(d3d8
);
7047 DestroyWindow(window
);
7050 static void test_update_texture_pool(void)
7059 {D3DPOOL_DEFAULT
, D3DUSAGE_DYNAMIC
},
7060 {D3DPOOL_MANAGED
, 0},
7061 {D3DPOOL_SYSTEMMEM
, 0},
7062 {D3DPOOL_SCRATCH
, 0},
7065 unsigned int expect_colour
, colour
, i
, j
;
7066 IDirect3DVolumeTexture8
*src_3d
, *dst_3d
;
7067 IDirect3DTexture8
*src_2d
, *dst_2d
;
7068 D3DLOCKED_RECT locked_rect
;
7069 IDirect3DDevice8
*device
;
7070 D3DLOCKED_BOX locked_box
;
7077 window
= create_window();
7078 d3d8
= Direct3DCreate8(D3D_SDK_VERSION
);
7079 ok(!!d3d8
, "Failed to create a D3D object.\n");
7080 if (!(device
= create_device(d3d8
, window
, NULL
)))
7082 skip("Failed to create a D3D device, skipping tests.\n");
7083 IDirect3D8_Release(d3d8
);
7084 DestroyWindow(window
);
7088 hr
= IDirect3DDevice8_GetDeviceCaps(device
, &caps
);
7089 ok(hr
== S_OK
, "Failed to get caps, hr %#lx.\n", hr
);
7091 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
7093 for (j
= 0; j
< ARRAY_SIZE(tests
); ++j
)
7095 winetest_push_context("Source test %u, destination test %u", i
, j
);
7097 hr
= IDirect3DDevice8_CreateTexture(device
, 1, 1, 1,
7098 tests
[i
].usage
, D3DFMT_A8R8G8B8
, tests
[i
].pool
, &src_2d
);
7099 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7100 hr
= IDirect3DDevice8_CreateTexture(device
, 1, 1, 1,
7101 tests
[j
].usage
, D3DFMT_A8R8G8B8
, tests
[j
].pool
, &dst_2d
);
7102 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7104 hr
= IDirect3DTexture8_LockRect(src_2d
, 0, &locked_rect
, NULL
, 0);
7105 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7106 *((DWORD
*)locked_rect
.pBits
) = 0x11223344;
7107 hr
= IDirect3DTexture8_UnlockRect(src_2d
, 0);
7108 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7110 hr
= IDirect3DTexture8_LockRect(dst_2d
, 0, &locked_rect
, NULL
, 0);
7111 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7112 *((DWORD
*)locked_rect
.pBits
) = 0x44332211;
7113 hr
= IDirect3DTexture8_UnlockRect(dst_2d
, 0);
7114 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7116 hr
= IDirect3DDevice8_UpdateTexture(device
, (IDirect3DBaseTexture8
*)src_2d
,
7117 (IDirect3DBaseTexture8
*)dst_2d
);
7118 if (tests
[i
].pool
== D3DPOOL_SYSTEMMEM
&& tests
[j
].pool
== D3DPOOL_DEFAULT
)
7120 expect_colour
= 0x11223344;
7121 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7125 expect_colour
= 0x44332211;
7126 ok(hr
== D3DERR_INVALIDCALL
, "Got hr %#lx.\n", hr
);
7129 hr
= IDirect3DTexture8_LockRect(dst_2d
, 0, &locked_rect
, NULL
, 0);
7130 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7131 colour
= *((DWORD
*)locked_rect
.pBits
);
7132 ok(colour
== expect_colour
, "Expected colour %08x, got %08x.\n", expect_colour
, colour
);
7133 hr
= IDirect3DTexture8_UnlockRect(dst_2d
, 0);
7134 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7136 IDirect3DTexture8_Release(src_2d
);
7137 IDirect3DTexture8_Release(dst_2d
);
7139 if (!(caps
.TextureCaps
& D3DPTEXTURECAPS_VOLUMEMAP
))
7142 hr
= IDirect3DDevice8_CreateVolumeTexture(device
, 1, 1, 1, 1,
7143 tests
[i
].usage
, D3DFMT_A8R8G8B8
, tests
[i
].pool
, &src_3d
);
7144 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7145 hr
= IDirect3DDevice8_CreateVolumeTexture(device
, 1, 1, 1, 1,
7146 tests
[j
].usage
, D3DFMT_A8R8G8B8
, tests
[j
].pool
, &dst_3d
);
7147 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7149 hr
= IDirect3DVolumeTexture8_LockBox(src_3d
, 0, &locked_box
, NULL
, 0);
7150 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7151 *((DWORD
*)locked_box
.pBits
) = 0x11223344;
7152 hr
= IDirect3DVolumeTexture8_UnlockBox(src_3d
, 0);
7153 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7155 hr
= IDirect3DVolumeTexture8_LockBox(dst_3d
, 0, &locked_box
, NULL
, 0);
7156 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7157 *((DWORD
*)locked_box
.pBits
) = 0x44332211;
7158 hr
= IDirect3DVolumeTexture8_UnlockBox(dst_3d
, 0);
7159 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7161 hr
= IDirect3DDevice8_UpdateTexture(device
, (IDirect3DBaseTexture8
*)src_3d
,
7162 (IDirect3DBaseTexture8
*)dst_3d
);
7163 if (tests
[i
].pool
== D3DPOOL_SYSTEMMEM
&& tests
[j
].pool
== D3DPOOL_DEFAULT
)
7165 expect_colour
= 0x11223344;
7166 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7170 expect_colour
= 0x44332211;
7171 ok(hr
== D3DERR_INVALIDCALL
, "Got hr %#lx.\n", hr
);
7174 hr
= IDirect3DVolumeTexture8_LockBox(dst_3d
, 0, &locked_box
, NULL
, 0);
7175 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7176 colour
= *((DWORD
*)locked_box
.pBits
);
7177 ok(colour
== expect_colour
, "Expected colour %08x, got %08x.\n", expect_colour
, colour
);
7178 hr
= IDirect3DVolumeTexture8_UnlockBox(dst_3d
, 0);
7179 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7181 IDirect3DVolumeTexture8_Release(src_3d
);
7182 IDirect3DVolumeTexture8_Release(dst_3d
);
7184 winetest_pop_context();
7188 refcount
= IDirect3DDevice8_Release(device
);
7189 ok(!refcount
, "Device has %lu references left.\n", refcount
);
7190 IDirect3D8_Release(d3d8
);
7191 DestroyWindow(window
);
7194 static void test_update_volumetexture(void)
7196 D3DADAPTER_IDENTIFIER8 identifier
;
7197 IDirect3DDevice8
*device
;
7201 IDirect3DVolumeTexture8
*src
, *dst
;
7209 UINT src_size
, dst_size
;
7210 UINT src_lvl
, dst_lvl
;
7211 D3DFORMAT src_fmt
, dst_fmt
;
7215 { 8, 8, 0, 0, D3DFMT_A8R8G8B8
, D3DFMT_A8R8G8B8
},
7216 { 8, 8, 4, 4, D3DFMT_A8R8G8B8
, D3DFMT_A8R8G8B8
},
7217 { 8, 8, 2, 2, D3DFMT_A8R8G8B8
, D3DFMT_A8R8G8B8
},
7218 { 8, 8, 1, 1, D3DFMT_A8R8G8B8
, D3DFMT_A8R8G8B8
},
7219 { 8, 8, 4, 0, D3DFMT_A8R8G8B8
, D3DFMT_A8R8G8B8
},
7220 { 8, 8, 1, 4, D3DFMT_A8R8G8B8
, D3DFMT_A8R8G8B8
}, /* Different level count */
7221 { 4, 8, 1, 1, D3DFMT_A8R8G8B8
, D3DFMT_A8R8G8B8
}, /* Different size */
7222 { 8, 8, 4, 4, D3DFMT_A8R8G8B8
, D3DFMT_X8R8G8B8
}, /* Different format */
7225 window
= create_window();
7226 d3d8
= Direct3DCreate8(D3D_SDK_VERSION
);
7227 ok(!!d3d8
, "Failed to create a D3D object.\n");
7228 hr
= IDirect3D8_GetAdapterIdentifier(d3d8
, D3DADAPTER_DEFAULT
, 0, &identifier
);
7229 ok(SUCCEEDED(hr
), "Failed to get adapter identifier, hr %#lx.\n", hr
);
7230 is_warp
= adapter_is_warp(&identifier
);
7231 if (!(device
= create_device(d3d8
, window
, NULL
)))
7233 skip("Failed to create a D3D device, skipping tests.\n");
7234 IDirect3D8_Release(d3d8
);
7235 DestroyWindow(window
);
7239 hr
= IDirect3DDevice8_GetDeviceCaps(device
, &caps
);
7240 ok(SUCCEEDED(hr
), "Failed to get caps, hr %#lx.\n", hr
);
7241 if (!(caps
.TextureCaps
& D3DPTEXTURECAPS_VOLUMEMAP
) || !(caps
.TextureCaps
& D3DPTEXTURECAPS_MIPVOLUMEMAP
))
7243 skip("Mipmapped volume maps not supported.\n");
7247 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
7249 hr
= IDirect3DDevice8_CreateVolumeTexture(device
,
7250 tests
[i
].src_size
, tests
[i
].src_size
, tests
[i
].src_size
,
7251 tests
[i
].src_lvl
, 0, tests
[i
].src_fmt
, D3DPOOL_SYSTEMMEM
, &src
);
7252 ok(SUCCEEDED(hr
), "Failed to create volume texture, hr %#lx, case %u.\n", hr
, i
);
7253 hr
= IDirect3DDevice8_CreateVolumeTexture(device
,
7254 tests
[i
].dst_size
, tests
[i
].dst_size
, tests
[i
].dst_size
,
7255 tests
[i
].dst_lvl
, 0, tests
[i
].dst_fmt
, D3DPOOL_DEFAULT
, &dst
);
7256 ok(SUCCEEDED(hr
), "Failed to create volume texture, hr %#lx, case %u.\n", hr
, i
);
7258 hr
= IDirect3DDevice8_UpdateTexture(device
, (IDirect3DBaseTexture8
*)src
, (IDirect3DBaseTexture8
*)dst
);
7259 todo_wine_if (FAILED(hr
))
7260 ok(SUCCEEDED(hr
) || (is_warp
&& (i
== 6 || i
== 7)), /* Fails with Win10 WARP driver */
7261 "Failed to update texture, hr %#lx, case %u.\n", hr
, i
);
7263 IDirect3DVolumeTexture8_Release(src
);
7264 IDirect3DVolumeTexture8_Release(dst
);
7267 /* As far as I can see, UpdateTexture on non-matching texture behaves like a memcpy. The raw data
7268 * stays the same in a format change, a 2x2x1 texture is copied into the first row of a 4x4x1 texture,
7269 * etc. I could not get it to segfault, but the nonexistent 5th pixel of a 2x2x1 texture is copied into
7270 * pixel 1x2x1 of a 4x4x1 texture, demonstrating a read beyond the texture's end. I suspect any bad
7271 * memory access is silently ignored by the runtime, in the kernel or on the GPU.
7273 * I'm not adding tests for this behavior until an application needs it. */
7276 refcount
= IDirect3DDevice8_Release(device
);
7277 ok(!refcount
, "Device has %lu references left.\n", refcount
);
7278 IDirect3D8_Release(d3d8
);
7279 DestroyWindow(window
);
7282 static void test_create_rt_ds_fail(void)
7284 IDirect3DDevice8
*device
;
7289 IDirect3DSurface8
*surface
;
7291 window
= create_window();
7292 d3d8
= Direct3DCreate8(D3D_SDK_VERSION
);
7293 ok(!!d3d8
, "Failed to create a D3D object.\n");
7294 if (!(device
= create_device(d3d8
, window
, NULL
)))
7296 skip("Failed to create a D3D device, skipping tests.\n");
7297 IDirect3D8_Release(d3d8
);
7298 DestroyWindow(window
);
7302 /* Output pointer == NULL segfaults on Windows. */
7304 surface
= (IDirect3DSurface8
*)0xdeadbeef;
7305 hr
= IDirect3DDevice8_CreateRenderTarget(device
, 4, 4, D3DFMT_D16
,
7306 D3DMULTISAMPLE_NONE
, FALSE
, &surface
);
7307 ok(hr
== D3DERR_INVALIDCALL
, "Creating a D16 render target returned hr %#lx.\n", hr
);
7308 ok(surface
== NULL
, "Got pointer %p, expected NULL.\n", surface
);
7310 IDirect3DSurface8_Release(surface
);
7312 surface
= (IDirect3DSurface8
*)0xdeadbeef;
7313 hr
= IDirect3DDevice8_CreateDepthStencilSurface(device
, 4, 4, D3DFMT_A8R8G8B8
,
7314 D3DMULTISAMPLE_NONE
, &surface
);
7315 ok(hr
== D3DERR_INVALIDCALL
, "Creating a A8R8G8B8 depth stencil returned hr %#lx.\n", hr
);
7316 ok(surface
== NULL
, "Got pointer %p, expected NULL.\n", surface
);
7318 IDirect3DSurface8_Release(surface
);
7320 refcount
= IDirect3DDevice8_Release(device
);
7321 ok(!refcount
, "Device has %lu references left.\n", refcount
);
7322 IDirect3D8_Release(d3d8
);
7323 DestroyWindow(window
);
7326 static void test_volume_blocks(void)
7328 IDirect3DDevice8
*device
;
7334 IDirect3DVolumeTexture8
*texture
;
7335 unsigned int w
, h
, d
, i
, j
;
7340 unsigned int block_width
;
7341 unsigned int block_height
;
7342 unsigned int block_depth
;
7343 unsigned int block_size
;
7344 unsigned int broken
;
7345 BOOL create_size_checked
, core_fmt
;
7349 /* Scratch volumes enforce DXTn block locks, unlike their surface counterparts.
7350 * ATI2N and YUV blocks are not enforced on any tested card (r200, gtx 460). */
7351 {D3DFMT_DXT1
, "D3DFMT_DXT1", 4, 4, 1, 8, 0, TRUE
, TRUE
},
7352 {D3DFMT_DXT2
, "D3DFMT_DXT2", 4, 4, 1, 16, 0, TRUE
, TRUE
},
7353 {D3DFMT_DXT3
, "D3DFMT_DXT3", 4, 4, 1, 16, 0, TRUE
, TRUE
},
7354 {D3DFMT_DXT4
, "D3DFMT_DXT4", 4, 4, 1, 16, 0, TRUE
, TRUE
},
7355 {D3DFMT_DXT5
, "D3DFMT_DXT5", 4, 4, 1, 16, 0, TRUE
, TRUE
},
7356 {D3DFMT_DXT5
, "D3DFMT_DXT5", 4, 4, 1, 16, 0, TRUE
, TRUE
},
7357 /* ATI2N has 2x2 blocks on all AMD cards and Geforce 7 cards,
7358 * which doesn't match the format spec. On newer Nvidia cards
7359 * it has the correct 4x4 block size.
7360 * ATI1N volume textures are only supported by AMD GPUs right
7361 * now and locking offsets seem just wrong. */
7362 {MAKEFOURCC('A','T','I','1'), "ATI1N", 4, 4, 1, 8, 2, FALSE
, FALSE
},
7363 {MAKEFOURCC('A','T','I','2'), "ATI2N", 4, 4, 1, 16, 1, FALSE
, FALSE
},
7364 {D3DFMT_YUY2
, "D3DFMT_YUY2", 2, 1, 1, 4, 1, FALSE
, TRUE
},
7365 {D3DFMT_UYVY
, "D3DFMT_UYVY", 2, 1, 1, 4, 1, FALSE
, TRUE
},
7371 BOOL need_driver_support
, need_runtime_support
;
7375 {D3DPOOL_DEFAULT
, "D3DPOOL_DEFAULT", TRUE
, FALSE
},
7376 {D3DPOOL_SCRATCH
, "D3DPOOL_SCRATCH", FALSE
, TRUE
},
7377 {D3DPOOL_SYSTEMMEM
, "D3DPOOL_SYSTEMMEM",TRUE
, FALSE
},
7378 {D3DPOOL_MANAGED
, "D3DPOOL_MANAGED", TRUE
, FALSE
},
7382 unsigned int x
, y
, z
, x2
, y2
, z2
;
7396 D3DLOCKED_BOX locked_box
;
7398 INT expected_row_pitch
, expected_slice_pitch
;
7401 unsigned int offset
, expected_offset
;
7403 window
= create_window();
7404 d3d8
= Direct3DCreate8(D3D_SDK_VERSION
);
7405 ok(!!d3d8
, "Failed to create a D3D object.\n");
7406 if (!(device
= create_device(d3d8
, window
, NULL
)))
7408 skip("Failed to create a D3D device, skipping tests.\n");
7409 IDirect3D8_Release(d3d8
);
7410 DestroyWindow(window
);
7413 hr
= IDirect3DDevice8_GetDeviceCaps(device
, &caps
);
7414 ok(SUCCEEDED(hr
), "Failed to get caps, hr %#lx.\n", hr
);
7415 pow2
= !!(caps
.TextureCaps
& D3DPTEXTURECAPS_VOLUMEMAP_POW2
);
7417 for (i
= 0; i
< ARRAY_SIZE(formats
); i
++)
7419 hr
= IDirect3D8_CheckDeviceFormat(d3d8
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
, D3DFMT_X8R8G8B8
,
7420 0, D3DRTYPE_VOLUMETEXTURE
, formats
[i
].fmt
);
7421 support
= SUCCEEDED(hr
);
7423 /* Test creation restrictions */
7424 for (w
= 1; w
<= 8; w
++)
7426 for (h
= 1; h
<= 8; h
++)
7428 for (d
= 1; d
<= 8; d
++)
7432 BOOL block_aligned
= TRUE
;
7434 if (w
& (formats
[i
].block_width
- 1) || h
& (formats
[i
].block_height
- 1))
7435 block_aligned
= FALSE
;
7437 size_is_pow2
= !((w
& (w
- 1)) || (h
& (h
- 1)) || (d
& (d
- 1)));
7439 for (j
= 0; j
< ARRAY_SIZE(create_tests
); j
++)
7441 BOOL may_succeed
= FALSE
;
7443 if (create_tests
[j
].need_runtime_support
&& !formats
[i
].core_fmt
&& !support
)
7444 expect_hr
= D3DERR_INVALIDCALL
;
7445 else if (formats
[i
].create_size_checked
&& !block_aligned
)
7446 expect_hr
= D3DERR_INVALIDCALL
;
7447 else if (pow2
&& !size_is_pow2
&& create_tests
[j
].need_driver_support
)
7448 expect_hr
= D3DERR_INVALIDCALL
;
7449 else if (create_tests
[j
].need_driver_support
&& !support
)
7450 expect_hr
= D3DERR_INVALIDCALL
;
7454 texture
= (IDirect3DVolumeTexture8
*)0xdeadbeef;
7455 hr
= IDirect3DDevice8_CreateVolumeTexture(device
, w
, h
, d
, 1, 0,
7456 formats
[i
].fmt
, create_tests
[j
].pool
, &texture
);
7458 /* Wine knows about ATI2N and happily creates a scratch resource even if GL
7459 * does not support it. Accept scratch creation of extension formats on
7460 * Windows as well if it occurs. We don't really care if e.g. a Windows 7
7461 * on an r200 GPU creates scratch ATI2N texture even though the card doesn't
7463 if (!formats
[i
].core_fmt
&& !support
&& FAILED(expect_hr
))
7466 ok(hr
== expect_hr
|| ((SUCCEEDED(hr
) && may_succeed
)),
7467 "Got unexpected hr %#lx for format %s, pool %s, size %ux%ux%u.\n",
7468 hr
, formats
[i
].name
, create_tests
[j
].name
, w
, h
, d
);
7471 ok(texture
== NULL
, "Got texture ptr %p, expected NULL.\n", texture
);
7473 IDirect3DVolumeTexture8_Release(texture
);
7479 if (!support
&& !formats
[i
].core_fmt
)
7482 hr
= IDirect3DDevice8_CreateVolumeTexture(device
, 24, 8, 8, 1, 0,
7483 formats
[i
].fmt
, D3DPOOL_SCRATCH
, &texture
);
7484 ok(SUCCEEDED(hr
), "Failed to create volume texture, hr %#lx.\n", hr
);
7486 /* Test lockrect offset */
7487 for (j
= 0; j
< ARRAY_SIZE(offset_tests
); j
++)
7489 unsigned int bytes_per_pixel
;
7490 bytes_per_pixel
= formats
[i
].block_size
/ (formats
[i
].block_width
* formats
[i
].block_height
);
7492 hr
= IDirect3DVolumeTexture8_LockBox(texture
, 0, &locked_box
, NULL
, 0);
7493 ok(SUCCEEDED(hr
), "Failed to unlock volume texture, hr %#lx.\n", hr
);
7495 base
= locked_box
.pBits
;
7496 if (formats
[i
].broken
== 1)
7498 expected_row_pitch
= bytes_per_pixel
* 24;
7500 else if (formats
[i
].broken
== 2)
7502 expected_row_pitch
= 24;
7506 expected_row_pitch
= (24 /* tex width */ + formats
[i
].block_height
- 1) / formats
[i
].block_width
7507 * formats
[i
].block_size
;
7509 ok(locked_box
.RowPitch
== expected_row_pitch
, "Got unexpected row pitch %d for format %s, expected %d.\n",
7510 locked_box
.RowPitch
, formats
[i
].name
, expected_row_pitch
);
7512 if (formats
[i
].broken
)
7514 expected_slice_pitch
= expected_row_pitch
* 8;
7518 expected_slice_pitch
= (8 /* tex height */ + formats
[i
].block_depth
- 1) / formats
[i
].block_height
7519 * expected_row_pitch
;
7521 ok(locked_box
.SlicePitch
== expected_slice_pitch
,
7522 "Got unexpected slice pitch %d for format %s, expected %d.\n",
7523 locked_box
.SlicePitch
, formats
[i
].name
, expected_slice_pitch
);
7525 hr
= IDirect3DVolumeTexture8_UnlockBox(texture
, 0);
7526 ok(SUCCEEDED(hr
), "Failed to unlock volume texture, hr %#lx, j %u.\n", hr
, j
);
7528 box
.Left
= offset_tests
[j
].x
;
7529 box
.Top
= offset_tests
[j
].y
;
7530 box
.Front
= offset_tests
[j
].z
;
7531 box
.Right
= offset_tests
[j
].x2
;
7532 box
.Bottom
= offset_tests
[j
].y2
;
7533 box
.Back
= offset_tests
[j
].z2
;
7534 hr
= IDirect3DVolumeTexture8_LockBox(texture
, 0, &locked_box
, &box
, 0);
7535 ok(SUCCEEDED(hr
), "Failed to lock volume texture, hr %#lx, j %u.\n", hr
, j
);
7537 offset
= (BYTE
*)locked_box
.pBits
- base
;
7538 if (formats
[i
].broken
== 1)
7540 expected_offset
= box
.Front
* expected_slice_pitch
7541 + box
.Top
* expected_row_pitch
7542 + box
.Left
* bytes_per_pixel
;
7544 else if (formats
[i
].broken
== 2)
7546 expected_offset
= box
.Front
* expected_slice_pitch
7547 + box
.Top
* expected_row_pitch
7552 expected_offset
= (box
.Front
/ formats
[i
].block_depth
) * expected_slice_pitch
7553 + (box
.Top
/ formats
[i
].block_height
) * expected_row_pitch
7554 + (box
.Left
/ formats
[i
].block_width
) * formats
[i
].block_size
;
7556 ok(offset
== expected_offset
, "Got unexpected offset %u for format %s, expected %u, box start %ux%ux%u.\n",
7557 offset
, formats
[i
].name
, expected_offset
, box
.Left
, box
.Top
, box
.Front
);
7559 hr
= IDirect3DVolumeTexture8_UnlockBox(texture
, 0);
7560 ok(SUCCEEDED(hr
), "Failed to unlock volume texture, hr %#lx.\n", hr
);
7563 /* Test partial block locks */
7566 if (formats
[i
].block_width
> 1)
7568 box
.Left
= formats
[i
].block_width
>> 1;
7570 box
.Right
= formats
[i
].block_width
;
7571 box
.Bottom
= formats
[i
].block_height
;
7572 hr
= IDirect3DVolumeTexture8_LockBox(texture
, 0, &locked_box
, &box
, 0);
7573 ok(FAILED(hr
) || broken(formats
[i
].broken
),
7574 "Partial block lock succeeded, expected failure, format %s.\n",
7578 hr
= IDirect3DVolumeTexture8_UnlockBox(texture
, 0);
7579 ok(SUCCEEDED(hr
), "Failed to unlock volume texture, hr %#lx.\n", hr
);
7584 box
.Right
= formats
[i
].block_width
>> 1;
7585 box
.Bottom
= formats
[i
].block_height
;
7586 hr
= IDirect3DVolumeTexture8_LockBox(texture
, 0, &locked_box
, &box
, 0);
7587 ok(FAILED(hr
) || broken(formats
[i
].broken
),
7588 "Partial block lock succeeded, expected failure, format %s.\n",
7592 hr
= IDirect3DVolumeTexture8_UnlockBox(texture
, 0);
7593 ok(SUCCEEDED(hr
), "Failed to unlock volume texture, hr %#lx.\n", hr
);
7597 if (formats
[i
].block_height
> 1)
7600 box
.Top
= formats
[i
].block_height
>> 1;
7601 box
.Right
= formats
[i
].block_width
;
7602 box
.Bottom
= formats
[i
].block_height
;
7603 hr
= IDirect3DVolumeTexture8_LockBox(texture
, 0, &locked_box
, &box
, 0);
7604 ok(FAILED(hr
) || broken(formats
[i
].broken
),
7605 "Partial block lock succeeded, expected failure, format %s.\n",
7609 hr
= IDirect3DVolumeTexture8_UnlockBox(texture
, 0);
7610 ok(SUCCEEDED(hr
), "Failed to unlock volume texture, hr %#lx.\n", hr
);
7615 box
.Right
= formats
[i
].block_width
;
7616 box
.Bottom
= formats
[i
].block_height
>> 1;
7617 hr
= IDirect3DVolumeTexture8_LockBox(texture
, 0, &locked_box
, &box
, 0);
7618 ok(FAILED(hr
) || broken(formats
[i
].broken
),
7619 "Partial block lock succeeded, expected failure, format %s.\n",
7623 hr
= IDirect3DVolumeTexture8_UnlockBox(texture
, 0);
7624 ok(SUCCEEDED(hr
), "Failed to unlock volume texture, hr %#lx.\n", hr
);
7628 /* Test full block lock */
7631 box
.Right
= formats
[i
].block_width
;
7632 box
.Bottom
= formats
[i
].block_height
;
7633 hr
= IDirect3DVolumeTexture8_LockBox(texture
, 0, &locked_box
, &box
, 0);
7634 ok(SUCCEEDED(hr
), "Failed to lock volume texture, hr %#lx.\n", hr
);
7635 hr
= IDirect3DVolumeTexture8_UnlockBox(texture
, 0);
7636 ok(SUCCEEDED(hr
), "Failed to unlock volume texture, hr %#lx.\n", hr
);
7638 IDirect3DVolumeTexture8_Release(texture
);
7640 /* Test mipmap locks. Don't do this with ATI2N, AMD warns that the runtime
7641 * does not allocate surfaces smaller than the blocksize properly. */
7642 if ((formats
[i
].block_width
> 1 || formats
[i
].block_height
> 1) && formats
[i
].core_fmt
)
7644 hr
= IDirect3DDevice8_CreateVolumeTexture(device
, formats
[i
].block_width
, formats
[i
].block_height
,
7645 2, 2, 0, formats
[i
].fmt
, D3DPOOL_SCRATCH
, &texture
);
7647 ok(SUCCEEDED(hr
), "CreateVolumeTexture failed, hr %#lx.\n", hr
);
7648 hr
= IDirect3DVolumeTexture8_LockBox(texture
, 1, &locked_box
, NULL
, 0);
7649 ok(SUCCEEDED(hr
), "Failed to lock volume texture mipmap, hr %#lx.\n", hr
);
7650 hr
= IDirect3DVolumeTexture8_UnlockBox(texture
, 1);
7651 ok(SUCCEEDED(hr
), "Failed to unlock volume texture, hr %#lx.\n", hr
);
7653 box
.Left
= box
.Top
= box
.Front
= 0;
7654 box
.Right
= formats
[i
].block_width
== 1 ? 1 : formats
[i
].block_width
>> 1;
7655 box
.Bottom
= formats
[i
].block_height
== 1 ? 1 : formats
[i
].block_height
>> 1;
7657 hr
= IDirect3DVolumeTexture8_LockBox(texture
, 1, &locked_box
, &box
, 0);
7658 ok(SUCCEEDED(hr
), "Failed to lock volume texture mipmap, hr %#lx.\n", hr
);
7659 hr
= IDirect3DVolumeTexture8_UnlockBox(texture
, 1);
7660 ok(SUCCEEDED(hr
), "Failed to unlock volume texture, hr %#lx.\n", hr
);
7662 box
.Right
= formats
[i
].block_width
;
7663 box
.Bottom
= formats
[i
].block_height
;
7664 hr
= IDirect3DVolumeTexture8_LockBox(texture
, 1, &locked_box
, &box
, 0);
7665 ok(hr
== D3DERR_INVALIDCALL
, "Got unexpected hr %#lx.\n", hr
);
7667 IDirect3DVolumeTexture8_UnlockBox(texture
, 1);
7669 IDirect3DVolumeTexture8_Release(texture
);
7673 refcount
= IDirect3DDevice8_Release(device
);
7674 ok(!refcount
, "Device has %u references left.\n", refcount
);
7675 IDirect3D8_Release(d3d8
);
7676 DestroyWindow(window
);
7679 static void test_lockbox_invalid(void)
7688 {{0, 0, 2, 2, 0, 1}, D3D_OK
}, /* Valid */
7689 {{0, 0, 4, 4, 0, 1}, D3D_OK
}, /* Valid */
7690 {{0, 0, 0, 4, 0, 1}, D3DERR_INVALIDCALL
}, /* 0 height */
7691 {{0, 0, 4, 0, 0, 1}, D3DERR_INVALIDCALL
}, /* 0 width */
7692 {{0, 0, 4, 4, 1, 1}, D3DERR_INVALIDCALL
}, /* 0 depth */
7693 {{4, 0, 0, 4, 0, 1}, D3DERR_INVALIDCALL
}, /* left > right */
7694 {{0, 4, 4, 0, 0, 1}, D3DERR_INVALIDCALL
}, /* top > bottom */
7695 {{0, 0, 4, 4, 1, 0}, D3DERR_INVALIDCALL
}, /* back > front */
7696 {{0, 0, 8, 4, 0, 1}, D3DERR_INVALIDCALL
}, /* right > surface */
7697 {{0, 0, 4, 8, 0, 1}, D3DERR_INVALIDCALL
}, /* bottom > surface */
7698 {{0, 0, 4, 4, 0, 3}, D3DERR_INVALIDCALL
}, /* back > surface */
7699 {{8, 0, 16, 4, 0, 1}, D3DERR_INVALIDCALL
}, /* left > surface */
7700 {{0, 8, 4, 16, 0, 1}, D3DERR_INVALIDCALL
}, /* top > surface */
7701 {{0, 0, 4, 4, 2, 4}, D3DERR_INVALIDCALL
}, /* top > surface */
7703 static const D3DBOX test_boxt_2
= {2, 2, 4, 4, 0, 1};
7704 IDirect3DVolumeTexture8
*texture
= NULL
;
7705 D3DLOCKED_BOX locked_box
;
7706 IDirect3DDevice8
*device
;
7714 window
= create_window();
7715 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
7716 ok(!!d3d
, "Failed to create a D3D object.\n");
7717 if (!(device
= create_device(d3d
, window
, NULL
)))
7719 skip("Failed to create a D3D device, skipping tests.\n");
7720 IDirect3D8_Release(d3d
);
7721 DestroyWindow(window
);
7725 hr
= IDirect3DDevice8_CreateVolumeTexture(device
, 4, 4, 2, 1, 0,
7726 D3DFMT_A8R8G8B8
, D3DPOOL_SCRATCH
, &texture
);
7727 ok(SUCCEEDED(hr
), "Failed to create volume texture, hr %#lx.\n", hr
);
7728 hr
= IDirect3DVolumeTexture8_LockBox(texture
, 0, &locked_box
, NULL
, 0);
7729 ok(SUCCEEDED(hr
), "Failed to lock volume texture, hr %#lx.\n", hr
);
7730 base
= locked_box
.pBits
;
7731 hr
= IDirect3DVolumeTexture8_UnlockBox(texture
, 0);
7732 ok(SUCCEEDED(hr
), "Failed to unlock volume texture, hr %#lx.\n", hr
);
7734 for (i
= 0; i
< ARRAY_SIZE(test_data
); ++i
)
7736 unsigned int offset
, expected_offset
;
7737 const D3DBOX
*box
= &test_data
[i
].box
;
7739 locked_box
.pBits
= (BYTE
*)0xdeadbeef;
7740 locked_box
.RowPitch
= 0xdeadbeef;
7741 locked_box
.SlicePitch
= 0xdeadbeef;
7743 hr
= IDirect3DVolumeTexture8_LockBox(texture
, 0, &locked_box
, box
, 0);
7744 /* Unlike surfaces, volumes properly check the box even in Windows XP */
7745 ok(hr
== test_data
[i
].result
,
7746 "Got unexpected hr %#lx with box [%u, %u, %u]->[%u, %u, %u], expected %#lx.\n",
7747 hr
, box
->Left
, box
->Top
, box
->Front
, box
->Right
, box
->Bottom
, box
->Back
,
7748 test_data
[i
].result
);
7752 offset
= (BYTE
*)locked_box
.pBits
- base
;
7753 expected_offset
= box
->Front
* locked_box
.SlicePitch
+ box
->Top
* locked_box
.RowPitch
+ box
->Left
* 4;
7754 ok(offset
== expected_offset
,
7755 "Got unexpected offset %u (expected %u) for rect [%u, %u, %u]->[%u, %u, %u].\n",
7756 offset
, expected_offset
, box
->Left
, box
->Top
, box
->Front
, box
->Right
, box
->Bottom
, box
->Back
);
7758 hr
= IDirect3DVolumeTexture8_UnlockBox(texture
, 0);
7759 ok(SUCCEEDED(hr
), "Failed to unlock volume texture, hr %#lx.\n", hr
);
7762 /* locked_box = NULL throws an exception on Windows */
7763 hr
= IDirect3DVolumeTexture8_LockBox(texture
, 0, &locked_box
, NULL
, 0);
7764 ok(SUCCEEDED(hr
), "Failed to lock volume texture, hr %#lx.\n", hr
);
7765 hr
= IDirect3DVolumeTexture8_LockBox(texture
, 0, &locked_box
, NULL
, 0);
7766 ok(hr
== D3DERR_INVALIDCALL
, "Got unexpected hr %#lx.\n", hr
);
7767 hr
= IDirect3DVolumeTexture8_UnlockBox(texture
, 0);
7768 ok(SUCCEEDED(hr
), "Failed to unlock volume texture, hr %#lx.\n", hr
);
7769 hr
= IDirect3DVolumeTexture8_UnlockBox(texture
, 0);
7770 ok(hr
== D3DERR_INVALIDCALL
, "Got unexpected hr %#lx.\n", hr
);
7772 hr
= IDirect3DVolumeTexture8_LockBox(texture
, 0, &locked_box
, &test_data
[0].box
, 0);
7773 ok(hr
== D3D_OK
, "Got unexpected hr %#lx for rect [%u, %u, %u]->[%u, %u, %u].\n",
7774 hr
, test_data
[0].box
.Left
, test_data
[0].box
.Top
, test_data
[0].box
.Front
,
7775 test_data
[0].box
.Right
, test_data
[0].box
.Bottom
, test_data
[0].box
.Back
);
7776 hr
= IDirect3DVolumeTexture8_LockBox(texture
, 0, &locked_box
, &test_data
[0].box
, 0);
7777 ok(hr
== D3DERR_INVALIDCALL
, "Got unexpected hr %#lx for rect [%u, %u, %u]->[%u, %u, %u].\n",
7778 hr
, test_data
[0].box
.Left
, test_data
[0].box
.Top
, test_data
[0].box
.Front
,
7779 test_data
[0].box
.Right
, test_data
[0].box
.Bottom
, test_data
[0].box
.Back
);
7780 hr
= IDirect3DVolumeTexture8_LockBox(texture
, 0, &locked_box
, &test_boxt_2
, 0);
7781 ok(hr
== D3DERR_INVALIDCALL
, "Got unexpected hr %#lx for rect [%u, %u, %u]->[%u, %u, %u].\n",
7782 hr
, test_boxt_2
.Left
, test_boxt_2
.Top
, test_boxt_2
.Front
,
7783 test_boxt_2
.Right
, test_boxt_2
.Bottom
, test_boxt_2
.Back
);
7784 hr
= IDirect3DVolumeTexture8_UnlockBox(texture
, 0);
7785 ok(SUCCEEDED(hr
), "Failed to unlock volume texture, hr %#lx.\n", hr
);
7787 IDirect3DVolumeTexture8_Release(texture
);
7789 hr
= IDirect3DDevice8_CreateVolumeTexture(device
, 4, 4, 2, 1, D3DUSAGE_WRITEONLY
,
7790 D3DFMT_A8R8G8B8
, D3DPOOL_SCRATCH
, &texture
);
7791 ok(hr
== D3DERR_INVALIDCALL
, "Got unexpected hr %#lx.\n", hr
);
7793 refcount
= IDirect3DDevice8_Release(device
);
7794 ok(!refcount
, "Device has %lu references left.\n", refcount
);
7795 IDirect3D8_Release(d3d
);
7796 DestroyWindow(window
);
7799 static void test_pixel_format(void)
7801 int format
, test_format
;
7802 PIXELFORMATDESCRIPTOR pfd
;
7803 IDirect3D8
*d3d8
= NULL
;
7804 IDirect3DDevice8
*device
= NULL
;
7805 HWND hwnd
, hwnd2
, hwnd3
;
7806 HDC hdc
, hdc2
, hdc3
;
7812 static const float point
[] = {0.0f
, 0.0f
, 0.0f
};
7814 hwnd
= create_window();
7815 ok(!!hwnd
, "Failed to create window.\n");
7816 hwnd2
= create_window();
7817 ok(!!hwnd2
, "Failed to create window.\n");
7820 ok(!!hdc
, "Failed to get DC.\n");
7821 hdc2
= GetDC(hwnd2
);
7822 ok(!!hdc2
, "Failed to get DC.\n");
7824 gl
= LoadLibraryA("opengl32.dll");
7825 ok(!!gl
, "failed to load opengl32.dll; SetPixelFormat()/GetPixelFormat() may not work right\n");
7827 format
= GetPixelFormat(hdc
);
7828 ok(format
== 0, "new window has pixel format %d\n", format
);
7830 ZeroMemory(&pfd
, sizeof(pfd
));
7831 pfd
.nSize
= sizeof(pfd
);
7833 pfd
.dwFlags
= PFD_DRAW_TO_WINDOW
| PFD_SUPPORT_OPENGL
;
7834 pfd
.iPixelType
= PFD_TYPE_RGBA
;
7835 pfd
.iLayerType
= PFD_MAIN_PLANE
;
7836 format
= ChoosePixelFormat(hdc
, &pfd
);
7839 skip("no pixel format available\n");
7843 if (!SetPixelFormat(hdc
, format
, &pfd
) || GetPixelFormat(hdc
) != format
)
7845 skip("failed to set pixel format\n");
7849 if (!SetPixelFormat(hdc2
, format
, &pfd
) || GetPixelFormat(hdc2
) != format
)
7851 skip("failed to set pixel format on second window\n");
7855 d3d8
= Direct3DCreate8(D3D_SDK_VERSION
);
7856 ok(!!d3d8
, "Failed to create a D3D object.\n");
7858 test_format
= GetPixelFormat(hdc
);
7859 ok(test_format
== format
, "window has pixel format %d, expected %d\n", test_format
, format
);
7861 if (!(device
= create_device(d3d8
, hwnd
, NULL
)))
7863 skip("Failed to create device\n");
7867 test_format
= GetPixelFormat(hdc
);
7868 ok(test_format
== format
, "window has pixel format %d, expected %d\n", test_format
, format
);
7870 hr
= IDirect3DDevice8_SetVertexShader(device
, D3DFVF_XYZ
);
7871 ok(SUCCEEDED(hr
), "Failed to set FVF, hr %#lx.\n", hr
);
7873 test_format
= GetPixelFormat(hdc
);
7874 ok(test_format
== format
, "window has pixel format %d, expected %d\n", test_format
, format
);
7876 hr
= IDirect3DDevice8_BeginScene(device
);
7877 ok(SUCCEEDED(hr
), "Got hr %#lx.\n", hr
);
7879 test_format
= GetPixelFormat(hdc
);
7880 ok(test_format
== format
, "window has pixel format %d, expected %d\n", test_format
, format
);
7882 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_POINTLIST
, 1, point
, 3 * sizeof(float));
7883 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
7885 test_format
= GetPixelFormat(hdc
);
7886 ok(test_format
== format
, "window has pixel format %d, expected %d\n", test_format
, format
);
7888 hr
= IDirect3DDevice8_EndScene(device
);
7889 ok(SUCCEEDED(hr
), "Got hr %#lx.\n", hr
);
7891 test_format
= GetPixelFormat(hdc
);
7892 ok(test_format
== format
, "window has pixel format %d, expected %d\n", test_format
, format
);
7894 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
7895 ok(SUCCEEDED(hr
), "Got hr %#lx.\n", hr
);
7897 test_format
= GetPixelFormat(hdc
);
7898 ok(test_format
== format
, "window has pixel format %d, expected %d\n", test_format
, format
);
7900 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, hwnd2
, NULL
);
7901 ok(SUCCEEDED(hr
), "Got hr %#lx.\n", hr
);
7903 test_format
= GetPixelFormat(hdc
);
7904 ok(test_format
== format
, "window has pixel format %d, expected %d\n", test_format
, format
);
7906 test_format
= GetPixelFormat(hdc2
);
7907 ok(test_format
== format
, "second window has pixel format %d, expected %d\n", test_format
, format
);
7909 refcount
= IDirect3DDevice8_Release(device
);
7910 ok(!refcount
, "Device has %lu references left.\n", refcount
);
7911 IDirect3D8_Release(d3d8
);
7913 test_format
= GetPixelFormat(hdc
);
7914 ok(test_format
== format
, "window has pixel format %d, expected %d\n", test_format
, format
);
7916 test_format
= GetPixelFormat(hdc2
);
7917 ok(test_format
== format
, "second window has pixel format %d, expected %d\n", test_format
, format
);
7919 /* Test that creating a device doesn't set a pixel format on a window which
7922 hwnd3
= create_window();
7923 hdc3
= GetDC(hwnd3
);
7925 test_format
= GetPixelFormat(hdc3
);
7926 ok(!test_format
, "Expected no format, got %d.\n", test_format
);
7928 d3d8
= Direct3DCreate8(D3D_SDK_VERSION
);
7929 ok(!!d3d8
, "Failed to create a D3D object.\n");
7930 if (!(device
= create_device(d3d8
, hwnd3
, NULL
)))
7932 skip("Failed to create device\n");
7936 hr
= IDirect3DDevice8_SetVertexShader(device
, D3DFVF_XYZ
);
7937 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7938 hr
= IDirect3DDevice8_BeginScene(device
);
7939 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7940 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_POINTLIST
, 1, point
, 3 * sizeof(float));
7941 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7942 hr
= IDirect3DDevice8_EndScene(device
);
7943 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7945 test_format
= GetPixelFormat(hdc3
);
7946 ok(!test_format
, "Expected no format, got %d.\n", test_format
);
7948 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
7949 ok(hr
== S_OK
, "Got hr %#lx.\n", hr
);
7951 test_format
= GetPixelFormat(hdc3
);
7952 ok(!test_format
, "Expected no format, got %d.\n", test_format
);
7954 refcount
= IDirect3DDevice8_Release(device
);
7955 ok(!refcount
, "Device has %lu references left.\n", refcount
);
7956 IDirect3D8_Release(d3d8
);
7958 test_format
= GetPixelFormat(hdc3
);
7959 ok(!test_format
, "Expected no format, got %d.\n", test_format
);
7961 ret
= SetPixelFormat(hdc3
, format
, &pfd
);
7962 ok(ret
, "Failed to set pixel format %d.\n", format
);
7964 test_format
= GetPixelFormat(hdc3
);
7965 ok(test_format
== format
, "Expected pixel format %d, got %d.\n", format
, test_format
);
7967 ReleaseDC(hwnd3
, hdc3
);
7968 DestroyWindow(hwnd3
);
7972 ReleaseDC(hwnd2
, hdc2
);
7973 ReleaseDC(hwnd
, hdc
);
7974 DestroyWindow(hwnd2
);
7975 DestroyWindow(hwnd
);
7978 static void test_begin_end_state_block(void)
7980 DWORD stateblock
, stateblock2
;
7981 IDirect3DDevice8
*device
;
7988 window
= create_window();
7989 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
7990 ok(!!d3d
, "Failed to create a D3D object.\n");
7991 if (!(device
= create_device(d3d
, window
, NULL
)))
7993 skip("Failed to create a D3D device, skipping tests.\n");
7994 IDirect3D8_Release(d3d
);
7995 DestroyWindow(window
);
7999 hr
= IDirect3DDevice8_BeginStateBlock(device
);
8000 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
8002 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_LIGHTING
, FALSE
);
8003 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
8005 stateblock
= 0xdeadbeef;
8006 hr
= IDirect3DDevice8_EndStateBlock(device
, &stateblock
);
8007 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
8008 ok(!!stateblock
&& stateblock
!= 0xdeadbeef, "Got unexpected stateblock %#lx.\n", stateblock
);
8010 stateblock2
= 0xdeadbeef;
8011 hr
= IDirect3DDevice8_EndStateBlock(device
, &stateblock2
);
8012 ok(hr
== D3DERR_INVALIDCALL
, "Got unexpected hr %#lx.\n", hr
);
8013 ok(stateblock2
== 0xdeadbeef, "Got unexpected stateblock %#lx.\n", stateblock2
);
8015 hr
= IDirect3DDevice8_GetRenderState(device
, D3DRS_LIGHTING
, &value
);
8016 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
8017 ok(value
== TRUE
, "Got unexpected value %#lx.\n", value
);
8019 hr
= IDirect3DDevice8_BeginStateBlock(device
);
8020 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
8022 hr
= IDirect3DDevice8_BeginStateBlock(device
);
8023 ok(hr
== D3DERR_INVALIDCALL
, "Got unexpected hr %#lx.\n", hr
);
8025 hr
= IDirect3DDevice8_ApplyStateBlock(device
, stateblock
);
8026 ok(hr
== D3DERR_INVALIDCALL
, "Got unexpected hr %#lx.\n", hr
);
8028 hr
= IDirect3DDevice8_CaptureStateBlock(device
, stateblock
);
8029 ok(hr
== D3DERR_INVALIDCALL
, "Got unexpected hr %#lx.\n", hr
);
8031 hr
= IDirect3DDevice8_CreateStateBlock(device
, D3DSBT_ALL
, &stateblock2
);
8032 ok(hr
== D3DERR_INVALIDCALL
, "Got unexpected hr %#lx.\n", hr
);
8034 hr
= IDirect3DDevice8_GetRenderState(device
, D3DRS_LIGHTING
, &value
);
8035 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
8036 ok(value
== TRUE
, "Got unexpected value %#lx.\n", value
);
8038 hr
= IDirect3DDevice8_EndStateBlock(device
, &stateblock2
);
8039 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
8041 hr
= IDirect3DDevice8_ApplyStateBlock(device
, stateblock2
);
8042 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
8044 hr
= IDirect3DDevice8_GetRenderState(device
, D3DRS_LIGHTING
, &value
);
8045 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
8046 ok(value
== TRUE
, "Got unexpected value %#lx.\n", value
);
8048 refcount
= IDirect3DDevice8_Release(device
);
8049 ok(!refcount
, "Device has %lu references left.\n", refcount
);
8050 IDirect3D8_Release(d3d
);
8051 DestroyWindow(window
);
8054 static void test_shader_constant_apply(void)
8056 static const float vs_const
[] = {1.0f
, 2.0f
, 3.0f
, 4.0f
};
8057 static const float ps_const
[] = {5.0f
, 6.0f
, 7.0f
, 8.0f
};
8058 static const float initial
[] = {0.0f
, 0.0f
, 0.0f
, 0.0f
};
8059 DWORD vs_version
, ps_version
;
8060 IDirect3DDevice8
*device
;
8069 window
= create_window();
8070 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
8071 ok(!!d3d
, "Failed to create a D3D object.\n");
8072 if (!(device
= create_device(d3d
, window
, NULL
)))
8074 skip("Failed to create a D3D device, skipping tests.\n");
8075 IDirect3D8_Release(d3d
);
8076 DestroyWindow(window
);
8080 hr
= IDirect3DDevice8_GetDeviceCaps(device
, &caps
);
8081 ok(SUCCEEDED(hr
), "Failed to get device caps, hr %#lx.\n", hr
);
8082 vs_version
= caps
.VertexShaderVersion
& 0xffff;
8083 ps_version
= caps
.PixelShaderVersion
& 0xffff;
8087 hr
= IDirect3DDevice8_SetVertexShaderConstant(device
, 0, initial
, 1);
8088 ok(SUCCEEDED(hr
), "Failed to set vertex shader constant, hr %#lx.\n", hr
);
8089 hr
= IDirect3DDevice8_SetVertexShaderConstant(device
, 1, initial
, 1);
8090 ok(SUCCEEDED(hr
), "Failed to set vertex shader constant, hr %#lx.\n", hr
);
8092 hr
= IDirect3DDevice8_GetVertexShaderConstant(device
, 0, ret
, 1);
8093 ok(SUCCEEDED(hr
), "Failed to get vertex shader constant, hr %#lx.\n", hr
);
8094 ok(!memcmp(ret
, initial
, sizeof(initial
)),
8095 "Got unexpected vertex shader constant {%.8e, %.8e, %.8e, %.8e}, expected {%.8e, %.8e, %.8e, %.8e}.\n",
8096 ret
[0], ret
[1], ret
[2], ret
[3], initial
[0], initial
[1], initial
[2], initial
[3]);
8097 hr
= IDirect3DDevice8_GetVertexShaderConstant(device
, 1, ret
, 1);
8098 ok(SUCCEEDED(hr
), "Failed to get vertex shader constant, hr %#lx.\n", hr
);
8099 ok(!memcmp(ret
, initial
, sizeof(initial
)),
8100 "Got unexpected vertex shader constant {%.8e, %.8e, %.8e, %.8e}, expected {%.8e, %.8e, %.8e, %.8e}.\n",
8101 ret
[0], ret
[1], ret
[2], ret
[3], initial
[0], initial
[1], initial
[2], initial
[3]);
8103 hr
= IDirect3DDevice8_SetVertexShaderConstant(device
, 0, vs_const
, 1);
8104 ok(SUCCEEDED(hr
), "Failed to set vertex shader constant, hr %#lx.\n", hr
);
8108 hr
= IDirect3DDevice8_SetPixelShaderConstant(device
, 0, initial
, 1);
8109 ok(SUCCEEDED(hr
), "Failed to set pixel shader constant, hr %#lx.\n", hr
);
8110 hr
= IDirect3DDevice8_SetPixelShaderConstant(device
, 1, initial
, 1);
8111 ok(SUCCEEDED(hr
), "Failed to set pixel shader constant, hr %#lx.\n", hr
);
8113 hr
= IDirect3DDevice8_GetPixelShaderConstant(device
, 0, ret
, 1);
8114 ok(SUCCEEDED(hr
), "Failed to get pixel shader constant, hr %#lx.\n", hr
);
8115 ok(!memcmp(ret
, initial
, sizeof(initial
)),
8116 "Got unexpected pixel shader constant {%.8e, %.8e, %.8e, %.8e}, expected {%.8e, %.8e, %.8e, %.8e}.\n",
8117 ret
[0], ret
[1], ret
[2], ret
[3], initial
[0], initial
[1], initial
[2], initial
[3]);
8118 hr
= IDirect3DDevice8_GetPixelShaderConstant(device
, 1, ret
, 1);
8119 ok(SUCCEEDED(hr
), "Failed to get pixel shader constant, hr %#lx.\n", hr
);
8120 ok(!memcmp(ret
, initial
, sizeof(initial
)),
8121 "Got unexpected pixel shader constant {%.8e, %.8e, %.8e, %.8e}, expected {%.8e, %.8e, %.8e, %.8e}.\n",
8122 ret
[0], ret
[1], ret
[2], ret
[3], initial
[0], initial
[1], initial
[2], initial
[3]);
8124 hr
= IDirect3DDevice8_SetPixelShaderConstant(device
, 0, ps_const
, 1);
8125 ok(SUCCEEDED(hr
), "Failed to set pixel shader constant, hr %#lx.\n", hr
);
8128 hr
= IDirect3DDevice8_BeginStateBlock(device
);
8129 ok(SUCCEEDED(hr
), "Failed to begin stateblock, hr %#lx.\n", hr
);
8133 hr
= IDirect3DDevice8_SetVertexShaderConstant(device
, 1, vs_const
, 1);
8134 ok(SUCCEEDED(hr
), "Failed to set vertex shader constant, hr %#lx.\n", hr
);
8138 hr
= IDirect3DDevice8_SetPixelShaderConstant(device
, 1, ps_const
, 1);
8139 ok(SUCCEEDED(hr
), "Failed to set pixel shader constant, hr %#lx.\n", hr
);
8142 hr
= IDirect3DDevice8_EndStateBlock(device
, &stateblock
);
8143 ok(SUCCEEDED(hr
), "Failed to end stateblock, hr %#lx.\n", hr
);
8147 hr
= IDirect3DDevice8_GetVertexShaderConstant(device
, 0, ret
, 1);
8148 ok(SUCCEEDED(hr
), "Failed to get vertex shader constant, hr %#lx.\n", hr
);
8149 ok(!memcmp(ret
, vs_const
, sizeof(vs_const
)),
8150 "Got unexpected vertex shader constant {%.8e, %.8e, %.8e, %.8e}, expected {%.8e, %.8e, %.8e, %.8e}.\n",
8151 ret
[0], ret
[1], ret
[2], ret
[3], vs_const
[0], vs_const
[1], vs_const
[2], vs_const
[3]);
8152 hr
= IDirect3DDevice8_GetVertexShaderConstant(device
, 1, ret
, 1);
8153 ok(SUCCEEDED(hr
), "Failed to get vertex shader constant, hr %#lx.\n", hr
);
8154 ok(!memcmp(ret
, initial
, sizeof(initial
)),
8155 "Got unexpected vertex shader constant {%.8e, %.8e, %.8e, %.8e}, expected {%.8e, %.8e, %.8e, %.8e}.\n",
8156 ret
[0], ret
[1], ret
[2], ret
[3], initial
[0], initial
[1], initial
[2], initial
[3]);
8160 hr
= IDirect3DDevice8_GetPixelShaderConstant(device
, 0, ret
, 1);
8161 ok(SUCCEEDED(hr
), "Failed to get pixel shader constant, hr %#lx.\n", hr
);
8162 ok(!memcmp(ret
, ps_const
, sizeof(ps_const
)),
8163 "Got unexpected pixel shader constant {%.8e, %.8e, %.8e, %.8e}, expected {%.8e, %.8e, %.8e, %.8e}.\n",
8164 ret
[0], ret
[1], ret
[2], ret
[3], ps_const
[0], ps_const
[1], ps_const
[2], ps_const
[3]);
8165 hr
= IDirect3DDevice8_GetPixelShaderConstant(device
, 1, ret
, 1);
8166 ok(SUCCEEDED(hr
), "Failed to get pixel shader constant, hr %#lx.\n", hr
);
8167 ok(!memcmp(ret
, initial
, sizeof(initial
)),
8168 "Got unexpected pixel shader constant {%.8e, %.8e, %.8e, %.8e}, expected {%.8e, %.8e, %.8e, %.8e}.\n",
8169 ret
[0], ret
[1], ret
[2], ret
[3], initial
[0], initial
[1], initial
[2], initial
[3]);
8172 /* Apply doesn't overwrite constants that aren't explicitly set on the
8173 * source stateblock. */
8174 hr
= IDirect3DDevice8_ApplyStateBlock(device
, stateblock
);
8175 ok(SUCCEEDED(hr
), "Failed to apply stateblock, hr %#lx.\n", hr
);
8179 hr
= IDirect3DDevice8_GetVertexShaderConstant(device
, 0, ret
, 1);
8180 ok(SUCCEEDED(hr
), "Failed to get vertex shader constant, hr %#lx.\n", hr
);
8181 ok(!memcmp(ret
, vs_const
, sizeof(vs_const
)),
8182 "Got unexpected vertex shader constant {%.8e, %.8e, %.8e, %.8e}, expected {%.8e, %.8e, %.8e, %.8e}.\n",
8183 ret
[0], ret
[1], ret
[2], ret
[3], vs_const
[0], vs_const
[1], vs_const
[2], vs_const
[3]);
8184 hr
= IDirect3DDevice8_GetVertexShaderConstant(device
, 1, ret
, 1);
8185 ok(SUCCEEDED(hr
), "Failed to get vertex shader constant, hr %#lx.\n", hr
);
8186 ok(!memcmp(ret
, vs_const
, sizeof(vs_const
)),
8187 "Got unexpected vertex shader constant {%.8e, %.8e, %.8e, %.8e}, expected {%.8e, %.8e, %.8e, %.8e}.\n",
8188 ret
[0], ret
[1], ret
[2], ret
[3], vs_const
[0], vs_const
[1], vs_const
[2], vs_const
[3]);
8192 hr
= IDirect3DDevice8_GetPixelShaderConstant(device
, 0, ret
, 1);
8193 ok(SUCCEEDED(hr
), "Failed to get pixel shader constant, hr %#lx.\n", hr
);
8194 ok(!memcmp(ret
, ps_const
, sizeof(ps_const
)),
8195 "Got unexpected pixel shader constant {%.8e, %.8e, %.8e, %.8e}, expected {%.8e, %.8e, %.8e, %.8e}.\n",
8196 ret
[0], ret
[1], ret
[2], ret
[3], ps_const
[0], ps_const
[1], ps_const
[2], ps_const
[3]);
8197 hr
= IDirect3DDevice8_GetPixelShaderConstant(device
, 1, ret
, 1);
8198 ok(SUCCEEDED(hr
), "Failed to get pixel shader constant, hr %#lx.\n", hr
);
8199 ok(!memcmp(ret
, ps_const
, sizeof(ps_const
)),
8200 "Got unexpected pixel shader constant {%.8e, %.8e, %.8e, %.8e}, expected {%.8e, %.8e, %.8e, %.8e}.\n",
8201 ret
[0], ret
[1], ret
[2], ret
[3], ps_const
[0], ps_const
[1], ps_const
[2], ps_const
[3]);
8204 IDirect3DDevice8_DeleteStateBlock(device
, stateblock
);
8205 refcount
= IDirect3DDevice8_Release(device
);
8206 ok(!refcount
, "Device has %lu references left.\n", refcount
);
8207 IDirect3D8_Release(d3d
);
8208 DestroyWindow(window
);
8211 static void test_resource_type(void)
8213 IDirect3DDevice8
*device
;
8214 IDirect3DSurface8
*surface
;
8215 IDirect3DTexture8
*texture
;
8216 IDirect3DCubeTexture8
*cube_texture
;
8217 IDirect3DVolume8
*volume
;
8218 IDirect3DVolumeTexture8
*volume_texture
;
8219 D3DSURFACE_DESC surface_desc
;
8220 D3DVOLUME_DESC volume_desc
;
8221 D3DRESOURCETYPE type
;
8228 window
= create_window();
8229 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
8230 ok(!!d3d
, "Failed to create a D3D object.\n");
8231 if (!(device
= create_device(d3d
, window
, NULL
)))
8233 skip("Failed to create a D3D device, skipping tests.\n");
8234 IDirect3D8_Release(d3d
);
8235 DestroyWindow(window
);
8239 hr
= IDirect3DDevice8_GetDeviceCaps(device
, &caps
);
8240 ok(SUCCEEDED(hr
), "Failed to get device caps, hr %#lx.\n", hr
);
8242 hr
= IDirect3DDevice8_CreateImageSurface(device
, 4, 4, D3DFMT_X8R8G8B8
, &surface
);
8243 ok(SUCCEEDED(hr
), "Failed to create surface, hr %#lx.\n", hr
);
8244 hr
= IDirect3DSurface8_GetDesc(surface
, &surface_desc
);
8245 ok(SUCCEEDED(hr
), "Failed to get surface description, hr %#lx.\n", hr
);
8246 ok(surface_desc
.Type
== D3DRTYPE_SURFACE
, "Expected type D3DRTYPE_SURFACE, got %u.\n",
8248 IDirect3DSurface8_Release(surface
);
8250 hr
= IDirect3DDevice8_CreateTexture(device
, 2, 8, 4, 0, D3DFMT_X8R8G8B8
,
8251 D3DPOOL_SYSTEMMEM
, &texture
);
8252 ok(SUCCEEDED(hr
), "Failed to create texture, hr %#lx.\n", hr
);
8253 type
= IDirect3DTexture8_GetType(texture
);
8254 ok(type
== D3DRTYPE_TEXTURE
, "Expected type D3DRTYPE_TEXTURE, got %u.\n", type
);
8256 hr
= IDirect3DTexture8_GetSurfaceLevel(texture
, 0, &surface
);
8257 ok(SUCCEEDED(hr
), "Failed to get surface level, hr %#lx.\n", hr
);
8258 hr
= IDirect3DSurface8_GetDesc(surface
, &surface_desc
);
8259 ok(SUCCEEDED(hr
), "Failed to get surface description, hr %#lx.\n", hr
);
8260 ok(surface_desc
.Type
== D3DRTYPE_SURFACE
, "Expected type D3DRTYPE_SURFACE, got %u.\n",
8262 ok(surface_desc
.Width
== 2, "Expected width 2, got %u.\n", surface_desc
.Width
);
8263 ok(surface_desc
.Height
== 8, "Expected height 8, got %u.\n", surface_desc
.Height
);
8264 hr
= IDirect3DTexture8_GetLevelDesc(texture
, 0, &surface_desc
);
8265 ok(SUCCEEDED(hr
), "Failed to get level description, hr %#lx.\n", hr
);
8266 ok(surface_desc
.Type
== D3DRTYPE_SURFACE
, "Expected type D3DRTYPE_SURFACE, got %u.\n",
8268 ok(surface_desc
.Width
== 2, "Expected width 2, got %u.\n", surface_desc
.Width
);
8269 ok(surface_desc
.Height
== 8, "Expected height 8, got %u.\n", surface_desc
.Height
);
8270 IDirect3DSurface8_Release(surface
);
8272 hr
= IDirect3DTexture8_GetSurfaceLevel(texture
, 2, &surface
);
8273 ok(SUCCEEDED(hr
), "Failed to get surface level, hr %#lx.\n", hr
);
8274 hr
= IDirect3DSurface8_GetDesc(surface
, &surface_desc
);
8275 ok(SUCCEEDED(hr
), "Failed to get surface description, hr %#lx.\n", hr
);
8276 ok(surface_desc
.Type
== D3DRTYPE_SURFACE
, "Expected type D3DRTYPE_SURFACE, got %u.\n",
8278 ok(surface_desc
.Width
== 1, "Expected width 1, got %u.\n", surface_desc
.Width
);
8279 ok(surface_desc
.Height
== 2, "Expected height 2, got %u.\n", surface_desc
.Height
);
8280 hr
= IDirect3DTexture8_GetLevelDesc(texture
, 2, &surface_desc
);
8281 ok(SUCCEEDED(hr
), "Failed to get level description, hr %#lx.\n", hr
);
8282 ok(surface_desc
.Type
== D3DRTYPE_SURFACE
, "Expected type D3DRTYPE_SURFACE, got %u.\n",
8284 ok(surface_desc
.Width
== 1, "Expected width 1, got %u.\n", surface_desc
.Width
);
8285 ok(surface_desc
.Height
== 2, "Expected height 2, got %u.\n", surface_desc
.Height
);
8286 IDirect3DSurface8_Release(surface
);
8287 IDirect3DTexture8_Release(texture
);
8289 if (caps
.TextureCaps
& D3DPTEXTURECAPS_CUBEMAP
)
8291 hr
= IDirect3DDevice8_CreateCubeTexture(device
, 1, 1, 0, D3DFMT_X8R8G8B8
,
8292 D3DPOOL_SYSTEMMEM
, &cube_texture
);
8293 ok(SUCCEEDED(hr
), "Failed to create cube texture, hr %#lx.\n", hr
);
8294 type
= IDirect3DCubeTexture8_GetType(cube_texture
);
8295 ok(type
== D3DRTYPE_CUBETEXTURE
, "Expected type D3DRTYPE_CUBETEXTURE, got %u.\n", type
);
8297 hr
= IDirect3DCubeTexture8_GetCubeMapSurface(cube_texture
,
8298 D3DCUBEMAP_FACE_NEGATIVE_X
, 0, &surface
);
8299 ok(SUCCEEDED(hr
), "Failed to get cube map surface, hr %#lx.\n", hr
);
8300 hr
= IDirect3DSurface8_GetDesc(surface
, &surface_desc
);
8301 ok(SUCCEEDED(hr
), "Failed to get surface description, hr %#lx.\n", hr
);
8302 ok(surface_desc
.Type
== D3DRTYPE_SURFACE
, "Expected type D3DRTYPE_SURFACE, got %u.\n",
8304 hr
= IDirect3DCubeTexture8_GetLevelDesc(cube_texture
, 0, &surface_desc
);
8305 ok(SUCCEEDED(hr
), "Failed to get level description, hr %#lx.\n", hr
);
8306 ok(surface_desc
.Type
== D3DRTYPE_SURFACE
, "Expected type D3DRTYPE_SURFACE, got %u.\n",
8308 IDirect3DSurface8_Release(surface
);
8309 IDirect3DCubeTexture8_Release(cube_texture
);
8312 skip("Cube maps not supported.\n");
8314 if (caps
.TextureCaps
& D3DPTEXTURECAPS_MIPVOLUMEMAP
)
8316 hr
= IDirect3DDevice8_CreateVolumeTexture(device
, 2, 4, 8, 4, 0, D3DFMT_X8R8G8B8
,
8317 D3DPOOL_SYSTEMMEM
, &volume_texture
);
8318 ok(SUCCEEDED(hr
), "CreateVolumeTexture failed, hr %#lx.\n", hr
);
8319 type
= IDirect3DVolumeTexture8_GetType(volume_texture
);
8320 ok(type
== D3DRTYPE_VOLUMETEXTURE
, "Expected type D3DRTYPE_VOLUMETEXTURE, got %u.\n", type
);
8322 hr
= IDirect3DVolumeTexture8_GetVolumeLevel(volume_texture
, 0, &volume
);
8323 ok(SUCCEEDED(hr
), "Failed to get volume level, hr %#lx.\n", hr
);
8324 /* IDirect3DVolume8 is not an IDirect3DResource8 and has no GetType method. */
8325 hr
= IDirect3DVolume8_GetDesc(volume
, &volume_desc
);
8326 ok(SUCCEEDED(hr
), "Failed to get volume description, hr %#lx.\n", hr
);
8327 ok(volume_desc
.Type
== D3DRTYPE_VOLUME
, "Expected type D3DRTYPE_VOLUME, got %u.\n",
8329 ok(volume_desc
.Width
== 2, "Expected width 2, got %u.\n", volume_desc
.Width
);
8330 ok(volume_desc
.Height
== 4, "Expected height 4, got %u.\n", volume_desc
.Height
);
8331 ok(volume_desc
.Depth
== 8, "Expected depth 8, got %u.\n", volume_desc
.Depth
);
8332 hr
= IDirect3DVolumeTexture8_GetLevelDesc(volume_texture
, 0, &volume_desc
);
8333 ok(SUCCEEDED(hr
), "Failed to get level description, hr %#lx.\n", hr
);
8334 ok(volume_desc
.Type
== D3DRTYPE_VOLUME
, "Expected type D3DRTYPE_VOLUME, got %u.\n",
8336 ok(volume_desc
.Width
== 2, "Expected width 2, got %u.\n", volume_desc
.Width
);
8337 ok(volume_desc
.Height
== 4, "Expected height 4, got %u.\n", volume_desc
.Height
);
8338 ok(volume_desc
.Depth
== 8, "Expected depth 8, got %u.\n", volume_desc
.Depth
);
8339 IDirect3DVolume8_Release(volume
);
8341 hr
= IDirect3DVolumeTexture8_GetVolumeLevel(volume_texture
, 2, &volume
);
8342 ok(SUCCEEDED(hr
), "Failed to get volume level, hr %#lx.\n", hr
);
8343 hr
= IDirect3DVolume8_GetDesc(volume
, &volume_desc
);
8344 ok(SUCCEEDED(hr
), "Failed to get volume description, hr %#lx.\n", hr
);
8345 ok(volume_desc
.Type
== D3DRTYPE_VOLUME
, "Expected type D3DRTYPE_VOLUME, got %u.\n",
8347 ok(volume_desc
.Width
== 1, "Expected width 1, got %u.\n", volume_desc
.Width
);
8348 ok(volume_desc
.Height
== 1, "Expected height 1, got %u.\n", volume_desc
.Height
);
8349 ok(volume_desc
.Depth
== 2, "Expected depth 2, got %u.\n", volume_desc
.Depth
);
8350 hr
= IDirect3DVolumeTexture8_GetLevelDesc(volume_texture
, 2, &volume_desc
);
8351 ok(SUCCEEDED(hr
), "Failed to get level description, hr %#lx.\n", hr
);
8352 ok(volume_desc
.Type
== D3DRTYPE_VOLUME
, "Expected type D3DRTYPE_VOLUME, got %u.\n",
8354 ok(volume_desc
.Width
== 1, "Expected width 1, got %u.\n", volume_desc
.Width
);
8355 ok(volume_desc
.Height
== 1, "Expected height 1, got %u.\n", volume_desc
.Height
);
8356 ok(volume_desc
.Depth
== 2, "Expected depth 2, got %u.\n", volume_desc
.Depth
);
8357 IDirect3DVolume8_Release(volume
);
8358 IDirect3DVolumeTexture8_Release(volume_texture
);
8361 skip("Mipmapped volume maps not supported.\n");
8363 refcount
= IDirect3DDevice8_Release(device
);
8364 ok(!refcount
, "Device has %lu references left.\n", refcount
);
8365 IDirect3D8_Release(d3d
);
8366 DestroyWindow(window
);
8369 static void test_mipmap_lock(void)
8371 IDirect3DDevice8
*device
;
8372 IDirect3DSurface8
*surface
, *surface2
, *surface_dst
, *surface_dst2
;
8373 IDirect3DTexture8
*texture
, *texture_dst
;
8378 D3DLOCKED_RECT locked_rect
;
8380 window
= create_window();
8381 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
8382 ok(!!d3d
, "Failed to create a D3D object.\n");
8383 if (!(device
= create_device(d3d
, window
, NULL
)))
8385 skip("Failed to create a D3D device, skipping tests.\n");
8386 IDirect3D8_Release(d3d
);
8387 DestroyWindow(window
);
8391 hr
= IDirect3DDevice8_CreateTexture(device
, 4, 4, 2, 0, D3DFMT_X8R8G8B8
,
8392 D3DPOOL_DEFAULT
, &texture_dst
);
8393 ok(SUCCEEDED(hr
), "Failed to create texture, hr %#lx.\n", hr
);
8394 hr
= IDirect3DTexture8_GetSurfaceLevel(texture_dst
, 0, &surface_dst
);
8395 ok(SUCCEEDED(hr
), "Failed to get surface level, hr %#lx.\n", hr
);
8396 hr
= IDirect3DTexture8_GetSurfaceLevel(texture_dst
, 1, &surface_dst2
);
8397 ok(SUCCEEDED(hr
), "Failed to get surface level, hr %#lx.\n", hr
);
8399 hr
= IDirect3DDevice8_CreateTexture(device
, 4, 4, 2, 0, D3DFMT_X8R8G8B8
,
8400 D3DPOOL_SYSTEMMEM
, &texture
);
8401 ok(SUCCEEDED(hr
), "Failed to create texture, hr %#lx.\n", hr
);
8402 hr
= IDirect3DTexture8_GetSurfaceLevel(texture
, 0, &surface
);
8403 ok(SUCCEEDED(hr
), "Failed to get surface level, hr %#lx.\n", hr
);
8404 hr
= IDirect3DTexture8_GetSurfaceLevel(texture
, 1, &surface2
);
8405 ok(SUCCEEDED(hr
), "Failed to get surface level, hr %#lx.\n", hr
);
8407 hr
= IDirect3DSurface8_LockRect(surface
, &locked_rect
, NULL
, 0);
8408 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
8409 hr
= IDirect3DSurface8_LockRect(surface2
, &locked_rect
, NULL
, 0);
8410 ok(SUCCEEDED(hr
), "Failed to lock surface, hr %#lx.\n", hr
);
8411 hr
= IDirect3DSurface8_UnlockRect(surface
);
8412 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
8414 hr
= IDirect3DDevice8_CopyRects(device
, surface
, NULL
, 0, surface_dst
, NULL
);
8415 ok(SUCCEEDED(hr
), "Failed to update surface, hr %#lx.\n", hr
);
8416 hr
= IDirect3DDevice8_CopyRects(device
, surface2
, NULL
, 0, surface_dst2
, NULL
);
8417 todo_wine
ok(hr
== D3DERR_INVALIDCALL
, "Got unexpected hr %#lx.\n", hr
);
8419 /* Apparently there's no validation on the container. */
8420 hr
= IDirect3DDevice8_UpdateTexture(device
, (IDirect3DBaseTexture8
*)texture
,
8421 (IDirect3DBaseTexture8
*)texture_dst
);
8422 ok(SUCCEEDED(hr
), "Failed to update texture, hr %#lx.\n", hr
);
8424 hr
= IDirect3DSurface8_UnlockRect(surface2
);
8425 ok(SUCCEEDED(hr
), "Failed to unlock surface, hr %#lx.\n", hr
);
8427 IDirect3DSurface8_Release(surface_dst2
);
8428 IDirect3DSurface8_Release(surface_dst
);
8429 IDirect3DSurface8_Release(surface2
);
8430 IDirect3DSurface8_Release(surface
);
8431 IDirect3DTexture8_Release(texture_dst
);
8432 IDirect3DTexture8_Release(texture
);
8434 refcount
= IDirect3DDevice8_Release(device
);
8435 ok(!refcount
, "Device has %lu references left.\n", refcount
);
8436 IDirect3D8_Release(d3d
);
8437 DestroyWindow(window
);
8440 static void test_writeonly_resource(void)
8443 IDirect3DDevice8
*device
;
8444 IDirect3DVertexBuffer8
*buffer
;
8455 {{-1.0f
, -1.0f
, 0.0f
}},
8456 {{-1.0f
, 1.0f
, 0.0f
}},
8457 {{ 1.0f
, -1.0f
, 0.0f
}},
8458 {{ 1.0f
, 1.0f
, 0.0f
}}
8461 window
= create_window();
8462 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
8463 ok(!!d3d
, "Failed to create a D3D object.\n");
8464 if (!(device
= create_device(d3d
, window
, NULL
)))
8466 skip("Failed to create a D3D device, skipping tests.\n");
8467 IDirect3D8_Release(d3d
);
8468 DestroyWindow(window
);
8472 hr
= IDirect3DDevice8_CreateVertexBuffer(device
, sizeof(quad
),
8473 D3DUSAGE_DYNAMIC
| D3DUSAGE_WRITEONLY
, 0, D3DPOOL_DEFAULT
, &buffer
);
8474 ok(SUCCEEDED(hr
), "Failed to create buffer, hr %#lx.\n", hr
);
8476 hr
= IDirect3DVertexBuffer8_Lock(buffer
, 0, 0, &ptr
, D3DLOCK_DISCARD
);
8477 ok(SUCCEEDED(hr
), "Failed to lock vertex buffer, hr %#lx.\n", hr
);
8478 memcpy(ptr
, quad
, sizeof(quad
));
8479 hr
= IDirect3DVertexBuffer8_Unlock(buffer
);
8480 ok(SUCCEEDED(hr
), "Failed to unlock vertex buffer, hr %#lx.\n", hr
);
8481 hr
= IDirect3DDevice8_SetStreamSource(device
, 0, buffer
, sizeof(*quad
));
8482 ok(SUCCEEDED(hr
), "Failed to set stream source, hr %#lx.\n", hr
);
8483 hr
= IDirect3DDevice8_SetVertexShader(device
, D3DFVF_XYZ
);
8484 ok(SUCCEEDED(hr
), "Failed to set FVF, hr %#lx.\n", hr
);
8486 hr
= IDirect3DDevice8_BeginScene(device
);
8487 ok(SUCCEEDED(hr
), "Got hr %#lx.\n", hr
);
8488 hr
= IDirect3DDevice8_DrawPrimitive(device
, D3DPT_TRIANGLESTRIP
, 0, 2);
8489 ok(SUCCEEDED(hr
), "Failed to draw, hr %#lx.\n", hr
);
8490 hr
= IDirect3DDevice8_EndScene(device
);
8491 ok(SUCCEEDED(hr
), "Got hr %#lx.\n", hr
);
8493 hr
= IDirect3DVertexBuffer8_Lock(buffer
, 0, 0, &ptr
, 0);
8494 ok(SUCCEEDED(hr
), "Failed to lock vertex buffer, hr %#lx.\n", hr
);
8495 ok (!memcmp(ptr
, quad
, sizeof(quad
)), "Got unexpected vertex buffer data.\n");
8496 hr
= IDirect3DVertexBuffer8_Unlock(buffer
);
8497 ok(SUCCEEDED(hr
), "Failed to unlock vertex buffer, hr %#lx.\n", hr
);
8499 hr
= IDirect3DVertexBuffer8_Lock(buffer
, 0, 0, &ptr
, D3DLOCK_READONLY
);
8500 ok(SUCCEEDED(hr
), "Failed to lock vertex buffer, hr %#lx.\n", hr
);
8501 ok (!memcmp(ptr
, quad
, sizeof(quad
)), "Got unexpected vertex buffer data.\n");
8502 hr
= IDirect3DVertexBuffer8_Unlock(buffer
);
8503 ok(SUCCEEDED(hr
), "Failed to unlock vertex buffer, hr %#lx.\n", hr
);
8505 refcount
= IDirect3DVertexBuffer8_Release(buffer
);
8506 ok(!refcount
, "Vertex buffer has %lu references left.\n", refcount
);
8507 refcount
= IDirect3DDevice8_Release(device
);
8508 ok(!refcount
, "Device has %lu references left.\n", refcount
);
8509 IDirect3D8_Release(d3d
);
8510 DestroyWindow(window
);
8513 static void test_lost_device(void)
8515 D3DADAPTER_IDENTIFIER8 identifier
;
8516 struct device_desc device_desc
;
8517 IDirect3DDevice8
*device
;
8524 window
= create_window();
8525 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
8526 ok(!!d3d
, "Failed to create a D3D object.\n");
8527 hr
= IDirect3D8_GetAdapterIdentifier(d3d
, D3DADAPTER_DEFAULT
, 0, &identifier
);
8528 ok(SUCCEEDED(hr
), "Failed to get adapter identifier, hr %#lx.\n", hr
);
8529 device_desc
.adapter_ordinal
= D3DADAPTER_DEFAULT
;
8530 device_desc
.device_window
= window
;
8531 device_desc
.width
= registry_mode
.dmPelsWidth
;
8532 device_desc
.height
= registry_mode
.dmPelsHeight
;
8533 device_desc
.flags
= CREATE_DEVICE_FULLSCREEN
;
8534 if (!(device
= create_device(d3d
, window
, &device_desc
)))
8536 skip("Failed to create a D3D device, skipping tests.\n");
8540 hr
= IDirect3DDevice8_TestCooperativeLevel(device
);
8541 if (hr
== D3DERR_DEVICELOST
)
8543 win_skip("Broken TestCooperativeLevel(), skipping test.\n");
8544 IDirect3DDevice8_Release(device
);
8547 if (adapter_is_warp(&identifier
))
8549 win_skip("Windows 10 WARP crashes during this test.\n");
8550 IDirect3DDevice8_Release(device
);
8554 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
8555 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
8556 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
8558 ret
= SetForegroundWindow(GetDesktopWindow());
8559 ok(ret
, "Failed to set foreground window.\n");
8560 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
8561 /* The device is not lost on Windows 10. */
8562 ok(hr
== D3DERR_DEVICELOST
|| broken(hr
== D3D_OK
), "Got unexpected hr %#lx.\n", hr
);
8563 hr
= IDirect3DDevice8_TestCooperativeLevel(device
);
8564 ok(hr
== D3DERR_DEVICELOST
|| broken(hr
== D3D_OK
), "Got unexpected hr %#lx.\n", hr
);
8566 ret
= ShowWindow(window
, SW_RESTORE
);
8567 ok(ret
, "Failed to restore window.\n");
8568 ret
= SetForegroundWindow(window
);
8569 ok(ret
, "Failed to set foreground window.\n");
8570 hr
= IDirect3DDevice8_TestCooperativeLevel(device
);
8571 ok(hr
== D3DERR_DEVICENOTRESET
|| broken(hr
== D3D_OK
), "Got unexpected hr %#lx.\n", hr
);
8572 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
8573 ok(hr
== D3DERR_DEVICELOST
|| broken(hr
== D3D_OK
), "Got unexpected hr %#lx.\n", hr
);
8575 hr
= reset_device(device
, &device_desc
);
8576 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
8577 hr
= IDirect3DDevice8_TestCooperativeLevel(device
);
8578 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
8579 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
8580 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
8582 device_desc
.flags
= 0;
8583 hr
= reset_device(device
, &device_desc
);
8584 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
8585 hr
= IDirect3DDevice8_TestCooperativeLevel(device
);
8586 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
8587 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
8588 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
8590 ret
= SetForegroundWindow(GetDesktopWindow());
8591 ok(ret
, "Failed to set foreground window.\n");
8592 hr
= IDirect3DDevice8_TestCooperativeLevel(device
);
8593 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
8594 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
8595 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
8597 ret
= ShowWindow(window
, SW_RESTORE
);
8598 ok(ret
, "Failed to restore window.\n");
8599 hr
= IDirect3DDevice8_TestCooperativeLevel(device
);
8600 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
8601 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
8602 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
8604 device_desc
.flags
= CREATE_DEVICE_FULLSCREEN
;
8605 hr
= reset_device(device
, &device_desc
);
8606 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
8607 hr
= IDirect3DDevice8_TestCooperativeLevel(device
);
8608 /* The device is not lost on Windows 10. */
8609 todo_wine
ok(hr
== D3DERR_DEVICELOST
|| broken(hr
== D3D_OK
), "Got unexpected hr %#lx.\n", hr
);
8610 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
8611 todo_wine
ok(hr
== D3DERR_DEVICELOST
|| broken(hr
== D3D_OK
), "Got unexpected hr %#lx.\n", hr
);
8613 ret
= SetForegroundWindow(GetDesktopWindow());
8614 ok(ret
, "Failed to set foreground window.\n");
8615 hr
= reset_device(device
, &device_desc
);
8616 ok(hr
== D3DERR_DEVICELOST
|| broken(hr
== D3D_OK
), "Got unexpected hr %#lx.\n", hr
);
8617 ret
= ShowWindow(window
, SW_RESTORE
);
8618 ok(ret
, "Failed to restore window.\n");
8619 ret
= SetForegroundWindow(window
);
8620 ok(ret
, "Failed to set foreground window.\n");
8621 hr
= reset_device(device
, &device_desc
);
8622 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
8624 refcount
= IDirect3DDevice8_Release(device
);
8625 ok(!refcount
, "Device has %lu references left.\n", refcount
);
8627 IDirect3D8_Release(d3d
);
8628 DestroyWindow(window
);
8631 static void test_resource_priority(void)
8633 IDirect3DDevice8
*device
;
8634 IDirect3DTexture8
*texture
;
8635 IDirect3DVertexBuffer8
*buffer
;
8644 BOOL can_set_priority
;
8648 {D3DPOOL_DEFAULT
, "D3DPOOL_DEFAULT", FALSE
},
8649 {D3DPOOL_SYSTEMMEM
, "D3DPOOL_SYSTEMMEM", FALSE
},
8650 {D3DPOOL_MANAGED
, "D3DPOOL_MANAGED", TRUE
},
8651 {D3DPOOL_SCRATCH
, "D3DPOOL_SCRATCH", FALSE
}
8656 window
= create_window();
8657 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
8658 ok(!!d3d
, "Failed to create a D3D object.\n");
8659 if (!(device
= create_device(d3d
, window
, NULL
)))
8661 skip("Failed to create a D3D device, skipping tests.\n");
8662 IDirect3D8_Release(d3d
);
8663 DestroyWindow(window
);
8667 for (i
= 0; i
< ARRAY_SIZE(test_data
); i
++)
8669 hr
= IDirect3DDevice8_CreateTexture(device
, 16, 16, 0, 0, D3DFMT_X8R8G8B8
,
8670 test_data
[i
].pool
, &texture
);
8671 ok(SUCCEEDED(hr
), "Failed to create texture, hr %#lx, pool %s.\n", hr
, test_data
[i
].name
);
8673 priority
= IDirect3DTexture8_GetPriority(texture
);
8674 ok(priority
== 0, "Got unexpected priority %lu, pool %s.\n", priority
, test_data
[i
].name
);
8675 priority
= IDirect3DTexture8_SetPriority(texture
, 1);
8676 ok(priority
== 0, "Got unexpected priority %lu, pool %s.\n", priority
, test_data
[i
].name
);
8677 priority
= IDirect3DTexture8_GetPriority(texture
);
8678 if (test_data
[i
].can_set_priority
)
8680 ok(priority
== 1, "Got unexpected priority %lu, pool %s.\n", priority
, test_data
[i
].name
);
8681 priority
= IDirect3DTexture8_SetPriority(texture
, 0);
8682 ok(priority
== 1, "Got unexpected priority %lu, pool %s.\n", priority
, test_data
[i
].name
);
8685 ok(priority
== 0, "Got unexpected priority %lu, pool %s.\n", priority
, test_data
[i
].name
);
8687 IDirect3DTexture8_Release(texture
);
8689 if (test_data
[i
].pool
!= D3DPOOL_SCRATCH
)
8691 hr
= IDirect3DDevice8_CreateVertexBuffer(device
, 256, 0, 0,
8692 test_data
[i
].pool
, &buffer
);
8693 ok(SUCCEEDED(hr
), "Failed to create buffer, hr %#lx, pool %s.\n", hr
, test_data
[i
].name
);
8695 priority
= IDirect3DVertexBuffer8_GetPriority(buffer
);
8696 ok(priority
== 0, "Got unexpected priority %lu, pool %s.\n", priority
, test_data
[i
].name
);
8697 priority
= IDirect3DVertexBuffer8_SetPriority(buffer
, 1);
8698 ok(priority
== 0, "Got unexpected priority %lu, pool %s.\n", priority
, test_data
[i
].name
);
8699 priority
= IDirect3DVertexBuffer8_GetPriority(buffer
);
8700 if (test_data
[i
].can_set_priority
)
8702 ok(priority
== 1, "Got unexpected priority %lu, pool %s.\n", priority
, test_data
[i
].name
);
8703 priority
= IDirect3DVertexBuffer8_SetPriority(buffer
, 0);
8704 ok(priority
== 1, "Got unexpected priority %lu, pool %s.\n", priority
, test_data
[i
].name
);
8707 ok(priority
== 0, "Got unexpected priority %lu, pool %s.\n", priority
, test_data
[i
].name
);
8709 IDirect3DVertexBuffer8_Release(buffer
);
8713 refcount
= IDirect3DDevice8_Release(device
);
8714 ok(!refcount
, "Device has %lu references left.\n", refcount
);
8715 IDirect3D8_Release(d3d
);
8716 DestroyWindow(window
);
8719 static void test_swapchain_parameters(void)
8721 IDirect3DSurface8
*backbuffer
;
8722 IDirect3DDevice8
*device
;
8723 HRESULT hr
, expected_hr
;
8728 D3DPRESENT_PARAMETERS present_parameters
, present_parameters_windowed
= {0};
8732 UINT backbuffer_count
;
8733 D3DSWAPEFFECT swap_effect
;
8738 /* Swap effect 0 is not allowed. */
8739 {TRUE
, 1, 0, D3DERR_INVALIDCALL
},
8740 {FALSE
, 1, 0, D3DERR_INVALIDCALL
},
8742 /* All (non-ex) swap effects are allowed in
8743 * windowed and fullscreen mode. */
8744 {TRUE
, 1, D3DSWAPEFFECT_DISCARD
, D3D_OK
},
8745 {TRUE
, 1, D3DSWAPEFFECT_FLIP
, D3D_OK
},
8746 {FALSE
, 1, D3DSWAPEFFECT_DISCARD
, D3D_OK
},
8747 {FALSE
, 1, D3DSWAPEFFECT_FLIP
, D3D_OK
},
8748 {FALSE
, 1, D3DSWAPEFFECT_COPY
, D3D_OK
},
8750 /* Only one backbuffer in copy mode. Reset allows it for
8752 {TRUE
, 0, D3DSWAPEFFECT_COPY
, D3D_OK
},
8753 {TRUE
, 1, D3DSWAPEFFECT_COPY
, D3D_OK
},
8754 {TRUE
, 2, D3DSWAPEFFECT_COPY
, D3DERR_INVALIDCALL
},
8755 {FALSE
, 2, D3DSWAPEFFECT_COPY
, D3DERR_INVALIDCALL
},
8756 {TRUE
, 0, D3DSWAPEFFECT_COPY_VSYNC
, D3D_OK
},
8757 {TRUE
, 1, D3DSWAPEFFECT_COPY_VSYNC
, D3D_OK
},
8758 {TRUE
, 2, D3DSWAPEFFECT_COPY_VSYNC
, D3DERR_INVALIDCALL
},
8759 {FALSE
, 2, D3DSWAPEFFECT_COPY_VSYNC
, D3DERR_INVALIDCALL
},
8761 /* Ok with the others, in fullscreen and windowed mode. */
8762 {TRUE
, 2, D3DSWAPEFFECT_DISCARD
, D3D_OK
},
8763 {TRUE
, 2, D3DSWAPEFFECT_FLIP
, D3D_OK
},
8764 {FALSE
, 2, D3DSWAPEFFECT_DISCARD
, D3D_OK
},
8765 {FALSE
, 2, D3DSWAPEFFECT_FLIP
, D3D_OK
},
8767 /* Invalid swapeffects. */
8768 {TRUE
, 1, D3DSWAPEFFECT_COPY_VSYNC
+ 1, D3DERR_INVALIDCALL
},
8769 {FALSE
, 1, D3DSWAPEFFECT_COPY_VSYNC
+ 1, D3DERR_INVALIDCALL
},
8771 /* 3 is the highest allowed backbuffer count. */
8772 {TRUE
, 3, D3DSWAPEFFECT_DISCARD
, D3D_OK
},
8773 {TRUE
, 4, D3DSWAPEFFECT_DISCARD
, D3DERR_INVALIDCALL
},
8774 {TRUE
, 4, D3DSWAPEFFECT_FLIP
, D3DERR_INVALIDCALL
},
8775 {FALSE
, 4, D3DSWAPEFFECT_DISCARD
, D3DERR_INVALIDCALL
},
8776 {FALSE
, 4, D3DSWAPEFFECT_FLIP
, D3DERR_INVALIDCALL
},
8779 window
= create_window();
8780 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
8781 ok(!!d3d
, "Failed to create a D3D object.\n");
8782 if (!(device
= create_device(d3d
, window
, NULL
)))
8784 skip("Failed to create a D3D device, skipping tests.\n");
8785 IDirect3D8_Release(d3d
);
8786 DestroyWindow(window
);
8789 hr
= IDirect3DDevice8_GetDeviceCaps(device
, &caps
);
8790 ok(SUCCEEDED(hr
), "Failed to get device caps, hr %#lx.\n", hr
);
8791 IDirect3DDevice8_Release(device
);
8793 present_parameters_windowed
.BackBufferWidth
= registry_mode
.dmPelsWidth
;
8794 present_parameters_windowed
.BackBufferHeight
= registry_mode
.dmPelsHeight
;
8795 present_parameters_windowed
.hDeviceWindow
= window
;
8796 present_parameters_windowed
.BackBufferFormat
= D3DFMT_X8R8G8B8
;
8797 present_parameters_windowed
.SwapEffect
= D3DSWAPEFFECT_COPY
;
8798 present_parameters_windowed
.Windowed
= TRUE
;
8799 present_parameters_windowed
.BackBufferCount
= 1;
8802 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
8804 UINT bb_count
= tests
[i
].backbuffer_count
? tests
[i
].backbuffer_count
: 1;
8806 memset(&present_parameters
, 0, sizeof(present_parameters
));
8807 present_parameters
.BackBufferWidth
= registry_mode
.dmPelsWidth
;
8808 present_parameters
.BackBufferHeight
= registry_mode
.dmPelsHeight
;
8809 present_parameters
.hDeviceWindow
= NULL
;
8810 present_parameters
.BackBufferFormat
= D3DFMT_X8R8G8B8
;
8812 present_parameters
.SwapEffect
= tests
[i
].swap_effect
;
8813 present_parameters
.Windowed
= tests
[i
].windowed
;
8814 present_parameters
.BackBufferCount
= tests
[i
].backbuffer_count
;
8816 hr
= IDirect3D8_CreateDevice(d3d
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
, window
,
8817 D3DCREATE_SOFTWARE_VERTEXPROCESSING
, &present_parameters
, &device
);
8818 ok(hr
== tests
[i
].hr
, "Expected hr %#lx, got %#lx, test %u.\n", tests
[i
].hr
, hr
, i
);
8821 for (j
= 0; j
< bb_count
; ++j
)
8823 hr
= IDirect3DDevice8_GetBackBuffer(device
, j
, D3DBACKBUFFER_TYPE_MONO
, &backbuffer
);
8824 ok(SUCCEEDED(hr
), "Failed to get backbuffer %u, hr %#lx, test %u.\n", j
, hr
, i
);
8825 IDirect3DSurface8_Release(backbuffer
);
8827 hr
= IDirect3DDevice8_GetBackBuffer(device
, j
, D3DBACKBUFFER_TYPE_MONO
, &backbuffer
);
8828 ok(hr
== D3DERR_INVALIDCALL
, "Got unexpected hr %#lx, test %u.\n", hr
, i
);
8830 IDirect3DDevice8_Release(device
);
8833 hr
= IDirect3D8_CreateDevice(d3d
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
, window
,
8834 D3DCREATE_SOFTWARE_VERTEXPROCESSING
, &present_parameters_windowed
, &device
);
8835 ok(SUCCEEDED(hr
), "Failed to create device, hr %#lx, test %u.\n", hr
, i
);
8837 memset(&present_parameters
, 0, sizeof(present_parameters
));
8838 present_parameters
.BackBufferWidth
= registry_mode
.dmPelsWidth
;
8839 present_parameters
.BackBufferHeight
= registry_mode
.dmPelsHeight
;
8840 present_parameters
.hDeviceWindow
= NULL
;
8841 present_parameters
.BackBufferFormat
= D3DFMT_X8R8G8B8
;
8843 present_parameters
.SwapEffect
= tests
[i
].swap_effect
;
8844 present_parameters
.Windowed
= tests
[i
].windowed
;
8845 present_parameters
.BackBufferCount
= tests
[i
].backbuffer_count
;
8847 hr
= IDirect3DDevice8_Reset(device
, &present_parameters
);
8848 ok(hr
== tests
[i
].hr
, "Expected hr %#lx, got %#lx, test %u.\n", tests
[i
].hr
, hr
, i
);
8852 hr
= IDirect3DDevice8_Reset(device
, &present_parameters_windowed
);
8853 ok(SUCCEEDED(hr
), "Failed to reset device, hr %#lx, test %u.\n", hr
, i
);
8857 for (j
= 0; j
< bb_count
; ++j
)
8859 hr
= IDirect3DDevice8_GetBackBuffer(device
, j
, D3DBACKBUFFER_TYPE_MONO
, &backbuffer
);
8861 ok(SUCCEEDED(hr
), "Failed to get backbuffer %u, hr %#lx, test %u.\n", j
, hr
, i
);
8863 IDirect3DSurface8_Release(backbuffer
);
8865 hr
= IDirect3DDevice8_GetBackBuffer(device
, j
, D3DBACKBUFFER_TYPE_MONO
, &backbuffer
);
8866 ok(hr
== D3DERR_INVALIDCALL
, "Got unexpected hr %#lx, test %u.\n", hr
, i
);
8868 IDirect3DDevice8_Release(device
);
8871 for (i
= 0; i
< 10; ++i
)
8873 memset(&present_parameters
, 0, sizeof(present_parameters
));
8874 present_parameters
.BackBufferWidth
= registry_mode
.dmPelsWidth
;
8875 present_parameters
.BackBufferHeight
= registry_mode
.dmPelsHeight
;
8876 present_parameters
.hDeviceWindow
= window
;
8877 present_parameters
.BackBufferFormat
= D3DFMT_X8R8G8B8
;
8878 present_parameters
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
8879 present_parameters
.Windowed
= FALSE
;
8880 present_parameters
.BackBufferCount
= 2;
8882 present_parameters
.FullScreen_PresentationInterval
= i
;
8883 switch (present_parameters
.FullScreen_PresentationInterval
)
8885 case D3DPRESENT_INTERVAL_ONE
:
8886 case D3DPRESENT_INTERVAL_TWO
:
8887 case D3DPRESENT_INTERVAL_THREE
:
8888 case D3DPRESENT_INTERVAL_FOUR
:
8889 if (!(caps
.PresentationIntervals
& present_parameters
.FullScreen_PresentationInterval
))
8892 case D3DPRESENT_INTERVAL_DEFAULT
:
8893 expected_hr
= D3D_OK
;
8896 expected_hr
= D3DERR_INVALIDCALL
;
8900 hr
= IDirect3D8_CreateDevice(d3d
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
, window
,
8901 D3DCREATE_SOFTWARE_VERTEXPROCESSING
, &present_parameters
, &device
);
8902 ok(hr
== expected_hr
, "Got unexpected hr %#lx, test %u.\n", hr
, i
);
8904 IDirect3DDevice8_Release(device
);
8907 memset(&present_parameters
, 0, sizeof(present_parameters
));
8908 present_parameters
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
8909 present_parameters
.Windowed
= TRUE
;
8910 present_parameters
.BackBufferWidth
= 0;
8911 present_parameters
.BackBufferHeight
= 0;
8912 present_parameters
.BackBufferFormat
= D3DFMT_X8R8G8B8
;
8914 hr
= IDirect3D8_CreateDevice(d3d
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
,
8915 window
, D3DCREATE_SOFTWARE_VERTEXPROCESSING
,
8916 &present_parameters
, &device
);
8918 ok(hr
== S_OK
, "Got unexpected hr %#lx.\n", hr
);
8919 ok(!present_parameters
.BackBufferWidth
, "Got unexpected BackBufferWidth %u.\n", present_parameters
.BackBufferWidth
);
8920 ok(!present_parameters
.BackBufferHeight
, "Got unexpected BackBufferHeight %u,.\n", present_parameters
.BackBufferHeight
);
8921 ok(present_parameters
.BackBufferFormat
== D3DFMT_X8R8G8B8
, "Got unexpected BackBufferFormat %#x.\n", present_parameters
.BackBufferFormat
);
8922 ok(present_parameters
.BackBufferCount
== 1, "Got unexpected BackBufferCount %u.\n", present_parameters
.BackBufferCount
);
8923 ok(!present_parameters
.MultiSampleType
, "Got unexpected MultiSampleType %u.\n", present_parameters
.MultiSampleType
);
8924 ok(present_parameters
.SwapEffect
== D3DSWAPEFFECT_DISCARD
, "Got unexpected SwapEffect %#x.\n", present_parameters
.SwapEffect
);
8925 ok(!present_parameters
.hDeviceWindow
, "Got unexpected hDeviceWindow %p.\n", present_parameters
.hDeviceWindow
);
8926 ok(present_parameters
.Windowed
, "Got unexpected Windowed %#x.\n", present_parameters
.Windowed
);
8927 ok(!present_parameters
.EnableAutoDepthStencil
, "Got unexpected EnableAutoDepthStencil %#x.\n", present_parameters
.EnableAutoDepthStencil
);
8928 ok(!present_parameters
.AutoDepthStencilFormat
, "Got unexpected AutoDepthStencilFormat %#x.\n", present_parameters
.AutoDepthStencilFormat
);
8929 ok(!present_parameters
.Flags
, "Got unexpected Flags %#lx.\n", present_parameters
.Flags
);
8930 ok(!present_parameters
.FullScreen_RefreshRateInHz
, "Got unexpected FullScreen_RefreshRateInHz %u.\n", present_parameters
.FullScreen_RefreshRateInHz
);
8931 ok(!present_parameters
.FullScreen_PresentationInterval
, "Got unexpected FullScreen_PresentationInterval %#x.\n", present_parameters
.FullScreen_PresentationInterval
);
8933 IDirect3DDevice8_Release(device
);
8934 IDirect3D8_Release(d3d
);
8935 DestroyWindow(window
);
8938 static void test_check_device_format(void)
8940 D3DDEVTYPE device_type
;
8944 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
8945 ok(!!d3d
, "Failed to create a D3D object.\n");
8947 for (device_type
= D3DDEVTYPE_HAL
; device_type
<= D3DDEVTYPE_SW
; ++device_type
)
8949 hr
= IDirect3D8_CheckDeviceFormat(d3d
, 0, device_type
, D3DFMT_UNKNOWN
,
8950 0, D3DRTYPE_SURFACE
, D3DFMT_A8R8G8B8
);
8951 ok(hr
== D3DERR_INVALIDCALL
, "Got unexpected hr %#lx, device type %#x.\n", hr
, device_type
);
8952 hr
= IDirect3D8_CheckDeviceFormat(d3d
, 0, device_type
, D3DFMT_UNKNOWN
,
8953 0, D3DRTYPE_TEXTURE
, D3DFMT_A8R8G8B8
);
8954 ok(hr
== D3DERR_INVALIDCALL
, "Got unexpected hr %#lx, device type %#x.\n", hr
, device_type
);
8955 hr
= IDirect3D8_CheckDeviceFormat(d3d
, 0, device_type
, D3DFMT_UNKNOWN
,
8956 0, D3DRTYPE_SURFACE
, D3DFMT_X8R8G8B8
);
8957 ok(hr
== D3DERR_INVALIDCALL
, "Got unexpected hr %#lx, device type %#x.\n", hr
, device_type
);
8958 hr
= IDirect3D8_CheckDeviceFormat(d3d
, 0, device_type
, D3DFMT_UNKNOWN
,
8959 0, D3DRTYPE_TEXTURE
, D3DFMT_X8R8G8B8
);
8960 ok(hr
== D3DERR_INVALIDCALL
, "Got unexpected hr %#lx, device type %#x.\n", hr
, device_type
);
8963 hr
= IDirect3D8_CheckDeviceFormat(d3d
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
, D3DFMT_A8R8G8B8
,
8964 0, D3DRTYPE_TEXTURE
, D3DFMT_X8R8G8B8
);
8965 ok(hr
== D3DERR_NOTAVAILABLE
, "Got unexpected hr %#lx.\n", hr
);
8966 hr
= IDirect3D8_CheckDeviceFormat(d3d
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
, D3DFMT_X8R8G8B8
,
8967 0, D3DRTYPE_TEXTURE
, D3DFMT_X8R8G8B8
);
8968 ok(hr
== D3D_OK
|| hr
== D3DERR_NOTAVAILABLE
, "Got unexpected hr %#lx.\n", hr
);
8970 hr
= IDirect3D8_CheckDeviceFormat(d3d
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
, D3DFMT_X8R8G8B8
,
8971 0, D3DRTYPE_VERTEXBUFFER
, D3DFMT_VERTEXDATA
);
8972 todo_wine
ok(hr
== D3DERR_INVALIDCALL
, "Got unexpected hr %#lx.\n", hr
);
8973 hr
= IDirect3D8_CheckDeviceFormat(d3d
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
, D3DFMT_X8R8G8B8
,
8974 0, D3DRTYPE_INDEXBUFFER
, D3DFMT_VERTEXDATA
);
8975 todo_wine
ok(hr
== D3DERR_INVALIDCALL
, "Got unexpected hr %#lx.\n", hr
);
8976 hr
= IDirect3D8_CheckDeviceFormat(d3d
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
, D3DFMT_X8R8G8B8
,
8977 0, D3DRTYPE_INDEXBUFFER
, D3DFMT_INDEX16
);
8978 todo_wine
ok(hr
== D3DERR_INVALIDCALL
, "Got unexpected hr %#lx.\n", hr
);
8980 hr
= IDirect3D8_CheckDeviceFormat(d3d
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
, D3DFMT_X8R8G8B8
,
8981 D3DUSAGE_SOFTWAREPROCESSING
, D3DRTYPE_VERTEXBUFFER
, D3DFMT_VERTEXDATA
);
8982 todo_wine
ok(hr
== D3DERR_INVALIDCALL
, "Got unexpected hr %#lx.\n", hr
);
8983 hr
= IDirect3D8_CheckDeviceFormat(d3d
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
, D3DFMT_X8R8G8B8
,
8984 D3DUSAGE_SOFTWAREPROCESSING
, D3DRTYPE_INDEXBUFFER
, D3DFMT_VERTEXDATA
);
8985 todo_wine
ok(hr
== D3DERR_INVALIDCALL
, "Got unexpected hr %#lx.\n", hr
);
8986 hr
= IDirect3D8_CheckDeviceFormat(d3d
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
, D3DFMT_X8R8G8B8
,
8987 D3DUSAGE_SOFTWAREPROCESSING
, D3DRTYPE_INDEXBUFFER
, D3DFMT_INDEX16
);
8988 todo_wine
ok(hr
== D3DERR_INVALIDCALL
, "Got unexpected hr %#lx.\n", hr
);
8990 hr
= IDirect3D8_CheckDepthStencilMatch(d3d
, D3DADAPTER_DEFAULT
,
8991 D3DDEVTYPE_HAL
, D3DFMT_X8R8G8B8
, D3DFMT_A8R8G8B8
, D3DFMT_D32
);
8992 ok(hr
== D3DERR_NOTAVAILABLE
|| broken(hr
== D3DERR_INVALIDCALL
/* Windows 10 */),
8993 "Got unexpected hr %#lx.\n", hr
);
8995 hr
= IDirect3D8_CheckDepthStencilMatch(d3d
, D3DADAPTER_DEFAULT
,
8996 D3DDEVTYPE_HAL
, D3DFMT_X8R8G8B8
, D3DFMT_R5G6B5
, D3DFMT_D32
);
8997 ok(hr
== D3DERR_NOTAVAILABLE
|| broken(hr
== D3DERR_INVALIDCALL
/* Windows 10 */),
8998 "Got unexpected hr %#lx.\n", hr
);
9000 IDirect3D8_Release(d3d
);
9003 static void test_miptree_layout(void)
9005 unsigned int pool_idx
, format_idx
, base_dimension
, level_count
, offset
, i
, j
;
9006 IDirect3DCubeTexture8
*texture_cube
;
9007 IDirect3DTexture8
*texture_2d
;
9008 IDirect3DDevice8
*device
;
9009 D3DLOCKED_RECT map_desc
;
9024 {D3DFMT_A8R8G8B8
, "D3DFMT_A8R8G8B8"},
9025 {D3DFMT_A8
, "D3DFMT_A8"},
9026 {D3DFMT_L8
, "D3DFMT_L8"},
9027 {MAKEFOURCC('A','T','I','1'), "D3DFMT_ATI1"},
9028 {MAKEFOURCC('A','T','I','2'), "D3DFMT_ATI2"},
9037 {D3DPOOL_MANAGED
, "D3DPOOL_MANAGED"},
9038 {D3DPOOL_SYSTEMMEM
, "D3DPOOL_SYSTEMMEM"},
9039 {D3DPOOL_SCRATCH
, "D3DPOOL_SCRATCH"},
9042 window
= create_window();
9043 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
9044 ok(!!d3d
, "Failed to create a D3D object.\n");
9045 if (!(device
= create_device(d3d
, window
, NULL
)))
9047 skip("Failed to create a D3D device, skipping tests.\n");
9051 hr
= IDirect3DDevice8_GetDeviceCaps(device
, &caps
);
9052 ok(SUCCEEDED(hr
), "Failed to get caps, hr %#lx.\n", hr
);
9054 base_dimension
= 257;
9055 if (caps
.TextureCaps
& (D3DPTEXTURECAPS_POW2
| D3DPTEXTURECAPS_CUBEMAP_POW2
))
9057 skip("Using power of two base dimension.\n");
9058 base_dimension
= 256;
9061 for (format_idx
= 0; format_idx
< ARRAY_SIZE(formats
); ++format_idx
)
9063 if (FAILED(hr
= IDirect3D8_CheckDeviceFormat(d3d
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
,
9064 D3DFMT_X8R8G8B8
, 0, D3DRTYPE_TEXTURE
, formats
[format_idx
].format
)))
9066 skip("%s textures not supported, skipping tests.\n", formats
[format_idx
].name
);
9070 for (pool_idx
= 0; pool_idx
< ARRAY_SIZE(pools
); ++pool_idx
)
9072 hr
= IDirect3DDevice8_CreateTexture(device
, base_dimension
, base_dimension
, 0, 0,
9073 formats
[format_idx
].format
, pools
[pool_idx
].pool
, &texture_2d
);
9074 ok(SUCCEEDED(hr
), "Failed to create a %s %s texture, hr %#lx.\n",
9075 pools
[pool_idx
].name
, formats
[format_idx
].name
, hr
);
9077 level_count
= IDirect3DTexture8_GetLevelCount(texture_2d
);
9078 for (i
= 0, offset
= 0; i
< level_count
; ++i
)
9080 hr
= IDirect3DTexture8_LockRect(texture_2d
, i
, &map_desc
, NULL
, 0);
9081 ok(SUCCEEDED(hr
), "%s, %s: Failed to lock level %u, hr %#lx.\n",
9082 pools
[pool_idx
].name
, formats
[format_idx
].name
, i
, hr
);
9085 base
= map_desc
.pBits
;
9087 ok(map_desc
.pBits
== base
+ offset
,
9088 "%s, %s, level %u: Got unexpected pBits %p, expected %p.\n",
9089 pools
[pool_idx
].name
, formats
[format_idx
].name
, i
, map_desc
.pBits
, base
+ offset
);
9090 offset
+= (base_dimension
>> i
) * map_desc
.Pitch
;
9092 hr
= IDirect3DTexture8_UnlockRect(texture_2d
, i
);
9093 ok(SUCCEEDED(hr
), "%s, %s Failed to unlock level %u, hr %#lx.\n",
9094 pools
[pool_idx
].name
, formats
[format_idx
].name
, i
, hr
);
9097 IDirect3DTexture8_Release(texture_2d
);
9100 if (FAILED(hr
= IDirect3D8_CheckDeviceFormat(d3d
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
,
9101 D3DFMT_X8R8G8B8
, 0, D3DRTYPE_CUBETEXTURE
, formats
[format_idx
].format
)))
9103 skip("%s cube textures not supported, skipping tests.\n", formats
[format_idx
].name
);
9107 for (pool_idx
= 0; pool_idx
< ARRAY_SIZE(pools
); ++pool_idx
)
9109 hr
= IDirect3DDevice8_CreateCubeTexture(device
, base_dimension
, 0, 0,
9110 formats
[format_idx
].format
, pools
[pool_idx
].pool
, &texture_cube
);
9111 ok(SUCCEEDED(hr
), "Failed to create a %s %s cube texture, hr %#lx.\n",
9112 pools
[pool_idx
].name
, formats
[format_idx
].name
, hr
);
9114 level_count
= IDirect3DCubeTexture8_GetLevelCount(texture_cube
);
9115 for (i
= 0, offset
= 0; i
< 6; ++i
)
9117 for (j
= 0; j
< level_count
; ++j
)
9119 hr
= IDirect3DCubeTexture8_LockRect(texture_cube
, i
, j
, &map_desc
, NULL
, 0);
9120 ok(SUCCEEDED(hr
), "%s, %s: Failed to lock face %u, level %u, hr %#lx.\n",
9121 pools
[pool_idx
].name
, formats
[format_idx
].name
, i
, j
, hr
);
9124 base
= map_desc
.pBits
;
9126 ok(map_desc
.pBits
== base
+ offset
,
9127 "%s, %s, face %u, level %u: Got unexpected pBits %p, expected %p.\n",
9128 pools
[pool_idx
].name
, formats
[format_idx
].name
, i
, j
, map_desc
.pBits
, base
+ offset
);
9129 offset
+= (base_dimension
>> j
) * map_desc
.Pitch
;
9131 hr
= IDirect3DCubeTexture8_UnlockRect(texture_cube
, i
, j
);
9132 ok(SUCCEEDED(hr
), "%s, %s: Failed to unlock face %u, level %u, hr %#lx.\n",
9133 pools
[pool_idx
].name
, formats
[format_idx
].name
, i
, j
, hr
);
9135 offset
= (offset
+ 15) & ~15;
9138 IDirect3DCubeTexture8_Release(texture_cube
);
9142 refcount
= IDirect3DDevice8_Release(device
);
9143 ok(!refcount
, "Device has %u references left.\n", refcount
);
9145 IDirect3D8_Release(d3d
);
9146 DestroyWindow(window
);
9149 static void test_render_target_device_mismatch(void)
9151 IDirect3DDevice8
*device
, *device2
;
9152 IDirect3DSurface8
*surface
, *rt
;
9158 window
= create_window();
9159 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
9160 ok(!!d3d
, "Failed to create a D3D object.\n");
9161 if (!(device
= create_device(d3d
, window
, NULL
)))
9163 skip("Failed to create a D3D device.\n");
9164 IDirect3D8_Release(d3d
);
9165 DestroyWindow(window
);
9169 hr
= IDirect3DDevice8_GetRenderTarget(device
, &rt
);
9170 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#lx.\n", hr
);
9172 device2
= create_device(d3d
, window
, NULL
);
9173 ok(!!device2
, "Failed to create a D3D device.\n");
9175 hr
= IDirect3DDevice8_CreateRenderTarget(device2
, 640, 480,
9176 D3DFMT_A8R8G8B8
, D3DMULTISAMPLE_NONE
, FALSE
, &surface
);
9177 ok(SUCCEEDED(hr
), "Failed to create render target, hr %#lx.\n", hr
);
9179 hr
= IDirect3DDevice8_SetRenderTarget(device
, surface
, NULL
);
9180 ok(hr
== D3DERR_INVALIDCALL
, "Got unexpected hr %#lx.\n", hr
);
9182 IDirect3DSurface8_Release(surface
);
9184 hr
= IDirect3DDevice8_GetRenderTarget(device2
, &surface
);
9185 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#lx.\n", hr
);
9187 hr
= IDirect3DDevice8_SetRenderTarget(device
, surface
, NULL
);
9188 ok(hr
== D3DERR_INVALIDCALL
, "Got unexpected hr %#lx.\n", hr
);
9190 IDirect3DSurface8_Release(surface
);
9192 hr
= IDirect3DDevice8_GetRenderTarget(device
, &surface
);
9193 ok(SUCCEEDED(hr
), "Failed to get render target, hr %#lx.\n", hr
);
9194 ok(surface
== rt
, "Got unexpected render target %p, expected %p.\n", surface
, rt
);
9195 IDirect3DSurface8_Release(surface
);
9196 IDirect3DSurface8_Release(rt
);
9198 refcount
= IDirect3DDevice8_Release(device
);
9199 ok(!refcount
, "Device has %u references left.\n", refcount
);
9200 refcount
= IDirect3DDevice8_Release(device2
);
9201 ok(!refcount
, "Device has %u references left.\n", refcount
);
9202 IDirect3D8_Release(d3d
);
9203 DestroyWindow(window
);
9206 static void test_format_unknown(void)
9208 IDirect3DDevice8
*device
;
9215 window
= create_window();
9216 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
9217 ok(!!d3d
, "Failed to create a D3D object.\n");
9218 if (!(device
= create_device(d3d
, window
, NULL
)))
9220 skip("Failed to create a D3D device.\n");
9221 IDirect3D8_Release(d3d
);
9222 DestroyWindow(window
);
9226 if (SUCCEEDED(IDirect3D8_CheckDeviceFormat(d3d
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
,
9227 D3DFMT_X8R8G8B8
, 0, D3DRTYPE_TEXTURE
, D3DFMT_P8
)))
9229 skip("P8 textures are supported, skipping some tests.\n");
9233 iface
= (void *)0xdeadbeef;
9234 hr
= IDirect3DDevice8_CreateRenderTarget(device
, 64, 64,
9235 D3DFMT_P8
, D3DMULTISAMPLE_NONE
, FALSE
, (IDirect3DSurface8
**)&iface
);
9236 ok(hr
== D3DERR_INVALIDCALL
, "Got unexpected hr %#lx.\n", hr
);
9237 ok(!iface
, "Got unexpected iface %p.\n", iface
);
9239 iface
= (void *)0xdeadbeef;
9240 hr
= IDirect3DDevice8_CreateDepthStencilSurface(device
, 64, 64,
9241 D3DFMT_P8
, D3DMULTISAMPLE_NONE
, (IDirect3DSurface8
**)&iface
);
9242 ok(hr
== D3DERR_INVALIDCALL
, "Got unexpected hr %#lx.\n", hr
);
9243 ok(!iface
, "Got unexpected iface %p.\n", iface
);
9245 iface
= (void *)0xdeadbeef;
9246 hr
= IDirect3DDevice8_CreateTexture(device
, 64, 64, 1, 0,
9247 D3DFMT_P8
, D3DPOOL_DEFAULT
, (IDirect3DTexture8
**)&iface
);
9248 ok(hr
== D3DERR_INVALIDCALL
, "Got unexpected hr %#lx.\n", hr
);
9249 ok(!iface
, "Got unexpected iface %p.\n", iface
);
9251 iface
= (void *)0xdeadbeef;
9252 hr
= IDirect3DDevice8_CreateCubeTexture(device
, 64, 1, 0,
9253 D3DFMT_P8
, D3DPOOL_DEFAULT
, (IDirect3DCubeTexture8
**)&iface
);
9254 ok(hr
== D3DERR_INVALIDCALL
, "Got unexpected hr %#lx.\n", hr
);
9255 ok(!iface
, "Got unexpected iface %p.\n", iface
);
9257 iface
= (void *)0xdeadbeef;
9258 hr
= IDirect3DDevice8_CreateVolumeTexture(device
, 64, 64, 1, 1, 0,
9259 D3DFMT_P8
, D3DPOOL_DEFAULT
, (IDirect3DVolumeTexture8
**)&iface
);
9260 ok(hr
== D3DERR_INVALIDCALL
, "Got unexpected hr %#lx.\n", hr
);
9261 ok(!iface
, "Got unexpected iface %p.\n", iface
);
9264 iface
= (void *)0xdeadbeef;
9265 hr
= IDirect3DDevice8_CreateRenderTarget(device
, 64, 64,
9266 D3DFMT_UNKNOWN
, D3DMULTISAMPLE_NONE
, FALSE
, (IDirect3DSurface8
**)&iface
);
9267 ok(hr
== D3DERR_INVALIDCALL
, "Got unexpected hr %#lx.\n", hr
);
9268 ok(iface
== (void *)0xdeadbeef, "Got unexpected iface %p.\n", iface
);
9270 iface
= (void *)0xdeadbeef;
9271 hr
= IDirect3DDevice8_CreateDepthStencilSurface(device
, 64, 64,
9272 D3DFMT_UNKNOWN
, D3DMULTISAMPLE_NONE
, (IDirect3DSurface8
**)&iface
);
9273 ok(hr
== D3DERR_INVALIDCALL
, "Got unexpected hr %#lx.\n", hr
);
9274 ok(iface
== (void *)0xdeadbeef, "Got unexpected iface %p.\n", iface
);
9276 iface
= (void *)0xdeadbeef;
9277 hr
= IDirect3DDevice8_CreateImageSurface(device
, 64, 64,
9278 D3DFMT_UNKNOWN
, (IDirect3DSurface8
**)&iface
);
9279 ok(hr
== D3DERR_INVALIDCALL
, "Got unexpected hr %#lx.\n", hr
);
9280 ok(!iface
, "Got unexpected iface %p.\n", iface
);
9282 iface
= (void *)0xdeadbeef;
9283 hr
= IDirect3DDevice8_CreateTexture(device
, 64, 64, 1, 0,
9284 D3DFMT_UNKNOWN
, D3DPOOL_DEFAULT
, (IDirect3DTexture8
**)&iface
);
9285 ok(hr
== D3DERR_INVALIDCALL
, "Got unexpected hr %#lx.\n", hr
);
9286 ok(iface
== (void *)0xdeadbeef, "Got unexpected iface %p.\n", iface
);
9288 iface
= (void *)0xdeadbeef;
9289 hr
= IDirect3DDevice8_CreateCubeTexture(device
, 64, 1, 0,
9290 D3DFMT_UNKNOWN
, D3DPOOL_DEFAULT
, (IDirect3DCubeTexture8
**)&iface
);
9291 ok(hr
== D3DERR_INVALIDCALL
, "Got unexpected hr %#lx.\n", hr
);
9292 ok(iface
== (void *)0xdeadbeef, "Got unexpected iface %p.\n", iface
);
9294 iface
= (void *)0xdeadbeef;
9295 hr
= IDirect3DDevice8_CreateVolumeTexture(device
, 64, 64, 1, 1, 0,
9296 D3DFMT_UNKNOWN
, D3DPOOL_DEFAULT
, (IDirect3DVolumeTexture8
**)&iface
);
9297 ok(hr
== D3DERR_INVALIDCALL
, "Got unexpected hr %#lx.\n", hr
);
9298 ok(iface
== (void *)0xdeadbeef, "Got unexpected iface %p.\n", iface
);
9300 refcount
= IDirect3DDevice8_Release(device
);
9301 ok(!refcount
, "Device has %u references left.\n", refcount
);
9302 IDirect3D8_Release(d3d
);
9303 DestroyWindow(window
);
9306 static void test_destroyed_window(void)
9308 IDirect3DDevice8
*device
;
9314 /* No WS_VISIBLE. */
9315 window
= CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW
,
9316 0, 0, 640, 480, NULL
, NULL
, NULL
, NULL
);
9317 ok(!!window
, "Failed to create a window.\n");
9319 d3d8
= Direct3DCreate8(D3D_SDK_VERSION
);
9320 ok(!!d3d8
, "Failed to create a D3D object.\n");
9321 device
= create_device(d3d8
, window
, NULL
);
9322 IDirect3D8_Release(d3d8
);
9323 DestroyWindow(window
);
9326 skip("Failed to create a 3D device, skipping test.\n");
9330 hr
= IDirect3DDevice8_BeginScene(device
);
9331 ok(SUCCEEDED(hr
), "Failed to begin scene, hr %#lx.\n", hr
);
9332 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0x00000000, 0.0f
, 0);
9333 ok(SUCCEEDED(hr
), "Failed to clear, hr %#lx.\n", hr
);
9334 hr
= IDirect3DDevice8_EndScene(device
);
9335 ok(SUCCEEDED(hr
), "Failed to end scene, hr %#lx.\n", hr
);
9336 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
9337 todo_wine
ok(hr
== D3DERR_INVALIDCALL
, "Got unexpected hr %#lx.\n", hr
);
9339 refcount
= IDirect3DDevice8_Release(device
);
9340 ok(!refcount
, "Device has %lu references left.\n", refcount
);
9343 static void test_lockable_backbuffer(void)
9345 D3DPRESENT_PARAMETERS present_parameters
= {0};
9346 struct device_desc device_desc
;
9347 IDirect3DSurface8
*surface
;
9348 IDirect3DDevice8
*device
;
9349 D3DLOCKED_RECT lockrect
;
9355 window
= create_window();
9356 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
9357 ok(!!d3d
, "Failed to create a D3D object.\n");
9359 if (!(device
= create_device(d3d
, window
, NULL
)))
9361 skip("Failed to create a D3D device, skipping tests.\n");
9362 IDirect3D8_Release(d3d
);
9363 DestroyWindow(window
);
9367 hr
= IDirect3DDevice8_GetBackBuffer(device
, 0, D3DBACKBUFFER_TYPE_MONO
, &surface
);
9368 ok(SUCCEEDED(hr
), "Failed to get backbuffer, hr %#lx.\n", hr
);
9370 hr
= IDirect3DSurface8_LockRect(surface
, &lockrect
, NULL
, D3DLOCK_READONLY
);
9371 ok(hr
== D3DERR_INVALIDCALL
, "Got unexpected hr %#lx.\n", hr
);
9373 IDirect3DSurface8_Release(surface
);
9375 /* Reset with D3DPRESENTFLAG_LOCKABLE_BACKBUFFER. */
9376 present_parameters
.BackBufferWidth
= 640;
9377 present_parameters
.BackBufferHeight
= 480;
9378 present_parameters
.BackBufferFormat
= D3DFMT_A8R8G8B8
;
9379 present_parameters
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
9380 present_parameters
.hDeviceWindow
= window
;
9381 present_parameters
.Windowed
= TRUE
;
9382 present_parameters
.EnableAutoDepthStencil
= TRUE
;
9383 present_parameters
.AutoDepthStencilFormat
= D3DFMT_D24S8
;
9384 present_parameters
.Flags
= D3DPRESENTFLAG_LOCKABLE_BACKBUFFER
;
9386 hr
= IDirect3DDevice8_Reset(device
, &present_parameters
);
9387 ok(SUCCEEDED(hr
), "Failed to reset device, hr %#lx.\n", hr
);
9389 hr
= IDirect3DDevice8_GetBackBuffer(device
, 0, D3DBACKBUFFER_TYPE_MONO
, &surface
);
9390 ok(SUCCEEDED(hr
), "Failed to get backbuffer, hr %#lx.\n", hr
);
9392 hr
= IDirect3DSurface8_LockRect(surface
, &lockrect
, NULL
, D3DLOCK_READONLY
);
9393 ok(SUCCEEDED(hr
), "Failed to lock rect, hr %#lx.\n", hr
);
9394 hr
= IDirect3DSurface8_UnlockRect(surface
);
9395 ok(SUCCEEDED(hr
), "Failed to unlock rect, hr %#lx.\n", hr
);
9397 IDirect3DSurface8_Release(surface
);
9398 refcount
= IDirect3DDevice8_Release(device
);
9399 ok(!refcount
, "Device has %lu references left.\n", refcount
);
9401 device_desc
.adapter_ordinal
= D3DADAPTER_DEFAULT
;
9402 device_desc
.width
= 640;
9403 device_desc
.height
= 480;
9404 device_desc
.device_window
= window
;
9405 device_desc
.flags
= CREATE_DEVICE_LOCKABLE_BACKBUFFER
;
9407 device
= create_device(d3d
, window
, &device_desc
);
9408 ok(!!device
, "Failed to create device.\n");
9410 hr
= IDirect3DDevice8_GetBackBuffer(device
, 0, D3DBACKBUFFER_TYPE_MONO
, &surface
);
9411 ok(SUCCEEDED(hr
), "Failed to get backbuffer, hr %#lx.\n", hr
);
9413 hr
= IDirect3DSurface8_LockRect(surface
, &lockrect
, NULL
, D3DLOCK_READONLY
);
9414 ok(SUCCEEDED(hr
), "Failed to lock rect, hr %#lx.\n", hr
);
9415 hr
= IDirect3DSurface8_UnlockRect(surface
);
9416 ok(SUCCEEDED(hr
), "Failed to unlock rect, hr %#lx.\n", hr
);
9418 IDirect3DSurface8_Release(surface
);
9419 refcount
= IDirect3DDevice8_Release(device
);
9420 ok(!refcount
, "Device has %lu references left.\n", refcount
);
9421 IDirect3D8_Release(d3d
);
9422 DestroyWindow(window
);
9425 static void test_clip_planes_limits(void)
9427 static const DWORD device_flags
[] = {0, CREATE_DEVICE_SWVP_ONLY
};
9428 IDirect3DDevice8
*device
;
9429 struct device_desc desc
;
9439 window
= create_window();
9440 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
9441 ok(!!d3d
, "Failed to create a D3D object.\n");
9443 for (i
= 0; i
< ARRAY_SIZE(device_flags
); ++i
)
9445 desc
.adapter_ordinal
= D3DADAPTER_DEFAULT
;
9446 desc
.device_window
= window
;
9449 desc
.flags
= device_flags
[i
];
9450 if (!(device
= create_device(d3d
, window
, &desc
)))
9452 skip("Failed to create D3D device, flags %#lx.\n", desc
.flags
);
9456 memset(&caps
, 0, sizeof(caps
));
9457 hr
= IDirect3DDevice8_GetDeviceCaps(device
, &caps
);
9458 ok(hr
== D3D_OK
, "Failed to get caps, hr %#lx.\n", hr
);
9460 trace("Max user clip planes: %lu.\n", caps
.MaxUserClipPlanes
);
9462 for (j
= 0; j
< caps
.MaxUserClipPlanes
; ++j
)
9464 memset(plane
, 0xff, sizeof(plane
));
9465 hr
= IDirect3DDevice8_GetClipPlane(device
, j
, plane
);
9466 ok(hr
== D3D_OK
, "Failed to get clip plane %u, hr %#lx.\n", j
, hr
);
9467 ok(!plane
[0] && !plane
[1] && !plane
[2] && !plane
[3],
9468 "Got unexpected plane %u: %.8e, %.8e, %.8e, %.8e.\n",
9469 j
, plane
[0], plane
[1], plane
[2], plane
[3]);
9475 for (j
= 0; j
< caps
.MaxUserClipPlanes
; ++j
)
9478 hr
= IDirect3DDevice8_SetClipPlane(device
, j
, plane
);
9479 ok(hr
== D3D_OK
, "Failed to set clip plane %u, hr %#lx.\n", j
, hr
);
9481 for (j
= 0; j
< caps
.MaxUserClipPlanes
; ++j
)
9483 memset(plane
, 0xff, sizeof(plane
));
9484 hr
= IDirect3DDevice8_GetClipPlane(device
, j
, plane
);
9485 ok(hr
== D3D_OK
, "Failed to get clip plane %u, hr %#lx.\n", j
, hr
);
9486 ok(plane
[0] == 2.0f
&& plane
[1] == 8.0f
&& plane
[2] == 5.0f
&& plane
[3] == j
,
9487 "Got unexpected plane %u: %.8e, %.8e, %.8e, %.8e.\n",
9488 j
, plane
[0], plane
[1], plane
[2], plane
[3]);
9491 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_CLIPPLANEENABLE
, 0xffffffff);
9492 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#lx.\n", hr
);
9493 hr
= IDirect3DDevice8_GetRenderState(device
, D3DRS_CLIPPLANEENABLE
, &state
);
9494 ok(SUCCEEDED(hr
), "Failed to get render state, hr %#lx.\n", hr
);
9495 ok(state
== 0xffffffff, "Got unexpected state %#lx.\n", state
);
9496 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_CLIPPLANEENABLE
, 0x80000000);
9497 ok(SUCCEEDED(hr
), "Failed to set render state, hr %#lx.\n", hr
);
9498 hr
= IDirect3DDevice8_GetRenderState(device
, D3DRS_CLIPPLANEENABLE
, &state
);
9499 ok(SUCCEEDED(hr
), "Failed to get render state, hr %#lx.\n", hr
);
9500 ok(state
== 0x80000000, "Got unexpected state %#lx.\n", state
);
9502 refcount
= IDirect3DDevice8_Release(device
);
9503 ok(!refcount
, "Device has %lu references left.\n", refcount
);
9506 IDirect3D8_Release(d3d
);
9507 DestroyWindow(window
);
9510 static void test_swapchain_multisample_reset(void)
9512 D3DPRESENT_PARAMETERS present_parameters
;
9513 IDirect3DDevice8
*device
;
9519 window
= create_window();
9520 ok(!!window
, "Failed to create a window.\n");
9521 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
9522 ok(!!d3d
, "Failed to create D3D object.\n");
9524 if (IDirect3D8_CheckDeviceMultiSampleType(d3d
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
,
9525 D3DFMT_A8R8G8B8
, TRUE
, D3DMULTISAMPLE_2_SAMPLES
) == D3DERR_NOTAVAILABLE
)
9527 skip("Multisampling not supported for D3DFMT_A8R8G8B8.\n");
9528 IDirect3D8_Release(d3d
);
9529 DestroyWindow(window
);
9533 if (!(device
= create_device(d3d
, window
, NULL
)))
9535 skip("Failed to create 3D device.\n");
9536 IDirect3D8_Release(d3d
);
9537 DestroyWindow(window
);
9541 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
| D3DCLEAR_ZBUFFER
, 0xffffffff, 1.0f
, 0);
9542 ok(hr
== D3D_OK
, "Failed to clear, hr %#lx.\n", hr
);
9544 memset(&present_parameters
, 0, sizeof(present_parameters
));
9545 present_parameters
.BackBufferWidth
= 640;
9546 present_parameters
.BackBufferHeight
= 480;
9547 present_parameters
.BackBufferFormat
= D3DFMT_A8R8G8B8
;
9548 present_parameters
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
9549 present_parameters
.hDeviceWindow
= NULL
;
9550 present_parameters
.Windowed
= TRUE
;
9551 present_parameters
.MultiSampleType
= D3DMULTISAMPLE_2_SAMPLES
;
9552 hr
= IDirect3DDevice8_Reset(device
, &present_parameters
);
9553 ok(hr
== D3D_OK
, "Failed to reset device, hr %#lx.\n", hr
);
9555 hr
= IDirect3DDevice8_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
, 0xffffffff, 0.0f
, 0);
9556 ok(hr
== D3D_OK
, "Failed to clear, hr %#lx.\n", hr
);
9558 refcount
= IDirect3DDevice8_Release(device
);
9559 ok(!refcount
, "Device has %lu references left.\n", refcount
);
9560 IDirect3D8_Release(d3d
);
9561 DestroyWindow(window
);
9564 static void test_device_caps(void)
9566 unsigned int adapter_idx
, adapter_count
;
9567 struct device_desc device_desc
;
9568 IDirect3DDevice8
*device
;
9575 window
= create_window();
9576 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
9577 ok(!!d3d
, "Failed to create a D3D object.\n");
9579 device_desc
.device_window
= window
;
9580 device_desc
.width
= 640;
9581 device_desc
.height
= 480;
9582 device_desc
.flags
= 0;
9584 adapter_count
= IDirect3D8_GetAdapterCount(d3d
);
9585 for (adapter_idx
= 0; adapter_idx
< adapter_count
; ++adapter_idx
)
9587 /* Test IDirect3D8_GetDeviceCaps */
9588 hr
= IDirect3D8_GetDeviceCaps(d3d
, adapter_idx
, D3DDEVTYPE_HAL
, &caps
);
9589 ok(hr
== D3D_OK
|| hr
== D3DERR_NOTAVAILABLE
, "Adapter %u: GetDeviceCaps failed, hr %#lx.\n",
9591 if (hr
== D3DERR_NOTAVAILABLE
)
9593 skip("Adapter %u: No Direct3D support, skipping test.\n", adapter_idx
);
9596 ok(caps
.AdapterOrdinal
== adapter_idx
, "Adapter %u: Got unexpected adapter ordinal %u.\n",
9597 adapter_idx
, caps
.AdapterOrdinal
);
9599 /* Test IDirect3DDevice8_GetDeviceCaps */
9600 device_desc
.adapter_ordinal
= adapter_idx
;
9601 device
= create_device(d3d
, window
, &device_desc
);
9604 skip("Adapter %u: Failed to create a D3D device, skipping test.\n", adapter_idx
);
9607 hr
= IDirect3DDevice8_GetDeviceCaps(device
, &caps
);
9608 ok(SUCCEEDED(hr
), "Adapter %u: Failed to get caps, hr %#lx.\n", adapter_idx
, hr
);
9610 ok(caps
.AdapterOrdinal
== adapter_idx
, "Adapter %u: Got unexpected adapter ordinal %u.\n",
9611 adapter_idx
, caps
.AdapterOrdinal
);
9612 ok(!(caps
.Caps
& ~D3DCAPS_READ_SCANLINE
),
9613 "Adapter %u: Caps field has unexpected flags %#lx.\n", adapter_idx
, caps
.Caps
);
9614 ok(!(caps
.Caps2
& ~(D3DCAPS2_CANCALIBRATEGAMMA
| D3DCAPS2_CANRENDERWINDOWED
9615 | D3DCAPS2_CANMANAGERESOURCE
| D3DCAPS2_DYNAMICTEXTURES
| D3DCAPS2_FULLSCREENGAMMA
9616 | D3DCAPS2_NO2DDURING3DSCENE
| D3DCAPS2_RESERVED
)),
9617 "Adapter %u: Caps2 field has unexpected flags %#lx.\n", adapter_idx
, caps
.Caps2
);
9618 /* Nvidia returns that 0x400 flag, which is probably Vista+
9619 * D3DCAPS3_DXVAHD from d3d9caps.h */
9620 /* AMD doesn't filter all the ddraw / d3d9 caps. Consider that behavior
9622 ok(!(caps
.Caps3
& ~(D3DCAPS3_ALPHA_FULLSCREEN_FLIP_OR_DISCARD
| D3DCAPS3_RESERVED
| 0x400))
9623 || broken(!(caps
.Caps3
& ~(D3DCAPS3_ALPHA_FULLSCREEN_FLIP_OR_DISCARD
| 0x80))),
9624 "Adapter %u: Caps3 field has unexpected flags %#lx.\n", adapter_idx
, caps
.Caps3
);
9625 ok(!(caps
.PrimitiveMiscCaps
& ~(D3DPMISCCAPS_MASKZ
| D3DPMISCCAPS_LINEPATTERNREP
9626 | D3DPMISCCAPS_CULLNONE
| D3DPMISCCAPS_CULLCW
| D3DPMISCCAPS_CULLCCW
9627 | D3DPMISCCAPS_COLORWRITEENABLE
| D3DPMISCCAPS_CLIPPLANESCALEDPOINTS
9628 | D3DPMISCCAPS_CLIPTLVERTS
| D3DPMISCCAPS_TSSARGTEMP
| D3DPMISCCAPS_BLENDOP
9629 | D3DPMISCCAPS_NULLREFERENCE
))
9630 || broken(!(caps
.PrimitiveMiscCaps
& ~0x003fdff6)),
9631 "Adapter %u: PrimitiveMiscCaps field has unexpected flags %#lx.\n", adapter_idx
,
9632 caps
.PrimitiveMiscCaps
);
9633 /* AMD includes an unknown 0x2 flag. */
9634 ok(!(caps
.RasterCaps
& ~(D3DPRASTERCAPS_DITHER
| D3DPRASTERCAPS_PAT
| D3DPRASTERCAPS_ZTEST
9635 | D3DPRASTERCAPS_FOGVERTEX
| D3DPRASTERCAPS_FOGTABLE
| D3DPRASTERCAPS_ANTIALIASEDGES
9636 | D3DPRASTERCAPS_MIPMAPLODBIAS
| D3DPRASTERCAPS_ZBIAS
| D3DPRASTERCAPS_ZBUFFERLESSHSR
9637 | D3DPRASTERCAPS_FOGRANGE
| D3DPRASTERCAPS_ANISOTROPY
| D3DPRASTERCAPS_WBUFFER
9638 | D3DPRASTERCAPS_WFOG
| D3DPRASTERCAPS_ZFOG
| D3DPRASTERCAPS_COLORPERSPECTIVE
9639 | D3DPRASTERCAPS_STRETCHBLTMULTISAMPLE
))
9640 || broken(!(caps
.RasterCaps
& ~0x0ff7f19b)),
9641 "Adapter %u: RasterCaps field has unexpected flags %#lx.\n", adapter_idx
,
9643 ok(!(caps
.SrcBlendCaps
& ~(D3DPBLENDCAPS_ZERO
| D3DPBLENDCAPS_ONE
| D3DPBLENDCAPS_SRCCOLOR
9644 | D3DPBLENDCAPS_INVSRCCOLOR
| D3DPBLENDCAPS_SRCALPHA
| D3DPBLENDCAPS_INVSRCALPHA
9645 | D3DPBLENDCAPS_DESTALPHA
| D3DPBLENDCAPS_INVDESTALPHA
| D3DPBLENDCAPS_DESTCOLOR
9646 | D3DPBLENDCAPS_INVDESTCOLOR
| D3DPBLENDCAPS_SRCALPHASAT
| D3DPBLENDCAPS_BOTHSRCALPHA
9647 | D3DPBLENDCAPS_BOTHINVSRCALPHA
)),
9648 "Adapter %u: SrcBlendCaps field has unexpected flags %#lx.\n", adapter_idx
,
9650 ok(!(caps
.DestBlendCaps
& ~(D3DPBLENDCAPS_ZERO
| D3DPBLENDCAPS_ONE
| D3DPBLENDCAPS_SRCCOLOR
9651 | D3DPBLENDCAPS_INVSRCCOLOR
| D3DPBLENDCAPS_SRCALPHA
| D3DPBLENDCAPS_INVSRCALPHA
9652 | D3DPBLENDCAPS_DESTALPHA
| D3DPBLENDCAPS_INVDESTALPHA
| D3DPBLENDCAPS_DESTCOLOR
9653 | D3DPBLENDCAPS_INVDESTCOLOR
| D3DPBLENDCAPS_SRCALPHASAT
| D3DPBLENDCAPS_BOTHSRCALPHA
9654 | D3DPBLENDCAPS_BOTHINVSRCALPHA
)),
9655 "Adapter %u: DestBlendCaps field has unexpected flags %#lx.\n", adapter_idx
,
9656 caps
.DestBlendCaps
);
9657 ok(!(caps
.TextureCaps
& ~(D3DPTEXTURECAPS_PERSPECTIVE
| D3DPTEXTURECAPS_POW2
9658 | D3DPTEXTURECAPS_ALPHA
| D3DPTEXTURECAPS_SQUAREONLY
9659 | D3DPTEXTURECAPS_TEXREPEATNOTSCALEDBYSIZE
| D3DPTEXTURECAPS_ALPHAPALETTE
9660 | D3DPTEXTURECAPS_NONPOW2CONDITIONAL
| D3DPTEXTURECAPS_PROJECTED
9661 | D3DPTEXTURECAPS_CUBEMAP
| D3DPTEXTURECAPS_VOLUMEMAP
| D3DPTEXTURECAPS_MIPMAP
9662 | D3DPTEXTURECAPS_MIPVOLUMEMAP
| D3DPTEXTURECAPS_MIPCUBEMAP
9663 | D3DPTEXTURECAPS_CUBEMAP_POW2
| D3DPTEXTURECAPS_VOLUMEMAP_POW2
)),
9664 "Adapter %u: TextureCaps field has unexpected flags %#lx.\n", adapter_idx
,
9666 ok(!(caps
.TextureFilterCaps
& ~(D3DPTFILTERCAPS_MINFPOINT
| D3DPTFILTERCAPS_MINFLINEAR
9667 | D3DPTFILTERCAPS_MINFANISOTROPIC
| D3DPTFILTERCAPS_MIPFPOINT
9668 | D3DPTFILTERCAPS_MIPFLINEAR
| D3DPTFILTERCAPS_MAGFPOINT
| D3DPTFILTERCAPS_MAGFLINEAR
9669 | D3DPTFILTERCAPS_MAGFANISOTROPIC
| D3DPTFILTERCAPS_MAGFAFLATCUBIC
9670 | D3DPTFILTERCAPS_MAGFGAUSSIANCUBIC
))
9671 || broken(!(caps
.TextureFilterCaps
& ~0x0703073f)),
9672 "Adapter %u: TextureFilterCaps field has unexpected flags %#lx.\n", adapter_idx
,
9673 caps
.TextureFilterCaps
);
9674 ok(!(caps
.CubeTextureFilterCaps
& ~(D3DPTFILTERCAPS_MINFPOINT
| D3DPTFILTERCAPS_MINFLINEAR
9675 | D3DPTFILTERCAPS_MINFANISOTROPIC
| D3DPTFILTERCAPS_MIPFPOINT
9676 | D3DPTFILTERCAPS_MIPFLINEAR
| D3DPTFILTERCAPS_MAGFPOINT
| D3DPTFILTERCAPS_MAGFLINEAR
9677 | D3DPTFILTERCAPS_MAGFANISOTROPIC
| D3DPTFILTERCAPS_MAGFAFLATCUBIC
9678 | D3DPTFILTERCAPS_MAGFGAUSSIANCUBIC
)),
9679 "Adapter %u: CubeTextureFilterCaps field has unexpected flags %#lx.\n", adapter_idx
,
9680 caps
.CubeTextureFilterCaps
);
9681 ok(!(caps
.VolumeTextureFilterCaps
& ~(D3DPTFILTERCAPS_MINFPOINT
| D3DPTFILTERCAPS_MINFLINEAR
9682 | D3DPTFILTERCAPS_MINFANISOTROPIC
| D3DPTFILTERCAPS_MIPFPOINT
9683 | D3DPTFILTERCAPS_MIPFLINEAR
| D3DPTFILTERCAPS_MAGFPOINT
| D3DPTFILTERCAPS_MAGFLINEAR
9684 | D3DPTFILTERCAPS_MAGFANISOTROPIC
| D3DPTFILTERCAPS_MAGFAFLATCUBIC
9685 | D3DPTFILTERCAPS_MAGFGAUSSIANCUBIC
)),
9686 "Adapter %u: VolumeTextureFilterCaps field has unexpected flags %#lx.\n",
9687 adapter_idx
, caps
.VolumeTextureFilterCaps
);
9688 ok(!(caps
.LineCaps
& ~(D3DLINECAPS_TEXTURE
| D3DLINECAPS_ZTEST
| D3DLINECAPS_BLEND
9689 | D3DLINECAPS_ALPHACMP
| D3DLINECAPS_FOG
)),
9690 "Adapter %u: LineCaps field has unexpected flags %#lx.\n", adapter_idx
,
9692 ok(!(caps
.StencilCaps
& ~(D3DSTENCILCAPS_KEEP
| D3DSTENCILCAPS_ZERO
| D3DSTENCILCAPS_REPLACE
9693 | D3DSTENCILCAPS_INCRSAT
| D3DSTENCILCAPS_DECRSAT
| D3DSTENCILCAPS_INVERT
9694 | D3DSTENCILCAPS_INCR
| D3DSTENCILCAPS_DECR
)),
9695 "Adapter %u: StencilCaps field has unexpected flags %#lx.\n", adapter_idx
,
9697 ok(!(caps
.VertexProcessingCaps
& ~(D3DVTXPCAPS_TEXGEN
| D3DVTXPCAPS_MATERIALSOURCE7
9698 | D3DVTXPCAPS_DIRECTIONALLIGHTS
| D3DVTXPCAPS_POSITIONALLIGHTS
| D3DVTXPCAPS_LOCALVIEWER
9699 | D3DVTXPCAPS_TWEENING
| D3DVTXPCAPS_NO_VSDT_UBYTE4
)),
9700 "Adapter %u: VertexProcessingCaps field has unexpected flags %#lx.\n", adapter_idx
,
9701 caps
.VertexProcessingCaps
);
9702 /* Both Nvidia and AMD give 10 here. */
9703 ok(caps
.MaxActiveLights
<= 10,
9704 "Adapter %u: MaxActiveLights field has unexpected value %lu.\n", adapter_idx
,
9705 caps
.MaxActiveLights
);
9706 /* AMD gives 6, Nvidia returns 8. */
9707 ok(caps
.MaxUserClipPlanes
<= 8,
9708 "Adapter %u: MaxUserClipPlanes field has unexpected value %lu.\n", adapter_idx
,
9709 caps
.MaxUserClipPlanes
);
9710 ok(caps
.MaxVertexW
== 0.0f
|| caps
.MaxVertexW
>= 1e10f
,
9711 "Adapter %u: MaxVertexW field has unexpected value %.8e.\n", adapter_idx
,
9714 refcount
= IDirect3DDevice8_Release(device
);
9715 ok(!refcount
, "Adapter %u: Device has %lu references left.\n", adapter_idx
, refcount
);
9717 IDirect3D8_Release(d3d
);
9718 DestroyWindow(window
);
9721 static void test_get_info(void)
9723 IDirect3DDevice8
*device
;
9731 window
= create_window();
9732 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
9733 ok(!!d3d
, "Failed to create a D3D object.\n");
9734 if (!(device
= create_device(d3d
, window
, NULL
)))
9736 skip("Failed to create a D3D device.\n");
9737 IDirect3D8_Release(d3d
);
9738 DestroyWindow(window
);
9742 /* As called by Chessmaster 9000 (bug 42118). */
9743 hr
= IDirect3DDevice8_GetInfo(device
, 4, info
, 16);
9744 ok(hr
== S_FALSE
, "Unexpected hr %#lx.\n", hr
);
9746 for (i
= 0; i
< 256; ++i
)
9748 hr
= IDirect3DDevice8_GetInfo(device
, i
, info
, sizeof(info
));
9750 ok(hr
== (i
< 4 ? E_FAIL
: S_FALSE
), "info_id %u, unexpected hr %#lx.\n", i
, hr
);
9752 ok(hr
== E_FAIL
|| hr
== S_FALSE
, "info_id %u, unexpected hr %#lx.\n", i
, hr
);
9755 refcount
= IDirect3DDevice8_Release(device
);
9756 ok(!refcount
, "Device has %lu references left.\n", refcount
);
9757 IDirect3D8_Release(d3d
);
9758 DestroyWindow(window
);
9761 static void test_resource_access(void)
9763 IDirect3DSurface8
*backbuffer
, *depth_stencil
;
9764 D3DFORMAT colour_format
, depth_format
, format
;
9765 BOOL depth_2d
, depth_cube
, depth_plain
;
9766 D3DADAPTER_IDENTIFIER8 identifier
;
9767 struct device_desc device_desc
;
9768 D3DSURFACE_DESC surface_desc
;
9769 BOOL skip_ati2n_once
= FALSE
;
9770 IDirect3DDevice8
*device
;
9787 enum resource_format
9797 enum resource_format format
;
9804 {D3DPOOL_DEFAULT
, FORMAT_COLOUR
, 0, TRUE
},
9805 {D3DPOOL_DEFAULT
, FORMAT_ATI2
, 0, TRUE
},
9806 {D3DPOOL_DEFAULT
, FORMAT_DEPTH
, 0, TRUE
},
9807 {D3DPOOL_DEFAULT
, FORMAT_COLOUR
, D3DUSAGE_RENDERTARGET
, TRUE
},
9808 {D3DPOOL_DEFAULT
, FORMAT_DEPTH
, D3DUSAGE_RENDERTARGET
, FALSE
},
9809 {D3DPOOL_DEFAULT
, FORMAT_COLOUR
, D3DUSAGE_DEPTHSTENCIL
, FALSE
},
9810 {D3DPOOL_DEFAULT
, FORMAT_DEPTH
, D3DUSAGE_DEPTHSTENCIL
, TRUE
},
9812 {D3DPOOL_DEFAULT
, FORMAT_COLOUR
, D3DUSAGE_DYNAMIC
, TRUE
},
9813 {D3DPOOL_DEFAULT
, FORMAT_ATI2
, D3DUSAGE_DYNAMIC
, TRUE
},
9814 {D3DPOOL_DEFAULT
, FORMAT_DEPTH
, D3DUSAGE_DYNAMIC
, TRUE
},
9815 {D3DPOOL_DEFAULT
, FORMAT_COLOUR
, D3DUSAGE_DYNAMIC
| D3DUSAGE_RENDERTARGET
, FALSE
},
9816 {D3DPOOL_DEFAULT
, FORMAT_DEPTH
, D3DUSAGE_DYNAMIC
| D3DUSAGE_RENDERTARGET
, FALSE
},
9817 {D3DPOOL_DEFAULT
, FORMAT_COLOUR
, D3DUSAGE_DYNAMIC
| D3DUSAGE_DEPTHSTENCIL
, FALSE
},
9818 {D3DPOOL_DEFAULT
, FORMAT_DEPTH
, D3DUSAGE_DYNAMIC
| D3DUSAGE_DEPTHSTENCIL
, FALSE
},
9820 {D3DPOOL_MANAGED
, FORMAT_COLOUR
, 0, TRUE
},
9821 {D3DPOOL_MANAGED
, FORMAT_ATI2
, 0, TRUE
},
9822 {D3DPOOL_MANAGED
, FORMAT_DEPTH
, 0, FALSE
},
9823 {D3DPOOL_MANAGED
, FORMAT_COLOUR
, D3DUSAGE_RENDERTARGET
, FALSE
},
9824 {D3DPOOL_MANAGED
, FORMAT_DEPTH
, D3DUSAGE_RENDERTARGET
, FALSE
},
9825 {D3DPOOL_MANAGED
, FORMAT_COLOUR
, D3DUSAGE_DEPTHSTENCIL
, FALSE
},
9826 {D3DPOOL_MANAGED
, FORMAT_DEPTH
, D3DUSAGE_DEPTHSTENCIL
, FALSE
},
9828 {D3DPOOL_SYSTEMMEM
, FORMAT_COLOUR
, 0, TRUE
},
9829 {D3DPOOL_SYSTEMMEM
, FORMAT_ATI2
, 0, TRUE
},
9830 {D3DPOOL_SYSTEMMEM
, FORMAT_DEPTH
, 0, FALSE
},
9831 {D3DPOOL_SYSTEMMEM
, FORMAT_COLOUR
, D3DUSAGE_RENDERTARGET
, FALSE
},
9832 {D3DPOOL_SYSTEMMEM
, FORMAT_DEPTH
, D3DUSAGE_RENDERTARGET
, FALSE
},
9833 {D3DPOOL_SYSTEMMEM
, FORMAT_COLOUR
, D3DUSAGE_DEPTHSTENCIL
, FALSE
},
9834 {D3DPOOL_SYSTEMMEM
, FORMAT_DEPTH
, D3DUSAGE_DEPTHSTENCIL
, FALSE
},
9836 {D3DPOOL_SCRATCH
, FORMAT_COLOUR
, 0, TRUE
},
9837 {D3DPOOL_SCRATCH
, FORMAT_ATI2
, 0, TRUE
},
9838 {D3DPOOL_SCRATCH
, FORMAT_DEPTH
, 0, FALSE
},
9839 {D3DPOOL_SCRATCH
, FORMAT_COLOUR
, D3DUSAGE_RENDERTARGET
, FALSE
},
9840 {D3DPOOL_SCRATCH
, FORMAT_DEPTH
, D3DUSAGE_RENDERTARGET
, FALSE
},
9841 {D3DPOOL_SCRATCH
, FORMAT_COLOUR
, D3DUSAGE_DEPTHSTENCIL
, FALSE
},
9842 {D3DPOOL_SCRATCH
, FORMAT_DEPTH
, D3DUSAGE_DEPTHSTENCIL
, FALSE
},
9847 enum surface_type type
;
9852 {"CUBE", SURFACE_CUBE
},
9855 {"IMAGE", SURFACE_IMAGE
},
9858 window
= create_window();
9859 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
9860 ok(!!d3d
, "Failed to create a D3D object.\n");
9861 hr
= IDirect3D8_GetAdapterIdentifier(d3d
, D3DADAPTER_DEFAULT
, 0, &identifier
);
9862 ok(SUCCEEDED(hr
), "Failed to get adapter identifier, hr %#lx.\n", hr
);
9863 warp
= adapter_is_warp(&identifier
);
9865 device_desc
.adapter_ordinal
= D3DADAPTER_DEFAULT
;
9866 device_desc
.device_window
= window
;
9867 device_desc
.width
= 16;
9868 device_desc
.height
= 16;
9869 device_desc
.flags
= 0;
9870 if (!(device
= create_device(d3d
, window
, &device_desc
)))
9872 skip("Failed to create a D3D device.\n");
9873 IDirect3D8_Release(d3d
);
9874 DestroyWindow(window
);
9878 hr
= IDirect3DDevice8_GetBackBuffer(device
, 0, D3DBACKBUFFER_TYPE_MONO
, &backbuffer
);
9879 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
9880 hr
= IDirect3DSurface8_GetDesc(backbuffer
, &surface_desc
);
9881 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
9882 colour_format
= surface_desc
.Format
;
9884 hr
= IDirect3DDevice8_GetDepthStencilSurface(device
, &depth_stencil
);
9885 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
9886 hr
= IDirect3DSurface8_GetDesc(depth_stencil
, &surface_desc
);
9887 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
9888 depth_format
= surface_desc
.Format
;
9890 depth_2d
= SUCCEEDED(IDirect3D8_CheckDeviceFormat(d3d
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
,
9891 D3DFMT_X8R8G8B8
, 0, D3DRTYPE_TEXTURE
, depth_format
));
9892 depth_cube
= SUCCEEDED(IDirect3D8_CheckDeviceFormat(d3d
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
,
9893 D3DFMT_X8R8G8B8
, 0, D3DRTYPE_CUBETEXTURE
, depth_format
));
9894 depth_plain
= SUCCEEDED(IDirect3D8_CheckDeviceFormat(d3d
, D3DADAPTER_DEFAULT
, D3DDEVTYPE_HAL
,
9895 D3DFMT_X8R8G8B8
, 0, D3DRTYPE_SURFACE
, depth_format
));
9897 hr
= IDirect3DDevice8_SetVertexShader(device
, D3DFVF_XYZRHW
);
9898 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
9900 for (i
= 0; i
< ARRAY_SIZE(surface_types
); ++i
)
9902 for (j
= 0; j
< ARRAY_SIZE(tests
); ++j
)
9904 IDirect3DCubeTexture8
*texture_cube
;
9905 IDirect3DBaseTexture8
*texture
;
9906 IDirect3DTexture8
*texture_2d
;
9907 IDirect3DSurface8
*surface
;
9908 HRESULT expected_hr
;
9911 if (tests
[j
].format
== FORMAT_ATI2
)
9912 format
= MAKEFOURCC('A','T','I','2');
9913 else if (tests
[j
].format
== FORMAT_DEPTH
)
9914 format
= depth_format
;
9916 format
= colour_format
;
9918 if (tests
[j
].format
== FORMAT_ATI2
&& FAILED(IDirect3D8_CheckDeviceFormat(d3d
, D3DADAPTER_DEFAULT
,
9919 D3DDEVTYPE_HAL
, D3DFMT_X8R8G8B8
, 0, D3DRTYPE_TEXTURE
, format
)))
9921 if (!skip_ati2n_once
)
9923 skip("ATI2N texture not supported.\n");
9924 skip_ati2n_once
= TRUE
;
9929 switch (surface_types
[i
].type
)
9932 hr
= IDirect3DDevice8_CreateTexture(device
, 16, 16, 1,
9933 tests
[j
].usage
, format
, tests
[j
].pool
, &texture_2d
);
9934 todo_wine_if(!tests
[j
].valid
&& tests
[j
].format
== FORMAT_DEPTH
&& !tests
[j
].usage
)
9935 ok(hr
== (tests
[j
].valid
&& (tests
[j
].format
!= FORMAT_DEPTH
|| depth_2d
)
9936 ? D3D_OK
: D3DERR_INVALIDCALL
),
9937 "Test %s %u: Got unexpected hr %#lx.\n", surface_types
[i
].name
, j
, hr
);
9941 hr
= IDirect3DTexture8_GetSurfaceLevel(texture_2d
, 0, &surface
);
9942 ok(hr
== D3D_OK
, "Test %s %u: Got unexpected hr %#lx.\n", surface_types
[i
].name
, j
, hr
);
9943 IDirect3DTexture8_Release(texture_2d
);
9947 hr
= IDirect3DDevice8_CreateCubeTexture(device
, 16, 1,
9948 tests
[j
].usage
, format
, tests
[j
].pool
, &texture_cube
);
9949 todo_wine_if(!tests
[j
].valid
&& tests
[j
].format
== FORMAT_DEPTH
&& !tests
[j
].usage
)
9950 ok(hr
== (tests
[j
].valid
&& (tests
[j
].format
!= FORMAT_DEPTH
|| depth_cube
)
9951 ? D3D_OK
: D3DERR_INVALIDCALL
),
9952 "Test %s %u: Got unexpected hr %#lx.\n", surface_types
[i
].name
, j
, hr
);
9956 hr
= IDirect3DCubeTexture8_GetCubeMapSurface(texture_cube
,
9957 D3DCUBEMAP_FACE_POSITIVE_X
, 0, &surface
);
9958 ok(hr
== D3D_OK
, "Test %s %u: Got unexpected hr %#lx.\n", surface_types
[i
].name
, j
, hr
);
9959 IDirect3DCubeTexture8_Release(texture_cube
);
9963 hr
= IDirect3DDevice8_CreateRenderTarget(device
, 16, 16, format
,
9964 D3DMULTISAMPLE_NONE
, tests
[j
].usage
& D3DUSAGE_DYNAMIC
, &surface
);
9965 ok(hr
== (tests
[j
].format
== FORMAT_COLOUR
? D3D_OK
: D3DERR_INVALIDCALL
),
9966 "Test %s %u: Got unexpected hr %#lx.\n", surface_types
[i
].name
, j
, hr
);
9972 hr
= IDirect3DDevice8_CreateDepthStencilSurface(device
,
9973 16, 16, format
, D3DMULTISAMPLE_NONE
, &surface
);
9974 todo_wine_if(tests
[j
].format
== FORMAT_ATI2
)
9975 ok(hr
== (tests
[j
].format
== FORMAT_DEPTH
? D3D_OK
9976 : tests
[j
].format
== FORMAT_COLOUR
? D3DERR_INVALIDCALL
: E_INVALIDARG
)
9977 || (tests
[j
].format
== FORMAT_ATI2
&& hr
== D3D_OK
),
9978 "Test %s %u: Got unexpected hr %#lx.\n", surface_types
[i
].name
, j
, hr
);
9984 hr
= IDirect3DDevice8_CreateImageSurface(device
, 16, 16, format
, &surface
);
9985 ok(hr
== ((tests
[j
].format
!= FORMAT_DEPTH
|| depth_plain
) ? D3D_OK
: D3DERR_INVALIDCALL
),
9986 "Test %s %u: Got unexpected hr %#lx.\n", surface_types
[i
].name
, j
, hr
);
9992 ok(0, "Invalid surface type %#x.\n", surface_types
[i
].type
);
9996 hr
= IDirect3DSurface8_GetDesc(surface
, &surface_desc
);
9997 ok(hr
== D3D_OK
, "Test %s %u: Got unexpected hr %#lx.\n", surface_types
[i
].name
, j
, hr
);
9998 if (surface_types
[i
].type
== SURFACE_RT
)
10000 ok(surface_desc
.Usage
== D3DUSAGE_RENDERTARGET
, "Test %s %u: Got unexpected usage %#lx.\n",
10001 surface_types
[i
].name
, j
, surface_desc
.Usage
);
10002 ok(surface_desc
.Pool
== D3DPOOL_DEFAULT
, "Test %s %u: Got unexpected pool %#x.\n",
10003 surface_types
[i
].name
, j
, surface_desc
.Pool
);
10005 else if (surface_types
[i
].type
== SURFACE_DS
)
10007 ok(surface_desc
.Usage
== D3DUSAGE_DEPTHSTENCIL
, "Test %s %u: Got unexpected usage %#lx.\n",
10008 surface_types
[i
].name
, j
, surface_desc
.Usage
);
10009 ok(surface_desc
.Pool
== D3DPOOL_DEFAULT
, "Test %s %u: Got unexpected pool %#x.\n",
10010 surface_types
[i
].name
, j
, surface_desc
.Pool
);
10012 else if (surface_types
[i
].type
== SURFACE_IMAGE
)
10014 ok(!surface_desc
.Usage
, "Test %s %u: Got unexpected usage %#lx.\n",
10015 surface_types
[i
].name
, j
, surface_desc
.Usage
);
10016 ok(surface_desc
.Pool
== D3DPOOL_SYSTEMMEM
, "Test %s %u: Got unexpected pool %#x.\n",
10017 surface_types
[i
].name
, j
, surface_desc
.Pool
);
10021 ok(surface_desc
.Usage
== tests
[j
].usage
, "Test %s %u: Got unexpected usage %#lx.\n",
10022 surface_types
[i
].name
, j
, surface_desc
.Usage
);
10023 ok(surface_desc
.Pool
== tests
[j
].pool
, "Test %s %u: Got unexpected pool %#x.\n",
10024 surface_types
[i
].name
, j
, surface_desc
.Pool
);
10027 hr
= IDirect3DSurface8_LockRect(surface
, &lr
, NULL
, 0);
10028 if (surface_desc
.Pool
!= D3DPOOL_DEFAULT
|| surface_desc
.Usage
& D3DUSAGE_DYNAMIC
10029 || (surface_types
[i
].type
== SURFACE_RT
&& tests
[j
].usage
& D3DUSAGE_DYNAMIC
)
10030 || surface_types
[i
].type
== SURFACE_IMAGE
10031 || tests
[j
].format
== FORMAT_ATI2
)
10032 expected_hr
= D3D_OK
;
10034 expected_hr
= D3DERR_INVALIDCALL
;
10035 ok(hr
== expected_hr
, "Test %s %u: Got unexpected hr %#lx.\n", surface_types
[i
].name
, j
, hr
);
10036 hr
= IDirect3DSurface8_UnlockRect(surface
);
10037 todo_wine_if(expected_hr
!= D3D_OK
&& surface_types
[i
].type
== SURFACE_2D
)
10038 ok(hr
== expected_hr
, "Test %s %u: Got unexpected hr %#lx.\n", surface_types
[i
].name
, j
, hr
);
10040 if (SUCCEEDED(IDirect3DSurface8_GetContainer(surface
, &IID_IDirect3DBaseTexture8
, (void **)&texture
)))
10042 hr
= IDirect3DDevice8_SetTexture(device
, 0, texture
);
10043 ok(hr
== D3D_OK
, "Test %s %u: Got unexpected hr %#lx.\n", surface_types
[i
].name
, j
, hr
);
10044 hr
= IDirect3DDevice8_SetTexture(device
, 0, NULL
);
10045 ok(hr
== D3D_OK
, "Test %s %u: Got unexpected hr %#lx.\n", surface_types
[i
].name
, j
, hr
);
10046 IDirect3DBaseTexture8_Release(texture
);
10049 hr
= IDirect3DDevice8_SetRenderTarget(device
, surface
, depth_stencil
);
10050 ok(hr
== (surface_desc
.Usage
& D3DUSAGE_RENDERTARGET
? D3D_OK
: D3DERR_INVALIDCALL
),
10051 "Test %s %u: Got unexpected hr %#lx.\n", surface_types
[i
].name
, j
, hr
);
10052 hr
= IDirect3DDevice8_SetRenderTarget(device
, backbuffer
, depth_stencil
);
10053 ok(hr
== D3D_OK
, "Test %s %u: Got unexpected hr %#lx.\n", surface_types
[i
].name
, j
, hr
);
10055 hr
= IDirect3DDevice8_SetRenderTarget(device
, backbuffer
, surface
);
10056 ok(hr
== (surface_desc
.Usage
& D3DUSAGE_DEPTHSTENCIL
? D3D_OK
: D3DERR_INVALIDCALL
),
10057 "Test %s %u: Got unexpected hr %#lx.\n", surface_types
[i
].name
, j
, hr
);
10058 hr
= IDirect3DDevice8_SetRenderTarget(device
, backbuffer
, depth_stencil
);
10059 ok(hr
== D3D_OK
, "Test %s %u: Got unexpected hr %#lx.\n", surface_types
[i
].name
, j
, hr
);
10061 IDirect3DSurface8_Release(surface
);
10065 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
10067 IDirect3DVolumeTexture8
*texture
;
10068 D3DVOLUME_DESC volume_desc
;
10069 IDirect3DVolume8
*volume
;
10070 HRESULT expected_hr
;
10073 if (tests
[i
].format
== FORMAT_DEPTH
)
10076 if (tests
[i
].format
== FORMAT_ATI2
)
10077 format
= MAKEFOURCC('A','T','I','2');
10079 format
= colour_format
;
10081 if (tests
[i
].format
== FORMAT_ATI2
&& FAILED(IDirect3D8_CheckDeviceFormat(d3d
, D3DADAPTER_DEFAULT
,
10082 D3DDEVTYPE_HAL
, D3DFMT_X8R8G8B8
, 0, D3DRTYPE_VOLUMETEXTURE
, format
)))
10084 if (!skip_ati2n_once
)
10086 skip("ATI2N texture not supported.\n");
10087 skip_ati2n_once
= TRUE
;
10092 hr
= IDirect3DDevice8_CreateVolumeTexture(device
, 16, 16, 1, 1,
10093 tests
[i
].usage
, format
, tests
[i
].pool
, &texture
);
10094 ok((hr
== ((!(tests
[i
].usage
& ~D3DUSAGE_DYNAMIC
) && tests
[i
].format
!= FORMAT_ATI2
)
10095 || (tests
[i
].pool
== D3DPOOL_SCRATCH
&& !tests
[i
].usage
)
10096 ? D3D_OK
: D3DERR_INVALIDCALL
))
10097 || (tests
[i
].format
== FORMAT_ATI2
&& (hr
== D3D_OK
|| warp
)),
10098 "Test %u: Got unexpected hr %#lx.\n", i
, hr
);
10102 hr
= IDirect3DVolumeTexture8_GetVolumeLevel(texture
, 0, &volume
);
10103 ok(hr
== D3D_OK
, "Test %u: Got unexpected hr %#lx.\n", i
, hr
);
10105 hr
= IDirect3DVolume8_GetDesc(volume
, &volume_desc
);
10106 ok(hr
== D3D_OK
, "Test %u: Got unexpected hr %#lx.\n", i
, hr
);
10107 ok(volume_desc
.Usage
== tests
[i
].usage
, "Test %u: Got unexpected usage %#lx.\n", i
, volume_desc
.Usage
);
10108 ok(volume_desc
.Pool
== tests
[i
].pool
, "Test %u: Got unexpected pool %#x.\n", i
, volume_desc
.Pool
);
10110 hr
= IDirect3DVolume8_LockBox(volume
, &lb
, NULL
, 0);
10111 if (volume_desc
.Pool
!= D3DPOOL_DEFAULT
|| volume_desc
.Usage
& D3DUSAGE_DYNAMIC
)
10112 expected_hr
= D3D_OK
;
10114 expected_hr
= D3DERR_INVALIDCALL
;
10115 ok(hr
== expected_hr
|| (volume_desc
.Pool
== D3DPOOL_DEFAULT
&& hr
== D3D_OK
),
10116 "Test %u: Got unexpected hr %#lx.\n", i
, hr
);
10117 hr
= IDirect3DVolume8_UnlockBox(volume
);
10118 ok(hr
== expected_hr
|| (volume_desc
.Pool
== D3DPOOL_DEFAULT
&& hr
== D3D_OK
),
10119 "Test %u: Got unexpected hr %#lx.\n", i
, hr
);
10121 hr
= IDirect3DDevice8_SetTexture(device
, 0, (IDirect3DBaseTexture8
*)texture
);
10122 ok(hr
== D3D_OK
, "Test %u: Got unexpected hr %#lx.\n", i
, hr
);
10123 hr
= IDirect3DDevice8_SetTexture(device
, 0, NULL
);
10124 ok(hr
== D3D_OK
, "Test %u: Got unexpected hr %#lx.\n", i
, hr
);
10126 IDirect3DVolume8_Release(volume
);
10127 IDirect3DVolumeTexture8_Release(texture
);
10130 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
10132 D3DINDEXBUFFER_DESC ib_desc
;
10133 IDirect3DIndexBuffer8
*ib
;
10136 hr
= IDirect3DDevice8_CreateIndexBuffer(device
, 16, tests
[i
].usage
,
10137 tests
[i
].format
== FORMAT_COLOUR
? D3DFMT_INDEX32
: D3DFMT_INDEX16
, tests
[i
].pool
, &ib
);
10138 ok(hr
== (tests
[i
].pool
== D3DPOOL_SCRATCH
|| (tests
[i
].usage
& ~D3DUSAGE_DYNAMIC
)
10139 ? D3DERR_INVALIDCALL
: D3D_OK
), "Test %u: Got unexpected hr %#lx.\n", i
, hr
);
10143 hr
= IDirect3DIndexBuffer8_GetDesc(ib
, &ib_desc
);
10144 ok(hr
== D3D_OK
, "Test %u: Got unexpected hr %#lx.\n", i
, hr
);
10145 ok(ib_desc
.Usage
== tests
[i
].usage
, "Test %u: Got unexpected usage %#lx.\n", i
, ib_desc
.Usage
);
10146 ok(ib_desc
.Pool
== tests
[i
].pool
, "Test %u: Got unexpected pool %#x.\n", i
, ib_desc
.Pool
);
10148 hr
= IDirect3DIndexBuffer8_Lock(ib
, 0, 0, &data
, 0);
10149 ok(hr
== D3D_OK
, "Test %u: Got unexpected hr %#lx.\n", i
, hr
);
10150 hr
= IDirect3DIndexBuffer8_Unlock(ib
);
10151 ok(hr
== D3D_OK
, "Test %u: Got unexpected hr %#lx.\n", i
, hr
);
10153 hr
= IDirect3DDevice8_SetIndices(device
, ib
, 0);
10154 ok(hr
== D3D_OK
, "Test %u: Got unexpected hr %#lx.\n", i
, hr
);
10155 hr
= IDirect3DDevice8_SetIndices(device
, NULL
, 0);
10156 ok(hr
== D3D_OK
, "Test %u: Got unexpected hr %#lx.\n", i
, hr
);
10158 IDirect3DIndexBuffer8_Release(ib
);
10161 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
10163 D3DVERTEXBUFFER_DESC vb_desc
;
10164 IDirect3DVertexBuffer8
*vb
;
10167 hr
= IDirect3DDevice8_CreateVertexBuffer(device
, 16, tests
[i
].usage
,
10168 tests
[i
].format
== FORMAT_COLOUR
? 0 : D3DFVF_XYZRHW
, tests
[i
].pool
, &vb
);
10169 ok(hr
== (tests
[i
].pool
== D3DPOOL_SCRATCH
|| (tests
[i
].usage
& ~D3DUSAGE_DYNAMIC
)
10170 ? D3DERR_INVALIDCALL
: D3D_OK
), "Test %u: Got unexpected hr %#lx.\n", i
, hr
);
10174 hr
= IDirect3DVertexBuffer8_GetDesc(vb
, &vb_desc
);
10175 ok(hr
== D3D_OK
, "Test %u: Got unexpected hr %#lx.\n", i
, hr
);
10176 ok(vb_desc
.Usage
== tests
[i
].usage
, "Test %u: Got unexpected usage %#lx.\n", i
, vb_desc
.Usage
);
10177 ok(vb_desc
.Pool
== tests
[i
].pool
, "Test %u: Got unexpected pool %#x.\n", i
, vb_desc
.Pool
);
10179 hr
= IDirect3DVertexBuffer8_Lock(vb
, 0, 0, &data
, 0);
10180 ok(hr
== D3D_OK
, "Test %u: Got unexpected hr %#lx.\n", i
, hr
);
10181 hr
= IDirect3DVertexBuffer8_Unlock(vb
);
10182 ok(hr
== D3D_OK
, "Test %u: Got unexpected hr %#lx.\n", i
, hr
);
10184 hr
= IDirect3DDevice8_SetStreamSource(device
, 0, vb
, 16);
10185 ok(hr
== D3D_OK
, "Test %u: Got unexpected hr %#lx.\n", i
, hr
);
10186 hr
= IDirect3DDevice8_SetStreamSource(device
, 0, NULL
, 0);
10187 ok(hr
== D3D_OK
, "Test %u: Got unexpected hr %#lx.\n", i
, hr
);
10189 IDirect3DVertexBuffer8_Release(vb
);
10192 IDirect3DSurface8_Release(depth_stencil
);
10193 IDirect3DSurface8_Release(backbuffer
);
10194 refcount
= IDirect3DDevice8_Release(device
);
10195 ok(!refcount
, "Device has %lu references left.\n", refcount
);
10196 IDirect3D8_Release(d3d
);
10197 DestroyWindow(window
);
10200 static void test_multiply_transform(void)
10202 IDirect3DDevice8
*device
;
10211 static const D3DTRANSFORMSTATETYPE tests
[] =
10223 D3DTS_WORLDMATRIX(0),
10224 D3DTS_WORLDMATRIX(1),
10225 D3DTS_WORLDMATRIX(2),
10226 D3DTS_WORLDMATRIX(3),
10227 D3DTS_WORLDMATRIX(255),
10230 static const D3DMATRIX mat1
=
10232 1.0f
, 0.0f
, 0.0f
, 0.0f
,
10233 0.0f
, 1.0f
, 0.0f
, 0.0f
,
10234 0.0f
, 0.0f
, 1.0f
, 0.0f
,
10235 0.0f
, 0.0f
, 0.0f
, 1.0f
,
10239 2.0f
, 0.0f
, 0.0f
, 0.0f
,
10240 0.0f
, 2.0f
, 0.0f
, 0.0f
,
10241 0.0f
, 0.0f
, 2.0f
, 0.0f
,
10242 0.0f
, 0.0f
, 0.0f
, 2.0f
,
10245 window
= create_window();
10246 ok(!!window
, "Failed to create a window.\n");
10247 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
10248 ok(!!d3d
, "Failed to create D3D object.\n");
10250 if (!(device
= create_device(d3d
, window
, NULL
)))
10252 skip("Failed to create 3D device.\n");
10253 IDirect3D8_Release(d3d
);
10254 DestroyWindow(window
);
10258 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)
10260 hr
= IDirect3DDevice8_GetTransform(device
, tests
[i
], &ret_mat
);
10261 ok(hr
== D3D_OK
, "Test %u: Got unexpected hr %#lx.\n", i
, hr
);
10262 ok(!memcmp(&ret_mat
, &mat1
, sizeof(mat1
)), "Test %u: Got unexpected transform matrix.\n", i
);
10264 hr
= IDirect3DDevice8_MultiplyTransform(device
, tests
[i
], &mat2
);
10265 ok(hr
== D3D_OK
, "Test %u: Got unexpected hr %#lx.\n", i
, hr
);
10267 hr
= IDirect3DDevice8_GetTransform(device
, tests
[i
], &ret_mat
);
10268 ok(hr
== D3D_OK
, "Test %u: Got unexpected hr %#lx.\n", i
, hr
);
10269 ok(!memcmp(&ret_mat
, &mat2
, sizeof(mat2
)), "Test %u: Got unexpected transform matrix.\n", i
);
10271 /* MultiplyTransform() goes directly into the primary stateblock. */
10273 hr
= IDirect3DDevice8_SetTransform(device
, tests
[i
], &mat1
);
10274 ok(hr
== D3D_OK
, "Test %u: Got unexpected hr %#lx.\n", i
, hr
);
10276 hr
= IDirect3DDevice8_BeginStateBlock(device
);
10277 ok(hr
== D3D_OK
, "Test %u: Got unexpected hr %#lx.\n", i
, hr
);
10279 hr
= IDirect3DDevice8_MultiplyTransform(device
, tests
[i
], &mat2
);
10280 ok(hr
== D3D_OK
, "Test %u: Got unexpected hr %#lx.\n", i
, hr
);
10282 hr
= IDirect3DDevice8_EndStateBlock(device
, &stateblock
);
10283 ok(hr
== D3D_OK
, "Test %u: Got unexpected hr %#lx.\n", i
, hr
);
10285 hr
= IDirect3DDevice8_GetTransform(device
, tests
[i
], &ret_mat
);
10286 ok(hr
== D3D_OK
, "Test %u: Got unexpected hr %#lx.\n", i
, hr
);
10287 ok(!memcmp(&ret_mat
, &mat2
, sizeof(mat2
)), "Test %u: Got unexpected transform matrix.\n", i
);
10289 hr
= IDirect3DDevice8_CaptureStateBlock(device
, stateblock
);
10290 ok(hr
== D3D_OK
, "Test %u: Got unexpected hr %#lx.\n", i
, hr
);
10292 hr
= IDirect3DDevice8_SetTransform(device
, tests
[i
], &mat1
);
10293 ok(hr
== D3D_OK
, "Test %u: Got unexpected hr %#lx.\n", i
, hr
);
10295 hr
= IDirect3DDevice8_ApplyStateBlock(device
, stateblock
);
10296 ok(hr
== D3D_OK
, "Test %u: Got unexpected hr %#lx.\n", i
, hr
);
10298 hr
= IDirect3DDevice8_GetTransform(device
, tests
[i
], &ret_mat
);
10299 ok(hr
== D3D_OK
, "Test %u: Got unexpected hr %#lx.\n", i
, hr
);
10300 ok(!memcmp(&ret_mat
, &mat1
, sizeof(mat1
)), "Test %u: Got unexpected transform matrix.\n", i
);
10302 IDirect3DDevice8_DeleteStateBlock(device
, stateblock
);
10305 refcount
= IDirect3DDevice8_Release(device
);
10306 ok(!refcount
, "Device has %lu references left.\n", refcount
);
10307 IDirect3D8_Release(d3d
);
10308 DestroyWindow(window
);
10311 static void test_draw_primitive(void)
10313 static const struct
10320 {{-1.0f
, -1.0f
, 0.0f
}, 0xffff0000},
10321 {{-1.0f
, 1.0f
, 0.0f
}, 0xffff0000},
10322 {{ 1.0f
, 1.0f
, 0.0f
}, 0xffff0000},
10323 {{ 1.0f
, -1.0f
, 0.0f
}, 0xffff0000},
10324 {{-1.0f
, -1.0f
, 0.0f
}, 0xffff0000},
10326 static const WORD indices
[] = {0, 1, 2, 3, 0, 2};
10328 IDirect3DVertexBuffer8
*vertex_buffer
, *current_vb
;
10329 IDirect3DIndexBuffer8
*index_buffer
, *current_ib
;
10330 UINT stride
, base_vertex_index
;
10331 IDirect3DDevice8
*device
;
10339 window
= create_window();
10340 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
10341 ok(!!d3d
, "Failed to create a D3D object.\n");
10342 if (!(device
= create_device(d3d
, window
, NULL
)))
10344 skip("Failed to create a D3D device.\n");
10345 IDirect3D8_Release(d3d
);
10346 DestroyWindow(window
);
10350 hr
= IDirect3DDevice8_CreateVertexBuffer(device
, sizeof(quad
), 0, 0,
10351 D3DPOOL_DEFAULT
, &vertex_buffer
);
10352 ok(SUCCEEDED(hr
), "CreateVertexBuffer failed, hr %#lx.\n", hr
);
10353 hr
= IDirect3DVertexBuffer8_Lock(vertex_buffer
, 0, 0, &ptr
, D3DLOCK_DISCARD
);
10354 ok(SUCCEEDED(hr
), "Lock failed, hr %#lx.\n", hr
);
10355 memcpy(ptr
, quad
, sizeof(quad
));
10356 hr
= IDirect3DVertexBuffer8_Unlock(vertex_buffer
);
10357 ok(SUCCEEDED(hr
), "Unlock failed, hr %#lx.\n", hr
);
10358 hr
= IDirect3DDevice8_SetStreamSource(device
, 0, vertex_buffer
, sizeof(*quad
));
10359 ok(SUCCEEDED(hr
), "SetStreamSource failed, hr %#lx.\n", hr
);
10360 hr
= IDirect3DDevice8_SetVertexShader(device
, D3DFVF_XYZ
| D3DFVF_DIFFUSE
);
10361 ok(SUCCEEDED(hr
), "Got unexpected hr %#lx.\n", hr
);
10363 hr
= IDirect3DDevice8_CreateIndexBuffer(device
, sizeof(indices
), 0, D3DFMT_INDEX16
,
10364 D3DPOOL_DEFAULT
, &index_buffer
);
10365 ok(SUCCEEDED(hr
), "CreateIndexBuffer failed, hr %#lx.\n", hr
);
10366 hr
= IDirect3DIndexBuffer8_Lock(index_buffer
, 0, 0, &ptr
, D3DLOCK_DISCARD
);
10367 ok(SUCCEEDED(hr
), "Lock failed, hr %#lx.\n", hr
);
10368 memcpy(ptr
, indices
, sizeof(indices
));
10369 hr
= IDirect3DIndexBuffer8_Unlock(index_buffer
);
10370 ok(SUCCEEDED(hr
), "Unlock failed, hr %#lx.\n", hr
);
10372 hr
= IDirect3DDevice8_SetRenderState(device
, D3DRS_LIGHTING
, FALSE
);
10373 ok(SUCCEEDED(hr
), "SetRenderState D3DRS_LIGHTING failed, hr %#lx.\n", hr
);
10375 hr
= IDirect3DDevice8_BeginScene(device
);
10376 ok(SUCCEEDED(hr
), "BeginScene failed, hr %#lx.\n", hr
);
10378 hr
= IDirect3DDevice8_DrawPrimitive(device
, D3DPT_TRIANGLELIST
, 0, 2);
10379 ok(SUCCEEDED(hr
), "DrawPrimitive failed, hr %#lx.\n", hr
);
10381 hr
= IDirect3DDevice8_GetStreamSource(device
, 0, ¤t_vb
, &stride
);
10382 ok(SUCCEEDED(hr
), "GetStreamSource failed, hr %#lx.\n", hr
);
10383 ok(current_vb
== vertex_buffer
, "Unexpected vb %p.\n", current_vb
);
10384 ok(stride
== sizeof(*quad
), "Unexpected stride %u.\n", stride
);
10385 IDirect3DVertexBuffer8_Release(current_vb
);
10387 /* Crashes on r200, Windows XP with STATUS_INTEGER_DIVIDE_BY_ZERO. */
10390 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLELIST
, 0, quad
, 0);
10391 ok(hr
== D3D_OK
, "DrawPrimitiveUP failed, hr %#lx.\n", hr
);
10393 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLELIST
, 0, quad
, sizeof(*quad
));
10394 ok(hr
== D3D_OK
, "DrawPrimitiveUP failed, hr %#lx.\n", hr
);
10396 hr
= IDirect3DDevice8_DrawPrimitiveUP(device
, D3DPT_TRIANGLELIST
, 2, quad
, sizeof(*quad
));
10397 ok(SUCCEEDED(hr
), "DrawPrimitiveUP failed, hr %#lx.\n", hr
);
10399 hr
= IDirect3DDevice8_GetStreamSource(device
, 0, ¤t_vb
, &stride
);
10400 ok(SUCCEEDED(hr
), "GetStreamSource failed, hr %#lx.\n", hr
);
10401 ok(!current_vb
, "Unexpected vb %p.\n", current_vb
);
10402 ok(!stride
, "Unexpected stride %u.\n", stride
);
10404 /* NULL index buffer, NULL stream source. */
10405 hr
= IDirect3DDevice8_SetIndices(device
, NULL
, 0);
10406 ok(SUCCEEDED(hr
), "SetIndices failed, hr %#lx.\n", hr
);
10407 hr
= IDirect3DDevice8_DrawIndexedPrimitive(device
, D3DPT_TRIANGLELIST
, 0, 4, 0, 2);
10408 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
10410 /* Valid index buffer, NULL stream source. */
10411 hr
= IDirect3DDevice8_SetIndices(device
, index_buffer
, 1);
10412 ok(SUCCEEDED(hr
), "SetIndices failed, hr %#lx.\n", hr
);
10413 hr
= IDirect3DDevice8_DrawIndexedPrimitive(device
, D3DPT_TRIANGLELIST
, 0, 4, 0, 2);
10414 ok(SUCCEEDED(hr
), "DrawIndexedPrimitive failed, hr %#lx.\n", hr
);
10416 hr
= IDirect3DDevice8_GetIndices(device
, ¤t_ib
, &base_vertex_index
);
10417 ok(SUCCEEDED(hr
), "GetIndices failed, hr %#lx.\n", hr
);
10418 ok(current_ib
== index_buffer
, "Unexpected index buffer %p.\n", current_ib
);
10419 ok(base_vertex_index
== 1, "Unexpected base vertex index %u.\n", base_vertex_index
);
10420 IDirect3DIndexBuffer8_Release(current_ib
);
10422 /* Crashes on r200, Windows XP with STATUS_INTEGER_DIVIDE_BY_ZERO. */
10425 hr
= IDirect3DDevice8_DrawIndexedPrimitiveUP(device
, D3DPT_TRIANGLELIST
, 0, 4, 0,
10426 indices
, D3DFMT_INDEX16
, quad
, 0);
10427 ok(SUCCEEDED(hr
), "DrawIndexedPrimitiveUP failed, hr %#lx.\n", hr
);
10428 hr
= IDirect3DDevice8_DrawIndexedPrimitiveUP(device
, D3DPT_TRIANGLELIST
, 0, 4, 2,
10429 indices
, D3DFMT_INDEX16
, quad
, 0);
10430 ok(SUCCEEDED(hr
), "DrawIndexedPrimitiveUP failed, hr %#lx.\n", hr
);
10433 hr
= IDirect3DDevice8_DrawIndexedPrimitiveUP(device
, D3DPT_TRIANGLELIST
, 0, 4, 2,
10434 indices
, D3DFMT_INDEX16
, quad
, sizeof(*quad
));
10435 ok(SUCCEEDED(hr
), "DrawIndexedPrimitiveUP failed, hr %#lx.\n", hr
);
10437 hr
= IDirect3DDevice8_GetIndices(device
, ¤t_ib
, &base_vertex_index
);
10438 ok(SUCCEEDED(hr
), "GetIndices failed, hr %#lx.\n", hr
);
10439 ok(!current_ib
, "Unexpected index buffer %p.\n", current_ib
);
10440 ok(!base_vertex_index
, "Unexpected base vertex index %u.\n", base_vertex_index
);
10442 /* Resetting of stream source and index buffer is not recorded in stateblocks. */
10444 hr
= IDirect3DDevice8_SetStreamSource(device
, 0, vertex_buffer
, sizeof(*quad
));
10445 ok(SUCCEEDED(hr
), "SetStreamSource failed, hr %#lx.\n", hr
);
10446 hr
= IDirect3DDevice8_SetIndices(device
, index_buffer
, 1);
10447 ok(SUCCEEDED(hr
), "SetIndices failed, hr %#lx.\n", hr
);
10449 hr
= IDirect3DDevice8_BeginStateBlock(device
);
10450 ok(SUCCEEDED(hr
), "BeginStateBlock failed, hr %#lx.\n", hr
);
10452 hr
= IDirect3DDevice8_DrawIndexedPrimitiveUP(device
, D3DPT_TRIANGLELIST
, 0, 4, 2,
10453 indices
, D3DFMT_INDEX16
, quad
, sizeof(*quad
));
10454 ok(SUCCEEDED(hr
), "DrawIndexedPrimitiveUP failed, hr %#lx.\n", hr
);
10456 hr
= IDirect3DDevice8_EndStateBlock(device
, &stateblock
);
10457 ok(SUCCEEDED(hr
), "BeginStateBlock failed, hr %#lx.\n", hr
);
10459 hr
= IDirect3DDevice8_GetStreamSource(device
, 0, ¤t_vb
, &stride
);
10460 ok(SUCCEEDED(hr
), "GetStreamSource failed, hr %#lx.\n", hr
);
10461 ok(!current_vb
, "Unexpected vb %p.\n", current_vb
);
10462 ok(!stride
, "Unexpected stride %u.\n", stride
);
10463 hr
= IDirect3DDevice8_GetIndices(device
, ¤t_ib
, &base_vertex_index
);
10464 ok(SUCCEEDED(hr
), "GetIndices failed, hr %#lx.\n", hr
);
10465 ok(!current_ib
, "Unexpected index buffer %p.\n", current_ib
);
10466 ok(!base_vertex_index
, "Unexpected base vertex index %u.\n", base_vertex_index
);
10468 hr
= IDirect3DDevice8_CaptureStateBlock(device
, stateblock
);
10469 ok(SUCCEEDED(hr
), "Capture failed, hr %#lx.\n", hr
);
10471 hr
= IDirect3DDevice8_SetStreamSource(device
, 0, vertex_buffer
, sizeof(*quad
));
10472 ok(SUCCEEDED(hr
), "SetStreamSource failed, hr %#lx.\n", hr
);
10473 hr
= IDirect3DDevice8_SetIndices(device
, index_buffer
, 1);
10474 ok(SUCCEEDED(hr
), "SetIndices failed, hr %#lx.\n", hr
);
10476 hr
= IDirect3DDevice8_ApplyStateBlock(device
, stateblock
);
10477 ok(SUCCEEDED(hr
), "Apply failed, hr %#lx.\n", hr
);
10479 hr
= IDirect3DDevice8_GetStreamSource(device
, 0, ¤t_vb
, &stride
);
10480 ok(SUCCEEDED(hr
), "GetStreamSource failed, hr %#lx.\n", hr
);
10481 ok(current_vb
== vertex_buffer
, "Unexpected vb %p.\n", current_vb
);
10482 ok(stride
== sizeof(*quad
), "Unexpected stride %u.\n", stride
);
10483 IDirect3DVertexBuffer8_Release(current_vb
);
10484 hr
= IDirect3DDevice8_GetIndices(device
, ¤t_ib
, &base_vertex_index
);
10485 ok(SUCCEEDED(hr
), "GetIndices failed, hr %#lx.\n", hr
);
10486 ok(current_ib
== index_buffer
, "Unexpected index buffer %p.\n", current_ib
);
10487 ok(base_vertex_index
== 1, "Unexpected base vertex index %u.\n", base_vertex_index
);
10488 IDirect3DIndexBuffer8_Release(current_ib
);
10490 hr
= IDirect3DDevice8_EndScene(device
);
10491 ok(SUCCEEDED(hr
), "EndScene failed, hr %#lx.\n", hr
);
10493 hr
= IDirect3DDevice8_Present(device
, NULL
, NULL
, NULL
, NULL
);
10494 ok(SUCCEEDED(hr
), "Present failed, hr %#lx.\n", hr
);
10496 IDirect3DDevice8_DeleteStateBlock(device
, stateblock
);
10497 IDirect3DVertexBuffer8_Release(vertex_buffer
);
10498 IDirect3DIndexBuffer8_Release(index_buffer
);
10499 refcount
= IDirect3DDevice8_Release(device
);
10500 ok(!refcount
, "Device has %lu references left.\n", refcount
);
10501 IDirect3D8_Release(d3d
);
10502 DestroyWindow(window
);
10505 static void test_get_display_mode(void)
10507 static const DWORD creation_flags
[] = {0, CREATE_DEVICE_FULLSCREEN
};
10508 unsigned int adapter_idx
, adapter_count
, mode_idx
, test_idx
;
10509 RECT previous_monitor_rect
;
10510 unsigned int width
, height
;
10511 IDirect3DDevice8
*device
;
10512 MONITORINFO monitor_info
;
10513 struct device_desc desc
;
10514 D3DDISPLAYMODE mode
;
10522 window
= create_window();
10523 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
10524 ok(!!d3d
, "Failed to create a D3D object.\n");
10526 if (!(device
= create_device(d3d
, window
, NULL
)))
10528 skip("Failed to create a D3D device.\n");
10529 IDirect3D8_Release(d3d
);
10530 DestroyWindow(window
);
10534 hr
= IDirect3DDevice8_GetDisplayMode(device
, &mode
);
10535 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
10536 ok(mode
.Format
== D3DFMT_X8R8G8B8
, "Unexpected format %#x.\n", mode
.Format
);
10537 hr
= IDirect3D8_GetAdapterDisplayMode(d3d
, D3DADAPTER_DEFAULT
, &mode
);
10538 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
10539 ok(mode
.Format
== D3DFMT_X8R8G8B8
, "Unexpected format %#x.\n", mode
.Format
);
10541 refcount
= IDirect3DDevice8_Release(device
);
10542 ok(!refcount
, "Device has %lu references left.\n", refcount
);
10544 desc
.adapter_ordinal
= D3DADAPTER_DEFAULT
;
10545 desc
.device_window
= window
;
10548 desc
.flags
= CREATE_DEVICE_FULLSCREEN
;
10549 if (!(device
= create_device(d3d
, window
, &desc
)))
10551 skip("Failed to create a D3D device.\n");
10552 IDirect3D8_Release(d3d
);
10553 DestroyWindow(window
);
10557 hr
= IDirect3DDevice8_GetDisplayMode(device
, &mode
);
10558 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
10559 ok(mode
.Width
== 640, "Unexpected width %u.\n", mode
.Width
);
10560 ok(mode
.Height
== 480, "Unexpected width %u.\n", mode
.Height
);
10561 ok(mode
.Format
== D3DFMT_X8R8G8B8
, "Unexpected format %#x.\n", mode
.Format
);
10562 hr
= IDirect3D8_GetAdapterDisplayMode(d3d
, D3DADAPTER_DEFAULT
, &mode
);
10563 ok(hr
== D3D_OK
, "Got unexpected hr %#lx.\n", hr
);
10564 ok(mode
.Width
== 640, "Unexpected width %u.\n", mode
.Width
);
10565 ok(mode
.Height
== 480, "Unexpected width %u.\n", mode
.Height
);
10566 ok(mode
.Format
== D3DFMT_X8R8G8B8
, "Unexpected format %#x.\n", mode
.Format
);
10568 refcount
= IDirect3DDevice8_Release(device
);
10569 ok(!refcount
, "Device has %lu references left.\n", refcount
);
10570 DestroyWindow(window
);
10572 /* D3D8 uses adapter indices to determine which adapter to use to get the display mode */
10573 adapter_count
= IDirect3D8_GetAdapterCount(d3d
);
10574 for (adapter_idx
= 0; adapter_idx
< adapter_count
; ++adapter_idx
)
10583 /* Find a mode different than that of the previous adapter, so that tests can be sure
10584 * that they are comparing to the current adapter display mode */
10585 monitor
= IDirect3D8_GetAdapterMonitor(d3d
, adapter_idx
- 1);
10586 ok(!!monitor
, "Adapter %u: GetAdapterMonitor failed.\n", adapter_idx
- 1);
10587 monitor_info
.cbSize
= sizeof(monitor_info
);
10588 ret
= GetMonitorInfoW(monitor
, &monitor_info
);
10589 ok(ret
, "Adapter %u: GetMonitorInfoW failed, error %#lx.\n", adapter_idx
- 1,
10591 previous_monitor_rect
= monitor_info
.rcMonitor
;
10593 desc
.width
= monitor_info
.rcMonitor
.right
- monitor_info
.rcMonitor
.left
;
10594 desc
.height
= monitor_info
.rcMonitor
.bottom
- monitor_info
.rcMonitor
.top
;
10595 for (mode_idx
= 0; SUCCEEDED(IDirect3D8_EnumAdapterModes(d3d
, adapter_idx
, mode_idx
,
10596 &mode
)); ++mode_idx
)
10598 if (mode
.Format
!= D3DFMT_X8R8G8B8
)
10600 if (mode
.Width
< 640 || mode
.Height
< 480)
10602 if (mode
.Width
!= desc
.width
&& mode
.Height
!= desc
.height
)
10605 ok(mode
.Width
!= desc
.width
&& mode
.Height
!= desc
.height
,
10606 "Adapter %u: Failed to find a different mode than %ux%u.\n", adapter_idx
,
10607 desc
.width
, desc
.height
);
10608 desc
.width
= mode
.Width
;
10609 desc
.height
= mode
.Height
;
10612 for (test_idx
= 0; test_idx
< ARRAY_SIZE(creation_flags
); ++test_idx
)
10614 window
= create_window();
10615 desc
.adapter_ordinal
= adapter_idx
;
10616 desc
.device_window
= window
;
10617 desc
.flags
= creation_flags
[test_idx
];
10618 if (!(device
= create_device(d3d
, window
, &desc
)))
10620 skip("Adapter %u test %u: Failed to create a D3D device.\n", adapter_idx
, test_idx
);
10621 DestroyWindow(window
);
10625 monitor
= IDirect3D8_GetAdapterMonitor(d3d
, adapter_idx
);
10626 ok(!!monitor
, "Adapter %u test %u: GetAdapterMonitor failed.\n", adapter_idx
, test_idx
);
10627 monitor_info
.cbSize
= sizeof(monitor_info
);
10628 ret
= GetMonitorInfoW(monitor
, &monitor_info
);
10629 ok(ret
, "Adapter %u test %u: GetMonitorInfoW failed, error %#lx.\n", adapter_idx
,
10630 test_idx
, GetLastError());
10631 width
= monitor_info
.rcMonitor
.right
- monitor_info
.rcMonitor
.left
;
10632 height
= monitor_info
.rcMonitor
.bottom
- monitor_info
.rcMonitor
.top
;
10636 /* Move the device window to the previous monitor to test that the device window
10637 * position doesn't affect which adapter to use to get the display mode */
10638 ret
= SetWindowPos(window
, 0, previous_monitor_rect
.left
, previous_monitor_rect
.top
,
10639 0, 0, SWP_NOZORDER
| SWP_NOSIZE
);
10640 ok(ret
, "Adapter %u test %u: SetWindowPos failed, error %#lx.\n", adapter_idx
,
10641 test_idx
, GetLastError());
10644 hr
= IDirect3D8_GetAdapterDisplayMode(d3d
, adapter_idx
, &mode
);
10645 ok(hr
== D3D_OK
, "Adapter %u test %u: GetAdapterDisplayMode failed, hr %#lx.\n",
10646 adapter_idx
, test_idx
, hr
);
10647 ok(mode
.Width
== width
, "Adapter %u test %u: Expect width %u, got %u.\n", adapter_idx
,
10648 test_idx
, width
, mode
.Width
);
10649 ok(mode
.Height
== height
, "Adapter %u test %u: Expect height %u, got %u.\n",
10650 adapter_idx
, test_idx
, height
, mode
.Height
);
10652 hr
= IDirect3DDevice8_GetDisplayMode(device
, &mode
);
10653 ok(hr
== D3D_OK
, "Adapter %u test %u: GetDisplayMode failed, hr %#lx.\n", adapter_idx
,
10655 ok(mode
.Width
== width
, "Adapter %u test %u: Expect width %u, got %u.\n", adapter_idx
,
10656 test_idx
, width
, mode
.Width
);
10657 ok(mode
.Height
== height
, "Adapter %u test %u: Expect height %u, got %u.\n",
10658 adapter_idx
, test_idx
, height
, mode
.Height
);
10660 refcount
= IDirect3DDevice8_Release(device
);
10661 ok(!refcount
, "Adapter %u test %u: Device has %lu references left.\n", adapter_idx
,
10662 test_idx
, refcount
);
10663 DestroyWindow(window
);
10667 IDirect3D8_Release(d3d
);
10670 static void test_multi_adapter(void)
10672 unsigned int i
, adapter_count
, expected_adapter_count
= 0;
10673 DISPLAY_DEVICEA display_device
;
10674 MONITORINFOEXA monitor_info
;
10675 DEVMODEA old_mode
, mode
;
10680 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
10681 ok(!!d3d
, "Failed to create a D3D object.\n");
10683 display_device
.cb
= sizeof(display_device
);
10684 for (i
= 0; EnumDisplayDevicesA(NULL
, i
, &display_device
, 0); ++i
)
10686 if (display_device
.StateFlags
& DISPLAY_DEVICE_ATTACHED_TO_DESKTOP
)
10687 ++expected_adapter_count
;
10690 adapter_count
= IDirect3D8_GetAdapterCount(d3d
);
10691 ok(adapter_count
== expected_adapter_count
, "Got unexpected adapter count %u, expected %u.\n",
10692 adapter_count
, expected_adapter_count
);
10694 for (i
= 0; i
< adapter_count
; ++i
)
10696 monitor
= IDirect3D8_GetAdapterMonitor(d3d
, i
);
10697 ok(!!monitor
, "Adapter %u: Failed to get monitor.\n", i
);
10699 monitor_info
.cbSize
= sizeof(monitor_info
);
10700 ret
= GetMonitorInfoA(monitor
, (MONITORINFO
*)&monitor_info
);
10701 ok(ret
, "Adapter %u: Failed to get monitor info, error %#lx.\n", i
, GetLastError());
10704 ok(monitor_info
.dwFlags
== MONITORINFOF_PRIMARY
,
10705 "Adapter %u: Got unexpected monitor flags %#lx.\n", i
, monitor_info
.dwFlags
);
10707 ok(!monitor_info
.dwFlags
, "Adapter %u: Got unexpected monitor flags %#lx.\n", i
,
10708 monitor_info
.dwFlags
);
10710 /* Test D3D adapters after they got detached */
10711 if (monitor_info
.dwFlags
== MONITORINFOF_PRIMARY
)
10714 /* Save current display settings */
10715 memset(&old_mode
, 0, sizeof(old_mode
));
10716 old_mode
.dmSize
= sizeof(old_mode
);
10717 ret
= EnumDisplaySettingsA(monitor_info
.szDevice
, ENUM_CURRENT_SETTINGS
, &old_mode
);
10718 /* Win10 TestBots may return FALSE but it's actually successful */
10719 ok(ret
|| broken(!ret
), "Adapter %u: EnumDisplaySettingsA failed for %s, error %#lx.\n", i
,
10720 monitor_info
.szDevice
, GetLastError());
10723 memset(&mode
, 0, sizeof(mode
));
10724 mode
.dmSize
= sizeof(mode
);
10725 mode
.dmFields
= DM_POSITION
| DM_PELSWIDTH
| DM_PELSHEIGHT
;
10726 mode
.dmPosition
= old_mode
.dmPosition
;
10727 ret
= ChangeDisplaySettingsExA(monitor_info
.szDevice
, &mode
, NULL
,
10728 CDS_UPDATEREGISTRY
| CDS_NORESET
, NULL
);
10729 ok(ret
== DISP_CHANGE_SUCCESSFUL
,
10730 "Adapter %u: ChangeDisplaySettingsExA %s returned unexpected %ld.\n", i
,
10731 monitor_info
.szDevice
, ret
);
10732 ret
= ChangeDisplaySettingsExA(monitor_info
.szDevice
, NULL
, NULL
, 0, NULL
);
10733 ok(ret
== DISP_CHANGE_SUCCESSFUL
,
10734 "Adapter %u: ChangeDisplaySettingsExA %s returned unexpected %ld.\n", i
,
10735 monitor_info
.szDevice
, ret
);
10737 /* Check if it is really detached */
10738 memset(&mode
, 0, sizeof(mode
));
10739 mode
.dmSize
= sizeof(mode
);
10740 ret
= EnumDisplaySettingsA(monitor_info
.szDevice
, ENUM_CURRENT_SETTINGS
, &mode
);
10741 /* Win10 TestBots may return FALSE but it's actually successful */
10742 ok(ret
|| broken(!ret
) , "Adapter %u: EnumDisplaySettingsA failed for %s, error %#lx.\n", i
,
10743 monitor_info
.szDevice
, GetLastError());
10744 if (mode
.dmPelsWidth
&& mode
.dmPelsHeight
)
10746 skip("Adapter %u: Failed to detach device %s.\n", i
, monitor_info
.szDevice
);
10750 /* Detaching adapter shouldn't reduce the adapter count */
10751 expected_adapter_count
= adapter_count
;
10752 adapter_count
= IDirect3D8_GetAdapterCount(d3d
);
10753 ok(adapter_count
== expected_adapter_count
,
10754 "Adapter %u: Got unexpected adapter count %u, expected %u.\n", i
, adapter_count
,
10755 expected_adapter_count
);
10757 monitor
= IDirect3D8_GetAdapterMonitor(d3d
, i
);
10758 ok(!monitor
, "Adapter %u: Expect monitor to be NULL.\n", i
);
10760 /* Restore settings */
10761 ret
= ChangeDisplaySettingsExA(monitor_info
.szDevice
, &old_mode
, NULL
,
10762 CDS_UPDATEREGISTRY
| CDS_NORESET
, NULL
);
10763 ok(ret
== DISP_CHANGE_SUCCESSFUL
,
10764 "Adapter %u: ChangeDisplaySettingsExA %s returned unexpected %ld.\n", i
,
10765 monitor_info
.szDevice
, ret
);
10766 ret
= ChangeDisplaySettingsExA(monitor_info
.szDevice
, NULL
, NULL
, 0, NULL
);
10767 ok(ret
== DISP_CHANGE_SUCCESSFUL
,
10768 "Adapter %u: ChangeDisplaySettingsExA %s returned unexpected %ld.\n", i
,
10769 monitor_info
.szDevice
, ret
);
10772 IDirect3D8_Release(d3d
);
10775 static void test_creation_parameters(void)
10777 unsigned int adapter_idx
, adapter_count
;
10778 D3DDEVICE_CREATION_PARAMETERS params
;
10779 struct device_desc device_desc
;
10780 IDirect3DDevice8
*device
;
10785 window
= create_window();
10786 ok(!!window
, "Failed to create a window.\n");
10787 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
10788 ok(!!d3d
, "Failed to create a D3D object.\n");
10790 device_desc
.device_window
= window
;
10791 device_desc
.width
= 640;
10792 device_desc
.height
= 480;
10793 device_desc
.flags
= 0;
10795 adapter_count
= IDirect3D8_GetAdapterCount(d3d
);
10796 for (adapter_idx
= 0; adapter_idx
< adapter_count
; ++adapter_idx
)
10798 device_desc
.adapter_ordinal
= adapter_idx
;
10799 if (!(device
= create_device(d3d
, window
, &device_desc
)))
10801 skip("Adapter %u: Failed to create a D3D device.\n", adapter_idx
);
10805 memset(¶ms
, 0, sizeof(params
));
10806 hr
= IDirect3DDevice8_GetCreationParameters(device
, ¶ms
);
10807 ok(hr
== D3D_OK
, "Adapter %u: GetCreationParameters failed, hr %#lx.\n", adapter_idx
, hr
);
10808 ok(params
.AdapterOrdinal
== adapter_idx
, "Adapter %u: Got unexpected adapter ordinal %u.\n",
10809 adapter_idx
, params
.AdapterOrdinal
);
10810 ok(params
.DeviceType
== D3DDEVTYPE_HAL
, "Adapter %u: Expect device type %#x, got %#x.\n",
10811 adapter_idx
, D3DDEVTYPE_HAL
, params
.DeviceType
);
10812 ok(params
.hFocusWindow
== window
, "Adapter %u: Expect focus window %p, got %p.\n",
10813 adapter_idx
, window
, params
.hFocusWindow
);
10815 IDirect3DDevice8_Release(device
);
10818 IDirect3D8_Release(d3d
);
10819 DestroyWindow(window
);
10822 static void test_cursor_clipping(void)
10824 unsigned int adapter_idx
, adapter_count
, mode_idx
;
10825 D3DDISPLAYMODE mode
, current_mode
;
10826 struct device_desc device_desc
;
10827 RECT virtual_rect
, clip_rect
;
10828 IDirect3DDevice8
*device
;
10834 window
= create_window();
10835 ok(!!window
, "Failed to create a window.\n");
10836 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
10837 ok(!!d3d
, "Failed to create a D3D object.\n");
10839 device_desc
.device_window
= window
;
10840 device_desc
.flags
= CREATE_DEVICE_FULLSCREEN
;
10842 adapter_count
= IDirect3D8_GetAdapterCount(d3d
);
10843 for (adapter_idx
= 0; adapter_idx
< adapter_count
; ++adapter_idx
)
10845 hr
= IDirect3D8_GetAdapterDisplayMode(d3d
, adapter_idx
, ¤t_mode
);
10846 ok(hr
== D3D_OK
, "Adapter %u: GetAdapterDisplayMode failed, hr %#lx.\n", adapter_idx
, hr
);
10847 for (mode_idx
= 0; SUCCEEDED(IDirect3D8_EnumAdapterModes(d3d
, adapter_idx
, mode_idx
, &mode
));
10850 if (mode
.Format
!= D3DFMT_X8R8G8B8
)
10852 if (mode
.Width
< 640 || mode
.Height
< 480)
10854 if (mode
.Width
!= current_mode
.Width
&& mode
.Height
!= current_mode
.Height
)
10857 ok(mode
.Width
!= current_mode
.Width
&& mode
.Height
!= current_mode
.Height
,
10858 "Adapter %u: Failed to find a different mode than %ux%u.\n", adapter_idx
,
10859 current_mode
.Width
, current_mode
.Height
);
10861 ret
= ClipCursor(NULL
);
10862 ok(ret
, "Adapter %u: ClipCursor failed, error %#lx.\n", adapter_idx
,
10864 get_virtual_rect(&virtual_rect
);
10865 ret
= GetClipCursor(&clip_rect
);
10866 ok(ret
, "Adapter %u: GetClipCursor failed, error %#lx.\n", adapter_idx
,
10868 ok(EqualRect(&clip_rect
, &virtual_rect
), "Adapter %u: Expect clip rect %s, got %s.\n",
10869 adapter_idx
, wine_dbgstr_rect(&virtual_rect
), wine_dbgstr_rect(&clip_rect
));
10871 device_desc
.adapter_ordinal
= adapter_idx
;
10872 device_desc
.width
= mode
.Width
;
10873 device_desc
.height
= mode
.Height
;
10874 if (!(device
= create_device(d3d
, window
, &device_desc
)))
10876 skip("Adapter %u: Failed to create a D3D device.\n", adapter_idx
);
10880 get_virtual_rect(&virtual_rect
);
10881 ret
= GetClipCursor(&clip_rect
);
10882 ok(ret
, "Adapter %u: GetClipCursor failed, error %#lx.\n", adapter_idx
,
10884 ok(EqualRect(&clip_rect
, &virtual_rect
), "Adapter %u: Expect clip rect %s, got %s.\n",
10885 adapter_idx
, wine_dbgstr_rect(&virtual_rect
), wine_dbgstr_rect(&clip_rect
));
10887 IDirect3DDevice8_Release(device
);
10889 get_virtual_rect(&virtual_rect
);
10890 ret
= GetClipCursor(&clip_rect
);
10891 ok(ret
, "Adapter %u: GetClipCursor failed, error %#lx.\n", adapter_idx
,
10893 ok(EqualRect(&clip_rect
, &virtual_rect
), "Adapter %u: Expect clip rect %s, got %s.\n",
10894 adapter_idx
, wine_dbgstr_rect(&virtual_rect
), wine_dbgstr_rect(&clip_rect
));
10897 IDirect3D8_Release(d3d
);
10898 DestroyWindow(window
);
10901 static void test_window_position(void)
10903 unsigned int adapter_idx
, adapter_count
;
10904 struct device_desc device_desc
;
10905 IDirect3DDevice8
*device
;
10906 MONITORINFO monitor_info
;
10914 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
10915 ok(!!d3d
, "Failed to create a D3D object.\n");
10917 adapter_count
= IDirect3D8_GetAdapterCount(d3d
);
10918 for (adapter_idx
= 0; adapter_idx
< adapter_count
; ++adapter_idx
)
10920 monitor
= IDirect3D8_GetAdapterMonitor(d3d
, adapter_idx
);
10921 ok(!!monitor
, "Adapter %u: GetAdapterMonitor failed.\n", adapter_idx
);
10922 monitor_info
.cbSize
= sizeof(monitor_info
);
10923 ret
= GetMonitorInfoW(monitor
, &monitor_info
);
10924 ok(ret
, "Adapter %u: GetMonitorInfoW failed, error %#lx.\n", adapter_idx
, GetLastError());
10926 window
= create_window();
10927 device_desc
.adapter_ordinal
= adapter_idx
;
10928 device_desc
.device_window
= window
;
10929 device_desc
.width
= monitor_info
.rcMonitor
.right
- monitor_info
.rcMonitor
.left
;
10930 device_desc
.height
= monitor_info
.rcMonitor
.bottom
- monitor_info
.rcMonitor
.top
;
10931 device_desc
.flags
= CREATE_DEVICE_FULLSCREEN
;
10932 if (!(device
= create_device(d3d
, window
, &device_desc
)))
10934 skip("Adapter %u: Failed to create a D3D device, skipping tests.\n", adapter_idx
);
10935 DestroyWindow(window
);
10939 ret
= GetWindowRect(window
, &window_rect
);
10940 ok(ret
, "Adapter %u: GetWindowRect failed, error %#lx.\n", adapter_idx
, GetLastError());
10941 ok(EqualRect(&window_rect
, &monitor_info
.rcMonitor
),
10942 "Adapter %u: Expect window rect %s, got %s.\n", adapter_idx
,
10943 wine_dbgstr_rect(&monitor_info
.rcMonitor
), wine_dbgstr_rect(&window_rect
));
10945 /* Device resets should restore the window rectangle to fit the whole monitor */
10946 ret
= SetWindowPos(window
, 0, 0, 0, 0, 0, SWP_NOZORDER
| SWP_NOSIZE
);
10947 ok(ret
, "Adapter %u: SetWindowPos failed, error %#lx.\n", adapter_idx
, GetLastError());
10948 hr
= reset_device(device
, &device_desc
);
10949 ok(hr
== D3D_OK
, "Adapter %u: Failed to reset device, hr %#lx.\n", adapter_idx
, hr
);
10951 ret
= GetWindowRect(window
, &window_rect
);
10952 ok(ret
, "Adapter %u: GetWindowRect failed, error %#lx.\n", adapter_idx
, GetLastError());
10953 ok(EqualRect(&window_rect
, &monitor_info
.rcMonitor
),
10954 "Adapter %u: Expect window rect %s, got %s.\n", adapter_idx
,
10955 wine_dbgstr_rect(&monitor_info
.rcMonitor
), wine_dbgstr_rect(&window_rect
));
10957 /* Window activation should restore the window rectangle to fit the whole monitor */
10958 ret
= SetWindowPos(window
, 0, 0, 0, 0, 0, SWP_NOZORDER
| SWP_NOSIZE
);
10959 ok(ret
, "Adapter %u: SetWindowPos failed, error %#lx.\n", adapter_idx
, GetLastError());
10960 ret
= SetForegroundWindow(GetDesktopWindow());
10961 ok(ret
, "Adapter %u: SetForegroundWindow failed, error %#lx.\n", adapter_idx
, GetLastError());
10963 ret
= ShowWindow(window
, SW_RESTORE
);
10964 ok(ret
, "Adapter %u: Failed to restore window, error %#lx.\n", adapter_idx
, GetLastError());
10966 ret
= SetForegroundWindow(window
);
10967 ok(ret
, "Adapter %u: SetForegroundWindow failed, error %#lx.\n", adapter_idx
, GetLastError());
10969 ret
= GetWindowRect(window
, &window_rect
);
10970 ok(ret
, "Adapter %u: GetWindowRect failed, error %#lx.\n", adapter_idx
, GetLastError());
10971 ok(EqualRect(&window_rect
, &monitor_info
.rcMonitor
),
10972 "Adapter %u: Expect window rect %s, got %s.\n", adapter_idx
,
10973 wine_dbgstr_rect(&monitor_info
.rcMonitor
), wine_dbgstr_rect(&window_rect
));
10975 IDirect3DDevice8_Release(device
);
10976 DestroyWindow(window
);
10979 IDirect3D8_Release(d3d
);
10982 static void test_filter(void)
10984 unsigned int mag
, min
, mip
;
10985 IDirect3DTexture8
*texture
;
10986 IDirect3DDevice8
*device
;
10994 d3d
= Direct3DCreate8(D3D_SDK_VERSION
);
10995 ok(!!d3d
, "Failed to create a D3D object.\n");
10997 window
= create_window();
10998 if (!(device
= create_device(d3d
, window
, NULL
)))
11000 skip("Failed to create a D3D device, skipping tests.\n");
11001 IDirect3D8_Release(d3d
);
11002 DestroyWindow(window
);
11006 hr
= IDirect3DDevice8_CreateTexture(device
, 128, 128, 0, 0, D3DFMT_X8R8G8B8
, D3DPOOL_MANAGED
, &texture
);
11007 ok(SUCCEEDED(hr
), "Failed to create texture, hr %#lx.\n", hr
);
11009 for (has_texture
= FALSE
; has_texture
<= TRUE
; ++has_texture
)
11010 for (mag
= 0; mag
<= D3DTEXF_GAUSSIANCUBIC
+ 1; ++mag
)
11011 for (min
= 0; min
<= D3DTEXF_GAUSSIANCUBIC
+ 1; ++min
)
11012 for (mip
= 0; mip
<= D3DTEXF_GAUSSIANCUBIC
+ 1; ++mip
)
11016 hr
= IDirect3DDevice8_SetTexture(device
, 0, (IDirect3DBaseTexture8
*)texture
);
11017 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#lx.\n", hr
);
11021 hr
= IDirect3DDevice8_SetTexture(device
, 0, NULL
);
11022 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#lx.\n", hr
);
11025 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_MAGFILTER
, mag
);
11026 ok(SUCCEEDED(hr
), "Failed to set sampler state, hr %#lx.\n", hr
);
11027 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_MINFILTER
, min
);
11028 ok(SUCCEEDED(hr
), "Failed to set sampler state, hr %#lx.\n", hr
);
11029 hr
= IDirect3DDevice8_SetTextureStageState(device
, 0, D3DTSS_MIPFILTER
, mip
);
11030 ok(SUCCEEDED(hr
), "Failed to set sampler state, hr %#lx.\n", hr
);
11032 passes
= 0xdeadbeef;
11033 hr
= IDirect3DDevice8_ValidateDevice(device
, &passes
);
11034 ok(SUCCEEDED(hr
), "Failed to validate device, hr %#lx.\n", hr
);
11035 ok(passes
&& passes
!= 0xdeadbeef, "Got unexpected passes %#lx.\n", passes
);
11038 hr
= IDirect3DDevice8_SetTexture(device
, 0, NULL
);
11039 ok(SUCCEEDED(hr
), "Failed to set texture, hr %#lx.\n", hr
);
11040 IDirect3DTexture8_Release(texture
);
11042 refcount
= IDirect3DDevice8_Release(device
);
11043 ok(!refcount
, "Device has %lu references left.\n", refcount
);
11044 IDirect3D8_Release(d3d
);
11045 DestroyWindow(window
);
11050 HMODULE d3d8_handle
= GetModuleHandleA("d3d8.dll");
11051 WNDCLASSA wc
= {0};
11053 DEVMODEW current_mode
;
11057 skip("Could not load d3d8.dll\n");
11061 memset(¤t_mode
, 0, sizeof(current_mode
));
11062 current_mode
.dmSize
= sizeof(current_mode
);
11063 ok(EnumDisplaySettingsW(NULL
, ENUM_CURRENT_SETTINGS
, ¤t_mode
), "Failed to get display mode.\n");
11064 registry_mode
.dmSize
= sizeof(registry_mode
);
11065 ok(EnumDisplaySettingsW(NULL
, ENUM_REGISTRY_SETTINGS
, ®istry_mode
), "Failed to get display mode.\n");
11066 if (current_mode
.dmPelsWidth
!= registry_mode
.dmPelsWidth
11067 || current_mode
.dmPelsHeight
!= registry_mode
.dmPelsHeight
)
11069 skip("Current mode does not match registry mode, skipping test.\n");
11073 wc
.lpfnWndProc
= DefWindowProcA
;
11074 wc
.lpszClassName
= "d3d8_test_wc";
11075 RegisterClassA(&wc
);
11077 ValidateVertexShader
= (void *)GetProcAddress(d3d8_handle
, "ValidateVertexShader");
11078 ValidatePixelShader
= (void *)GetProcAddress(d3d8_handle
, "ValidatePixelShader");
11080 if (!(d3d8
= Direct3DCreate8(D3D_SDK_VERSION
)))
11082 skip("could not create D3D8\n");
11085 IDirect3D8_Release(d3d8
);
11088 test_display_formats();
11089 test_display_modes();
11090 test_shader_versions();
11093 test_mipmap_levels();
11094 test_checkdevicemultisampletype();
11095 test_invalid_multisample();
11104 test_set_stream_source();
11105 test_ApplyStateBlock();
11106 test_render_zero_triangles();
11107 test_depth_stencil_reset();
11109 test_wndproc_windowed();
11110 test_depth_stencil_size();
11111 test_window_style();
11112 test_unsupported_shaders();
11113 test_mode_change();
11114 test_device_window_reset();
11115 test_reset_resources();
11117 test_set_rt_vp_scissor();
11118 test_validate_vs();
11119 test_validate_ps();
11120 test_volume_get_container();
11121 test_vb_lock_flags();
11122 test_texture_stage_states();
11123 test_cube_textures();
11124 test_get_set_texture();
11125 test_image_surface_pool();
11126 test_surface_get_container();
11127 test_lockrect_invalid();
11128 test_private_data();
11129 test_surface_dimensions();
11130 test_surface_format_null();
11131 test_surface_double_unlock();
11132 test_surface_blocks();
11133 test_set_palette();
11134 test_pinned_buffers();
11135 test_npot_textures();
11136 test_volume_locking();
11137 test_update_texture_pool();
11138 test_update_volumetexture();
11139 test_create_rt_ds_fail();
11140 test_volume_blocks();
11141 test_lockbox_invalid();
11142 test_pixel_format();
11143 test_begin_end_state_block();
11144 test_shader_constant_apply();
11145 test_resource_type();
11146 test_mipmap_lock();
11147 test_writeonly_resource();
11148 test_lost_device();
11149 test_resource_priority();
11150 test_swapchain_parameters();
11151 test_check_device_format();
11152 test_miptree_layout();
11153 test_render_target_device_mismatch();
11154 test_format_unknown();
11155 test_destroyed_window();
11156 test_lockable_backbuffer();
11157 test_clip_planes_limits();
11158 test_swapchain_multisample_reset();
11159 test_device_caps();
11161 test_resource_access();
11162 test_multiply_transform();
11163 test_draw_primitive();
11164 test_get_display_mode();
11165 test_multi_adapter();
11166 test_creation_parameters();
11167 test_cursor_clipping();
11168 test_window_position();
11171 UnregisterClassA("d3d8_test_wc", GetModuleHandleA(NULL
));