wined3d: Add a dirty region to the destination texture in wined3d_device_context_blt...
[wine.git] / dlls / d3d8 / tests / visual.c
blob1f6e91609db92163a2d67ccf71d3e276b2baecde
1 /*
2 * Copyright (C) 2005 Henri Verbeet
3 * Copyright (C) 2007, 2009, 2011-2013 Stefan Dösinger(for CodeWeavers)
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 /* See comment in dlls/d3d9/tests/visual.c for general guidelines */
22 #include <limits.h>
23 #include <math.h>
25 #define COBJMACROS
26 #include <d3d8.h>
27 #include "wine/test.h"
29 struct vec2
31 float x, y;
34 struct vec3
36 float x, y, z;
39 struct vec4
41 float x, y, z, w;
44 static HWND create_window(void)
46 RECT rect;
48 SetRect(&rect, 0, 0, 640, 480);
49 AdjustWindowRect(&rect, WS_OVERLAPPEDWINDOW | WS_VISIBLE, FALSE);
50 return CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
51 0, 0, rect.right - rect.left, rect.bottom - rect.top, 0, 0, 0, 0);
54 static BOOL compare_uint(unsigned int x, unsigned int y, unsigned int max_diff)
56 unsigned int diff = x > y ? x - y : y - x;
58 return diff <= max_diff;
61 static BOOL color_match(D3DCOLOR c1, D3DCOLOR c2, BYTE max_diff)
63 return compare_uint(c1 & 0xff, c2 & 0xff, max_diff)
64 && compare_uint((c1 >> 8) & 0xff, (c2 >> 8) & 0xff, max_diff)
65 && compare_uint((c1 >> 16) & 0xff, (c2 >> 16) & 0xff, max_diff)
66 && compare_uint((c1 >> 24) & 0xff, (c2 >> 24) & 0xff, max_diff);
69 static BOOL compare_float(float f, float g, unsigned int ulps)
71 int x = *(int *)&f;
72 int y = *(int *)&g;
74 if (x < 0)
75 x = INT_MIN - x;
76 if (y < 0)
77 y = INT_MIN - y;
79 if (abs(x - y) > ulps)
80 return FALSE;
82 return TRUE;
85 static BOOL compare_vec4(const struct vec4 *vec, float x, float y, float z, float w, unsigned int ulps)
87 return compare_float(vec->x, x, ulps)
88 && compare_float(vec->y, y, ulps)
89 && compare_float(vec->z, z, ulps)
90 && compare_float(vec->w, w, ulps);
93 static BOOL adapter_is_warp(const D3DADAPTER_IDENTIFIER8 *identifier)
95 return !strcmp(identifier->Driver, "d3d10warp.dll");
98 struct surface_readback
100 IDirect3DSurface8 *surface;
101 D3DLOCKED_RECT locked_rect;
104 static void get_surface_readback(IDirect3DSurface8 *surface, struct surface_readback *rb)
106 IDirect3DTexture8 *tex = NULL;
107 IDirect3DDevice8 *device;
108 D3DSURFACE_DESC desc;
109 HRESULT hr;
111 memset(rb, 0, sizeof(*rb));
112 hr = IDirect3DSurface8_GetDevice(surface, &device);
113 ok(SUCCEEDED(hr), "Failed to get device, hr %#lx.\n", hr);
114 hr = IDirect3DSurface8_GetDesc(surface, &desc);
115 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#lx.\n", hr);
117 if (desc.Pool == D3DPOOL_DEFAULT || (desc.Usage & D3DUSAGE_WRITEONLY))
119 hr = IDirect3DDevice8_CreateTexture(device, desc.Width, desc.Height, 1, 0, desc.Format, D3DPOOL_SYSTEMMEM, &tex);
120 ok(hr == S_OK, "Got hr %#lx.\n", hr);
121 hr = IDirect3DTexture8_GetSurfaceLevel(tex, 0, &rb->surface);
122 ok(hr == S_OK, "Got hr %#lx.\n", hr);
123 hr = IDirect3DDevice8_CopyRects(device, surface, NULL, 0, rb->surface, NULL);
124 ok(hr == S_OK, "Got hr %#lx.\n", hr);
125 IDirect3DTexture8_Release(tex);
127 else
129 IDirect3DSurface8_AddRef(surface);
130 rb->surface = surface;
132 hr = IDirect3DSurface8_LockRect(rb->surface, &rb->locked_rect, NULL, D3DLOCK_READONLY);
133 ok(hr == S_OK, "Got hr %#lx.\n", hr);
134 IDirect3DDevice8_Release(device);
137 static DWORD get_readback_color(struct surface_readback *rb, unsigned int x, unsigned int y)
139 return ((DWORD *)rb->locked_rect.pBits)[y * rb->locked_rect.Pitch / sizeof(DWORD) + x];
142 static void release_surface_readback(struct surface_readback *rb)
144 HRESULT hr;
146 hr = IDirect3DSurface8_UnlockRect(rb->surface);
147 ok(hr == S_OK, "Got hr %#lx.\n", hr);
148 IDirect3DSurface8_Release(rb->surface);
151 static DWORD getPixelColor(IDirect3DDevice8 *device, UINT x, UINT y)
153 DWORD ret;
154 IDirect3DSurface8 *rt;
155 struct surface_readback rb;
156 HRESULT hr;
158 hr = IDirect3DDevice8_GetRenderTarget(device, &rt);
159 ok(hr == S_OK, "Got hr %#lx.\n", hr);
161 get_surface_readback(rt, &rb);
162 /* Remove the X channel for now. DirectX and OpenGL have different ideas how to treat it apparently, and it isn't
163 * really important for these tests
165 ret = get_readback_color(&rb, x, y) & 0x00ffffff;
166 release_surface_readback(&rb);
168 IDirect3DSurface8_Release(rt);
169 return ret;
172 static D3DCOLOR get_surface_color(IDirect3DSurface8 *surface, UINT x, UINT y)
174 DWORD color;
175 HRESULT hr;
176 D3DSURFACE_DESC desc;
177 RECT rectToLock = {x, y, x+1, y+1};
178 D3DLOCKED_RECT lockedRect;
180 hr = IDirect3DSurface8_GetDesc(surface, &desc);
181 ok(SUCCEEDED(hr), "Got hr %#lx.\n", hr);
183 hr = IDirect3DSurface8_LockRect(surface, &lockedRect, &rectToLock, D3DLOCK_READONLY);
184 ok(SUCCEEDED(hr), "Got hr %#lx.\n", hr);
186 switch(desc.Format)
188 case D3DFMT_A8R8G8B8:
189 color = ((D3DCOLOR *)lockedRect.pBits)[0];
190 break;
192 default:
193 trace("Error: unknown surface format: %u.\n", desc.Format);
194 color = 0xdeadbeef;
195 break;
198 hr = IDirect3DSurface8_UnlockRect(surface);
199 ok(SUCCEEDED(hr), "Got hr %#lx.\n", hr);
201 return color;
204 static void check_rect(struct surface_readback *rb, RECT r, const char *message)
206 LONG x_coords[2][2] =
208 {r.left - 1, r.left + 1},
209 {r.right + 1, r.right - 1},
211 LONG y_coords[2][2] =
213 {r.top - 1, r.top + 1},
214 {r.bottom + 1, r.bottom - 1}
216 unsigned int i, j, x_side, y_side, color;
217 LONG x, y;
219 for (i = 0; i < 2; ++i)
221 for (j = 0; j < 2; ++j)
223 for (x_side = 0; x_side < 2; ++x_side)
225 for (y_side = 0; y_side < 2; ++y_side)
227 unsigned int expected = (x_side == 1 && y_side == 1) ? 0xffffffff : 0xff000000;
229 x = x_coords[i][x_side];
230 y = y_coords[j][y_side];
231 if (x < 0 || x >= 640 || y < 0 || y >= 480)
232 continue;
233 color = get_readback_color(rb, x, y);
234 ok(color == expected, "%s: Pixel (%ld, %ld) has color %08x, expected %08x.\n",
235 message, x, y, color, expected);
242 #define check_rt_color(a, b) check_rt_color_(__LINE__, a, b)
243 static void check_rt_color_(unsigned int line, IDirect3DSurface8 *rt, D3DCOLOR expected_color)
245 unsigned int color = 0xdeadbeef;
246 struct surface_readback rb;
247 D3DSURFACE_DESC desc;
248 unsigned int x, y;
249 HRESULT hr;
251 hr = IDirect3DSurface8_GetDesc(rt, &desc);
252 ok_(__FILE__, line)(hr == S_OK, "Failed to get surface desc, hr %#lx.\n", hr);
254 get_surface_readback(rt, &rb);
255 for (y = 0; y < desc.Height; ++y)
257 for (x = 0; x < desc.Width; ++x)
259 color = get_readback_color(&rb, x, y) & 0x00ffffff;
260 if (color != expected_color)
261 break;
263 if (color != expected_color)
264 break;
266 release_surface_readback(&rb);
267 ok_(__FILE__, line)(color == expected_color, "Got unexpected color 0x%08x.\n", color);
270 static IDirect3DDevice8 *create_device(IDirect3D8 *d3d, HWND device_window, HWND focus_window, BOOL windowed)
272 D3DPRESENT_PARAMETERS present_parameters = {0};
273 IDirect3DDevice8 *device;
275 present_parameters.Windowed = windowed;
276 present_parameters.hDeviceWindow = device_window;
277 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
278 present_parameters.BackBufferWidth = 640;
279 present_parameters.BackBufferHeight = 480;
280 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
281 present_parameters.EnableAutoDepthStencil = TRUE;
282 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
284 if (SUCCEEDED(IDirect3D8_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, focus_window,
285 D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device)))
286 return device;
288 return NULL;
291 static void test_sanity(void)
293 IDirect3DDevice8 *device;
294 unsigned int color;
295 IDirect3D8 *d3d;
296 ULONG refcount;
297 HWND window;
298 HRESULT hr;
300 window = create_window();
301 d3d = Direct3DCreate8(D3D_SDK_VERSION);
302 ok(!!d3d, "Failed to create a D3D object.\n");
303 if (!(device = create_device(d3d, window, window, TRUE)))
305 skip("Failed to create a D3D device, skipping tests.\n");
306 goto done;
309 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 1.0f, 0);
310 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
311 color = getPixelColor(device, 1, 1);
312 ok(color == 0x00ff0000, "Got unexpected color 0x%08x.\n", color);
314 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
315 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
317 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ddee, 1.0f, 0);
318 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
319 color = getPixelColor(device, 639, 479);
320 ok(color == 0x0000ddee, "Got unexpected color 0x%08x.\n", color);
322 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
323 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
325 refcount = IDirect3DDevice8_Release(device);
326 ok(!refcount, "Device has %lu references left.\n", refcount);
327 done:
328 IDirect3D8_Release(d3d);
329 DestroyWindow(window);
332 static void lighting_test(void)
334 DWORD nfvf = D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_NORMAL;
335 DWORD fvf = D3DFVF_XYZ | D3DFVF_DIFFUSE;
336 IDirect3DDevice8 *device;
337 unsigned int color, i;
338 IDirect3D8 *d3d;
339 ULONG refcount;
340 HWND window;
341 HRESULT hr;
343 static const struct
345 struct vec3 position;
346 DWORD diffuse;
348 unlitquad[] =
350 {{-1.0f, -1.0f, 0.1f}, 0xffff0000},
351 {{-1.0f, 0.0f, 0.1f}, 0xffff0000},
352 {{ 0.0f, 0.0f, 0.1f}, 0xffff0000},
353 {{ 0.0f, -1.0f, 0.1f}, 0xffff0000},
355 litquad[] =
357 {{-1.0f, 0.0f, 0.1f}, 0xff00ff00},
358 {{-1.0f, 1.0f, 0.1f}, 0xff00ff00},
359 {{ 0.0f, 1.0f, 0.1f}, 0xff00ff00},
360 {{ 0.0f, 0.0f, 0.1f}, 0xff00ff00},
362 static const struct
364 struct vec3 position;
365 struct vec3 normal;
366 DWORD diffuse;
368 unlitnquad[] =
370 {{0.0f, -1.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xff0000ff},
371 {{0.0f, 0.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xff0000ff},
372 {{1.0f, 0.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xff0000ff},
373 {{1.0f, -1.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xff0000ff},
375 litnquad[] =
377 {{0.0f, 0.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xffffff00},
378 {{0.0f, 1.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xffffff00},
379 {{1.0f, 1.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xffffff00},
380 {{1.0f, 0.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xffffff00},
382 nquad[] =
384 {{-1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
385 {{-1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
386 {{ 1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
387 {{ 1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
389 rotatedquad[] =
391 {{-10.0f, -11.0f, 11.0f}, {-1.0f, 0.0f, 0.0f}, 0xff0000ff},
392 {{-10.0f, -9.0f, 11.0f}, {-1.0f, 0.0f, 0.0f}, 0xff0000ff},
393 {{-10.0f, -9.0f, 9.0f}, {-1.0f, 0.0f, 0.0f}, 0xff0000ff},
394 {{-10.0f, -11.0f, 9.0f}, {-1.0f, 0.0f, 0.0f}, 0xff0000ff},
396 translatedquad[] =
398 {{-11.0f, -11.0f, -10.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
399 {{-11.0f, -9.0f, -10.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
400 {{ -9.0f, -9.0f, -10.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
401 {{ -9.0f, -11.0f, -10.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
403 static const WORD indices[] = {0, 1, 2, 2, 3, 0};
404 static const D3DMATRIX mat =
406 1.0f, 0.0f, 0.0f, 0.0f,
407 0.0f, 1.0f, 0.0f, 0.0f,
408 0.0f, 0.0f, 1.0f, 0.0f,
409 0.0f, 0.0f, 0.0f, 1.0f,
410 }}},
411 mat_singular =
413 1.0f, 0.0f, 1.0f, 0.0f,
414 0.0f, 1.0f, 0.0f, 0.0f,
415 1.0f, 0.0f, 1.0f, 0.0f,
416 0.0f, 0.0f, 0.5f, 1.0f,
417 }}},
418 mat_transf =
420 0.0f, 0.0f, 1.0f, 0.0f,
421 0.0f, 1.0f, 0.0f, 0.0f,
422 -1.0f, 0.0f, 0.0f, 0.0f,
423 10.f, 10.0f, 10.0f, 1.0f,
424 }}},
425 mat_nonaffine =
427 1.0f, 0.0f, 0.0f, 0.0f,
428 0.0f, 1.0f, 0.0f, 0.0f,
429 0.0f, 0.0f, 1.0f, -1.0f,
430 10.f, 10.0f, 10.0f, 0.0f,
431 }}};
432 static const struct
434 const D3DMATRIX *world_matrix;
435 const void *quad;
436 unsigned int size;
437 DWORD expected, broken;
438 const char *message;
440 tests[] =
442 {&mat, nquad, sizeof(nquad[0]), 0x000000ff, 0xdeadbeef,
443 "Lit quad with light"},
444 /* Starting around Win10 20H? this test returns 0x00000000, but only
445 * in d3d8. In ddraw and d3d9 it works like in older windows versions.
446 * The behavior is GPU independent. */
447 {&mat_singular, nquad, sizeof(nquad[0]), 0x000000ff, 0x00000000,
448 "Lit quad with singular world matrix"},
449 {&mat_transf, rotatedquad, sizeof(rotatedquad[0]), 0x000000ff, 0xdeadbeef,
450 "Lit quad with transformation matrix"},
451 {&mat_nonaffine, translatedquad, sizeof(translatedquad[0]), 0x00000000, 0xdeadbeef,
452 "Lit quad with non-affine matrix"},
455 window = create_window();
456 d3d = Direct3DCreate8(D3D_SDK_VERSION);
457 ok(!!d3d, "Failed to create a D3D object.\n");
458 if (!(device = create_device(d3d, window, window, TRUE)))
460 skip("Failed to create a D3D device, skipping tests.\n");
461 goto done;
464 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
465 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
467 hr = IDirect3DDevice8_SetTransform(device, D3DTS_WORLDMATRIX(0), &mat);
468 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
469 hr = IDirect3DDevice8_SetTransform(device, D3DTS_VIEW, &mat);
470 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
471 hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, &mat);
472 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
473 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, FALSE);
474 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
475 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, FALSE);
476 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
477 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
478 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
479 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
480 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
481 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
482 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
484 hr = IDirect3DDevice8_SetVertexShader(device, fvf);
485 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
487 hr = IDirect3DDevice8_BeginScene(device);
488 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
490 /* No lights are defined... That means, lit vertices should be entirely black. */
491 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
492 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
493 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
494 2, indices, D3DFMT_INDEX16, unlitquad, sizeof(unlitquad[0]));
495 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
497 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, TRUE);
498 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
499 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
500 2, indices, D3DFMT_INDEX16, litquad, sizeof(litquad[0]));
501 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
503 hr = IDirect3DDevice8_SetVertexShader(device, nfvf);
504 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#lx.\n", hr);
506 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
507 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
508 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
509 2, indices, D3DFMT_INDEX16, unlitnquad, sizeof(unlitnquad[0]));
510 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
512 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, TRUE);
513 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
514 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
515 2, indices, D3DFMT_INDEX16, litnquad, sizeof(litnquad[0]));
516 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
518 hr = IDirect3DDevice8_EndScene(device);
519 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
521 color = getPixelColor(device, 160, 360); /* Lower left quad - unlit without normals */
522 ok(color == 0x00ff0000, "Unlit quad without normals has color 0x%08x, expected 0x00ff0000.\n", color);
523 color = getPixelColor(device, 160, 120); /* Upper left quad - lit without normals */
524 ok(color == 0x00000000, "Lit quad without normals has color 0x%08x, expected 0x00000000.\n", color);
525 color = getPixelColor(device, 480, 360); /* Lower right quad - unlit with normals */
526 ok(color == 0x000000ff, "Unlit quad with normals has color 0x%08x, expected 0x000000ff.\n", color);
527 color = getPixelColor(device, 480, 120); /* Upper right quad - lit with normals */
528 ok(color == 0x00000000, "Lit quad with normals has color 0x%08x, expected 0x00000000.\n", color);
530 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
532 hr = IDirect3DDevice8_LightEnable(device, 0, TRUE);
533 ok(SUCCEEDED(hr), "Failed to enable light 0, hr %#lx.\n", hr);
535 for (i = 0; i < ARRAY_SIZE(tests); ++i)
537 hr = IDirect3DDevice8_SetTransform(device, D3DTS_WORLD, tests[i].world_matrix);
538 ok(SUCCEEDED(hr), "Failed to set world transform, hr %#lx.\n", hr);
540 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
541 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
543 hr = IDirect3DDevice8_BeginScene(device);
544 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
546 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
547 2, indices, D3DFMT_INDEX16, tests[i].quad, tests[i].size);
548 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
550 hr = IDirect3DDevice8_EndScene(device);
551 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
553 color = getPixelColor(device, 320, 240);
554 ok(color == tests[i].expected || broken(color == tests[i].broken),
555 "%s has color 0x%08x.\n", tests[i].message, color);
558 refcount = IDirect3DDevice8_Release(device);
559 ok(!refcount, "Device has %lu references left.\n", refcount);
560 done:
561 IDirect3D8_Release(d3d);
562 DestroyWindow(window);
565 static void test_specular_lighting(void)
567 static const unsigned int vertices_side = 5;
568 const unsigned int indices_count = (vertices_side - 1) * (vertices_side - 1) * 2 * 3;
569 static const DWORD fvf = D3DFVF_XYZ | D3DFVF_NORMAL;
570 static const D3DMATRIX mat =
572 1.0f, 0.0f, 0.0f, 0.0f,
573 0.0f, 1.0f, 0.0f, 0.0f,
574 0.0f, 0.0f, 1.0f, 0.0f,
575 0.0f, 0.0f, 0.0f, 1.0f,
576 }}};
577 static const D3DLIGHT8 directional =
579 D3DLIGHT_DIRECTIONAL,
580 {0.0f, 0.0f, 0.0f, 0.0f},
581 {1.0f, 1.0f, 1.0f, 0.0f},
582 {0.0f, 0.0f, 0.0f, 0.0f},
583 {0.0f, 0.0f, 0.0f},
584 {0.0f, 0.0f, 1.0f},
586 point =
588 D3DLIGHT_POINT,
589 {0.0f, 0.0f, 0.0f, 0.0f},
590 {1.0f, 1.0f, 1.0f, 0.0f},
591 {0.0f, 0.0f, 0.0f, 0.0f},
592 {0.0f, 0.0f, 0.0f},
593 {0.0f, 0.0f, 0.0f},
594 100.0f,
595 0.0f,
596 0.0f, 0.0f, 1.0f,
598 spot =
600 D3DLIGHT_SPOT,
601 {0.0f, 0.0f, 0.0f, 0.0f},
602 {1.0f, 1.0f, 1.0f, 0.0f},
603 {0.0f, 0.0f, 0.0f, 0.0f},
604 {0.0f, 0.0f, 0.0f},
605 {0.0f, 0.0f, 1.0f},
606 100.0f,
607 1.0f,
608 0.0f, 0.0f, 1.0f,
609 M_PI / 12.0f, M_PI / 3.0f
611 /* The chosen range value makes the test fail when using a manhattan
612 * distance metric vs the correct euclidean distance. */
613 point_range =
615 D3DLIGHT_POINT,
616 {0.0f, 0.0f, 0.0f, 0.0f},
617 {1.0f, 1.0f, 1.0f, 0.0f},
618 {0.0f, 0.0f, 0.0f, 0.0f},
619 {0.0f, 0.0f, 0.0f},
620 {0.0f, 0.0f, 0.0f},
621 1.2f,
622 0.0f,
623 0.0f, 0.0f, 1.0f,
625 point_side =
627 D3DLIGHT_POINT,
628 {0.0f, 0.0f, 0.0f, 0.0f},
629 {1.0f, 1.0f, 1.0f, 0.0f},
630 {0.0f, 0.0f, 0.0f, 0.0f},
631 {-1.1f, 0.0f, 1.1f},
632 {0.0f, 0.0f, 0.0f},
633 100.0f,
634 0.0f,
635 0.0f, 0.0f, 1.0f,
637 static const struct expected_color
639 unsigned int x, y, color;
641 expected_directional[] =
643 {160, 120, 0x00ffffff},
644 {320, 120, 0x00ffffff},
645 {480, 120, 0x00ffffff},
646 {160, 240, 0x00ffffff},
647 {320, 240, 0x00ffffff},
648 {480, 240, 0x00ffffff},
649 {160, 360, 0x00ffffff},
650 {320, 360, 0x00ffffff},
651 {480, 360, 0x00ffffff},
653 expected_directional_local[] =
655 {160, 120, 0x003c3c3c},
656 {320, 120, 0x00717171},
657 {480, 120, 0x003c3c3c},
658 {160, 240, 0x00717171},
659 {320, 240, 0x00ffffff},
660 {480, 240, 0x00717171},
661 {160, 360, 0x003c3c3c},
662 {320, 360, 0x00717171},
663 {480, 360, 0x003c3c3c},
665 expected_point[] =
667 {160, 120, 0x00282828},
668 {320, 120, 0x005a5a5a},
669 {480, 120, 0x00282828},
670 {160, 240, 0x005a5a5a},
671 {320, 240, 0x00ffffff},
672 {480, 240, 0x005a5a5a},
673 {160, 360, 0x00282828},
674 {320, 360, 0x005a5a5a},
675 {480, 360, 0x00282828},
677 expected_point_local[] =
679 {160, 120, 0x00000000},
680 {320, 120, 0x00070707},
681 {480, 120, 0x00000000},
682 {160, 240, 0x00070707},
683 {320, 240, 0x00ffffff},
684 {480, 240, 0x00070707},
685 {160, 360, 0x00000000},
686 {320, 360, 0x00070707},
687 {480, 360, 0x00000000},
689 expected_spot[] =
691 {160, 120, 0x00000000},
692 {320, 120, 0x00141414},
693 {480, 120, 0x00000000},
694 {160, 240, 0x00141414},
695 {320, 240, 0x00ffffff},
696 {480, 240, 0x00141414},
697 {160, 360, 0x00000000},
698 {320, 360, 0x00141414},
699 {480, 360, 0x00000000},
701 expected_spot_local[] =
703 {160, 120, 0x00000000},
704 {320, 120, 0x00020202},
705 {480, 120, 0x00000000},
706 {160, 240, 0x00020202},
707 {320, 240, 0x00ffffff},
708 {480, 240, 0x00020202},
709 {160, 360, 0x00000000},
710 {320, 360, 0x00020202},
711 {480, 360, 0x00000000},
713 expected_point_range[] =
715 {160, 120, 0x00000000},
716 {320, 120, 0x005a5a5a},
717 {480, 120, 0x00000000},
718 {160, 240, 0x005a5a5a},
719 {320, 240, 0x00ffffff},
720 {480, 240, 0x005a5a5a},
721 {160, 360, 0x00000000},
722 {320, 360, 0x005a5a5a},
723 {480, 360, 0x00000000},
725 expected_point_side[] =
727 {160, 120, 0x00000000},
728 {320, 120, 0x00000000},
729 {480, 120, 0x00000000},
730 {160, 240, 0x00000000},
731 {320, 240, 0x00000000},
732 {480, 240, 0x00000000},
733 {160, 360, 0x00000000},
734 {320, 360, 0x00000000},
735 {480, 360, 0x00000000},
737 expected_directional_0[] =
739 {160, 120, 0x00ffffff},
740 {320, 120, 0x00ffffff},
741 {480, 120, 0x00ffffff},
742 {160, 240, 0x00ffffff},
743 {320, 240, 0x00ffffff},
744 {480, 240, 0x00ffffff},
745 {160, 360, 0x00ffffff},
746 {320, 360, 0x00ffffff},
747 {480, 360, 0x00ffffff},
749 expected_directional_local_0[] =
751 {160, 120, 0x00ffffff},
752 {320, 120, 0x00ffffff},
753 {480, 120, 0x00ffffff},
754 {160, 240, 0x00ffffff},
755 {320, 240, 0x00ffffff},
756 {480, 240, 0x00ffffff},
757 {160, 360, 0x00ffffff},
758 {320, 360, 0x00ffffff},
759 {480, 360, 0x00ffffff},
761 expected_point_0[] =
763 {160, 120, 0x00aaaaaa},
764 {320, 120, 0x00cccccc},
765 {480, 120, 0x00aaaaaa},
766 {160, 240, 0x00cccccc},
767 {320, 240, 0x00ffffff},
768 {480, 240, 0x00cccccc},
769 {160, 360, 0x00aaaaaa},
770 {320, 360, 0x00cccccc},
771 {480, 360, 0x00aaaaaa},
773 expected_spot_0[] =
775 {160, 120, 0x00000000},
776 {320, 120, 0x002e2e2e},
777 {480, 120, 0x00000000},
778 {160, 240, 0x002e2e2e},
779 {320, 240, 0x00ffffff},
780 {480, 240, 0x002e2e2e},
781 {160, 360, 0x00000000},
782 {320, 360, 0x002e2e2e},
783 {480, 360, 0x00000000},
785 expected_point_range_0[] =
787 {160, 120, 0x00000000},
788 {320, 120, 0x00cccccc},
789 {480, 120, 0x00000000},
790 {160, 240, 0x00cccccc},
791 {320, 240, 0x00ffffff},
792 {480, 240, 0x00cccccc},
793 {160, 360, 0x00000000},
794 {320, 360, 0x00cccccc},
795 {480, 360, 0x00000000},
797 static const struct
799 const D3DLIGHT8 *light;
800 BOOL local_viewer;
801 float specular_power;
802 const struct expected_color *expected;
803 unsigned int expected_count;
805 tests[] =
807 {&directional, FALSE, 30.0f, expected_directional, ARRAY_SIZE(expected_directional)},
808 {&directional, TRUE, 30.0f, expected_directional_local, ARRAY_SIZE(expected_directional_local)},
809 {&point, FALSE, 30.0f, expected_point, ARRAY_SIZE(expected_point)},
810 {&point, TRUE, 30.0f, expected_point_local, ARRAY_SIZE(expected_point_local)},
811 {&spot, FALSE, 30.0f, expected_spot, ARRAY_SIZE(expected_spot)},
812 {&spot, TRUE, 30.0f, expected_spot_local, ARRAY_SIZE(expected_spot_local)},
813 {&point_range, FALSE, 30.0f, expected_point_range, ARRAY_SIZE(expected_point_range)},
814 {&point_side, TRUE, 0.0f, expected_point_side, ARRAY_SIZE(expected_point_side)},
815 {&directional, FALSE, 0.0f, expected_directional_0, ARRAY_SIZE(expected_directional_0)},
816 {&directional, TRUE, 0.0f, expected_directional_local_0, ARRAY_SIZE(expected_directional_local_0)},
817 {&point, FALSE, 0.0f, expected_point_0, ARRAY_SIZE(expected_point_0)},
818 {&point, TRUE, 0.0f, expected_point_0, ARRAY_SIZE(expected_point_0)},
819 {&spot, FALSE, 0.0f, expected_spot_0, ARRAY_SIZE(expected_spot_0)},
820 {&spot, TRUE, 0.0f, expected_spot_0, ARRAY_SIZE(expected_spot_0)},
821 {&point_range, FALSE, 0.0f, expected_point_range_0, ARRAY_SIZE(expected_point_range_0)},
823 unsigned int color, i, j, x, y;
824 IDirect3DDevice8 *device;
825 D3DMATERIAL8 material;
826 IDirect3D8 *d3d;
827 ULONG refcount;
828 HWND window;
829 HRESULT hr;
830 struct
832 struct vec3 position;
833 struct vec3 normal;
834 } *quad;
835 WORD *indices;
837 quad = HeapAlloc(GetProcessHeap(), 0, vertices_side * vertices_side * sizeof(*quad));
838 indices = HeapAlloc(GetProcessHeap(), 0, indices_count * sizeof(*indices));
839 for (i = 0, y = 0; y < vertices_side; ++y)
841 for (x = 0; x < vertices_side; ++x)
843 quad[i].position.x = x * 2.0f / (vertices_side - 1) - 1.0f;
844 quad[i].position.y = y * 2.0f / (vertices_side - 1) - 1.0f;
845 quad[i].position.z = 1.0f;
846 quad[i].normal.x = 0.0f;
847 quad[i].normal.y = 0.0f;
848 quad[i++].normal.z = -1.0f;
851 for (i = 0, y = 0; y < (vertices_side - 1); ++y)
853 for (x = 0; x < (vertices_side - 1); ++x)
855 indices[i++] = y * vertices_side + x + 1;
856 indices[i++] = y * vertices_side + x;
857 indices[i++] = (y + 1) * vertices_side + x;
858 indices[i++] = y * vertices_side + x + 1;
859 indices[i++] = (y + 1) * vertices_side + x;
860 indices[i++] = (y + 1) * vertices_side + x + 1;
864 window = create_window();
865 d3d = Direct3DCreate8(D3D_SDK_VERSION);
866 ok(!!d3d, "Failed to create a D3D object.\n");
867 if (!(device = create_device(d3d, window, window, TRUE)))
869 skip("Failed to create a D3D device, skipping tests.\n");
870 goto done;
873 hr = IDirect3DDevice8_SetTransform(device, D3DTS_WORLD, &mat);
874 ok(SUCCEEDED(hr), "Failed to set world transform, hr %#lx.\n", hr);
875 hr = IDirect3DDevice8_SetTransform(device, D3DTS_VIEW, &mat);
876 ok(SUCCEEDED(hr), "Failed to set view transform, hr %#lx.\n", hr);
877 hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, &mat);
878 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#lx.\n", hr);
879 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, FALSE);
880 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#lx.\n", hr);
881 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, FALSE);
882 ok(SUCCEEDED(hr), "Failed to disable z test, hr %#lx.\n", hr);
883 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
884 ok(SUCCEEDED(hr), "Failed to disable fog, hr %#lx.\n", hr);
886 hr = IDirect3DDevice8_SetVertexShader(device, fvf);
887 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr);
889 hr = IDirect3DDevice8_LightEnable(device, 0, TRUE);
890 ok(SUCCEEDED(hr), "Failed to enable light 0, hr %#lx.\n", hr);
891 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SPECULARENABLE, TRUE);
892 ok(SUCCEEDED(hr), "Failed to enable specular lighting, hr %#lx.\n", hr);
894 for (i = 0; i < ARRAY_SIZE(tests); ++i)
896 hr = IDirect3DDevice8_SetLight(device, 0, tests[i].light);
897 ok(SUCCEEDED(hr), "Failed to set light parameters, hr %#lx.\n", hr);
899 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LOCALVIEWER, tests[i].local_viewer);
900 ok(SUCCEEDED(hr), "Failed to set local viewer state, hr %#lx.\n", hr);
902 memset(&material, 0, sizeof(material));
903 material.Specular.r = 1.0f;
904 material.Specular.g = 1.0f;
905 material.Specular.b = 1.0f;
906 material.Specular.a = 1.0f;
907 material.Power = tests[i].specular_power;
908 hr = IDirect3DDevice8_SetMaterial(device, &material);
909 ok(SUCCEEDED(hr), "Failed to set material, hr %#lx.\n", hr);
911 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
912 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
914 hr = IDirect3DDevice8_BeginScene(device);
915 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
917 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST,
918 0, vertices_side * vertices_side, indices_count / 3, indices,
919 D3DFMT_INDEX16, quad, sizeof(quad[0]));
920 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
922 hr = IDirect3DDevice8_EndScene(device);
923 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
925 for (j = 0; j < tests[i].expected_count; ++j)
927 color = getPixelColor(device, tests[i].expected[j].x, tests[i].expected[j].y);
928 ok(color_match(color, tests[i].expected[j].color, 1),
929 "Expected color 0x%08x at location (%u, %u), got 0x%08x, case %u.\n",
930 tests[i].expected[j].color, tests[i].expected[j].x,
931 tests[i].expected[j].y, color, i);
935 refcount = IDirect3DDevice8_Release(device);
936 ok(!refcount, "Device has %lu references left.\n", refcount);
937 done:
938 IDirect3D8_Release(d3d);
939 DestroyWindow(window);
940 HeapFree(GetProcessHeap(), 0, indices);
941 HeapFree(GetProcessHeap(), 0, quad);
944 static void clear_test(void)
946 /* Tests the correctness of clearing parameters */
947 D3DRECT rect_negneg, rect[2];
948 IDirect3DDevice8 *device;
949 unsigned int color;
950 IDirect3D8 *d3d;
951 ULONG refcount;
952 HWND window;
953 HRESULT hr;
955 window = create_window();
956 d3d = Direct3DCreate8(D3D_SDK_VERSION);
957 ok(!!d3d, "Failed to create a D3D object.\n");
958 if (!(device = create_device(d3d, window, window, TRUE)))
960 skip("Failed to create a D3D device, skipping tests.\n");
961 goto done;
964 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
965 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
967 /* Positive x, negative y */
968 rect[0].x1 = 0;
969 rect[0].y1 = 480;
970 rect[0].x2 = 320;
971 rect[0].y2 = 240;
973 /* Positive x, positive y */
974 rect[1].x1 = 0;
975 rect[1].y1 = 0;
976 rect[1].x2 = 320;
977 rect[1].y2 = 240;
978 /* Clear 2 rectangles with one call. Shows that a positive value is returned, but the negative rectangle
979 * is ignored, the positive is still cleared afterwards
981 hr = IDirect3DDevice8_Clear(device, 2, rect, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
982 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
984 /* negative x, negative y */
985 rect_negneg.x1 = 640;
986 rect_negneg.y1 = 240;
987 rect_negneg.x2 = 320;
988 rect_negneg.y2 = 0;
989 hr = IDirect3DDevice8_Clear(device, 1, &rect_negneg, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
990 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
992 color = getPixelColor(device, 160, 360); /* lower left quad */
993 ok(color == 0x00ffffff, "Clear rectangle 3(pos, neg) has color %08x\n", color);
994 color = getPixelColor(device, 160, 120); /* upper left quad */
995 ok(color == 0x00ff0000, "Clear rectangle 1(pos, pos) has color %08x\n", color);
996 color = getPixelColor(device, 480, 360); /* lower right quad */
997 ok(color == 0x00ffffff, "Clear rectangle 4(NULL) has color %08x\n", color);
998 color = getPixelColor(device, 480, 120); /* upper right quad */
999 ok(color == 0x00ffffff, "Clear rectangle 4(neg, neg) has color %08x\n", color);
1001 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
1003 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
1004 ok(SUCCEEDED(hr), "Got hr %#lx.\n", hr);
1006 rect[0].x1 = 0;
1007 rect[0].y1 = 0;
1008 rect[0].x2 = 640;
1009 rect[0].y2 = 480;
1010 hr = IDirect3DDevice8_Clear(device, 0, rect, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1011 ok(SUCCEEDED(hr), "Got hr %#lx.\n", hr);
1013 color = getPixelColor(device, 320, 240);
1014 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff), 1),
1015 "Clear with count = 0, rect != NULL has color %#08x\n", color);
1017 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
1019 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
1020 ok(SUCCEEDED(hr), "Got hr %#lx.\n", hr);
1021 hr = IDirect3DDevice8_Clear(device, 1, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
1022 ok(SUCCEEDED(hr), "Got hr %#lx.\n", hr);
1024 color = getPixelColor(device, 320, 240);
1025 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
1026 "Clear with count = 1, rect = NULL has color %#08x\n", color);
1028 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
1030 refcount = IDirect3DDevice8_Release(device);
1031 ok(!refcount, "Device has %lu references left.\n", refcount);
1032 done:
1033 IDirect3D8_Release(d3d);
1034 DestroyWindow(window);
1037 static void fog_test(void)
1039 float start = 0.0f, end = 1.0f;
1040 IDirect3DDevice8 *device;
1041 unsigned int color;
1042 IDirect3D8 *d3d;
1043 ULONG refcount;
1044 D3DCAPS8 caps;
1045 HWND window;
1046 HRESULT hr;
1048 /* Gets full z based fog with linear fog, no fog with specular color. */
1049 static const struct
1051 float x, y, z;
1052 D3DCOLOR diffuse;
1053 D3DCOLOR specular;
1055 untransformed_1[] =
1057 {-1.0f, -1.0f, 0.1f, 0xffff0000, 0xff000000},
1058 {-1.0f, 0.0f, 0.1f, 0xffff0000, 0xff000000},
1059 { 0.0f, 0.0f, 0.1f, 0xffff0000, 0xff000000},
1060 { 0.0f, -1.0f, 0.1f, 0xffff0000, 0xff000000},
1062 /* Ok, I am too lazy to deal with transform matrices. */
1063 untransformed_2[] =
1065 {-1.0f, 0.0f, 1.0f, 0xffff0000, 0xff000000},
1066 {-1.0f, 1.0f, 1.0f, 0xffff0000, 0xff000000},
1067 { 0.0f, 1.0f, 1.0f, 0xffff0000, 0xff000000},
1068 { 0.0f, 0.0f, 1.0f, 0xffff0000, 0xff000000},
1070 far_quad1[] =
1072 {-1.0f, -1.0f, 0.5f, 0xffff0000, 0xff000000},
1073 {-1.0f, 0.0f, 0.5f, 0xffff0000, 0xff000000},
1074 { 0.0f, 0.0f, 0.5f, 0xffff0000, 0xff000000},
1075 { 0.0f, -1.0f, 0.5f, 0xffff0000, 0xff000000},
1077 far_quad2[] =
1079 {-1.0f, 0.0f, 1.5f, 0xffff0000, 0xff000000},
1080 {-1.0f, 1.0f, 1.5f, 0xffff0000, 0xff000000},
1081 { 0.0f, 1.0f, 1.5f, 0xffff0000, 0xff000000},
1082 { 0.0f, 0.0f, 1.5f, 0xffff0000, 0xff000000},
1085 /* Untransformed ones. Give them a different diffuse color to make the
1086 * test look nicer. It also makes making sure that they are drawn
1087 * correctly easier. */
1088 static const struct
1090 float x, y, z, rhw;
1091 D3DCOLOR diffuse;
1092 D3DCOLOR specular;
1094 transformed_1[] =
1096 {320.0f, 0.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
1097 {640.0f, 0.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
1098 {640.0f, 240.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
1099 {320.0f, 240.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
1101 transformed_2[] =
1103 {320.0f, 240.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
1104 {640.0f, 240.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
1105 {640.0f, 480.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
1106 {320.0f, 480.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
1108 static const D3DMATRIX ident_mat =
1110 1.0f, 0.0f, 0.0f, 0.0f,
1111 0.0f, 1.0f, 0.0f, 0.0f,
1112 0.0f, 0.0f, 1.0f, 0.0f,
1113 0.0f, 0.0f, 0.0f, 1.0f,
1114 }}};
1115 static const D3DMATRIX world_mat1 =
1117 1.0f, 0.0f, 0.0f, 0.0f,
1118 0.0f, 1.0f, 0.0f, 0.0f,
1119 0.0f, 0.0f, 1.0f, 0.0f,
1120 0.0f, 0.0f, -0.5f, 1.0f,
1121 }}};
1122 static const D3DMATRIX world_mat2 =
1124 1.0f, 0.0f, 0.0f, 0.0f,
1125 0.0f, 1.0f, 0.0f, 0.0f,
1126 0.0f, 0.0f, 1.0f, 0.0f,
1127 0.0f, 0.0f, 1.0f, 1.0f,
1128 }}};
1129 static const D3DMATRIX proj_mat =
1131 1.0f, 0.0f, 0.0f, 0.0f,
1132 0.0f, 1.0f, 0.0f, 0.0f,
1133 0.0f, 0.0f, 1.0f, 0.0f,
1134 0.0f, 0.0f, -1.0f, 1.0f,
1135 }}};
1136 static const WORD Indices[] = {0, 1, 2, 2, 3, 0};
1138 window = create_window();
1139 d3d = Direct3DCreate8(D3D_SDK_VERSION);
1140 ok(!!d3d, "Failed to create a D3D object.\n");
1141 if (!(device = create_device(d3d, window, window, TRUE)))
1143 skip("Failed to create a D3D device, skipping tests.\n");
1144 goto done;
1147 memset(&caps, 0, sizeof(caps));
1148 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
1149 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
1150 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1151 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
1153 /* Setup initial states: No lighting, fog on, fog color */
1154 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, FALSE);
1155 ok(SUCCEEDED(hr), "Failed to disable D3DRS_ZENABLE, hr %#lx.\n", hr);
1156 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1157 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
1158 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
1159 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
1160 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
1161 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
1162 /* Some of the tests seem to depend on the projection matrix explicitly
1163 * being set to an identity matrix, even though that's the default.
1164 * (AMD Radeon HD 6310, Windows 7) */
1165 hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, &ident_mat);
1166 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#lx.\n", hr);
1168 /* First test: Both table fog and vertex fog off */
1169 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1170 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
1171 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
1172 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
1174 /* Start = 0, end = 1. Should be default, but set them */
1175 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1176 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
1177 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1178 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
1180 hr = IDirect3DDevice8_BeginScene(device);
1181 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
1183 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1184 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#lx.\n", hr);
1185 /* Untransformed, vertex fog = NONE, table fog = NONE:
1186 * Read the fog weighting from the specular color. */
1187 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1188 2 /* PrimCount */, Indices, D3DFMT_INDEX16, untransformed_1, sizeof(untransformed_1[0]));
1189 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
1191 /* This makes it use the Z value. */
1192 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1193 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
1194 /* Untransformed, vertex fog != none (or table fog != none):
1195 * Use the Z value as input into the equation. */
1196 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1197 2 /* PrimCount */, Indices, D3DFMT_INDEX16, untransformed_2, sizeof(untransformed_2[0]));
1198 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
1200 /* Transformed vertices. */
1201 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1202 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#lx.\n", hr);
1203 /* Transformed, vertex fog != NONE, pixel fog == NONE:
1204 * Use specular color alpha component. */
1205 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1206 2 /* PrimCount */, Indices, D3DFMT_INDEX16, transformed_1, sizeof(transformed_1[0]));
1207 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
1209 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
1210 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
1211 /* Transformed, table fog != none, vertex anything:
1212 * Use Z value as input to the fog equation. */
1213 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1214 2 /* PrimCount */, Indices, D3DFMT_INDEX16, transformed_2, sizeof(transformed_2[0]));
1215 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
1217 hr = IDirect3DDevice8_EndScene(device);
1218 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
1220 color = getPixelColor(device, 160, 360);
1221 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xFF, 0x00, 0x00), 1),
1222 "Untransformed vertex with no table or vertex fog has color %08x\n", color);
1223 color = getPixelColor(device, 160, 120);
1224 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xFF, 0x00), 1),
1225 "Untransformed vertex with linear vertex fog has color %08x\n", color);
1226 color = getPixelColor(device, 480, 120);
1227 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xFF, 0xFF, 0x00), 1),
1228 "Transformed vertex with linear vertex fog has color %08x\n", color);
1229 color = getPixelColor(device, 480, 360);
1230 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xFF, 0x00), 1),
1231 "Transformed vertex with linear table fog has color %08x\n", color);
1233 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
1235 if (caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)
1237 /* A simple fog + non-identity world matrix test */
1238 hr = IDirect3DDevice8_SetTransform(device, D3DTS_WORLDMATRIX(0), &world_mat1);
1239 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
1241 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
1242 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
1243 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
1244 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
1246 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1247 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
1249 hr = IDirect3DDevice8_BeginScene(device);
1250 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
1251 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1252 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#lx.\n", hr);
1253 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
1254 2, Indices, D3DFMT_INDEX16, far_quad1, sizeof(far_quad1[0]));
1255 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
1256 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
1257 2, Indices, D3DFMT_INDEX16, far_quad2, sizeof(far_quad2[0]));
1258 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
1259 hr = IDirect3DDevice8_EndScene(device);
1260 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
1262 color = getPixelColor(device, 160, 360);
1263 ok(color_match(color, 0x00ff0000, 4), "Unfogged quad has color %08x\n", color);
1264 color = getPixelColor(device, 160, 120);
1265 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
1266 "Fogged out quad has color %08x\n", color);
1268 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
1270 /* Test fog behavior with an orthogonal (but not identity) projection matrix */
1271 hr = IDirect3DDevice8_SetTransform(device, D3DTS_WORLDMATRIX(0), &world_mat2);
1272 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
1273 hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, &proj_mat);
1274 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
1276 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1277 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
1279 hr = IDirect3DDevice8_BeginScene(device);
1280 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
1281 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1282 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#lx.\n", hr);
1283 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
1284 2, Indices, D3DFMT_INDEX16, untransformed_1, sizeof(untransformed_1[0]));
1285 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
1286 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
1287 2, Indices, D3DFMT_INDEX16, untransformed_2, sizeof(untransformed_2[0]));
1288 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
1289 hr = IDirect3DDevice8_EndScene(device);
1290 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
1292 color = getPixelColor(device, 160, 360);
1293 ok(color_match(color, 0x00e51900, 4), "Partially fogged quad has color %08x\n", color);
1294 color = getPixelColor(device, 160, 120);
1295 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
1296 "Fogged out quad has color %08x\n", color);
1298 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
1300 else
1302 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping some fog tests\n");
1305 refcount = IDirect3DDevice8_Release(device);
1306 ok(!refcount, "Device has %lu references left.\n", refcount);
1307 done:
1308 IDirect3D8_Release(d3d);
1309 DestroyWindow(window);
1312 /* This tests fog in combination with shaders.
1313 * What's tested: linear fog (vertex and table) with pixel shader
1314 * linear table fog with non foggy vertex shader
1315 * vertex fog with foggy vertex shader, non-linear
1316 * fog with shader, non-linear fog with foggy shader,
1317 * linear table fog with foggy shader */
1318 static void fog_with_shader_test(void)
1320 /* Fill the null-shader entry with the FVF (SetVertexShader is "overloaded" on d3d8...) */
1321 DWORD vertex_shader[3] = {D3DFVF_XYZ | D3DFVF_DIFFUSE, 0, 0};
1322 DWORD pixel_shader[2] = {0, 0};
1323 IDirect3DDevice8 *device;
1324 unsigned int color, i, j;
1325 IDirect3D8 *d3d;
1326 ULONG refcount;
1327 D3DCAPS8 caps;
1328 HWND window;
1329 HRESULT hr;
1330 union
1332 float f;
1333 DWORD i;
1334 } start, end;
1336 /* Basic vertex shader without fog computation ("non foggy") */
1337 static const DWORD vertex_shader_code1[] =
1339 0xfffe0100, /* vs.1.0 */
1340 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1341 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
1342 0x0000ffff
1344 /* Basic vertex shader with reversed fog computation ("foggy") */
1345 static const DWORD vertex_shader_code2[] =
1347 0xfffe0100, /* vs.1.0 */
1348 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1349 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
1350 0x00000002, 0x800f0000, 0x90aa0000, 0xa0aa0000, /* add r0, v0.z, c0.z */
1351 0x00000005, 0xc00f0001, 0x80000000, 0xa0000000, /* mul oFog, r0.x, c0.x */
1352 0x0000ffff
1354 /* Basic pixel shader */
1355 static const DWORD pixel_shader_code[] =
1357 0xffff0101, /* ps_1_1 */
1358 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
1359 0x0000ffff
1361 static struct
1363 struct vec3 position;
1364 DWORD diffuse;
1366 quad[] =
1368 {{-1.0f, -1.0f, 0.0f}, 0xffff0000},
1369 {{-1.0f, 1.0f, 0.0f}, 0xffff0000},
1370 {{ 1.0f, -1.0f, 0.0f}, 0xffff0000},
1371 {{ 1.0f, 1.0f, 0.0f}, 0xffff0000},
1373 static const DWORD decl[] =
1375 D3DVSD_STREAM(0),
1376 D3DVSD_REG(0, D3DVSDT_FLOAT3), /* position, v0 */
1377 D3DVSD_REG(1, D3DVSDT_D3DCOLOR), /* diffuse color, v1 */
1378 D3DVSD_END()
1380 static const float vs_constant[4] = {-1.25f, 0.0f, -0.9f, 0.0f};
1381 /* This reference data was collected on a nVidia GeForce 7600GS
1382 * driver version 84.19 DirectX version 9.0c on Windows XP */
1383 static const struct test_data_t
1385 int vshader;
1386 int pshader;
1387 D3DFOGMODE vfog;
1388 D3DFOGMODE tfog;
1389 BOOL uninitialized_reg;
1390 unsigned int color[11];
1392 test_data[] =
1394 /* Only pixel shader */
1395 {0, 1, D3DFOG_NONE, D3DFOG_LINEAR, FALSE,
1396 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1397 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1398 {0, 1, D3DFOG_EXP, D3DFOG_LINEAR, FALSE,
1399 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1400 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1401 {0, 1, D3DFOG_EXP2, D3DFOG_LINEAR, FALSE,
1402 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1403 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1404 {0, 1, D3DFOG_LINEAR, D3DFOG_NONE, FALSE,
1405 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1406 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1407 {0, 1, D3DFOG_LINEAR, D3DFOG_LINEAR, FALSE,
1408 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1409 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1411 /* Vertex shader */
1412 {1, 0, D3DFOG_NONE, D3DFOG_NONE, TRUE,
1413 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1414 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1415 {1, 0, D3DFOG_NONE, D3DFOG_LINEAR, FALSE,
1416 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1417 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1418 {1, 0, D3DFOG_EXP, D3DFOG_LINEAR, FALSE,
1419 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1420 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1422 {1, 0, D3DFOG_EXP2, D3DFOG_LINEAR, FALSE,
1423 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1424 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1425 {1, 0, D3DFOG_LINEAR, D3DFOG_LINEAR, FALSE,
1426 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1427 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1429 /* Vertex shader and pixel shader */
1430 /* The next 4 tests would read the fog coord output, but it isn't available.
1431 * The result is a fully fogged quad, no matter what the Z coord is. */
1432 {1, 1, D3DFOG_NONE, D3DFOG_NONE, TRUE,
1433 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1434 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1435 {1, 1, D3DFOG_LINEAR, D3DFOG_NONE, TRUE,
1436 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1437 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1438 {1, 1, D3DFOG_EXP, D3DFOG_NONE, TRUE,
1439 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1440 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1441 {1, 1, D3DFOG_EXP2, D3DFOG_NONE, TRUE,
1442 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1443 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1445 /* These use the Z coordinate with linear table fog */
1446 {1, 1, D3DFOG_NONE, D3DFOG_LINEAR, FALSE,
1447 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1448 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1449 {1, 1, D3DFOG_EXP, D3DFOG_LINEAR, FALSE,
1450 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1451 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1452 {1, 1, D3DFOG_EXP2, D3DFOG_LINEAR, FALSE,
1453 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1454 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1455 {1, 1, D3DFOG_LINEAR, D3DFOG_LINEAR, FALSE,
1456 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1457 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1459 /* Non-linear table fog without fog coord */
1460 {1, 1, D3DFOG_NONE, D3DFOG_EXP, FALSE,
1461 {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
1462 0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
1463 {1, 1, D3DFOG_NONE, D3DFOG_EXP2, FALSE,
1464 {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
1465 0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
1467 /* These tests fail on older Nvidia drivers */
1468 /* Foggy vertex shader */
1469 {2, 0, D3DFOG_NONE, D3DFOG_NONE, FALSE,
1470 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1471 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1472 {2, 0, D3DFOG_EXP, D3DFOG_NONE, FALSE,
1473 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1474 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1475 {2, 0, D3DFOG_EXP2, D3DFOG_NONE, FALSE,
1476 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1477 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1478 {2, 0, D3DFOG_LINEAR, D3DFOG_NONE, FALSE,
1479 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1480 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1482 /* Foggy vertex shader and pixel shader. First 4 tests with vertex fog,
1483 * all using the fixed fog-coord linear fog */
1484 {2, 1, D3DFOG_NONE, D3DFOG_NONE, FALSE,
1485 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1486 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1487 {2, 1, D3DFOG_EXP, D3DFOG_NONE, FALSE,
1488 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1489 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1490 {2, 1, D3DFOG_EXP2, D3DFOG_NONE, FALSE,
1491 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1492 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1493 {2, 1, D3DFOG_LINEAR, D3DFOG_NONE, FALSE,
1494 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1495 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1497 /* These use table fog. Here the shader-provided fog coordinate is
1498 * ignored and the z coordinate used instead */
1499 {2, 1, D3DFOG_NONE, D3DFOG_EXP, FALSE,
1500 {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
1501 0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
1502 {2, 1, D3DFOG_NONE, D3DFOG_EXP2, FALSE,
1503 {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
1504 0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
1505 {2, 1, D3DFOG_NONE, D3DFOG_LINEAR, FALSE,
1506 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1507 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1509 static const D3DMATRIX identity =
1511 1.0f, 0.0f, 0.0f, 0.0f,
1512 0.0f, 1.0f, 0.0f, 0.0f,
1513 0.0f, 0.0f, 1.0f, 0.0f,
1514 0.0f, 0.0f, 0.0f, 1.0f,
1515 }}};
1517 window = create_window();
1518 d3d = Direct3DCreate8(D3D_SDK_VERSION);
1519 ok(!!d3d, "Failed to create a D3D object.\n");
1520 if (!(device = create_device(d3d, window, window, TRUE)))
1522 skip("Failed to create a D3D device, skipping tests.\n");
1523 goto done;
1526 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
1527 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
1528 if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1) || caps.PixelShaderVersion < D3DPS_VERSION(1, 1))
1530 skip("No vs_1_1 / ps_1_1 support, skipping tests.\n");
1531 IDirect3DDevice8_Release(device);
1532 goto done;
1535 /* NOTE: changing these values will not affect the tests with foggy vertex
1536 * shader, as the values are hardcoded in the shader constant. */
1537 start.f = 0.1f;
1538 end.f = 0.9f;
1540 /* Some of the tests seem to depend on the projection matrix explicitly
1541 * being set to an identity matrix, even though that's the default.
1542 * (AMD Radeon HD 6310, Windows 7) */
1543 hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, &identity);
1544 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#lx.\n", hr);
1546 hr = IDirect3DDevice8_CreateVertexShader(device, decl, vertex_shader_code1, &vertex_shader[1], 0);
1547 ok(SUCCEEDED(hr), "Got hr %#lx.\n", hr);
1548 hr = IDirect3DDevice8_CreateVertexShader(device, decl, vertex_shader_code2, &vertex_shader[2], 0);
1549 ok(SUCCEEDED(hr), "Got hr %#lx.\n", hr);
1550 hr = IDirect3DDevice8_CreatePixelShader(device, pixel_shader_code, &pixel_shader[1]);
1551 ok(SUCCEEDED(hr), "Got hr %#lx.\n", hr);
1553 /* Set shader constant value */
1554 hr = IDirect3DDevice8_SetVertexShader(device, vertex_shader[2]);
1555 ok(SUCCEEDED(hr), "Got hr %#lx.\n", hr);
1556 hr = IDirect3DDevice8_SetVertexShaderConstant(device, 0, vs_constant, 1);
1557 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
1559 /* Setup initial states: No lighting, fog on, fog color */
1560 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1561 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
1562 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
1563 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
1564 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
1565 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
1567 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1568 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
1569 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
1570 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
1572 /* Use fogtart = 0.1 and end = 0.9 to test behavior outside the fog transition phase, too */
1573 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGSTART, start.i);
1574 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
1575 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGEND, end.i);
1576 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
1578 for (i = 0; i < ARRAY_SIZE(test_data); ++i)
1580 hr = IDirect3DDevice8_SetVertexShader(device, vertex_shader[test_data[i].vshader]);
1581 ok(SUCCEEDED(hr), "Got hr %#lx.\n", hr);
1582 hr = IDirect3DDevice8_SetPixelShader(device, pixel_shader[test_data[i].pshader]);
1583 ok(SUCCEEDED(hr), "Got hr %#lx.\n", hr);
1584 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGVERTEXMODE, test_data[i].vfog);
1585 ok( hr == D3D_OK, "Got hr %#lx.\n", hr);
1586 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGTABLEMODE, test_data[i].tfog);
1587 ok( hr == D3D_OK, "Got hr %#lx.\n", hr);
1589 for(j = 0; j < 11; ++j)
1591 /* Don't use the whole zrange to prevent rounding errors */
1592 quad[0].position.z = 0.001f + j / 10.02f;
1593 quad[1].position.z = 0.001f + j / 10.02f;
1594 quad[2].position.z = 0.001f + j / 10.02f;
1595 quad[3].position.z = 0.001f + j / 10.02f;
1597 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff00ff, 1.0f, 0);
1598 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
1600 hr = IDirect3DDevice8_BeginScene(device);
1601 ok( hr == D3D_OK, "Got hr %#lx.\n", hr);
1603 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1604 ok(SUCCEEDED(hr), "Got hr %#lx.\n", hr);
1606 hr = IDirect3DDevice8_EndScene(device);
1607 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
1609 /* As the red and green component are the result of blending use 5% tolerance on the expected value */
1610 color = getPixelColor(device, 128, 240);
1611 ok(color_match(color, test_data[i].color[j], 13) || broken(test_data[i].uninitialized_reg),
1612 "fog vs%i ps%i fvm%i ftm%i %d: got color %08x, expected %08x +-5%%\n",
1613 test_data[i].vshader, test_data[i].pshader,
1614 test_data[i].vfog, test_data[i].tfog, j, color, test_data[i].color[j]);
1617 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
1619 IDirect3DDevice8_DeleteVertexShader(device, vertex_shader[1]);
1620 IDirect3DDevice8_DeleteVertexShader(device, vertex_shader[2]);
1621 IDirect3DDevice8_DeleteVertexShader(device, pixel_shader[1]);
1622 refcount = IDirect3DDevice8_Release(device);
1623 ok(!refcount, "Device has %lu references left.\n", refcount);
1624 done:
1625 IDirect3D8_Release(d3d);
1626 DestroyWindow(window);
1629 static void cnd_test(void)
1631 DWORD shader_11_coissue_2, shader_12_coissue_2, shader_13_coissue_2, shader_14_coissue_2;
1632 DWORD shader_11_coissue, shader_12_coissue, shader_13_coissue, shader_14_coissue;
1633 DWORD shader_11, shader_12, shader_13, shader_14;
1634 IDirect3DDevice8 *device;
1635 unsigned int color;
1636 IDirect3D8 *d3d;
1637 ULONG refcount;
1638 D3DCAPS8 caps;
1639 HWND window;
1640 HRESULT hr;
1642 /* ps 1.x shaders are rather picky with writemasks and source swizzles.
1643 * The dp3 is used to copy r0.r to all components of r1, then copy r1.a to
1644 * r0.a. Essentially it does a mov r0.a, r0.r, which isn't allowed as-is
1645 * in 1.x pixel shaders. */
1646 static const DWORD shader_code_11[] =
1648 0xffff0101, /* ps_1_1 */
1649 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
1650 0x00000040, 0xb00f0000, /* texcoord t0 */
1651 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
1652 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3 r1, r0, c0 */
1653 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
1654 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
1655 0x0000ffff /* end */
1657 static const DWORD shader_code_12[] =
1659 0xffff0102, /* ps_1_2 */
1660 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
1661 0x00000040, 0xb00f0000, /* texcoord t0 */
1662 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
1663 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3 r1, r0, c0 */
1664 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
1665 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
1666 0x0000ffff /* end */
1668 static const DWORD shader_code_13[] =
1670 0xffff0103, /* ps_1_3 */
1671 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
1672 0x00000040, 0xb00f0000, /* texcoord t0 */
1673 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
1674 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3, r1, r0, c0 */
1675 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
1676 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
1677 0x0000ffff /* end */
1679 static const DWORD shader_code_14[] =
1681 0xffff0104, /* ps_1_3 */
1682 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
1683 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0, t0 */
1684 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
1685 0x00000050, 0x800f0000, 0x80e40000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0, c1, c2 */
1686 0x0000ffff /* end */
1689 /* Special fun: The coissue flag on cnd: Apparently cnd always selects the 2nd source,
1690 * as if the src0 comparison against 0.5 always evaluates to true. The coissue flag isn't
1691 * set by the compiler, it was added manually after compilation. Note that the COISSUE
1692 * flag on a color(.xyz) operation is only allowed after an alpha operation. DirectX doesn't
1693 * have proper docs, but GL_ATI_fragment_shader explains the pairing of color and alpha ops
1694 * well enough.
1696 * The shader attempts to test the range [-1;1] against coissued cnd, which is a bit tricky.
1697 * The input from t0 is [0;1]. 0.5 is subtracted, then we have to multiply with 2. Since
1698 * constants are clamped to [-1;1], a 2.0 is constructed by adding c0.r(=1.0) to c0.r into r1.r,
1699 * then r1(2.0, 0.0, 0.0, 0.0) is passed to dp3(explained above).
1701 static const DWORD shader_code_11_coissue[] =
1703 0xffff0101, /* ps_1_1 */
1704 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
1705 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
1706 0x00000040, 0xb00f0000, /* texcoord t0 */
1707 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
1708 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
1709 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
1710 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
1711 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
1712 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.xyz, r0.a, c1, c2*/
1713 0x0000ffff /* end */
1715 static const DWORD shader_code_11_coissue_2[] =
1717 0xffff0101, /* ps_1_1 */
1718 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
1719 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
1720 0x00000040, 0xb00f0000, /* texcoord t0 */
1721 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
1722 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
1723 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
1724 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
1725 0x00000001, 0x800f0000, 0x80e40001, /* mov r0, r1 */
1726 0x00000001, 0x80070000, 0x80ff0001, /* mov r0.xyz, r1.a */
1727 0x40000050, 0x80080000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.a, r0.a, c1, c2 */
1728 0x00000001, 0x80070000, 0x80ff0000, /* mov r0.xyz, r0.a */
1729 0x0000ffff /* end */
1731 static const DWORD shader_code_12_coissue[] =
1733 0xffff0102, /* ps_1_2 */
1734 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
1735 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
1736 0x00000040, 0xb00f0000, /* texcoord t0 */
1737 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
1738 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
1739 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
1740 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
1741 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
1742 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.xyz, r0.a, c1, c2*/
1743 0x0000ffff /* end */
1745 static const DWORD shader_code_12_coissue_2[] =
1747 0xffff0102, /* ps_1_2 */
1748 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
1749 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
1750 0x00000040, 0xb00f0000, /* texcoord t0 */
1751 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
1752 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
1753 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
1754 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
1755 0x00000001, 0x800f0000, 0x80e40001, /* mov r0, r1 */
1756 0x00000001, 0x80070000, 0x80ff0001, /* mov r0.xyz, r1.a */
1757 0x40000050, 0x80080000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.a, r0.a, c1, c2 */
1758 0x00000001, 0x80070000, 0x80ff0000, /* mov r0.xyz, r0.a */
1759 0x0000ffff /* end */
1761 static const DWORD shader_code_13_coissue[] =
1763 0xffff0103, /* ps_1_3 */
1764 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
1765 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
1766 0x00000040, 0xb00f0000, /* texcoord t0 */
1767 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
1768 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
1769 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
1770 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
1771 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
1772 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.xyz, r0.a, c1, c2*/
1773 0x0000ffff /* end */
1775 static const DWORD shader_code_13_coissue_2[] =
1777 0xffff0103, /* ps_1_3 */
1778 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
1779 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
1780 0x00000040, 0xb00f0000, /* texcoord t0 */
1781 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
1782 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
1783 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
1784 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
1785 0x00000001, 0x800f0000, 0x80e40001, /* mov r0, r1 */
1786 0x00000001, 0x80070000, 0x80ff0001, /* mov r0.xyz, r1.a */
1787 0x40000050, 0x80080000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.a, r0.a, c1, c2 */
1788 0x00000001, 0x80070000, 0x80ff0000, /* mov r0.xyz, r0.a */
1789 0x0000ffff /* end */
1791 /* ps_1_4 does not have a different cnd behavior, just pass the [0;1]
1792 * texcrd result to cnd, it will compare against 0.5. */
1793 static const DWORD shader_code_14_coissue[] =
1795 0xffff0104, /* ps_1_4 */
1796 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
1797 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0.xyz, t0 */
1798 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
1799 0x40000050, 0x80070000, 0x80e40000, 0xa0e40001, 0xa0e40002, /* +cnd r0.xyz, r0, c1, c2 */
1800 0x0000ffff /* end */
1802 static const DWORD shader_code_14_coissue_2[] =
1804 0xffff0104, /* ps_1_4 */
1805 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
1806 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0.xyz, t0 */
1807 0x00000001, 0x80080000, 0x80000000, /* mov r0.a, r0.x */
1808 0x00000001, 0x80070001, 0xa0ff0000, /* mov r1.xyz, c0.a */
1809 0x40000050, 0x80080001, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r1.a, r0.a, c1, c2 */
1810 0x00000001, 0x80070000, 0x80ff0001, /* mov r0.xyz, r1.a */
1811 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
1812 0x0000ffff /* end */
1814 static const float quad1[] =
1816 -1.0f, -1.0f, 0.1f, 0.0f, 0.0f, 1.0f,
1817 -1.0f, 0.0f, 0.1f, 0.0f, 1.0f, 0.0f,
1818 0.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f,
1819 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 0.0f
1821 static const float quad2[] =
1823 0.0f, -1.0f, 0.1f, 0.0f, 0.0f, 1.0f,
1824 0.0f, 0.0f, 0.1f, 0.0f, 1.0f, 0.0f,
1825 1.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f,
1826 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 0.0f
1828 static const float quad3[] =
1830 0.0f, 0.0f, 0.1f, 0.0f, 0.0f, 1.0f,
1831 0.0f, 1.0f, 0.1f, 0.0f, 1.0f, 0.0f,
1832 1.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f,
1833 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 0.0f
1835 static const float quad4[] =
1837 -1.0f, 0.0f, 0.1f, 0.0f, 0.0f, 1.0f,
1838 -1.0f, 1.0f, 0.1f, 0.0f, 1.0f, 0.0f,
1839 0.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f,
1840 0.0f, 1.0f, 0.1f, 1.0f, 1.0f, 0.0f
1842 static const float test_data_c1[4] = {0.0f, 0.0f, 0.0f, 0.0f};
1843 static const float test_data_c2[4] = {1.0f, 1.0f, 1.0f, 1.0f};
1844 static const float test_data_c1_coi[4] = {0.0f, 1.0f, 0.0f, 0.0f};
1845 static const float test_data_c2_coi[4] = {1.0f, 0.0f, 1.0f, 1.0f};
1847 window = create_window();
1848 d3d = Direct3DCreate8(D3D_SDK_VERSION);
1849 ok(!!d3d, "Failed to create a D3D object.\n");
1850 if (!(device = create_device(d3d, window, window, TRUE)))
1852 skip("Failed to create a D3D device, skipping tests.\n");
1853 goto done;
1856 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
1857 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
1858 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 4))
1860 skip("No ps_1_4 support, skipping tests.\n");
1861 IDirect3DDevice8_Release(device);
1862 goto done;
1865 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
1866 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
1868 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code_11, &shader_11);
1869 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
1870 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code_12, &shader_12);
1871 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
1872 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code_13, &shader_13);
1873 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
1874 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code_14, &shader_14);
1875 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
1876 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code_11_coissue, &shader_11_coissue);
1877 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
1878 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code_12_coissue, &shader_12_coissue);
1879 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
1880 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code_13_coissue, &shader_13_coissue);
1881 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
1882 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code_14_coissue, &shader_14_coissue);
1883 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
1884 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code_11_coissue_2, &shader_11_coissue_2);
1885 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
1886 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code_12_coissue_2, &shader_12_coissue_2);
1887 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
1888 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code_13_coissue_2, &shader_13_coissue_2);
1889 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
1890 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code_14_coissue_2, &shader_14_coissue_2);
1891 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
1893 hr = IDirect3DDevice8_SetPixelShaderConstant(device, 1, test_data_c1, 1);
1894 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
1895 hr = IDirect3DDevice8_SetPixelShaderConstant(device, 2, test_data_c2, 1);
1896 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
1897 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX1);
1898 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
1900 hr = IDirect3DDevice8_BeginScene(device);
1901 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
1903 hr = IDirect3DDevice8_SetPixelShader(device, shader_11);
1904 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
1905 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
1906 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
1908 hr = IDirect3DDevice8_SetPixelShader(device, shader_12);
1909 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
1910 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
1911 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
1913 hr = IDirect3DDevice8_SetPixelShader(device, shader_13);
1914 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
1915 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
1916 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
1918 hr = IDirect3DDevice8_SetPixelShader(device, shader_14);
1919 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
1920 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
1921 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
1923 hr = IDirect3DDevice8_EndScene(device);
1924 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
1926 hr = IDirect3DDevice8_SetPixelShader(device, 0);
1927 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
1929 /* This is the 1.4 test. Each component(r, g, b) is tested separately against 0.5 */
1930 color = getPixelColor(device, 158, 118);
1931 ok(color == 0x00ff00ff, "pixel 158, 118 has color %08x, expected 0x00ff00ff\n", color);
1932 color = getPixelColor(device, 162, 118);
1933 ok(color == 0x000000ff, "pixel 162, 118 has color %08x, expected 0x000000ff\n", color);
1934 color = getPixelColor(device, 158, 122);
1935 ok(color == 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color);
1936 color = getPixelColor(device, 162, 122);
1937 ok(color == 0x0000ffff, "pixel 162, 122 has color %08x, expected 0x0000ffff\n", color);
1939 /* 1.1 shader. All 3 components get set, based on the .w comparison */
1940 color = getPixelColor(device, 158, 358);
1941 ok(color == 0x00ffffff, "pixel 158, 358 has color %08x, expected 0x00ffffff\n", color);
1942 color = getPixelColor(device, 162, 358);
1943 ok(color_match(color, 0x00000000, 1),
1944 "pixel 162, 358 has color %08x, expected 0x00000000\n", color);
1945 color = getPixelColor(device, 158, 362);
1946 ok(color == 0x00ffffff, "pixel 158, 362 has color %08x, expected 0x00ffffff\n", color);
1947 color = getPixelColor(device, 162, 362);
1948 ok(color_match(color, 0x00000000, 1),
1949 "pixel 162, 362 has color %08x, expected 0x00000000\n", color);
1951 /* 1.2 shader */
1952 color = getPixelColor(device, 478, 358);
1953 ok(color == 0x00ffffff, "pixel 478, 358 has color %08x, expected 0x00ffffff\n", color);
1954 color = getPixelColor(device, 482, 358);
1955 ok(color_match(color, 0x00000000, 1),
1956 "pixel 482, 358 has color %08x, expected 0x00000000\n", color);
1957 color = getPixelColor(device, 478, 362);
1958 ok(color == 0x00ffffff, "pixel 478, 362 has color %08x, expected 0x00ffffff\n", color);
1959 color = getPixelColor(device, 482, 362);
1960 ok(color_match(color, 0x00000000, 1),
1961 "pixel 482, 362 has color %08x, expected 0x00000000\n", color);
1963 /* 1.3 shader */
1964 color = getPixelColor(device, 478, 118);
1965 ok(color == 0x00ffffff, "pixel 478, 118 has color %08x, expected 0x00ffffff\n", color);
1966 color = getPixelColor(device, 482, 118);
1967 ok(color_match(color, 0x00000000, 1),
1968 "pixel 482, 118 has color %08x, expected 0x00000000\n", color);
1969 color = getPixelColor(device, 478, 122);
1970 ok(color == 0x00ffffff, "pixel 478, 122 has color %08x, expected 0x00ffffff\n", color);
1971 color = getPixelColor(device, 482, 122);
1972 ok(color_match(color, 0x00000000, 1),
1973 "pixel 482, 122 has color %08x, expected 0x00000000\n", color);
1975 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
1976 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
1978 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0f, 0);
1979 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
1980 hr = IDirect3DDevice8_SetPixelShaderConstant(device, 1, test_data_c1_coi, 1);
1981 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
1982 hr = IDirect3DDevice8_SetPixelShaderConstant(device, 2, test_data_c2_coi, 1);
1983 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
1985 hr = IDirect3DDevice8_BeginScene(device);
1986 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
1988 hr = IDirect3DDevice8_SetPixelShader(device, shader_11_coissue);
1989 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
1990 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
1991 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
1993 hr = IDirect3DDevice8_SetPixelShader(device, shader_12_coissue);
1994 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
1995 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
1996 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
1998 hr = IDirect3DDevice8_SetPixelShader(device, shader_13_coissue);
1999 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
2000 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
2001 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
2003 hr = IDirect3DDevice8_SetPixelShader(device, shader_14_coissue);
2004 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
2005 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
2006 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
2008 hr = IDirect3DDevice8_EndScene(device);
2009 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
2011 hr = IDirect3DDevice8_SetPixelShader(device, 0);
2012 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
2014 /* This is the 1.4 test. The coissue doesn't change the behavior here, but keep in mind
2015 * that we swapped the values in c1 and c2 to make the other tests return some color
2017 color = getPixelColor(device, 158, 118);
2018 ok(color == 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color);
2019 color = getPixelColor(device, 162, 118);
2020 ok(color == 0x0000ffff, "pixel 162, 118 has color %08x, expected 0x0000ffff\n", color);
2021 color = getPixelColor(device, 158, 122);
2022 ok(color == 0x00ff00ff, "pixel 162, 122 has color %08x, expected 0x00ff00ff\n", color);
2023 color = getPixelColor(device, 162, 122);
2024 ok(color == 0x000000ff, "pixel 162, 122 has color %08x, expected 0x000000ff\n", color);
2026 /* 1.1 shader. coissue flag changed the semantic of cnd, c1 is always selected
2027 * (The Win7 nvidia driver always selects c2)
2029 color = getPixelColor(device, 158, 358);
2030 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
2031 "pixel 158, 358 has color %08x, expected 0x0000ff00\n", color);
2032 color = getPixelColor(device, 162, 358);
2033 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
2034 "pixel 162, 358 has color %08x, expected 0x0000ff00\n", color);
2035 color = getPixelColor(device, 158, 362);
2036 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
2037 "pixel 158, 362 has color %08x, expected 0x0000ff00\n", color);
2038 color = getPixelColor(device, 162, 362);
2039 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
2040 "pixel 162, 362 has color %08x, expected 0x0000ff00\n", color);
2042 /* 1.2 shader */
2043 color = getPixelColor(device, 478, 358);
2044 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
2045 "pixel 478, 358 has color %08x, expected 0x0000ff00\n", color);
2046 color = getPixelColor(device, 482, 358);
2047 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
2048 "pixel 482, 358 has color %08x, expected 0x0000ff00\n", color);
2049 color = getPixelColor(device, 478, 362);
2050 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
2051 "pixel 478, 362 has color %08x, expected 0x0000ff00\n", color);
2052 color = getPixelColor(device, 482, 362);
2053 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
2054 "pixel 482, 362 has color %08x, expected 0x0000ff00\n", color);
2056 /* 1.3 shader */
2057 color = getPixelColor(device, 478, 118);
2058 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
2059 "pixel 478, 118 has color %08x, expected 0x0000ff00\n", color);
2060 color = getPixelColor(device, 482, 118);
2061 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
2062 "pixel 482, 118 has color %08x, expected 0x0000ff00\n", color);
2063 color = getPixelColor(device, 478, 122);
2064 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
2065 "pixel 478, 122 has color %08x, expected 0x0000ff00\n", color);
2066 color = getPixelColor(device, 482, 122);
2067 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
2068 "pixel 482, 122 has color %08x, expected 0x0000ff00\n", color);
2070 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
2071 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
2073 /* Retest with the coissue flag on the alpha instruction instead. This
2074 * works "as expected". The Windows 8 testbot (WARP) seems to handle this
2075 * the same as coissue on .rgb. */
2076 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0f, 0);
2077 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
2079 hr = IDirect3DDevice8_BeginScene(device);
2080 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
2082 hr = IDirect3DDevice8_SetPixelShader(device, shader_11_coissue_2);
2083 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
2084 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
2085 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
2087 hr = IDirect3DDevice8_SetPixelShader(device, shader_12_coissue_2);
2088 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
2089 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
2090 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
2092 hr = IDirect3DDevice8_SetPixelShader(device, shader_13_coissue_2);
2093 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
2094 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
2095 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
2097 hr = IDirect3DDevice8_SetPixelShader(device, shader_14_coissue_2);
2098 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
2099 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
2100 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
2102 hr = IDirect3DDevice8_EndScene(device);
2103 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
2105 /* 1.4 shader */
2106 color = getPixelColor(device, 158, 118);
2107 ok(color == 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color);
2108 color = getPixelColor(device, 162, 118);
2109 ok(color == 0x00000000, "pixel 162, 118 has color %08x, expected 0x00000000\n", color);
2110 color = getPixelColor(device, 158, 122);
2111 ok(color == 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color);
2112 color = getPixelColor(device, 162, 122);
2113 ok(color == 0x00000000, "pixel 162, 122 has color %08x, expected 0x00000000\n", color);
2115 /* 1.1 shader */
2116 color = getPixelColor(device, 238, 358);
2117 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
2118 "pixel 238, 358 has color %08x, expected 0x00ffffff\n", color);
2119 color = getPixelColor(device, 242, 358);
2120 ok(color_match(color, 0x00000000, 1),
2121 "pixel 242, 358 has color %08x, expected 0x00000000\n", color);
2122 color = getPixelColor(device, 238, 362);
2123 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
2124 "pixel 238, 362 has color %08x, expected 0x00ffffff\n", color);
2125 color = getPixelColor(device, 242, 362);
2126 ok(color_match(color, 0x00000000, 1),
2127 "pixel 242, 362 has color %08x, expected 0x00000000\n", color);
2129 /* 1.2 shader */
2130 color = getPixelColor(device, 558, 358);
2131 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
2132 "pixel 558, 358 has color %08x, expected 0x00ffffff\n", color);
2133 color = getPixelColor(device, 562, 358);
2134 ok(color_match(color, 0x00000000, 1),
2135 "pixel 562, 358 has color %08x, expected 0x00000000\n", color);
2136 color = getPixelColor(device, 558, 362);
2137 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
2138 "pixel 558, 362 has color %08x, expected 0x00ffffff\n", color);
2139 color = getPixelColor(device, 562, 362);
2140 ok(color_match(color, 0x00000000, 1),
2141 "pixel 562, 362 has color %08x, expected 0x00000000\n", color);
2143 /* 1.3 shader */
2144 color = getPixelColor(device, 558, 118);
2145 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
2146 "pixel 558, 118 has color %08x, expected 0x00ffffff\n", color);
2147 color = getPixelColor(device, 562, 118);
2148 ok(color_match(color, 0x00000000, 1),
2149 "pixel 562, 118 has color %08x, expected 0x00000000\n", color);
2150 color = getPixelColor(device, 558, 122);
2151 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
2152 "pixel 558, 122 has color %08x, expected 0x00ffffff\n", color);
2153 color = getPixelColor(device, 562, 122);
2154 ok(color_match(color, 0x00000000, 1),
2155 "pixel 562, 122 has color %08x, expected 0x00000000\n", color);
2157 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
2158 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
2160 IDirect3DDevice8_DeletePixelShader(device, shader_14_coissue_2);
2161 IDirect3DDevice8_DeletePixelShader(device, shader_13_coissue_2);
2162 IDirect3DDevice8_DeletePixelShader(device, shader_12_coissue_2);
2163 IDirect3DDevice8_DeletePixelShader(device, shader_11_coissue_2);
2164 IDirect3DDevice8_DeletePixelShader(device, shader_14_coissue);
2165 IDirect3DDevice8_DeletePixelShader(device, shader_13_coissue);
2166 IDirect3DDevice8_DeletePixelShader(device, shader_12_coissue);
2167 IDirect3DDevice8_DeletePixelShader(device, shader_11_coissue);
2168 IDirect3DDevice8_DeletePixelShader(device, shader_14);
2169 IDirect3DDevice8_DeletePixelShader(device, shader_13);
2170 IDirect3DDevice8_DeletePixelShader(device, shader_12);
2171 IDirect3DDevice8_DeletePixelShader(device, shader_11);
2172 refcount = IDirect3DDevice8_Release(device);
2173 ok(!refcount, "Device has %lu references left.\n", refcount);
2174 done:
2175 IDirect3D8_Release(d3d);
2176 DestroyWindow(window);
2179 static void z_range_test(void)
2181 IDirect3DDevice8 *device;
2182 unsigned int color;
2183 IDirect3D8 *d3d;
2184 ULONG refcount;
2185 D3DCAPS8 caps;
2186 DWORD shader;
2187 HWND window;
2188 HRESULT hr;
2190 static const struct
2192 struct vec3 position;
2193 DWORD diffuse;
2195 quad[] =
2197 {{-1.0f, 0.0f, 1.1f}, 0xffff0000},
2198 {{-1.0f, 1.0f, 1.1f}, 0xffff0000},
2199 {{ 1.0f, 0.0f, -1.1f}, 0xffff0000},
2200 {{ 1.0f, 1.0f, -1.1f}, 0xffff0000},
2202 quad2[] =
2204 {{-1.0f, 0.0f, 1.1f}, 0xff0000ff},
2205 {{-1.0f, 1.0f, 1.1f}, 0xff0000ff},
2206 {{ 1.0f, 0.0f, -1.1f}, 0xff0000ff},
2207 {{ 1.0f, 1.0f, -1.1f}, 0xff0000ff},
2209 static const struct
2211 struct vec4 position;
2212 DWORD diffuse;
2214 quad3[] =
2216 {{640.0f, 240.0f, -1.1f, 1.0f}, 0xffffff00},
2217 {{640.0f, 480.0f, -1.1f, 1.0f}, 0xffffff00},
2218 {{ 0.0f, 240.0f, 1.1f, 1.0f}, 0xffffff00},
2219 {{ 0.0f, 480.0f, 1.1f, 1.0f}, 0xffffff00},
2221 quad4[] =
2223 {{640.0f, 240.0f, -1.1f, 1.0f}, 0xff00ff00},
2224 {{640.0f, 480.0f, -1.1f, 1.0f}, 0xff00ff00},
2225 {{ 0.0f, 240.0f, 1.1f, 1.0f}, 0xff00ff00},
2226 {{ 0.0f, 480.0f, 1.1f, 1.0f}, 0xff00ff00},
2228 static const DWORD shader_code[] =
2230 0xfffe0101, /* vs_1_1 */
2231 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
2232 0x00000001, 0xd00f0000, 0xa0e40000, /* mov oD0, c0 */
2233 0x0000ffff /* end */
2235 static const float color_const_1[] = {1.0f, 0.0f, 0.0f, 1.0f};
2236 static const float color_const_2[] = {0.0f, 0.0f, 1.0f, 1.0f};
2237 static const DWORD vertex_declaration[] =
2239 D3DVSD_STREAM(0),
2240 D3DVSD_REG(D3DVSDE_POSITION, D3DVSDT_FLOAT3),
2241 D3DVSD_END()
2244 window = create_window();
2245 d3d = Direct3DCreate8(D3D_SDK_VERSION);
2246 ok(!!d3d, "Failed to create a D3D object.\n");
2247 if (!(device = create_device(d3d, window, window, TRUE)))
2249 skip("Failed to create a D3D device, skipping tests.\n");
2250 goto done;
2253 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
2254 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
2256 /* Does the Present clear the depth stencil? Clear the depth buffer with some value != 0,
2257 * then call Present. Then clear the color buffer to make sure it has some defined content
2258 * after the Present with D3DSWAPEFFECT_DISCARD. After that draw a plane that is somewhere cut
2259 * by the depth value. */
2260 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.75f, 0);
2261 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
2262 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
2263 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
2264 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
2265 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
2267 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
2268 ok(SUCCEEDED(hr), "Failed to disabled lighting, hr %#lx.\n", hr);
2269 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, TRUE);
2270 ok(SUCCEEDED(hr), "Failed to enable clipping, hr %#lx.\n", hr);
2271 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
2272 ok(SUCCEEDED(hr), "Failed to enable z test, hr %#lx.\n", hr);
2273 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
2274 ok(SUCCEEDED(hr), "Failed to disable z writes, hr %#lx.\n", hr);
2275 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
2276 ok(SUCCEEDED(hr), "Failed to set z function, hr %#lx.\n", hr);
2277 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
2278 ok(SUCCEEDED(hr), "Failed set FVF, hr %#lx.\n", hr);
2280 hr = IDirect3DDevice8_BeginScene(device);
2281 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
2283 /* Test the untransformed vertex path */
2284 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
2285 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
2286 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
2287 ok(SUCCEEDED(hr), "Failed to set z function, hr %#lx.\n", hr);
2288 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
2289 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
2291 /* Test the transformed vertex path */
2292 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
2293 ok(SUCCEEDED(hr), "Failed set FVF, hr %#lx.\n", hr);
2295 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(quad4[0]));
2296 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
2297 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
2298 ok(SUCCEEDED(hr), "Failed to set z function, hr %#lx.\n", hr);
2299 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(quad3[0]));
2300 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
2302 hr = IDirect3DDevice8_EndScene(device);
2303 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
2305 /* Do not test the exact corner pixels, but go pretty close to them */
2307 /* Clipped because z > 1.0 */
2308 color = getPixelColor(device, 28, 238);
2309 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2310 color = getPixelColor(device, 28, 241);
2311 if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
2312 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2313 else
2314 ok(color_match(color, 0x00ffff00, 0), "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2316 /* Not clipped, > z buffer clear value(0.75).
2318 * On the r500 driver on Windows D3DCMP_GREATER and D3DCMP_GREATEREQUAL are broken for depth
2319 * values > 0.5. The range appears to be distorted, apparently an incoming value of ~0.875 is
2320 * equal to a stored depth buffer value of 0.5. */
2321 color = getPixelColor(device, 31, 238);
2322 ok(color_match(color, 0x00ff0000, 0), "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2323 color = getPixelColor(device, 31, 241);
2324 ok(color_match(color, 0x00ffff00, 0), "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2325 color = getPixelColor(device, 100, 238);
2326 ok(color_match(color, 0x00ff0000, 0) || broken(color_match(color, 0x00ffffff, 0)),
2327 "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2328 color = getPixelColor(device, 100, 241);
2329 ok(color_match(color, 0x00ffff00, 0) || broken(color_match(color, 0x00ffffff, 0)),
2330 "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2332 /* Not clipped, < z buffer clear value */
2333 color = getPixelColor(device, 104, 238);
2334 ok(color_match(color, 0x000000ff, 0), "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2335 color = getPixelColor(device, 104, 241);
2336 ok(color_match(color, 0x0000ff00, 0), "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
2337 color = getPixelColor(device, 318, 238);
2338 ok(color_match(color, 0x000000ff, 0), "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2339 color = getPixelColor(device, 318, 241);
2340 ok(color_match(color, 0x0000ff00, 0), "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
2342 /* Clipped because z < 0.0 */
2343 color = getPixelColor(device, 321, 238);
2344 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2345 color = getPixelColor(device, 321, 241);
2346 if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
2347 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2348 else
2349 ok(color_match(color, 0x0000ff00, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2351 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
2352 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
2354 /* Test the shader path */
2355 if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1))
2357 skip("Vertex shaders not supported\n");
2358 IDirect3DDevice8_Release(device);
2359 goto done;
2361 hr = IDirect3DDevice8_CreateVertexShader(device, vertex_declaration, shader_code, &shader, 0);
2362 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#lx.\n", hr);
2364 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
2365 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
2367 hr = IDirect3DDevice8_SetVertexShader(device, shader);
2368 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#lx.\n", hr);
2370 hr = IDirect3DDevice8_BeginScene(device);
2371 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
2373 hr = IDirect3DDevice8_SetVertexShaderConstant(device, 0, color_const_1, 1);
2374 ok(SUCCEEDED(hr), "Failed to set vs constant 0, hr %#lx.\n", hr);
2375 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
2376 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
2378 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
2379 ok(SUCCEEDED(hr), "Failed to set z function, hr %#lx.\n", hr);
2380 hr = IDirect3DDevice8_SetVertexShaderConstant(device, 0, color_const_2, 1);
2381 ok(SUCCEEDED(hr), "Failed to set vs constant 0, hr %#lx.\n", hr);
2382 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
2383 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
2385 hr = IDirect3DDevice8_EndScene(device);
2386 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
2388 hr = IDirect3DDevice8_SetVertexShader(device, 0);
2389 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#lx.\n", hr);
2391 hr = IDirect3DDevice8_DeleteVertexShader(device, shader);
2392 ok(SUCCEEDED(hr), "Failed to delete vertex shader, hr %#lx.\n", hr);
2394 /* Z < 1.0 */
2395 color = getPixelColor(device, 28, 238);
2396 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2398 /* 1.0 < z < 0.75 */
2399 color = getPixelColor(device, 31, 238);
2400 ok(color_match(color, 0x00ff0000, 0), "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2401 color = getPixelColor(device, 100, 238);
2402 ok(color_match(color, 0x00ff0000, 0) || broken(color_match(color, 0x00ffffff, 0)),
2403 "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2405 /* 0.75 < z < 0.0 */
2406 color = getPixelColor(device, 104, 238);
2407 ok(color_match(color, 0x000000ff, 0), "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2408 color = getPixelColor(device, 318, 238);
2409 ok(color_match(color, 0x000000ff, 0), "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2411 /* 0.0 < z */
2412 color = getPixelColor(device, 321, 238);
2413 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2415 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
2416 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
2418 refcount = IDirect3DDevice8_Release(device);
2419 ok(!refcount, "Device has %lu references left.\n", refcount);
2420 done:
2421 IDirect3D8_Release(d3d);
2422 DestroyWindow(window);
2425 static void test_scalar_instructions(void)
2427 IDirect3DDevice8 *device;
2428 unsigned int color, i;
2429 IDirect3D8 *d3d;
2430 ULONG refcount;
2431 D3DCAPS8 caps;
2432 DWORD shader;
2433 HWND window;
2434 HRESULT hr;
2436 static const struct vec3 quad[] =
2438 {-1.0f, -1.0f, 0.0f},
2439 {-1.0f, 1.0f, 0.0f},
2440 { 1.0f, -1.0f, 0.0f},
2441 { 1.0f, 1.0f, 0.0f},
2443 static const DWORD decl[] =
2445 D3DVSD_STREAM(0),
2446 D3DVSD_REG(D3DVSDE_POSITION, D3DVSDT_FLOAT3), /* dcl_position v0 */
2447 D3DVSD_CONST(0, 1), 0x3e800000, 0x3f000000, 0x3f800000, 0x40000000, /* def c0, 0.25, 0.5, 1.0, 2.0 */
2448 D3DVSD_END()
2450 static const DWORD rcp_test[] =
2452 0xfffe0101, /* vs_1_1 */
2453 0x0009fffe, 0x30303030, 0x30303030, /* Shaders have to have a minimal size. */
2454 0x30303030, 0x30303030, 0x30303030, /* Add a filler comment. Usually d3dx8's */
2455 0x30303030, 0x30303030, 0x30303030, /* version comment makes the shader big */
2456 0x00303030, /* enough to make Windows happy. */
2457 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
2458 0x00000006, 0xd00f0000, 0xa0e40000, /* rcp oD0, c0 */
2459 0x0000ffff /* END */
2461 static const DWORD rsq_test[] =
2463 0xfffe0101, /* vs_1_1 */
2464 0x0009fffe, 0x30303030, 0x30303030, /* Shaders have to have a minimal size. */
2465 0x30303030, 0x30303030, 0x30303030, /* Add a filler comment. Usually d3dx8's */
2466 0x30303030, 0x30303030, 0x30303030, /* version comment makes the shader big */
2467 0x00303030, /* enough to make Windows happy. */
2468 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
2469 0x00000007, 0xd00f0000, 0xa0e40000, /* rsq oD0, c0 */
2470 0x0000ffff /* END */
2472 static const DWORD exp_test[] =
2474 0xfffe0101, /* vs_1_1 */
2475 0x0009fffe, 0x30303030, 0x30303030, /* Shaders have to have a minimal size. */
2476 0x30303030, 0x30303030, 0x30303030, /* Add a filler comment. Usually d3dx8's */
2477 0x30303030, 0x30303030, 0x30303030, /* version comment makes the shader big */
2478 0x00303030, /* enough to make Windows happy. */
2479 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
2480 0x0000000e, 0x800f0000, 0xa0e40000, /* exp r0, c0 */
2481 0x00000006, 0xd00f0000, 0x80000000, /* rcp oD0, r0.x */
2482 0x0000ffff, /* END */
2484 static const DWORD expp_test[] =
2486 0xfffe0101, /* vs_1_1 */
2487 0x0009fffe, 0x30303030, 0x30303030, /* Shaders have to have a minimal size. */
2488 0x30303030, 0x30303030, 0x30303030, /* Add a filler comment. Usually d3dx8's */
2489 0x30303030, 0x30303030, 0x30303030, /* version comment makes the shader big */
2490 0x00303030, /* enough to make Windows happy. */
2491 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
2492 0x0000004e, 0x800f0000, 0xa0e40000, /* expp r0, c0 */
2493 0x00000006, 0xd00f0000, 0x80000000, /* rcp oD0, r0.x */
2494 0x0000ffff, /* END */
2496 static const DWORD log_test[] =
2498 0xfffe0101, /* vs_1_1 */
2499 0x0009fffe, 0x30303030, 0x30303030, /* Shaders have to have a minimal size. */
2500 0x30303030, 0x30303030, 0x30303030, /* Add a filler comment. Usually d3dx8's */
2501 0x30303030, 0x30303030, 0x30303030, /* version comment makes the shader big */
2502 0x00303030, /* enough to make Windows happy. */
2503 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
2504 0x0000000f, 0xd00f0000, 0xa0e40000, /* log oD0, c0 */
2505 0x0000ffff, /* END */
2507 static const DWORD logp_test[] =
2509 0xfffe0101, /* vs_1_1 */
2510 0x0009fffe, 0x30303030, 0x30303030, /* Shaders have to have a minimal size. */
2511 0x30303030, 0x30303030, 0x30303030, /* Add a filler comment. Usually d3dx8's */
2512 0x30303030, 0x30303030, 0x30303030, /* version comment makes the shader big */
2513 0x00303030, /* enough to make Windows happy. */
2514 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
2515 0x0000004f, 0xd00f0000, 0xa0e40000, /* logp oD0, c0 */
2516 0x0000ffff, /* END */
2518 static const struct
2520 const char *name;
2521 const DWORD *byte_code;
2522 unsigned int color;
2523 /* Some drivers, including Intel HD4000 10.18.10.3345 and VMware SVGA
2524 * 3D 7.14.1.5025, use the .x component instead of the .w one. */
2525 unsigned int broken_color;
2527 test_data[] =
2529 {"rcp_test", rcp_test, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x80), D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff)},
2530 {"rsq_test", rsq_test, D3DCOLOR_ARGB(0x00, 0xb4, 0xb4, 0xb4), D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff)},
2531 {"exp_test", exp_test, D3DCOLOR_ARGB(0x00, 0x40, 0x40, 0x40), D3DCOLOR_ARGB(0x00, 0xd6, 0xd6, 0xd6)},
2532 {"expp_test", expp_test, D3DCOLOR_ARGB(0x00, 0x40, 0x40, 0x40), D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff)},
2533 {"log_test", log_test, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff), D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
2534 {"logp_test", logp_test, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff), D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
2537 window = create_window();
2538 d3d = Direct3DCreate8(D3D_SDK_VERSION);
2539 ok(!!d3d, "Failed to create a D3D object.\n");
2540 if (!(device = create_device(d3d, window, window, TRUE)))
2542 skip("Failed to create a D3D device, skipping tests.\n");
2543 goto done;
2546 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
2547 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
2548 if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1))
2550 skip("No vs_1_1 support, skipping tests.\n");
2551 IDirect3DDevice8_Release(device);
2552 goto done;
2555 for (i = 0; i < ARRAY_SIZE(test_data); ++i)
2557 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff336699, 0.0f, 0);
2558 ok(SUCCEEDED(hr), "%s: Failed to clear, hr %#lx.\n", test_data[i].name, hr);
2560 hr = IDirect3DDevice8_CreateVertexShader(device, decl, test_data[i].byte_code, &shader, 0);
2561 ok(SUCCEEDED(hr), "%s: Failed to create vertex shader, hr %#lx.\n", test_data[i].name, hr);
2562 hr = IDirect3DDevice8_SetVertexShader(device, shader);
2563 ok(SUCCEEDED(hr), "%s: Failed to set vertex shader, hr %#lx.\n", test_data[i].name, hr);
2565 hr = IDirect3DDevice8_BeginScene(device);
2566 ok(SUCCEEDED(hr), "%s: Failed to begin scene, hr %#lx.\n", test_data[i].name, hr);
2567 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], 3 * sizeof(float));
2568 ok(SUCCEEDED(hr), "%s: Failed to draw primitive, hr %#lx.\n", test_data[i].name, hr);
2569 hr = IDirect3DDevice8_EndScene(device);
2570 ok(SUCCEEDED(hr), "%s: Failed to end scene, hr %#lx.\n", test_data[i].name, hr);
2572 color = getPixelColor(device, 320, 240);
2573 ok(color_match(color, test_data[i].color, 4) || broken(color_match(color, test_data[i].broken_color, 4)),
2574 "%s: Got unexpected color 0x%08x, expected 0x%08x.\n",
2575 test_data[i].name, color, test_data[i].color);
2577 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
2578 ok(SUCCEEDED(hr), "%s: Failed to present, hr %#lx.\n", test_data[i].name, hr);
2580 hr = IDirect3DDevice8_SetVertexShader(device, 0);
2581 ok(SUCCEEDED(hr), "%s: Failed to set vertex shader, hr %#lx.\n", test_data[i].name, hr);
2582 hr = IDirect3DDevice8_DeleteVertexShader(device, shader);
2583 ok(SUCCEEDED(hr), "%s: Failed to delete vertex shader, hr %#lx.\n", test_data[i].name, hr);
2586 refcount = IDirect3DDevice8_Release(device);
2587 ok(!refcount, "Device has %lu references left.\n", refcount);
2588 done:
2589 IDirect3D8_Release(d3d);
2590 DestroyWindow(window);
2593 static void offscreen_test(void)
2595 IDirect3DSurface8 *backbuffer, *offscreen, *depthstencil;
2596 IDirect3DTexture8 *offscreenTexture;
2597 IDirect3DDevice8 *device;
2598 unsigned int color;
2599 IDirect3D8 *d3d;
2600 ULONG refcount;
2601 HWND window;
2602 HRESULT hr;
2604 static const float quad[][5] =
2606 {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
2607 {-0.5f, 0.5f, 0.1f, 0.0f, 1.0f},
2608 { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
2609 { 0.5f, 0.5f, 0.1f, 1.0f, 1.0f},
2612 window = create_window();
2613 d3d = Direct3DCreate8(D3D_SDK_VERSION);
2614 ok(!!d3d, "Failed to create a D3D object.\n");
2615 if (!(device = create_device(d3d, window, window, TRUE)))
2617 skip("Failed to create a D3D device, skipping tests.\n");
2618 goto done;
2621 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 1.0f, 0);
2622 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
2624 hr = IDirect3DDevice8_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET,
2625 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture);
2626 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got hr %#lx.\n", hr);
2627 if (!offscreenTexture)
2629 trace("Failed to create an X8R8G8B8 offscreen texture, trying R5G6B5\n");
2630 hr = IDirect3DDevice8_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET,
2631 D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &offscreenTexture);
2632 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got hr %#lx.\n", hr);
2633 if (!offscreenTexture)
2635 skip("Cannot create an offscreen render target.\n");
2636 IDirect3DDevice8_Release(device);
2637 goto done;
2641 hr = IDirect3DDevice8_GetDepthStencilSurface(device, &depthstencil);
2642 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
2644 hr = IDirect3DDevice8_GetBackBuffer(device, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
2645 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
2647 hr = IDirect3DTexture8_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
2648 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
2650 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX1);
2651 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
2653 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
2654 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
2655 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
2656 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
2657 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MINFILTER, D3DTEXF_NONE);
2658 ok(SUCCEEDED(hr), "Got hr %#lx.\n", hr);
2659 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MAGFILTER, D3DTEXF_NONE);
2660 ok(SUCCEEDED(hr), "Got hr %#lx.\n", hr);
2661 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
2662 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
2664 hr = IDirect3DDevice8_BeginScene(device);
2665 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
2667 hr = IDirect3DDevice8_SetRenderTarget(device, offscreen, depthstencil);
2668 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
2669 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 1.0f, 0);
2670 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
2672 /* Draw without textures - Should result in a white quad. */
2673 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
2674 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
2676 hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, depthstencil);
2677 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
2678 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)offscreenTexture);
2679 ok(SUCCEEDED(hr), "Failed to set texture, hr %#lx.\n", hr);
2681 /* This time with the texture .*/
2682 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
2683 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
2685 hr = IDirect3DDevice8_EndScene(device);
2686 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
2688 /* Center quad - should be white */
2689 color = getPixelColor(device, 320, 240);
2690 ok(color == 0x00ffffff, "Offscreen failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2691 /* Some quad in the cleared part of the texture */
2692 color = getPixelColor(device, 170, 240);
2693 ok(color == 0x00ff00ff, "Offscreen failed: Got color 0x%08x, expected 0x00ff00ff.\n", color);
2694 /* Part of the originally cleared back buffer */
2695 color = getPixelColor(device, 10, 10);
2696 ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2697 color = getPixelColor(device, 10, 470);
2698 ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2700 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
2702 IDirect3DSurface8_Release(backbuffer);
2703 IDirect3DTexture8_Release(offscreenTexture);
2704 IDirect3DSurface8_Release(offscreen);
2705 IDirect3DSurface8_Release(depthstencil);
2706 refcount = IDirect3DDevice8_Release(device);
2707 ok(!refcount, "Device has %lu references left.\n", refcount);
2708 done:
2709 IDirect3D8_Release(d3d);
2710 DestroyWindow(window);
2713 static void test_blend(void)
2715 IDirect3DSurface8 *backbuffer, *offscreen, *depthstencil;
2716 IDirect3DTexture8 *offscreenTexture;
2717 IDirect3DDevice8 *device;
2718 unsigned int color;
2719 IDirect3D8 *d3d;
2720 ULONG refcount;
2721 HWND window;
2722 HRESULT hr;
2724 static const struct
2726 struct vec3 position;
2727 DWORD diffuse;
2729 quad1[] =
2731 {{-1.0f, -1.0f, 0.1f}, 0x4000ff00},
2732 {{-1.0f, 0.0f, 0.1f}, 0x4000ff00},
2733 {{ 1.0f, -1.0f, 0.1f}, 0x4000ff00},
2734 {{ 1.0f, 0.0f, 0.1f}, 0x4000ff00},
2736 quad2[] =
2738 {{-1.0f, 0.0f, 0.1f}, 0xc00000ff},
2739 {{-1.0f, 1.0f, 0.1f}, 0xc00000ff},
2740 {{ 1.0f, 0.0f, 0.1f}, 0xc00000ff},
2741 {{ 1.0f, 1.0f, 0.1f}, 0xc00000ff},
2743 static const float composite_quad[][5] =
2745 { 0.0f, -1.0f, 0.1f, 0.0f, 1.0f},
2746 { 0.0f, 1.0f, 0.1f, 0.0f, 0.0f},
2747 { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f},
2748 { 1.0f, 1.0f, 0.1f, 1.0f, 0.0f},
2751 window = create_window();
2752 d3d = Direct3DCreate8(D3D_SDK_VERSION);
2753 ok(!!d3d, "Failed to create a D3D object.\n");
2754 if (!(device = create_device(d3d, window, window, TRUE)))
2756 skip("Failed to create a D3D device, skipping tests.\n");
2757 goto done;
2760 /* Clear the render target with alpha = 0.5 */
2761 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x80ff0000, 1.0f, 0);
2762 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
2764 hr = IDirect3DDevice8_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET,
2765 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture);
2766 ok(SUCCEEDED(hr), "Failed to create texture, hr %#lx.\n", hr);
2768 hr = IDirect3DDevice8_GetDepthStencilSurface(device, &depthstencil);
2769 ok(SUCCEEDED(hr), "Failed to get depth/stencil buffer, hr %#lx.\n", hr);
2770 hr = IDirect3DDevice8_GetBackBuffer(device, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
2771 ok(SUCCEEDED(hr), "Failed to get back buffer, hr %#lx.\n", hr);
2773 hr = IDirect3DTexture8_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
2774 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
2776 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
2777 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
2779 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
2780 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
2781 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
2782 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
2783 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MINFILTER, D3DTEXF_NONE);
2784 ok(SUCCEEDED(hr), "Got hr %#lx.\n", hr);
2785 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MAGFILTER, D3DTEXF_NONE);
2786 ok(SUCCEEDED(hr), "Got hr %#lx.\n", hr);
2787 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
2788 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
2790 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
2791 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
2792 hr = IDirect3DDevice8_BeginScene(device);
2793 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
2795 /* Draw two quads, one with src alpha blending, one with dest alpha blending. */
2796 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
2797 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
2798 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
2799 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
2800 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
2801 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
2803 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
2804 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
2805 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
2806 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
2807 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
2808 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
2810 /* Switch to the offscreen buffer, and redo the testing. The offscreen
2811 * render target doesn't have an alpha channel. DESTALPHA and INVDESTALPHA
2812 * "don't work" on render targets without alpha channel, they give
2813 * essentially ZERO and ONE blend factors. */
2814 hr = IDirect3DDevice8_SetRenderTarget(device, offscreen, 0);
2815 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
2816 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
2817 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
2819 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
2820 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
2821 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
2822 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
2823 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
2824 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
2826 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
2827 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
2828 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
2829 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
2830 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
2831 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
2833 hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, depthstencil);
2834 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
2836 /* Render the offscreen texture onto the frame buffer to be able to
2837 * compare it regularly. Disable alpha blending for the final
2838 * composition. */
2839 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
2840 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
2841 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX1);
2842 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#lx.\n", hr);
2844 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *) offscreenTexture);
2845 ok(SUCCEEDED(hr), "Failed to set texture, hr %#lx.\n", hr);
2846 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, composite_quad, sizeof(float) * 5);
2847 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
2849 hr = IDirect3DDevice8_EndScene(device);
2850 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
2852 color = getPixelColor(device, 160, 360);
2853 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
2854 "SRCALPHA on frame buffer returned color %08x, expected 0x00bf4000\n", color);
2856 color = getPixelColor(device, 160, 120);
2857 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x00, 0x80), 2),
2858 "DSTALPHA on frame buffer returned color %08x, expected 0x007f0080\n", color);
2860 color = getPixelColor(device, 480, 360);
2861 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
2862 "SRCALPHA on texture returned color %08x, expected 0x00bf4000\n", color);
2864 color = getPixelColor(device, 480, 120);
2865 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
2866 "DSTALPHA on texture returned color %08x, expected 0x000000ff\n", color);
2868 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
2870 IDirect3DSurface8_Release(backbuffer);
2871 IDirect3DTexture8_Release(offscreenTexture);
2872 IDirect3DSurface8_Release(offscreen);
2873 IDirect3DSurface8_Release(depthstencil);
2874 refcount = IDirect3DDevice8_Release(device);
2875 ok(!refcount, "Device has %lu references left.\n", refcount);
2876 done:
2877 IDirect3D8_Release(d3d);
2878 DestroyWindow(window);
2881 static void p8_texture_test(void)
2883 IDirect3DTexture8 *texture, *texture2;
2884 IDirect3DDevice8 *device;
2885 PALETTEENTRY table[256];
2886 unsigned int color, i;
2887 unsigned char *data;
2888 D3DLOCKED_RECT lr;
2889 IDirect3D8 *d3d;
2890 ULONG refcount;
2891 D3DCAPS8 caps;
2892 HWND window;
2893 HRESULT hr;
2895 static const float quad[] =
2897 -1.0f, 0.0f, 0.1f, 0.0f, 0.0f,
2898 -1.0f, 1.0f, 0.1f, 0.0f, 1.0f,
2899 1.0f, 0.0f, 0.1f, 1.0f, 0.0f,
2900 1.0f, 1.0f, 0.1f, 1.0f, 1.0f,
2902 static const float quad2[] =
2904 -1.0f, -1.0f, 0.1f, 0.0f, 0.0f,
2905 -1.0f, 0.0f, 0.1f, 0.0f, 1.0f,
2906 1.0f, -1.0f, 0.1f, 1.0f, 0.0f,
2907 1.0f, 0.0f, 0.1f, 1.0f, 1.0f,
2910 window = create_window();
2911 d3d = Direct3DCreate8(D3D_SDK_VERSION);
2912 ok(!!d3d, "Failed to create a D3D object.\n");
2913 if (!(device = create_device(d3d, window, window, TRUE)))
2915 skip("Failed to create a D3D device, skipping tests.\n");
2916 goto done;
2919 if (IDirect3D8_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
2920 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_P8) != D3D_OK)
2922 skip("D3DFMT_P8 textures not supported.\n");
2923 IDirect3DDevice8_Release(device);
2924 goto done;
2927 hr = IDirect3DDevice8_CreateTexture(device, 1, 1, 1, 0, D3DFMT_P8, D3DPOOL_MANAGED, &texture2);
2928 ok(SUCCEEDED(hr), "Failed to create texture, hr %#lx.\n", hr);
2929 memset(&lr, 0, sizeof(lr));
2930 hr = IDirect3DTexture8_LockRect(texture2, 0, &lr, NULL, 0);
2931 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
2932 data = lr.pBits;
2933 *data = 1;
2934 hr = IDirect3DTexture8_UnlockRect(texture2, 0);
2935 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
2937 hr = IDirect3DDevice8_CreateTexture(device, 1, 1, 1, 0, D3DFMT_P8, D3DPOOL_MANAGED, &texture);
2938 ok(SUCCEEDED(hr), "Failed to create texture, hr %#lx.\n", hr);
2939 memset(&lr, 0, sizeof(lr));
2940 hr = IDirect3DTexture8_LockRect(texture, 0, &lr, NULL, 0);
2941 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
2942 data = lr.pBits;
2943 *data = 1;
2944 hr = IDirect3DTexture8_UnlockRect(texture, 0);
2945 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
2947 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff000000, 1.0f, 0);
2948 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
2950 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
2951 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
2952 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
2953 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
2955 /* The first part of the test should work both with and without D3DPTEXTURECAPS_ALPHAPALETTE;
2956 alpha of every entry is set to 1.0, which MS says is required when there's no
2957 D3DPTEXTURECAPS_ALPHAPALETTE capability */
2958 for (i = 0; i < 256; i++) {
2959 table[i].peRed = table[i].peGreen = table[i].peBlue = 0;
2960 table[i].peFlags = 0xff;
2962 table[1].peRed = 0xff;
2963 hr = IDirect3DDevice8_SetPaletteEntries(device, 0, table);
2964 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
2966 table[1].peRed = 0;
2967 table[1].peBlue = 0xff;
2968 hr = IDirect3DDevice8_SetPaletteEntries(device, 1, table);
2969 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
2971 hr = IDirect3DDevice8_BeginScene(device);
2972 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
2974 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
2975 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
2976 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
2977 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
2978 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX1);
2979 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#lx.\n", hr);
2980 hr = IDirect3DDevice8_SetCurrentTexturePalette(device, 0);
2981 ok(SUCCEEDED(hr), "Failed to set texture palette, hr %#lx.\n", hr);
2982 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture2);
2983 ok(SUCCEEDED(hr), "Failed to set texture, hr %#lx.\n", hr);
2984 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
2985 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
2987 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
2988 ok(SUCCEEDED(hr), "Failed to set texture, hr %#lx.\n", hr);
2989 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
2990 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
2992 hr = IDirect3DDevice8_SetCurrentTexturePalette(device, 1);
2993 ok(SUCCEEDED(hr), "Failed to set texture palette, hr %#lx.\n", hr);
2994 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
2995 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
2997 hr = IDirect3DDevice8_EndScene(device);
2998 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
3000 color = getPixelColor(device, 32, 32);
3001 ok(color_match(color, 0x00ff0000, 0), "Got unexpected color 0x%08x.\n", color);
3002 color = getPixelColor(device, 32, 320);
3003 ok(color_match(color, 0x000000ff, 0), "Got unexpected color 0x%08x.\n", color);
3005 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
3006 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
3008 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
3009 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
3011 hr = IDirect3DDevice8_BeginScene(device);
3012 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
3013 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture2);
3014 ok(SUCCEEDED(hr), "Failed to set texture, hr %#lx.\n", hr);
3015 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
3016 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
3017 hr = IDirect3DDevice8_EndScene(device);
3018 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
3020 color = getPixelColor(device, 32, 32);
3021 ok(color_match(color, 0x000000ff, 0), "Got unexpected color 0x%08x.\n", color);
3023 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
3024 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
3026 /* Test palettes with alpha */
3027 IDirect3DDevice8_GetDeviceCaps(device, &caps);
3028 if (!(caps.TextureCaps & D3DPTEXTURECAPS_ALPHAPALETTE)) {
3029 skip("no D3DPTEXTURECAPS_ALPHAPALETTE capability, tests with alpha in palette will be skipped\n");
3030 } else {
3031 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
3032 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
3034 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
3035 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
3037 for (i = 0; i < 256; i++) {
3038 table[i].peRed = table[i].peGreen = table[i].peBlue = 0;
3039 table[i].peFlags = 0xff;
3041 table[1].peRed = 0xff;
3042 table[1].peFlags = 0x80;
3043 hr = IDirect3DDevice8_SetPaletteEntries(device, 0, table);
3044 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
3046 table[1].peRed = 0;
3047 table[1].peBlue = 0xff;
3048 table[1].peFlags = 0x80;
3049 hr = IDirect3DDevice8_SetPaletteEntries(device, 1, table);
3050 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
3052 hr = IDirect3DDevice8_BeginScene(device);
3053 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
3055 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
3056 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
3057 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
3058 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
3059 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX1);
3060 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#lx.\n", hr);
3062 hr = IDirect3DDevice8_SetCurrentTexturePalette(device, 0);
3063 ok(SUCCEEDED(hr), "Failed to set texture palette, hr %#lx.\n", hr);
3064 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
3065 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
3067 hr = IDirect3DDevice8_SetCurrentTexturePalette(device, 1);
3068 ok(SUCCEEDED(hr), "Failed to set texture palette, hr %#lx.\n", hr);
3069 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
3070 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
3072 hr = IDirect3DDevice8_EndScene(device);
3073 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
3075 color = getPixelColor(device, 32, 32);
3076 ok(color_match(color, 0x00800000, 1), "Got unexpected color 0x%08x.\n", color);
3077 color = getPixelColor(device, 32, 320);
3078 ok(color_match(color, 0x00000080, 1), "Got unexpected color 0x%08x.\n", color);
3080 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
3081 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
3084 IDirect3DTexture8_Release(texture);
3085 IDirect3DTexture8_Release(texture2);
3086 refcount = IDirect3DDevice8_Release(device);
3087 ok(!refcount, "Device has %lu references left.\n", refcount);
3088 done:
3089 IDirect3D8_Release(d3d);
3090 DestroyWindow(window);
3093 static void texop_test(void)
3095 IDirect3DTexture8 *texture;
3096 D3DLOCKED_RECT locked_rect;
3097 IDirect3DDevice8 *device;
3098 unsigned int color, i;
3099 IDirect3D8 *d3d;
3100 ULONG refcount;
3101 D3DCAPS8 caps;
3102 HWND window;
3103 HRESULT hr;
3105 static const struct {
3106 float x, y, z;
3107 D3DCOLOR diffuse;
3108 float s, t;
3109 } quad[] = {
3110 {-1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00), -1.0f, -1.0f},
3111 {-1.0f, 1.0f, 0.1f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00), -1.0f, 1.0f},
3112 { 1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00), 1.0f, -1.0f},
3113 { 1.0f, 1.0f, 0.1f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00), 1.0f, 1.0f}
3116 static const struct {
3117 D3DTEXTUREOP op;
3118 const char *name;
3119 DWORD caps_flag;
3120 unsigned int result;
3121 } test_data[] = {
3122 {D3DTOP_SELECTARG1, "SELECTARG1", D3DTEXOPCAPS_SELECTARG1, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
3123 {D3DTOP_SELECTARG2, "SELECTARG2", D3DTEXOPCAPS_SELECTARG2, D3DCOLOR_ARGB(0x00, 0x33, 0x33, 0x33)},
3124 {D3DTOP_MODULATE, "MODULATE", D3DTEXOPCAPS_MODULATE, D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x00)},
3125 {D3DTOP_MODULATE2X, "MODULATE2X", D3DTEXOPCAPS_MODULATE2X, D3DCOLOR_ARGB(0x00, 0x00, 0x66, 0x00)},
3126 {D3DTOP_MODULATE4X, "MODULATE4X", D3DTEXOPCAPS_MODULATE4X, D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
3127 {D3DTOP_ADD, "ADD", D3DTEXOPCAPS_ADD, D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
3129 {D3DTOP_ADDSIGNED, "ADDSIGNED", D3DTEXOPCAPS_ADDSIGNED, D3DCOLOR_ARGB(0x00, 0x00, 0xb2, 0x00)},
3130 {D3DTOP_ADDSIGNED2X, "ADDSIGNED2X", D3DTEXOPCAPS_ADDSIGNED2X, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
3132 {D3DTOP_SUBTRACT, "SUBTRACT", D3DTEXOPCAPS_SUBTRACT, D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
3133 {D3DTOP_ADDSMOOTH, "ADDSMOOTH", D3DTEXOPCAPS_ADDSMOOTH, D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
3134 {D3DTOP_BLENDDIFFUSEALPHA, "BLENDDIFFUSEALPHA", D3DTEXOPCAPS_BLENDDIFFUSEALPHA, D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
3135 {D3DTOP_BLENDTEXTUREALPHA, "BLENDTEXTUREALPHA", D3DTEXOPCAPS_BLENDTEXTUREALPHA, D3DCOLOR_ARGB(0x00, 0x14, 0xad, 0x14)},
3136 {D3DTOP_BLENDFACTORALPHA, "BLENDFACTORALPHA", D3DTEXOPCAPS_BLENDFACTORALPHA, D3DCOLOR_ARGB(0x00, 0x07, 0xe4, 0x07)},
3137 {D3DTOP_BLENDTEXTUREALPHAPM, "BLENDTEXTUREALPHAPM", D3DTEXOPCAPS_BLENDTEXTUREALPHAPM, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
3138 {D3DTOP_BLENDCURRENTALPHA, "BLENDCURRENTALPHA", D3DTEXOPCAPS_BLENDCURRENTALPHA, D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
3139 {D3DTOP_MODULATEALPHA_ADDCOLOR, "MODULATEALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x1f, 0xff, 0x1f)},
3140 {D3DTOP_MODULATECOLOR_ADDALPHA, "MODULATECOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0x99, 0xcc, 0x99)},
3141 {D3DTOP_MODULATEINVALPHA_ADDCOLOR, "MODULATEINVALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
3142 {D3DTOP_MODULATEINVCOLOR_ADDALPHA, "MODULATEINVCOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0xcc, 0x99, 0xcc)},
3143 /* BUMPENVMAP & BUMPENVMAPLUMINANCE have their own tests */
3144 {D3DTOP_DOTPRODUCT3, "DOTPRODUCT2", D3DTEXOPCAPS_DOTPRODUCT3, D3DCOLOR_ARGB(0x00, 0x99, 0x99, 0x99)},
3145 {D3DTOP_MULTIPLYADD, "MULTIPLYADD", D3DTEXOPCAPS_MULTIPLYADD, D3DCOLOR_ARGB(0x00, 0xff, 0x33, 0x00)},
3146 {D3DTOP_LERP, "LERP", D3DTEXOPCAPS_LERP, D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x33)},
3149 window = create_window();
3150 d3d = Direct3DCreate8(D3D_SDK_VERSION);
3151 ok(!!d3d, "Failed to create a D3D object.\n");
3152 if (!(device = create_device(d3d, window, window, TRUE)))
3154 skip("Failed to create a D3D device, skipping tests.\n");
3155 goto done;
3158 memset(&caps, 0, sizeof(caps));
3159 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
3160 ok(SUCCEEDED(hr), "Got hr %#lx.\n", hr);
3162 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX0);
3163 ok(SUCCEEDED(hr), "Got hr %#lx.\n", hr);
3165 hr = IDirect3DDevice8_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture);
3166 ok(SUCCEEDED(hr), "Got hr %#lx.\n", hr);
3167 hr = IDirect3DTexture8_LockRect(texture, 0, &locked_rect, NULL, 0);
3168 ok(SUCCEEDED(hr), "Got hr %#lx.\n", hr);
3169 *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x99, 0x00, 0xff, 0x00);
3170 hr = IDirect3DTexture8_UnlockRect(texture, 0);
3171 ok(SUCCEEDED(hr), "Got hr %#lx.\n", hr);
3172 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
3173 ok(SUCCEEDED(hr), "Got hr %#lx.\n", hr);
3175 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG0, D3DTA_DIFFUSE);
3176 ok(SUCCEEDED(hr), "Got hr %#lx.\n", hr);
3177 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
3178 ok(SUCCEEDED(hr), "Got hr %#lx.\n", hr);
3179 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
3180 ok(SUCCEEDED(hr), "Got hr %#lx.\n", hr);
3182 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
3183 ok(SUCCEEDED(hr), "Got hr %#lx.\n", hr);
3185 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3186 ok(SUCCEEDED(hr), "Got hr %#lx.\n", hr);
3187 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xdd333333);
3188 ok(SUCCEEDED(hr), "Got hr %#lx.\n", hr);
3189 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_ALPHA);
3190 ok(SUCCEEDED(hr), "Got hr %#lx.\n", hr);
3192 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
3193 ok(SUCCEEDED(hr), "Got hr %#lx.\n", hr);
3195 for (i = 0; i < ARRAY_SIZE(test_data); ++i)
3197 if (!(caps.TextureOpCaps & test_data[i].caps_flag))
3199 skip("tex operation %s not supported\n", test_data[i].name);
3200 continue;
3203 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLOROP, test_data[i].op);
3204 ok(SUCCEEDED(hr), "Got hr %#lx.\n", hr);
3206 hr = IDirect3DDevice8_BeginScene(device);
3207 ok(SUCCEEDED(hr), "Got hr %#lx.\n", hr);
3209 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
3210 ok(SUCCEEDED(hr), "Got hr %#lx.\n", hr);
3212 hr = IDirect3DDevice8_EndScene(device);
3213 ok(SUCCEEDED(hr), "Got hr %#lx.\n", hr);
3215 color = getPixelColor(device, 320, 240);
3216 ok(color_match(color, test_data[i].result, 3), "Operation %s returned color 0x%08x, expected 0x%08x\n",
3217 test_data[i].name, color, test_data[i].result);
3219 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
3220 ok(SUCCEEDED(hr), "Got hr %#lx.\n", hr);
3222 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
3223 ok(SUCCEEDED(hr), "Got hr %#lx.\n", hr);
3226 IDirect3DTexture8_Release(texture);
3227 refcount = IDirect3DDevice8_Release(device);
3228 ok(!refcount, "Device has %lu references left.\n", refcount);
3229 done:
3230 IDirect3D8_Release(d3d);
3231 DestroyWindow(window);
3234 /* This test tests depth clamping / clipping behaviour:
3235 * - With software vertex processing, depth values are clamped to the
3236 * minimum / maximum z value when D3DRS_CLIPPING is disabled, and clipped
3237 * when D3DRS_CLIPPING is enabled. Pretransformed vertices behave the
3238 * same as regular vertices here.
3239 * - With hardware vertex processing, D3DRS_CLIPPING seems to be ignored.
3240 * Normal vertices are always clipped. Pretransformed vertices are
3241 * clipped when D3DPMISCCAPS_CLIPTLVERTS is set, clamped when it isn't.
3242 * - The viewport's MinZ/MaxZ is irrelevant for this.
3244 static void depth_clamp_test(void)
3246 IDirect3DDevice8 *device;
3247 unsigned int color;
3248 D3DVIEWPORT8 vp;
3249 IDirect3D8 *d3d;
3250 ULONG refcount;
3251 D3DCAPS8 caps;
3252 HWND window;
3253 HRESULT hr;
3255 static const struct
3257 struct vec4 position;
3258 DWORD diffuse;
3260 quad1[] =
3262 {{ 0.0f, 0.0f, 5.0f, 1.0f}, 0xff002b7f},
3263 {{640.0f, 0.0f, 5.0f, 1.0f}, 0xff002b7f},
3264 {{ 0.0f, 480.0f, 5.0f, 1.0f}, 0xff002b7f},
3265 {{640.0f, 480.0f, 5.0f, 1.0f}, 0xff002b7f},
3267 quad2[] =
3269 {{ 0.0f, 300.0f, 10.0f, 1.0f}, 0xfff9e814},
3270 {{640.0f, 300.0f, 10.0f, 1.0f}, 0xfff9e814},
3271 {{ 0.0f, 360.0f, 10.0f, 1.0f}, 0xfff9e814},
3272 {{640.0f, 360.0f, 10.0f, 1.0f}, 0xfff9e814},
3274 quad3[] =
3276 {{112.0f, 108.0f, 5.0f, 1.0f}, 0xffffffff},
3277 {{208.0f, 108.0f, 5.0f, 1.0f}, 0xffffffff},
3278 {{112.0f, 204.0f, 5.0f, 1.0f}, 0xffffffff},
3279 {{208.0f, 204.0f, 5.0f, 1.0f}, 0xffffffff},
3281 quad4[] =
3283 {{ 42.0f, 41.0f, 10.0f, 1.0f}, 0xffffffff},
3284 {{112.0f, 41.0f, 10.0f, 1.0f}, 0xffffffff},
3285 {{ 42.0f, 108.0f, 10.0f, 1.0f}, 0xffffffff},
3286 {{112.0f, 108.0f, 10.0f, 1.0f}, 0xffffffff},
3288 static const struct
3290 struct vec3 position;
3291 DWORD diffuse;
3293 quad5[] =
3295 {{-0.5f, 0.5f, 10.0f}, 0xff14f914},
3296 {{ 0.5f, 0.5f, 10.0f}, 0xff14f914},
3297 {{-0.5f, -0.5f, 10.0f}, 0xff14f914},
3298 {{ 0.5f, -0.5f, 10.0f}, 0xff14f914},
3300 quad6[] =
3302 {{-1.0f, 0.5f, 10.0f}, 0xfff91414},
3303 {{ 1.0f, 0.5f, 10.0f}, 0xfff91414},
3304 {{-1.0f, 0.25f, 10.0f}, 0xfff91414},
3305 {{ 1.0f, 0.25f, 10.0f}, 0xfff91414},
3308 window = create_window();
3309 d3d = Direct3DCreate8(D3D_SDK_VERSION);
3310 ok(!!d3d, "Failed to create a D3D object.\n");
3311 if (!(device = create_device(d3d, window, window, TRUE)))
3313 skip("Failed to create a D3D device, skipping tests.\n");
3314 goto done;
3317 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
3318 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
3320 vp.X = 0;
3321 vp.Y = 0;
3322 vp.Width = 640;
3323 vp.Height = 480;
3324 vp.MinZ = 0.0;
3325 vp.MaxZ = 7.5;
3327 hr = IDirect3DDevice8_SetViewport(device, &vp);
3328 ok(SUCCEEDED(hr), "SetViewport failed, hr %#lx.\n", hr);
3330 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0, 0);
3331 ok(SUCCEEDED(hr), "Clear failed, hr %#lx.\n", hr);
3333 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, FALSE);
3334 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
3335 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3336 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
3337 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
3338 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
3339 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
3340 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
3342 hr = IDirect3DDevice8_BeginScene(device);
3343 ok(SUCCEEDED(hr), "BeginScene failed, hr %#lx.\n", hr);
3345 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
3346 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#lx.\n", hr);
3348 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
3349 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#lx.\n", hr);
3350 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
3351 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#lx.\n", hr);
3353 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, TRUE);
3354 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
3356 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
3357 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#lx.\n", hr);
3358 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(*quad4));
3359 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#lx.\n", hr);
3361 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, FALSE);
3362 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
3363 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
3364 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#lx.\n", hr);
3366 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad5, sizeof(*quad5));
3367 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#lx.\n", hr);
3369 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, TRUE);
3370 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
3372 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad6, sizeof(*quad6));
3373 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#lx.\n", hr);
3375 hr = IDirect3DDevice8_EndScene(device);
3376 ok(SUCCEEDED(hr), "EndScene failed, hr %#lx.\n", hr);
3378 if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
3380 color = getPixelColor(device, 75, 75);
3381 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
3382 color = getPixelColor(device, 150, 150);
3383 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
3384 color = getPixelColor(device, 320, 240);
3385 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
3386 color = getPixelColor(device, 320, 330);
3387 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
3388 color = getPixelColor(device, 320, 330);
3389 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
3391 else
3393 color = getPixelColor(device, 75, 75);
3394 ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
3395 color = getPixelColor(device, 150, 150);
3396 ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
3397 color = getPixelColor(device, 320, 240);
3398 ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);
3399 color = getPixelColor(device, 320, 330);
3400 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
3401 color = getPixelColor(device, 320, 330);
3402 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
3405 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
3406 ok(SUCCEEDED(hr), "Got hr %#lx.\n", hr);
3408 refcount = IDirect3DDevice8_Release(device);
3409 ok(!refcount, "Device has %lu references left.\n", refcount);
3410 done:
3411 IDirect3D8_Release(d3d);
3412 DestroyWindow(window);
3415 static void depth_buffer_test(void)
3417 IDirect3DSurface8 *backbuffer, *rt1, *rt2, *rt3;
3418 IDirect3DSurface8 *depth_stencil;
3419 IDirect3DDevice8 *device;
3420 unsigned int color, i, j;
3421 D3DVIEWPORT8 vp;
3422 IDirect3D8 *d3d;
3423 ULONG refcount;
3424 HWND window;
3425 HRESULT hr;
3427 static const struct
3429 struct vec3 position;
3430 DWORD diffuse;
3432 quad1[] =
3434 {{-1.0f, 1.0f, 0.33f}, 0xff00ff00},
3435 {{ 1.0f, 1.0f, 0.33f}, 0xff00ff00},
3436 {{-1.0f, -1.0f, 0.33f}, 0xff00ff00},
3437 {{ 1.0f, -1.0f, 0.33f}, 0xff00ff00},
3439 quad2[] =
3441 {{-1.0f, 1.0f, 0.50f}, 0xffff00ff},
3442 {{ 1.0f, 1.0f, 0.50f}, 0xffff00ff},
3443 {{-1.0f, -1.0f, 0.50f}, 0xffff00ff},
3444 {{ 1.0f, -1.0f, 0.50f}, 0xffff00ff},
3446 quad3[] =
3448 {{-1.0f, 1.0f, 0.66f}, 0xffff0000},
3449 {{ 1.0f, 1.0f, 0.66f}, 0xffff0000},
3450 {{-1.0f, -1.0f, 0.66f}, 0xffff0000},
3451 {{ 1.0f, -1.0f, 0.66f}, 0xffff0000},
3453 static const unsigned int expected_colors[4][4] =
3455 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
3456 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
3457 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x00ff0000},
3458 {0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
3461 window = create_window();
3462 d3d = Direct3DCreate8(D3D_SDK_VERSION);
3463 ok(!!d3d, "Failed to create a D3D object.\n");
3464 if (!(device = create_device(d3d, window, window, TRUE)))
3466 skip("Failed to create a D3D device, skipping tests.\n");
3467 goto done;
3470 vp.X = 0;
3471 vp.Y = 0;
3472 vp.Width = 640;
3473 vp.Height = 480;
3474 vp.MinZ = 0.0;
3475 vp.MaxZ = 1.0;
3477 hr = IDirect3DDevice8_SetViewport(device, &vp);
3478 ok(SUCCEEDED(hr), "SetViewport failed, hr %#lx.\n", hr);
3480 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3481 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
3482 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
3483 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
3484 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
3485 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
3486 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
3487 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
3488 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
3489 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#lx.\n", hr);
3491 hr = IDirect3DDevice8_GetDepthStencilSurface(device, &depth_stencil);
3492 ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#lx.\n", hr);
3493 hr = IDirect3DDevice8_GetRenderTarget(device, &backbuffer);
3494 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#lx.\n", hr);
3495 hr = IDirect3DDevice8_CreateRenderTarget(device, 320, 240, D3DFMT_A8R8G8B8,
3496 D3DMULTISAMPLE_NONE, FALSE, &rt1);
3497 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#lx.\n", hr);
3498 hr = IDirect3DDevice8_CreateRenderTarget(device, 480, 360, D3DFMT_A8R8G8B8,
3499 D3DMULTISAMPLE_NONE, FALSE, &rt2);
3500 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#lx.\n", hr);
3501 hr = IDirect3DDevice8_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
3502 D3DMULTISAMPLE_NONE, FALSE, &rt3);
3503 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#lx.\n", hr);
3505 hr = IDirect3DDevice8_SetRenderTarget(device, rt3, depth_stencil);
3506 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#lx.\n", hr);
3507 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0f, 0);
3508 ok(SUCCEEDED(hr), "Clear failed, hr %#lx.\n", hr);
3510 hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, depth_stencil);
3511 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#lx.\n", hr);
3512 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
3513 ok(SUCCEEDED(hr), "Clear failed, hr %#lx.\n", hr);
3515 hr = IDirect3DDevice8_SetRenderTarget(device, rt1, depth_stencil);
3516 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#lx.\n", hr);
3517 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0f, 0);
3518 ok(SUCCEEDED(hr), "Clear failed, hr %#lx.\n", hr);
3520 hr = IDirect3DDevice8_SetRenderTarget(device, rt2, depth_stencil);
3521 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#lx.\n", hr);
3522 hr = IDirect3DDevice8_BeginScene(device);
3523 ok(SUCCEEDED(hr), "BeginScene failed, hr %#lx.\n", hr);
3524 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
3525 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#lx.\n", hr);
3526 hr = IDirect3DDevice8_EndScene(device);
3527 ok(SUCCEEDED(hr), "EndScene failed, hr %#lx.\n", hr);
3529 hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, depth_stencil);
3530 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#lx.\n", hr);
3532 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
3533 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
3535 hr = IDirect3DDevice8_BeginScene(device);
3536 ok(SUCCEEDED(hr), "BeginScene failed, hr %#lx.\n", hr);
3537 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
3538 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#lx.\n", hr);
3539 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
3540 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#lx.\n", hr);
3541 hr = IDirect3DDevice8_EndScene(device);
3542 ok(SUCCEEDED(hr), "EndScene failed, hr %#lx.\n", hr);
3544 for (i = 0; i < 4; ++i)
3546 for (j = 0; j < 4; ++j)
3548 unsigned int x = 80 * ((2 * j) + 1);
3549 unsigned int y = 60 * ((2 * i) + 1);
3550 color = getPixelColor(device, x, y);
3551 ok(color_match(color, expected_colors[i][j], 0),
3552 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors[i][j], x, y, color);
3556 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
3557 ok(SUCCEEDED(hr), "Got hr %#lx.\n", hr);
3559 IDirect3DSurface8_Release(depth_stencil);
3560 IDirect3DSurface8_Release(backbuffer);
3561 IDirect3DSurface8_Release(rt3);
3562 IDirect3DSurface8_Release(rt2);
3563 IDirect3DSurface8_Release(rt1);
3564 refcount = IDirect3DDevice8_Release(device);
3565 ok(!refcount, "Device has %lu references left.\n", refcount);
3566 done:
3567 IDirect3D8_Release(d3d);
3568 DestroyWindow(window);
3571 /* Test that partial depth copies work the way they're supposed to. The clear
3572 * on rt2 only needs a partial copy of the onscreen depth/stencil buffer, and
3573 * the following draw should only copy back the part that was modified. */
3574 static void depth_buffer2_test(void)
3576 IDirect3DSurface8 *backbuffer, *rt1, *rt2;
3577 IDirect3DSurface8 *depth_stencil;
3578 IDirect3DDevice8 *device;
3579 unsigned int color, i, j;
3580 D3DVIEWPORT8 vp;
3581 IDirect3D8 *d3d;
3582 ULONG refcount;
3583 HWND window;
3584 HRESULT hr;
3586 static const struct
3588 struct vec3 position;
3589 DWORD diffuse;
3591 quad[] =
3593 {{-1.0f, 1.0f, 0.66f}, 0xffff0000},
3594 {{ 1.0f, 1.0f, 0.66f}, 0xffff0000},
3595 {{-1.0f, -1.0f, 0.66f}, 0xffff0000},
3596 {{ 1.0f, -1.0f, 0.66f}, 0xffff0000},
3599 window = create_window();
3600 d3d = Direct3DCreate8(D3D_SDK_VERSION);
3601 ok(!!d3d, "Failed to create a D3D object.\n");
3602 if (!(device = create_device(d3d, window, window, TRUE)))
3604 skip("Failed to create a D3D device, skipping tests.\n");
3605 goto done;
3608 vp.X = 0;
3609 vp.Y = 0;
3610 vp.Width = 640;
3611 vp.Height = 480;
3612 vp.MinZ = 0.0;
3613 vp.MaxZ = 1.0;
3615 hr = IDirect3DDevice8_SetViewport(device, &vp);
3616 ok(SUCCEEDED(hr), "SetViewport failed, hr %#lx.\n", hr);
3618 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3619 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
3620 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
3621 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
3622 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
3623 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
3624 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
3625 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
3626 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
3627 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#lx.\n", hr);
3629 hr = IDirect3DDevice8_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
3630 D3DMULTISAMPLE_NONE, FALSE, &rt1);
3631 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#lx.\n", hr);
3632 hr = IDirect3DDevice8_CreateRenderTarget(device, 480, 360, D3DFMT_A8R8G8B8,
3633 D3DMULTISAMPLE_NONE, FALSE, &rt2);
3634 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#lx.\n", hr);
3635 hr = IDirect3DDevice8_GetDepthStencilSurface(device, &depth_stencil);
3636 ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#lx.\n", hr);
3637 hr = IDirect3DDevice8_GetRenderTarget(device, &backbuffer);
3638 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#lx.\n", hr);
3640 hr = IDirect3DDevice8_SetRenderTarget(device, rt1, depth_stencil);
3641 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#lx.\n", hr);
3642 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
3643 ok(SUCCEEDED(hr), "Clear failed, hr %#lx.\n", hr);
3645 hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, depth_stencil);
3646 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#lx.\n", hr);
3647 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 0.5f, 0);
3648 ok(SUCCEEDED(hr), "Clear failed, hr %#lx.\n", hr);
3650 hr = IDirect3DDevice8_SetRenderTarget(device, rt2, depth_stencil);
3651 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#lx.\n", hr);
3652 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0f, 0);
3653 ok(SUCCEEDED(hr), "Clear failed, hr %#lx.\n", hr);
3655 hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, depth_stencil);
3656 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#lx.\n", hr);
3658 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
3659 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
3661 hr = IDirect3DDevice8_BeginScene(device);
3662 ok(SUCCEEDED(hr), "BeginScene failed, hr %#lx.\n", hr);
3663 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
3664 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#lx.\n", hr);
3665 hr = IDirect3DDevice8_EndScene(device);
3666 ok(SUCCEEDED(hr), "EndScene failed, hr %#lx.\n", hr);
3668 for (i = 0; i < 4; ++i)
3670 for (j = 0; j < 4; ++j)
3672 unsigned int x = 80 * ((2 * j) + 1);
3673 unsigned int y = 60 * ((2 * i) + 1);
3674 color = getPixelColor(device, x, y);
3675 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
3676 "Expected color 0x0000ff00 %u,%u, got 0x%08x.\n", x, y, color);
3680 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
3681 ok(SUCCEEDED(hr), "Got hr %#lx.\n", hr);
3683 IDirect3DSurface8_Release(depth_stencil);
3684 IDirect3DSurface8_Release(backbuffer);
3685 IDirect3DSurface8_Release(rt2);
3686 IDirect3DSurface8_Release(rt1);
3687 refcount = IDirect3DDevice8_Release(device);
3688 ok(!refcount, "Device has %lu references left.\n", refcount);
3689 done:
3690 IDirect3D8_Release(d3d);
3691 DestroyWindow(window);
3694 static void intz_test(void)
3696 IDirect3DSurface8 *original_rt, *rt;
3697 struct surface_readback rb;
3698 IDirect3DTexture8 *texture;
3699 IDirect3DDevice8 *device;
3700 IDirect3DSurface8 *ds;
3701 IDirect3D8 *d3d;
3702 ULONG refcount;
3703 D3DCAPS8 caps;
3704 HWND window;
3705 HRESULT hr;
3706 DWORD ps;
3707 UINT i;
3709 static const DWORD ps_code[] =
3711 0xffff0101, /* ps_1_1 */
3712 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c0, 1.0, 0.0, 1.0, 1.0 */
3713 0x00000051, 0xa00f0001, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c1, 0.0, 1.0, 0.0, 0.0 */
3714 0x00000042, 0xb00f0000, /* tex t0 */
3715 0x00000042, 0xb00f0001, /* tex t1 */
3716 0x00000005, 0xb00f0000, 0xa0e40000, 0xb0e40000, /* mul t0, c0, t0 */
3717 0x00000004, 0x800f0000, 0xa0e40001, 0xb0e40001, 0xb0e40000, /* mad r0, c1, t1, t0 */
3718 0x0000ffff, /* end */
3720 static const struct
3722 float x, y, z;
3723 float s0, t0, p0;
3724 float s1, t1, p1, q1;
3726 quad[] =
3728 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.5f},
3729 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
3730 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
3731 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.5f},
3733 half_quad_1[] =
3735 { -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.5f},
3736 { 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
3737 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
3738 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.5f},
3740 half_quad_2[] =
3742 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.5f},
3743 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
3744 { -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
3745 { 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.5f},
3747 static const struct
3749 unsigned int x, y, color;
3751 expected_colors[] =
3753 { 80, 100, 0x20204020},
3754 {240, 100, 0x6060bf60},
3755 {400, 100, 0x9f9f409f},
3756 {560, 100, 0xdfdfbfdf},
3757 { 80, 450, 0x20204020},
3758 {240, 450, 0x6060bf60},
3759 {400, 450, 0x9f9f409f},
3760 {560, 450, 0xdfdfbfdf},
3763 window = create_window();
3764 d3d = Direct3DCreate8(D3D_SDK_VERSION);
3765 ok(!!d3d, "Failed to create a D3D object.\n");
3766 if (!(device = create_device(d3d, window, window, TRUE)))
3768 skip("Failed to create a D3D device, skipping tests.\n");
3769 goto done;
3772 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
3773 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#lx.\n", hr);
3774 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 1))
3776 skip("No pixel shader 1.1 support, skipping INTZ test.\n");
3777 IDirect3DDevice8_Release(device);
3778 goto done;
3780 if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
3782 skip("No unconditional NP2 texture support, skipping INTZ test.\n");
3783 IDirect3DDevice8_Release(device);
3784 goto done;
3787 if (FAILED(hr = IDirect3D8_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
3788 D3DFMT_X8R8G8B8, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, MAKEFOURCC('I','N','T','Z'))))
3790 skip("No INTZ support, skipping INTZ test.\n");
3791 IDirect3DDevice8_Release(device);
3792 goto done;
3795 hr = IDirect3DDevice8_GetRenderTarget(device, &original_rt);
3796 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#lx.\n", hr);
3798 hr = IDirect3DDevice8_CreateTexture(device, 640, 480, 1,
3799 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture);
3800 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#lx.\n", hr);
3801 hr = IDirect3DDevice8_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
3802 D3DMULTISAMPLE_NONE, FALSE, &rt);
3803 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#lx.\n", hr);
3804 hr = IDirect3DDevice8_CreatePixelShader(device, ps_code, &ps);
3805 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#lx.\n", hr);
3807 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX2
3808 | D3DFVF_TEXCOORDSIZE3(0) | D3DFVF_TEXCOORDSIZE4(1));
3809 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#lx.\n", hr);
3810 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
3811 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
3812 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
3813 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
3814 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
3815 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
3816 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3817 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
3819 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MINFILTER, D3DTEXF_POINT);
3820 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#lx.\n", hr);
3821 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MIPFILTER, D3DTEXF_POINT);
3822 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#lx.\n", hr);
3823 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MAGFILTER, D3DTEXF_POINT);
3824 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#lx.\n", hr);
3825 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
3826 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#lx.\n", hr);
3828 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP);
3829 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#lx.\n", hr);
3830 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP);
3831 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#lx.\n", hr);
3832 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MAGFILTER, D3DTEXF_POINT);
3833 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#lx.\n", hr);
3834 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MINFILTER, D3DTEXF_POINT);
3835 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#lx.\n", hr);
3836 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MIPFILTER, D3DTEXF_POINT);
3837 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#lx.\n", hr);
3838 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS,
3839 D3DTTFF_COUNT4 | D3DTTFF_PROJECTED);
3840 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#lx.\n", hr);
3842 hr = IDirect3DTexture8_GetSurfaceLevel(texture, 0, &ds);
3843 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#lx.\n", hr);
3845 /* Render offscreen, using the INTZ texture as depth buffer */
3846 hr = IDirect3DDevice8_SetRenderTarget(device, rt, ds);
3847 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#lx.\n", hr);
3848 hr = IDirect3DDevice8_SetPixelShader(device, 0);
3849 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#lx.\n", hr);
3851 /* Setup the depth/stencil surface. */
3852 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
3853 ok(SUCCEEDED(hr), "Clear failed, hr %#lx.\n", hr);
3855 hr = IDirect3DDevice8_BeginScene(device);
3856 ok(SUCCEEDED(hr), "BeginScene failed, hr %#lx.\n", hr);
3857 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
3858 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#lx.\n", hr);
3859 hr = IDirect3DDevice8_EndScene(device);
3860 ok(SUCCEEDED(hr), "EndScene failed, hr %#lx.\n", hr);
3862 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, NULL);
3863 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#lx.\n", hr);
3864 IDirect3DSurface8_Release(ds);
3865 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
3866 ok(SUCCEEDED(hr), "SetTexture failed, hr %#lx.\n", hr);
3867 hr = IDirect3DDevice8_SetTexture(device, 1, (IDirect3DBaseTexture8 *)texture);
3868 ok(SUCCEEDED(hr), "SetTexture failed, hr %#lx.\n", hr);
3869 hr = IDirect3DDevice8_SetPixelShader(device, ps);
3870 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#lx.\n", hr);
3872 /* Read the depth values back. */
3873 hr = IDirect3DDevice8_BeginScene(device);
3874 ok(SUCCEEDED(hr), "BeginScene failed, hr %#lx.\n", hr);
3875 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
3876 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#lx.\n", hr);
3877 hr = IDirect3DDevice8_EndScene(device);
3878 ok(SUCCEEDED(hr), "EndScene failed, hr %#lx.\n", hr);
3880 get_surface_readback(original_rt, &rb);
3881 for (i = 0; i < ARRAY_SIZE(expected_colors); ++i)
3883 unsigned int color = get_readback_color(&rb, expected_colors[i].x, expected_colors[i].y);
3884 ok(color_match(color, expected_colors[i].color, 1),
3885 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
3886 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
3888 release_surface_readback(&rb);
3890 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
3891 ok(SUCCEEDED(hr), "Present failed, hr %#lx.\n", hr);
3893 hr = IDirect3DDevice8_SetTexture(device, 0, NULL);
3894 ok(SUCCEEDED(hr), "SetTexture failed, hr %#lx.\n", hr);
3895 hr = IDirect3DDevice8_SetTexture(device, 1, NULL);
3896 ok(SUCCEEDED(hr), "SetTexture failed, hr %#lx.\n", hr);
3897 IDirect3DTexture8_Release(texture);
3899 /* Render onscreen while using the INTZ texture as depth buffer */
3900 hr = IDirect3DDevice8_CreateTexture(device, 640, 480, 1,
3901 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture);
3902 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#lx.\n", hr);
3903 hr = IDirect3DTexture8_GetSurfaceLevel(texture, 0, &ds);
3904 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#lx.\n", hr);
3905 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, ds);
3906 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#lx.\n", hr);
3907 hr = IDirect3DDevice8_SetPixelShader(device, 0);
3908 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#lx.\n", hr);
3910 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
3911 ok(SUCCEEDED(hr), "Clear failed, hr %#lx.\n", hr);
3913 hr = IDirect3DDevice8_BeginScene(device);
3914 ok(SUCCEEDED(hr), "BeginScene failed, hr %#lx.\n", hr);
3915 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
3916 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#lx.\n", hr);
3917 hr = IDirect3DDevice8_EndScene(device);
3918 ok(SUCCEEDED(hr), "EndScene failed, hr %#lx.\n", hr);
3920 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, NULL);
3921 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#lx.\n", hr);
3922 IDirect3DSurface8_Release(ds);
3923 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
3924 ok(SUCCEEDED(hr), "SetTexture failed, hr %#lx.\n", hr);
3925 hr = IDirect3DDevice8_SetTexture(device, 1, (IDirect3DBaseTexture8 *)texture);
3926 ok(SUCCEEDED(hr), "SetTexture failed, hr %#lx.\n", hr);
3927 hr = IDirect3DDevice8_SetPixelShader(device, ps);
3928 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#lx.\n", hr);
3930 /* Read the depth values back. */
3931 hr = IDirect3DDevice8_BeginScene(device);
3932 ok(SUCCEEDED(hr), "BeginScene failed, hr %#lx.\n", hr);
3933 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
3934 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#lx.\n", hr);
3935 hr = IDirect3DDevice8_EndScene(device);
3936 ok(SUCCEEDED(hr), "EndScene failed, hr %#lx.\n", hr);
3938 get_surface_readback(original_rt, &rb);
3939 for (i = 0; i < ARRAY_SIZE(expected_colors); ++i)
3941 unsigned int color = get_readback_color(&rb, expected_colors[i].x, expected_colors[i].y);
3942 ok(color_match(color, expected_colors[i].color, 1),
3943 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
3944 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
3946 release_surface_readback(&rb);
3948 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
3949 ok(SUCCEEDED(hr), "Present failed, hr %#lx.\n", hr);
3951 hr = IDirect3DDevice8_SetTexture(device, 0, NULL);
3952 ok(SUCCEEDED(hr), "SetTexture failed, hr %#lx.\n", hr);
3953 hr = IDirect3DDevice8_SetTexture(device, 1, NULL);
3954 ok(SUCCEEDED(hr), "SetTexture failed, hr %#lx.\n", hr);
3955 IDirect3DTexture8_Release(texture);
3957 /* Render offscreen, then onscreen, and finally check the INTZ texture in both areas */
3958 hr = IDirect3DDevice8_CreateTexture(device, 640, 480, 1,
3959 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture);
3960 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#lx.\n", hr);
3961 hr = IDirect3DTexture8_GetSurfaceLevel(texture, 0, &ds);
3962 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#lx.\n", hr);
3963 hr = IDirect3DDevice8_SetRenderTarget(device, rt, ds);
3964 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#lx.\n", hr);
3965 hr = IDirect3DDevice8_SetPixelShader(device, 0);
3966 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#lx.\n", hr);
3968 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
3969 ok(SUCCEEDED(hr), "Clear failed, hr %#lx.\n", hr);
3971 hr = IDirect3DDevice8_BeginScene(device);
3972 ok(SUCCEEDED(hr), "BeginScene failed, hr %#lx.\n", hr);
3973 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, half_quad_1, sizeof(*half_quad_1));
3974 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#lx.\n", hr);
3975 hr = IDirect3DDevice8_EndScene(device);
3976 ok(SUCCEEDED(hr), "EndScene failed, hr %#lx.\n", hr);
3978 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, ds);
3979 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#lx.\n", hr);
3981 hr = IDirect3DDevice8_BeginScene(device);
3982 ok(SUCCEEDED(hr), "BeginScene failed, hr %#lx.\n", hr);
3983 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, half_quad_2, sizeof(*half_quad_2));
3984 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#lx.\n", hr);
3985 hr = IDirect3DDevice8_EndScene(device);
3986 ok(SUCCEEDED(hr), "EndScene failed, hr %#lx.\n", hr);
3988 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, NULL);
3989 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#lx.\n", hr);
3990 IDirect3DSurface8_Release(ds);
3991 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
3992 ok(SUCCEEDED(hr), "SetTexture failed, hr %#lx.\n", hr);
3993 hr = IDirect3DDevice8_SetTexture(device, 1, (IDirect3DBaseTexture8 *)texture);
3994 ok(SUCCEEDED(hr), "SetTexture failed, hr %#lx.\n", hr);
3995 hr = IDirect3DDevice8_SetPixelShader(device, ps);
3996 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#lx.\n", hr);
3998 /* Read the depth values back. */
3999 hr = IDirect3DDevice8_BeginScene(device);
4000 ok(SUCCEEDED(hr), "BeginScene failed, hr %#lx.\n", hr);
4001 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
4002 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#lx.\n", hr);
4003 hr = IDirect3DDevice8_EndScene(device);
4004 ok(SUCCEEDED(hr), "EndScene failed, hr %#lx.\n", hr);
4006 get_surface_readback(original_rt, &rb);
4007 for (i = 0; i < ARRAY_SIZE(expected_colors); ++i)
4009 unsigned int color = get_readback_color(&rb, expected_colors[i].x, expected_colors[i].y);
4010 ok(color_match(color, expected_colors[i].color, 1),
4011 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
4012 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
4014 release_surface_readback(&rb);
4016 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
4017 ok(SUCCEEDED(hr), "Present failed, hr %#lx.\n", hr);
4019 IDirect3DTexture8_Release(texture);
4020 hr = IDirect3DDevice8_DeletePixelShader(device, ps);
4021 ok(SUCCEEDED(hr), "DeletePixelShader failed, hr %#lx.\n", hr);
4022 IDirect3DSurface8_Release(original_rt);
4023 IDirect3DSurface8_Release(rt);
4024 refcount = IDirect3DDevice8_Release(device);
4025 ok(!refcount, "Device has %lu references left.\n", refcount);
4026 done:
4027 IDirect3D8_Release(d3d);
4028 DestroyWindow(window);
4031 static void shadow_test(void)
4033 IDirect3DSurface8 *original_rt, *rt;
4034 struct surface_readback rb;
4035 IDirect3DDevice8 *device;
4036 IDirect3D8 *d3d;
4037 ULONG refcount;
4038 D3DCAPS8 caps;
4039 HWND window;
4040 HRESULT hr;
4041 DWORD ps;
4042 UINT i;
4044 static const DWORD ps_code[] =
4046 0xffff0101, /* ps_1_1 */
4047 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c0, 1.0, 0.0, 1.0, 1.0 */
4048 0x00000051, 0xa00f0001, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c1, 0.0, 1.0, 0.0, 0.0 */
4049 0x00000042, 0xb00f0000, /* tex t0 */
4050 0x00000042, 0xb00f0001, /* tex t1 */
4051 0x00000005, 0xb00f0000, 0xa0e40000, 0xb0e40000, /* mul t0, c0, t0 */
4052 0x00000004, 0x800f0000, 0xa0e40001, 0xb0e40001, 0xb0e40000, /* mad r0, c1, t1, t0 */
4053 0x0000ffff, /* end */
4055 static const struct
4057 D3DFORMAT format;
4058 const char *name;
4060 formats[] =
4062 {D3DFMT_D16_LOCKABLE, "D3DFMT_D16_LOCKABLE"},
4063 {D3DFMT_D32, "D3DFMT_D32"},
4064 {D3DFMT_D15S1, "D3DFMT_D15S1"},
4065 {D3DFMT_D24S8, "D3DFMT_D24S8"},
4066 {D3DFMT_D24X8, "D3DFMT_D24X8"},
4067 {D3DFMT_D24X4S4, "D3DFMT_D24X4S4"},
4068 {D3DFMT_D16, "D3DFMT_D16"},
4070 static const struct
4072 float x, y, z;
4073 float s0, t0, p0;
4074 float s1, t1, p1, q1;
4076 quad[] =
4078 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f},
4079 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f},
4080 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
4081 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f},
4083 static const struct
4085 unsigned int x, y, color;
4087 expected_colors[] =
4089 {400, 60, 0x00000000},
4090 {560, 180, 0xffff00ff},
4091 {560, 300, 0xffff00ff},
4092 {400, 420, 0xffffffff},
4093 {240, 420, 0xffffffff},
4094 { 80, 300, 0x00000000},
4095 { 80, 180, 0x00000000},
4096 {240, 60, 0x00000000},
4099 window = create_window();
4100 d3d = Direct3DCreate8(D3D_SDK_VERSION);
4101 ok(!!d3d, "Failed to create a D3D object.\n");
4102 if (!(device = create_device(d3d, window, window, TRUE)))
4104 skip("Failed to create a D3D device, skipping tests.\n");
4105 goto done;
4108 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
4109 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#lx.\n", hr);
4110 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 1))
4112 skip("No pixel shader 1.1 support, skipping shadow test.\n");
4113 IDirect3DDevice8_Release(device);
4114 goto done;
4117 hr = IDirect3DDevice8_GetRenderTarget(device, &original_rt);
4118 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#lx.\n", hr);
4120 hr = IDirect3DDevice8_CreateRenderTarget(device, 1024, 1024, D3DFMT_A8R8G8B8,
4121 D3DMULTISAMPLE_NONE, FALSE, &rt);
4122 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#lx.\n", hr);
4123 hr = IDirect3DDevice8_CreatePixelShader(device, ps_code, &ps);
4124 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#lx.\n", hr);
4126 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX2
4127 | D3DFVF_TEXCOORDSIZE3(0) | D3DFVF_TEXCOORDSIZE4(1));
4128 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#lx.\n", hr);
4129 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
4130 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
4131 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
4132 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
4133 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
4134 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
4135 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
4136 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
4138 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MINFILTER, D3DTEXF_POINT);
4139 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#lx.\n", hr);
4140 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MIPFILTER, D3DTEXF_POINT);
4141 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#lx.\n", hr);
4142 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MAGFILTER, D3DTEXF_POINT);
4143 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#lx.\n", hr);
4144 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
4145 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#lx.\n", hr);
4147 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP);
4148 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#lx.\n", hr);
4149 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP);
4150 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#lx.\n", hr);
4151 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MAGFILTER, D3DTEXF_POINT);
4152 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#lx.\n", hr);
4153 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MINFILTER, D3DTEXF_POINT);
4154 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#lx.\n", hr);
4155 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MIPFILTER, D3DTEXF_POINT);
4156 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#lx.\n", hr);
4157 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS,
4158 D3DTTFF_COUNT4 | D3DTTFF_PROJECTED);
4159 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#lx.\n", hr);
4161 for (i = 0; i < ARRAY_SIZE(formats); ++i)
4163 D3DFORMAT format = formats[i].format;
4164 IDirect3DTexture8 *texture;
4165 IDirect3DSurface8 *ds;
4166 unsigned int j;
4168 if (FAILED(IDirect3D8_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
4169 D3DFMT_X8R8G8B8, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, format)))
4170 continue;
4172 hr = IDirect3DDevice8_CreateTexture(device, 1024, 1024, 1,
4173 D3DUSAGE_DEPTHSTENCIL, format, D3DPOOL_DEFAULT, &texture);
4174 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#lx.\n", hr);
4176 hr = IDirect3DTexture8_GetSurfaceLevel(texture, 0, &ds);
4177 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#lx.\n", hr);
4179 hr = IDirect3DDevice8_SetRenderTarget(device, rt, ds);
4180 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#lx.\n", hr);
4182 hr = IDirect3DDevice8_SetPixelShader(device, 0);
4183 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#lx.\n", hr);
4185 /* Setup the depth/stencil surface. */
4186 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
4187 ok(SUCCEEDED(hr), "Clear failed, hr %#lx.\n", hr);
4189 hr = IDirect3DDevice8_BeginScene(device);
4190 ok(SUCCEEDED(hr), "BeginScene failed, hr %#lx.\n", hr);
4191 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
4192 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#lx.\n", hr);
4193 hr = IDirect3DDevice8_EndScene(device);
4194 ok(SUCCEEDED(hr), "EndScene failed, hr %#lx.\n", hr);
4196 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, NULL);
4197 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#lx.\n", hr);
4198 IDirect3DSurface8_Release(ds);
4200 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
4201 ok(SUCCEEDED(hr), "SetTexture failed, hr %#lx.\n", hr);
4202 hr = IDirect3DDevice8_SetTexture(device, 1, (IDirect3DBaseTexture8 *)texture);
4203 ok(SUCCEEDED(hr), "SetTexture failed, hr %#lx.\n", hr);
4205 hr = IDirect3DDevice8_SetPixelShader(device, ps);
4206 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#lx.\n", hr);
4208 /* Do the actual shadow mapping. */
4209 hr = IDirect3DDevice8_BeginScene(device);
4210 ok(SUCCEEDED(hr), "BeginScene failed, hr %#lx.\n", hr);
4211 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
4212 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#lx.\n", hr);
4213 hr = IDirect3DDevice8_EndScene(device);
4214 ok(SUCCEEDED(hr), "EndScene failed, hr %#lx.\n", hr);
4216 hr = IDirect3DDevice8_SetTexture(device, 0, NULL);
4217 ok(SUCCEEDED(hr), "SetTexture failed, hr %#lx.\n", hr);
4218 hr = IDirect3DDevice8_SetTexture(device, 1, NULL);
4219 ok(SUCCEEDED(hr), "SetTexture failed, hr %#lx.\n", hr);
4220 IDirect3DTexture8_Release(texture);
4222 get_surface_readback(original_rt, &rb);
4223 for (j = 0; j < ARRAY_SIZE(expected_colors); ++j)
4225 unsigned int color = get_readback_color(&rb, expected_colors[j].x, expected_colors[j].y);
4226 /* Geforce 7 on Windows returns 1.0 in alpha when the depth format is D24S8 or D24X8,
4227 * whereas other GPUs (all AMD, newer Nvidia) return the same value they return in .rgb.
4228 * Accept alpha mismatches as broken but make sure to check the color channels. */
4229 ok(color_match(color, expected_colors[j].color, 0)
4230 || broken(color_match(color & 0x00ffffff, expected_colors[j].color & 0x00ffffff, 0)),
4231 "Expected color 0x%08x at (%u, %u) for format %s, got 0x%08x.\n",
4232 expected_colors[j].color, expected_colors[j].x, expected_colors[j].y,
4233 formats[i].name, color);
4235 release_surface_readback(&rb);
4237 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
4238 ok(SUCCEEDED(hr), "Present failed, hr %#lx.\n", hr);
4241 hr = IDirect3DDevice8_DeletePixelShader(device, ps);
4242 ok(SUCCEEDED(hr), "DeletePixelShader failed, hr %#lx.\n", hr);
4243 IDirect3DSurface8_Release(original_rt);
4244 IDirect3DSurface8_Release(rt);
4245 refcount = IDirect3DDevice8_Release(device);
4246 ok(!refcount, "Device has %lu references left.\n", refcount);
4247 done:
4248 IDirect3D8_Release(d3d);
4249 DestroyWindow(window);
4252 static void multisample_copy_rects_test(void)
4254 IDirect3DSurface8 *ds, *ds_plain, *rt, *readback;
4255 RECT src_rect = {64, 64, 128, 128};
4256 POINT dst_point = {96, 96};
4257 D3DLOCKED_RECT locked_rect;
4258 IDirect3DDevice8 *device;
4259 unsigned int color;
4260 IDirect3D8 *d3d;
4261 ULONG refcount;
4262 HWND window;
4263 HRESULT hr;
4265 window = create_window();
4266 d3d = Direct3DCreate8(D3D_SDK_VERSION);
4267 ok(!!d3d, "Failed to create a D3D object.\n");
4268 if (!(device = create_device(d3d, window, window, TRUE)))
4270 skip("Failed to create a D3D device, skipping tests.\n");
4271 goto done;
4274 if (FAILED(IDirect3D8_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT,
4275 D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES)))
4277 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping multisampled CopyRects test.\n");
4278 IDirect3DDevice8_Release(device);
4279 goto done;
4282 hr = IDirect3DDevice8_CreateRenderTarget(device, 256, 256, D3DFMT_A8R8G8B8,
4283 D3DMULTISAMPLE_2_SAMPLES, FALSE, &rt);
4284 ok(SUCCEEDED(hr), "Failed to create render target, hr %#lx.\n", hr);
4285 hr = IDirect3DDevice8_CreateDepthStencilSurface(device, 256, 256, D3DFMT_D24S8,
4286 D3DMULTISAMPLE_2_SAMPLES, &ds);
4287 ok(SUCCEEDED(hr), "Failed to create depth stencil surface, hr %#lx.\n", hr);
4288 hr = IDirect3DDevice8_CreateDepthStencilSurface(device, 256, 256, D3DFMT_D24S8,
4289 D3DMULTISAMPLE_NONE, &ds_plain);
4290 ok(SUCCEEDED(hr), "Failed to create depth stencil surface, hr %#lx.\n", hr);
4291 hr = IDirect3DDevice8_CreateImageSurface(device, 256, 256, D3DFMT_A8R8G8B8, &readback);
4292 ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#lx.\n", hr);
4294 hr = IDirect3DDevice8_SetRenderTarget(device, rt, ds);
4295 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
4297 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
4298 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#lx.\n", hr);
4300 hr = IDirect3DDevice8_CopyRects(device, rt, NULL, 0, readback, NULL);
4301 ok(SUCCEEDED(hr), "Failed to read render target back, hr %#lx.\n", hr);
4303 hr = IDirect3DDevice8_CopyRects(device, ds, NULL, 0, ds_plain, NULL);
4304 ok(hr == D3DERR_INVALIDCALL, "Depth buffer copy, hr %#lx, expected %#lx.\n", hr, D3DERR_INVALIDCALL);
4306 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4307 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#lx.\n", hr);
4309 hr = IDirect3DDevice8_CopyRects(device, rt, &src_rect, 1, readback, &dst_point);
4310 ok(SUCCEEDED(hr), "Failed to read render target back, hr %#lx.\n", hr);
4312 hr = IDirect3DSurface8_LockRect(readback, &locked_rect, NULL, D3DLOCK_READONLY);
4313 ok(SUCCEEDED(hr), "Failed to lock readback surface, hr %#lx.\n", hr);
4315 color = *(DWORD *)((BYTE *)locked_rect.pBits + 31 * locked_rect.Pitch + 31 * 4);
4316 ok(color == 0xff00ff00, "Got unexpected color 0x%08x.\n", color);
4318 color = *(DWORD *)((BYTE *)locked_rect.pBits + 127 * locked_rect.Pitch + 127 * 4);
4319 ok(color == 0xffff0000, "Got unexpected color 0x%08x.\n", color);
4321 hr = IDirect3DSurface8_UnlockRect(readback);
4322 ok(SUCCEEDED(hr), "Failed to unlock readback surface, hr %#lx.\n", hr);
4324 IDirect3DSurface8_Release(readback);
4325 IDirect3DSurface8_Release(ds_plain);
4326 IDirect3DSurface8_Release(ds);
4327 IDirect3DSurface8_Release(rt);
4328 refcount = IDirect3DDevice8_Release(device);
4329 ok(!refcount, "Device has %lu references left.\n", refcount);
4330 done:
4331 IDirect3D8_Release(d3d);
4332 DestroyWindow(window);
4335 static void resz_test(void)
4337 IDirect3DSurface8 *rt, *original_rt, *ds, *original_ds, *intz_ds;
4338 IDirect3DTexture8 *texture;
4339 IDirect3DDevice8 *device;
4340 IDirect3D8 *d3d;
4341 DWORD ps, value;
4342 unsigned int i;
4343 ULONG refcount;
4344 D3DCAPS8 caps;
4345 HWND window;
4346 HRESULT hr;
4348 static const DWORD ps_code[] =
4350 0xffff0101, /* ps_1_1 */
4351 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1.0, 0.0, 0.0, 0.0 */
4352 0x00000051, 0xa00f0001, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c1, 0.0, 1.0, 0.0, 0.0 */
4353 0x00000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c2, 0.0, 0.0, 1.0, 0.0 */
4354 0x00000042, 0xb00f0000, /* tex t0 */
4355 0x00000042, 0xb00f0001, /* tex t1 */
4356 0x00000008, 0xb0070001, 0xa0e40000, 0xb0e40001, /* dp3 t1.xyz, c0, t1 */
4357 0x00000005, 0x80070000, 0xa0e40001, 0xb0e40001, /* mul r0.xyz, c1, t1 */
4358 0x00000004, 0x80070000, 0xa0e40000, 0xb0e40000, 0x80e40000, /* mad r0.xyz, c0, t0, r0 */
4359 0x40000001, 0x80080000, 0xa0aa0002, /* +mov r0.w, c2.z */
4360 0x0000ffff, /* end */
4362 static const struct
4364 float x, y, z;
4365 float s0, t0, p0;
4366 float s1, t1, p1, q1;
4368 quad[] =
4370 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.5f},
4371 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
4372 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
4373 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.5f},
4375 static const struct
4377 unsigned int x, y, color;
4379 expected_colors[] =
4381 { 80, 100, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
4382 {240, 100, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
4383 {400, 100, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
4384 {560, 100, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
4385 { 80, 450, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
4386 {240, 450, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
4387 {400, 450, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
4388 {560, 450, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
4391 window = create_window();
4392 d3d = Direct3DCreate8(D3D_SDK_VERSION);
4393 ok(!!d3d, "Failed to create a D3D object.\n");
4394 if (!(device = create_device(d3d, window, window, TRUE)))
4396 skip("Failed to create a D3D device, skipping tests.\n");
4397 goto done;
4400 if (FAILED(IDirect3D8_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT,
4401 D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES)))
4403 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping RESZ test.\n");
4404 IDirect3DDevice8_Release(device);
4405 goto done;
4407 if (FAILED(IDirect3D8_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT,
4408 D3DDEVTYPE_HAL, D3DFMT_D24S8, TRUE, D3DMULTISAMPLE_2_SAMPLES)))
4410 skip("Multisampling not supported for D3DFMT_D24S8, skipping RESZ test.\n");
4411 IDirect3DDevice8_Release(device);
4412 goto done;
4414 if (FAILED(IDirect3D8_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
4415 D3DFMT_X8R8G8B8, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, MAKEFOURCC('I','N','T','Z'))))
4417 skip("No INTZ support, skipping RESZ test.\n");
4418 IDirect3DDevice8_Release(device);
4419 goto done;
4421 if (FAILED(IDirect3D8_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
4422 D3DFMT_X8R8G8B8, D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE, MAKEFOURCC('R','E','S','Z'))))
4424 skip("No RESZ support, skipping RESZ test.\n");
4425 IDirect3DDevice8_Release(device);
4426 goto done;
4429 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
4430 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#lx.\n", hr);
4431 if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
4433 skip("No unconditional NP2 texture support, skipping INTZ test.\n");
4434 IDirect3DDevice8_Release(device);
4435 goto done;
4438 hr = IDirect3DDevice8_GetRenderTarget(device, &original_rt);
4439 ok(SUCCEEDED(hr), "Failed to get render target, hr %#lx.\n", hr);
4440 hr = IDirect3DDevice8_GetDepthStencilSurface(device, &original_ds);
4441 ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#lx.\n", hr);
4443 hr = IDirect3DDevice8_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
4444 D3DMULTISAMPLE_2_SAMPLES, FALSE, &rt);
4445 ok(SUCCEEDED(hr), "Failed to create render target, hr %#lx.\n", hr);
4446 hr = IDirect3DDevice8_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
4447 D3DMULTISAMPLE_2_SAMPLES, &ds);
4449 hr = IDirect3DDevice8_CreateTexture(device, 640, 480, 1,
4450 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture);
4451 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#lx.\n", hr);
4452 hr = IDirect3DTexture8_GetSurfaceLevel(texture, 0, &intz_ds);
4453 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#lx.\n", hr);
4455 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, intz_ds);
4456 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
4457 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
4458 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#lx.\n", hr);
4460 hr = IDirect3DDevice8_SetRenderTarget(device, rt, ds);
4461 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
4462 IDirect3DSurface8_Release(intz_ds);
4463 hr = IDirect3DDevice8_CreatePixelShader(device, ps_code, &ps);
4464 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#lx.\n", hr);
4466 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX2
4467 | D3DFVF_TEXCOORDSIZE3(0) | D3DFVF_TEXCOORDSIZE4(1));
4468 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#lx.\n", hr);
4469 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
4470 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
4471 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
4472 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
4473 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
4474 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
4475 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
4476 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
4478 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MINFILTER, D3DTEXF_POINT);
4479 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#lx.\n", hr);
4480 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MIPFILTER, D3DTEXF_POINT);
4481 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#lx.\n", hr);
4482 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MAGFILTER, D3DTEXF_POINT);
4483 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#lx.\n", hr);
4484 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
4485 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#lx.\n", hr);
4487 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP);
4488 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#lx.\n", hr);
4489 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP);
4490 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#lx.\n", hr);
4491 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MAGFILTER, D3DTEXF_POINT);
4492 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#lx.\n", hr);
4493 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MINFILTER, D3DTEXF_POINT);
4494 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#lx.\n", hr);
4495 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MIPFILTER, D3DTEXF_POINT);
4496 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#lx.\n", hr);
4497 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS,
4498 D3DTTFF_COUNT4 | D3DTTFF_PROJECTED);
4499 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#lx.\n", hr);
4501 /* Render offscreen (multisampled), blit the depth buffer into the INTZ texture and then check its contents. */
4502 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
4503 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#lx.\n", hr);
4505 hr = IDirect3DDevice8_BeginScene(device);
4506 ok(SUCCEEDED(hr), "BeginScene failed, hr %#lx.\n", hr);
4507 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
4508 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#lx.\n", hr);
4510 /* The destination depth texture has to be bound to sampler 0 */
4511 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
4512 ok(SUCCEEDED(hr), "SetTexture failed, hr %#lx.\n", hr);
4514 /* the ATI "spec" says you have to do a dummy draw to ensure correct commands ordering */
4515 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, FALSE);
4516 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
4517 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
4518 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
4519 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0);
4520 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
4521 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
4522 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#lx.\n", hr);
4523 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, TRUE);
4524 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
4525 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
4526 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
4527 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0xf);
4528 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
4530 /* The actual multisampled depth buffer resolve happens here */
4531 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
4532 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#lx.\n", hr);
4533 hr = IDirect3DDevice8_GetRenderState(device, D3DRS_POINTSIZE, &value);
4534 ok(SUCCEEDED(hr), "Got hr %#lx.\n", hr);
4535 ok(value == 0x7fa05000, "Got value %#lx.\n", value);
4537 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, NULL);
4538 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
4539 hr = IDirect3DDevice8_SetTexture(device, 1, (IDirect3DBaseTexture8 *)texture);
4540 ok(SUCCEEDED(hr), "SetTexture failed, hr %#lx.\n", hr);
4541 hr = IDirect3DDevice8_SetPixelShader(device, ps);
4542 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#lx.\n", hr);
4544 /* Read the depth values back. */
4545 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
4546 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#lx.\n", hr);
4547 hr = IDirect3DDevice8_EndScene(device);
4548 ok(SUCCEEDED(hr), "EndScene failed, hr %#lx.\n", hr);
4550 for (i = 0; i < ARRAY_SIZE(expected_colors); ++i)
4552 unsigned int color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
4553 ok(color_match(color, expected_colors[i].color, 1),
4554 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
4555 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
4558 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
4559 ok(SUCCEEDED(hr), "Got hr %#lx.\n", hr);
4561 /* Test edge cases - try with no texture at all */
4562 hr = IDirect3DDevice8_SetTexture(device, 0, NULL);
4563 ok(SUCCEEDED(hr), "SetTexture failed, hr %#lx.\n", hr);
4564 hr = IDirect3DDevice8_SetTexture(device, 1, NULL);
4565 ok(SUCCEEDED(hr), "SetTexture failed, hr %#lx.\n", hr);
4566 hr = IDirect3DDevice8_SetRenderTarget(device, rt, ds);
4567 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
4569 hr = IDirect3DDevice8_BeginScene(device);
4570 ok(SUCCEEDED(hr), "BeginScene failed, hr %#lx.\n", hr);
4571 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
4572 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#lx.\n", hr);
4573 hr = IDirect3DDevice8_EndScene(device);
4574 ok(SUCCEEDED(hr), "EndScene failed, hr %#lx.\n", hr);
4576 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
4577 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#lx.\n", hr);
4579 /* With a non-multisampled depth buffer */
4580 IDirect3DSurface8_Release(ds);
4581 IDirect3DSurface8_Release(rt);
4582 hr = IDirect3DDevice8_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
4583 D3DMULTISAMPLE_NONE, &ds);
4585 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, ds);
4586 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
4587 hr = IDirect3DDevice8_SetPixelShader(device, 0);
4588 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#lx.\n", hr);
4590 hr = IDirect3DDevice8_BeginScene(device);
4591 ok(SUCCEEDED(hr), "BeginScene failed, hr %#lx.\n", hr);
4592 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
4593 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#lx.\n", hr);
4594 hr = IDirect3DDevice8_EndScene(device);
4595 ok(SUCCEEDED(hr), "EndScene failed, hr %#lx.\n", hr);
4597 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
4598 ok(SUCCEEDED(hr), "SetTexture failed, hr %#lx.\n", hr);
4600 hr = IDirect3DDevice8_BeginScene(device);
4601 ok(SUCCEEDED(hr), "BeginScene failed, hr %#lx.\n", hr);
4602 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, FALSE);
4603 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
4604 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
4605 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
4606 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0);
4607 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
4608 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
4609 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#lx.\n", hr);
4610 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, TRUE);
4611 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
4612 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
4613 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
4614 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0xf);
4615 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
4616 hr = IDirect3DDevice8_EndScene(device);
4617 ok(SUCCEEDED(hr), "EndScene failed, hr %#lx.\n", hr);
4619 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
4620 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#lx.\n", hr);
4622 hr = IDirect3DDevice8_SetTexture(device, 1, (IDirect3DBaseTexture8 *)texture);
4623 ok(SUCCEEDED(hr), "SetTexture failed, hr %#lx.\n", hr);
4624 hr = IDirect3DDevice8_SetPixelShader(device, ps);
4625 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#lx.\n", hr);
4627 /* Read the depth values back. */
4628 hr = IDirect3DDevice8_BeginScene(device);
4629 ok(SUCCEEDED(hr), "BeginScene failed, hr %#lx.\n", hr);
4630 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
4631 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#lx.\n", hr);
4632 hr = IDirect3DDevice8_EndScene(device);
4633 ok(SUCCEEDED(hr), "EndScene failed, hr %#lx.\n", hr);
4635 for (i = 0; i < ARRAY_SIZE(expected_colors); ++i)
4637 unsigned int color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
4638 ok(color_match(color, expected_colors[i].color, 1),
4639 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
4640 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
4643 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
4644 ok(SUCCEEDED(hr), "Got hr %#lx.\n", hr);
4646 IDirect3DSurface8_Release(ds);
4647 IDirect3DTexture8_Release(texture);
4648 hr = IDirect3DDevice8_DeletePixelShader(device, ps);
4649 ok(SUCCEEDED(hr), "DeletePixelShader failed, hr %#lx.\n", hr);
4650 IDirect3DSurface8_Release(original_ds);
4651 IDirect3DSurface8_Release(original_rt);
4653 refcount = IDirect3DDevice8_Release(device);
4654 ok(!refcount, "Device has %lu references left.\n", refcount);
4655 done:
4656 IDirect3D8_Release(d3d);
4657 DestroyWindow(window);
4660 static void zenable_test(void)
4662 unsigned int color, x, y, i, j, test;
4663 IDirect3DDevice8 *device;
4664 IDirect3D8 *d3d;
4665 ULONG refcount;
4666 D3DCAPS8 caps;
4667 HWND window;
4668 HRESULT hr;
4669 IDirect3DSurface8 *ds, *rt;
4671 static const struct
4673 struct vec4 position;
4674 D3DCOLOR diffuse;
4676 tquad[] =
4678 {{ 0.0f, 480.0f, -0.5f, 1.0f}, 0xff00ff00},
4679 {{ 0.0f, 0.0f, -0.5f, 1.0f}, 0xff00ff00},
4680 {{640.0f, 480.0f, 1.5f, 1.0f}, 0xff00ff00},
4681 {{640.0f, 0.0f, 1.5f, 1.0f}, 0xff00ff00},
4684 window = create_window();
4685 d3d = Direct3DCreate8(D3D_SDK_VERSION);
4686 ok(!!d3d, "Failed to create a D3D object.\n");
4687 if (!(device = create_device(d3d, window, window, TRUE)))
4689 skip("Failed to create a D3D device, skipping tests.\n");
4690 goto done;
4693 hr = IDirect3DDevice8_GetDepthStencilSurface(device, &ds);
4694 ok(SUCCEEDED(hr), "Failed to get depth stencil surface, hr %#lx.\n", hr);
4695 hr = IDirect3DDevice8_GetRenderTarget(device, &rt);
4696 ok(SUCCEEDED(hr), "Failed to get render target surface, hr %#lx.\n", hr);
4698 for (test = 0; test < 2; ++test)
4700 /* The Windows 8 testbot (WARP) appears to clip with
4701 * ZENABLE = D3DZB_TRUE and no depth buffer set. */
4702 static const D3DCOLOR expected_broken[] =
4704 0x00ff0000, 0x0000ff00, 0x0000ff00, 0x00ff0000,
4705 0x00ff0000, 0x0000ff00, 0x0000ff00, 0x00ff0000,
4706 0x00ff0000, 0x0000ff00, 0x0000ff00, 0x00ff0000,
4707 0x00ff0000, 0x0000ff00, 0x0000ff00, 0x00ff0000,
4710 if (!test)
4712 hr = IDirect3DDevice8_SetRenderTarget(device, rt, NULL);
4713 ok(SUCCEEDED(hr), "Failed to set depth stencil surface, hr %#lx.\n", hr);
4715 else
4717 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
4718 ok(SUCCEEDED(hr), "Failed to disable z-buffering, hr %#lx.\n", hr);
4719 hr = IDirect3DDevice8_SetRenderTarget(device, rt, ds);
4720 ok(SUCCEEDED(hr), "Failed to set depth stencil surface, hr %#lx.\n", hr);
4721 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 0.0f, 0);
4722 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#lx.\n", hr);
4724 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
4725 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr);
4727 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0f, 0);
4728 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#lx.\n", hr);
4729 hr = IDirect3DDevice8_BeginScene(device);
4730 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
4731 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, tquad, sizeof(*tquad));
4732 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
4733 hr = IDirect3DDevice8_EndScene(device);
4734 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
4736 for (i = 0; i < 4; ++i)
4738 for (j = 0; j < 4; ++j)
4740 x = 80 * ((2 * j) + 1);
4741 y = 60 * ((2 * i) + 1);
4742 color = getPixelColor(device, x, y);
4743 ok(color_match(color, 0x0000ff00, 1)
4744 || broken(color_match(color, expected_broken[i * 4 + j], 1) && !test),
4745 "Expected color 0x0000ff00 at %u, %u, got 0x%08x.\n", x, y, color);
4749 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
4750 ok(SUCCEEDED(hr), "Failed to present backbuffer, hr %#lx.\n", hr);
4753 IDirect3DSurface8_Release(ds);
4754 IDirect3DSurface8_Release(rt);
4756 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
4757 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
4759 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1)
4760 && caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
4762 static const DWORD vs_code[] =
4764 0xfffe0101, /* vs_1_1 */
4765 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4766 0x00000001, 0xd00f0000, 0x90e40000, /* mov oD0, v0 */
4767 0x0000ffff
4769 static const DWORD ps_code[] =
4771 0xffff0101, /* ps_1_1 */
4772 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
4773 0x0000ffff /* end */
4775 static const struct vec3 quad[] =
4777 {-1.0f, -1.0f, -0.5f},
4778 {-1.0f, 1.0f, -0.5f},
4779 { 1.0f, -1.0f, 1.5f},
4780 { 1.0f, 1.0f, 1.5f},
4782 static const unsigned int expected[] =
4784 0x00ff0000, 0x0060df60, 0x009fdf9f, 0x00ff0000,
4785 0x00ff0000, 0x00609f60, 0x009f9f9f, 0x00ff0000,
4786 0x00ff0000, 0x00606060, 0x009f609f, 0x00ff0000,
4787 0x00ff0000, 0x00602060, 0x009f209f, 0x00ff0000,
4789 /* The Windows 8 testbot (WARP) appears to not clip z for regular
4790 * vertices either. */
4791 static const D3DCOLOR expected_broken[] =
4793 0x0020df20, 0x0060df60, 0x009fdf9f, 0x00dfdfdf,
4794 0x00209f20, 0x00609f60, 0x009f9f9f, 0x00df9fdf,
4795 0x00206020, 0x00606060, 0x009f609f, 0x00df60df,
4796 0x00202020, 0x00602060, 0x009f209f, 0x00df20df,
4798 static const DWORD decl[] =
4800 D3DVSD_STREAM(0),
4801 D3DVSD_REG(D3DVSDE_POSITION, D3DVSDT_FLOAT3),
4802 D3DVSD_END()
4804 DWORD vs, ps;
4806 hr = IDirect3DDevice8_CreateVertexShader(device, decl, vs_code, &vs, 0);
4807 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#lx.\n", hr);
4808 hr = IDirect3DDevice8_CreatePixelShader(device, ps_code, &ps);
4809 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#lx.\n", hr);
4810 hr = IDirect3DDevice8_SetVertexShader(device, vs);
4811 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#lx.\n", hr);
4812 hr = IDirect3DDevice8_SetPixelShader(device, ps);
4813 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#lx.\n", hr);
4815 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0f, 0);
4816 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#lx.\n", hr);
4817 hr = IDirect3DDevice8_BeginScene(device);
4818 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
4819 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
4820 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
4821 hr = IDirect3DDevice8_EndScene(device);
4822 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
4824 for (i = 0; i < 4; ++i)
4826 for (j = 0; j < 4; ++j)
4828 x = 80 * ((2 * j) + 1);
4829 y = 60 * ((2 * i) + 1);
4830 color = getPixelColor(device, x, y);
4831 ok(color_match(color, expected[i * 4 + j], 1)
4832 || broken(color_match(color, expected_broken[i * 4 + j], 1)),
4833 "Expected color 0x%08x at %u, %u, got 0x%08x.\n", expected[i * 4 + j], x, y, color);
4837 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
4838 ok(SUCCEEDED(hr), "Failed to present backbuffer, hr %#lx.\n", hr);
4840 hr = IDirect3DDevice8_DeletePixelShader(device, ps);
4841 ok(SUCCEEDED(hr), "Failed to delete pixel shader, hr %#lx.\n", hr);
4842 hr = IDirect3DDevice8_DeleteVertexShader(device, vs);
4843 ok(SUCCEEDED(hr), "Failed to delete vertex shader, hr %#lx.\n", hr);
4846 refcount = IDirect3DDevice8_Release(device);
4847 ok(!refcount, "Device has %lu references left.\n", refcount);
4848 done:
4849 IDirect3D8_Release(d3d);
4850 DestroyWindow(window);
4853 static void fog_special_test(void)
4855 IDirect3DDevice8 *device;
4856 unsigned int color, i;
4857 IDirect3D8 *d3d;
4858 ULONG refcount;
4859 D3DCAPS8 caps;
4860 DWORD ps, vs;
4861 HWND window;
4862 HRESULT hr;
4863 union
4865 float f;
4866 DWORD d;
4867 } conv;
4869 static const struct
4871 struct vec3 position;
4872 D3DCOLOR diffuse;
4874 quad[] =
4876 {{ -1.0f, -1.0f, 0.0f}, 0xff00ff00},
4877 {{ -1.0f, 1.0f, 0.0f}, 0xff00ff00},
4878 {{ 1.0f, -1.0f, 1.0f}, 0xff00ff00},
4879 {{ 1.0f, 1.0f, 1.0f}, 0xff00ff00}
4881 static const struct
4883 DWORD vertexmode, tablemode;
4884 BOOL vs, ps;
4885 unsigned int color_left, color_right;
4887 tests[] =
4889 {D3DFOG_LINEAR, D3DFOG_NONE, FALSE, FALSE, 0x00ff0000, 0x00ff0000},
4890 {D3DFOG_LINEAR, D3DFOG_NONE, FALSE, TRUE, 0x00ff0000, 0x00ff0000},
4891 {D3DFOG_LINEAR, D3DFOG_NONE, TRUE, FALSE, 0x00ff0000, 0x00ff0000},
4892 {D3DFOG_LINEAR, D3DFOG_NONE, TRUE, TRUE, 0x00ff0000, 0x00ff0000},
4894 {D3DFOG_NONE, D3DFOG_LINEAR, FALSE, FALSE, 0x0000ff00, 0x00ff0000},
4895 {D3DFOG_NONE, D3DFOG_LINEAR, FALSE, TRUE, 0x0000ff00, 0x00ff0000},
4896 {D3DFOG_NONE, D3DFOG_LINEAR, TRUE, FALSE, 0x0000ff00, 0x00ff0000},
4897 {D3DFOG_NONE, D3DFOG_LINEAR, TRUE, TRUE, 0x0000ff00, 0x00ff0000},
4899 static const DWORD pixel_shader_code[] =
4901 0xffff0101, /* ps.1.1 */
4902 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
4903 0x0000ffff
4905 static const DWORD vertex_decl[] =
4907 D3DVSD_STREAM(0),
4908 D3DVSD_REG(0, D3DVSDT_FLOAT3), /* position, v0 */
4909 D3DVSD_REG(1, D3DVSDT_D3DCOLOR), /* diffuse color, v1 */
4910 D3DVSD_END()
4912 static const DWORD vertex_shader_code[] =
4914 0xfffe0101, /* vs.1.1 */
4915 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4916 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
4917 0x0000ffff
4919 static const D3DMATRIX identity =
4921 1.0f, 0.0f, 0.0f, 0.0f,
4922 0.0f, 1.0f, 0.0f, 0.0f,
4923 0.0f, 0.0f, 1.0f, 0.0f,
4924 0.0f, 0.0f, 0.0f, 1.0f,
4925 }}};
4927 window = create_window();
4928 d3d = Direct3DCreate8(D3D_SDK_VERSION);
4929 ok(!!d3d, "Failed to create a D3D object.\n");
4930 if (!(device = create_device(d3d, window, window, TRUE)))
4932 skip("Failed to create a D3D device, skipping tests.\n");
4933 goto done;
4936 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
4937 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
4938 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
4940 hr = IDirect3DDevice8_CreateVertexShader(device, vertex_decl, vertex_shader_code, &vs, 0);
4941 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#lx.\n", hr);
4943 else
4945 skip("Vertex Shaders not supported, skipping some fog tests.\n");
4946 vs = 0;
4948 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
4950 hr = IDirect3DDevice8_CreatePixelShader(device, pixel_shader_code, &ps);
4951 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#lx.\n", hr);
4953 else
4955 skip("Pixel Shaders not supported, skipping some fog tests.\n");
4956 ps = 0;
4959 /* The table fog tests seem to depend on the projection matrix explicitly
4960 * being set to an identity matrix, even though that's the default.
4961 * (AMD Radeon HD 6310, Windows 7) */
4962 hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, &identity);
4963 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#lx.\n", hr);
4965 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
4966 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#lx.\n", hr);
4967 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
4968 ok(SUCCEEDED(hr), "Failed to enable fog, hr %#lx.\n", hr);
4969 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGCOLOR, 0xffff0000);
4970 ok(SUCCEEDED(hr), "Failed to set fog color, hr %#lx.\n", hr);
4972 conv.f = 0.5f;
4973 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGSTART, conv.d);
4974 ok(SUCCEEDED(hr), "Failed to set fog start, hr %#lx.\n", hr);
4975 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGEND, conv.d);
4976 ok(SUCCEEDED(hr), "Failed to set fog end, hr %#lx.\n", hr);
4978 for (i = 0; i < ARRAY_SIZE(tests); i++)
4980 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
4981 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#lx.\n", hr);
4983 if (!tests[i].vs)
4985 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
4986 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#lx.\n", hr);
4988 else if (vs)
4990 hr = IDirect3DDevice8_SetVertexShader(device, vs);
4991 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#lx.\n", hr);
4993 else
4995 continue;
4998 if (!tests[i].ps)
5000 hr = IDirect3DDevice8_SetPixelShader(device, 0);
5001 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#lx.\n", hr);
5003 else if (ps)
5005 hr = IDirect3DDevice8_SetPixelShader(device, ps);
5006 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#lx.\n", hr);
5008 else
5010 continue;
5013 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGVERTEXMODE, tests[i].vertexmode);
5014 ok(SUCCEEDED(hr), "Failed to set fogvertexmode, hr %#lx.\n", hr);
5015 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGTABLEMODE, tests[i].tablemode);
5016 ok(SUCCEEDED(hr), "Failed to set fogtablemode, hr %#lx.\n", hr);
5018 hr = IDirect3DDevice8_BeginScene(device);
5019 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
5020 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
5021 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
5022 hr = IDirect3DDevice8_EndScene(device);
5023 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
5025 color = getPixelColor(device, 310, 240);
5026 ok(color_match(color, tests[i].color_left, 1),
5027 "Expected left color 0x%08x, got 0x%08x, case %u.\n", tests[i].color_left, color, i);
5028 color = getPixelColor(device, 330, 240);
5029 ok(color_match(color, tests[i].color_right, 1),
5030 "Expected right color 0x%08x, got 0x%08x, case %u.\n", tests[i].color_right, color, i);
5032 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5033 ok(SUCCEEDED(hr), "Failed to present backbuffer, hr %#lx.\n", hr);
5036 if (vs)
5037 IDirect3DDevice8_DeleteVertexShader(device, vs);
5038 if (ps)
5039 IDirect3DDevice8_DeletePixelShader(device, ps);
5040 refcount = IDirect3DDevice8_Release(device);
5041 ok(!refcount, "Device has %lu references left.\n", refcount);
5042 done:
5043 IDirect3D8_Release(d3d);
5044 DestroyWindow(window);
5047 static void volume_dxtn_test(void)
5049 IDirect3DVolumeTexture8 *texture;
5050 struct surface_readback rb;
5051 unsigned int colour, i, j;
5052 IDirect3DDevice8 *device;
5053 IDirect3DSurface8 *rt;
5054 D3DLOCKED_BOX box;
5055 IDirect3D8 *d3d;
5056 ULONG refcount;
5057 HWND window;
5058 HRESULT hr;
5060 static const BYTE dxt1_data[] =
5062 0x00, 0xf8, 0x00, 0xf8, 0xf0, 0xf0, 0xf0, 0xf0,
5063 0xe0, 0x07, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00,
5064 0x1f, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00,
5065 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00
5067 static const BYTE dxt3_data[] =
5069 0xff, 0xee, 0xff, 0xee, 0xff, 0xee, 0xff, 0xee, 0x00, 0xf8, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00,
5070 0xff, 0xdd, 0xff, 0xdd, 0xff, 0xdd, 0xff, 0xdd, 0xe0, 0x07, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00,
5071 0xff, 0xcc, 0xff, 0xcc, 0xff, 0xcc, 0xff, 0xcc, 0x1f, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00,
5072 0xff, 0xbb, 0xff, 0xbb, 0xff, 0xbb, 0xff, 0xbb, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00
5074 static const BYTE dxt5_data[] =
5076 /* A 8x4x2 texture consisting of 4 4x4 blocks. The colours of the
5077 * blocks are red, green, blue and white. */
5078 0xff, 0xff, 0x80, 0x0d, 0xd8, 0x80, 0x0d, 0xd8, 0x00, 0xf8, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00,
5079 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00,
5080 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00,
5081 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00
5083 static const unsigned int dxt1_expected_colours[] =
5085 0xffff0000, 0x00000000, 0xff00ff00, 0xff00ff00,
5086 0xff0000ff, 0xff0000ff, 0xffffffff, 0xffffffff,
5088 static const unsigned int dxt3_expected_colours[] =
5090 0xffff0000, 0xeeff0000, 0xff00ff00, 0xdd00ff00,
5091 0xff0000ff, 0xcc0000ff, 0xffffffff, 0xbbffffff,
5093 static const unsigned int dxt5_expected_colours[] =
5095 0xffff0000, 0x00ff0000, 0xff00ff00, 0xff00ff00,
5096 0xff0000ff, 0xff0000ff, 0xffffffff, 0xffffffff
5099 static const struct
5101 const char *name;
5102 D3DFORMAT format;
5103 const BYTE *data;
5104 DWORD data_size;
5105 const unsigned int *expected_colours;
5107 tests[] =
5109 {"DXT1", D3DFMT_DXT1, dxt1_data, sizeof(dxt1_data), dxt1_expected_colours},
5110 {"DXT3", D3DFMT_DXT3, dxt3_data, sizeof(dxt3_data), dxt3_expected_colours},
5111 {"DXT5", D3DFMT_DXT5, dxt5_data, sizeof(dxt5_data), dxt5_expected_colours},
5114 static const struct
5116 struct vec3 position;
5117 struct vec3 texcrd;
5119 quads[] =
5121 {{ -1.0f, -1.0f, 0.0f}, { 0.0f, 0.0f, 0.25f}},
5122 {{ -1.0f, 1.0f, 0.0f}, { 0.0f, 1.0f, 0.25f}},
5123 {{ 0.0f, -1.0f, 1.0f}, { 1.0f, 0.0f, 0.25f}},
5124 {{ 0.0f, 1.0f, 1.0f}, { 1.0f, 1.0f, 0.25f}},
5126 {{ 0.0f, -1.0f, 0.0f}, { 0.0f, 0.0f, 0.75f}},
5127 {{ 0.0f, 1.0f, 0.0f}, { 0.0f, 1.0f, 0.75f}},
5128 {{ 1.0f, -1.0f, 1.0f}, { 1.0f, 0.0f, 0.75f}},
5129 {{ 1.0f, 1.0f, 1.0f}, { 1.0f, 1.0f, 0.75f}},
5132 window = create_window();
5133 d3d = Direct3DCreate8(D3D_SDK_VERSION);
5134 ok(!!d3d, "Failed to create a D3D object.\n");
5136 if (!(device = create_device(d3d, window, window, TRUE)))
5138 skip("Failed to create a D3D device, skipping tests.\n");
5139 goto done;
5142 hr = IDirect3DDevice8_GetRenderTarget(device, &rt);
5143 ok(SUCCEEDED(hr), "Failed to get render target, hr %#lx.\n", hr);
5145 for (i = 0; i < ARRAY_SIZE(tests); ++i)
5147 if (FAILED(IDirect3D8_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
5148 D3DFMT_X8R8G8B8, 0, D3DRTYPE_VOLUMETEXTURE, tests[i].format)))
5150 skip("%s volume textures are not supported, skipping test.\n", tests[i].name);
5151 continue;
5153 hr = IDirect3DDevice8_CreateVolumeTexture(device, 8, 4, 2, 1, 0,
5154 tests[i].format, D3DPOOL_MANAGED, &texture);
5155 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#lx.\n", hr);
5157 hr = IDirect3DVolumeTexture8_LockBox(texture, 0, &box, NULL, 0);
5158 ok(SUCCEEDED(hr), "Failed to lock volume texture, hr %#lx.\n", hr);
5159 memcpy(box.pBits, tests[i].data, tests[i].data_size);
5160 hr = IDirect3DVolumeTexture8_UnlockBox(texture, 0);
5161 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#lx.\n", hr);
5163 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE3(0));
5164 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr);
5165 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
5166 ok(SUCCEEDED(hr), "Failed to set texture, hr %#lx.\n", hr);
5167 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
5168 ok(SUCCEEDED(hr), "Failed to set colour op, hr %#lx.\n", hr);
5169 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
5170 ok(SUCCEEDED(hr), "Failed to set colour arg, hr %#lx.\n", hr);
5171 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
5172 ok(SUCCEEDED(hr), "Failed to set colour op, hr %#lx.\n", hr);
5173 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MAGFILTER, D3DTEXF_POINT);
5174 ok(SUCCEEDED(hr), "Failed to set mag filter, hr %#lx.\n", hr);
5176 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff00ff, 1.0f, 0);
5177 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
5178 hr = IDirect3DDevice8_BeginScene(device);
5179 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
5180 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads));
5181 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
5182 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[4], sizeof(*quads));
5183 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
5184 hr = IDirect3DDevice8_EndScene(device);
5185 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
5187 get_surface_readback(rt, &rb);
5188 for (j = 0; j < ARRAY_SIZE(dxt1_expected_colours); ++j)
5190 colour = get_readback_color(&rb, 40 + 80 * j, 240);
5191 ok(color_match(colour, tests[i].expected_colours[j], 1),
5192 "Expected colour 0x%08x, got 0x%08x, case %u.\n", tests[i].expected_colours[j], colour, j);
5194 release_surface_readback(&rb);
5196 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5197 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
5198 IDirect3DVolumeTexture8_Release(texture);
5201 IDirect3DSurface8_Release(rt);
5202 refcount = IDirect3DDevice8_Release(device);
5203 ok(!refcount, "Device has %lu references left.\n", refcount);
5204 done:
5205 IDirect3D8_Release(d3d);
5206 DestroyWindow(window);
5209 static void volume_v16u16_test(void)
5211 IDirect3DVolumeTexture8 *texture;
5212 IDirect3DDevice8 *device;
5213 unsigned int color, i;
5214 D3DLOCKED_BOX box;
5215 IDirect3D8 *d3d;
5216 ULONG refcount;
5217 D3DCAPS8 caps;
5218 DWORD shader;
5219 SHORT *texel;
5220 HWND window;
5221 HRESULT hr;
5223 static const struct
5225 struct vec3 position;
5226 struct vec3 texcrd;
5228 quads[] =
5230 {{ -1.0f, -1.0f, 0.0f}, { 0.0f, 0.0f, 0.25f}},
5231 {{ -1.0f, 1.0f, 0.0f}, { 0.0f, 1.0f, 0.25f}},
5232 {{ 0.0f, -1.0f, 1.0f}, { 1.0f, 0.0f, 0.25f}},
5233 {{ 0.0f, 1.0f, 1.0f}, { 1.0f, 1.0f, 0.25f}},
5235 {{ 0.0f, -1.0f, 0.0f}, { 0.0f, 0.0f, 0.75f}},
5236 {{ 0.0f, 1.0f, 0.0f}, { 0.0f, 1.0f, 0.75f}},
5237 {{ 1.0f, -1.0f, 1.0f}, { 1.0f, 0.0f, 0.75f}},
5238 {{ 1.0f, 1.0f, 1.0f}, { 1.0f, 1.0f, 0.75f}},
5240 static const DWORD shader_code[] =
5242 0xffff0101, /* ps_1_1 */
5243 0x00000051, 0xa00f0000, 0x3f000000, 0x3f000000, /* def c0, 0.5, 0.5, */
5244 0x3f000000, 0x3f000000, /* 0.5, 0.5 */
5245 0x00000042, 0xb00f0000, /* tex t0 */
5246 0x00000004, 0x800f0000, 0xb0e40000, 0xa0e40000, 0xa0e40000, /* mad r0, t0, c0, c0 */
5247 0x0000ffff /* end */
5250 window = create_window();
5251 d3d = Direct3DCreate8(D3D_SDK_VERSION);
5252 ok(!!d3d, "Failed to create a D3D object.\n");
5253 if (!(device = create_device(d3d, window, window, TRUE)))
5255 skip("Failed to create a D3D device, skipping tests.\n");
5256 goto done;
5259 if (FAILED(IDirect3D8_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
5260 D3DFMT_X8R8G8B8, 0, D3DRTYPE_VOLUMETEXTURE, D3DFMT_V16U16)))
5262 skip("Volume V16U16 textures are not supported, skipping test.\n");
5263 IDirect3DDevice8_Release(device);
5264 goto done;
5266 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
5267 ok(SUCCEEDED(hr), "Failed to get caps, hr %#lx.\n", hr);
5268 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 1))
5270 skip("No pixel shader 1.1 support, skipping test.\n");
5271 IDirect3DDevice8_Release(device);
5272 goto done;
5275 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE3(0));
5276 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr);
5277 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code, &shader);
5278 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#lx.\n", hr);
5279 hr = IDirect3DDevice8_SetPixelShader(device, shader);
5280 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#lx.\n", hr);
5281 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MAGFILTER, D3DTEXF_POINT);
5282 ok(SUCCEEDED(hr), "Failed to set filter, hr %#lx.\n", hr);
5284 for (i = 0; i < 2; i++)
5286 D3DPOOL pool;
5288 if (i)
5289 pool = D3DPOOL_SYSTEMMEM;
5290 else
5291 pool = D3DPOOL_MANAGED;
5293 hr = IDirect3DDevice8_CreateVolumeTexture(device, 1, 2, 2, 1, 0, D3DFMT_V16U16,
5294 pool, &texture);
5295 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#lx.\n", hr);
5297 hr = IDirect3DVolumeTexture8_LockBox(texture, 0, &box, NULL, 0);
5298 ok(SUCCEEDED(hr), "Failed to lock volume texture, hr %#lx.\n", hr);
5300 texel = (SHORT *)((BYTE *)box.pBits + 0 * box.RowPitch + 0 * box.SlicePitch);
5301 texel[0] = 32767;
5302 texel[1] = 32767;
5303 texel = (SHORT *)((BYTE *)box.pBits + 1 * box.RowPitch + 0 * box.SlicePitch);
5304 texel[0] = -32768;
5305 texel[1] = 0;
5306 texel = (SHORT *)((BYTE *)box.pBits + 0 * box.RowPitch + 1 * box.SlicePitch);
5307 texel[0] = -16384;
5308 texel[1] = 16384;
5309 texel = (SHORT *)((BYTE *)box.pBits + 1 * box.RowPitch + 1 * box.SlicePitch);
5310 texel[0] = 0;
5311 texel[1] = 0;
5313 hr = IDirect3DVolumeTexture8_UnlockBox(texture, 0);
5314 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#lx.\n", hr);
5316 if (i)
5318 IDirect3DVolumeTexture8 *texture2;
5320 hr = IDirect3DDevice8_CreateVolumeTexture(device, 1, 2, 2, 1, 0, D3DFMT_V16U16,
5321 D3DPOOL_DEFAULT, &texture2);
5322 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#lx.\n", hr);
5324 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)texture,
5325 (IDirect3DBaseTexture8 *)texture2);
5326 ok(SUCCEEDED(hr), "Failed to update texture, hr %#lx.\n", hr);
5328 IDirect3DVolumeTexture8_Release(texture);
5329 texture = texture2;
5332 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *) texture);
5333 ok(SUCCEEDED(hr), "Failed to set texture, hr %#lx.\n", hr);
5335 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff00ff, 1.0f, 0);
5336 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
5337 hr = IDirect3DDevice8_BeginScene(device);
5338 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
5339 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads));
5340 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
5341 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[4], sizeof(*quads));
5342 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
5343 hr = IDirect3DDevice8_EndScene(device);
5344 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
5346 color = getPixelColor(device, 120, 160);
5347 ok (color_match(color, 0x000080ff, 2),
5348 "Expected color 0x000080ff, got 0x%08x, V16U16 input -32768, 0.\n", color);
5349 color = getPixelColor(device, 120, 400);
5350 ok (color_match(color, 0x00ffffff, 2),
5351 "Expected color 0x00ffffff, got 0x%08x, V16U16 input 32767, 32767.\n", color);
5352 color = getPixelColor(device, 360, 160);
5353 ok (color_match(color, 0x007f7fff, 2),
5354 "Expected color 0x007f7fff, got 0x%08x, V16U16 input 0, 0.\n", color);
5355 color = getPixelColor(device, 360, 400);
5356 ok (color_match(color, 0x0040c0ff, 2),
5357 "Expected color 0x0040c0ff, got 0x%08x, V16U16 input -16384, 16384.\n", color);
5359 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5360 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
5362 IDirect3DVolumeTexture8_Release(texture);
5365 hr = IDirect3DDevice8_DeletePixelShader(device, shader);
5366 ok(SUCCEEDED(hr), "Failed delete pixel shader, hr %#lx.\n", hr);
5367 refcount = IDirect3DDevice8_Release(device);
5368 ok(!refcount, "Device has %lu references left.\n", refcount);
5369 done:
5370 IDirect3D8_Release(d3d);
5371 DestroyWindow(window);
5374 static void fill_surface(IDirect3DSurface8 *surface, DWORD color, DWORD flags)
5376 D3DSURFACE_DESC desc;
5377 D3DLOCKED_RECT l;
5378 HRESULT hr;
5379 unsigned int x, y;
5380 DWORD *mem;
5382 hr = IDirect3DSurface8_GetDesc(surface, &desc);
5383 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#lx.\n", hr);
5384 hr = IDirect3DSurface8_LockRect(surface, &l, NULL, flags);
5385 ok(SUCCEEDED(hr), "Failed to lock surface, hr %#lx.\n", hr);
5386 if (FAILED(hr))
5387 return;
5389 for (y = 0; y < desc.Height; y++)
5391 mem = (DWORD *)((BYTE *)l.pBits + y * l.Pitch);
5392 for (x = 0; x < l.Pitch / sizeof(DWORD); x++)
5394 mem[x] = color;
5397 hr = IDirect3DSurface8_UnlockRect(surface);
5398 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#lx.\n", hr);
5401 static void add_dirty_rect_test_draw(IDirect3DDevice8 *device)
5403 HRESULT hr;
5404 static const struct
5406 struct vec3 position;
5407 struct vec2 texcoord;
5409 quad[] =
5411 {{-1.0f, -1.0f, 0.0f}, {0.0f, 0.0f}},
5412 {{-1.0f, 1.0f, 0.0f}, {0.0f, 1.0f}},
5413 {{ 1.0f, -1.0f, 0.0f}, {1.0f, 0.0f}},
5414 {{ 1.0f, 1.0f, 0.0f}, {1.0f, 1.0f}},
5417 hr = IDirect3DDevice8_BeginScene(device);
5418 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
5419 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad, sizeof(*quad));
5420 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
5421 hr = IDirect3DDevice8_EndScene(device);
5422 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
5425 static void add_dirty_rect_test(void)
5427 IDirect3DTexture8 *tex_dst1, *tex_dst2, *tex_src_red, *tex_src_green,
5428 *tex_managed, *tex_dynamic;
5429 IDirect3DSurface8 *surface_dst2, *surface_src_green, *surface_src_red,
5430 *surface_managed0, *surface_managed1, *surface_dynamic;
5431 struct surface_readback rb;
5432 D3DLOCKED_RECT locked_rect;
5433 IDirect3DDevice8 *device;
5434 unsigned int color, i;
5435 IDirect3D8 *d3d;
5436 ULONG refcount;
5437 DWORD *texel;
5438 HWND window;
5439 HRESULT hr;
5441 static const RECT part_rect = {96, 96, 160, 160};
5442 static const RECT oob_rect[] =
5444 { 0, 0, 200, 300},
5445 { 0, 0, 300, 200},
5446 {100, 100, 10, 10},
5447 {200, 300, 10, 10},
5448 {300, 200, 310, 210},
5449 { 0, 0, 0, 0},
5452 window = create_window();
5453 d3d = Direct3DCreate8(D3D_SDK_VERSION);
5454 ok(!!d3d, "Failed to create a D3D object.\n");
5455 if (!(device = create_device(d3d, window, window, TRUE)))
5457 skip("Failed to create a D3D device, skipping tests.\n");
5458 goto done;
5461 hr = IDirect3DDevice8_CreateTexture(device, 256, 256, 1, 0, D3DFMT_X8R8G8B8,
5462 D3DPOOL_DEFAULT, &tex_dst1);
5463 ok(SUCCEEDED(hr), "Failed to create texture, hr %#lx.\n", hr);
5464 hr = IDirect3DDevice8_CreateTexture(device, 256, 256, 1, 0, D3DFMT_X8R8G8B8,
5465 D3DPOOL_DEFAULT, &tex_dst2);
5466 ok(SUCCEEDED(hr), "Failed to create texture, hr %#lx.\n", hr);
5467 hr = IDirect3DDevice8_CreateTexture(device, 256, 256, 1, 0, D3DFMT_X8R8G8B8,
5468 D3DPOOL_SYSTEMMEM, &tex_src_red);
5469 ok(SUCCEEDED(hr), "Failed to create texture, hr %#lx.\n", hr);
5470 hr = IDirect3DDevice8_CreateTexture(device, 256, 256, 1, 0, D3DFMT_X8R8G8B8,
5471 D3DPOOL_SYSTEMMEM, &tex_src_green);
5472 ok(SUCCEEDED(hr), "Failed to create texture, hr %#lx.\n", hr);
5473 hr = IDirect3DDevice8_CreateTexture(device, 256, 256, 2, 0, D3DFMT_X8R8G8B8,
5474 D3DPOOL_MANAGED, &tex_managed);
5475 ok(SUCCEEDED(hr), "Failed to create texture, hr %#lx.\n", hr);
5476 hr = IDirect3DDevice8_CreateTexture(device, 256, 256, 1, D3DUSAGE_DYNAMIC,
5477 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &tex_dynamic);
5478 ok(SUCCEEDED(hr), "Failed to create texture, hr %#lx.\n", hr);
5480 hr = IDirect3DTexture8_GetSurfaceLevel(tex_dst2, 0, &surface_dst2);
5481 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#lx.\n", hr);
5482 hr = IDirect3DTexture8_GetSurfaceLevel(tex_src_green, 0, &surface_src_green);
5483 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#lx.\n", hr);
5484 hr = IDirect3DTexture8_GetSurfaceLevel(tex_src_red, 0, &surface_src_red);
5485 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#lx.\n", hr);
5486 hr = IDirect3DTexture8_GetSurfaceLevel(tex_managed, 0, &surface_managed0);
5487 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#lx.\n", hr);
5488 hr = IDirect3DTexture8_GetSurfaceLevel(tex_managed, 1, &surface_managed1);
5489 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#lx.\n", hr);
5490 hr = IDirect3DTexture8_GetSurfaceLevel(tex_dynamic, 0, &surface_dynamic);
5491 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#lx.\n", hr);
5493 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX1);
5494 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#lx.\n", hr);
5495 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
5496 ok(SUCCEEDED(hr), "Failed to set color op, hr %#lx.\n", hr);
5497 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
5498 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#lx.\n", hr);
5499 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MIPFILTER, D3DTEXF_POINT);
5500 ok(SUCCEEDED(hr), "Failed to set mip filter, hr %#lx.\n", hr);
5502 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)tex_dst2);
5503 ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr);
5504 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_red,
5505 (IDirect3DBaseTexture8 *)tex_dst2);
5506 fill_surface(surface_src_green, 0x00000080, D3DLOCK_NO_DIRTY_UPDATE);
5507 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_green,
5508 (IDirect3DBaseTexture8 *)tex_dst2);
5509 ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr);
5510 add_dirty_rect_test_draw(device);
5511 color = getPixelColor(device, 320, 240);
5512 ok(color_match(color, 0x00000080, 1), "Unexpected colour 0x%08x.\n", color);
5513 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5514 ok(hr == D3D_OK, "Unexpected hr %#lx.\n", hr);
5516 fill_surface(surface_src_red, 0x00ff0000, 0);
5517 fill_surface(surface_src_green, 0x0000ff00, 0);
5519 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_green,
5520 (IDirect3DBaseTexture8 *)tex_dst1);
5521 ok(SUCCEEDED(hr), "Failed to update texture, hr %#lx.\n", hr);
5523 /* The second UpdateTexture call writing to tex_dst2 is ignored because tex_src_green is not dirty. */
5524 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_red,
5525 (IDirect3DBaseTexture8 *)tex_dst2);
5526 ok(SUCCEEDED(hr), "Failed to update texture, hr %#lx.\n", hr);
5527 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_green,
5528 (IDirect3DBaseTexture8 *)tex_dst2);
5529 ok(SUCCEEDED(hr), "Failed to update texture, hr %#lx.\n", hr);
5531 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)tex_dst1);
5532 ok(SUCCEEDED(hr), "Failed to set texture, hr %#lx.\n", hr);
5533 add_dirty_rect_test_draw(device);
5534 color = getPixelColor(device, 320, 240);
5535 ok(color_match(color, 0x0000ff00, 1),
5536 "Expected color 0x0000ff00, got 0x%08x.\n", color);
5537 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5538 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
5540 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)tex_dst2);
5541 ok(SUCCEEDED(hr), "Failed to set texture, hr %#lx.\n", hr);
5542 add_dirty_rect_test_draw(device);
5543 color = getPixelColor(device, 320, 240);
5544 ok(color_match(color, 0x00ff0000, 1),
5545 "Expected color 0x00ff0000, got 0x%08x.\n", color);
5546 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5547 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
5549 /* AddDirtyRect on the destination is ignored. */
5550 hr = IDirect3DTexture8_AddDirtyRect(tex_dst2, &part_rect);
5551 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#lx.\n", hr);
5552 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_green,
5553 (IDirect3DBaseTexture8 *)tex_dst2);
5554 ok(SUCCEEDED(hr), "Failed to update texture, hr %#lx.\n", hr);
5555 add_dirty_rect_test_draw(device);
5556 color = getPixelColor(device, 320, 240);
5557 ok(color_match(color, 0x00ff0000, 1),
5558 "Expected color 0x00ff0000, got 0x%08x.\n", color);
5559 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5560 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
5562 hr = IDirect3DTexture8_AddDirtyRect(tex_dst2, NULL);
5563 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#lx.\n", hr);
5564 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_green,
5565 (IDirect3DBaseTexture8 *)tex_dst2);
5566 ok(SUCCEEDED(hr), "Failed to update texture, hr %#lx.\n", hr);
5567 add_dirty_rect_test_draw(device);
5568 color = getPixelColor(device, 320, 240);
5569 ok(color_match(color, 0x00ff0000, 1),
5570 "Expected color 0x00ff0000, got 0x%08x.\n", color);
5571 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5572 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
5574 /* AddDirtyRect on the source makes UpdateTexture work. Partial rectangle
5575 * tracking is supported. */
5576 hr = IDirect3DTexture8_AddDirtyRect(tex_src_green, &part_rect);
5577 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#lx.\n", hr);
5578 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_green,
5579 (IDirect3DBaseTexture8 *)tex_dst2);
5580 ok(SUCCEEDED(hr), "Failed to update texture, hr %#lx.\n", hr);
5581 add_dirty_rect_test_draw(device);
5582 color = getPixelColor(device, 320, 240);
5583 ok(color_match(color, 0x0000ff00, 1),
5584 "Expected color 0x0000ff00, got 0x%08x.\n", color);
5585 color = getPixelColor(device, 1, 1);
5586 ok(color_match(color, 0x00ff0000, 1),
5587 "Expected color 0x00ff0000, got 0x%08x.\n", color);
5588 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5589 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
5591 hr = IDirect3DTexture8_AddDirtyRect(tex_src_green, NULL);
5592 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#lx.\n", hr);
5593 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_green,
5594 (IDirect3DBaseTexture8 *)tex_dst2);
5595 ok(SUCCEEDED(hr), "Failed to update texture, hr %#lx.\n", hr);
5596 add_dirty_rect_test_draw(device);
5597 color = getPixelColor(device, 1, 1);
5598 ok(color_match(color, 0x0000ff00, 1),
5599 "Expected color 0x0000ff00, got 0x%08x.\n", color);
5601 /* UpdateTexture() ignores locks made with D3DLOCK_NO_DIRTY_UPDATE. */
5602 fill_surface(surface_src_green, 0x00000080, D3DLOCK_NO_DIRTY_UPDATE);
5603 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_green,
5604 (IDirect3DBaseTexture8 *)tex_dst2);
5605 ok(SUCCEEDED(hr), "Failed to update texture, hr %#lx.\n", hr);
5606 add_dirty_rect_test_draw(device);
5607 color = getPixelColor(device, 320, 240);
5608 ok(color_match(color, 0x0000ff00, 1),
5609 "Expected color 0x0000ff00, got 0x%08x.\n", color);
5610 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5611 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
5613 /* Manually copying the surface works, though. */
5614 hr = IDirect3DDevice8_CopyRects(device, surface_src_green, NULL, 0, surface_dst2, NULL);
5615 ok(hr == D3D_OK, "Failed to copy rects, hr %#lx.\n", hr);
5616 add_dirty_rect_test_draw(device);
5617 color = getPixelColor(device, 320, 240);
5618 ok(color_match(color, 0x00000080, 1), "Got unexpected colour 0x%08x.\n", color);
5619 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5620 ok(hr == D3D_OK, "Failed to present, hr %#lx.\n", hr);
5622 /* Readonly maps write to D3DPOOL_SYSTEMMEM, but don't record a dirty rectangle. */
5623 fill_surface(surface_src_green, 0x000000ff, D3DLOCK_READONLY);
5624 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_green,
5625 (IDirect3DBaseTexture8 *)tex_dst2);
5626 ok(SUCCEEDED(hr), "Failed to update texture, hr %#lx.\n", hr);
5627 add_dirty_rect_test_draw(device);
5628 color = getPixelColor(device, 320, 240);
5629 ok(color_match(color, 0x00000080, 1), "Got unexpected colour 0x%08x.\n", color);
5630 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5631 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
5633 hr = IDirect3DTexture8_AddDirtyRect(tex_src_green, NULL);
5634 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_green,
5635 (IDirect3DBaseTexture8 *)tex_dst2);
5636 ok(SUCCEEDED(hr), "Failed to update texture, hr %#lx.\n", hr);
5637 add_dirty_rect_test_draw(device);
5638 color = getPixelColor(device, 320, 240);
5639 ok(color_match(color, 0x000000ff, 1),
5640 "Expected color 0x000000ff, got 0x%08x.\n", color);
5641 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5642 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
5644 /* Maps without either of these flags record a dirty rectangle. */
5645 fill_surface(surface_src_green, 0x00ffffff, 0);
5646 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_green,
5647 (IDirect3DBaseTexture8 *)tex_dst2);
5648 ok(SUCCEEDED(hr), "Failed to update texture, hr %#lx.\n", hr);
5649 add_dirty_rect_test_draw(device);
5650 color = getPixelColor(device, 320, 240);
5651 ok(color_match(color, 0x00ffffff, 1),
5652 "Expected color 0x00ffffff, got 0x%08x.\n", color);
5653 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5654 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
5656 /* Partial LockRect works just like a partial AddDirtyRect call. */
5657 hr = IDirect3DTexture8_LockRect(tex_src_green, 0, &locked_rect, &part_rect, 0);
5658 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#lx.\n", hr);
5659 texel = locked_rect.pBits;
5660 for (i = 0; i < 64; i++)
5661 texel[i] = 0x00ff00ff;
5662 for (i = 1; i < 64; i++)
5663 memcpy((BYTE *)locked_rect.pBits + i * locked_rect.Pitch, locked_rect.pBits, locked_rect.Pitch);
5664 hr = IDirect3DTexture8_UnlockRect(tex_src_green, 0);
5665 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#lx.\n", hr);
5666 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_green,
5667 (IDirect3DBaseTexture8 *)tex_dst2);
5668 ok(SUCCEEDED(hr), "Failed to update texture, hr %#lx.\n", hr);
5669 add_dirty_rect_test_draw(device);
5670 color = getPixelColor(device, 320, 240);
5671 ok(color_match(color, 0x00ff00ff, 1),
5672 "Expected color 0x00ff00ff, got 0x%08x.\n", color);
5673 color = getPixelColor(device, 1, 1);
5674 ok(color_match(color, 0x00ffffff, 1),
5675 "Expected color 0x00ffffff, got 0x%08x.\n", color);
5676 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5677 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
5679 fill_surface(surface_src_red, 0x00ff0000, 0);
5680 fill_surface(surface_src_green, 0x0000ff00, 0);
5682 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_green,
5683 (IDirect3DBaseTexture8 *)tex_dst1);
5684 ok(SUCCEEDED(hr), "Failed to update texture, hr %#lx.\n", hr);
5685 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)tex_dst1);
5686 ok(SUCCEEDED(hr), "Failed to set texture, hr %#lx.\n", hr);
5687 add_dirty_rect_test_draw(device);
5688 color = getPixelColor(device, 320, 240);
5689 ok(color_match(color, 0x0000ff00, 1),
5690 "Expected color 0x0000ff00, got 0x%08x.\n", color);
5691 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5692 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
5694 /* CopyRects() ignores the missing dirty marker. */
5695 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_red,
5696 (IDirect3DBaseTexture8 *)tex_dst2);
5697 hr = IDirect3DDevice8_CopyRects(device, surface_src_green, NULL, 0, surface_dst2, NULL);
5698 ok(SUCCEEDED(hr), "Failed to update surface, hr %#lx.\n", hr);
5699 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)tex_dst2);
5700 ok(SUCCEEDED(hr), "Failed to set texture, hr %#lx.\n", hr);
5701 add_dirty_rect_test_draw(device);
5702 color = getPixelColor(device, 320, 240);
5703 ok(color_match(color, 0x0000ff00, 1),
5704 "Expected color 0x0000ff00, got 0x%08x.\n", color);
5705 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5706 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
5708 fill_surface(surface_src_green, 0x000000ff, D3DLOCK_NO_DIRTY_UPDATE);
5710 /* So does drawing directly from the sysmem texture. */
5711 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)tex_src_green);
5712 ok(hr == S_OK, "Failed to set texture, hr %#lx.\n", hr);
5713 add_dirty_rect_test_draw(device);
5714 color = getPixelColor(device, 320, 240);
5715 ok(color_match(color, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color);
5717 /* Blitting to the sysmem texture adds a dirty rect. */
5718 fill_surface(surface_src_red, 0x00000000, D3DLOCK_NO_DIRTY_UPDATE);
5719 fill_surface(surface_src_green, 0x00ff00ff, D3DLOCK_NO_DIRTY_UPDATE);
5720 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)tex_dst1);
5721 ok(hr == S_OK, "Failed to set texture, hr %#lx.\n", hr);
5722 hr = IDirect3DDevice8_CopyRects(device, surface_src_green, NULL, 0, surface_src_red, NULL);
5723 ok(hr == S_OK, "Failed to update surface, hr %#lx.\n", hr);
5724 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_red,
5725 (IDirect3DBaseTexture8 *)tex_dst1);
5726 ok(hr == S_OK, "Failed to update texture, hr %#lx.\n", hr);
5727 add_dirty_rect_test_draw(device);
5728 color = getPixelColor(device, 320, 240);
5729 ok(color_match(color, 0x00ff00ff, 1), "Got unexpected color 0x%08x.\n", color);
5731 /* Tests with managed textures. */
5732 fill_surface(surface_managed0, 0x00ff0000, 0);
5733 fill_surface(surface_managed1, 0x00ff0000, 0);
5734 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)tex_managed);
5735 ok(SUCCEEDED(hr), "Failed to set texture, hr %#lx.\n", hr);
5736 add_dirty_rect_test_draw(device);
5737 color = getPixelColor(device, 320, 240);
5738 ok(color_match(color, 0x00ff0000, 1),
5739 "Expected color 0x00ff0000, got 0x%08x.\n", color);
5740 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5741 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
5742 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MAXMIPLEVEL, 1);
5743 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#lx.\n", hr);
5744 add_dirty_rect_test_draw(device);
5745 color = getPixelColor(device, 320, 240);
5746 ok(color_match(color, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color);
5747 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5748 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
5750 /* Managed textures also honor D3DLOCK_NO_DIRTY_UPDATE. */
5751 fill_surface(surface_managed0, 0x0000ff00, D3DLOCK_NO_DIRTY_UPDATE);
5752 fill_surface(surface_managed1, 0x000000ff, D3DLOCK_NO_DIRTY_UPDATE);
5753 add_dirty_rect_test_draw(device);
5754 color = getPixelColor(device, 320, 240);
5755 ok(color_match(color, 0x00ff0000, 1),
5756 "Expected color 0x00ff0000, got 0x%08x.\n", color);
5757 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5758 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
5759 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MAXMIPLEVEL, 0);
5760 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#lx.\n", hr);
5761 add_dirty_rect_test_draw(device);
5762 color = getPixelColor(device, 320, 240);
5763 ok(color_match(color, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color);
5764 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5765 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
5767 /* AddDirtyRect uploads the new contents.
5768 * Partial surface updates work, and two separate dirty rectangles are
5769 * tracked individually. Tested on Nvidia Kepler, other drivers untested. */
5770 hr = IDirect3DTexture8_AddDirtyRect(tex_managed, &part_rect);
5771 ok(hr == S_OK, "Failed to add dirty rect, hr %#lx.\n", hr);
5772 add_dirty_rect_test_draw(device);
5773 color = getPixelColor(device, 320, 240);
5774 ok(color_match(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
5775 color = getPixelColor(device, 1, 1);
5776 todo_wine ok(color_match(color, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color);
5777 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5778 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
5780 hr = IDirect3DTexture8_AddDirtyRect(tex_managed, NULL);
5781 ok(hr == S_OK, "Failed to add dirty rect, hr %#lx.\n", hr);
5782 add_dirty_rect_test_draw(device);
5783 color = getPixelColor(device, 320, 240);
5784 ok(color_match(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
5785 color = getPixelColor(device, 1, 1);
5786 ok(color_match(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
5787 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5788 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
5790 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MAXMIPLEVEL, 1);
5791 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#lx.\n", hr);
5792 add_dirty_rect_test_draw(device);
5793 color = getPixelColor(device, 320, 240);
5794 ok(color_match(color, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color);
5795 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5796 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
5798 /* So does ResourceManagerDiscardBytes. */
5799 fill_surface(surface_managed0, 0x00ffff00, D3DLOCK_NO_DIRTY_UPDATE);
5800 fill_surface(surface_managed1, 0x00ff00ff, D3DLOCK_NO_DIRTY_UPDATE);
5801 hr = IDirect3DDevice8_ResourceManagerDiscardBytes(device, 0);
5802 ok(SUCCEEDED(hr), "Failed to evict managed resources, hr %#lx.\n", hr);
5803 add_dirty_rect_test_draw(device);
5804 color = getPixelColor(device, 320, 240);
5805 ok(color_match(color, 0x00ff00ff, 1), "Got unexpected color 0x%08x.\n", color);
5806 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5807 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
5808 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MAXMIPLEVEL, 0);
5809 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#lx.\n", hr);
5810 add_dirty_rect_test_draw(device);
5811 color = getPixelColor(device, 320, 240);
5812 ok(color_match(color, 0x00ffff00, 1), "Got unexpected color 0x%08x.\n", color);
5813 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5814 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
5816 /* Test blitting from a managed texture. */
5817 fill_surface(surface_managed0, 0x0000ff00, D3DLOCK_NO_DIRTY_UPDATE);
5818 hr = IDirect3DDevice8_CopyRects(device, surface_managed0, NULL, 0, surface_dst2, NULL);
5819 ok(hr == D3D_OK, "Failed to update surface, hr %#lx.\n", hr);
5820 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)tex_dst2);
5821 ok(hr == D3D_OK, "Failed to set texture, hr %#lx.\n", hr);
5822 add_dirty_rect_test_draw(device);
5823 color = getPixelColor(device, 320, 240);
5824 ok(color_match(color, 0x0000ff00, 1), "Got unexpected colour 0x%08x.\n", color);
5825 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5826 ok(hr == D3D_OK, "Failed to present, hr %#lx.\n", hr);
5828 /* Test blitting to a managed texture. */
5829 fill_surface(surface_managed0, 0x000000ff, 0);
5830 /* Draw so that both the CPU and GPU copies are blue. */
5831 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)tex_managed);
5832 ok(SUCCEEDED(hr), "Failed to set texture, hr %#lx.\n", hr);
5833 add_dirty_rect_test_draw(device);
5834 color = getPixelColor(device, 320, 240);
5835 ok(color_match(color, 0x000000ff, 0), "Got unexpected colour 0x%08x.\n", color);
5836 hr = IDirect3DDevice8_CopyRects(device, surface_dst2, NULL, 0, surface_managed0, NULL);
5837 ok(hr == D3D_OK, "Failed to update surface, hr %#lx.\n", hr);
5838 add_dirty_rect_test_draw(device);
5839 color = getPixelColor(device, 320, 240);
5840 ok(color_match(color, 0x0000ff00, 0), "Got unexpected colour 0x%08x.\n", color);
5841 get_surface_readback(surface_managed0, &rb);
5842 color = get_readback_color(&rb, 320, 240) & 0x00ffffff;
5843 ok(color_match(color, 0x0000ff00, 0), "Got unexpected colour 0x%08x.\n", color);
5844 release_surface_readback(&rb);
5846 /* Tests with dynamic textures */
5847 fill_surface(surface_dynamic, 0x0000ffff, 0);
5848 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)tex_dynamic);
5849 ok(SUCCEEDED(hr), "Failed to set texture, hr %#lx.\n", hr);
5850 add_dirty_rect_test_draw(device);
5851 color = getPixelColor(device, 320, 240);
5852 ok(color_match(color, 0x0000ffff, 1),
5853 "Expected color 0x0000ffff, got 0x%08x.\n", color);
5854 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5855 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
5857 /* Dynamic textures don't honor D3DLOCK_NO_DIRTY_UPDATE. */
5858 fill_surface(surface_dynamic, 0x00ffff00, D3DLOCK_NO_DIRTY_UPDATE);
5859 add_dirty_rect_test_draw(device);
5860 color = getPixelColor(device, 320, 240);
5861 ok(color_match(color, 0x00ffff00, 1),
5862 "Expected color 0x00ffff00, got 0x%08x.\n", color);
5863 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5864 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
5866 /* AddDirtyRect on a locked texture is allowed. */
5867 hr = IDirect3DTexture8_LockRect(tex_src_red, 0, &locked_rect, NULL, 0);
5868 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#lx.\n", hr);
5869 hr = IDirect3DTexture8_AddDirtyRect(tex_src_red, NULL);
5870 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#lx.\n", hr);
5871 hr = IDirect3DTexture8_UnlockRect(tex_src_red, 0);
5872 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#lx.\n", hr);
5874 /* Redundant AddDirtyRect calls are ok. */
5875 hr = IDirect3DTexture8_AddDirtyRect(tex_managed, NULL);
5876 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#lx.\n", hr);
5877 hr = IDirect3DTexture8_AddDirtyRect(tex_managed, NULL);
5878 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#lx.\n", hr);
5880 /* Test out-of-bounds regions. */
5881 for (i = 0; i < ARRAY_SIZE(oob_rect); ++i)
5883 hr = IDirect3DTexture8_AddDirtyRect(tex_src_red, &oob_rect[i]);
5884 ok(hr == D3DERR_INVALIDCALL, "[%u] Got unexpected hr %#lx.\n", i, hr);
5885 hr = IDirect3DTexture8_LockRect(tex_src_red, 0, &locked_rect, &oob_rect[i], 0);
5886 ok(SUCCEEDED(hr), "[%u] Got unexpected hr %#lx.\n", i, hr);
5887 hr = IDirect3DTexture8_UnlockRect(tex_src_red, 0);
5888 ok(SUCCEEDED(hr), "[%u] Got unexpected hr %#lx.\n", i, hr);
5891 IDirect3DSurface8_Release(surface_dst2);
5892 IDirect3DSurface8_Release(surface_managed1);
5893 IDirect3DSurface8_Release(surface_managed0);
5894 IDirect3DSurface8_Release(surface_src_red);
5895 IDirect3DSurface8_Release(surface_src_green);
5896 IDirect3DSurface8_Release(surface_dynamic);
5897 IDirect3DTexture8_Release(tex_src_red);
5898 IDirect3DTexture8_Release(tex_src_green);
5899 IDirect3DTexture8_Release(tex_dst1);
5900 IDirect3DTexture8_Release(tex_dst2);
5901 IDirect3DTexture8_Release(tex_managed);
5902 IDirect3DTexture8_Release(tex_dynamic);
5904 /* As above, test CopyRect() after locking the source with
5905 * D3DLOCK_NO_DIRTY_UPDATE, but this time do it immediately after creating
5906 * the destination texture. This is a regression test for a previously
5907 * broken code path. */
5909 hr = IDirect3DDevice8_CreateTexture(device, 256, 256, 1, 0, D3DFMT_X8R8G8B8,
5910 D3DPOOL_DEFAULT, &tex_dst2);
5911 ok(hr == D3D_OK, "Failed to create texture, hr %#lx.\n", hr);
5912 hr = IDirect3DDevice8_CreateTexture(device, 256, 256, 1, 0, D3DFMT_X8R8G8B8,
5913 D3DPOOL_SYSTEMMEM, &tex_src_green);
5914 ok(hr == D3D_OK, "Failed to create texture, hr %#lx.\n", hr);
5916 hr = IDirect3DTexture8_GetSurfaceLevel(tex_dst2, 0, &surface_dst2);
5917 ok(hr == D3D_OK, "Failed to get surface level, hr %#lx.\n", hr);
5918 hr = IDirect3DTexture8_GetSurfaceLevel(tex_src_green, 0, &surface_src_green);
5919 ok(hr == D3D_OK, "Failed to get surface level, hr %#lx.\n", hr);
5921 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)tex_dst2);
5922 ok(hr == D3D_OK, "Failed to set texture, hr %#lx.\n", hr);
5923 fill_surface(surface_src_green, 0x00ff0000, D3DLOCK_NO_DIRTY_UPDATE);
5924 hr = IDirect3DDevice8_CopyRects(device, surface_src_green, NULL, 0, surface_dst2, NULL);
5925 ok(hr == D3D_OK, "Failed to copy rects, hr %#lx.\n", hr);
5926 add_dirty_rect_test_draw(device);
5927 color = getPixelColor(device, 320, 240);
5928 ok(color_match(color, 0x00ff0000, 1), "Got unexpected colour 0x%08x.\n", color);
5929 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5930 ok(hr == D3D_OK, "Failed to present, hr %#lx.\n", hr);
5932 IDirect3DSurface8_Release(surface_dst2);
5933 IDirect3DSurface8_Release(surface_src_green);
5934 IDirect3DTexture8_Release(tex_dst2);
5935 IDirect3DTexture8_Release(tex_src_green);
5937 refcount = IDirect3DDevice8_Release(device);
5938 ok(!refcount, "Device has %lu references left.\n", refcount);
5939 done:
5940 IDirect3D8_Release(d3d);
5941 DestroyWindow(window);
5944 static void test_buffer_no_dirty_update(void)
5946 unsigned int refcount, colour;
5947 IDirect3DVertexBuffer8 *vb;
5948 IDirect3DDevice8 *device;
5949 IDirect3D8 *d3d;
5950 HWND window;
5951 HRESULT hr;
5952 BYTE *data;
5954 static const struct
5956 struct vec3 position;
5957 DWORD diffuse;
5959 green_quad[] =
5961 {{-1.0f, -1.0f, 0.1f}, 0xff00ff00},
5962 {{-1.0f, 1.0f, 0.1f}, 0xff00ff00},
5963 {{ 1.0f, -1.0f, 0.1f}, 0xff00ff00},
5965 {{ 1.0f, -1.0f, 0.1f}, 0xff00ff00},
5966 {{-1.0f, 1.0f, 0.1f}, 0xff00ff00},
5967 {{ 1.0f, 1.0f, 0.1f}, 0xff00ff00},
5969 red_quad[] =
5971 {{-1.0f, -1.0f, 0.1f}, 0xffff0000},
5972 {{-1.0f, 1.0f, 0.1f}, 0xffff0000},
5973 {{ 1.0f, -1.0f, 0.1f}, 0xffff0000},
5975 {{ 1.0f, -1.0f, 0.1f}, 0xffff0000},
5976 {{-1.0f, 1.0f, 0.1f}, 0xffff0000},
5977 {{ 1.0f, 1.0f, 0.1f}, 0xffff0000},
5980 window = create_window();
5981 d3d = Direct3DCreate8(D3D_SDK_VERSION);
5982 ok(!!d3d, "Failed to create a D3D object.\n");
5983 if (!(device = create_device(d3d, window, window, TRUE)))
5985 skip("Failed to create a D3D device.\n");
5986 goto done;
5989 hr = IDirect3DDevice8_CreateVertexBuffer(device, sizeof(green_quad), 0, 0, D3DPOOL_MANAGED, &vb);
5990 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
5992 hr = IDirect3DVertexBuffer8_Lock(vb, 0, 0, &data, 0);
5993 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
5994 memcpy(data, red_quad, sizeof(red_quad));
5995 hr = IDirect3DVertexBuffer8_Unlock(vb);
5996 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
5998 hr = IDirect3DVertexBuffer8_Lock(vb, 0, 0, &data, D3DLOCK_NO_DIRTY_UPDATE);
5999 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
6000 memcpy(data, green_quad, sizeof(green_quad));
6001 hr = IDirect3DVertexBuffer8_Unlock(vb);
6002 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
6004 hr = IDirect3DDevice8_BeginScene(device);
6005 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
6006 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6007 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
6008 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, FALSE);
6009 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
6010 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
6011 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
6012 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
6013 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
6014 hr = IDirect3DDevice8_SetStreamSource(device, 0, vb, sizeof(*green_quad));
6015 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
6016 hr = IDirect3DDevice8_DrawPrimitive(device, D3DPT_TRIANGLELIST, 0, 2);
6017 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
6018 hr = IDirect3DDevice8_EndScene(device);
6019 ok(hr == D3D_OK, "Got hr %#lx.\n", hr);
6020 colour = getPixelColor(device, 320, 240);
6021 ok(color_match(colour, 0x0000ff00, 1), "Got unexpected colour 0x%08x.\n", colour);
6023 IDirect3DVertexBuffer8_Release(vb);
6024 refcount = IDirect3DDevice8_Release(device);
6025 ok(!refcount, "Device has %u references left.\n", refcount);
6026 done:
6027 IDirect3D8_Release(d3d);
6028 DestroyWindow(window);
6031 static void test_3dc_formats(void)
6033 static const char ati1n_data[] =
6035 /* A 4x4 texture with the color component at 50%. */
6036 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6038 static const char ati2n_data[] =
6040 /* A 8x4 texture consisting of 2 4x4 blocks. The first block has 50% first color component,
6041 * 0% second component. Second block is the opposite. */
6042 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6043 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6045 static const struct
6047 struct vec3 position;
6048 struct vec2 texcoord;
6050 quads[] =
6052 {{-1.0f, -1.0f, 0.0f}, {0.0f, 0.0f}},
6053 {{-1.0f, 1.0f, 0.0f}, {0.0f, 1.0f}},
6054 {{ 0.0f, -1.0f, 1.0f}, {1.0f, 0.0f}},
6055 {{ 0.0f, 1.0f, 1.0f}, {1.0f, 1.0f}},
6057 {{ 0.0f, -1.0f, 0.0f}, {0.0f, 0.0f}},
6058 {{ 0.0f, 1.0f, 0.0f}, {0.0f, 1.0f}},
6059 {{ 1.0f, -1.0f, 1.0f}, {1.0f, 0.0f}},
6060 {{ 1.0f, 1.0f, 1.0f}, {1.0f, 1.0f}},
6062 static const DWORD ati1n_fourcc = MAKEFOURCC('A','T','I','1');
6063 static const DWORD ati2n_fourcc = MAKEFOURCC('A','T','I','2');
6064 static const struct
6066 struct vec2 position;
6067 D3DCOLOR amd_r500;
6068 D3DCOLOR amd_r600;
6069 D3DCOLOR nvidia_old;
6070 D3DCOLOR nvidia_new;
6072 expected_colors[] =
6074 {{ 80, 240}, 0x007fffff, 0x003f3f3f, 0x007f7f7f, 0x007f0000},
6075 {{240, 240}, 0x007fffff, 0x003f3f3f, 0x007f7f7f, 0x007f0000},
6076 {{400, 240}, 0x00007fff, 0x00007fff, 0x00007fff, 0x00007fff},
6077 {{560, 240}, 0x007f00ff, 0x007f00ff, 0x007f00ff, 0x007f00ff},
6079 IDirect3D8 *d3d;
6080 IDirect3DDevice8 *device;
6081 IDirect3DTexture8 *ati1n_texture, *ati2n_texture;
6082 unsigned int color, i;
6083 D3DCAPS8 caps;
6084 D3DLOCKED_RECT rect;
6085 ULONG refcount;
6086 HWND window;
6087 HRESULT hr;
6089 window = create_window();
6090 d3d = Direct3DCreate8(D3D_SDK_VERSION);
6091 ok(!!d3d, "Failed to create a D3D object.\n");
6092 if (FAILED(IDirect3D8_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
6093 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, ati1n_fourcc)))
6095 skip("ATI1N textures are not supported, skipping test.\n");
6096 goto done;
6098 if (FAILED(IDirect3D8_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
6099 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, ati2n_fourcc)))
6101 skip("ATI2N textures are not supported, skipping test.\n");
6102 goto done;
6104 if (!(device = create_device(d3d, window, window, TRUE)))
6106 skip("Failed to create a D3D device, skipping tests.\n");
6107 goto done;
6109 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
6110 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
6111 if (!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP))
6113 skip("D3DTA_TEMP not supported, skipping tests.\n");
6114 IDirect3DDevice8_Release(device);
6115 goto done;
6118 hr = IDirect3DDevice8_CreateTexture(device, 4, 4, 1, 0, ati1n_fourcc,
6119 D3DPOOL_MANAGED, &ati1n_texture);
6120 ok(SUCCEEDED(hr), "Failed to create texture, hr %#lx.\n", hr);
6122 hr = IDirect3DTexture8_LockRect(ati1n_texture, 0, &rect, NULL, 0);
6123 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#lx.\n", hr);
6124 memcpy(rect.pBits, ati1n_data, sizeof(ati1n_data));
6125 hr = IDirect3DTexture8_UnlockRect(ati1n_texture, 0);
6126 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#lx.\n", hr);
6128 hr = IDirect3DDevice8_CreateTexture(device, 8, 4, 1, 0, ati2n_fourcc,
6129 D3DPOOL_MANAGED, &ati2n_texture);
6130 ok(SUCCEEDED(hr), "Failed to create texture, hr %#lx.\n", hr);
6132 hr = IDirect3DTexture8_LockRect(ati2n_texture, 0, &rect, NULL, 0);
6133 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#lx.\n", hr);
6134 memcpy(rect.pBits, ati2n_data, sizeof(ati2n_data));
6135 hr = IDirect3DTexture8_UnlockRect(ati2n_texture, 0);
6136 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#lx.\n", hr);
6138 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE2(0));
6139 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr);
6140 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BLENDTEXTUREALPHA);
6141 ok(SUCCEEDED(hr), "Failed to set color op, hr %#lx.\n", hr);
6142 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
6143 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#lx.\n", hr);
6144 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TEMP);
6145 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#lx.\n", hr);
6146 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
6147 ok(SUCCEEDED(hr), "Failed to set alpha op, hr %#lx.\n", hr);
6148 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
6149 ok(SUCCEEDED(hr), "Failed to set alpha arg, hr %#lx.\n", hr);
6150 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
6151 ok(SUCCEEDED(hr), "Failed to set color op, hr %#lx.\n", hr);
6152 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MAGFILTER, D3DTEXF_POINT);
6153 ok(SUCCEEDED(hr), "Failed to set mag filter, hr %#lx.\n", hr);
6155 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff00ff, 1.0f, 0);
6156 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
6157 hr = IDirect3DDevice8_BeginScene(device);
6158 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
6159 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)ati1n_texture);
6160 ok(SUCCEEDED(hr), "Failed to set texture, hr %#lx.\n", hr);
6161 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads));
6162 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
6163 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)ati2n_texture);
6164 ok(SUCCEEDED(hr), "Failed to set texture, hr %#lx.\n", hr);
6165 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[4], sizeof(*quads));
6166 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
6167 hr = IDirect3DDevice8_EndScene(device);
6168 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
6170 for (i = 0; i < 4; ++i)
6172 color = getPixelColor(device, expected_colors[i].position.x, expected_colors[i].position.y);
6173 ok (color_match(color, expected_colors[i].amd_r500, 1)
6174 || color_match(color, expected_colors[i].amd_r600, 1)
6175 || color_match(color, expected_colors[i].nvidia_old, 1)
6176 || color_match(color, expected_colors[i].nvidia_new, 1),
6177 "Got unexpected color 0x%08x, case %u.\n", color, i);
6180 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
6181 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
6182 IDirect3DTexture8_Release(ati2n_texture);
6183 IDirect3DTexture8_Release(ati1n_texture);
6184 refcount = IDirect3DDevice8_Release(device);
6185 ok(!refcount, "Device has %lu references left.\n", refcount);
6187 done:
6188 IDirect3D8_Release(d3d);
6189 DestroyWindow(window);
6192 static void test_fog_interpolation(void)
6194 HRESULT hr;
6195 IDirect3DDevice8 *device;
6196 unsigned int color, i;
6197 IDirect3D8 *d3d;
6198 ULONG refcount;
6199 HWND window;
6201 static const struct
6203 struct vec3 position;
6204 D3DCOLOR diffuse;
6205 D3DCOLOR specular;
6207 quad[] =
6209 {{-1.0f, -1.0f, 0.0f}, 0xffff0000, 0xff000000},
6210 {{-1.0f, 1.0f, 0.0f}, 0xffff0000, 0xff000000},
6211 {{ 1.0f, -1.0f, 1.0f}, 0xffff0000, 0x00000000},
6212 {{ 1.0f, 1.0f, 1.0f}, 0xffff0000, 0x00000000},
6214 union
6216 DWORD d;
6217 float f;
6218 } conv;
6219 static const struct
6221 D3DFOGMODE vfog, tfog;
6222 D3DSHADEMODE shade;
6223 D3DCOLOR middle_color;
6224 BOOL todo;
6226 tests[] =
6228 {D3DFOG_NONE, D3DFOG_NONE, D3DSHADE_FLAT, 0x00007f80, FALSE},
6229 {D3DFOG_NONE, D3DFOG_NONE, D3DSHADE_GOURAUD, 0x00007f80, FALSE},
6230 {D3DFOG_EXP, D3DFOG_NONE, D3DSHADE_FLAT, 0x00007f80, TRUE},
6231 {D3DFOG_EXP, D3DFOG_NONE, D3DSHADE_GOURAUD, 0x00007f80, TRUE},
6232 {D3DFOG_NONE, D3DFOG_EXP, D3DSHADE_FLAT, 0x0000ea15, FALSE},
6233 {D3DFOG_NONE, D3DFOG_EXP, D3DSHADE_GOURAUD, 0x0000ea15, FALSE},
6234 {D3DFOG_EXP, D3DFOG_EXP, D3DSHADE_FLAT, 0x0000ea15, FALSE},
6235 {D3DFOG_EXP, D3DFOG_EXP, D3DSHADE_GOURAUD, 0x0000ea15, FALSE},
6237 static const D3DMATRIX ident_mat =
6239 1.0f, 0.0f, 0.0f, 0.0f,
6240 0.0f, 1.0f, 0.0f, 0.0f,
6241 0.0f, 0.0f, 1.0f, 0.0f,
6242 0.0f, 0.0f, 0.0f, 1.0f
6243 }}};
6244 D3DCAPS8 caps;
6246 window = create_window();
6247 d3d = Direct3DCreate8(D3D_SDK_VERSION);
6248 ok(!!d3d, "Failed to create a D3D object.\n");
6250 if (!(device = create_device(d3d, window, window, TRUE)))
6252 skip("Failed to create a D3D device, skipping tests.\n");
6253 IDirect3D8_Release(d3d);
6254 DestroyWindow(window);
6255 return;
6258 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
6259 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
6260 if (!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE))
6261 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping some fog tests\n");
6263 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
6264 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#lx.\n", hr);
6265 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6266 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
6267 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, FALSE);
6268 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
6269 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
6270 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
6271 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGCOLOR, 0x0000ff00);
6272 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
6273 conv.f = 5.0;
6274 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGDENSITY, conv.d);
6275 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
6277 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
6278 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#lx.\n", hr);
6279 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TFACTOR);
6280 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#lx.\n", hr);
6281 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x000000ff);
6282 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
6284 /* Some of the tests seem to depend on the projection matrix explicitly
6285 * being set to an identity matrix, even though that's the default.
6286 * (AMD Radeon X1600, AMD Radeon HD 6310, Windows 7). Without this,
6287 * the drivers seem to use a static z = 1.0 input for the fog equation.
6288 * The input value is independent of the actual z and w component of
6289 * the vertex position. */
6290 hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, &ident_mat);
6291 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#lx.\n", hr);
6293 for (i = 0; i < ARRAY_SIZE(tests); i++)
6295 if(!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE) && tests[i].tfog)
6296 continue;
6298 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00808080, 0.0f, 0);
6299 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
6301 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SHADEMODE, tests[i].shade);
6302 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
6303 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGVERTEXMODE, tests[i].vfog);
6304 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
6305 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGTABLEMODE, tests[i].tfog);
6306 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
6307 hr = IDirect3DDevice8_BeginScene(device);
6308 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
6309 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
6310 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
6311 hr = IDirect3DDevice8_EndScene(device);
6312 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
6314 color = getPixelColor(device, 0, 240);
6315 ok(color_match(color, 0x000000ff, 2), "Got unexpected color 0x%08x, case %u.\n", color, i);
6316 color = getPixelColor(device, 320, 240);
6317 todo_wine_if (tests[i].todo)
6318 ok(color_match(color, tests[i].middle_color, 2),
6319 "Got unexpected color 0x%08x, case %u.\n", color, i);
6320 color = getPixelColor(device, 639, 240);
6321 ok(color_match(color, 0x0000fd02, 2), "Got unexpected color 0x%08x, case %u.\n", color, i);
6322 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
6323 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
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_negative_fixedfunction_fog(void)
6334 HRESULT hr;
6335 IDirect3DDevice8 *device;
6336 unsigned int color, i;
6337 IDirect3D8 *d3d;
6338 ULONG refcount;
6339 HWND window;
6341 static const struct
6343 struct vec3 position;
6344 D3DCOLOR diffuse;
6346 quad[] =
6348 {{-1.0f, -1.0f, -0.5f}, 0xffff0000},
6349 {{-1.0f, 1.0f, -0.5f}, 0xffff0000},
6350 {{ 1.0f, -1.0f, -0.5f}, 0xffff0000},
6351 {{ 1.0f, 1.0f, -0.5f}, 0xffff0000},
6353 static const struct
6355 struct vec4 position;
6356 D3DCOLOR diffuse;
6358 tquad[] =
6360 {{ 0.0f, 0.0f, -0.5f, 1.0f}, 0xffff0000},
6361 {{640.0f, 0.0f, -0.5f, 1.0f}, 0xffff0000},
6362 {{ 0.0f, 480.0f, -0.5f, 1.0f}, 0xffff0000},
6363 {{640.0f, 480.0f, -0.5f, 1.0f}, 0xffff0000},
6365 static const D3DMATRIX zero =
6367 1.0f, 0.0f, 0.0f, 0.0f,
6368 0.0f, 1.0f, 0.0f, 0.0f,
6369 0.0f, 0.0f, 0.0f, 0.0f,
6370 0.0f, 0.0f, 0.0f, 1.0f
6371 }}};
6372 /* Needed to make AMD drivers happy. Yeah, it is not supposed to
6373 * have an effect on RHW draws. */
6374 static const D3DMATRIX identity =
6376 1.0f, 0.0f, 0.0f, 0.0f,
6377 0.0f, 1.0f, 0.0f, 0.0f,
6378 0.0f, 0.0f, 1.0f, 0.0f,
6379 0.0f, 0.0f, 0.0f, 1.0f
6380 }}};
6381 static const struct
6383 DWORD pos_type;
6384 const void *quad;
6385 size_t stride;
6386 const D3DMATRIX *matrix;
6387 union
6389 float f;
6390 DWORD d;
6391 } start, end;
6392 D3DFOGMODE vfog, tfog;
6393 DWORD color, color_broken, color_broken2;
6395 tests[] =
6397 /* Run the XYZRHW tests first. Depth clamping is broken after RHW draws on the testbot.
6399 * Geforce8+ GPUs on Windows abs() table fog, everything else does not. */
6400 {D3DFVF_XYZRHW, tquad, sizeof(*tquad), &identity, { 0.0f}, {1.0f},
6401 D3DFOG_NONE, D3DFOG_LINEAR, 0x00ff0000, 0x00808000, 0x00808000},
6402 /* r200 GPUs and presumably all d3d8 and older HW clamp the fog
6403 * parameters to 0.0 and 1.0 in the table fog case. */
6404 {D3DFVF_XYZRHW, tquad, sizeof(*tquad), &identity, {-1.0f}, {0.0f},
6405 D3DFOG_NONE, D3DFOG_LINEAR, 0x00808000, 0x00ff0000, 0x0000ff00},
6406 /* test_fog_interpolation shows that vertex fog evaluates the fog
6407 * equation in the vertex pipeline. Start = -1.0 && end = 0.0 shows
6408 * that the abs happens before the fog equation is evaluated.
6410 * Vertex fog abs() behavior is the same on all GPUs. */
6411 {D3DFVF_XYZ, quad, sizeof(*quad), &zero, { 0.0f}, {1.0f},
6412 D3DFOG_LINEAR, D3DFOG_NONE, 0x00808000, 0x00808000, 0x00808000},
6413 {D3DFVF_XYZ, quad, sizeof(*quad), &zero, {-1.0f}, {0.0f},
6414 D3DFOG_LINEAR, D3DFOG_NONE, 0x0000ff00, 0x0000ff00, 0x0000ff00},
6415 {D3DFVF_XYZ, quad, sizeof(*quad), &zero, { 0.0f}, {1.0f},
6416 D3DFOG_EXP, D3DFOG_NONE, 0x009b6400, 0x009b6400, 0x009b6400},
6418 D3DCAPS8 caps;
6420 window = create_window();
6421 d3d = Direct3DCreate8(D3D_SDK_VERSION);
6422 ok(!!d3d, "Failed to create a D3D object.\n");
6424 if (!(device = create_device(d3d, window, window, TRUE)))
6426 skip("Failed to create a D3D device, skipping tests.\n");
6427 IDirect3D8_Release(d3d);
6428 DestroyWindow(window);
6429 return;
6432 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
6433 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
6434 if (!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE))
6435 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping some fog tests.\n");
6437 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6438 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
6439 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
6440 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
6441 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
6442 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
6443 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGCOLOR, 0x0000ff00);
6444 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
6445 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, FALSE);
6446 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
6448 for (i = 0; i < ARRAY_SIZE(tests); i++)
6450 if (!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE) && tests[i].tfog)
6451 continue;
6453 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x000000ff, 0.0f, 0);
6454 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
6456 hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, tests[i].matrix);
6457 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#lx.\n", hr);
6458 hr = IDirect3DDevice8_SetVertexShader(device, tests[i].pos_type | D3DFVF_DIFFUSE);
6459 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#lx.\n", hr);
6460 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGSTART, tests[i].start.d);
6461 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
6462 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGEND, tests[i].end.d);
6463 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
6464 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGVERTEXMODE, tests[i].vfog);
6465 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
6466 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGTABLEMODE, tests[i].tfog);
6467 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
6469 hr = IDirect3DDevice8_BeginScene(device);
6470 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
6471 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, tests[i].quad, tests[i].stride);
6472 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
6473 hr = IDirect3DDevice8_EndScene(device);
6474 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
6476 color = getPixelColor(device, 320, 240);
6477 ok(color_match(color, tests[i].color, 2) || broken(color_match(color, tests[i].color_broken, 2))
6478 || broken(color_match(color, tests[i].color_broken2, 2)),
6479 "Got unexpected color 0x%08x, case %u.\n", color, i);
6480 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
6481 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
6484 refcount = IDirect3DDevice8_Release(device);
6485 ok(!refcount, "Device has %lu references left.\n", refcount);
6486 IDirect3D8_Release(d3d);
6487 DestroyWindow(window);
6490 static void test_table_fog_zw(void)
6492 HRESULT hr;
6493 IDirect3DDevice8 *device;
6494 unsigned int color, i;
6495 IDirect3D8 *d3d;
6496 ULONG refcount;
6497 HWND window;
6498 D3DCAPS8 caps;
6499 static struct
6501 struct vec4 position;
6502 D3DCOLOR diffuse;
6504 quad[] =
6506 {{ 0.0f, 0.0f, 0.0f, 0.0f}, 0xffff0000},
6507 {{640.0f, 0.0f, 0.0f, 0.0f}, 0xffff0000},
6508 {{ 0.0f, 480.0f, 0.0f, 0.0f}, 0xffff0000},
6509 {{640.0f, 480.0f, 0.0f, 0.0f}, 0xffff0000},
6511 static const D3DMATRIX identity =
6513 1.0f, 0.0f, 0.0f, 0.0f,
6514 0.0f, 1.0f, 0.0f, 0.0f,
6515 0.0f, 0.0f, 1.0f, 0.0f,
6516 0.0f, 0.0f, 0.0f, 1.0f
6517 }}};
6518 static const struct
6520 float z, w;
6521 D3DZBUFFERTYPE z_test;
6522 unsigned int color;
6524 tests[] =
6526 {0.7f, 0.0f, D3DZB_TRUE, 0x004cb200},
6527 {0.7f, 0.0f, D3DZB_FALSE, 0x004cb200},
6528 {0.7f, 0.3f, D3DZB_TRUE, 0x004cb200},
6529 {0.7f, 0.3f, D3DZB_FALSE, 0x004cb200},
6530 {0.7f, 3.0f, D3DZB_TRUE, 0x004cb200},
6531 {0.7f, 3.0f, D3DZB_FALSE, 0x004cb200},
6532 {0.3f, 0.0f, D3DZB_TRUE, 0x00b24c00},
6533 {0.3f, 0.0f, D3DZB_FALSE, 0x00b24c00},
6536 window = create_window();
6537 d3d = Direct3DCreate8(D3D_SDK_VERSION);
6538 ok(!!d3d, "Failed to create a D3D object.\n");
6540 if (!(device = create_device(d3d, window, window, TRUE)))
6542 skip("Failed to create a D3D device, skipping tests.\n");
6543 IDirect3D8_Release(d3d);
6544 DestroyWindow(window);
6545 return;
6548 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
6549 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
6550 if (!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE))
6552 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping POSITIONT table fog test.\n");
6553 goto done;
6556 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6557 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
6558 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
6559 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
6560 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGCOLOR, 0x0000ff00);
6561 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
6562 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, FALSE);
6563 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#lx.\n", hr);
6564 /* Work around an AMD Windows driver bug. Needs a proj matrix applied redundantly. */
6565 hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, &identity);
6566 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#lx.\n", hr);
6567 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
6568 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
6569 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
6570 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#lx.\n", hr);
6572 for (i = 0; i < ARRAY_SIZE(tests); ++i)
6574 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
6575 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
6577 quad[0].position.z = tests[i].z;
6578 quad[1].position.z = tests[i].z;
6579 quad[2].position.z = tests[i].z;
6580 quad[3].position.z = tests[i].z;
6581 quad[0].position.w = tests[i].w;
6582 quad[1].position.w = tests[i].w;
6583 quad[2].position.w = tests[i].w;
6584 quad[3].position.w = tests[i].w;
6585 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, tests[i].z_test);
6586 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
6588 hr = IDirect3DDevice8_BeginScene(device);
6589 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
6590 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
6591 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
6592 hr = IDirect3DDevice8_EndScene(device);
6593 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
6595 color = getPixelColor(device, 320, 240);
6596 ok(color_match(color, tests[i].color, 2),
6597 "Got unexpected color 0x%08x, expected 0x%08x, case %u.\n", color, tests[i].color, i);
6598 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
6599 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
6602 done:
6603 refcount = IDirect3DDevice8_Release(device);
6604 ok(!refcount, "Device has %lu references left.\n", refcount);
6605 IDirect3D8_Release(d3d);
6606 DestroyWindow(window);
6609 static void test_signed_formats(void)
6611 unsigned int expected_color, color, i, j, x, y;
6612 IDirect3DDevice8 *device;
6613 HWND window;
6614 HRESULT hr;
6615 IDirect3DTexture8 *texture, *texture_sysmem;
6616 D3DLOCKED_RECT locked_rect;
6617 DWORD shader, shader_alpha;
6618 IDirect3D8 *d3d;
6619 D3DCAPS8 caps;
6620 ULONG refcount;
6622 /* See comments in the d3d9 version of this test for an
6623 * explanation of these values. */
6624 static const USHORT content_v8u8[4][4] =
6626 {0x0000, 0x7f7f, 0x8880, 0x0000},
6627 {0x0080, 0x8000, 0x7f00, 0x007f},
6628 {0x193b, 0xe8c8, 0x0808, 0xf8f8},
6629 {0x4444, 0xc0c0, 0xa066, 0x22e0},
6631 static const DWORD content_v16u16[4][4] =
6633 {0x00000000, 0x7fff7fff, 0x88008000, 0x00000000},
6634 {0x00008000, 0x80000000, 0x7fff0000, 0x00007fff},
6635 {0x19993bbb, 0xe800c800, 0x08880888, 0xf800f800},
6636 {0x44444444, 0xc000c000, 0xa0006666, 0x2222e000},
6638 static const DWORD content_q8w8v8u8[4][4] =
6640 {0x00000000, 0xff7f7f7f, 0x7f008880, 0x817f0000},
6641 {0x10000080, 0x20008000, 0x30007f00, 0x4000007f},
6642 {0x5020193b, 0x6028e8c8, 0x70020808, 0x807ff8f8},
6643 {0x90414444, 0xa000c0c0, 0x8261a066, 0x834922e0},
6645 static const DWORD content_x8l8v8u8[4][4] =
6647 {0x00000000, 0x00ff7f7f, 0x00008880, 0x00ff0000},
6648 {0x00000080, 0x00008000, 0x00007f00, 0x0000007f},
6649 {0x0041193b, 0x0051e8c8, 0x00040808, 0x00fff8f8},
6650 {0x00824444, 0x0000c0c0, 0x00c2a066, 0x009222e0},
6652 static const USHORT content_l6v5u5[4][4] =
6654 {0x0000, 0xfdef, 0x0230, 0xfc00},
6655 {0x0010, 0x0200, 0x01e0, 0x000f},
6656 {0x4067, 0x53b9, 0x0421, 0xffff},
6657 {0x8108, 0x0318, 0xc28c, 0x909c},
6659 static const struct
6661 D3DFORMAT format;
6662 const char *name;
6663 const void *content;
6664 SIZE_T pixel_size;
6665 BOOL blue, alpha;
6666 unsigned int slop, slop_broken, alpha_broken;
6668 formats[] =
6670 {D3DFMT_V8U8, "D3DFMT_V8U8", content_v8u8, sizeof(WORD), FALSE, FALSE, 1, 0, FALSE},
6671 {D3DFMT_V16U16, "D3DFMT_V16U16", content_v16u16, sizeof(DWORD), FALSE, FALSE, 1, 0, FALSE},
6672 {D3DFMT_Q8W8V8U8, "D3DFMT_Q8W8V8U8", content_q8w8v8u8, sizeof(DWORD), TRUE, TRUE, 1, 0, TRUE },
6673 {D3DFMT_X8L8V8U8, "D3DFMT_X8L8V8U8", content_x8l8v8u8, sizeof(DWORD), TRUE, FALSE, 1, 0, FALSE},
6674 {D3DFMT_L6V5U5, "D3DFMT_L6V5U5", content_l6v5u5, sizeof(WORD), TRUE, FALSE, 4, 7, FALSE},
6676 static const struct
6678 D3DPOOL pool;
6679 UINT width;
6681 tests[] =
6683 {D3DPOOL_SYSTEMMEM, 4},
6684 {D3DPOOL_SYSTEMMEM, 1},
6685 {D3DPOOL_MANAGED, 4},
6686 {D3DPOOL_MANAGED, 1},
6688 static const DWORD shader_code[] =
6690 0xffff0101, /* ps_1_1 */
6691 0x00000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, /* def c0, 0.5, 0.5, 0,5, 0,5 */
6692 0x00000042, 0xb00f0000, /* tex t0 */
6693 0x00000004, 0x800f0000, 0xb0e40000, 0xa0e40000, 0xa0e40000, /* mad r0, t0, c0, c0 */
6694 0x0000ffff /* end */
6696 static const DWORD shader_code_alpha[] =
6698 /* The idea of this shader is to replicate the alpha value in .rg, and set
6699 * blue to 1.0 iff the alpha value is < -1.0 and 0.0 otherwise. */
6700 0xffff0101, /* ps_1_1 */
6701 0x00000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, /* def c0, 0.5, 0.5, 0.5, 0.5 */
6702 0x00000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0 */
6703 0x00000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c2, 0.0, 0.0, 1.0, 0.0 */
6704 0x00000042, 0xb00f0000, /* tex t0 */
6705 0x00000004, 0x80070000, 0xb0ff0000, 0xa0e40000, 0xa0e40000, /* mad r0.rgb, t0.a, c0, c0 */
6706 0x00000003, 0x80080000, 0xb1ff0000, 0xa0e40000, /* sub r0.a, -t0.a, c0 */
6707 0x00000050, 0x80080000, 0x80ff0000, 0xa0ff0001, 0xa0ff0002, /* cnd r0.a, r0.a, c1.a, c2.a */
6708 0x00000005, 0x80070001, 0xa0e40001, 0x80e40000, /* mul r1.rgb, c1, r0 */
6709 0x00000004, 0x80070000, 0x80ff0000, 0xa0e40002, 0x80e40001, /* mad r0.rgb, r0.a, c2, r1 */
6710 0x0000ffff /* end */
6712 static const struct
6714 struct vec3 position;
6715 struct vec2 texcrd;
6717 quad[] =
6719 /* Flip the y coordinate to make the input and
6720 * output arrays easier to compare. */
6721 {{ -1.0f, -1.0f, 0.0f}, { 0.0f, 1.0f}},
6722 {{ -1.0f, 1.0f, 0.0f}, { 0.0f, 0.0f}},
6723 {{ 1.0f, -1.0f, 0.0f}, { 1.0f, 1.0f}},
6724 {{ 1.0f, 1.0f, 0.0f}, { 1.0f, 0.0f}},
6726 static const D3DCOLOR expected_alpha[4][4] =
6728 {0x00808000, 0x007f7f00, 0x00ffff00, 0x00000000},
6729 {0x00909000, 0x00a0a000, 0x00b0b000, 0x00c0c000},
6730 {0x00d0d000, 0x00e0e000, 0x00f0f000, 0x00000000},
6731 {0x00101000, 0x00202000, 0x00010100, 0x00020200},
6733 static const BOOL alpha_broken[4][4] =
6735 {FALSE, FALSE, FALSE, FALSE},
6736 {FALSE, FALSE, FALSE, FALSE},
6737 {FALSE, FALSE, FALSE, TRUE },
6738 {FALSE, FALSE, FALSE, FALSE},
6740 static const D3DCOLOR expected_colors[4][4] =
6742 {0x00808080, 0x00fefeff, 0x00010780, 0x008080ff},
6743 {0x00018080, 0x00800180, 0x0080fe80, 0x00fe8080},
6744 {0x00ba98a0, 0x004767a8, 0x00888881, 0x007878ff},
6745 {0x00c3c3c0, 0x003f3f80, 0x00e51fe1, 0x005fa2c8},
6748 window = create_window();
6749 d3d = Direct3DCreate8(D3D_SDK_VERSION);
6750 ok(!!d3d, "Failed to create a D3D object.\n");
6752 if (!(device = create_device(d3d, window, window, TRUE)))
6754 skip("Failed to create a D3D device, skipping tests.\n");
6755 IDirect3D8_Release(d3d);
6756 DestroyWindow(window);
6757 return;
6760 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
6761 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
6763 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 1))
6765 skip("Pixel shaders not supported, skipping converted format test.\n");
6766 goto done;
6769 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
6770 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
6771 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX1);
6772 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr);
6773 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code, &shader);
6774 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#lx.\n", hr);
6775 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code_alpha, &shader_alpha);
6776 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#lx.\n", hr);
6778 for (i = 0; i < ARRAY_SIZE(formats); i++)
6780 hr = IDirect3D8_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
6781 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, formats[i].format);
6782 if (FAILED(hr))
6784 skip("Format %s not supported, skipping.\n", formats[i].name);
6785 continue;
6788 for (j = 0; j < ARRAY_SIZE(tests); j++)
6790 texture_sysmem = NULL;
6791 hr = IDirect3DDevice8_CreateTexture(device, tests[j].width, 4, 1, 0,
6792 formats[i].format, tests[j].pool, &texture);
6793 ok(SUCCEEDED(hr), "Failed to create texture, hr %#lx.\n", hr);
6795 hr = IDirect3DTexture8_LockRect(texture, 0, &locked_rect, NULL, 0);
6796 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#lx.\n", hr);
6797 for (y = 0; y < 4; y++)
6799 memcpy((char *)locked_rect.pBits + y * locked_rect.Pitch,
6800 (char *)formats[i].content + y * 4 * formats[i].pixel_size,
6801 tests[j].width * formats[i].pixel_size);
6803 hr = IDirect3DTexture8_UnlockRect(texture, 0);
6804 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#lx.\n", hr);
6806 if (tests[j].pool == D3DPOOL_SYSTEMMEM)
6808 texture_sysmem = texture;
6809 hr = IDirect3DDevice8_CreateTexture(device, tests[j].width, 4, 1, 0,
6810 formats[i].format, D3DPOOL_DEFAULT, &texture);
6811 ok(SUCCEEDED(hr), "Failed to create texture, hr %#lx.\n", hr);
6813 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)texture_sysmem,
6814 (IDirect3DBaseTexture8 *)texture);
6815 ok(SUCCEEDED(hr), "Failed to update texture, hr %#lx.\n", hr);
6816 IDirect3DTexture8_Release(texture_sysmem);
6819 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
6820 ok(SUCCEEDED(hr), "Failed to set texture, hr %#lx.\n", hr);
6821 hr = IDirect3DDevice8_SetPixelShader(device, shader_alpha);
6822 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#lx.\n", hr);
6824 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00330033, 0.0f, 0);
6825 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
6826 hr = IDirect3DDevice8_BeginScene(device);
6827 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
6828 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(*quad));
6829 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
6830 hr = IDirect3DDevice8_EndScene(device);
6831 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
6833 for (y = 0; y < 4; y++)
6835 for (x = 0; x < tests[j].width; x++)
6837 BOOL r200_broken = formats[i].alpha_broken && alpha_broken[y][x];
6838 if (formats[i].alpha)
6839 expected_color = expected_alpha[y][x];
6840 else
6841 expected_color = 0x00ffff00;
6843 color = getPixelColor(device, 80 + 160 * x, 60 + 120 * y);
6844 ok(color_match(color, expected_color, 1) || broken(r200_broken),
6845 "Expected color 0x%08x, got 0x%08x, format %s, test %u, location %ux%u.\n",
6846 expected_color, color, formats[i].name, j, x, y);
6849 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
6850 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
6852 hr = IDirect3DDevice8_SetPixelShader(device, shader);
6853 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#lx.\n", hr);
6855 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00330033, 0.0f, 0);
6856 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
6857 hr = IDirect3DDevice8_BeginScene(device);
6858 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
6859 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(*quad));
6860 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
6861 hr = IDirect3DDevice8_EndScene(device);
6862 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
6864 for (y = 0; y < 4; y++)
6866 for (x = 0; x < tests[j].width; x++)
6868 expected_color = expected_colors[y][x];
6869 if (!formats[i].blue)
6870 expected_color |= 0x000000ff;
6872 color = getPixelColor(device, 80 + 160 * x, 60 + 120 * y);
6873 ok(color_match(color, expected_color, formats[i].slop)
6874 || broken(color_match(color, expected_color, formats[i].slop_broken)),
6875 "Expected color 0x%08x, got 0x%08x, format %s, test %u, location %ux%u.\n",
6876 expected_color, color, formats[i].name, j, x, y);
6879 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
6880 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
6882 IDirect3DTexture8_Release(texture);
6886 IDirect3DDevice8_DeletePixelShader(device, shader);
6887 IDirect3DDevice8_DeletePixelShader(device, shader_alpha);
6889 done:
6890 refcount = IDirect3DDevice8_Release(device);
6891 ok(!refcount, "Device has %lu references left.\n", refcount);
6892 IDirect3D8_Release(d3d);
6893 DestroyWindow(window);
6896 static void test_updatetexture(void)
6898 unsigned int color, t, i, f, l, x, y, z;
6899 D3DADAPTER_IDENTIFIER8 identifier;
6900 IDirect3DDevice8 *device;
6901 IDirect3D8 *d3d;
6902 HWND window;
6903 HRESULT hr;
6904 IDirect3DBaseTexture8 *src, *dst;
6905 D3DLOCKED_RECT locked_rect;
6906 D3DLOCKED_BOX locked_box;
6907 ULONG refcount;
6908 D3DCAPS8 caps;
6909 BOOL ati2n_supported, do_visual_test;
6910 static const struct
6912 struct vec3 pos;
6913 struct vec2 texcoord;
6915 quad[] =
6917 {{-1.0f, -1.0f, 0.0f}, {0.0f, 1.0f}},
6918 {{-1.0f, 1.0f, 0.0f}, {0.0f, 0.0f}},
6919 {{ 1.0f, -1.0f, 0.0f}, {1.0f, 1.0f}},
6920 {{ 1.0f, 1.0f, 0.0f}, {1.0f, 0.0f}},
6922 static const struct
6924 struct vec3 pos;
6925 struct vec3 texcoord;
6927 quad_cube_tex[] =
6929 {{-1.0f, -1.0f, 0.0f}, {1.0f, -0.5f, 0.5f}},
6930 {{-1.0f, 1.0f, 0.0f}, {1.0f, 0.5f, 0.5f}},
6931 {{ 1.0f, -1.0f, 0.0f}, {1.0f, -0.5f, -0.5f}},
6932 {{ 1.0f, 1.0f, 0.0f}, {1.0f, 0.5f, -0.5f}},
6934 static const struct
6936 UINT src_width, src_height;
6937 UINT dst_width, dst_height;
6938 UINT src_levels, dst_levels;
6939 D3DFORMAT src_format, dst_format;
6940 BOOL broken_result, broken_updatetex;
6942 tests[] =
6944 {8, 8, 8, 8, 0, 0, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 0 */
6945 {8, 8, 8, 8, 4, 4, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 1 */
6946 {8, 8, 8, 8, 2, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 2 */
6947 {8, 8, 8, 8, 1, 1, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 3 */
6948 {8, 8, 8, 8, 4, 0, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 4 */
6949 {8, 8, 2, 2, 4, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 5 */
6950 /* The WARP renderer doesn't handle these cases correctly. */
6951 {8, 8, 8, 8, 4, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, TRUE}, /* 6 */
6952 {8, 8, 4, 4, 4, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, TRUE}, /* 7 */
6953 /* Not clear what happens here on Windows, it doesn't make much sense
6954 * though (on Nvidia it seems to upload the 4x4 surface into the 7x7
6955 * one or something like that). */
6956 /* {8, 8, 7, 7, 4, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, */
6957 {8, 8, 8, 8, 1, 4, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 8 */
6958 /* For this one UpdateTexture() returns failure on WARP on > Win 10 1709. */
6959 {4, 4, 8, 8, 1, 1, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE, TRUE}, /* 9 */
6960 /* This one causes weird behavior on Windows (it probably writes out
6961 * of the texture memory). */
6962 /* {8, 8, 4, 4, 1, 1, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, */
6963 {8, 4, 4, 2, 4, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 10 */
6964 {8, 4, 2, 4, 4, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 11 */
6965 {8, 8, 8, 8, 4, 4, D3DFMT_A8R8G8B8, D3DFMT_X8R8G8B8, FALSE}, /* 12 */
6966 {8, 8, 8, 8, 4, 4, D3DFMT_X8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 13 */
6967 /* The data is converted correctly on AMD, on Nvidia nothing happens
6968 * (it draws a black quad). */
6969 {8, 8, 8, 8, 4, 4, D3DFMT_A8R8G8B8, D3DFMT_R5G6B5, TRUE}, /* 14 */
6970 /* This one doesn't seem to give the expected results on AMD. */
6971 /* {8, 8, 8, 8, 4, 4, D3DFMT_A8R8G8B8, D3DFMT_Q8W8V8U8, FALSE}, */
6972 {8, 8, 8, 8, 4, 4, MAKEFOURCC('A','T','I','2'), MAKEFOURCC('A','T','I','2'), FALSE}, /* 15 */
6973 {8, 8, 8, 8, 4, 2, MAKEFOURCC('A','T','I','2'), MAKEFOURCC('A','T','I','2'), FALSE}, /* 16 */
6974 {8, 8, 2, 2, 4, 2, MAKEFOURCC('A','T','I','2'), MAKEFOURCC('A','T','I','2'), FALSE}, /* 17 */
6976 static const struct
6978 D3DRESOURCETYPE type;
6979 DWORD fvf;
6980 const void *quad;
6981 unsigned int vertex_size;
6982 DWORD cap;
6983 const char *name;
6985 texture_types[] =
6987 {D3DRTYPE_TEXTURE, D3DFVF_XYZ | D3DFVF_TEX1,
6988 quad, sizeof(*quad), D3DPTEXTURECAPS_MIPMAP, "2D mipmapped"},
6990 {D3DRTYPE_CUBETEXTURE, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE3(0),
6991 quad_cube_tex, sizeof(*quad_cube_tex), D3DPTEXTURECAPS_CUBEMAP, "Cube"},
6993 {D3DRTYPE_VOLUMETEXTURE, D3DFVF_XYZ | D3DFVF_TEX1,
6994 quad, sizeof(*quad), D3DPTEXTURECAPS_VOLUMEMAP, "Volume"}
6997 window = create_window();
6998 d3d = Direct3DCreate8(D3D_SDK_VERSION);
6999 ok(!!d3d, "Failed to create a D3D object.\n");
7000 if (!(device = create_device(d3d, window, window, TRUE)))
7002 skip("Failed to create a D3D device, skipping tests.\n");
7003 IDirect3D8_Release(d3d);
7004 DestroyWindow(window);
7005 return;
7008 hr = IDirect3D8_GetAdapterIdentifier(d3d, D3DADAPTER_DEFAULT, 0, &identifier);
7009 ok(hr == S_OK, "Got hr %#lx.\n", hr);
7010 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
7011 ok(SUCCEEDED(hr), "Failed to get caps, hr %#lx.\n", hr);
7013 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR);
7014 ok(SUCCEEDED(hr), "Failed to set texture filtering state, hr %#lx.\n", hr);
7015 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP);
7016 ok(SUCCEEDED(hr), "Failed to set texture filtering state, hr %#lx.\n", hr);
7017 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP);
7018 ok(SUCCEEDED(hr), "Failed to set texture filtering state, hr %#lx.\n", hr);
7019 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_ADDRESSW, D3DTADDRESS_CLAMP);
7020 ok(SUCCEEDED(hr), "Failed to set texture filtering state, hr %#lx.\n", hr);
7021 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
7022 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
7023 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7024 ok(hr == D3D_OK, "Failed to set texture stage state, hr %#lx.\n", hr);
7025 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7026 ok(hr == D3D_OK, "Failed to set texture stage state, hr %#lx.\n", hr);
7028 for (t = 0; t < ARRAY_SIZE(texture_types); ++t)
7030 if (!(caps.TextureCaps & texture_types[t].cap))
7032 skip("%s textures not supported, skipping some tests.\n", texture_types[t].name);
7033 continue;
7036 if (FAILED(IDirect3D8_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
7037 D3DFMT_X8R8G8B8, 0, texture_types[t].type, MAKEFOURCC('A','T','I','2'))))
7039 skip("%s ATI2N textures are not supported, skipping some tests.\n", texture_types[t].name);
7040 ati2n_supported = FALSE;
7042 else
7044 ati2n_supported = TRUE;
7047 hr = IDirect3DDevice8_SetVertexShader(device, texture_types[t].fvf);
7048 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr);
7050 for (i = 0; i < ARRAY_SIZE(tests); ++i)
7052 if (tests[i].src_format == MAKEFOURCC('A','T','I','2') && !ati2n_supported)
7053 continue;
7055 switch (texture_types[t].type)
7057 case D3DRTYPE_TEXTURE:
7058 hr = IDirect3DDevice8_CreateTexture(device,
7059 tests[i].src_width, tests[i].src_height,
7060 tests[i].src_levels, 0, tests[i].src_format, D3DPOOL_SYSTEMMEM,
7061 (IDirect3DTexture8 **)&src);
7062 ok(SUCCEEDED(hr), "Failed to create texture, hr %#lx, case %u, %u.\n", hr, t, i);
7063 hr = IDirect3DDevice8_CreateTexture(device,
7064 tests[i].dst_width, tests[i].dst_height,
7065 tests[i].dst_levels, 0, tests[i].dst_format, D3DPOOL_DEFAULT,
7066 (IDirect3DTexture8 **)&dst);
7067 ok(SUCCEEDED(hr), "Failed to create texture, hr %#lx, case %u, %u.\n", hr, t, i);
7068 break;
7069 case D3DRTYPE_CUBETEXTURE:
7070 hr = IDirect3DDevice8_CreateCubeTexture(device,
7071 tests[i].src_width,
7072 tests[i].src_levels, 0, tests[i].src_format, D3DPOOL_SYSTEMMEM,
7073 (IDirect3DCubeTexture8 **)&src);
7074 ok(SUCCEEDED(hr), "Failed to create texture, hr %#lx, case %u, %u.\n", hr, t, i);
7075 hr = IDirect3DDevice8_CreateCubeTexture(device,
7076 tests[i].dst_width,
7077 tests[i].dst_levels, 0, tests[i].dst_format, D3DPOOL_DEFAULT,
7078 (IDirect3DCubeTexture8 **)&dst);
7079 ok(SUCCEEDED(hr), "Failed to create texture, hr %#lx, case %u, %u.\n", hr, t, i);
7080 break;
7081 case D3DRTYPE_VOLUMETEXTURE:
7082 hr = IDirect3DDevice8_CreateVolumeTexture(device,
7083 tests[i].src_width, tests[i].src_height, tests[i].src_width,
7084 tests[i].src_levels, 0, tests[i].src_format, D3DPOOL_SYSTEMMEM,
7085 (IDirect3DVolumeTexture8 **)&src);
7086 ok(SUCCEEDED(hr), "Failed to create texture, hr %#lx, case %u, %u.\n", hr, t, i);
7087 hr = IDirect3DDevice8_CreateVolumeTexture(device,
7088 tests[i].dst_width, tests[i].dst_height, tests[i].dst_width,
7089 tests[i].dst_levels, 0, tests[i].dst_format, D3DPOOL_DEFAULT,
7090 (IDirect3DVolumeTexture8 **)&dst);
7091 ok(SUCCEEDED(hr), "Failed to create texture, hr %#lx, case %u, %u.\n", hr, t, i);
7092 break;
7093 default:
7094 trace("Unexpected resource type.\n");
7097 /* Skip the visual part of the test for ATI2N (laziness) and cases that
7098 * give a different (and unlikely to be useful) result. */
7099 do_visual_test = (tests[i].src_format == D3DFMT_A8R8G8B8 || tests[i].src_format == D3DFMT_X8R8G8B8)
7100 && tests[i].src_levels != 0
7101 && tests[i].src_width >= tests[i].dst_width && tests[i].src_height >= tests[i].dst_height
7102 && !(tests[i].src_width > tests[i].src_height && tests[i].dst_width < tests[i].dst_height);
7104 if (do_visual_test)
7106 DWORD *ptr = NULL;
7107 unsigned int width, height, depth, row_pitch = 0, slice_pitch = 0;
7109 for (f = 0; f < (texture_types[t].type == D3DRTYPE_CUBETEXTURE ? 6 : 1); ++f)
7111 width = tests[i].src_width;
7112 height = texture_types[t].type != D3DRTYPE_CUBETEXTURE ? tests[i].src_height : tests[i].src_width;
7113 depth = texture_types[t].type == D3DRTYPE_VOLUMETEXTURE ? width : 1;
7115 for (l = 0; l < tests[i].src_levels; ++l)
7117 switch (texture_types[t].type)
7119 case D3DRTYPE_TEXTURE:
7120 hr = IDirect3DTexture8_LockRect((IDirect3DTexture8 *)src,
7121 l, &locked_rect, NULL, 0);
7122 ptr = locked_rect.pBits;
7123 row_pitch = locked_rect.Pitch / sizeof(*ptr);
7124 break;
7125 case D3DRTYPE_CUBETEXTURE:
7126 hr = IDirect3DCubeTexture8_LockRect((IDirect3DCubeTexture8 *)src,
7127 f, l, &locked_rect, NULL, 0);
7128 ptr = locked_rect.pBits;
7129 row_pitch = locked_rect.Pitch / sizeof(*ptr);
7130 break;
7131 case D3DRTYPE_VOLUMETEXTURE:
7132 hr = IDirect3DVolumeTexture8_LockBox((IDirect3DVolumeTexture8 *)src,
7133 l, &locked_box, NULL, 0);
7134 ptr = locked_box.pBits;
7135 row_pitch = locked_box.RowPitch / sizeof(*ptr);
7136 slice_pitch = locked_box.SlicePitch / sizeof(*ptr);
7137 break;
7138 default:
7139 trace("Unexpected resource type.\n");
7141 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#lx.\n", hr);
7143 for (z = 0; z < depth; ++z)
7145 for (y = 0; y < height; ++y)
7147 for (x = 0; x < width; ++x)
7149 ptr[z * slice_pitch + y * row_pitch + x] = 0xff000000
7150 | (DWORD)(x / (width - 1.0f) * 255.0f) << 16
7151 | (DWORD)(y / (height - 1.0f) * 255.0f) << 8;
7156 switch (texture_types[t].type)
7158 case D3DRTYPE_TEXTURE:
7159 hr = IDirect3DTexture8_UnlockRect((IDirect3DTexture8 *)src, l);
7160 break;
7161 case D3DRTYPE_CUBETEXTURE:
7162 hr = IDirect3DCubeTexture8_UnlockRect((IDirect3DCubeTexture8 *)src, f, l);
7163 break;
7164 case D3DRTYPE_VOLUMETEXTURE:
7165 hr = IDirect3DVolumeTexture8_UnlockBox((IDirect3DVolumeTexture8 *)src, l);
7166 break;
7167 default:
7168 trace("Unexpected resource type.\n");
7170 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#lx.\n", hr);
7172 width >>= 1;
7173 if (!width)
7174 width = 1;
7175 height >>= 1;
7176 if (!height)
7177 height = 1;
7178 depth >>= 1;
7179 if (!depth)
7180 depth = 1;
7185 hr = IDirect3DDevice8_UpdateTexture(device, src, dst);
7186 if (FAILED(hr))
7188 todo_wine ok(SUCCEEDED(hr) || broken(tests[i].broken_updatetex),
7189 "Failed to update texture, hr %#lx, case %u, %u.\n", hr, t, i);
7190 IDirect3DBaseTexture8_Release(src);
7191 IDirect3DBaseTexture8_Release(dst);
7192 continue;
7194 ok(SUCCEEDED(hr), "Failed to update texture, hr %#lx, case %u, %u.\n", hr, t, i);
7196 if (do_visual_test)
7198 IDirect3DTexture8 *rb_texture;
7199 struct surface_readback rb;
7200 IDirect3DSurface8 *rt;
7201 D3DSURFACE_DESC desc;
7203 hr = IDirect3DDevice8_SetTexture(device, 0, dst);
7204 ok(SUCCEEDED(hr), "Failed to set texture, hr %#lx.\n", hr);
7206 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 1.0f, 0);
7207 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
7209 hr = IDirect3DDevice8_BeginScene(device);
7210 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
7211 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,
7212 texture_types[t].quad, texture_types[t].vertex_size);
7213 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
7214 hr = IDirect3DDevice8_EndScene(device);
7215 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
7217 /* Read back manually. WARP often completely breaks down with
7218 * these draws and fails to copy to the staging texture. */
7220 hr = IDirect3DDevice8_GetRenderTarget(device, &rt);
7221 ok(hr == S_OK, "Got hr %#lx.\n", hr);
7223 hr = IDirect3DSurface8_GetDesc(rt, &desc);
7224 ok(hr == S_OK, "Got hr %#lx.\n", hr);
7225 hr = IDirect3DDevice8_CreateTexture(device, desc.Width, desc.Height,
7226 1, 0, desc.Format, D3DPOOL_SYSTEMMEM, &rb_texture);
7227 ok(hr == S_OK, "Got hr %#lx.\n", hr);
7228 hr = IDirect3DTexture8_GetSurfaceLevel(rb_texture, 0, &rb.surface);
7229 ok(hr == S_OK, "Got hr %#lx.\n", hr);
7231 hr = IDirect3DDevice8_CopyRects(device, rt, NULL, 0, rb.surface, NULL);
7232 ok(hr == S_OK || broken(adapter_is_warp(&identifier)), "Got hr %#lx.\n", hr);
7233 if (SUCCEEDED(hr))
7235 hr = IDirect3DSurface8_LockRect(rb.surface, &rb.locked_rect, NULL, D3DLOCK_READONLY);
7236 ok(hr == S_OK, "Got hr %#lx.\n", hr);
7238 color = get_readback_color(&rb, 320, 240) & 0x00ffffff;
7239 ok(color_match(color, 0x007f7f00, 3) || broken(tests[i].broken_result),
7240 "Got unexpected color 0x%08x, case %u, %u.\n", color, t, i);
7242 hr = IDirect3DSurface8_UnlockRect(rb.surface);
7243 ok(hr == S_OK, "Got hr %#lx.\n", hr);
7246 IDirect3DSurface8_Release(rb.surface);
7247 IDirect3DTexture8_Release(rb_texture);
7248 IDirect3DSurface8_Release(rt);
7251 IDirect3DBaseTexture8_Release(src);
7252 IDirect3DBaseTexture8_Release(dst);
7256 refcount = IDirect3DDevice8_Release(device);
7257 ok(!refcount, "Device has %lu references left.\n", refcount);
7258 IDirect3D8_Release(d3d);
7259 DestroyWindow(window);
7262 static BOOL point_match(IDirect3DDevice8 *device, UINT x, UINT y, UINT r)
7264 D3DCOLOR color;
7266 color = D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff);
7267 if (!color_match(getPixelColor(device, x + r, y), color, 1))
7268 return FALSE;
7269 if (!color_match(getPixelColor(device, x - r, y), color, 1))
7270 return FALSE;
7271 if (!color_match(getPixelColor(device, x, y + r), color, 1))
7272 return FALSE;
7273 if (!color_match(getPixelColor(device, x, y - r), color, 1))
7274 return FALSE;
7276 ++r;
7277 color = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff);
7278 if (!color_match(getPixelColor(device, x + r, y), color, 1))
7279 return FALSE;
7280 if (!color_match(getPixelColor(device, x - r, y), color, 1))
7281 return FALSE;
7282 if (!color_match(getPixelColor(device, x, y + r), color, 1))
7283 return FALSE;
7284 if (!color_match(getPixelColor(device, x, y - r), color, 1))
7285 return FALSE;
7287 return TRUE;
7290 static void test_pointsize(void)
7292 static const float a = 0.5f, b = 0.5f, c = 0.5f;
7293 float ptsize, ptsizemax_orig, ptsizemin_orig;
7294 IDirect3DSurface8 *rt, *backbuffer, *depthstencil;
7295 IDirect3DTexture8 *tex1, *tex2;
7296 IDirect3DDevice8 *device;
7297 unsigned int color, i, j;
7298 DWORD vs, ps;
7299 D3DLOCKED_RECT lr;
7300 IDirect3D8 *d3d;
7301 ULONG refcount;
7302 D3DCAPS8 caps;
7303 HWND window;
7304 HRESULT hr;
7306 static const DWORD tex1_data[4] = {0x00ff0000, 0x00ff0000, 0x00000000, 0x00000000};
7307 static const DWORD tex2_data[4] = {0x00000000, 0x0000ff00, 0x00000000, 0x0000ff00};
7308 static const float vertices[] =
7310 64.0f, 64.0f, 0.1f,
7311 128.0f, 64.0f, 0.1f,
7312 192.0f, 64.0f, 0.1f,
7313 256.0f, 64.0f, 0.1f,
7314 320.0f, 64.0f, 0.1f,
7315 384.0f, 64.0f, 0.1f,
7316 448.0f, 64.0f, 0.1f,
7317 512.0f, 64.0f, 0.1f,
7319 static const struct
7321 float x, y, z;
7322 float point_size;
7324 vertex_pointsize = {64.0f, 64.0f, 0.1f, 48.0f},
7325 vertex_pointsize_scaled = {64.0f, 64.0f, 0.1f, 24.0f},
7326 vertex_pointsize_zero = {64.0f, 64.0f, 0.1f, 0.0f};
7327 static const DWORD decl[] =
7329 D3DVSD_STREAM(0),
7330 D3DVSD_REG(0, D3DVSDT_FLOAT3), /* position */
7331 D3DVSD_END()
7333 decl_psize[] =
7335 D3DVSD_STREAM(0),
7336 D3DVSD_REG(0, D3DVSDT_FLOAT3), /* position, v0 */
7337 D3DVSD_REG(1, D3DVSDT_FLOAT1), /* point size, v1 */
7338 D3DVSD_END()
7340 static const DWORD vshader_code[] =
7342 0xfffe0101, /* vs_1_1 */
7343 0x00000005, 0x800f0000, 0x90000000, 0xa0e40000, /* mul r0, v0.x, c0 */
7344 0x00000004, 0x800f0000, 0x90550000, 0xa0e40001, 0x80e40000, /* mad r0, v0.y, c1, r0 */
7345 0x00000004, 0x800f0000, 0x90aa0000, 0xa0e40002, 0x80e40000, /* mad r0, v0.z, c2, r0 */
7346 0x00000004, 0xc00f0000, 0x90ff0000, 0xa0e40003, 0x80e40000, /* mad oPos, v0.w, c3, r0 */
7347 0x0000ffff
7349 static const DWORD vshader_psize_code[] =
7351 0xfffe0101, /* vs_1_1 */
7352 0x00000005, 0x800f0000, 0x90000000, 0xa0e40000, /* mul r0, v0.x, c0 */
7353 0x00000004, 0x800f0000, 0x90550000, 0xa0e40001, 0x80e40000, /* mad r0, v0.y, c1, r0 */
7354 0x00000004, 0x800f0000, 0x90aa0000, 0xa0e40002, 0x80e40000, /* mad r0, v0.z, c2, r0 */
7355 0x00000004, 0xc00f0000, 0x90ff0000, 0xa0e40003, 0x80e40000, /* mad oPos, v0.w, c3, r0 */
7356 0x00000001, 0xc00f0002, 0x90000001, /* mov oPts, v1.x */
7357 0x0000ffff
7359 static const DWORD pshader_code[] =
7361 0xffff0101, /* ps_1_1 */
7362 0x00000042, 0xb00f0000, /* tex t0 */
7363 0x00000042, 0xb00f0001, /* tex t1 */
7364 0x00000002, 0x800f0000, 0xb0e40000, 0xb0e40001, /* add r0, t0, t1 */
7365 0x0000ffff
7367 static const struct test_shader
7369 DWORD version;
7370 const DWORD *code;
7372 novs = {0, NULL},
7373 vs1 = {D3DVS_VERSION(1, 1), vshader_code},
7374 vs1_psize = {D3DVS_VERSION(1, 1), vshader_psize_code},
7375 nops = {0, NULL},
7376 ps1 = {D3DPS_VERSION(1, 1), pshader_code};
7377 static const struct
7379 const DWORD *decl;
7380 const struct test_shader *vs;
7381 const struct test_shader *ps;
7382 DWORD accepted_fvf;
7383 unsigned int nonscaled_size, scaled_size;
7385 test_setups[] =
7387 {NULL, &novs, &nops, D3DFVF_XYZ, 32, 62},
7388 {decl, &vs1, &ps1, D3DFVF_XYZ, 32, 32},
7389 {NULL, &novs, &ps1, D3DFVF_XYZ, 32, 62},
7390 {decl, &vs1, &nops, D3DFVF_XYZ, 32, 32},
7391 {NULL, &novs, &nops, D3DFVF_XYZ | D3DFVF_PSIZE, 48, 48},
7392 {decl_psize, &vs1_psize, &ps1, D3DFVF_XYZ | D3DFVF_PSIZE, 48, 24},
7394 static const struct
7396 BOOL zero_size;
7397 BOOL scale;
7398 BOOL override_min;
7399 DWORD fvf;
7400 const void *vertex_data;
7401 unsigned int vertex_size;
7403 tests[] =
7405 {FALSE, FALSE, FALSE, D3DFVF_XYZ, vertices, sizeof(float) * 3},
7406 {FALSE, TRUE, FALSE, D3DFVF_XYZ, vertices, sizeof(float) * 3},
7407 {FALSE, FALSE, TRUE, D3DFVF_XYZ, vertices, sizeof(float) * 3},
7408 {TRUE, FALSE, FALSE, D3DFVF_XYZ, vertices, sizeof(float) * 3},
7409 {FALSE, FALSE, FALSE, D3DFVF_XYZ | D3DFVF_PSIZE, &vertex_pointsize, sizeof(vertex_pointsize)},
7410 {FALSE, TRUE, FALSE, D3DFVF_XYZ | D3DFVF_PSIZE, &vertex_pointsize_scaled, sizeof(vertex_pointsize_scaled)},
7411 {FALSE, FALSE, TRUE, D3DFVF_XYZ | D3DFVF_PSIZE, &vertex_pointsize, sizeof(vertex_pointsize)},
7412 {TRUE, FALSE, FALSE, D3DFVF_XYZ | D3DFVF_PSIZE, &vertex_pointsize_zero, sizeof(vertex_pointsize_zero)},
7414 /* Transforms the coordinate system [-1.0;1.0]x[1.0;-1.0] to
7415 * [0.0;0.0]x[640.0;480.0]. Z is untouched. */
7416 D3DMATRIX matrix =
7418 2.0f / 640.0f, 0.0f, 0.0f, 0.0f,
7419 0.0f, -2.0f / 480.0f, 0.0f, 0.0f,
7420 0.0f, 0.0f, 1.0f, 0.0f,
7421 -1.0f, 1.0f, 0.0f, 1.0f,
7422 }}};
7424 window = create_window();
7425 d3d = Direct3DCreate8(D3D_SDK_VERSION);
7426 ok(!!d3d, "Failed to create a D3D object.\n");
7427 if (!(device = create_device(d3d, window, window, TRUE)))
7429 skip("Failed to create a D3D device, skipping tests.\n");
7430 goto done;
7433 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
7434 ok(SUCCEEDED(hr), "Failed to get caps, hr %#lx.\n", hr);
7435 if (caps.MaxPointSize < 32.0f)
7437 skip("MaxPointSize %f < 32.0, skipping.\n", caps.MaxPointSize);
7438 IDirect3DDevice8_Release(device);
7439 goto done;
7442 /* The r500 Windows driver needs a draw with regular texture coordinates at least once during the
7443 * device's lifetime, otherwise texture coordinate generation only works for texture 0. */
7444 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX1);
7445 ok(SUCCEEDED(hr), "Got hr %#lx.\n", hr);
7446 hr = IDirect3DDevice8_BeginScene(device);
7447 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
7448 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, vertices, sizeof(float) * 5);
7449 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
7450 hr = IDirect3DDevice8_EndScene(device);
7451 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
7453 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
7454 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
7455 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
7456 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#lx.\n", hr);
7457 hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, &matrix);
7458 ok(SUCCEEDED(hr), "Failed to set projection matrix, hr %#lx.\n", hr);
7459 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ);
7460 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr);
7462 hr = IDirect3DDevice8_BeginScene(device);
7463 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
7465 ptsize = 15.0f;
7466 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
7467 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
7468 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
7469 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
7471 ptsize = 31.0f;
7472 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
7473 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
7474 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[3], sizeof(float) * 3);
7475 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
7477 ptsize = 30.75f;
7478 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
7479 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
7480 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[6], sizeof(float) * 3);
7481 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
7483 if (caps.MaxPointSize >= 63.0f)
7485 ptsize = 63.0f;
7486 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
7487 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
7488 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[9], sizeof(float) * 3);
7489 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
7491 ptsize = 62.75f;
7492 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
7493 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
7494 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[15], sizeof(float) * 3);
7495 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
7498 ptsize = 1.0f;
7499 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
7500 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
7501 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[12], sizeof(float) * 3);
7502 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
7504 hr = IDirect3DDevice8_GetRenderState(device, D3DRS_POINTSIZE_MAX, (DWORD *)&ptsizemax_orig);
7505 ok(SUCCEEDED(hr), "Failed to get render state, hr %#lx.\n", hr);
7506 hr = IDirect3DDevice8_GetRenderState(device, D3DRS_POINTSIZE_MIN, (DWORD *)&ptsizemin_orig);
7507 ok(SUCCEEDED(hr), "Failed to get render state, hr %#lx.\n", hr);
7509 /* What happens if point scaling is disabled, and POINTSIZE_MAX < POINTSIZE? */
7510 ptsize = 15.0f;
7511 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
7512 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
7513 ptsize = 1.0f;
7514 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE_MAX, *(DWORD *)&ptsize);
7515 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
7516 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[18], sizeof(float) * 3);
7517 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
7519 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE_MAX, *(DWORD *)&ptsizemax_orig);
7520 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
7522 /* pointsize < pointsize_min < pointsize_max?
7523 * pointsize = 1.0, pointsize_min = 15.0, pointsize_max = default(usually 64.0) */
7524 ptsize = 1.0f;
7525 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
7526 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
7527 ptsize = 15.0f;
7528 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE_MIN, *(DWORD *)&ptsize);
7529 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
7530 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[21], sizeof(float) * 3);
7531 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
7533 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE_MIN, *(DWORD *)&ptsizemin_orig);
7534 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
7536 hr = IDirect3DDevice8_EndScene(device);
7537 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
7539 ok(point_match(device, 64, 64, 7), "point_match(64, 64, 7) failed, expected point size 15.\n");
7540 ok(point_match(device, 128, 64, 15), "point_match(128, 64, 15) failed, expected point size 31.\n");
7541 ok(point_match(device, 192, 64, 15), "point_match(192, 64, 15) failed, expected point size 31.\n");
7543 if (caps.MaxPointSize >= 63.0f)
7545 ok(point_match(device, 256, 64, 31), "point_match(256, 64, 31) failed, expected point size 63.\n");
7546 ok(point_match(device, 384, 64, 31), "point_match(384, 64, 31) failed, expected point size 63.\n");
7549 ok(point_match(device, 320, 64, 0), "point_match(320, 64, 0) failed, expected point size 1.\n");
7550 /* ptsize = 15, ptsize_max = 1 --> point has size 1 */
7551 ok(point_match(device, 448, 64, 0), "point_match(448, 64, 0) failed, expected point size 1.\n");
7552 /* ptsize = 1, ptsize_max = default(64), ptsize_min = 15 --> point has size 15 */
7553 ok(point_match(device, 512, 64, 7), "point_match(512, 64, 7) failed, expected point size 15.\n");
7555 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
7557 /* The following code tests point sprites with two textures, to see if each texture coordinate unit
7558 * generates texture coordinates for the point(result: Yes, it does)
7560 * However, not all GL implementations support point sprites(they need GL_ARB_point_sprite), but there
7561 * is no point sprite cap bit in d3d because native d3d software emulates point sprites. Until the
7562 * SW emulation is implemented in wined3d, this test will fail on GL drivers that does not support them.
7564 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
7565 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
7567 hr = IDirect3DDevice8_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex1);
7568 ok(SUCCEEDED(hr), "Failed to create texture, hr %#lx.\n", hr);
7569 hr = IDirect3DDevice8_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex2);
7570 ok(SUCCEEDED(hr), "Failed to create texture, hr %#lx.\n", hr);
7571 memset(&lr, 0, sizeof(lr));
7572 hr = IDirect3DTexture8_LockRect(tex1, 0, &lr, NULL, 0);
7573 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#lx.\n", hr);
7574 memcpy(lr.pBits, tex1_data, sizeof(tex1_data));
7575 hr = IDirect3DTexture8_UnlockRect(tex1, 0);
7576 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#lx.\n", hr);
7577 memset(&lr, 0, sizeof(lr));
7578 hr = IDirect3DTexture8_LockRect(tex2, 0, &lr, NULL, 0);
7579 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#lx.\n", hr);
7580 memcpy(lr.pBits, tex2_data, sizeof(tex2_data));
7581 hr = IDirect3DTexture8_UnlockRect(tex2, 0);
7582 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#lx.\n", hr);
7583 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)tex1);
7584 ok(SUCCEEDED(hr), "Failed to set texture, hr %#lx.\n", hr);
7585 hr = IDirect3DDevice8_SetTexture(device, 1, (IDirect3DBaseTexture8 *)tex2);
7586 ok(SUCCEEDED(hr), "Failed to set texture, hr %#lx.\n", hr);
7587 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7588 ok(SUCCEEDED(hr), "Failed to set color op, hr %#lx.\n", hr);
7589 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7590 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#lx.\n", hr);
7591 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
7592 ok(SUCCEEDED(hr), "Failed to set color op, hr %#lx.\n", hr);
7593 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7594 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#lx.\n", hr);
7595 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
7596 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#lx.\n", hr);
7598 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSPRITEENABLE, TRUE);
7599 ok(SUCCEEDED(hr), "Failed to enable point sprites, hr %#lx.\n", hr);
7600 ptsize = 32.0f;
7601 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
7602 ok(SUCCEEDED(hr), "Failed to set point size, hr %#lx.\n", hr);
7604 hr = IDirect3DDevice8_BeginScene(device);
7605 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
7606 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
7607 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
7608 hr = IDirect3DDevice8_EndScene(device);
7609 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
7611 color = getPixelColor(device, 64 - 4, 64 - 4);
7612 ok(color == 0x00ff0000, "pSprite: Pixel (64 - 4),(64 - 4) has color 0x%08x, expected 0x00ff0000\n", color);
7613 color = getPixelColor(device, 64 - 4, 64 + 4);
7614 ok(color == 0x00000000, "pSprite: Pixel (64 - 4),(64 + 4) has color 0x%08x, expected 0x00000000\n", color);
7615 color = getPixelColor(device, 64 + 4, 64 + 4);
7616 ok(color == 0x0000ff00, "pSprite: Pixel (64 + 4),(64 + 4) has color 0x%08x, expected 0x0000ff00\n", color);
7617 color = getPixelColor(device, 64 + 4, 64 - 4);
7618 ok(color == 0x00ffff00, "pSprite: Pixel (64 + 4),(64 - 4) has color 0x%08x, expected 0x00ffff00\n", color);
7619 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
7621 U(matrix).m[0][0] = 1.0f / 64.0f;
7622 U(matrix).m[1][1] = -1.0f / 64.0f;
7623 hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, &matrix);
7624 ok(SUCCEEDED(hr), "Failed to set projection matrix, hr %#lx.\n", hr);
7626 hr = IDirect3DDevice8_GetRenderTarget(device, &backbuffer);
7627 ok(SUCCEEDED(hr), "Failed to get backbuffer, hr %#lx.\n", hr);
7628 hr = IDirect3DDevice8_GetDepthStencilSurface(device, &depthstencil);
7629 ok(SUCCEEDED(hr), "Failed to get depth / stencil buffer, hr %#lx.\n", hr);
7631 hr = IDirect3DDevice8_CreateRenderTarget(device, 128, 128, D3DFMT_A8R8G8B8,
7632 D3DMULTISAMPLE_NONE, TRUE, &rt);
7633 ok(SUCCEEDED(hr), "Failed to create a render target, hr %#lx.\n", hr);
7635 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSCALE_A, *(DWORD *)&a);
7636 ok(SUCCEEDED(hr), "Failed setting point scale attenuation coefficient, hr %#lx.\n", hr);
7637 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSCALE_B, *(DWORD *)&b);
7638 ok(SUCCEEDED(hr), "Failed setting point scale attenuation coefficient, hr %#lx.\n", hr);
7639 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSCALE_C, *(DWORD *)&c);
7640 ok(SUCCEEDED(hr), "Failed setting point scale attenuation coefficient, hr %#lx.\n", hr);
7641 hr = IDirect3DDevice8_SetVertexShaderConstant(device, 0, &S(U(matrix))._11, 4);
7642 ok(SUCCEEDED(hr), "Failed to set vertex shader constants, hr %#lx.\n", hr);
7644 if (caps.MaxPointSize < 63.0f)
7646 skip("MaxPointSize %f < 63.0, skipping some tests.\n", caps.MaxPointSize);
7647 goto cleanup;
7650 hr = IDirect3DDevice8_SetRenderTarget(device, rt, depthstencil);
7651 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
7653 for (i = 0; i < ARRAY_SIZE(test_setups); ++i)
7655 if (caps.VertexShaderVersion < test_setups[i].vs->version
7656 || caps.PixelShaderVersion < test_setups[i].ps->version)
7658 skip("Vertex / pixel shader version not supported, skipping test.\n");
7659 continue;
7661 if (test_setups[i].vs->code)
7663 hr = IDirect3DDevice8_CreateVertexShader(device, test_setups[i].decl, test_setups[i].vs->code, &vs, 0);
7664 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#lx (case %u).\n", hr, i);
7666 else
7668 vs = 0;
7670 if (test_setups[i].ps->code)
7672 hr = IDirect3DDevice8_CreatePixelShader(device, test_setups[i].ps->code, &ps);
7673 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#lx (case %u).\n", hr, i);
7675 else
7677 ps = 0;
7680 hr = IDirect3DDevice8_SetVertexShader(device, vs ? vs : test_setups[i].accepted_fvf);
7681 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#lx.\n", hr);
7682 hr = IDirect3DDevice8_SetPixelShader(device, ps);
7683 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#lx.\n", hr);
7685 for (j = 0; j < ARRAY_SIZE(tests); ++j)
7687 unsigned int size = tests[j].override_min ? 63 : tests[j].zero_size ? 0 : tests[j].scale
7688 ? test_setups[i].scaled_size : test_setups[i].nonscaled_size;
7690 if (test_setups[i].accepted_fvf != tests[j].fvf)
7691 continue;
7693 ptsize = tests[j].zero_size ? 0.0f : 32.0f;
7694 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
7695 ok(SUCCEEDED(hr), "Failed to set pointsize, hr %#lx.\n", hr);
7697 ptsize = tests[j].override_min ? 63.0f : tests[j].zero_size ? 0.0f : ptsizemin_orig;
7698 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE_MIN, *(DWORD *)&ptsize);
7699 ok(SUCCEEDED(hr), "Failed to set minimum pointsize, hr %#lx.\n", hr);
7701 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSCALEENABLE, tests[j].scale);
7702 ok(SUCCEEDED(hr), "Failed setting point scale state, hr %#lx.\n", hr);
7704 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
7705 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
7707 hr = IDirect3DDevice8_BeginScene(device);
7708 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
7709 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1,
7710 tests[j].vertex_data, tests[j].vertex_size);
7711 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
7712 hr = IDirect3DDevice8_EndScene(device);
7713 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
7715 if (tests[j].zero_size)
7717 /* Technically 0 pointsize is undefined in OpenGL but in practice it seems like
7718 * it does the "useful" thing on all the drivers I tried. */
7719 /* On WARP it does draw some pixels, most of the time. */
7720 color = getPixelColor(device, 64, 64);
7721 ok(color_match(color, 0x0000ffff, 0)
7722 || broken(color_match(color, 0x00ff0000, 0))
7723 || broken(color_match(color, 0x00ffff00, 0))
7724 || broken(color_match(color, 0x00000000, 0))
7725 || broken(color_match(color, 0x0000ff00, 0)),
7726 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
7728 else
7730 struct surface_readback rb;
7732 get_surface_readback(rt, &rb);
7733 color = get_readback_color(&rb, 64 - size / 2 + 1, 64 - size / 2 + 1);
7734 ok(color_match(color, 0x00ff0000, 0),
7735 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
7736 color = get_readback_color(&rb, 64 + size / 2 - 1, 64 - size / 2 + 1);
7737 ok(color_match(color, 0x00ffff00, 0),
7738 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
7739 color = get_readback_color(&rb, 64 - size / 2 + 1, 64 + size / 2 - 1);
7740 ok(color_match(color, 0x00000000, 0),
7741 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
7742 color = get_readback_color(&rb, 64 + size / 2 - 1, 64 + size / 2 - 1);
7743 ok(color_match(color, 0x0000ff00, 0),
7744 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
7746 color = get_readback_color(&rb, 64 - size / 2 - 1, 64 - size / 2 - 1);
7747 ok(color_match(color, 0xff00ffff, 0),
7748 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
7749 color = get_readback_color(&rb, 64 + size / 2 + 1, 64 - size / 2 - 1);
7750 ok(color_match(color, 0xff00ffff, 0),
7751 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
7752 color = get_readback_color(&rb, 64 - size / 2 - 1, 64 + size / 2 + 1);
7753 ok(color_match(color, 0xff00ffff, 0),
7754 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
7755 color = get_readback_color(&rb, 64 + size / 2 + 1, 64 + size / 2 + 1);
7756 ok(color_match(color, 0xff00ffff, 0),
7757 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
7759 release_surface_readback(&rb);
7762 IDirect3DDevice8_SetVertexShader(device, 0);
7763 IDirect3DDevice8_SetPixelShader(device, 0);
7764 if (vs)
7765 IDirect3DDevice8_DeleteVertexShader(device, vs);
7766 if (ps)
7767 IDirect3DDevice8_DeletePixelShader(device, ps);
7769 hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, depthstencil);
7770 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
7772 cleanup:
7773 IDirect3DSurface8_Release(backbuffer);
7774 IDirect3DSurface8_Release(depthstencil);
7775 IDirect3DSurface8_Release(rt);
7777 IDirect3DTexture8_Release(tex1);
7778 IDirect3DTexture8_Release(tex2);
7779 refcount = IDirect3DDevice8_Release(device);
7780 ok(!refcount, "Device has %lu references left.\n", refcount);
7781 done:
7782 IDirect3D8_Release(d3d);
7783 DestroyWindow(window);
7786 static void test_multisample_mismatch(void)
7788 IDirect3DDevice8 *device;
7789 IDirect3D8 *d3d;
7790 HWND window;
7791 HRESULT hr;
7792 ULONG refcount;
7793 IDirect3DSurface8 *rt_multi, *ds;
7795 window = create_window();
7796 d3d = Direct3DCreate8(D3D_SDK_VERSION);
7797 ok(!!d3d, "Failed to create a D3D object.\n");
7798 if (FAILED(IDirect3D8_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
7799 D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES)))
7801 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping multisample mismatch test.\n");
7802 IDirect3D8_Release(d3d);
7803 return;
7806 if (!(device = create_device(d3d, window, window, TRUE)))
7808 skip("Failed to create a D3D device, skipping tests.\n");
7809 goto done;
7812 hr = IDirect3DDevice8_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
7813 D3DMULTISAMPLE_2_SAMPLES, FALSE, &rt_multi);
7814 ok(SUCCEEDED(hr), "Failed to create render target, hr %#lx.\n", hr);
7815 hr = IDirect3DDevice8_GetDepthStencilSurface(device, &ds);
7816 ok(SUCCEEDED(hr), "Failed to get original depth/stencil, hr %#lx.\n", hr);
7818 hr = IDirect3DDevice8_SetRenderTarget(device, rt_multi, ds);
7819 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#lx.\n", hr);
7821 IDirect3DSurface8_Release(ds);
7822 IDirect3DSurface8_Release(rt_multi);
7824 refcount = IDirect3DDevice8_Release(device);
7825 ok(!refcount, "Device has %lu references left.\n", refcount);
7826 done:
7827 IDirect3D8_Release(d3d);
7828 DestroyWindow(window);
7831 static void test_texcoordindex(void)
7833 static const D3DMATRIX mat =
7835 1.0f, 0.0f, 0.0f, 0.0f,
7836 0.0f, 0.0f, 0.0f, 0.0f,
7837 0.0f, 0.0f, 0.0f, 0.0f,
7838 0.0f, 0.0f, 0.0f, 0.0f,
7839 }}};
7840 static const struct
7842 struct vec3 pos;
7843 struct vec2 texcoord1;
7844 struct vec2 texcoord2;
7845 struct vec2 texcoord3;
7847 quad[] =
7849 {{-1.0f, -1.0f, 0.0f}, {0.0f, 1.0f}, {0.0f, 0.0f}, {1.0f, 1.0f}},
7850 {{-1.0f, 1.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 1.0f}, {1.0f, 0.0f}},
7851 {{ 1.0f, -1.0f, 0.0f}, {1.0f, 1.0f}, {1.0f, 0.0f}, {0.0f, 1.0f}},
7852 {{ 1.0f, 1.0f, 0.0f}, {1.0f, 0.0f}, {1.0f, 1.0f}, {0.0f, 0.0f}},
7854 IDirect3DDevice8 *device;
7855 IDirect3D8 *d3d;
7856 HWND window;
7857 HRESULT hr;
7858 IDirect3DTexture8 *texture1, *texture2;
7859 D3DLOCKED_RECT locked_rect;
7860 unsigned int color;
7861 ULONG refcount;
7862 DWORD *ptr;
7864 window = create_window();
7865 d3d = Direct3DCreate8(D3D_SDK_VERSION);
7866 ok(!!d3d, "Failed to create a D3D object.\n");
7867 if (!(device = create_device(d3d, window, window, TRUE)))
7869 skip("Failed to create a D3D device, skipping tests.\n");
7870 IDirect3D8_Release(d3d);
7871 DestroyWindow(window);
7872 return;
7875 hr = IDirect3DDevice8_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture1);
7876 ok(SUCCEEDED(hr), "Failed to create texture, hr %#lx.\n", hr);
7877 hr = IDirect3DDevice8_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture2);
7878 ok(SUCCEEDED(hr), "Failed to create texture, hr %#lx.\n", hr);
7880 hr = IDirect3DTexture8_LockRect(texture1, 0, &locked_rect, NULL, D3DLOCK_DISCARD);
7881 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#lx.\n", hr);
7882 ptr = locked_rect.pBits;
7883 ptr[0] = 0xff000000;
7884 ptr[1] = 0xff00ff00;
7885 ptr[2] = 0xff0000ff;
7886 ptr[3] = 0xff00ffff;
7887 hr = IDirect3DTexture8_UnlockRect(texture1, 0);
7888 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#lx.\n", hr);
7890 hr = IDirect3DTexture8_LockRect(texture2, 0, &locked_rect, NULL, D3DLOCK_DISCARD);
7891 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#lx.\n", hr);
7892 ptr = locked_rect.pBits;
7893 ptr[0] = 0xff000000;
7894 ptr[1] = 0xff0000ff;
7895 ptr[2] = 0xffff0000;
7896 ptr[3] = 0xffff00ff;
7897 hr = IDirect3DTexture8_UnlockRect(texture2, 0);
7898 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#lx.\n", hr);
7900 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture1);
7901 ok(SUCCEEDED(hr), "Failed to set texture, hr %#lx.\n", hr);
7902 hr = IDirect3DDevice8_SetTexture(device, 1, (IDirect3DBaseTexture8 *)texture2);
7903 ok(SUCCEEDED(hr), "Failed to set texture, hr %#lx.\n", hr);
7904 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX3);
7905 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr);
7906 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
7907 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#lx.\n", hr);
7908 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7909 ok(SUCCEEDED(hr), "Failed to set color op, hr %#lx.\n", hr);
7910 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7911 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#lx.\n", hr);
7912 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
7913 ok(SUCCEEDED(hr), "Failed to set color op, hr %#lx.\n", hr);
7914 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7915 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#lx.\n", hr);
7916 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
7917 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#lx.\n", hr);
7918 hr = IDirect3DDevice8_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
7919 ok(SUCCEEDED(hr), "Failed to set color op, hr %#lx.\n", hr);
7921 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_TEXCOORDINDEX, 1);
7922 ok(SUCCEEDED(hr), "Failed to set texcoord index, hr %#lx.\n", hr);
7923 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_TEXCOORDINDEX, 0);
7924 ok(SUCCEEDED(hr), "Failed to set texcoord index, hr %#lx.\n", hr);
7926 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 1.0f, 0);
7927 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
7929 hr = IDirect3DDevice8_BeginScene(device);
7930 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
7931 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
7932 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
7933 hr = IDirect3DDevice8_EndScene(device);
7934 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
7936 color = getPixelColor(device, 160, 120);
7937 ok(color_match(color, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color);
7938 color = getPixelColor(device, 480, 120);
7939 ok(color_match(color, 0x0000ffff, 2), "Got unexpected color 0x%08x.\n", color);
7940 color = getPixelColor(device, 160, 360);
7941 ok(color_match(color, 0x00ff0000, 2), "Got unexpected color 0x%08x.\n", color);
7942 color = getPixelColor(device, 480, 360);
7943 ok(color_match(color, 0x00ffffff, 2), "Got unexpected color 0x%08x.\n", color);
7945 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
7946 ok(SUCCEEDED(hr), "Failed to set texture transform flags, hr %#lx.\n", hr);
7947 hr = IDirect3DDevice8_SetTransform(device, D3DTS_TEXTURE1, &mat);
7948 ok(SUCCEEDED(hr), "Failed to set transformation matrix, hr %#lx.\n", hr);
7950 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 1.0f, 0);
7951 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
7953 hr = IDirect3DDevice8_BeginScene(device);
7954 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
7955 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
7956 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
7957 hr = IDirect3DDevice8_EndScene(device);
7958 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
7960 color = getPixelColor(device, 160, 120);
7961 ok(color_match(color, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color);
7962 color = getPixelColor(device, 480, 120);
7963 ok(color_match(color, 0x0000ffff, 2), "Got unexpected color 0x%08x.\n", color);
7964 color = getPixelColor(device, 160, 360);
7965 ok(color_match(color, 0x00000000, 2), "Got unexpected color 0x%08x.\n", color);
7966 color = getPixelColor(device, 480, 360);
7967 ok(color_match(color, 0x0000ffff, 2), "Got unexpected color 0x%08x.\n", color);
7969 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
7970 ok(SUCCEEDED(hr), "Failed to set texture transform flags, hr %#lx.\n", hr);
7971 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_TEXCOORDINDEX, 2);
7972 ok(SUCCEEDED(hr), "Failed to set texcoord index, hr %#lx.\n", hr);
7974 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 1.0f, 0);
7975 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
7977 hr = IDirect3DDevice8_BeginScene(device);
7978 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
7979 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
7980 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
7981 hr = IDirect3DDevice8_EndScene(device);
7982 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
7984 color = getPixelColor(device, 160, 120);
7985 ok(color_match(color, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color);
7986 color = getPixelColor(device, 480, 120);
7987 ok(color_match(color, 0x0000ffff, 2), "Got unexpected color 0x%08x.\n", color);
7988 color = getPixelColor(device, 160, 360);
7989 ok(color_match(color, 0x00ff00ff, 2), "Got unexpected color 0x%08x.\n", color);
7990 color = getPixelColor(device, 480, 360);
7991 ok(color_match(color, 0x00ffff00, 2), "Got unexpected color 0x%08x.\n", color);
7993 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
7994 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
7996 IDirect3DTexture8_Release(texture1);
7997 IDirect3DTexture8_Release(texture2);
7999 refcount = IDirect3DDevice8_Release(device);
8000 ok(!refcount, "Device has %lu references left.\n", refcount);
8001 IDirect3D8_Release(d3d);
8002 DestroyWindow(window);
8005 static void test_vshader_input(void)
8007 DWORD swapped_twotexcrd_shader, swapped_onetexcrd_shader = 0;
8008 DWORD swapped_twotex_wrongidx_shader = 0, swapped_twotexcrd_rightorder_shader;
8009 DWORD texcoord_color_shader, color_ubyte_shader, color_color_shader, color_float_shader;
8010 DWORD color_nocolor_shader = 0;
8011 IDirect3DDevice8 *device;
8012 unsigned int color;
8013 IDirect3D8 *d3d;
8014 ULONG refcount;
8015 D3DCAPS8 caps;
8016 HWND window;
8017 HRESULT hr;
8019 static const DWORD swapped_shader_code[] =
8021 0xfffe0101, /* vs_1_1 */
8022 0x00000001, 0xc00f0000, 0x90e40000, /* mov o0, v0 */
8023 0x00000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
8024 0x00000002, 0xd00f0000, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
8025 0x0000ffff /* end */
8027 static const DWORD texcoord_color_shader_code[] =
8029 0xfffe0101, /* vs_1_1 */
8030 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
8031 0x00000001, 0xd00f0000, 0x90e40007, /* mov oD0, v7 */
8032 0x0000ffff /* end */
8034 static const DWORD color_color_shader_code[] =
8036 0xfffe0101, /* vs_1_1 */
8037 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
8038 0x00000005, 0xd00f0000, 0xa0e40000, 0x90e40005, /* mul oD0, c0, v5 */
8039 0x0000ffff /* end */
8041 static const float quad1[] =
8043 -1.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
8044 -1.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
8045 0.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
8046 0.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
8048 static const float quad4[] =
8050 0.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
8051 0.0f, 1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
8052 1.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
8053 1.0f, 1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
8055 static const struct
8057 struct vec3 position;
8058 DWORD diffuse;
8060 quad1_color[] =
8062 {{-1.0f, -1.0f, 0.1f}, 0x00ff8040},
8063 {{-1.0f, 0.0f, 0.1f}, 0x00ff8040},
8064 {{ 0.0f, -1.0f, 0.1f}, 0x00ff8040},
8065 {{ 0.0f, 0.0f, 0.1f}, 0x00ff8040},
8067 quad2_color[] =
8069 {{ 0.0f, -1.0f, 0.1f}, 0x00ff8040},
8070 {{ 0.0f, 0.0f, 0.1f}, 0x00ff8040},
8071 {{ 1.0f, -1.0f, 0.1f}, 0x00ff8040},
8072 {{ 1.0f, 0.0f, 0.1f}, 0x00ff8040},
8074 static const struct
8076 struct vec3 position;
8077 struct vec3 dummy; /* testing D3DVSD_SKIP */
8078 DWORD diffuse;
8080 quad3_color[] =
8082 {{-1.0f, 0.0f, 0.1f}, {0.0f}, 0x00ff8040},
8083 {{-1.0f, 1.0f, 0.1f}, {0.0f}, 0x00ff8040},
8084 {{ 0.0f, 0.0f, 0.1f}, {0.0f}, 0x00ff8040},
8085 {{ 0.0f, 1.0f, 0.1f}, {0.0f}, 0x00ff8040},
8087 static const float quad4_color[] =
8089 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 0.0f, 0.0f,
8090 0.0f, 1.0f, 0.1f, 1.0f, 1.0f, 0.0f, 0.0f,
8091 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 0.0f, 1.0f,
8092 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 0.0f, 1.0f,
8094 static const DWORD decl_twotexcrd[] =
8096 D3DVSD_STREAM(0),
8097 D3DVSD_REG(0, D3DVSDT_FLOAT3), /* position */
8098 D3DVSD_REG(1, D3DVSDT_FLOAT4), /* texcoord0 */
8099 D3DVSD_REG(2, D3DVSDT_FLOAT4), /* texcoord1 */
8100 D3DVSD_END()
8102 static const DWORD decl_twotexcrd_rightorder[] =
8104 D3DVSD_STREAM(0),
8105 D3DVSD_REG(0, D3DVSDT_FLOAT3), /* position */
8106 D3DVSD_REG(2, D3DVSDT_FLOAT4), /* texcoord0 */
8107 D3DVSD_REG(1, D3DVSDT_FLOAT4), /* texcoord1 */
8108 D3DVSD_END()
8110 static const DWORD decl_onetexcrd[] =
8112 D3DVSD_STREAM(0),
8113 D3DVSD_REG(0, D3DVSDT_FLOAT3), /* position */
8114 D3DVSD_REG(1, D3DVSDT_FLOAT4), /* texcoord0 */
8115 D3DVSD_END()
8117 static const DWORD decl_twotexcrd_wrongidx[] =
8119 D3DVSD_STREAM(0),
8120 D3DVSD_REG(0, D3DVSDT_FLOAT3), /* position */
8121 D3DVSD_REG(2, D3DVSDT_FLOAT4), /* texcoord1 */
8122 D3DVSD_REG(3, D3DVSDT_FLOAT4), /* texcoord2 */
8123 D3DVSD_END()
8125 static const DWORD decl_texcoord_color[] =
8127 D3DVSD_STREAM(0),
8128 D3DVSD_REG(0, D3DVSDT_FLOAT3), /* position */
8129 D3DVSD_REG(7, D3DVSDT_D3DCOLOR), /* texcoord0 */
8130 D3DVSD_END()
8132 static const DWORD decl_color_color[] =
8134 D3DVSD_STREAM(0),
8135 D3DVSD_REG(0, D3DVSDT_FLOAT3), /* position */
8136 D3DVSD_SKIP(3), /* not used */
8137 D3DVSD_REG(5, D3DVSDT_D3DCOLOR), /* diffuse */
8138 D3DVSD_END()
8140 static const DWORD decl_color_ubyte[] =
8142 D3DVSD_STREAM(0),
8143 D3DVSD_REG(0, D3DVSDT_FLOAT3),
8144 D3DVSD_REG(5, D3DVSDT_UBYTE4),
8145 D3DVSD_END()
8147 static const DWORD decl_color_float[] =
8149 D3DVSD_STREAM(0),
8150 D3DVSD_REG(0, D3DVSDT_FLOAT3),
8151 D3DVSD_REG(5, D3DVSDT_FLOAT4),
8152 D3DVSD_END()
8154 static const DWORD decl_nocolor[] =
8156 D3DVSD_STREAM(0),
8157 D3DVSD_REG(0, D3DVSDT_FLOAT3),
8158 D3DVSD_END()
8160 static const float normalize[4] = {1.0f / 256.0f, 1.0f / 256.0f, 1.0f / 256.0f, 1.0f / 256.0f};
8161 static const float no_normalize[4] = {1.0f, 1.0f, 1.0f, 1.0f};
8163 window = create_window();
8164 d3d = Direct3DCreate8(D3D_SDK_VERSION);
8165 ok(!!d3d, "Failed to create a D3D object.\n");
8166 if (!(device = create_device(d3d, window, window, TRUE)))
8168 skip("Failed to create a D3D device, skipping tests.\n");
8169 goto done;
8172 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
8173 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
8174 if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1))
8176 skip("No vs_1_1 support, skipping tests.\n");
8177 IDirect3DDevice8_Release(device);
8178 goto done;
8181 hr = IDirect3DDevice8_CreateVertexShader(device, decl_twotexcrd, swapped_shader_code, &swapped_twotexcrd_shader, 0);
8182 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#lx.\n", hr);
8183 hr = IDirect3DDevice8_CreateVertexShader(device, decl_onetexcrd, swapped_shader_code, &swapped_onetexcrd_shader, 0);
8184 todo_wine ok(hr == D3DERR_INVALIDCALL, "Unexpected error while creating vertex shader, hr %#lx.\n", hr);
8185 hr = IDirect3DDevice8_CreateVertexShader(device, decl_twotexcrd_wrongidx, swapped_shader_code, &swapped_twotex_wrongidx_shader, 0);
8186 todo_wine ok(hr == D3DERR_INVALIDCALL, "Unexpected error while creating vertex shader, hr %#lx.\n", hr);
8187 hr = IDirect3DDevice8_CreateVertexShader(device, decl_twotexcrd_rightorder, swapped_shader_code, &swapped_twotexcrd_rightorder_shader, 0);
8188 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#lx.\n", hr);
8190 hr = IDirect3DDevice8_CreateVertexShader(device, decl_texcoord_color, texcoord_color_shader_code, &texcoord_color_shader, 0);
8191 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#lx.\n", hr);
8192 hr = IDirect3DDevice8_CreateVertexShader(device, decl_color_ubyte, color_color_shader_code, &color_ubyte_shader, 0);
8193 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#lx.\n", hr);
8194 hr = IDirect3DDevice8_CreateVertexShader(device, decl_color_color, color_color_shader_code, &color_color_shader, 0);
8195 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#lx.\n", hr);
8196 hr = IDirect3DDevice8_CreateVertexShader(device, decl_color_float, color_color_shader_code, &color_float_shader, 0);
8197 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#lx.\n", hr);
8198 hr = IDirect3DDevice8_CreateVertexShader(device, decl_nocolor, color_color_shader_code, &color_nocolor_shader, 0);
8199 todo_wine ok(hr == D3DERR_INVALIDCALL, "Unexpected error while creating vertex shader, hr %#lx.\n", hr);
8201 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 1.0f, 0);
8202 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
8204 hr = IDirect3DDevice8_BeginScene(device);
8205 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
8207 hr = IDirect3DDevice8_SetVertexShader(device, swapped_twotexcrd_shader);
8208 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#lx.\n", hr);
8210 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 11);
8211 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
8213 hr = IDirect3DDevice8_SetVertexShader(device, swapped_twotexcrd_rightorder_shader);
8214 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#lx.\n", hr);
8215 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 11);
8216 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
8218 hr = IDirect3DDevice8_EndScene(device);
8219 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
8221 color = getPixelColor(device, 160, 360);
8222 ok(color_match(color, 0x00ffff80, 1), "Got unexpected color 0x%08x for quad 1 (2crd).\n", color);
8223 color = getPixelColor(device, 480, 160);
8224 ok(color == 0x00000000, "Got unexpected color 0x%08x for quad 4 (2crd-rightorder).\n", color);
8226 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
8227 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
8229 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
8230 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
8232 hr = IDirect3DDevice8_BeginScene(device);
8233 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
8235 hr = IDirect3DDevice8_SetVertexShader(device, texcoord_color_shader);
8236 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#lx.\n", hr);
8237 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1_color, sizeof(quad1_color[0]));
8238 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
8240 hr = IDirect3DDevice8_SetVertexShader(device, color_ubyte_shader);
8241 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#lx.\n", hr);
8243 hr = IDirect3DDevice8_SetVertexShaderConstant(device, 0, normalize, 1);
8244 ok(SUCCEEDED(hr), "Failed to set vertex shader constant, hr %#lx.\n", hr);
8245 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_color, sizeof(quad2_color[0]));
8246 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
8248 hr = IDirect3DDevice8_SetVertexShaderConstant(device, 0, no_normalize, 1);
8249 ok(SUCCEEDED(hr), "Failed to set vertex shader constant, hr %#lx.\n", hr);
8250 hr = IDirect3DDevice8_SetVertexShader(device, color_color_shader);
8251 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#lx.\n", hr);
8252 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3_color, sizeof(quad3_color[0]));
8253 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
8255 hr = IDirect3DDevice8_SetVertexShader(device, color_float_shader);
8256 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#lx.\n", hr);
8257 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4_color, sizeof(float) * 7);
8258 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
8260 hr = IDirect3DDevice8_EndScene(device);
8261 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
8263 IDirect3DDevice8_SetVertexShader(device, 0);
8265 color = getPixelColor(device, 160, 360);
8266 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
8267 "Input test: Quad 1(color-texcoord) returned color 0x%08x, expected 0x00ff8040\n", color);
8268 color = getPixelColor(device, 480, 360);
8269 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x40, 0x80, 0xff), 1),
8270 "Input test: Quad 2(color-ubyte) returned color 0x%08x, expected 0x004080ff\n", color);
8271 color = getPixelColor(device, 160, 120);
8272 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
8273 "Input test: Quad 3(color-color) returned color 0x%08x, expected 0x00ff8040\n", color);
8274 color = getPixelColor(device, 480, 160);
8275 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 1),
8276 "Input test: Quad 4(color-float) returned color 0x%08x, expected 0x00ffff00\n", color);
8278 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
8279 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
8281 IDirect3DDevice8_DeleteVertexShader(device, swapped_twotexcrd_shader);
8282 IDirect3DDevice8_DeleteVertexShader(device, swapped_onetexcrd_shader);
8283 IDirect3DDevice8_DeleteVertexShader(device, swapped_twotex_wrongidx_shader);
8284 IDirect3DDevice8_DeleteVertexShader(device, swapped_twotexcrd_rightorder_shader);
8285 IDirect3DDevice8_DeleteVertexShader(device, texcoord_color_shader);
8286 IDirect3DDevice8_DeleteVertexShader(device, color_ubyte_shader);
8287 IDirect3DDevice8_DeleteVertexShader(device, color_color_shader);
8288 IDirect3DDevice8_DeleteVertexShader(device, color_float_shader);
8289 IDirect3DDevice8_DeleteVertexShader(device, color_nocolor_shader);
8291 refcount = IDirect3DDevice8_Release(device);
8292 ok(!refcount, "Device has %lu references left.\n", refcount);
8293 done:
8294 IDirect3D8_Release(d3d);
8295 DestroyWindow(window);
8298 static void test_fixed_function_fvf(void)
8300 IDirect3DDevice8 *device;
8301 unsigned int color;
8302 IDirect3D8 *d3d;
8303 ULONG refcount;
8304 D3DCAPS8 caps;
8305 HWND window;
8306 HRESULT hr;
8308 static const struct
8310 struct vec3 position;
8311 DWORD diffuse;
8313 quad1[] =
8315 {{-1.0f, -1.0f, 0.1f}, 0x00ffff00},
8316 {{-1.0f, 0.0f, 0.1f}, 0x00ffff00},
8317 {{ 0.0f, -1.0f, 0.1f}, 0x00ffff00},
8318 {{ 0.0f, 0.0f, 0.1f}, 0x00ffff00},
8320 static const struct vec3 quad2[] =
8322 {-1.0f, -1.0f, 0.1f},
8323 {-1.0f, 0.0f, 0.1f},
8324 { 0.0f, -1.0f, 0.1f},
8325 { 0.0f, 0.0f, 0.1f},
8327 static const struct
8329 struct vec4 position;
8330 DWORD diffuse;
8332 quad_transformed[] =
8334 {{ 90.0f, 110.0f, 0.1f, 2.0f}, 0x00ffff00},
8335 {{570.0f, 110.0f, 0.1f, 2.0f}, 0x00ffff00},
8336 {{ 90.0f, 300.0f, 0.1f, 2.0f}, 0x00ffff00},
8337 {{570.0f, 300.0f, 0.1f, 2.0f}, 0x00ffff00},
8340 window = create_window();
8341 d3d = Direct3DCreate8(D3D_SDK_VERSION);
8342 ok(!!d3d, "Failed to create a D3D object.\n");
8343 if (!(device = create_device(d3d, window, window, TRUE)))
8345 skip("Failed to create a D3D device, skipping tests.\n");
8346 goto done;
8349 memset(&caps, 0, sizeof(caps));
8350 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
8351 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
8353 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
8354 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
8356 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
8357 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#lx.\n", hr);
8359 hr = IDirect3DDevice8_BeginScene(device);
8360 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
8362 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8363 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr);
8364 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
8365 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
8367 hr = IDirect3DDevice8_EndScene(device);
8368 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
8370 color = getPixelColor(device, 160, 360);
8371 ok(color == 0x00ffff00,
8372 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
8373 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
8375 /* Test with no diffuse color attribute. */
8376 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8377 ok(SUCCEEDED(hr), "Got hr %#lx.\n", hr);
8379 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ);
8380 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr);
8381 hr = IDirect3DDevice8_BeginScene(device);
8382 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
8383 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad2, sizeof(quad2[0]));
8384 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
8385 hr = IDirect3DDevice8_EndScene(device);
8386 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
8388 color = getPixelColor(device, 160, 360);
8389 ok(color == 0x00ffffff, "Got unexpected color 0x%08x in the no diffuse attribute test.\n", color);
8390 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
8392 /* Test what happens with specular lighting enabled and no specular color attribute. */
8393 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
8394 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
8395 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SPECULARENABLE, TRUE);
8396 ok(SUCCEEDED(hr), "Failed to enable specular lighting, hr %#lx.\n", hr);
8397 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8398 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr);
8399 hr = IDirect3DDevice8_BeginScene(device);
8400 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
8402 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad1, sizeof(quad1[0]));
8403 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
8405 hr = IDirect3DDevice8_EndScene(device);
8406 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
8407 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SPECULARENABLE, FALSE);
8408 ok(SUCCEEDED(hr), "Failed to disable specular lighting, hr %#lx.\n", hr);
8410 color = getPixelColor(device, 160, 360);
8411 ok(color == 0x00ffff00, "Got unexpected color 0x%08x in the no specular attribute test.\n", color);
8413 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
8415 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
8416 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr);
8418 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8419 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
8421 hr = IDirect3DDevice8_BeginScene(device);
8422 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
8423 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad_transformed, sizeof(quad_transformed[0]));
8424 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
8425 hr = IDirect3DDevice8_EndScene(device);
8426 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
8428 color = getPixelColor(device, 88, 108);
8429 ok(color == 0x000000ff,
8430 "pixel 88/108 has color %08x, expected 0x000000ff\n", color);
8431 color = getPixelColor(device, 92, 108);
8432 ok(color == 0x000000ff,
8433 "pixel 92/108 has color %08x, expected 0x000000ff\n", color);
8434 color = getPixelColor(device, 88, 112);
8435 ok(color == 0x000000ff,
8436 "pixel 88/112 has color %08x, expected 0x000000ff\n", color);
8437 color = getPixelColor(device, 92, 112);
8438 ok(color == 0x00ffff00,
8439 "pixel 92/112 has color %08x, expected 0x00ffff00\n", color);
8441 color = getPixelColor(device, 568, 108);
8442 ok(color == 0x000000ff,
8443 "pixel 568/108 has color %08x, expected 0x000000ff\n", color);
8444 color = getPixelColor(device, 572, 108);
8445 ok(color == 0x000000ff,
8446 "pixel 572/108 has color %08x, expected 0x000000ff\n", color);
8447 color = getPixelColor(device, 568, 112);
8448 ok(color == 0x00ffff00,
8449 "pixel 568/112 has color %08x, expected 0x00ffff00\n", color);
8450 color = getPixelColor(device, 572, 112);
8451 ok(color == 0x000000ff,
8452 "pixel 572/112 has color %08x, expected 0x000000ff\n", color);
8454 color = getPixelColor(device, 88, 298);
8455 ok(color == 0x000000ff,
8456 "pixel 88/298 has color %08x, expected 0x000000ff\n", color);
8457 color = getPixelColor(device, 92, 298);
8458 ok(color == 0x00ffff00,
8459 "pixel 92/298 has color %08x, expected 0x00ffff00\n", color);
8460 color = getPixelColor(device, 88, 302);
8461 ok(color == 0x000000ff,
8462 "pixel 88/302 has color %08x, expected 0x000000ff\n", color);
8463 color = getPixelColor(device, 92, 302);
8464 ok(color == 0x000000ff,
8465 "pixel 92/302 has color %08x, expected 0x000000ff\n", color);
8467 color = getPixelColor(device, 568, 298);
8468 ok(color == 0x00ffff00,
8469 "pixel 568/298 has color %08x, expected 0x00ffff00\n", color);
8470 color = getPixelColor(device, 572, 298);
8471 ok(color == 0x000000ff,
8472 "pixel 572/298 has color %08x, expected 0x000000ff\n", color);
8473 color = getPixelColor(device, 568, 302);
8474 ok(color == 0x000000ff,
8475 "pixel 568/302 has color %08x, expected 0x000000ff\n", color);
8476 color = getPixelColor(device, 572, 302);
8477 ok(color == 0x000000ff,
8478 "pixel 572/302 has color %08x, expected 0x000000ff\n", color);
8480 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
8482 refcount = IDirect3DDevice8_Release(device);
8483 ok(!refcount, "Device has %lu references left.\n", refcount);
8484 done:
8485 IDirect3D8_Release(d3d);
8486 DestroyWindow(window);
8489 static void test_flip(void)
8491 IDirect3DDevice8 *device;
8492 unsigned int color, i;
8493 IDirect3D8 *d3d;
8494 ULONG refcount;
8495 HWND window;
8496 HRESULT hr;
8497 IDirect3DSurface8 *back_buffers[3], *test_surface;
8498 D3DPRESENT_PARAMETERS present_parameters = {0};
8500 window = create_window();
8501 d3d = Direct3DCreate8(D3D_SDK_VERSION);
8502 ok(!!d3d, "Failed to create a D3D object.\n");
8504 present_parameters.BackBufferWidth = 640;
8505 present_parameters.BackBufferHeight = 480;
8506 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
8507 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
8508 present_parameters.hDeviceWindow = window;
8509 present_parameters.Windowed = TRUE;
8510 present_parameters.BackBufferCount = 3;
8511 present_parameters.Flags = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER;
8512 if (FAILED(hr = IDirect3D8_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
8513 window, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device)))
8515 skip("Failed to create a D3D device, skipping tests.\n");
8516 IDirect3D8_Release(d3d);
8517 DestroyWindow(window);
8518 return;
8521 for (i = 0; i < ARRAY_SIZE(back_buffers); ++i)
8523 hr = IDirect3DDevice8_GetBackBuffer(device, i, D3DBACKBUFFER_TYPE_MONO, &back_buffers[i]);
8524 ok(SUCCEEDED(hr), "Failed to get back buffer, hr %#lx.\n", hr);
8526 hr = IDirect3DDevice8_GetRenderTarget(device, &test_surface);
8527 ok(SUCCEEDED(hr), "Failed to get render target, hr %#lx.\n", hr);
8528 ok(test_surface == back_buffers[0], "Expected render target %p, got %p.\n", back_buffers[0], test_surface);
8529 IDirect3DSurface8_Release(test_surface);
8532 hr = IDirect3DDevice8_SetRenderTarget(device, back_buffers[0], NULL);
8533 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
8534 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0f, 0);
8535 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx\n", hr);
8537 hr = IDirect3DDevice8_SetRenderTarget(device, back_buffers[1], NULL);
8538 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
8539 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0f, 0);
8540 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx\n", hr);
8542 hr = IDirect3DDevice8_SetRenderTarget(device, back_buffers[2], NULL);
8543 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
8544 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0f, 0);
8545 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx\n", hr);
8547 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
8548 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
8550 /* Render target is unmodified. */
8551 hr = IDirect3DDevice8_GetRenderTarget(device, &test_surface);
8552 ok(SUCCEEDED(hr), "Failed to get render target, hr %#lx.\n", hr);
8553 ok(test_surface == back_buffers[2], "Expected render target %p, got %p.\n", back_buffers[2], test_surface);
8554 IDirect3DSurface8_Release(test_surface);
8556 /* Backbuffer surface pointers are unmodified */
8557 for (i = 0; i < ARRAY_SIZE(back_buffers); ++i)
8559 hr = IDirect3DDevice8_GetBackBuffer(device, i, D3DBACKBUFFER_TYPE_MONO, &test_surface);
8560 ok(SUCCEEDED(hr), "Failed to get back buffer, hr %#lx.\n", hr);
8561 ok(test_surface == back_buffers[i], "Expected back buffer %u = %p, got %p.\n",
8562 i, back_buffers[i], test_surface);
8563 IDirect3DSurface8_Release(test_surface);
8566 /* Contents were changed. */
8567 color = get_surface_color(back_buffers[0], 1, 1);
8568 ok(color == 0xff00ff00, "Got unexpected color 0x%08x.\n", color);
8569 color = get_surface_color(back_buffers[1], 1, 1);
8570 ok(color == 0xff0000ff, "Got unexpected color 0x%08x.\n", color);
8572 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff808080, 0.0f, 0);
8573 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx\n", hr);
8575 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
8576 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
8578 color = get_surface_color(back_buffers[0], 1, 1);
8579 ok(color == 0xff0000ff, "Got unexpected color 0x%08x.\n", color);
8580 color = get_surface_color(back_buffers[1], 1, 1);
8581 ok(color == 0xff808080, "Got unexpected color 0x%08x.\n", color);
8583 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
8584 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
8586 color = get_surface_color(back_buffers[0], 1, 1);
8587 ok(color == 0xff808080, "Got unexpected color 0x%08x.\n", color);
8589 for (i = 0; i < ARRAY_SIZE(back_buffers); ++i)
8590 IDirect3DSurface8_Release(back_buffers[i]);
8592 refcount = IDirect3DDevice8_Release(device);
8593 ok(!refcount, "Device has %lu references left.\n", refcount);
8595 if (FAILED(IDirect3D8_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
8596 D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES)))
8598 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping multisample flip test.\n");
8599 goto done;
8602 present_parameters.BackBufferCount = 2;
8603 present_parameters.MultiSampleType = D3DMULTISAMPLE_2_SAMPLES;
8604 present_parameters.Flags = 0;
8605 hr = IDirect3D8_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
8606 window, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device);
8608 for (i = 0; i < present_parameters.BackBufferCount; ++i)
8610 hr = IDirect3DDevice8_GetBackBuffer(device, i, D3DBACKBUFFER_TYPE_MONO, &back_buffers[i]);
8611 ok(SUCCEEDED(hr), "Failed to get back buffer, hr %#lx.\n", hr);
8614 hr = IDirect3DDevice8_SetRenderTarget(device, back_buffers[1], NULL);
8615 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
8616 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff808080, 0.0f, 0);
8617 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
8619 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
8620 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
8622 hr = IDirect3DDevice8_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
8623 D3DMULTISAMPLE_NONE, TRUE, &test_surface);
8624 ok(SUCCEEDED(hr), "Failed to create surface, hr %#lx.\n", hr);
8625 hr = IDirect3DDevice8_CopyRects(device, back_buffers[0], NULL, 0, test_surface, NULL);
8626 ok(SUCCEEDED(hr), "CopyRects failed, hr %#lx.\n", hr);
8628 color = get_surface_color(test_surface, 1, 1);
8629 ok(color == 0xff808080, "Got unexpected color 0x%08x.\n", color);
8631 IDirect3DSurface8_Release(test_surface);
8632 for (i = 0; i < present_parameters.BackBufferCount; ++i)
8633 IDirect3DSurface8_Release(back_buffers[i]);
8635 refcount = IDirect3DDevice8_Release(device);
8636 ok(!refcount, "Device has %lu references left.\n", refcount);
8638 done:
8639 IDirect3D8_Release(d3d);
8640 DestroyWindow(window);
8643 static void test_uninitialized_varyings(void)
8645 static const D3DMATRIX mat =
8647 1.0f, 0.0f, 0.0f, 0.0f,
8648 0.0f, 1.0f, 0.0f, 0.0f,
8649 0.0f, 0.0f, 1.0f, 0.0f,
8650 0.0f, 0.0f, 0.0f, 1.0f,
8651 }}};
8652 static const struct vec3 quad[] =
8654 {-1.0f, -1.0f, 0.1f},
8655 {-1.0f, 1.0f, 0.1f},
8656 { 1.0f, -1.0f, 0.1f},
8657 { 1.0f, 1.0f, 0.1f},
8659 static const DWORD decl[] =
8661 D3DVSD_STREAM(0),
8662 D3DVSD_REG(0, D3DVSDT_FLOAT3),
8663 D3DVSD_CONST(0, 1), 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, /* def c0, 0.5, 0.5, 0.5, 0.5 */
8664 D3DVSD_END()
8666 static const DWORD vs1_code[] =
8668 0xfffe0101, /* vs_1_1 */
8669 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
8670 0x0000ffff
8672 static const DWORD vs1_partial_code[] =
8674 0xfffe0101, /* vs_1_1 */
8675 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
8676 0x00000001, 0xd0010000, 0xa0e40000, /* mov oD0.x, c0 */
8677 0x00000001, 0xd0010001, 0xa0e40000, /* mov oD1.x, c0 */
8678 0x00000001, 0xe0010000, 0xa0e40000, /* mov oT0.x, c0 */
8679 0x0000ffff
8681 static const DWORD ps1_diffuse_code[] =
8683 0xffff0101, /* ps_1_1 */
8684 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
8685 0x0000ffff
8687 static const DWORD ps1_specular_code[] =
8689 0xffff0101, /* ps_1_1 */
8690 0x00000001, 0x800f0000, 0x90e40001, /* mov r0, v1 */
8691 0x0000ffff
8693 static const DWORD ps1_texcoord_code[] =
8695 0xffff0101, /* ps_1_1 */
8696 0x00000040, 0xb00f0000, /* texcoord t0 */
8697 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
8698 0x0000ffff
8700 static const struct
8702 DWORD vs_version;
8703 const DWORD *vs;
8704 DWORD ps_version;
8705 const DWORD *ps;
8706 D3DCOLOR expected;
8707 BOOL allow_zero_alpha;
8708 BOOL partial;
8709 BOOL broken_warp;
8711 /* On AMD specular color is generally initialized to 0x00000000 and texcoords to 0xff000000
8712 * while on Nvidia it's the opposite. Just allow both.
8714 * Partially initialized varyings reliably handle the component that has been initialized.
8715 * The uninitialized components generally follow the rule above, with some exceptions on
8716 * radeon cards. r500 and r600 GPUs have been found to set uninitialized components to 0.0,
8717 * 0.5 and 1.0 without a sensible pattern. */
8718 tests[] =
8720 {D3DVS_VERSION(1, 1), vs1_code, 0, NULL, 0xffffffff},
8721 { 0, NULL, D3DPS_VERSION(1, 1), ps1_texcoord_code, 0xff000000, TRUE},
8722 {D3DVS_VERSION(1, 1), vs1_code, D3DPS_VERSION(1, 1), ps1_diffuse_code, 0xffffffff},
8723 {D3DVS_VERSION(1, 1), vs1_code, D3DPS_VERSION(1, 1), ps1_specular_code, 0xff000000, TRUE, FALSE, TRUE},
8724 {D3DVS_VERSION(1, 1), vs1_code, D3DPS_VERSION(1, 1), ps1_texcoord_code, 0xff000000, TRUE},
8725 {D3DVS_VERSION(1, 1), vs1_partial_code, 0, NULL, 0xff7fffff, FALSE, TRUE},
8726 {D3DVS_VERSION(1, 1), vs1_partial_code, D3DPS_VERSION(1, 1), ps1_diffuse_code, 0xff7fffff, FALSE, TRUE},
8727 {D3DVS_VERSION(1, 1), vs1_partial_code, D3DPS_VERSION(1, 1), ps1_specular_code, 0xff7f0000, TRUE, TRUE},
8728 {D3DVS_VERSION(1, 1), vs1_partial_code, D3DPS_VERSION(1, 1), ps1_texcoord_code, 0xff7f0000, TRUE, TRUE},
8730 IDirect3DDevice8 *device;
8731 unsigned int color, i;
8732 IDirect3D8 *d3d;
8733 HWND window;
8734 HRESULT hr;
8735 DWORD vs, ps;
8736 ULONG refcount;
8737 D3DCAPS8 caps;
8738 IDirect3DSurface8 *backbuffer;
8739 D3DADAPTER_IDENTIFIER8 identifier;
8740 struct surface_readback rb;
8741 BOOL warp;
8743 window = create_window();
8744 d3d = Direct3DCreate8(D3D_SDK_VERSION);
8745 ok(!!d3d, "Failed to create a D3D object.\n");
8746 if (!(device = create_device(d3d, window, window, TRUE)))
8748 skip("Failed to create a D3D device, skipping tests.\n");
8749 IDirect3D8_Release(d3d);
8750 DestroyWindow(window);
8751 return;
8754 hr = IDirect3D8_GetAdapterIdentifier(d3d, D3DADAPTER_DEFAULT, 0, &identifier);
8755 ok(SUCCEEDED(hr), "Failed to get adapter identifier, hr %#lx.\n", hr);
8756 warp = adapter_is_warp(&identifier);
8758 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
8759 ok(SUCCEEDED(hr), "Failed to get caps, hr %#lx.\n", hr);
8761 hr = IDirect3DDevice8_GetBackBuffer(device, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8762 ok(SUCCEEDED(hr), "Failed to get back buffer, hr %#lx.\n", hr);
8764 hr = IDirect3DDevice8_SetTransform(device, D3DTS_WORLD, &mat);
8765 ok(SUCCEEDED(hr), "Failed to set world transform, hr %#lx.\n", hr);
8766 hr = IDirect3DDevice8_SetTransform(device, D3DTS_VIEW, &mat);
8767 ok(SUCCEEDED(hr), "Failed to set view transform, hr %#lx.\n", hr);
8768 hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, &mat);
8769 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#lx.\n", hr);
8770 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, FALSE);
8771 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#lx.\n", hr);
8772 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, FALSE);
8773 ok(SUCCEEDED(hr), "Failed to disable Z test, hr %#lx.\n", hr);
8774 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
8775 ok(SUCCEEDED(hr), "Failed to disable fog, hr %#lx.\n", hr);
8776 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
8777 ok(SUCCEEDED(hr), "Failed to disable stencil test, hr %#lx.\n", hr);
8778 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8779 ok(SUCCEEDED(hr), "Failed to disable culling, hr %#lx.\n", hr);
8781 for (i = 0; i < ARRAY_SIZE(tests); ++i)
8783 if (caps.VertexShaderVersion < tests[i].vs_version
8784 || caps.PixelShaderVersion < tests[i].ps_version)
8786 skip("Vertex / pixel shader version not supported, skipping test %u.\n", i);
8787 continue;
8789 if (tests[i].vs)
8791 hr = IDirect3DDevice8_CreateVertexShader(device, decl, tests[i].vs, &vs, 0);
8792 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#lx (case %u).\n", hr, i);
8793 hr = IDirect3DDevice8_SetVertexShader(device, vs);
8794 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#lx.\n", hr);
8796 else
8798 vs = 0;
8799 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ);
8800 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#lx.\n", hr);
8802 if (tests[i].ps)
8804 hr = IDirect3DDevice8_CreatePixelShader(device, tests[i].ps, &ps);
8805 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#lx (case %u).\n", hr, i);
8807 else
8809 ps = 0;
8812 hr = IDirect3DDevice8_SetPixelShader(device, ps);
8813 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#lx.\n", hr);
8815 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0f, 0);
8816 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
8818 hr = IDirect3DDevice8_BeginScene(device);
8819 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
8821 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
8822 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
8824 hr = IDirect3DDevice8_EndScene(device);
8825 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
8827 get_surface_readback(backbuffer, &rb);
8828 color = get_readback_color(&rb, 320, 240);
8829 ok(color_match(color, tests[i].expected, 1)
8830 || (tests[i].allow_zero_alpha && color_match(color, tests[i].expected & 0x00ffffff, 1))
8831 || (broken(warp && tests[i].broken_warp))
8832 || broken(tests[i].partial && color_match(color & 0x00ff0000, tests[i].expected & 0x00ff0000, 1)),
8833 "Got unexpected color 0x%08x, case %u.\n", color, i);
8834 release_surface_readback(&rb);
8836 if (vs)
8837 IDirect3DDevice8_DeleteVertexShader(device, vs);
8838 if (ps)
8839 IDirect3DDevice8_DeletePixelShader(device, ps);
8842 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
8843 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
8845 IDirect3DSurface8_Release(backbuffer);
8846 refcount = IDirect3DDevice8_Release(device);
8847 ok(!refcount, "Device has %lu references left.\n", refcount);
8848 IDirect3D8_Release(d3d);
8849 DestroyWindow(window);
8852 static void test_shademode(void)
8854 IDirect3DVertexBuffer8 *vb_strip;
8855 IDirect3DVertexBuffer8 *vb_list;
8856 unsigned int color0, color1;
8857 IDirect3DDevice8 *device;
8858 BYTE *data = NULL;
8859 IDirect3D8 *d3d;
8860 ULONG refcount;
8861 D3DCAPS8 caps;
8862 DWORD vs, ps;
8863 HWND window;
8864 HRESULT hr;
8865 UINT i;
8866 static const DWORD decl[] =
8868 D3DVSD_STREAM(0),
8869 D3DVSD_REG(D3DVSDE_POSITION, D3DVSDT_FLOAT3),
8870 D3DVSD_REG(D3DVSDE_DIFFUSE, D3DVSDT_D3DCOLOR),
8871 D3DVSD_END()
8873 static const DWORD vs1_code[] =
8875 0xfffe0101, /* vs_1_1 */
8876 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
8877 0x00000001, 0xd00f0000, 0x90e40005, /* mov oD0, v5 */
8878 0x0000ffff
8880 static const DWORD ps1_code[] =
8882 0xffff0101, /* ps_1_1 */
8883 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
8884 0x0000ffff
8886 static const struct
8888 struct vec3 position;
8889 DWORD diffuse;
8891 quad_strip[] =
8893 {{-1.0f, -1.0f, 0.0f}, 0xffff0000},
8894 {{-1.0f, 1.0f, 0.0f}, 0xff00ff00},
8895 {{ 1.0f, -1.0f, 0.0f}, 0xff0000ff},
8896 {{ 1.0f, 1.0f, 0.0f}, 0xffffffff},
8898 quad_list[] =
8900 {{-1.0f, -1.0f, 0.0f}, 0xffff0000},
8901 {{-1.0f, 1.0f, 0.0f}, 0xff00ff00},
8902 {{ 1.0f, -1.0f, 0.0f}, 0xff0000ff},
8904 {{ 1.0f, -1.0f, 0.0f}, 0xff0000ff},
8905 {{-1.0f, 1.0f, 0.0f}, 0xff00ff00},
8906 {{ 1.0f, 1.0f, 0.0f}, 0xffffffff},
8908 static const struct test_shader
8910 DWORD version;
8911 const DWORD *code;
8913 novs = {0, NULL},
8914 vs_1 = {D3DVS_VERSION(1, 1), vs1_code},
8915 nops = {0, NULL},
8916 ps_1 = {D3DPS_VERSION(1, 1), ps1_code};
8917 static const struct
8919 const struct test_shader *vs, *ps;
8920 DWORD primtype;
8921 DWORD shademode;
8922 unsigned int color0, color1;
8924 tests[] =
8926 {&novs, &nops, D3DPT_TRIANGLESTRIP, D3DSHADE_FLAT, 0x00ff0000, 0x0000ff00},
8927 {&novs, &nops, D3DPT_TRIANGLESTRIP, D3DSHADE_PHONG, 0x000dca28, 0x000d45c7},
8928 {&novs, &nops, D3DPT_TRIANGLESTRIP, D3DSHADE_GOURAUD, 0x000dca28, 0x000d45c7},
8929 {&novs, &nops, D3DPT_TRIANGLESTRIP, D3DSHADE_PHONG, 0x000dca28, 0x000d45c7},
8930 {&novs, &nops, D3DPT_TRIANGLELIST, D3DSHADE_FLAT, 0x00ff0000, 0x000000ff},
8931 {&novs, &nops, D3DPT_TRIANGLELIST, D3DSHADE_GOURAUD, 0x000dca28, 0x000d45c7},
8932 {&vs_1, &ps_1, D3DPT_TRIANGLESTRIP, D3DSHADE_FLAT, 0x00ff0000, 0x0000ff00},
8933 {&vs_1, &ps_1, D3DPT_TRIANGLESTRIP, D3DSHADE_GOURAUD, 0x000dca28, 0x000d45c7},
8934 {&vs_1, &ps_1, D3DPT_TRIANGLELIST, D3DSHADE_FLAT, 0x00ff0000, 0x000000ff},
8935 {&vs_1, &ps_1, D3DPT_TRIANGLELIST, D3DSHADE_GOURAUD, 0x000dca28, 0x000d45c7},
8936 {&novs, &ps_1, D3DPT_TRIANGLESTRIP, D3DSHADE_FLAT, 0x00ff0000, 0x0000ff00},
8937 {&vs_1, &nops, D3DPT_TRIANGLESTRIP, D3DSHADE_FLAT, 0x00ff0000, 0x0000ff00},
8940 window = create_window();
8941 d3d = Direct3DCreate8(D3D_SDK_VERSION);
8942 ok(!!d3d, "Failed to create a D3D object.\n");
8943 if (!(device = create_device(d3d, window, window, TRUE)))
8945 skip("Failed to create a D3D device, skipping tests.\n");
8946 IDirect3D8_Release(d3d);
8947 DestroyWindow(window);
8948 return;
8951 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
8952 ok(hr == D3D_OK, "Failed to disable lighting, hr %#lx.\n", hr);
8953 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
8954 ok(SUCCEEDED(hr), "Failed to disable fog, hr %#lx.\n", hr);
8956 hr = IDirect3DDevice8_CreateVertexBuffer(device, sizeof(quad_strip), 0, 0, D3DPOOL_MANAGED, &vb_strip);
8957 ok(hr == D3D_OK, "Failed to create vertex buffer, hr %#lx.\n", hr);
8958 hr = IDirect3DVertexBuffer8_Lock(vb_strip, 0, sizeof(quad_strip), &data, 0);
8959 ok(hr == D3D_OK, "Failed to lock vertex buffer, hr %#lx.\n", hr);
8960 memcpy(data, quad_strip, sizeof(quad_strip));
8961 hr = IDirect3DVertexBuffer8_Unlock(vb_strip);
8962 ok(hr == D3D_OK, "Failed to unlock vertex buffer, hr %#lx.\n", hr);
8964 hr = IDirect3DDevice8_CreateVertexBuffer(device, sizeof(quad_list), 0, 0, D3DPOOL_MANAGED, &vb_list);
8965 ok(hr == D3D_OK, "Failed to create vertex buffer, hr %#lx.\n", hr);
8966 hr = IDirect3DVertexBuffer8_Lock(vb_list, 0, sizeof(quad_list), &data, 0);
8967 ok(hr == D3D_OK, "Failed to lock vertex buffer, hr %#lx.\n", hr);
8968 memcpy(data, quad_list, sizeof(quad_list));
8969 hr = IDirect3DVertexBuffer8_Unlock(vb_list);
8970 ok(hr == D3D_OK, "Failed to unlock vertex buffer, hr %#lx.\n", hr);
8972 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
8973 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
8975 /* Try it first with a TRIANGLESTRIP. Do it with different geometry because
8976 * the color fixups we have to do for FLAT shading will be dependent on that. */
8978 for (i = 0; i < ARRAY_SIZE(tests); ++i)
8980 if (tests[i].vs->version)
8982 if (caps.VertexShaderVersion >= tests[i].vs->version)
8984 hr = IDirect3DDevice8_CreateVertexShader(device, decl, tests[i].vs->code, &vs, 0);
8985 ok(hr == D3D_OK, "Failed to create vertex shader, hr %#lx.\n", hr);
8986 hr = IDirect3DDevice8_SetVertexShader(device, vs);
8987 ok(hr == D3D_OK, "Failed to set vertex shader, hr %#lx.\n", hr);
8989 else
8991 skip("Shader version unsupported, skipping some tests.\n");
8992 continue;
8995 else
8997 vs = 0;
8998 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8999 ok(hr == D3D_OK, "Failed to set FVF, hr %#lx.\n", hr);
9001 if (tests[i].ps->version)
9003 if (caps.PixelShaderVersion >= tests[i].ps->version)
9005 hr = IDirect3DDevice8_CreatePixelShader(device, tests[i].ps->code, &ps);
9006 ok(hr == D3D_OK, "Failed to create pixel shader, hr %#lx.\n", hr);
9007 hr = IDirect3DDevice8_SetPixelShader(device, ps);
9008 ok(hr == D3D_OK, "Failed to set pixel shader, hr %#lx.\n", hr);
9010 else
9012 skip("Shader version unsupported, skipping some tests.\n");
9013 if (vs)
9015 IDirect3DDevice8_SetVertexShader(device, 0);
9016 IDirect3DDevice8_DeleteVertexShader(device, vs);
9018 continue;
9021 else
9023 ps = 0;
9026 hr = IDirect3DDevice8_SetStreamSource(device, 0,
9027 tests[i].primtype == D3DPT_TRIANGLESTRIP ? vb_strip : vb_list, sizeof(quad_strip[0]));
9028 ok(hr == D3D_OK, "Failed to set stream source, hr %#lx.\n", hr);
9030 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
9031 ok(hr == D3D_OK, "Failed to clear, hr %#lx.\n", hr);
9033 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SHADEMODE, tests[i].shademode);
9034 ok(hr == D3D_OK, "Failed to set shade mode, hr %#lx.\n", hr);
9036 hr = IDirect3DDevice8_BeginScene(device);
9037 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
9038 hr = IDirect3DDevice8_DrawPrimitive(device, tests[i].primtype, 0, 2);
9039 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
9040 hr = IDirect3DDevice8_EndScene(device);
9041 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
9043 color0 = getPixelColor(device, 100, 100); /* Inside first triangle */
9044 color1 = getPixelColor(device, 500, 350); /* Inside second triangle */
9046 /* For D3DSHADE_FLAT it should take the color of the first vertex of
9047 * each triangle. This requires EXT_provoking_vertex or similar
9048 * functionality being available. */
9049 /* PHONG should be the same as GOURAUD, since no hardware implements
9050 * this. */
9051 ok(color_match(color0, tests[i].color0, 1), "Test %u shading has color0 %08x, expected %08x.\n",
9052 i, color0, tests[i].color0);
9053 ok(color_match(color1, tests[i].color1, 1), "Test %u shading has color1 %08x, expected %08x.\n",
9054 i, color1, tests[i].color1);
9056 IDirect3DDevice8_SetVertexShader(device, 0);
9057 IDirect3DDevice8_SetPixelShader(device, 0);
9059 if (ps)
9060 IDirect3DDevice8_DeletePixelShader(device, ps);
9061 if (vs)
9062 IDirect3DDevice8_DeleteVertexShader(device, vs);
9065 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
9066 ok(hr == D3D_OK, "Failed to present, hr %#lx.\n", hr);
9068 IDirect3DVertexBuffer8_Release(vb_strip);
9069 IDirect3DVertexBuffer8_Release(vb_list);
9070 refcount = IDirect3DDevice8_Release(device);
9071 ok(!refcount, "Device has %lu references left.\n", refcount);
9072 IDirect3D8_Release(d3d);
9073 DestroyWindow(window);
9076 static void test_multisample_init(void)
9078 IDirect3DDevice8 *device;
9079 unsigned int color, x, y;
9080 IDirect3D8 *d3d;
9081 IDirect3DSurface8 *back, *multi;
9082 ULONG refcount;
9083 HWND window;
9084 HRESULT hr;
9085 struct surface_readback rb;
9086 BOOL all_zero = TRUE;
9088 window = create_window();
9089 d3d = Direct3DCreate8(D3D_SDK_VERSION);
9090 ok(!!d3d, "Failed to create a D3D object.\n");
9092 if (FAILED(IDirect3D8_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
9093 D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES)))
9095 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping multisample init test.\n");
9096 goto done;
9099 if (!(device = create_device(d3d, window, window, TRUE)))
9101 skip("Failed to create a D3D device, skipping tests.\n");
9102 goto done;
9105 hr = IDirect3DDevice8_GetBackBuffer(device, 0, D3DBACKBUFFER_TYPE_MONO, &back);
9106 ok(SUCCEEDED(hr), "Failed to get back buffer, hr %#lx.\n", hr);
9107 hr = IDirect3DDevice8_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
9108 D3DMULTISAMPLE_2_SAMPLES, FALSE, &multi);
9109 ok(SUCCEEDED(hr), "Failed to create multisampled render target, hr %#lx.\n", hr);
9111 hr = IDirect3DDevice8_CopyRects(device, multi, NULL, 0, back, NULL);
9112 ok(SUCCEEDED(hr), "CopyRects failed, hr %#lx.\n", hr);
9114 get_surface_readback(back, &rb);
9115 for (y = 0; y < 480; ++y)
9117 for (x = 0; x < 640; ++x)
9119 color = get_readback_color(&rb, x, y);
9120 if (!color_match(color, 0x00000000, 0))
9122 all_zero = FALSE;
9123 break;
9126 if (!all_zero)
9127 break;
9129 release_surface_readback(&rb);
9130 ok(all_zero, "Got unexpected color 0x%08x, position %ux%u.\n", color, x, y);
9132 IDirect3DSurface8_Release(multi);
9133 IDirect3DSurface8_Release(back);
9135 refcount = IDirect3DDevice8_Release(device);
9136 ok(!refcount, "Device has %lu references left.\n", refcount);
9138 done:
9139 IDirect3D8_Release(d3d);
9140 DestroyWindow(window);
9143 static void test_texture_blending(void)
9145 #define STATE_END() {0xffffffff, 0xffffffff}
9146 #define IS_STATE_END(s) (s.name == 0xffffffff && s.value == 0xffffffff)
9148 IDirect3DTexture8 *texture_bumpmap, *texture_red;
9149 IDirect3DSurface8 *backbuffer;
9150 unsigned int color, i, j, k;
9151 struct surface_readback rb;
9152 D3DLOCKED_RECT locked_rect;
9153 IDirect3DDevice8 *device;
9154 IDirect3D8 *d3d;
9155 ULONG refcount;
9156 D3DCAPS8 caps;
9157 HWND window;
9158 HRESULT hr;
9160 static const struct
9162 struct vec3 position;
9163 DWORD diffuse;
9165 quad[] =
9167 {{-1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0x80, 0xff, 0xff, 0x02)},
9168 {{-1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0x80, 0xff, 0xff, 0x02)},
9169 {{ 1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0x80, 0xff, 0xff, 0x02)},
9170 {{ 1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0x80, 0xff, 0xff, 0x02)},
9173 static const float bumpenvmat[4] = {1.0f, 1.0f, 0.0f, 0.0f};
9175 struct texture_stage_state
9177 D3DTEXTURESTAGESTATETYPE name;
9178 DWORD value;
9181 struct texture_stage
9183 enum
9185 TEXTURE_INVALID,
9186 TEXTURE_NONE,
9187 TEXTURE_BUMPMAP,
9188 TEXTURE_RED,
9190 texture;
9191 struct texture_stage_state state[20];
9194 static const struct texture_stage default_stage_state =
9196 TEXTURE_NONE,
9198 {D3DTSS_COLOROP, D3DTOP_DISABLE},
9199 {D3DTSS_COLORARG1, D3DTA_TEXTURE},
9200 {D3DTSS_COLORARG2, D3DTA_CURRENT},
9201 {D3DTSS_ALPHAOP, D3DTOP_DISABLE},
9202 {D3DTSS_ALPHAARG1, D3DTA_TEXTURE},
9203 {D3DTSS_ALPHAARG2, D3DTA_CURRENT},
9204 {D3DTSS_BUMPENVMAT00, 0},
9205 {D3DTSS_BUMPENVMAT01, 0},
9206 {D3DTSS_BUMPENVMAT10, 0},
9207 {D3DTSS_BUMPENVMAT11, 0},
9208 {D3DTSS_BUMPENVLSCALE, 0},
9209 {D3DTSS_BUMPENVLOFFSET, 0},
9210 {D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE},
9211 {D3DTSS_COLORARG0, D3DTA_CURRENT},
9212 {D3DTSS_ALPHAARG0, D3DTA_CURRENT},
9213 {D3DTSS_RESULTARG, D3DTA_CURRENT},
9214 STATE_END(),
9218 const struct test
9220 DWORD tex_op_caps;
9221 unsigned int expected_color;
9222 struct texture_stage stage[8];
9224 tests[] =
9227 D3DTEXOPCAPS_DISABLE,
9228 0x80ffff02,
9231 TEXTURE_NONE,
9233 STATE_END(),
9239 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1,
9240 0x80ffff02,
9243 TEXTURE_NONE,
9245 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
9246 {D3DTSS_COLORARG1, D3DTA_CURRENT},
9247 STATE_END(),
9250 {TEXTURE_INVALID}
9254 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1,
9255 0x80ffff02,
9258 TEXTURE_NONE,
9260 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
9261 {D3DTSS_COLORARG1, D3DTA_CURRENT},
9262 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
9263 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
9264 STATE_END(),
9270 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1,
9271 0x80ffff02,
9274 TEXTURE_NONE,
9276 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
9277 {D3DTSS_COLORARG1, D3DTA_DIFFUSE},
9278 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
9279 {D3DTSS_ALPHAARG1, D3DTA_DIFFUSE},
9280 STATE_END(),
9286 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1,
9287 0x00000000,
9290 TEXTURE_NONE,
9292 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
9293 {D3DTSS_COLORARG1, D3DTA_TEMP},
9294 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
9295 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
9296 STATE_END(),
9303 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE,
9304 0x80ff0000,
9307 TEXTURE_BUMPMAP,
9309 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
9310 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
9311 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
9312 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
9313 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
9314 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
9315 {D3DTSS_ALPHAARG1, D3DTA_TEXTURE},
9316 STATE_END(),
9321 TEXTURE_RED,
9323 {D3DTSS_COLOROP, D3DTOP_MODULATE},
9324 STATE_END(),
9327 {TEXTURE_INVALID}
9331 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE,
9332 0x80ff0000,
9335 TEXTURE_BUMPMAP,
9337 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
9338 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
9339 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
9340 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
9341 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
9342 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
9343 {D3DTSS_ALPHAARG1, D3DTA_DIFFUSE},
9344 STATE_END(),
9348 TEXTURE_RED,
9350 {D3DTSS_COLOROP, D3DTOP_MODULATE},
9351 STATE_END(),
9354 {TEXTURE_INVALID}
9358 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE,
9359 0x80ff0000,
9362 TEXTURE_BUMPMAP,
9364 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
9365 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
9366 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
9367 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
9368 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
9369 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
9370 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
9371 STATE_END(),
9375 TEXTURE_RED,
9377 {D3DTSS_COLOROP, D3DTOP_MODULATE},
9378 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
9379 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
9380 STATE_END(),
9383 {TEXTURE_INVALID}
9387 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE,
9388 0x00ff0000,
9391 TEXTURE_BUMPMAP,
9393 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
9394 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
9395 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
9396 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
9397 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
9398 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
9399 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
9400 STATE_END(),
9404 TEXTURE_RED,
9406 {D3DTSS_COLOROP, D3DTOP_MODULATE},
9407 {D3DTSS_COLORARG1, D3DTA_TEXTURE},
9408 {D3DTSS_COLORARG2, D3DTA_CURRENT},
9409 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
9410 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
9411 STATE_END(),
9414 {TEXTURE_INVALID}
9418 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE,
9419 0x80ff0000,
9422 TEXTURE_BUMPMAP,
9424 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
9425 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
9426 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
9427 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
9428 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
9429 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
9430 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
9431 STATE_END(),
9435 TEXTURE_RED,
9437 {D3DTSS_COLOROP, D3DTOP_MODULATE},
9438 {D3DTSS_COLORARG1, D3DTA_TEXTURE},
9439 {D3DTSS_COLORARG2, D3DTA_CURRENT},
9440 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
9441 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
9442 STATE_END(),
9445 {TEXTURE_INVALID}
9450 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE
9451 | D3DTEXOPCAPS_ADD,
9452 0x80ff0000,
9455 TEXTURE_BUMPMAP,
9457 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
9458 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
9459 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
9460 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
9461 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
9462 {D3DTSS_ALPHAOP, D3DTOP_ADD},
9463 {D3DTSS_ALPHAARG1, D3DTA_DIFFUSE},
9464 {D3DTSS_ALPHAARG2, D3DTA_CURRENT},
9465 STATE_END(),
9469 TEXTURE_RED,
9471 {D3DTSS_COLOROP, D3DTOP_MODULATE},
9472 {D3DTSS_COLORARG1, D3DTA_TEXTURE},
9473 {D3DTSS_COLORARG2, D3DTA_CURRENT},
9474 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
9475 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
9476 STATE_END(),
9479 {TEXTURE_INVALID}
9483 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE
9484 | D3DTEXOPCAPS_MODULATE2X,
9485 0x80ffff00,
9488 TEXTURE_BUMPMAP,
9490 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
9491 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
9492 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
9493 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
9494 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
9495 {D3DTSS_ALPHAOP, D3DTOP_MODULATE2X},
9496 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
9497 {D3DTSS_ALPHAARG2, D3DTA_DIFFUSE},
9498 STATE_END(),
9502 TEXTURE_RED,
9504 {D3DTSS_COLOROP, D3DTOP_MODULATE},
9505 {D3DTSS_COLORARG1, D3DTA_CURRENT},
9506 {D3DTSS_COLORARG2, D3DTA_CURRENT},
9507 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
9508 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
9509 STATE_END(),
9512 {TEXTURE_INVALID}
9516 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP,
9517 0x80ffff02,
9520 TEXTURE_NONE,
9522 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
9523 {D3DTSS_COLORARG1, D3DTA_DIFFUSE},
9524 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
9525 {D3DTSS_ALPHAARG1, D3DTA_DIFFUSE},
9526 {D3DTSS_RESULTARG, D3DTA_TEMP},
9527 STATE_END(),
9531 TEXTURE_BUMPMAP,
9533 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
9534 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
9535 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
9536 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
9537 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
9538 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
9539 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
9540 {D3DTSS_RESULTARG, D3DTA_TEMP},
9541 STATE_END(),
9545 TEXTURE_RED,
9547 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
9548 {D3DTSS_COLORARG1, D3DTA_TEXTURE},
9549 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
9550 {D3DTSS_ALPHAARG1, D3DTA_TEXTURE},
9551 STATE_END(),
9555 TEXTURE_NONE,
9557 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
9558 {D3DTSS_COLORARG1, D3DTA_TEMP},
9559 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
9560 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
9561 STATE_END(),
9564 {TEXTURE_INVALID}
9569 window = create_window();
9570 d3d = Direct3DCreate8(D3D_SDK_VERSION);
9571 ok(!!d3d, "Failed to create a D3D object.\n");
9572 if (!(device = create_device(d3d, window, window, TRUE)))
9574 skip("Failed to create a D3D device.\n");
9575 goto done;
9578 memset(&caps, 0, sizeof(caps));
9579 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
9580 ok(hr == D3D_OK, "IDirect3DDevice8_GetDeviceCaps failed hr %#lx.\n", hr);
9582 if(!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP))
9584 skip("D3DPMISCCAPS_TSSARGTEMP not supported.\n");
9585 IDirect3DDevice8_Release(device);
9586 goto done;
9589 if (FAILED(IDirect3D8_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
9590 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_V8U8)))
9592 skip("D3DFMT_V8U8 not supported for legacy bump mapping.\n");
9593 IDirect3DDevice8_Release(device);
9594 goto done;
9597 hr = IDirect3DDevice8_GetBackBuffer(device, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9598 ok(hr == D3D_OK, "Can't get back buffer, hr %#lx.\n", hr);
9600 hr = IDirect3DDevice8_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture_bumpmap);
9601 ok(hr == D3D_OK, "IDirect3DDevice8_CreateTexture failed, hr %#lx.\n", hr);
9602 hr = IDirect3DDevice8_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture_red);
9603 ok(hr == D3D_OK, "IDirect3DDevice8_CreateTexture failed, hr %#lx.\n", hr);
9605 memset(&locked_rect, 0, sizeof(locked_rect));
9606 hr = IDirect3DTexture8_LockRect(texture_bumpmap, 0, &locked_rect, NULL, 0);
9607 ok(SUCCEEDED(hr), "LockRect failed, hr %#lx.\n", hr);
9608 *((WORD *)locked_rect.pBits) = 0xff00;
9609 hr = IDirect3DTexture8_UnlockRect(texture_bumpmap, 0);
9610 ok(SUCCEEDED(hr), "UnlockRect failed, hr %#lx.\n", hr);
9612 memset(&locked_rect, 0, sizeof(locked_rect));
9613 hr = IDirect3DTexture8_LockRect(texture_red, 0, &locked_rect, NULL, 0);
9614 ok(SUCCEEDED(hr), "LockRect failed, hr %#lx.\n", hr);
9615 *((DWORD *)locked_rect.pBits) = 0x00ff0000;
9616 hr = IDirect3DTexture8_UnlockRect(texture_red, 0);
9617 ok(SUCCEEDED(hr), "UnlockRect failed, hr %#lx.\n", hr);
9619 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9620 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr);
9621 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9622 ok(hr == D3D_OK, "Failed to disable lighting, hr %#lx.\n", hr);
9624 for (i = 0; i < ARRAY_SIZE(tests); ++i)
9626 const struct test *current_test = &tests[i];
9628 if ((caps.TextureOpCaps & current_test->tex_op_caps) != current_test->tex_op_caps)
9630 skip("Texture operations %#lx not supported.\n", current_test->tex_op_caps);
9631 continue;
9634 for (j = 0; j < caps.MaxTextureBlendStages; ++j)
9636 IDirect3DTexture8 *current_texture = NULL;
9638 for (k = 0; !IS_STATE_END(default_stage_state.state[k]); ++k)
9640 hr = IDirect3DDevice8_SetTextureStageState(device, j,
9641 default_stage_state.state[k].name, default_stage_state.state[k].value);
9642 ok(SUCCEEDED(hr), "Test %u: SetTextureStageState failed, hr %#lx.\n", i, hr);
9645 if (current_test->stage[j].texture != TEXTURE_INVALID)
9647 const struct texture_stage_state *current_state = current_test->stage[j].state;
9649 switch (current_test->stage[j].texture)
9651 case TEXTURE_RED:
9652 current_texture = texture_red;
9653 break;
9654 case TEXTURE_BUMPMAP:
9655 current_texture = texture_bumpmap;
9656 break;
9657 default:
9658 current_texture = NULL;
9659 break;
9662 for (k = 0; !IS_STATE_END(current_state[k]); ++k)
9664 hr = IDirect3DDevice8_SetTextureStageState(device, j,
9665 current_state[k].name, current_state[k].value);
9666 ok(SUCCEEDED(hr), "Test %u: SetTextureStageState failed, hr %#lx.\n", i, hr);
9670 hr = IDirect3DDevice8_SetTexture(device, j, (IDirect3DBaseTexture8 *)current_texture);
9671 ok(SUCCEEDED(hr), "Test %u: SetTexture failed, hr %#lx.\n", i, hr);
9674 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
9675 ok(hr == D3D_OK, "Test %u: IDirect3DDevice8_Clear failed, hr %#lx.\n", i, hr);
9677 hr = IDirect3DDevice8_BeginScene(device);
9678 ok(SUCCEEDED(hr), "Test %u: BeginScene failed, hr %#lx.\n", i, hr);
9679 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
9680 ok(SUCCEEDED(hr), "Test %u: DrawPrimitiveUP failed, hr %#lx.\n", i, hr);
9681 hr = IDirect3DDevice8_EndScene(device);
9682 ok(SUCCEEDED(hr), "Test %u: EndScene failed, hr %#lx.\n", i, hr);
9684 get_surface_readback(backbuffer, &rb);
9685 color = get_readback_color(&rb, 320, 240);
9686 ok(color_match(color, current_test->expected_color, 1),
9687 "Test %u: Got color 0x%08x, expected 0x%08x.\n", i, color, current_test->expected_color);
9688 release_surface_readback(&rb);
9689 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
9690 ok(SUCCEEDED(hr), "Test %u: Present failed, hr %#lx.\n", i, hr);
9693 IDirect3DTexture8_Release(texture_bumpmap);
9694 IDirect3DTexture8_Release(texture_red);
9695 IDirect3DSurface8_Release(backbuffer);
9696 refcount = IDirect3DDevice8_Release(device);
9697 ok(!refcount, "Device has %lu references left.\n", refcount);
9698 done:
9699 IDirect3D8_Release(d3d);
9700 DestroyWindow(window);
9703 static void test_color_clamping(void)
9705 static const D3DMATRIX mat =
9707 1.0f, 0.0f, 0.0f, 0.0f,
9708 0.0f, 1.0f, 0.0f, 0.0f,
9709 0.0f, 0.0f, 1.0f, 0.0f,
9710 0.0f, 0.0f, 0.0f, 1.0f,
9711 }}};
9712 static const struct vec3 quad[] =
9714 {-1.0f, -1.0f, 0.1f},
9715 {-1.0f, 1.0f, 0.1f},
9716 { 1.0f, -1.0f, 0.1f},
9717 { 1.0f, 1.0f, 0.1f},
9719 static const DWORD decl[] =
9721 D3DVSD_STREAM(0),
9722 D3DVSD_REG(D3DVSDE_POSITION, D3DVSDT_FLOAT3),
9723 D3DVSD_CONST(0, 1), 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c0, 1.0, 1.0, 1.0, 1.0 */
9724 D3DVSD_END()
9726 static const DWORD vs1_code[] =
9728 0xfffe0101, /* vs_1_1 */
9729 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
9730 0x00000002, 0xd00f0000, 0xa0e40000, 0xa0e40000, /* add oD0, c0, c0 */
9731 0x00000002, 0xd00f0001, 0xa0e40000, 0xa0e40000, /* add oD1, c0, c0 */
9732 0x0000ffff
9734 static const DWORD ps1_code[] =
9736 0xffff0101, /* ps_1_1 */
9737 0x00000051, 0xa00f0000, 0x3e800000, 0x3e800000, 0x3e800000, 0x3e800000, /* def c0, 0.25, 0.25, 0.25, 0.25 */
9738 0x00000002, 0x800f0000, 0x90e40000, 0x90e40001, /* add r0, v0, v1 */
9739 0x00000005, 0x800f0000, 0x80e40000, 0xa0e40000, /* mul r0, r0, c0 */
9740 0x0000ffff
9742 static const struct
9744 DWORD vs_version;
9745 const DWORD *vs;
9746 DWORD ps_version;
9747 const DWORD *ps;
9748 D3DCOLOR expected, broken;
9750 tests[] =
9752 {0, NULL, 0, NULL, 0x00404040},
9753 {0, NULL, D3DPS_VERSION(1, 1), ps1_code, 0x00404040, 0x00808080},
9754 {D3DVS_VERSION(1, 1), vs1_code, 0, NULL, 0x00404040},
9755 {D3DVS_VERSION(1, 1), vs1_code, D3DPS_VERSION(1, 1), ps1_code, 0x007f7f7f},
9757 IDirect3DDevice8 *device;
9758 unsigned int color, i;
9759 IDirect3D8 *d3d;
9760 ULONG refcount;
9761 D3DCAPS8 caps;
9762 DWORD vs, ps;
9763 HWND window;
9764 HRESULT hr;
9766 window = create_window();
9767 d3d = Direct3DCreate8(D3D_SDK_VERSION);
9768 ok(!!d3d, "Failed to create a D3D object.\n");
9769 if (!(device = create_device(d3d, window, window, TRUE)))
9771 skip("Failed to create a D3D device, skipping tests.\n");
9772 IDirect3D8_Release(d3d);
9773 DestroyWindow(window);
9774 return;
9777 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
9778 ok(SUCCEEDED(hr), "Failed to get caps, hr %#lx.\n", hr);
9780 hr = IDirect3DDevice8_SetTransform(device, D3DTS_WORLD, &mat);
9781 ok(SUCCEEDED(hr), "Failed to set world transform, hr %#lx.\n", hr);
9782 hr = IDirect3DDevice8_SetTransform(device, D3DTS_VIEW, &mat);
9783 ok(SUCCEEDED(hr), "Failed to set view transform, hr %#lx.\n", hr);
9784 hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, &mat);
9785 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#lx.\n", hr);
9786 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, FALSE);
9787 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#lx.\n", hr);
9788 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, FALSE);
9789 ok(SUCCEEDED(hr), "Failed to disable Z test, hr %#lx.\n", hr);
9790 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
9791 ok(SUCCEEDED(hr), "Failed to disable fog, hr %#lx.\n", hr);
9792 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
9793 ok(SUCCEEDED(hr), "Failed to disable stencil test, hr %#lx.\n", hr);
9794 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
9795 ok(SUCCEEDED(hr), "Failed to disable culling, hr %#lx.\n", hr);
9796 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9797 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#lx.\n", hr);
9799 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xff404040);
9800 ok(SUCCEEDED(hr), "Failed to set texture factor, hr %#lx.\n", hr);
9801 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
9802 ok(SUCCEEDED(hr), "Failed to set color op, hr %#lx.\n", hr);
9803 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9804 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#lx.\n", hr);
9805 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_SPECULAR);
9806 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#lx.\n", hr);
9807 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_MODULATE);
9808 ok(SUCCEEDED(hr), "Failed to set color op, hr %#lx.\n", hr);
9809 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TFACTOR);
9810 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#lx.\n", hr);
9811 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
9812 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#lx.\n", hr);
9814 for (i = 0; i < ARRAY_SIZE(tests); ++i)
9816 if (caps.VertexShaderVersion < tests[i].vs_version
9817 || caps.PixelShaderVersion < tests[i].ps_version)
9819 skip("Vertex / pixel shader version not supported, skipping test %u.\n", i);
9820 continue;
9822 if (tests[i].vs)
9824 hr = IDirect3DDevice8_CreateVertexShader(device, decl, tests[i].vs, &vs, 0);
9825 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#lx (case %u).\n", hr, i);
9827 else
9829 vs = D3DFVF_XYZ;
9831 if (tests[i].ps)
9833 hr = IDirect3DDevice8_CreatePixelShader(device, tests[i].ps, &ps);
9834 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#lx (case %u).\n", hr, i);
9836 else
9838 ps = 0;
9841 hr = IDirect3DDevice8_SetVertexShader(device, vs);
9842 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#lx.\n", hr);
9843 hr = IDirect3DDevice8_SetPixelShader(device, ps);
9844 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#lx.\n", hr);
9846 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0f, 0);
9847 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
9849 hr = IDirect3DDevice8_BeginScene(device);
9850 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
9852 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
9853 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
9855 hr = IDirect3DDevice8_EndScene(device);
9856 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
9858 color = getPixelColor(device, 320, 240);
9859 ok(color_match(color, tests[i].expected, 1) || broken(color_match(color, tests[i].broken, 1)),
9860 "Got unexpected color 0x%08x, case %u.\n", color, i);
9862 if (vs != D3DFVF_XYZ)
9863 IDirect3DDevice8_DeleteVertexShader(device, vs);
9864 if (ps)
9865 IDirect3DDevice8_DeletePixelShader(device, ps);
9868 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
9869 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
9871 refcount = IDirect3DDevice8_Release(device);
9872 ok(!refcount, "Device has %lu references left.\n", refcount);
9873 IDirect3D8_Release(d3d);
9874 DestroyWindow(window);
9877 static void test_edge_antialiasing_blending(void)
9879 IDirect3DDevice8 *device;
9880 unsigned int color;
9881 IDirect3D8 *d3d8;
9882 ULONG refcount;
9883 D3DCAPS8 caps;
9884 HWND window;
9885 HRESULT hr;
9887 static const struct
9889 struct vec3 position;
9890 DWORD diffuse;
9892 green_quad[] =
9894 {{-1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0x7f, 0x00, 0xff, 0x00)},
9895 {{-1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0x7f, 0x00, 0xff, 0x00)},
9896 {{ 1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0x7f, 0x00, 0xff, 0x00)},
9897 {{ 1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0x7f, 0x00, 0xff, 0x00)},
9899 static const struct
9901 struct vec3 position;
9902 DWORD diffuse;
9904 red_quad[] =
9906 {{-1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0xcc, 0xff, 0x00, 0x00)},
9907 {{-1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0xcc, 0xff, 0x00, 0x00)},
9908 {{ 1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0xcc, 0xff, 0x00, 0x00)},
9909 {{ 1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0xcc, 0xff, 0x00, 0x00)},
9912 window = create_window();
9913 d3d8 = Direct3DCreate8(D3D_SDK_VERSION);
9914 ok(!!d3d8, "Failed to create a D3D object.\n");
9915 if (!(device = create_device(d3d8, window, window, TRUE)))
9917 skip("Failed to create a D3D device.\n");
9918 IDirect3D8_Release(d3d8);
9919 DestroyWindow(window);
9920 return;
9923 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
9924 ok(SUCCEEDED(hr), "Failed to get caps, hr %#lx.\n", hr);
9925 trace("Edge antialiasing support: %#lx.\n", caps.RasterCaps & D3DPRASTERCAPS_ANTIALIASEDGES);
9927 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, FALSE);
9928 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#lx.\n", hr);
9929 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, FALSE);
9930 ok(SUCCEEDED(hr), "Failed to disable Z test, hr %#lx.\n", hr);
9931 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9932 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#lx.\n", hr);
9934 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
9935 ok(SUCCEEDED(hr), "Failed to enable blending, hr %#lx.\n", hr);
9936 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_BLENDOP, D3DBLENDOP_ADD);
9937 ok(SUCCEEDED(hr), "Failed to set blend op, hr %#lx.\n", hr);
9938 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
9939 ok(SUCCEEDED(hr), "Failed to set src blend, hr %#lx.\n", hr);
9940 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_DESTALPHA);
9941 ok(SUCCEEDED(hr), "Failed to set dest blend, hr %#lx.\n", hr);
9943 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9944 ok(SUCCEEDED(hr), "Failed to set color op, hr %#lx.\n", hr);
9945 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9946 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#lx.\n", hr);
9947 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
9948 ok(SUCCEEDED(hr), "Failed to set alpha op, hr %#lx.\n", hr);
9949 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
9950 ok(SUCCEEDED(hr), "Failed to set alpha arg, hr %#lx.\n", hr);
9952 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9953 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr);
9955 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xccff0000, 0.0f, 0);
9956 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
9957 hr = IDirect3DDevice8_BeginScene(device);
9958 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
9959 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, green_quad, sizeof(*green_quad));
9960 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
9961 hr = IDirect3DDevice8_EndScene(device);
9962 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
9963 color = getPixelColor(device, 320, 240);
9964 ok(color_match(color, 0x00cc7f00, 1), "Got unexpected color 0x%08x.\n", color);
9966 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x7f00ff00, 0.0f, 0);
9967 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
9968 hr = IDirect3DDevice8_BeginScene(device);
9969 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
9970 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, red_quad, sizeof(*red_quad));
9971 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
9972 hr = IDirect3DDevice8_EndScene(device);
9973 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
9974 color = getPixelColor(device, 320, 240);
9975 ok(color_match(color, 0x00cc7f00, 1), "Got unexpected color 0x%08x.\n", color);
9977 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
9978 ok(SUCCEEDED(hr), "Failed to disable blending, hr %#lx.\n", hr);
9980 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xccff0000, 0.0f, 0);
9981 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
9982 hr = IDirect3DDevice8_BeginScene(device);
9983 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
9984 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, green_quad, sizeof(*green_quad));
9985 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
9986 hr = IDirect3DDevice8_EndScene(device);
9987 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
9988 color = getPixelColor(device, 320, 240);
9989 ok(color_match(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
9991 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x7f00ff00, 0.0f, 0);
9992 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
9993 hr = IDirect3DDevice8_BeginScene(device);
9994 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
9995 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, red_quad, sizeof(*red_quad));
9996 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
9997 hr = IDirect3DDevice8_EndScene(device);
9998 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
9999 color = getPixelColor(device, 320, 240);
10000 ok(color_match(color, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color);
10002 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_EDGEANTIALIAS, TRUE);
10003 ok(SUCCEEDED(hr), "Failed to enable edge antialiasing, hr %#lx.\n", hr);
10005 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xccff0000, 0.0f, 0);
10006 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
10007 hr = IDirect3DDevice8_BeginScene(device);
10008 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
10009 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, green_quad, sizeof(*green_quad));
10010 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
10011 hr = IDirect3DDevice8_EndScene(device);
10012 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
10013 color = getPixelColor(device, 320, 240);
10014 ok(color_match(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
10016 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x7f00ff00, 0.0f, 0);
10017 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
10018 hr = IDirect3DDevice8_BeginScene(device);
10019 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
10020 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, red_quad, sizeof(*red_quad));
10021 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
10022 hr = IDirect3DDevice8_EndScene(device);
10023 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
10024 color = getPixelColor(device, 320, 240);
10025 ok(color_match(color, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color);
10027 refcount = IDirect3DDevice8_Release(device);
10028 ok(!refcount, "Device has %lu references left.\n", refcount);
10029 IDirect3D8_Release(d3d8);
10030 DestroyWindow(window);
10033 /* This test shows that 0xffff is valid index in D3D8. */
10034 static void test_max_index16(void)
10036 static const struct vertex
10038 struct vec3 position;
10039 DWORD diffuse;
10041 green_quad[] =
10043 {{-1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
10044 {{-1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
10045 {{ 1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
10046 {{ 1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
10048 static const unsigned short indices[] = {0, 1, 2, 0xffff};
10049 static const unsigned int vertex_count = 0xffff + 1;
10051 D3DADAPTER_IDENTIFIER8 identifier;
10052 IDirect3DVertexBuffer8 *vb;
10053 IDirect3DIndexBuffer8 *ib;
10054 IDirect3DDevice8 *device;
10055 struct vertex *vb_data;
10056 unsigned int color;
10057 IDirect3D8 *d3d8;
10058 ULONG refcount;
10059 D3DCAPS8 caps;
10060 HWND window;
10061 BYTE *data;
10062 HRESULT hr;
10063 BOOL warp;
10065 window = create_window();
10066 d3d8 = Direct3DCreate8(D3D_SDK_VERSION);
10067 ok(!!d3d8, "Failed to create a D3D object.\n");
10069 hr = IDirect3D8_GetAdapterIdentifier(d3d8, D3DADAPTER_DEFAULT, 0, &identifier);
10070 ok(SUCCEEDED(hr), "Failed to get adapter identifier, hr %#lx.\n", hr);
10071 warp = adapter_is_warp(&identifier);
10073 if (!(device = create_device(d3d8, window, window, TRUE)))
10075 skip("Failed to create a D3D device.\n");
10076 IDirect3D8_Release(d3d8);
10077 DestroyWindow(window);
10078 return;
10081 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
10082 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
10083 if (caps.MaxVertexIndex < 0xffff)
10085 skip("Max vertex index is lower than 0xffff (%#lx).\n", caps.MaxVertexIndex);
10086 IDirect3DDevice8_Release(device);
10087 IDirect3D8_Release(d3d8);
10088 DestroyWindow(window);
10089 return;
10092 hr = IDirect3DDevice8_CreateVertexBuffer(device, vertex_count * sizeof(*green_quad), 0,
10093 D3DFVF_XYZ | D3DFVF_DIFFUSE, D3DPOOL_MANAGED, &vb);
10094 ok(SUCCEEDED(hr), "Failed to create vertex buffer, hr %#lx.\n", hr);
10096 hr = IDirect3DDevice8_CreateIndexBuffer(device, sizeof(indices), 0,
10097 D3DFMT_INDEX16, D3DPOOL_MANAGED, &ib);
10098 ok(SUCCEEDED(hr), "Failed to create index buffer, hr %#lx.\n", hr);
10100 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, FALSE);
10101 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#lx.\n", hr);
10102 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, FALSE);
10103 ok(SUCCEEDED(hr), "Failed to disable Z test, hr %#lx.\n", hr);
10104 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10105 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#lx.\n", hr);
10107 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10108 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr);
10110 hr = IDirect3DVertexBuffer8_Lock(vb, 0, sizeof(green_quad), (BYTE **)&vb_data, 0);
10111 ok(hr == D3D_OK, "Failed to lock vertex buffer, hr %#lx.\n", hr);
10112 vb_data[0] = green_quad[0];
10113 vb_data[1] = green_quad[1];
10114 vb_data[2] = green_quad[2];
10115 vb_data[0xffff] = green_quad[3];
10116 hr = IDirect3DVertexBuffer8_Unlock(vb);
10117 ok(hr == D3D_OK, "Failed to unlock vertex buffer, hr %#lx.\n", hr);
10119 hr = IDirect3DIndexBuffer8_Lock(ib, 0, sizeof(indices), &data, 0);
10120 ok(hr == D3D_OK, "Failed to lock index buffer, hr %#lx.\n", hr);
10121 memcpy(data, indices, sizeof(indices));
10122 hr = IDirect3DIndexBuffer8_Unlock(ib);
10123 ok(hr == D3D_OK, "Failed to unlock index buffer, hr %#lx.\n", hr);
10125 hr = IDirect3DDevice8_SetIndices(device, ib, 0);
10126 ok(hr == D3D_OK, "Failed to set index buffer, hr %#lx.\n", hr);
10127 hr = IDirect3DDevice8_SetStreamSource(device, 0, vb, sizeof(struct vertex));
10128 ok(hr == D3D_OK, "Failed to set stream source, hr %#lx.\n", hr);
10130 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
10131 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
10132 hr = IDirect3DDevice8_BeginScene(device);
10133 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
10134 hr = IDirect3DDevice8_DrawIndexedPrimitive(device, D3DPT_TRIANGLESTRIP, 0, vertex_count, 0, 2);
10135 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
10136 hr = IDirect3DDevice8_EndScene(device);
10137 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
10138 color = getPixelColor(device, 20, 20);
10139 ok(color_match(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
10140 color = getPixelColor(device, 320, 240);
10141 ok(color_match(color, 0x0000ff00, 1) || broken(warp), "Got unexpected color 0x%08x.\n", color);
10142 color = getPixelColor(device, 620, 460);
10143 ok(color_match(color, 0x0000ff00, 1) || broken(warp), "Got unexpected color 0x%08x.\n", color);
10145 IDirect3DIndexBuffer8_Release(ib);
10146 IDirect3DVertexBuffer8_Release(vb);
10147 refcount = IDirect3DDevice8_Release(device);
10148 ok(!refcount, "Device has %lu references left.\n", refcount);
10149 IDirect3D8_Release(d3d8);
10150 DestroyWindow(window);
10153 static void test_backbuffer_resize(void)
10155 D3DPRESENT_PARAMETERS present_parameters = {0};
10156 IDirect3DSurface8 *backbuffer;
10157 IDirect3DDevice8 *device;
10158 unsigned int color;
10159 IDirect3D8 *d3d;
10160 ULONG refcount;
10161 HWND window;
10162 HRESULT hr;
10164 static const struct
10166 struct vec3 position;
10167 DWORD diffuse;
10169 quad[] =
10171 {{-1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
10172 {{-1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
10173 {{ 1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
10174 {{ 1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
10177 window = create_window();
10178 d3d = Direct3DCreate8(D3D_SDK_VERSION);
10179 ok(!!d3d, "Failed to create a D3D object.\n");
10180 if (!(device = create_device(d3d, window, window, TRUE)))
10182 skip("Failed to create a D3D device.\n");
10183 goto done;
10186 /* Wine d3d8 implementation had a bug which was triggered by a
10187 * SetRenderTarget() call with an unreferenced surface. */
10188 hr = IDirect3DDevice8_GetBackBuffer(device, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
10189 ok(SUCCEEDED(hr), "Failed to get backbuffer, hr %#lx.\n", hr);
10190 refcount = IDirect3DSurface8_Release(backbuffer);
10191 ok(!refcount, "Surface has %lu references left.\n", refcount);
10192 hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, NULL);
10193 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
10194 hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, NULL);
10195 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
10197 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 1.0f, 0);
10198 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
10199 color = getPixelColor(device, 1, 1);
10200 ok(color == 0x00ff0000, "Got unexpected color 0x%08x.\n", color);
10202 present_parameters.BackBufferWidth = 800;
10203 present_parameters.BackBufferHeight = 600;
10204 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
10205 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
10206 present_parameters.hDeviceWindow = NULL;
10207 present_parameters.Windowed = TRUE;
10208 present_parameters.EnableAutoDepthStencil = TRUE;
10209 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
10210 hr = IDirect3DDevice8_Reset(device, &present_parameters);
10211 ok(SUCCEEDED(hr), "Failed to reset, hr %#lx.\n", hr);
10213 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, FALSE);
10214 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#lx.\n", hr);
10215 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, FALSE);
10216 ok(SUCCEEDED(hr), "Failed to disable Z test, hr %#lx.\n", hr);
10217 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10218 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#lx.\n", hr);
10219 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10220 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr);
10222 hr = IDirect3DDevice8_GetBackBuffer(device, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
10223 ok(SUCCEEDED(hr), "Failed to get backbuffer, hr %#lx.\n", hr);
10224 hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, NULL);
10225 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx.\n", hr);
10226 IDirect3DSurface8_Release(backbuffer);
10228 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 1.0f, 0);
10229 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
10230 color = getPixelColor(device, 1, 1);
10231 ok(color == 0x00ffff00, "Got unexpected color 0x%08x.\n", color);
10232 color = getPixelColor(device, 700, 500);
10233 ok(color == 0x00ffff00, "Got unexpected color 0x%08x.\n", color);
10235 hr = IDirect3DDevice8_BeginScene(device);
10236 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
10237 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10238 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
10239 hr = IDirect3DDevice8_EndScene(device);
10240 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
10241 color = getPixelColor(device, 1, 1);
10242 ok(color == 0x0000ff00, "Got unexpected color 0x%08x.\n", color);
10243 color = getPixelColor(device, 700, 500);
10244 ok(color == 0x0000ff00, "Got unexpected color 0x%08x.\n", color);
10246 refcount = IDirect3DDevice8_Release(device);
10247 ok(!refcount, "Device has %lu references left.\n", refcount);
10248 done:
10249 IDirect3D8_Release(d3d);
10250 DestroyWindow(window);
10253 static void test_drawindexedprimitiveup(void)
10255 static const struct vertex
10257 struct vec3 position;
10258 DWORD diffuse;
10260 quad[] =
10262 {{-1.0f, -1.0f, 0.1f}, 0xff00ff00},
10263 {{-1.0f, 1.0f, 0.1f}, 0xff0000ff},
10264 {{ 1.0f, -1.0f, 0.1f}, 0xffff0000},
10265 {{ 1.0f, 1.0f, 0.1f}, 0xff0000ff},
10267 {{-1.0f, -1.0f, 0.1f}, 0xff0000ff},
10268 {{-1.0f, 1.0f, 0.1f}, 0xff00ff00},
10269 {{ 1.0f, -1.0f, 0.1f}, 0xffff0000},
10270 {{ 1.0f, 1.0f, 0.1f}, 0xff00ff00},
10272 static const unsigned short indices[] = {0, 1, 2, 3, 4, 5, 6, 7};
10273 IDirect3DDevice8 *device;
10274 unsigned int color;
10275 IDirect3D8 *d3d;
10276 ULONG refcount;
10277 HWND window;
10278 HRESULT hr;
10280 window = create_window();
10281 d3d = Direct3DCreate8(D3D_SDK_VERSION);
10282 ok(!!d3d, "Failed to create a D3D object.\n");
10284 if (!(device = create_device(d3d, window, window, TRUE)))
10286 skip("Failed to create a D3D device.\n");
10287 IDirect3D8_Release(d3d);
10288 DestroyWindow(window);
10289 return;
10292 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, FALSE);
10293 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#lx.\n", hr);
10294 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, FALSE);
10295 ok(SUCCEEDED(hr), "Failed to disable Z test, hr %#lx.\n", hr);
10296 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10297 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#lx.\n", hr);
10299 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
10300 ok(SUCCEEDED(hr), "Failed to set color op, hr %#lx.\n", hr);
10301 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
10302 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#lx.\n", hr);
10303 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
10304 ok(SUCCEEDED(hr), "Failed to set alpha op, hr %#lx.\n", hr);
10305 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
10306 ok(SUCCEEDED(hr), "Failed to set alpha arg, hr %#lx.\n", hr);
10308 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10309 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr);
10311 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
10312 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
10314 hr = IDirect3DDevice8_BeginScene(device);
10315 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
10316 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 4, 4, 2, indices + 4, D3DFMT_INDEX16, quad, sizeof(*quad));
10317 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
10318 hr = IDirect3DDevice8_EndScene(device);
10319 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
10321 color = getPixelColor(device, 160, 120);
10322 ok(color_match(color, 0x0040bf00, 1), "Got unexpected color 0x%08x.\n", color);
10323 color = getPixelColor(device, 480, 120);
10324 ok(color_match(color, 0x0040bf00, 1), "Got unexpected color 0x%08x.\n", color);
10325 color = getPixelColor(device, 160, 360);
10326 ok(color_match(color, 0x00404080, 1), "Got unexpected color 0x%08x.\n", color);
10327 color = getPixelColor(device, 480, 360);
10328 ok(color_match(color, 0x00bf4000, 1), "Got unexpected color 0x%08x.\n", color);
10330 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
10331 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
10333 hr = IDirect3DDevice8_BeginScene(device);
10334 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
10335 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 0, 4, 2, indices, D3DFMT_INDEX16, quad, sizeof(*quad));
10336 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
10337 hr = IDirect3DDevice8_EndScene(device);
10338 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
10340 color = getPixelColor(device, 160, 120);
10341 ok(color_match(color, 0x004000bf, 1), "Got unexpected color 0x%08x.\n", color);
10342 color = getPixelColor(device, 480, 120);
10343 ok(color_match(color, 0x004000bf, 1), "Got unexpected color 0x%08x.\n", color);
10344 color = getPixelColor(device, 160, 360);
10345 ok(color_match(color, 0x00408040, 1), "Got unexpected color 0x%08x.\n", color);
10346 color = getPixelColor(device, 480, 360);
10347 ok(color_match(color, 0x00bf0040, 1), "Got unexpected color 0x%08x.\n", color);
10349 refcount = IDirect3DDevice8_Release(device);
10350 ok(!refcount, "Device has %lu references left.\n", refcount);
10351 IDirect3D8_Release(d3d);
10352 DestroyWindow(window);
10355 static void test_map_synchronisation(void)
10357 unsigned int colour, i, j, tri_count, size;
10358 LARGE_INTEGER frequency, diff, ts[3];
10359 D3DADAPTER_IDENTIFIER8 identifier;
10360 IDirect3DVertexBuffer8 *buffer;
10361 IDirect3DDevice8 *device;
10362 BOOL unsynchronised, ret;
10363 IDirect3D8 *d3d;
10364 ULONG refcount;
10365 D3DCAPS8 caps;
10366 HWND window;
10367 HRESULT hr;
10369 static const struct
10371 unsigned int flags;
10372 BOOL unsynchronised;
10374 tests[] =
10376 {0, FALSE},
10377 {D3DLOCK_NOOVERWRITE, TRUE},
10378 {D3DLOCK_DISCARD, FALSE},
10379 {D3DLOCK_NOOVERWRITE | D3DLOCK_DISCARD, TRUE},
10382 static const struct quad
10384 struct
10386 struct vec3 position;
10387 DWORD diffuse;
10388 } strip[4];
10390 quad1 =
10393 {{-1.0f, -1.0f, 0.0f}, 0xffff0000},
10394 {{-1.0f, 1.0f, 0.0f}, 0xff00ff00},
10395 {{ 1.0f, -1.0f, 0.0f}, 0xff0000ff},
10396 {{ 1.0f, 1.0f, 0.0f}, 0xffffffff},
10399 quad2 =
10402 {{-1.0f, -1.0f, 0.0f}, 0xffffff00},
10403 {{-1.0f, 1.0f, 0.0f}, 0xffffff00},
10404 {{ 1.0f, -1.0f, 0.0f}, 0xffffff00},
10405 {{ 1.0f, 1.0f, 0.0f}, 0xffffff00},
10408 struct quad *quads;
10410 window = create_window();
10411 ok(!!window, "Failed to create a window.\n");
10413 d3d = Direct3DCreate8(D3D_SDK_VERSION);
10414 ok(!!d3d, "Failed to create a D3D object.\n");
10415 if (!(device = create_device(d3d, window, window, TRUE)))
10417 skip("Failed to create a D3D device, skipping tests.\n");
10418 IDirect3D8_Release(d3d);
10419 DestroyWindow(window);
10420 return;
10423 hr = IDirect3D8_GetAdapterIdentifier(d3d, D3DADAPTER_DEFAULT, 0, &identifier);
10424 ok(SUCCEEDED(hr), "Failed to get adapter identifier, hr %#lx.\n", hr);
10425 /* Maps are always synchronised on WARP. */
10426 if (adapter_is_warp(&identifier))
10428 skip("Running on WARP, skipping test.\n");
10429 goto done;
10432 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
10433 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#lx.\n", hr);
10435 tri_count = 0x1000;
10436 if (tri_count > caps.MaxPrimitiveCount)
10438 skip("Device supports only %lu primitives, skipping test.\n", caps.MaxPrimitiveCount);
10439 goto done;
10441 size = (tri_count + 2) * sizeof(*quad1.strip);
10443 ret = QueryPerformanceFrequency(&frequency);
10444 ok(ret, "Failed to get performance counter frequency.\n");
10446 hr = IDirect3DDevice8_CreateVertexBuffer(device, size,
10447 D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, 0, D3DPOOL_DEFAULT, &buffer);
10448 ok(SUCCEEDED(hr), "Failed to create vertex buffer, hr %#lx.\n", hr);
10449 hr = IDirect3DVertexBuffer8_Lock(buffer, 0, size, (BYTE **)&quads, D3DLOCK_DISCARD);
10450 ok(SUCCEEDED(hr), "Failed to lock vertex buffer, hr %#lx.\n", hr);
10451 for (j = 0; j < size / sizeof(*quads); ++j)
10453 quads[j] = quad1;
10455 hr = IDirect3DVertexBuffer8_Unlock(buffer);
10456 ok(SUCCEEDED(hr), "Failed to unlock vertex buffer, hr %#lx.\n", hr);
10458 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10459 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
10460 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10461 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr);
10462 hr = IDirect3DDevice8_SetStreamSource(device, 0, buffer, sizeof(*quads->strip));
10463 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#lx.\n", hr);
10465 /* Initial draw to initialise states, compile shaders, etc. */
10466 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0f, 0);
10467 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
10468 hr = IDirect3DDevice8_BeginScene(device);
10469 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
10470 hr = IDirect3DDevice8_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, tri_count);
10471 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
10472 hr = IDirect3DDevice8_EndScene(device);
10473 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
10474 /* Read the result to ensure the GPU has finished drawing. */
10475 colour = getPixelColor(device, 320, 240);
10477 /* Time drawing tri_count triangles. */
10478 ret = QueryPerformanceCounter(&ts[0]);
10479 ok(ret, "Failed to read performance counter.\n");
10480 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0f, 0);
10481 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
10482 hr = IDirect3DDevice8_BeginScene(device);
10483 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
10484 hr = IDirect3DDevice8_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, tri_count);
10485 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
10486 hr = IDirect3DDevice8_EndScene(device);
10487 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
10488 colour = getPixelColor(device, 320, 240);
10489 /* Time drawing a single triangle. */
10490 ret = QueryPerformanceCounter(&ts[1]);
10491 ok(ret, "Failed to read performance counter.\n");
10492 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0f, 0);
10493 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
10494 hr = IDirect3DDevice8_BeginScene(device);
10495 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
10496 hr = IDirect3DDevice8_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 1);
10497 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
10498 hr = IDirect3DDevice8_EndScene(device);
10499 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
10500 colour = getPixelColor(device, 320, 240);
10501 ret = QueryPerformanceCounter(&ts[2]);
10502 ok(ret, "Failed to read performance counter.\n");
10504 IDirect3DVertexBuffer8_Release(buffer);
10506 /* Estimate the number of triangles we can draw in 100ms. */
10507 diff.QuadPart = ts[1].QuadPart - ts[0].QuadPart + ts[1].QuadPart - ts[2].QuadPart;
10508 tri_count = (tri_count * frequency.QuadPart) / (diff.QuadPart * 10);
10509 tri_count = ((tri_count + 2 + 3) & ~3) - 2;
10510 if (tri_count > caps.MaxPrimitiveCount)
10512 skip("Would need to draw %u triangles, but the device only supports %lu primitives.\n",
10513 tri_count, caps.MaxPrimitiveCount);
10514 goto done;
10516 size = (tri_count + 2) * sizeof(*quad1.strip);
10518 for (i = 0; i < ARRAY_SIZE(tests); ++i)
10520 hr = IDirect3DDevice8_CreateVertexBuffer(device, size,
10521 D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, 0, D3DPOOL_DEFAULT, &buffer);
10522 ok(SUCCEEDED(hr), "Failed to create vertex buffer, hr %#lx.\n", hr);
10523 hr = IDirect3DVertexBuffer8_Lock(buffer, 0, size, (BYTE **)&quads, D3DLOCK_DISCARD);
10524 ok(SUCCEEDED(hr), "Failed to lock vertex buffer, hr %#lx.\n", hr);
10525 for (j = 0; j < size / sizeof(*quads); ++j)
10527 quads[j] = quad1;
10529 hr = IDirect3DVertexBuffer8_Unlock(buffer);
10530 ok(SUCCEEDED(hr), "Failed to unlock vertex buffer, hr %#lx.\n", hr);
10532 hr = IDirect3DDevice8_SetStreamSource(device, 0, buffer, sizeof(*quads->strip));
10533 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#lx.\n", hr);
10535 /* Start a draw operation. */
10536 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0f, 0);
10537 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
10538 hr = IDirect3DDevice8_BeginScene(device);
10539 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
10540 hr = IDirect3DDevice8_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, tri_count);
10541 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
10542 hr = IDirect3DDevice8_EndScene(device);
10543 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
10545 /* Map the last quad while the draw is in progress. */
10546 hr = IDirect3DVertexBuffer8_Lock(buffer, size - sizeof(quad2),
10547 sizeof(quad2), (BYTE **)&quads, tests[i].flags);
10548 ok(SUCCEEDED(hr), "Failed to lock vertex buffer, hr %#lx.\n", hr);
10549 *quads = quad2;
10550 hr = IDirect3DVertexBuffer8_Unlock(buffer);
10551 ok(SUCCEEDED(hr), "Failed to unlock vertex buffer, hr %#lx.\n", hr);
10553 colour = getPixelColor(device, 320, 240);
10554 unsynchronised = color_match(colour, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 1);
10555 ok(tests[i].unsynchronised == unsynchronised, "Expected %s map for flags %#x.\n",
10556 tests[i].unsynchronised ? "unsynchronised" : "synchronised", tests[i].flags);
10558 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
10559 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
10561 IDirect3DVertexBuffer8_Release(buffer);
10564 done:
10565 refcount = IDirect3DDevice8_Release(device);
10566 ok(!refcount, "Device has %lu references left.\n", refcount);
10567 IDirect3D8_Release(d3d);
10568 DestroyWindow(window);
10571 static void test_viewport(void)
10573 static const struct
10575 D3DVIEWPORT8 vp;
10576 RECT expected_rect;
10577 const char *message;
10579 tests[] =
10581 {{ 0, 0, 640, 480}, { 0, 120, 479, 359}, "Viewport (0, 0) - (640, 480)"},
10582 {{ 0, 0, 320, 240}, { 0, 60, 239, 179}, "Viewport (0, 0) - (320, 240)"},
10583 {{ 0, 0, 1280, 960}, { 0, 240, 639, 479}, "Viewport (0, 0) - (1280, 960)"},
10584 {{ 0, 0, 2000, 1600}, {-10, -10, -10, -10}, "Viewport (0, 0) - (2000, 1600)"},
10585 {{100, 100, 640, 480}, {100, 220, 579, 459}, "Viewport (100, 100) - (640, 480)"},
10586 {{ 0, 0, 8192, 8192}, {-10, -10, -10, -10}, "Viewport (0, 0) - (8192, 8192)"},
10588 static const struct vec3 quad[] =
10590 {-1.5f, -0.5f, 0.1f},
10591 {-1.5f, 0.5f, 0.1f},
10592 { 0.5f, -0.5f, 0.1f},
10593 { 0.5f, 0.5f, 0.1f},
10595 static const struct vec2 rt_sizes[] =
10597 {640, 480}, {1280, 960}, {320, 240}, {800, 600},
10599 struct surface_readback rb;
10600 IDirect3DDevice8 *device;
10601 IDirect3DSurface8 *rt;
10602 unsigned int i, j;
10603 IDirect3D8 *d3d;
10604 ULONG refcount;
10605 HWND window;
10606 HRESULT hr;
10608 window = create_window();
10609 d3d = Direct3DCreate8(D3D_SDK_VERSION);
10610 ok(!!d3d, "Failed to create a D3D object.\n");
10611 if (!(device = create_device(d3d, window, window, TRUE)))
10613 skip("Failed to create a D3D device, skipping tests.\n");
10614 goto done;
10617 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
10618 ok(SUCCEEDED(hr), "Failed to disable depth test, hr %#lx.\n", hr);
10619 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10620 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#lx.\n", hr);
10622 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ);
10623 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#lx.\n", hr);
10625 /* This crashes on Windows. */
10626 /* hr = IDirect3DDevice8_SetViewport(device, NULL); */
10628 for (i = 0; i < ARRAY_SIZE(rt_sizes); ++i)
10630 if (i)
10632 hr = IDirect3DDevice8_CreateRenderTarget(device, rt_sizes[i].x, rt_sizes[i].y,
10633 D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, TRUE, &rt);
10634 ok(SUCCEEDED(hr), "Failed to create render target, hr %#lx (i %u).\n", hr, i);
10635 hr = IDirect3DDevice8_SetRenderTarget(device, rt, NULL);
10636 ok(SUCCEEDED(hr), "Failed to set render target, hr %#lx (i %u).\n", hr, i);
10638 else
10640 hr = IDirect3DDevice8_GetBackBuffer(device, 0, D3DBACKBUFFER_TYPE_MONO, &rt);
10641 ok(SUCCEEDED(hr), "Failed to get backbuffer, hr %#lx.\n", hr);
10644 for (j = 0; j < ARRAY_SIZE(tests); ++j)
10646 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 1.0f, 0);
10647 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx (i %u, j %u).\n", hr, i, j);
10649 hr = IDirect3DDevice8_SetViewport(device, &tests[j].vp);
10650 if (tests[j].vp.X + tests[j].vp.Width > rt_sizes[i].x
10651 || tests[j].vp.Y + tests[j].vp.Height > rt_sizes[i].y)
10653 ok(hr == D3DERR_INVALIDCALL,
10654 "Setting the viewport returned unexpected hr %#lx (i %u, j %u).\n", hr, i, j);
10655 continue;
10657 else
10659 ok(SUCCEEDED(hr), "Failed to set the viewport, hr %#lx (i %u, j %u).\n", hr, i, j);
10662 hr = IDirect3DDevice8_BeginScene(device);
10663 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx (i %u, j %u).\n", hr, i, j);
10664 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
10665 ok(SUCCEEDED(hr), "Got unexpected hr %#lx (i %u, j %u).\n", hr, i, j);
10666 hr = IDirect3DDevice8_EndScene(device);
10667 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx (i %u, j %u).\n", hr, i, j);
10669 get_surface_readback(rt, &rb);
10670 check_rect(&rb, tests[j].expected_rect, tests[j].message);
10671 release_surface_readback(&rb);
10674 IDirect3DSurface8_Release(rt);
10677 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
10678 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
10680 refcount = IDirect3DDevice8_Release(device);
10681 ok(!refcount, "Device has %lu references left.\n", refcount);
10682 done:
10683 IDirect3D8_Release(d3d);
10684 DestroyWindow(window);
10687 static void test_color_vertex(void)
10689 IDirect3DDevice8 *device;
10690 unsigned int colour, i;
10691 D3DMATERIAL8 material;
10692 IDirect3D8 *d3d;
10693 ULONG refcount;
10694 HWND window;
10695 HRESULT hr;
10697 /* The idea here is to set up ambient light parameters in a way that the
10698 * ambient colour from the material is just passed through. The emissive
10699 * colour is just passed through anyway. The sum of ambient + emissive
10700 * should allow deduction of where the material colour came from.
10702 * Note that in cases without a D3DFVF_DIFFUSE flag the first colour value
10703 * in the struct will be fed into the specular vertex colour slot. */
10704 static const struct
10706 DWORD fvf, color_vertex, ambient, emissive;
10707 unsigned int result;
10709 tests[] =
10711 {D3DFVF_DIFFUSE | D3DFVF_SPECULAR, FALSE, D3DMCS_COLOR1, D3DMCS_COLOR2, 0x000000c0},
10713 {D3DFVF_DIFFUSE | D3DFVF_SPECULAR, TRUE, D3DMCS_COLOR1, D3DMCS_COLOR2, 0x00ffff00},
10714 {D3DFVF_DIFFUSE | D3DFVF_SPECULAR, TRUE, D3DMCS_MATERIAL, D3DMCS_COLOR2, 0x0000ff80},
10715 {D3DFVF_DIFFUSE | D3DFVF_SPECULAR, TRUE, D3DMCS_COLOR1, D3DMCS_MATERIAL, 0x00ff0040},
10716 {D3DFVF_DIFFUSE | D3DFVF_SPECULAR, TRUE, D3DMCS_COLOR1, D3DMCS_COLOR1, 0x00ff0000},
10717 {D3DFVF_DIFFUSE | D3DFVF_SPECULAR, TRUE, D3DMCS_COLOR2, D3DMCS_COLOR2, 0x0000ff00},
10719 {D3DFVF_SPECULAR, TRUE, D3DMCS_COLOR1, D3DMCS_COLOR2, 0x00ff0080},
10720 {D3DFVF_SPECULAR, TRUE, D3DMCS_COLOR1, D3DMCS_MATERIAL, 0x000000c0},
10721 {D3DFVF_SPECULAR, TRUE, D3DMCS_MATERIAL, D3DMCS_COLOR2, 0x00ff0080},
10722 {D3DFVF_DIFFUSE, TRUE, D3DMCS_COLOR1, D3DMCS_COLOR2, 0x00ff0040},
10723 {D3DFVF_DIFFUSE, TRUE, D3DMCS_COLOR1, D3DMCS_MATERIAL, 0x00ff0040},
10724 {D3DFVF_DIFFUSE, TRUE, D3DMCS_COLOR2, D3DMCS_MATERIAL, 0x000000c0},
10726 {0, TRUE, D3DMCS_COLOR1, D3DMCS_COLOR2, 0x000000c0},
10728 static const struct
10730 struct vec3 position;
10731 DWORD diffuse;
10732 DWORD specular;
10734 quad[] =
10736 {{-1.0f, -1.0f, 0.0f}, 0xffff0000, 0xff00ff00},
10737 {{-1.0f, 1.0f, 0.0f}, 0xffff0000, 0xff00ff00},
10738 {{ 1.0f, -1.0f, 0.0f}, 0xffff0000, 0xff00ff00},
10739 {{ 1.0f, 1.0f, 0.0f}, 0xffff0000, 0xff00ff00},
10742 window = create_window();
10743 ok(!!window, "Failed to create a window.\n");
10745 d3d = Direct3DCreate8(D3D_SDK_VERSION);
10746 ok(!!d3d, "Failed to create a D3D object.\n");
10747 if (!(device = create_device(d3d, window, window, TRUE)))
10749 skip("Failed to create a D3D device, skipping tests.\n");
10750 IDirect3D8_Release(d3d);
10751 DestroyWindow(window);
10752 return;
10755 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, TRUE);
10756 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
10757 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_AMBIENT, 0xffffffff);
10758 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
10760 memset(&material, 0, sizeof(material));
10761 material.Ambient.b = 0.5f;
10762 material.Emissive.b = 0.25f;
10763 hr = IDirect3DDevice8_SetMaterial(device, &material);
10764 ok(SUCCEEDED(hr), "Failed to set material, hr %#lx\n", hr);
10766 for (i = 0; i < ARRAY_SIZE(tests); ++i)
10768 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_COLORVERTEX, tests[i].color_vertex);
10769 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
10770 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_AMBIENTMATERIALSOURCE, tests[i].ambient);
10771 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
10772 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_EMISSIVEMATERIALSOURCE, tests[i].emissive);
10773 ok(SUCCEEDED(hr), "Failed to set render state, hr %#lx.\n", hr);
10774 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | tests[i].fvf);
10775 ok(SUCCEEDED(hr), "Failed to set vertex format, hr %#lx.\n", hr);
10777 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x77777777, 0.0f, 0);
10778 ok(SUCCEEDED(hr), "Failed to clear depth/stencil, hr %#lx.\n", hr);
10780 hr = IDirect3DDevice8_BeginScene(device);
10781 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#lx.\n", hr);
10782 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10783 ok(SUCCEEDED(hr), "Failed to draw, hr %#lx.\n", hr);
10784 hr = IDirect3DDevice8_EndScene(device);
10785 ok(SUCCEEDED(hr), "Failed to end scene, hr %#lx.\n", hr);
10787 colour = getPixelColor(device, 320, 240);
10788 ok(color_match(colour, tests[i].result, 1),
10789 "Expected colour 0x%08x for test %u, got 0x%08x.\n",
10790 tests[i].result, i, colour);
10793 refcount = IDirect3DDevice8_Release(device);
10794 ok(!refcount, "Device has %lu references left.\n", refcount);
10795 IDirect3D8_Release(d3d);
10796 DestroyWindow(window);
10799 static void test_sysmem_draw(void)
10801 IDirect3DVertexBuffer8 *vb, *vb_s0, *vb_s1, *dst_vb, *get_vb;
10802 D3DPRESENT_PARAMETERS present_parameters = {0};
10803 unsigned int colour, i, stride;
10804 IDirect3DTexture8 *texture;
10805 IDirect3DIndexBuffer8 *ib;
10806 IDirect3DDevice8 *device;
10807 struct vec4 *dst_data;
10808 D3DLOCKED_RECT lr;
10809 IDirect3D8 *d3d;
10810 ULONG refcount;
10811 HWND window;
10812 HRESULT hr;
10813 BYTE *data;
10814 DWORD vs;
10816 static const DWORD texture_data[4] = {0xffff0000, 0xff00ff00, 0xff0000ff, 0xffffffff};
10817 static const DWORD decl[] =
10819 D3DVSD_STREAM(0),
10820 D3DVSD_REG(D3DVSDE_POSITION, D3DVSDT_FLOAT3),
10821 D3DVSD_STREAM(1),
10822 D3DVSD_REG(D3DVSDE_DIFFUSE, D3DVSDT_D3DCOLOR),
10823 D3DVSD_END()
10825 static const struct
10827 struct vec3 position;
10828 DWORD diffuse;
10830 quad[] =
10832 {{-0.5f, -0.5f, 0.0f}, 0xffff0000},
10833 {{-0.5f, 0.5f, 0.0f}, 0xff00ff00},
10834 {{ 0.5f, -0.5f, 0.0f}, 0xff0000ff},
10835 {{ 0.5f, 0.5f, 0.0f}, 0xffffffff},
10837 static const struct vec3 quad_s0[] =
10839 {-1.0f, -1.0f, 0.0f},
10840 {-1.0f, 1.0f, 0.0f},
10841 { 1.0f, -1.0f, 0.0f},
10842 { 1.0f, 1.0f, 0.0f},
10844 {-1.0f, -1.0f, 0.0f},
10845 {-1.0f, 1.0f, 0.0f},
10846 { 1.0f, -1.0f, 0.0f},
10847 { 1.0f, 1.0f, 0.0f},
10849 static const DWORD quad_s1[] =
10851 0xffff0000,
10852 0xff00ff00,
10853 0xff0000ff,
10854 0xffffffff,
10856 0xff443322,
10857 0xff443322,
10858 0xff443322,
10859 0xff443322,
10861 static const short indices[] = {5, 6, 7, 8, 0, 1, 2, 3};
10863 window = create_window();
10864 ok(!!window, "Failed to create a window.\n");
10866 d3d = Direct3DCreate8(D3D_SDK_VERSION);
10867 ok(!!d3d, "Failed to create a D3D object.\n");
10869 present_parameters.BackBufferWidth = 640;
10870 present_parameters.BackBufferHeight = 480;
10871 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
10872 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
10873 present_parameters.hDeviceWindow = window;
10874 present_parameters.Windowed = TRUE;
10875 present_parameters.EnableAutoDepthStencil = TRUE;
10876 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
10877 if (FAILED(hr = IDirect3D8_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
10878 window, D3DCREATE_MIXED_VERTEXPROCESSING, &present_parameters, &device)))
10880 skip("Failed to create a D3D device, skipping tests.\n");
10881 IDirect3D8_Release(d3d);
10882 DestroyWindow(window);
10883 return;
10886 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10887 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
10889 hr = IDirect3DDevice8_CreateVertexBuffer(device, sizeof(quad), 0, 0, D3DPOOL_SYSTEMMEM, &vb);
10890 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
10891 hr = IDirect3DVertexBuffer8_Lock(vb, 0, sizeof(quad), &data, 0);
10892 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
10893 memcpy(data, quad, sizeof(quad));
10894 hr = IDirect3DVertexBuffer8_Unlock(vb);
10895 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
10897 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x77777777, 0.0f, 0);
10898 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
10900 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10901 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
10902 hr = IDirect3DDevice8_SetStreamSource(device, 0, vb, sizeof(*quad));
10903 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
10905 hr = IDirect3DDevice8_BeginScene(device);
10906 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
10907 hr = IDirect3DDevice8_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
10908 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
10909 hr = IDirect3DDevice8_EndScene(device);
10910 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
10912 colour = getPixelColor(device, 320, 240);
10913 ok(color_match(colour, 0x00007f7f, 1), "Got unexpected colour 0x%08x.\n", colour);
10915 hr = IDirect3DDevice8_CreateVertexBuffer(device, ARRAY_SIZE(quad) * sizeof(*dst_data),
10916 0, D3DFVF_XYZRHW, D3DPOOL_SYSTEMMEM, &dst_vb);
10917 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
10918 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SOFTWAREVERTEXPROCESSING, TRUE);
10919 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
10920 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10921 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
10922 hr = IDirect3DDevice8_SetStreamSource(device, 0, vb, sizeof(*quad));
10923 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
10925 hr = IDirect3DDevice8_ProcessVertices(device, 0, 0, ARRAY_SIZE(quad), dst_vb, 0);
10926 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
10927 hr = IDirect3DVertexBuffer8_Lock(dst_vb, 0, 0, (BYTE **)&dst_data, 0);
10928 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
10929 for (i = 0; i < ARRAY_SIZE(quad); ++i)
10931 ok(compare_vec4(&dst_data[i], quad[i].position.x * 320.0f + 320.0f,
10932 -quad[i].position.y * 240.0f + 240.0f, 0.0f, 1.0f, 4),
10933 "Got unexpected vertex %u {%.8e, %.8e, %.8e, %.8e}.\n",
10934 i, dst_data[i].x, dst_data[i].y, dst_data[i].z, dst_data[i].w);
10936 hr = IDirect3DVertexBuffer8_Unlock(dst_vb);
10937 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
10939 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SOFTWAREVERTEXPROCESSING, FALSE);
10940 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
10941 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10942 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
10943 hr = IDirect3DDevice8_SetStreamSource(device, 0, vb, sizeof(*quad));
10944 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
10946 hr = IDirect3DDevice8_CreateIndexBuffer(device, sizeof(indices), 0,
10947 D3DFMT_INDEX16, D3DPOOL_SYSTEMMEM, &ib);
10948 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
10949 hr = IDirect3DIndexBuffer8_Lock(ib, 0, sizeof(indices), &data, 0);
10950 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
10951 memcpy(data, indices, sizeof(indices));
10952 hr = IDirect3DIndexBuffer8_Unlock(ib);
10953 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
10955 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x77777777, 0.0f, 0);
10956 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
10958 hr = IDirect3DDevice8_SetIndices(device, ib, 0);
10959 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
10961 hr = IDirect3DDevice8_BeginScene(device);
10962 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
10963 hr = IDirect3DDevice8_DrawIndexedPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 4, 4, 2);
10964 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
10965 hr = IDirect3DDevice8_EndScene(device);
10966 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
10968 colour = getPixelColor(device, 320, 240);
10969 ok(color_match(colour, 0x00007f7f, 1), "Got unexpected colour 0x%08x.\n", colour);
10971 hr = IDirect3DDevice8_CreateVertexShader(device, decl, NULL, &vs, 0);
10972 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
10973 hr = IDirect3DDevice8_SetVertexShader(device, vs);
10974 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
10976 hr = IDirect3DDevice8_CreateVertexBuffer(device, sizeof(quad_s0), 0, 0, D3DPOOL_SYSTEMMEM, &vb_s0);
10977 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
10978 hr = IDirect3DVertexBuffer8_Lock(vb_s0, 0, sizeof(quad_s0), &data, 0);
10979 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
10980 memcpy(data, quad_s0, sizeof(quad_s0));
10981 hr = IDirect3DVertexBuffer8_Unlock(vb_s0);
10982 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
10983 hr = IDirect3DDevice8_CreateVertexBuffer(device, sizeof(quad_s1), 0, 0, D3DPOOL_SYSTEMMEM, &vb_s1);
10984 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
10985 hr = IDirect3DVertexBuffer8_Lock(vb_s1, 0, sizeof(quad_s1), &data, 0);
10986 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
10987 memcpy(data, quad_s1, sizeof(quad_s1));
10988 hr = IDirect3DVertexBuffer8_Unlock(vb_s1);
10989 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
10991 hr = IDirect3DDevice8_SetStreamSource(device, 0, vb_s0, sizeof(*quad_s0));
10992 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
10993 hr = IDirect3DDevice8_SetStreamSource(device, 1, vb_s1, sizeof(*quad_s1));
10994 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
10996 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x77777777, 0.0f, 0);
10997 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
10999 hr = IDirect3DDevice8_BeginScene(device);
11000 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11001 hr = IDirect3DDevice8_DrawIndexedPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 4, 4, 2);
11002 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11003 hr = IDirect3DDevice8_EndScene(device);
11004 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11006 colour = getPixelColor(device, 320, 240);
11007 ok(color_match(colour, 0x00007f7f, 1), "Got unexpected colour 0x%08x.\n", colour);
11009 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x77777777, 0.0f, 0);
11010 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11012 hr = IDirect3DDevice8_SetIndices(device, ib, 4);
11013 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11015 hr = IDirect3DDevice8_BeginScene(device);
11016 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11017 hr = IDirect3DDevice8_DrawIndexedPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 5, 4, 2);
11018 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11019 hr = IDirect3DDevice8_EndScene(device);
11020 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11022 colour = getPixelColor(device, 320, 240);
11023 ok(color_match(colour, 0x00443322, 1), "Got unexpected colour 0x%08x.\n", colour);
11025 /* Test that releasing but not unbinding a vertex buffer doesn't break. */
11026 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11027 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11028 hr = IDirect3DDevice8_SetStreamSource(device, 0, vb, sizeof(*quad));
11029 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11030 hr = IDirect3DDevice8_SetIndices(device, ib, 0);
11031 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11033 refcount = IDirect3DVertexBuffer8_Release(vb_s1);
11034 ok(!refcount, "Unexpected refcount %lu.\n", refcount);
11035 hr = IDirect3DDevice8_GetStreamSource(device, 1, &get_vb, &stride);
11036 ok(SUCCEEDED(hr), "Got unexpected hr %#lx.\n", hr);
11037 ok(get_vb == vb_s1, "Got unexpected vertex buffer %p.\n", get_vb);
11038 refcount = IDirect3DVertexBuffer8_Release(get_vb);
11039 ok(!refcount, "Unexpected refcount %lu.\n", refcount);
11041 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x77777777, 0.0f, 0);
11042 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11044 hr = IDirect3DDevice8_BeginScene(device);
11045 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11046 hr = IDirect3DDevice8_DrawIndexedPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 4, 4, 2);
11047 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11048 hr = IDirect3DDevice8_EndScene(device);
11049 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11051 colour = getPixelColor(device, 320, 240);
11052 ok(color_match(colour, 0x00007f7f, 1), "Got unexpected colour 0x%08x.\n", colour);
11054 hr = IDirect3DDevice8_SetVertexShader(device, vs);
11055 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11056 hr = IDirect3DDevice8_SetStreamSource(device, 0, vb_s0, sizeof(*quad_s0));
11057 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11059 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x77777777, 0.0f, 0);
11060 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11062 hr = IDirect3DDevice8_BeginScene(device);
11063 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11064 hr = IDirect3DDevice8_DrawIndexedPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 4, 4, 2);
11065 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11066 hr = IDirect3DDevice8_EndScene(device);
11067 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11069 colour = getPixelColor(device, 320, 240);
11070 ok(color_match(colour, 0x00007f7f, 1), "Got unexpected colour 0x%08x.\n", colour);
11072 hr = IDirect3DDevice8_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &texture);
11073 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11074 memset(&lr, 0, sizeof(lr));
11075 hr = IDirect3DTexture8_LockRect(texture, 0, &lr, NULL, 0);
11076 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11077 memcpy(lr.pBits, texture_data, sizeof(texture_data));
11078 hr = IDirect3DTexture8_UnlockRect(texture, 0);
11079 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11081 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
11082 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11084 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x77777777, 0.0f, 0);
11085 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11087 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ);
11088 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11090 hr = IDirect3DDevice8_BeginScene(device);
11091 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11092 hr = IDirect3DDevice8_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
11093 ok(hr == D3D_OK || hr == E_FAIL, "Got unexpected hr %#lx.\n", hr);
11094 hr = IDirect3DDevice8_EndScene(device);
11095 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11097 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
11098 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11100 IDirect3DTexture8_Release(texture);
11101 IDirect3DVertexBuffer8_Release(vb_s0);
11102 IDirect3DDevice8_DeleteVertexShader(device, vs);
11103 IDirect3DIndexBuffer8_Release(ib);
11104 IDirect3DVertexBuffer8_Release(dst_vb);
11105 IDirect3DVertexBuffer8_Release(vb);
11106 refcount = IDirect3DDevice8_Release(device);
11107 ok(!refcount, "Device has %lu references left.\n", refcount);
11108 IDirect3D8_Release(d3d);
11109 DestroyWindow(window);
11112 static void test_alphatest(void)
11114 #define ALPHATEST_PASSED 0x0000ff00
11115 #define ALPHATEST_FAILED 0x00ff0000
11116 IDirect3DDevice8 *device;
11117 unsigned int color, i, j;
11118 IDirect3D8 *d3d;
11119 ULONG refcount;
11120 D3DCAPS8 caps;
11121 DWORD value;
11122 HWND window;
11123 HRESULT hr;
11124 DWORD ps;
11126 static const struct
11128 D3DCMPFUNC func;
11129 unsigned int color_less, color_equal, color_greater;
11131 test_data[] =
11133 {D3DCMP_NEVER, ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_FAILED},
11134 {D3DCMP_LESS, ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_FAILED},
11135 {D3DCMP_EQUAL, ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_FAILED},
11136 {D3DCMP_LESSEQUAL, ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_FAILED},
11137 {D3DCMP_GREATER, ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_PASSED},
11138 {D3DCMP_NOTEQUAL, ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_PASSED},
11139 {D3DCMP_GREATEREQUAL, ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_PASSED},
11140 {D3DCMP_ALWAYS, ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_PASSED},
11142 static const struct
11144 struct vec3 position;
11145 DWORD diffuse;
11147 quad[] =
11149 {{-1.0f, -1.0f, 0.1f}, ALPHATEST_PASSED | 0x80000000},
11150 {{-1.0f, 1.0f, 0.1f}, ALPHATEST_PASSED | 0x80000000},
11151 {{ 1.0f, -1.0f, 0.1f}, ALPHATEST_PASSED | 0x80000000},
11152 {{ 1.0f, 1.0f, 0.1f}, ALPHATEST_PASSED | 0x80000000},
11155 window = create_window();
11156 ok(!!window, "Failed to create a window.\n");
11158 d3d = Direct3DCreate8(D3D_SDK_VERSION);
11159 ok(!!d3d, "Failed to create a D3D object.\n");
11161 if (!(device = create_device(d3d, window, window, TRUE)))
11163 skip("Failed to create a D3D device, skipping tests.\n");
11164 goto done;
11167 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
11168 ok(hr == D3D_OK, "Failed to clear, hr %#lx.\n", hr);
11170 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11171 ok(hr == D3D_OK, "Failed to disable lighting, hr %#lx.\n", hr);
11172 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ALPHATESTENABLE, TRUE);
11173 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState, hr %#lx.\n", hr);
11174 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11175 ok(hr == D3D_OK, "IDirect3DDevice8_SetVertexShader failed, hr %#lx.\n", hr);
11177 ps = 0;
11178 for (j = 0; j < 2; ++j)
11180 if (j == 1)
11182 /* Try a pixel shader instead of fixed function. The wined3d code
11183 * may emulate the alpha test either for performance reasons
11184 * (floating point RTs) or to work around driver bugs (GeForce
11185 * 7x00 cards on MacOS). There may be a different codepath for ffp
11186 * and shader in this case, and the test should cover both. */
11187 static const DWORD shader_code[] =
11189 0xffff0101, /* ps_1_1 */
11190 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
11191 0x0000ffff /* end */
11193 memset(&caps, 0, sizeof(caps));
11194 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
11195 ok(hr == D3D_OK, "IDirect3DDevice8_GetDeviceCaps failed, hr %#lx.\n", hr);
11196 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 1))
11197 break;
11199 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code, &ps);
11200 ok(hr == D3D_OK, "IDirect3DDevice8_CreatePixelShader failed, hr %#lx.\n", hr);
11201 hr = IDirect3DDevice8_SetPixelShader(device, ps);
11202 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShader failed, hr %#lx.\n", hr);
11205 for (i = 0; i < ARRAY_SIZE(test_data); ++i)
11207 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ALPHAFUNC, test_data[i].func);
11208 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr %#lx.\n", hr);
11210 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0f, 0);
11211 ok(hr == D3D_OK, "IDirect3DDevice8_Clear failed, hr %#lx.\n", hr);
11212 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ALPHAREF, 0x70);
11213 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr %#lx.\n", hr);
11214 hr = IDirect3DDevice8_BeginScene(device);
11215 ok(hr == D3D_OK, "IDirect3DDevice8_BeginScene failed, hr %#lx.\n", hr);
11216 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11217 ok(hr == D3D_OK, "IDirect3DDevice8_DrawPrimitiveUP failed, hr %#lx.\n", hr);
11218 hr = IDirect3DDevice8_EndScene(device);
11219 ok(hr == D3D_OK, "IDirect3DDevice8_EndScene failed, hr %#lx.\n", hr);
11220 color = getPixelColor(device, 320, 240);
11221 ok(color_match(color, test_data[i].color_greater, 0),
11222 "Alphatest failed, color 0x%08x, expected 0x%08x, alpha > ref, func %u.\n",
11223 color, test_data[i].color_greater, test_data[i].func);
11224 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
11225 ok(hr == D3D_OK, "IDirect3DDevice8_Present failed, hr %#lx.\n", hr);
11227 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0f, 0);
11228 ok(hr == D3D_OK, "IDirect3DDevice8_Clear failed, hr %#lx.\n", hr);
11229 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ALPHAREF, 0xff70);
11230 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr %#lx.\n", hr);
11231 hr = IDirect3DDevice8_GetRenderState(device, D3DRS_ALPHAREF, &value);
11232 ok(hr == D3D_OK, "IDirect3DDevice8_GetRenderState failed, hr %#lx.\n", hr);
11233 ok(value == 0xff70, "Unexpected D3DRS_ALPHAREF value %#lx.\n", value);
11234 hr = IDirect3DDevice8_BeginScene(device);
11235 ok(hr == D3D_OK, "IDirect3DDevice8_BeginScene failed, hr %#lx.\n", hr);
11236 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11237 ok(hr == D3D_OK, "IDirect3DDevice8_DrawPrimitiveUP failed, hr %#lx.\n", hr);
11238 hr = IDirect3DDevice8_EndScene(device);
11239 ok(hr == D3D_OK, "IDirect3DDevice8_EndScene failed, hr %#lx.\n", hr);
11240 color = getPixelColor(device, 320, 240);
11241 ok(color_match(color, test_data[i].color_greater, 0),
11242 "Alphatest failed, color 0x%08x, expected 0x%08x, alpha > ref, func %u.\n",
11243 color, test_data[i].color_greater, test_data[i].func);
11244 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
11245 ok(hr == D3D_OK, "IDirect3DDevice8_Present failed, hr %#lx.\n", hr);
11248 if (ps)
11249 IDirect3DDevice8_DeletePixelShader(device, ps);
11251 refcount = IDirect3DDevice8_Release(device);
11252 ok(!refcount, "Device has %lu references left.\n", refcount);
11253 done:
11254 IDirect3D8_Release(d3d);
11255 DestroyWindow(window);
11258 static void test_desktop_window(void)
11260 IDirect3DDevice8 *device;
11261 unsigned int color;
11262 IDirect3D8 *d3d;
11263 ULONG refcount;
11264 HWND window;
11265 HRESULT hr;
11267 window = create_window();
11268 d3d = Direct3DCreate8(D3D_SDK_VERSION);
11269 ok(!!d3d, "Failed to create a D3D object.\n");
11270 if (!(device = create_device(d3d, window, window, TRUE)))
11272 skip("Failed to create a D3D device, skipping tests.\n");
11273 IDirect3D8_Release(d3d);
11274 DestroyWindow(window);
11275 return;
11277 IDirect3DDevice8_Release(device);
11278 DestroyWindow(window);
11280 device = create_device(d3d, GetDesktopWindow(), GetDesktopWindow(), TRUE);
11281 ok(!!device, "Failed to create a D3D device.\n");
11283 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 1.0f, 0);
11284 ok(SUCCEEDED(hr), "Failed to clear, hr %#lx.\n", hr);
11285 color = getPixelColor(device, 1, 1);
11286 ok(color == 0x00ff0000, "Got unexpected color 0x%08x.\n", color);
11288 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
11289 ok(SUCCEEDED(hr), "Failed to present, hr %#lx.\n", hr);
11291 refcount = IDirect3DDevice8_Release(device);
11292 ok(!refcount, "Device has %lu references left.\n", refcount);
11294 IDirect3D8_Release(d3d);
11297 static void test_sample_mask(void)
11299 IDirect3DSurface8 *rt, *ms_rt;
11300 struct surface_readback rb;
11301 IDirect3DDevice8 *device;
11302 unsigned int colour;
11303 IDirect3D8 *d3d;
11304 ULONG refcount;
11305 HWND window;
11306 HRESULT hr;
11308 static const struct
11310 struct vec3 position;
11311 DWORD diffuse;
11313 quad[] =
11315 {{-1.0f, -1.0f, 0.1f}, 0xffffffff},
11316 {{-1.0f, 1.0f, 0.1f}, 0xffffffff},
11317 {{ 1.0f, -1.0f, 0.1f}, 0xffffffff},
11318 {{ 1.0f, 1.0f, 0.1f}, 0xffffffff},
11321 window = create_window();
11322 d3d = Direct3DCreate8(D3D_SDK_VERSION);
11323 ok(!!d3d, "Failed to create a D3D object.\n");
11325 if (FAILED(IDirect3D8_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
11326 D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES)))
11328 skip("Multisampling not supported for D3DFMT_A8R8G8B8.\n");
11329 IDirect3D8_Release(d3d);
11330 DestroyWindow(window);
11331 return;
11334 if (!(device = create_device(d3d, window, window, TRUE)))
11336 skip("Failed to create a 3D device.\n");
11337 IDirect3D8_Release(d3d);
11338 DestroyWindow(window);
11339 return;
11342 hr = IDirect3DDevice8_CreateRenderTarget(device, 128, 128, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, FALSE, &rt);
11343 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11344 hr = IDirect3DDevice8_CreateRenderTarget(device, 128, 128,
11345 D3DFMT_A8R8G8B8, D3DMULTISAMPLE_2_SAMPLES, FALSE, &ms_rt);
11346 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11348 hr = IDirect3DDevice8_SetRenderTarget(device, ms_rt, NULL);
11349 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11351 hr = IDirect3DDevice8_BeginScene(device);
11352 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11354 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11355 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11356 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_MULTISAMPLEMASK, 0x5);
11357 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11359 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0f, 0);
11360 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11361 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11362 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11363 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
11364 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11366 hr = IDirect3DDevice8_CopyRects(device, ms_rt, NULL, 0, rt, NULL);
11367 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11368 get_surface_readback(rt, &rb);
11369 colour = get_readback_color(&rb, 64, 64);
11370 /* Multiple generations of Nvidia cards return broken results.
11371 * A mask with no bits or all bits set produce the expected results (0x00 / 0xff),
11372 * but any other mask behaves almost as if the result is 0.5 + (enabled / total)
11373 * samples. It's not quite that though (you'd expect 0xbf or 0xc0 instead of 0xbc).
11375 * I looked at a few other possible problems: Incorrectly enabled Z test, alpha test,
11376 * culling, the multisample mask affecting CopyRects. Neither of these make a difference. */
11377 ok(color_match(colour, 0xffff8080, 1) || broken(color_match(colour, 0xffffbcbc, 1)),
11378 "Got unexpected colour %08x.\n", colour);
11379 release_surface_readback(&rb);
11381 hr = IDirect3DDevice8_EndScene(device);
11382 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11384 IDirect3DSurface8_Release(ms_rt);
11385 IDirect3DSurface8_Release(rt);
11386 refcount = IDirect3DDevice8_Release(device);
11387 ok(!refcount, "Device has %lu references left.\n", refcount);
11388 IDirect3D8_Release(d3d);
11389 DestroyWindow(window);
11392 struct dynamic_vb_vertex
11394 struct vec3 position;
11395 DWORD diffuse;
11398 static void fill_dynamic_vb_quad(struct dynamic_vb_vertex *quad, unsigned int x, unsigned int y)
11400 unsigned int i;
11402 memset(quad, 0, 4 * sizeof(*quad));
11404 quad[0].position.x = quad[1].position.x = -1.0f + 0.01f * x;
11405 quad[2].position.x = quad[3].position.x = -1.0f + 0.01f * (x + 1);
11407 quad[0].position.y = quad[2].position.y = -1.0f + 0.01f * y;
11408 quad[1].position.y = quad[3].position.y = -1.0f + 0.01f * (y + 1);
11410 for (i = 0; i < 4; ++i)
11411 quad[i].diffuse = 0xff00ff00;
11414 static void test_dynamic_map_synchronization(void)
11416 IDirect3DVertexBuffer8 *buffer;
11417 IDirect3DDevice8 *device;
11418 IDirect3DSurface8 *rt;
11419 unsigned int x, y;
11420 IDirect3D8 *d3d;
11421 ULONG refcount;
11422 HWND window;
11423 HRESULT hr;
11424 BYTE *data;
11426 window = create_window();
11427 d3d = Direct3DCreate8(D3D_SDK_VERSION);
11428 ok(!!d3d, "Failed to create a D3D object.\n");
11429 if (!(device = create_device(d3d, window, window, TRUE)))
11431 skip("Failed to create a D3D device, skipping tests.\n");
11432 IDirect3D8_Release(d3d);
11433 DestroyWindow(window);
11434 return;
11437 hr = IDirect3DDevice8_CreateVertexBuffer(device, 200 * 4 * sizeof(struct dynamic_vb_vertex),
11438 D3DUSAGE_DYNAMIC, D3DFVF_XYZ, D3DPOOL_DEFAULT, &buffer);
11439 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11441 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0f, 0);
11442 ok(hr == D3D_OK, "Failed to clear, hr %#lx.\n", hr);
11444 hr = IDirect3DDevice8_BeginScene(device);
11445 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11446 hr = IDirect3DDevice8_SetStreamSource(device, 0, buffer, sizeof(struct dynamic_vb_vertex));
11447 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11448 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11449 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11450 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, FALSE);
11451 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11452 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11453 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11455 for (y = 0; y < 200; ++y)
11457 hr = IDirect3DVertexBuffer8_Lock(buffer, 0, 0, &data, D3DLOCK_DISCARD);
11458 ok(hr == D3D_OK, "Failed to map buffer, hr %#lx.\n", hr);
11460 fill_dynamic_vb_quad((struct dynamic_vb_vertex *)data, 0, y);
11462 hr = IDirect3DVertexBuffer8_Unlock(buffer);
11463 ok(hr == D3D_OK, "Failed to map buffer, hr %#lx.\n", hr);
11465 hr = IDirect3DDevice8_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
11466 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11468 for (x = 1; x < 200; ++x)
11470 hr = IDirect3DVertexBuffer8_Lock(buffer, 4 * sizeof(struct dynamic_vb_vertex) * x,
11471 4 * sizeof(struct dynamic_vb_vertex), &data, D3DLOCK_NOOVERWRITE);
11472 ok(hr == D3D_OK, "Failed to map buffer, hr %#lx.\n", hr);
11474 fill_dynamic_vb_quad((struct dynamic_vb_vertex *)data, x, y);
11476 hr = IDirect3DVertexBuffer8_Unlock(buffer);
11477 ok(hr == D3D_OK, "Failed to map buffer, hr %#lx.\n", hr);
11479 hr = IDirect3DDevice8_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4 * x, 2);
11480 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11484 hr = IDirect3DDevice8_GetRenderTarget(device, &rt);
11485 ok(hr == S_OK, "Failed to get render target, hr %#lx.\n", hr);
11486 check_rt_color(rt, 0x0000ff00);
11487 IDirect3DSurface8_Release(rt);
11489 hr = IDirect3DDevice8_EndScene(device);
11490 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11492 IDirect3DVertexBuffer8_Release(buffer);
11493 refcount = IDirect3DDevice8_Release(device);
11494 ok(!refcount, "Device has %lu references left.\n", refcount);
11495 IDirect3D8_Release(d3d);
11496 DestroyWindow(window);
11499 static void test_filling_convention(void)
11501 static const DWORD colour_bottom = 0x00ffff00;
11502 static const DWORD colour_clear = 0x000000ff;
11503 static const DWORD colour_right = 0x00000000;
11504 static const DWORD colour_left = 0x00ff0000;
11505 static const DWORD colour_top = 0x0000ff00;
11506 unsigned int colour, expected, i, j, x, y;
11507 IDirect3DSurface8 *rt, *backbuffer, *cur;
11508 struct surface_readback rb;
11509 IDirect3DDevice8 *device;
11510 DWORD shader = 0;
11511 IDirect3D8 *d3d;
11512 ULONG refcount;
11513 D3DCAPS8 caps;
11514 HWND window;
11515 HRESULT hr;
11516 BOOL todo;
11518 static const unsigned int vp_size = 8;
11519 const D3DVIEWPORT8 vp = { 0, 0, vp_size, vp_size, 0.0, 1.0 };
11520 static const DWORD vs_code[] =
11522 0xfffe0101, /* vs_1_1 */
11523 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
11524 0x00000001, 0xd00f0000, 0x90e40005, /* mov oD0, v5 */
11525 0x0000ffff /* end */
11527 static const DWORD decl[] =
11529 D3DVSD_STREAM(0),
11530 D3DVSD_REG(D3DVSDE_POSITION, D3DVSDT_FLOAT3),
11531 D3DVSD_REG(D3DVSDE_DIFFUSE, D3DVSDT_D3DCOLOR),
11532 D3DVSD_END()
11535 /* This test data follows the examples in MSDN's
11536 * "Rasterization Rules (Direct3D 9)" article.
11538 * See the d3d9 test for a comment about the eps value. */
11539 static const float eps = 1.0f / 64.0f;
11540 const struct
11542 struct vec3 position;
11543 DWORD diffuse;
11545 center_tris[] =
11547 /* left */
11548 {{-2.5f / 4.0f, -1.5f / 4.0f, 0.0f}, colour_left},
11549 {{-2.5f / 4.0f, 2.5f / 4.0f, 0.0f}, colour_left},
11550 {{-1.5f / 4.0f, 0.5f / 4.0f, 0.0f}, colour_left},
11552 /* top */
11553 {{-1.5f / 4.0f, 0.5f / 4.0f, 0.0f}, colour_top},
11554 {{-2.5f / 4.0f, 2.5f / 4.0f, 0.0f}, colour_top},
11555 {{-0.5f / 4.0f, 2.5f / 4.0f, 0.0f}, colour_top},
11557 /* right */
11558 {{-0.5f / 4.0f, -1.5f / 4.0f, 0.0f}, colour_right},
11559 {{-1.5f / 4.0f, 0.5f / 4.0f, 0.0f}, colour_right},
11560 {{-0.5f / 4.0f, 2.5f / 4.0f, 0.0f}, colour_right},
11562 /* bottom */
11563 {{-2.5f / 4.0f, -1.5f / 4.0f, 0.0f}, colour_bottom},
11564 {{-1.5f / 4.0f, 0.5f / 4.0f, 0.0f}, colour_bottom},
11565 {{-0.5f / 4.0f, -1.5f / 4.0f, 0.0f}, colour_bottom},
11568 edge_tris[] =
11570 /* left */
11571 {{-2.0f / 4.0f, -1.0f / 4.0f, 0.0f}, colour_left},
11572 {{-2.0f / 4.0f, 3.0f / 4.0f, 0.0f}, colour_left},
11573 {{-1.0f / 4.0f, 1.0f / 4.0f, 0.0f}, colour_left},
11575 /* top */
11576 {{-1.0f / 4.0f, 1.0f / 4.0f, 0.0f}, colour_top},
11577 {{-2.0f / 4.0f, 3.0f / 4.0f, 0.0f}, colour_top},
11578 {{ 0.0f / 4.0f, 3.0f / 4.0f, 0.0f}, colour_top},
11580 /* right */
11581 {{ 0.0f / 4.0f, -1.0f / 4.0f, 0.0f}, colour_right},
11582 {{-1.0f / 4.0f, 1.0f / 4.0f, 0.0f}, colour_right},
11583 {{ 0.0f / 4.0f, 3.0f / 4.0f, 0.0f}, colour_right},
11585 /* bottom */
11586 {{-2.0f / 4.0f, -1.0f / 4.0f, 0.0f}, colour_bottom},
11587 {{-1.0f / 4.0f, 1.0f / 4.0f, 0.0f}, colour_bottom},
11588 {{ 0.0f / 4.0f, -1.0f / 4.0f, 0.0f}, colour_bottom},
11590 nudge_right_tris[] =
11592 /* left */
11593 {{eps - 2.0f / 4.0f, -1.0f / 4.0f, 0.0f}, colour_left},
11594 {{eps - 2.0f / 4.0f, 3.0f / 4.0f, 0.0f}, colour_left},
11595 {{eps - 1.0f / 4.0f, 1.0f / 4.0f, 0.0f}, colour_left},
11597 /* top */
11598 {{eps - 1.0f / 4.0f, 1.0f / 4.0f, 0.0f}, colour_top},
11599 {{eps - 2.0f / 4.0f, 3.0f / 4.0f, 0.0f}, colour_top},
11600 {{eps - 0.0f / 4.0f, 3.0f / 4.0f, 0.0f}, colour_top},
11602 /* right */
11603 {{eps - 0.0f / 4.0f, -1.0f / 4.0f, 0.0f}, colour_right},
11604 {{eps - 1.0f / 4.0f, 1.0f / 4.0f, 0.0f}, colour_right},
11605 {{eps - 0.0f / 4.0f, 3.0f / 4.0f, 0.0f}, colour_right},
11607 /* bottom */
11608 {{eps - 2.0f / 4.0f, -1.0f / 4.0f, 0.0f}, colour_bottom},
11609 {{eps - 1.0f / 4.0f, 1.0f / 4.0f, 0.0f}, colour_bottom},
11610 {{eps - 0.0f / 4.0f, -1.0f / 4.0f, 0.0f}, colour_bottom},
11612 nudge_left_tris[] =
11614 {{-eps - 2.0f / 4.0f, -1.0f / 4.0f, 0.0f}, colour_left},
11615 {{-eps - 2.0f / 4.0f, 3.0f / 4.0f, 0.0f}, colour_left},
11616 {{-eps - 1.0f / 4.0f, 1.0f / 4.0f, 0.0f}, colour_left},
11618 /* top */
11619 {{-eps - 1.0f / 4.0f, 1.0f / 4.0f, 0.0f}, colour_top},
11620 {{-eps - 2.0f / 4.0f, 3.0f / 4.0f, 0.0f}, colour_top},
11621 {{-eps - 0.0f / 4.0f, 3.0f / 4.0f, 0.0f}, colour_top},
11623 /* right */
11624 {{-eps - 0.0f / 4.0f, -1.0f / 4.0f, 0.0f}, colour_right},
11625 {{-eps - 1.0f / 4.0f, 1.0f / 4.0f, 0.0f}, colour_right},
11626 {{-eps - 0.0f / 4.0f, 3.0f / 4.0f, 0.0f}, colour_right},
11628 /* bottom */
11629 {{-eps - 2.0f / 4.0f, -1.0f / 4.0f, 0.0f}, colour_bottom},
11630 {{-eps - 1.0f / 4.0f, 1.0f / 4.0f, 0.0f}, colour_bottom},
11631 {{-eps - 0.0f / 4.0f, -1.0f / 4.0f, 0.0f}, colour_bottom},
11633 nudge_top_tris[] =
11635 /* left */
11636 {{-2.0f / 4.0f, eps - 1.0f / 4.0f, 0.0f}, colour_left},
11637 {{-2.0f / 4.0f, eps + 3.0f / 4.0f, 0.0f}, colour_left},
11638 {{-1.0f / 4.0f, eps + 1.0f / 4.0f, 0.0f}, colour_left},
11640 /* top */
11641 {{-1.0f / 4.0f, eps + 1.0f / 4.0f, 0.0f}, colour_top},
11642 {{-2.0f / 4.0f, eps + 3.0f / 4.0f, 0.0f}, colour_top},
11643 {{ 0.0f / 4.0f, eps + 3.0f / 4.0f, 0.0f}, colour_top},
11645 /* right */
11646 {{ 0.0f / 4.0f, eps - 1.0f / 4.0f, 0.0f}, colour_right},
11647 {{-1.0f / 4.0f, eps + 1.0f / 4.0f, 0.0f}, colour_right},
11648 {{ 0.0f / 4.0f, eps + 3.0f / 4.0f, 0.0f}, colour_right},
11650 /* bottom */
11651 {{-2.0f / 4.0f, eps - 1.0f / 4.0f, 0.0f}, colour_bottom},
11652 {{-1.0f / 4.0f, eps + 1.0f / 4.0f, 0.0f}, colour_bottom},
11653 {{ 0.0f / 4.0f, eps - 1.0f / 4.0f, 0.0f}, colour_bottom},
11655 nudge_bottom_tris[] =
11657 /* left */
11658 {{-2.0f / 4.0f, -eps - 1.0f / 4.0f, 0.0f}, colour_left},
11659 {{-2.0f / 4.0f, -eps + 3.0f / 4.0f, 0.0f}, colour_left},
11660 {{-1.0f / 4.0f, -eps + 1.0f / 4.0f, 0.0f}, colour_left},
11662 /* top */
11663 {{-1.0f / 4.0f, -eps + 1.0f / 4.0f, 0.0f}, colour_top},
11664 {{-2.0f / 4.0f, -eps + 3.0f / 4.0f, 0.0f}, colour_top},
11665 {{ 0.0f / 4.0f, -eps + 3.0f / 4.0f, 0.0f}, colour_top},
11667 /* right */
11668 {{ 0.0f / 4.0f, -eps - 1.0f / 4.0f, 0.0f}, colour_right},
11669 {{-1.0f / 4.0f, -eps + 1.0f / 4.0f, 0.0f}, colour_right},
11670 {{ 0.0f / 4.0f, -eps + 3.0f / 4.0f, 0.0f}, colour_right},
11672 /* bottom */
11673 {{-2.0f / 4.0f, -eps - 1.0f / 4.0f, 0.0f}, colour_bottom},
11674 {{-1.0f / 4.0f, -eps + 1.0f / 4.0f, 0.0f}, colour_bottom},
11675 {{ 0.0f / 4.0f, -eps - 1.0f / 4.0f, 0.0f}, colour_bottom},
11678 const struct
11680 struct vec4 position;
11681 DWORD diffuse;
11683 center_tris_t[] =
11685 /* left */
11686 {{ 1.5f, 1.5f, 0.0f, 1.0f}, colour_left},
11687 {{ 2.5f, 3.5f, 0.0f, 1.0f}, colour_left},
11688 {{ 1.5f, 5.5f, 0.0f, 1.0f}, colour_left},
11690 /* top */
11691 {{ 1.5f, 1.5f, 0.0f, 1.0f}, colour_top},
11692 {{ 3.5f, 1.5f, 0.0f, 1.0f}, colour_top},
11693 {{ 2.5f, 3.5f, 0.0f, 1.0f}, colour_top},
11695 /* right */
11696 {{ 3.5f, 1.5f, 0.0f, 1.0f}, colour_right},
11697 {{ 3.5f, 5.5f, 0.0f, 1.0f}, colour_right},
11698 {{ 2.5f, 3.5f, 0.0f, 1.0f}, colour_right},
11700 /* bottom */
11701 {{ 2.5f, 3.5f, 0.0f, 1.0f}, colour_bottom},
11702 {{ 3.5f, 5.5f, 0.0f, 1.0f}, colour_bottom},
11703 {{ 1.5f, 5.5f, 0.0f, 1.0f}, colour_bottom},
11705 edge_tris_t[] =
11707 /* left */
11708 {{ 2.0f, 1.0f, 0.0f, 1.0f}, colour_left},
11709 {{ 3.0f, 3.0f, 0.0f, 1.0f}, colour_left},
11710 {{ 2.0f, 5.0f, 0.0f, 1.0f}, colour_left},
11712 /* top */
11713 {{ 2.0f, 1.0f, 0.0f, 1.0f}, colour_top},
11714 {{ 4.0f, 1.0f, 0.0f, 1.0f}, colour_top},
11715 {{ 3.0f, 3.0f, 0.0f, 1.0f}, colour_top},
11717 /* right */
11718 {{ 4.0f, 1.0f, 0.0f, 1.0f}, colour_right},
11719 {{ 4.0f, 5.0f, 0.0f, 1.0f}, colour_right},
11720 {{ 3.0f, 3.0f, 0.0f, 1.0f}, colour_right},
11722 /* bottom */
11723 {{ 3.0f, 3.0f, 0.0f, 1.0f}, colour_bottom},
11724 {{ 4.0f, 5.0f, 0.0f, 1.0f}, colour_bottom},
11725 {{ 2.0f, 5.0f, 0.0f, 1.0f}, colour_bottom},
11728 const struct
11730 const void *geometry;
11731 size_t stride;
11732 DWORD fvf;
11733 const char *expected[8];
11735 tests[] =
11738 center_tris,
11739 sizeof(center_tris[0]),
11740 D3DFVF_XYZ | D3DFVF_DIFFUSE,
11742 " ",
11743 " ",
11744 " TT ",
11745 " LR ",
11746 " LR ",
11747 " BB ",
11748 " ",
11753 edge_tris,
11754 sizeof(edge_tris[0]),
11755 D3DFVF_XYZ | D3DFVF_DIFFUSE,
11757 " ",
11758 " TT ",
11759 " LT ",
11760 " LR ",
11761 " LB ",
11762 " ",
11763 " ",
11768 nudge_right_tris,
11769 sizeof(nudge_right_tris[0]),
11770 D3DFVF_XYZ | D3DFVF_DIFFUSE,
11772 " ",
11773 " TT ",
11774 " TR ",
11775 " LR ",
11776 " BR ",
11777 " ",
11778 " ",
11783 nudge_left_tris,
11784 sizeof(nudge_left_tris[0]),
11785 D3DFVF_XYZ | D3DFVF_DIFFUSE,
11787 " ",
11788 " TT ",
11789 " LT ",
11790 " LR ",
11791 " LB ",
11792 " ",
11793 " ",
11798 nudge_top_tris,
11799 sizeof(nudge_top_tris[0]),
11800 D3DFVF_XYZ | D3DFVF_DIFFUSE,
11802 " ",
11803 " LT ",
11804 " LT ",
11805 " LB ",
11806 " LB ",
11807 " ",
11808 " ",
11813 nudge_bottom_tris,
11814 sizeof(nudge_bottom_tris[0]),
11815 D3DFVF_XYZ | D3DFVF_DIFFUSE,
11817 " ",
11818 " ",
11819 " LT ",
11820 " Lt ",
11821 " LB ",
11822 " lB ",
11823 " ",
11828 center_tris_t,
11829 sizeof(center_tris_t[0]),
11830 D3DFVF_XYZRHW | D3DFVF_DIFFUSE,
11832 " ",
11833 " ",
11834 " TT ",
11835 " LR ",
11836 " LR ",
11837 " BB ",
11838 " ",
11843 edge_tris_t,
11844 sizeof(edge_tris_t[0]),
11845 D3DFVF_XYZRHW | D3DFVF_DIFFUSE,
11847 " ",
11848 " TT ",
11849 " LT ",
11850 " LR ",
11851 " LB ",
11852 " ",
11853 " ",
11859 window = create_window();
11860 d3d = Direct3DCreate8(D3D_SDK_VERSION);
11861 ok(!!d3d, "Failed to create a D3D object.\n");
11863 if (!(device = create_device(d3d, window, window, TRUE)))
11865 skip("Failed to create a 3D device.\n");
11866 IDirect3D8_Release(d3d);
11867 DestroyWindow(window);
11868 return;
11871 hr = IDirect3DDevice8_CreateRenderTarget(device, vp_size, vp_size,
11872 D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, FALSE, &rt);
11873 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11874 hr = IDirect3DDevice8_GetBackBuffer(device, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
11875 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11877 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
11878 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11879 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
11881 hr = IDirect3DDevice8_CreateVertexShader(device, decl, vs_code, &shader, 0);
11882 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11884 else
11885 skip("Skipping vertex shader codepath in filling convention test.\n");
11887 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11888 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11889 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
11890 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11892 for (i = 0; i < ARRAY_SIZE(tests); ++i)
11894 /* Run tests with shader and fixed function vertex processing if shaders are
11895 * supported. There's no point in running the XYZRHW tests with a VS though. */
11896 if (shader && ((tests[i].fvf & D3DFVF_POSITION_MASK) == D3DFVF_XYZ))
11897 j = 0;
11898 else
11899 j = 2;
11901 for (; j < 4; ++j)
11903 cur = (j & 1) ? rt : backbuffer;
11905 hr = IDirect3DDevice8_SetVertexShader(device, (j & 2) ? tests[i].fvf : shader);
11906 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11908 hr = IDirect3DDevice8_SetRenderTarget(device, cur, NULL);
11909 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11910 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, colour_clear, 0.0f, 0);
11911 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11912 hr = IDirect3DDevice8_SetViewport(device, &vp);
11913 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11915 hr = IDirect3DDevice8_BeginScene(device);
11916 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11917 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, tests[i].geometry, tests[i].stride);
11918 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11919 hr = IDirect3DDevice8_EndScene(device);
11920 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11922 get_surface_readback(cur, &rb);
11923 for (y = 0; y < 8; y++)
11925 for (x = 0; x < 8; x++)
11927 todo = FALSE;
11928 switch (tests[i].expected[y][x])
11930 case 'l': todo = TRUE;
11931 case 'L':
11932 expected = colour_left;
11933 break;
11934 case 't': todo = TRUE;
11935 case 'T':
11936 expected = colour_top;
11937 break;
11938 case 'r': todo = TRUE;
11939 case 'R':
11940 expected = colour_right;
11941 break;
11942 case 'b': todo = TRUE;
11943 case 'B':
11944 expected = colour_bottom;
11945 break;
11946 case ' ':
11947 expected = colour_clear;
11948 break;
11949 default:
11950 ok(0, "Unexpected entry in expected test char\n");
11951 expected = 0xdeadbeef;
11953 colour = get_readback_color(&rb, x, y);
11954 /* The nudge-to-bottom test fails on cards that give us a bottom-left
11955 * filling convention. The cause isn't the bottom part of the filling
11956 * convention, but because wined3d will nudge geometry to the left to
11957 * keep diagonals (the 'R' in test case 'edge_tris') intact. */
11958 todo_wine_if(todo && !color_match(colour, expected, 1))
11959 ok(color_match(colour, expected, 1), "Got unexpected colour %08x, %ux%u, case %u, j %u.\n",
11960 colour, x, y, i, j);
11963 release_surface_readback(&rb);
11965 /* IDirect3DDevice8::CopyRects can't stretch, so don't bother making the offscreen surface
11966 * visible. Use the d3d9 test if you need to see visual output. */
11967 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
11968 ok(hr == D3D_OK, "Got unexpected hr %#lx.\n", hr);
11972 if (shader)
11973 IDirect3DDevice8_DeleteVertexShader(device, shader);
11974 IDirect3DSurface8_Release(backbuffer);
11975 IDirect3DSurface8_Release(rt);
11976 refcount = IDirect3DDevice8_Release(device);
11977 ok(!refcount, "Device has %lu references left.\n", refcount);
11978 IDirect3D8_Release(d3d);
11979 DestroyWindow(window);
11982 START_TEST(visual)
11984 D3DADAPTER_IDENTIFIER8 identifier;
11985 IDirect3D8 *d3d;
11986 HRESULT hr;
11988 if (!(d3d = Direct3DCreate8(D3D_SDK_VERSION)))
11990 skip("Failed to create D3D8 object.\n");
11991 return;
11994 memset(&identifier, 0, sizeof(identifier));
11995 hr = IDirect3D8_GetAdapterIdentifier(d3d, D3DADAPTER_DEFAULT, 0, &identifier);
11996 ok(SUCCEEDED(hr), "Failed to get adapter identifier, hr %#lx.\n", hr);
11997 trace("Driver string: \"%s\"\n", identifier.Driver);
11998 trace("Description string: \"%s\"\n", identifier.Description);
11999 /* Only Windows XP's default VGA driver should have an empty description */
12000 ok(identifier.Description[0] || broken(!strcmp(identifier.Driver, "vga.dll")), "Empty driver description.\n");
12001 trace("Driver version %d.%d.%d.%d\n",
12002 HIWORD(U(identifier.DriverVersion).HighPart), LOWORD(U(identifier.DriverVersion).HighPart),
12003 HIWORD(U(identifier.DriverVersion).LowPart), LOWORD(U(identifier.DriverVersion).LowPart));
12005 IDirect3D8_Release(d3d);
12007 test_sanity();
12008 depth_clamp_test();
12009 lighting_test();
12010 test_specular_lighting();
12011 clear_test();
12012 fog_test();
12013 z_range_test();
12014 offscreen_test();
12015 test_blend();
12016 test_scalar_instructions();
12017 fog_with_shader_test();
12018 cnd_test();
12019 p8_texture_test();
12020 texop_test();
12021 depth_buffer_test();
12022 depth_buffer2_test();
12023 intz_test();
12024 shadow_test();
12025 multisample_copy_rects_test();
12026 zenable_test();
12027 resz_test();
12028 fog_special_test();
12029 volume_dxtn_test();
12030 volume_v16u16_test();
12031 add_dirty_rect_test();
12032 test_buffer_no_dirty_update();
12033 test_3dc_formats();
12034 test_fog_interpolation();
12035 test_negative_fixedfunction_fog();
12036 test_table_fog_zw();
12037 test_signed_formats();
12038 test_updatetexture();
12039 test_pointsize();
12040 test_multisample_mismatch();
12041 test_texcoordindex();
12042 test_vshader_input();
12043 test_fixed_function_fvf();
12044 test_flip();
12045 test_uninitialized_varyings();
12046 test_shademode();
12047 test_multisample_init();
12048 test_texture_blending();
12049 test_color_clamping();
12050 test_edge_antialiasing_blending();
12051 test_max_index16();
12052 test_backbuffer_resize();
12053 test_drawindexedprimitiveup();
12054 test_map_synchronisation();
12055 test_viewport();
12056 test_color_vertex();
12057 test_sysmem_draw();
12058 test_alphatest();
12059 test_desktop_window();
12060 test_sample_mask();
12061 test_dynamic_map_synchronization();
12062 test_filling_convention();