d3d8/tests: Accept new WARP test failure in test_updatetexture().
[wine.git] / dlls / d3d8 / tests / visual.c
blobb7f6dd62e9c7e1a43bcd3f43df227713fd5c5f6a
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_rt_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 %#x.\n", hr);
114 hr = IDirect3DSurface8_GetDesc(surface, &desc);
115 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
116 hr = IDirect3DDevice8_CreateTexture(device, desc.Width, desc.Height, 1, 0, desc.Format, D3DPOOL_SYSTEMMEM, &tex);
117 if (FAILED(hr) || !tex)
119 trace("Can't create an offscreen plain surface to read the render target data, hr %#x.\n", hr);
120 goto error;
122 hr = IDirect3DTexture8_GetSurfaceLevel(tex, 0, &rb->surface);
123 if (FAILED(hr))
125 trace("Can't get surface from texture, hr %#x.\n", hr);
126 goto error;
128 hr = IDirect3DDevice8_CopyRects(device, surface, NULL, 0, rb->surface, NULL);
129 if (FAILED(hr))
131 trace("Can't read the render target, hr %#x.\n", hr);
132 goto error;
134 hr = IDirect3DSurface8_LockRect(rb->surface, &rb->locked_rect, NULL, D3DLOCK_READONLY);
135 if (FAILED(hr))
137 trace("Can't lock the offscreen surface, hr %#x.\n", hr);
138 goto error;
140 IDirect3DTexture8_Release(tex);
141 IDirect3DDevice8_Release(device);
142 return;
144 error:
145 if (rb->surface)
146 IDirect3DSurface8_Release(rb->surface);
147 rb->surface = NULL;
148 if (tex)
149 IDirect3DTexture8_Release(tex);
150 IDirect3DDevice8_Release(device);
153 static DWORD get_readback_color(struct surface_readback *rb, unsigned int x, unsigned int y)
155 return rb->locked_rect.pBits
156 ? ((DWORD *)rb->locked_rect.pBits)[y * rb->locked_rect.Pitch / sizeof(DWORD) + x] : 0xdeadbeef;
159 static void release_surface_readback(struct surface_readback *rb)
161 HRESULT hr;
163 if (!rb->surface)
164 return;
165 if (rb->locked_rect.pBits && FAILED(hr = IDirect3DSurface8_UnlockRect(rb->surface)))
166 trace("Can't unlock the offscreen surface, hr %#x.\n", hr);
167 IDirect3DSurface8_Release(rb->surface);
170 static DWORD getPixelColor(IDirect3DDevice8 *device, UINT x, UINT y)
172 DWORD ret;
173 IDirect3DSurface8 *rt;
174 struct surface_readback rb;
175 HRESULT hr;
177 hr = IDirect3DDevice8_GetRenderTarget(device, &rt);
178 if (FAILED(hr))
180 trace("Can't get the render target, hr %#x.\n", hr);
181 return 0xdeadbeef;
184 get_rt_readback(rt, &rb);
185 /* Remove the X channel for now. DirectX and OpenGL have different ideas how to treat it apparently, and it isn't
186 * really important for these tests
188 ret = get_readback_color(&rb, x, y) & 0x00ffffff;
189 release_surface_readback(&rb);
191 IDirect3DSurface8_Release(rt);
192 return ret;
195 static D3DCOLOR get_surface_color(IDirect3DSurface8 *surface, UINT x, UINT y)
197 DWORD color;
198 HRESULT hr;
199 D3DSURFACE_DESC desc;
200 RECT rectToLock = {x, y, x+1, y+1};
201 D3DLOCKED_RECT lockedRect;
203 hr = IDirect3DSurface8_GetDesc(surface, &desc);
204 ok(SUCCEEDED(hr), "Failed to get surface description, hr=%#x.\n", hr);
206 hr = IDirect3DSurface8_LockRect(surface, &lockedRect, &rectToLock, D3DLOCK_READONLY);
207 ok(SUCCEEDED(hr), "Failed to lock surface, hr=%#x.\n", hr);
209 switch(desc.Format)
211 case D3DFMT_A8R8G8B8:
212 color = ((D3DCOLOR *)lockedRect.pBits)[0];
213 break;
215 default:
216 trace("Error: unknown surface format: %u.\n", desc.Format);
217 color = 0xdeadbeef;
218 break;
221 hr = IDirect3DSurface8_UnlockRect(surface);
222 ok(SUCCEEDED(hr), "Failed to unlock surface, hr=%#x.\n", hr);
224 return color;
227 static void check_rect(struct surface_readback *rb, RECT r, const char *message)
229 LONG x_coords[2][2] =
231 {r.left - 1, r.left + 1},
232 {r.right + 1, r.right - 1},
234 LONG y_coords[2][2] =
236 {r.top - 1, r.top + 1},
237 {r.bottom + 1, r.bottom - 1}
239 unsigned int i, j, x_side, y_side;
240 DWORD color;
241 LONG x, y;
243 for (i = 0; i < 2; ++i)
245 for (j = 0; j < 2; ++j)
247 for (x_side = 0; x_side < 2; ++x_side)
249 for (y_side = 0; y_side < 2; ++y_side)
251 DWORD expected = (x_side == 1 && y_side == 1) ? 0xffffffff : 0xff000000;
253 x = x_coords[i][x_side];
254 y = y_coords[j][y_side];
255 if (x < 0 || x >= 640 || y < 0 || y >= 480)
256 continue;
257 color = get_readback_color(rb, x, y);
258 ok(color == expected, "%s: Pixel (%d, %d) has color %08x, expected %08x.\n",
259 message, x, y, color, expected);
266 #define check_rt_color(a, b) check_rt_color_(__LINE__, a, b)
267 static void check_rt_color_(unsigned int line, IDirect3DSurface8 *rt, D3DCOLOR expected_color)
269 D3DCOLOR color = 0xdeadbeef;
270 struct surface_readback rb;
271 D3DSURFACE_DESC desc;
272 unsigned int x, y;
273 HRESULT hr;
275 hr = IDirect3DSurface8_GetDesc(rt, &desc);
276 ok_(__FILE__, line)(hr == S_OK, "Failed to get surface desc, hr %#x.\n", hr);
278 get_rt_readback(rt, &rb);
279 for (y = 0; y < desc.Height; ++y)
281 for (x = 0; x < desc.Width; ++x)
283 color = get_readback_color(&rb, x, y) & 0x00ffffff;
284 if (color != expected_color)
285 break;
287 if (color != expected_color)
288 break;
290 release_surface_readback(&rb);
291 ok_(__FILE__, line)(color == expected_color, "Got unexpected color 0x%08x.\n", color);
294 static IDirect3DDevice8 *create_device(IDirect3D8 *d3d, HWND device_window, HWND focus_window, BOOL windowed)
296 D3DPRESENT_PARAMETERS present_parameters = {0};
297 IDirect3DDevice8 *device;
299 present_parameters.Windowed = windowed;
300 present_parameters.hDeviceWindow = device_window;
301 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
302 present_parameters.BackBufferWidth = 640;
303 present_parameters.BackBufferHeight = 480;
304 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
305 present_parameters.EnableAutoDepthStencil = TRUE;
306 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
308 if (SUCCEEDED(IDirect3D8_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, focus_window,
309 D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device)))
310 return device;
312 return NULL;
315 static void test_sanity(void)
317 IDirect3DDevice8 *device;
318 IDirect3D8 *d3d;
319 D3DCOLOR color;
320 ULONG refcount;
321 HWND window;
322 HRESULT hr;
324 window = create_window();
325 d3d = Direct3DCreate8(D3D_SDK_VERSION);
326 ok(!!d3d, "Failed to create a D3D object.\n");
327 if (!(device = create_device(d3d, window, window, TRUE)))
329 skip("Failed to create a D3D device, skipping tests.\n");
330 goto done;
333 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 1.0f, 0);
334 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
335 color = getPixelColor(device, 1, 1);
336 ok(color == 0x00ff0000, "Got unexpected color 0x%08x.\n", color);
338 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
339 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
341 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ddee, 1.0f, 0);
342 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
343 color = getPixelColor(device, 639, 479);
344 ok(color == 0x0000ddee, "Got unexpected color 0x%08x.\n", color);
346 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
347 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
349 refcount = IDirect3DDevice8_Release(device);
350 ok(!refcount, "Device has %u references left.\n", refcount);
351 done:
352 IDirect3D8_Release(d3d);
353 DestroyWindow(window);
356 static void lighting_test(void)
358 DWORD nfvf = D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_NORMAL;
359 DWORD fvf = D3DFVF_XYZ | D3DFVF_DIFFUSE;
360 IDirect3DDevice8 *device;
361 IDirect3D8 *d3d;
362 D3DCOLOR color;
363 ULONG refcount;
364 HWND window;
365 HRESULT hr;
366 unsigned int i;
368 static const struct
370 struct vec3 position;
371 DWORD diffuse;
373 unlitquad[] =
375 {{-1.0f, -1.0f, 0.1f}, 0xffff0000},
376 {{-1.0f, 0.0f, 0.1f}, 0xffff0000},
377 {{ 0.0f, 0.0f, 0.1f}, 0xffff0000},
378 {{ 0.0f, -1.0f, 0.1f}, 0xffff0000},
380 litquad[] =
382 {{-1.0f, 0.0f, 0.1f}, 0xff00ff00},
383 {{-1.0f, 1.0f, 0.1f}, 0xff00ff00},
384 {{ 0.0f, 1.0f, 0.1f}, 0xff00ff00},
385 {{ 0.0f, 0.0f, 0.1f}, 0xff00ff00},
387 static const struct
389 struct vec3 position;
390 struct vec3 normal;
391 DWORD diffuse;
393 unlitnquad[] =
395 {{0.0f, -1.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xff0000ff},
396 {{0.0f, 0.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xff0000ff},
397 {{1.0f, 0.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xff0000ff},
398 {{1.0f, -1.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xff0000ff},
400 litnquad[] =
402 {{0.0f, 0.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xffffff00},
403 {{0.0f, 1.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xffffff00},
404 {{1.0f, 1.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xffffff00},
405 {{1.0f, 0.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xffffff00},
407 nquad[] =
409 {{-1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
410 {{-1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
411 {{ 1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
412 {{ 1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
414 rotatedquad[] =
416 {{-10.0f, -11.0f, 11.0f}, {-1.0f, 0.0f, 0.0f}, 0xff0000ff},
417 {{-10.0f, -9.0f, 11.0f}, {-1.0f, 0.0f, 0.0f}, 0xff0000ff},
418 {{-10.0f, -9.0f, 9.0f}, {-1.0f, 0.0f, 0.0f}, 0xff0000ff},
419 {{-10.0f, -11.0f, 9.0f}, {-1.0f, 0.0f, 0.0f}, 0xff0000ff},
421 translatedquad[] =
423 {{-11.0f, -11.0f, -10.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
424 {{-11.0f, -9.0f, -10.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
425 {{ -9.0f, -9.0f, -10.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
426 {{ -9.0f, -11.0f, -10.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
428 static const WORD indices[] = {0, 1, 2, 2, 3, 0};
429 static const D3DMATRIX mat =
431 1.0f, 0.0f, 0.0f, 0.0f,
432 0.0f, 1.0f, 0.0f, 0.0f,
433 0.0f, 0.0f, 1.0f, 0.0f,
434 0.0f, 0.0f, 0.0f, 1.0f,
435 }}},
436 mat_singular =
438 1.0f, 0.0f, 1.0f, 0.0f,
439 0.0f, 1.0f, 0.0f, 0.0f,
440 1.0f, 0.0f, 1.0f, 0.0f,
441 0.0f, 0.0f, 0.5f, 1.0f,
442 }}},
443 mat_transf =
445 0.0f, 0.0f, 1.0f, 0.0f,
446 0.0f, 1.0f, 0.0f, 0.0f,
447 -1.0f, 0.0f, 0.0f, 0.0f,
448 10.f, 10.0f, 10.0f, 1.0f,
449 }}},
450 mat_nonaffine =
452 1.0f, 0.0f, 0.0f, 0.0f,
453 0.0f, 1.0f, 0.0f, 0.0f,
454 0.0f, 0.0f, 1.0f, -1.0f,
455 10.f, 10.0f, 10.0f, 0.0f,
456 }}};
457 static const struct
459 const D3DMATRIX *world_matrix;
460 const void *quad;
461 unsigned int size;
462 DWORD expected, broken;
463 const char *message;
465 tests[] =
467 {&mat, nquad, sizeof(nquad[0]), 0x000000ff, 0xdeadbeef,
468 "Lit quad with light"},
469 /* Starting around Win10 20H? this test returns 0x00000000, but only
470 * in d3d8. In ddraw and d3d9 it works like in older windows versions.
471 * The behavior is GPU independent. */
472 {&mat_singular, nquad, sizeof(nquad[0]), 0x000000ff, 0x00000000,
473 "Lit quad with singular world matrix"},
474 {&mat_transf, rotatedquad, sizeof(rotatedquad[0]), 0x000000ff, 0xdeadbeef,
475 "Lit quad with transformation matrix"},
476 {&mat_nonaffine, translatedquad, sizeof(translatedquad[0]), 0x00000000, 0xdeadbeef,
477 "Lit quad with non-affine matrix"},
480 window = create_window();
481 d3d = Direct3DCreate8(D3D_SDK_VERSION);
482 ok(!!d3d, "Failed to create a D3D object.\n");
483 if (!(device = create_device(d3d, window, window, TRUE)))
485 skip("Failed to create a D3D device, skipping tests.\n");
486 goto done;
489 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
490 ok(hr == D3D_OK, "IDirect3DDevice8_Clear failed with %#08x\n", hr);
492 hr = IDirect3DDevice8_SetTransform(device, D3DTS_WORLDMATRIX(0), &mat);
493 ok(hr == D3D_OK, "IDirect3DDevice8_SetTransform returned %#08x\n", hr);
494 hr = IDirect3DDevice8_SetTransform(device, D3DTS_VIEW, &mat);
495 ok(hr == D3D_OK, "IDirect3DDevice8_SetTransform returned %#08x\n", hr);
496 hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, &mat);
497 ok(hr == D3D_OK, "IDirect3DDevice8_SetTransform returned %#08x\n", hr);
498 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, FALSE);
499 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %#08x\n", hr);
500 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, FALSE);
501 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %#08x\n", hr);
502 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
503 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %#08x\n", hr);
504 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
505 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %#08x\n", hr);
506 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
507 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed with %#08x\n", hr);
509 hr = IDirect3DDevice8_SetVertexShader(device, fvf);
510 ok(hr == D3D_OK, "IDirect3DDevice8_SetVertexShader returned %#08x\n", hr);
512 hr = IDirect3DDevice8_BeginScene(device);
513 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
515 /* No lights are defined... That means, lit vertices should be entirely black. */
516 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
517 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
518 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
519 2, indices, D3DFMT_INDEX16, unlitquad, sizeof(unlitquad[0]));
520 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
522 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, TRUE);
523 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
524 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
525 2, indices, D3DFMT_INDEX16, litquad, sizeof(litquad[0]));
526 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
528 hr = IDirect3DDevice8_SetVertexShader(device, nfvf);
529 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
531 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
532 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
533 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
534 2, indices, D3DFMT_INDEX16, unlitnquad, sizeof(unlitnquad[0]));
535 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
537 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, TRUE);
538 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
539 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
540 2, indices, D3DFMT_INDEX16, litnquad, sizeof(litnquad[0]));
541 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
543 hr = IDirect3DDevice8_EndScene(device);
544 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
546 color = getPixelColor(device, 160, 360); /* Lower left quad - unlit without normals */
547 ok(color == 0x00ff0000, "Unlit quad without normals has color 0x%08x, expected 0x00ff0000.\n", color);
548 color = getPixelColor(device, 160, 120); /* Upper left quad - lit without normals */
549 ok(color == 0x00000000, "Lit quad without normals has color 0x%08x, expected 0x00000000.\n", color);
550 color = getPixelColor(device, 480, 360); /* Lower right quad - unlit with normals */
551 ok(color == 0x000000ff, "Unlit quad with normals has color 0x%08x, expected 0x000000ff.\n", color);
552 color = getPixelColor(device, 480, 120); /* Upper right quad - lit with normals */
553 ok(color == 0x00000000, "Lit quad with normals has color 0x%08x, expected 0x00000000.\n", color);
555 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
557 hr = IDirect3DDevice8_LightEnable(device, 0, TRUE);
558 ok(SUCCEEDED(hr), "Failed to enable light 0, hr %#x.\n", hr);
560 for (i = 0; i < ARRAY_SIZE(tests); ++i)
562 hr = IDirect3DDevice8_SetTransform(device, D3DTS_WORLD, tests[i].world_matrix);
563 ok(SUCCEEDED(hr), "Failed to set world transform, hr %#x.\n", hr);
565 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
566 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
568 hr = IDirect3DDevice8_BeginScene(device);
569 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
571 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
572 2, indices, D3DFMT_INDEX16, tests[i].quad, tests[i].size);
573 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
575 hr = IDirect3DDevice8_EndScene(device);
576 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
578 color = getPixelColor(device, 320, 240);
579 ok(color == tests[i].expected || broken(color == tests[i].broken),
580 "%s has color 0x%08x.\n", tests[i].message, color);
583 refcount = IDirect3DDevice8_Release(device);
584 ok(!refcount, "Device has %u references left.\n", refcount);
585 done:
586 IDirect3D8_Release(d3d);
587 DestroyWindow(window);
590 static void test_specular_lighting(void)
592 static const unsigned int vertices_side = 5;
593 const unsigned int indices_count = (vertices_side - 1) * (vertices_side - 1) * 2 * 3;
594 static const DWORD fvf = D3DFVF_XYZ | D3DFVF_NORMAL;
595 static const D3DMATRIX mat =
597 1.0f, 0.0f, 0.0f, 0.0f,
598 0.0f, 1.0f, 0.0f, 0.0f,
599 0.0f, 0.0f, 1.0f, 0.0f,
600 0.0f, 0.0f, 0.0f, 1.0f,
601 }}};
602 static const D3DLIGHT8 directional =
604 D3DLIGHT_DIRECTIONAL,
605 {0.0f, 0.0f, 0.0f, 0.0f},
606 {1.0f, 1.0f, 1.0f, 0.0f},
607 {0.0f, 0.0f, 0.0f, 0.0f},
608 {0.0f, 0.0f, 0.0f},
609 {0.0f, 0.0f, 1.0f},
611 point =
613 D3DLIGHT_POINT,
614 {0.0f, 0.0f, 0.0f, 0.0f},
615 {1.0f, 1.0f, 1.0f, 0.0f},
616 {0.0f, 0.0f, 0.0f, 0.0f},
617 {0.0f, 0.0f, 0.0f},
618 {0.0f, 0.0f, 0.0f},
619 100.0f,
620 0.0f,
621 0.0f, 0.0f, 1.0f,
623 spot =
625 D3DLIGHT_SPOT,
626 {0.0f, 0.0f, 0.0f, 0.0f},
627 {1.0f, 1.0f, 1.0f, 0.0f},
628 {0.0f, 0.0f, 0.0f, 0.0f},
629 {0.0f, 0.0f, 0.0f},
630 {0.0f, 0.0f, 1.0f},
631 100.0f,
632 1.0f,
633 0.0f, 0.0f, 1.0f,
634 M_PI / 12.0f, M_PI / 3.0f
636 /* The chosen range value makes the test fail when using a manhattan
637 * distance metric vs the correct euclidean distance. */
638 point_range =
640 D3DLIGHT_POINT,
641 {0.0f, 0.0f, 0.0f, 0.0f},
642 {1.0f, 1.0f, 1.0f, 0.0f},
643 {0.0f, 0.0f, 0.0f, 0.0f},
644 {0.0f, 0.0f, 0.0f},
645 {0.0f, 0.0f, 0.0f},
646 1.2f,
647 0.0f,
648 0.0f, 0.0f, 1.0f,
650 point_side =
652 D3DLIGHT_POINT,
653 {0.0f, 0.0f, 0.0f, 0.0f},
654 {1.0f, 1.0f, 1.0f, 0.0f},
655 {0.0f, 0.0f, 0.0f, 0.0f},
656 {-1.1f, 0.0f, 1.1f},
657 {0.0f, 0.0f, 0.0f},
658 100.0f,
659 0.0f,
660 0.0f, 0.0f, 1.0f,
662 static const struct expected_color
664 unsigned int x, y;
665 D3DCOLOR color;
667 expected_directional[] =
669 {160, 120, 0x00ffffff},
670 {320, 120, 0x00ffffff},
671 {480, 120, 0x00ffffff},
672 {160, 240, 0x00ffffff},
673 {320, 240, 0x00ffffff},
674 {480, 240, 0x00ffffff},
675 {160, 360, 0x00ffffff},
676 {320, 360, 0x00ffffff},
677 {480, 360, 0x00ffffff},
679 expected_directional_local[] =
681 {160, 120, 0x003c3c3c},
682 {320, 120, 0x00717171},
683 {480, 120, 0x003c3c3c},
684 {160, 240, 0x00717171},
685 {320, 240, 0x00ffffff},
686 {480, 240, 0x00717171},
687 {160, 360, 0x003c3c3c},
688 {320, 360, 0x00717171},
689 {480, 360, 0x003c3c3c},
691 expected_point[] =
693 {160, 120, 0x00282828},
694 {320, 120, 0x005a5a5a},
695 {480, 120, 0x00282828},
696 {160, 240, 0x005a5a5a},
697 {320, 240, 0x00ffffff},
698 {480, 240, 0x005a5a5a},
699 {160, 360, 0x00282828},
700 {320, 360, 0x005a5a5a},
701 {480, 360, 0x00282828},
703 expected_point_local[] =
705 {160, 120, 0x00000000},
706 {320, 120, 0x00070707},
707 {480, 120, 0x00000000},
708 {160, 240, 0x00070707},
709 {320, 240, 0x00ffffff},
710 {480, 240, 0x00070707},
711 {160, 360, 0x00000000},
712 {320, 360, 0x00070707},
713 {480, 360, 0x00000000},
715 expected_spot[] =
717 {160, 120, 0x00000000},
718 {320, 120, 0x00141414},
719 {480, 120, 0x00000000},
720 {160, 240, 0x00141414},
721 {320, 240, 0x00ffffff},
722 {480, 240, 0x00141414},
723 {160, 360, 0x00000000},
724 {320, 360, 0x00141414},
725 {480, 360, 0x00000000},
727 expected_spot_local[] =
729 {160, 120, 0x00000000},
730 {320, 120, 0x00020202},
731 {480, 120, 0x00000000},
732 {160, 240, 0x00020202},
733 {320, 240, 0x00ffffff},
734 {480, 240, 0x00020202},
735 {160, 360, 0x00000000},
736 {320, 360, 0x00020202},
737 {480, 360, 0x00000000},
739 expected_point_range[] =
741 {160, 120, 0x00000000},
742 {320, 120, 0x005a5a5a},
743 {480, 120, 0x00000000},
744 {160, 240, 0x005a5a5a},
745 {320, 240, 0x00ffffff},
746 {480, 240, 0x005a5a5a},
747 {160, 360, 0x00000000},
748 {320, 360, 0x005a5a5a},
749 {480, 360, 0x00000000},
751 expected_point_side[] =
753 {160, 120, 0x00000000},
754 {320, 120, 0x00000000},
755 {480, 120, 0x00000000},
756 {160, 240, 0x00000000},
757 {320, 240, 0x00000000},
758 {480, 240, 0x00000000},
759 {160, 360, 0x00000000},
760 {320, 360, 0x00000000},
761 {480, 360, 0x00000000},
763 expected_directional_0[] =
765 {160, 120, 0x00ffffff},
766 {320, 120, 0x00ffffff},
767 {480, 120, 0x00ffffff},
768 {160, 240, 0x00ffffff},
769 {320, 240, 0x00ffffff},
770 {480, 240, 0x00ffffff},
771 {160, 360, 0x00ffffff},
772 {320, 360, 0x00ffffff},
773 {480, 360, 0x00ffffff},
775 expected_directional_local_0[] =
777 {160, 120, 0x00ffffff},
778 {320, 120, 0x00ffffff},
779 {480, 120, 0x00ffffff},
780 {160, 240, 0x00ffffff},
781 {320, 240, 0x00ffffff},
782 {480, 240, 0x00ffffff},
783 {160, 360, 0x00ffffff},
784 {320, 360, 0x00ffffff},
785 {480, 360, 0x00ffffff},
787 expected_point_0[] =
789 {160, 120, 0x00aaaaaa},
790 {320, 120, 0x00cccccc},
791 {480, 120, 0x00aaaaaa},
792 {160, 240, 0x00cccccc},
793 {320, 240, 0x00ffffff},
794 {480, 240, 0x00cccccc},
795 {160, 360, 0x00aaaaaa},
796 {320, 360, 0x00cccccc},
797 {480, 360, 0x00aaaaaa},
799 expected_spot_0[] =
801 {160, 120, 0x00000000},
802 {320, 120, 0x002e2e2e},
803 {480, 120, 0x00000000},
804 {160, 240, 0x002e2e2e},
805 {320, 240, 0x00ffffff},
806 {480, 240, 0x002e2e2e},
807 {160, 360, 0x00000000},
808 {320, 360, 0x002e2e2e},
809 {480, 360, 0x00000000},
811 expected_point_range_0[] =
813 {160, 120, 0x00000000},
814 {320, 120, 0x00cccccc},
815 {480, 120, 0x00000000},
816 {160, 240, 0x00cccccc},
817 {320, 240, 0x00ffffff},
818 {480, 240, 0x00cccccc},
819 {160, 360, 0x00000000},
820 {320, 360, 0x00cccccc},
821 {480, 360, 0x00000000},
823 static const struct
825 const D3DLIGHT8 *light;
826 BOOL local_viewer;
827 float specular_power;
828 const struct expected_color *expected;
829 unsigned int expected_count;
831 tests[] =
833 {&directional, FALSE, 30.0f, expected_directional, ARRAY_SIZE(expected_directional)},
834 {&directional, TRUE, 30.0f, expected_directional_local, ARRAY_SIZE(expected_directional_local)},
835 {&point, FALSE, 30.0f, expected_point, ARRAY_SIZE(expected_point)},
836 {&point, TRUE, 30.0f, expected_point_local, ARRAY_SIZE(expected_point_local)},
837 {&spot, FALSE, 30.0f, expected_spot, ARRAY_SIZE(expected_spot)},
838 {&spot, TRUE, 30.0f, expected_spot_local, ARRAY_SIZE(expected_spot_local)},
839 {&point_range, FALSE, 30.0f, expected_point_range, ARRAY_SIZE(expected_point_range)},
840 {&point_side, TRUE, 0.0f, expected_point_side, ARRAY_SIZE(expected_point_side)},
841 {&directional, FALSE, 0.0f, expected_directional_0, ARRAY_SIZE(expected_directional_0)},
842 {&directional, TRUE, 0.0f, expected_directional_local_0, ARRAY_SIZE(expected_directional_local_0)},
843 {&point, FALSE, 0.0f, expected_point_0, ARRAY_SIZE(expected_point_0)},
844 {&point, TRUE, 0.0f, expected_point_0, ARRAY_SIZE(expected_point_0)},
845 {&spot, FALSE, 0.0f, expected_spot_0, ARRAY_SIZE(expected_spot_0)},
846 {&spot, TRUE, 0.0f, expected_spot_0, ARRAY_SIZE(expected_spot_0)},
847 {&point_range, FALSE, 0.0f, expected_point_range_0, ARRAY_SIZE(expected_point_range_0)},
849 IDirect3DDevice8 *device;
850 D3DMATERIAL8 material;
851 IDirect3D8 *d3d;
852 D3DCOLOR color;
853 ULONG refcount;
854 HWND window;
855 HRESULT hr;
856 unsigned int i, j, x, y;
857 struct
859 struct vec3 position;
860 struct vec3 normal;
861 } *quad;
862 WORD *indices;
864 quad = HeapAlloc(GetProcessHeap(), 0, vertices_side * vertices_side * sizeof(*quad));
865 indices = HeapAlloc(GetProcessHeap(), 0, indices_count * sizeof(*indices));
866 for (i = 0, y = 0; y < vertices_side; ++y)
868 for (x = 0; x < vertices_side; ++x)
870 quad[i].position.x = x * 2.0f / (vertices_side - 1) - 1.0f;
871 quad[i].position.y = y * 2.0f / (vertices_side - 1) - 1.0f;
872 quad[i].position.z = 1.0f;
873 quad[i].normal.x = 0.0f;
874 quad[i].normal.y = 0.0f;
875 quad[i++].normal.z = -1.0f;
878 for (i = 0, y = 0; y < (vertices_side - 1); ++y)
880 for (x = 0; x < (vertices_side - 1); ++x)
882 indices[i++] = y * vertices_side + x + 1;
883 indices[i++] = y * vertices_side + x;
884 indices[i++] = (y + 1) * vertices_side + x;
885 indices[i++] = y * vertices_side + x + 1;
886 indices[i++] = (y + 1) * vertices_side + x;
887 indices[i++] = (y + 1) * vertices_side + x + 1;
891 window = create_window();
892 d3d = Direct3DCreate8(D3D_SDK_VERSION);
893 ok(!!d3d, "Failed to create a D3D object.\n");
894 if (!(device = create_device(d3d, window, window, TRUE)))
896 skip("Failed to create a D3D device, skipping tests.\n");
897 goto done;
900 hr = IDirect3DDevice8_SetTransform(device, D3DTS_WORLD, &mat);
901 ok(SUCCEEDED(hr), "Failed to set world transform, hr %#x.\n", hr);
902 hr = IDirect3DDevice8_SetTransform(device, D3DTS_VIEW, &mat);
903 ok(SUCCEEDED(hr), "Failed to set view transform, hr %#x.\n", hr);
904 hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, &mat);
905 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
906 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, FALSE);
907 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#x.\n", hr);
908 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, FALSE);
909 ok(SUCCEEDED(hr), "Failed to disable z test, hr %#x.\n", hr);
910 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
911 ok(SUCCEEDED(hr), "Failed to disable fog, hr %#x.\n", hr);
913 hr = IDirect3DDevice8_SetVertexShader(device, fvf);
914 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
916 hr = IDirect3DDevice8_LightEnable(device, 0, TRUE);
917 ok(SUCCEEDED(hr), "Failed to enable light 0, hr %#x.\n", hr);
918 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SPECULARENABLE, TRUE);
919 ok(SUCCEEDED(hr), "Failed to enable specular lighting, hr %#x.\n", hr);
921 for (i = 0; i < ARRAY_SIZE(tests); ++i)
923 hr = IDirect3DDevice8_SetLight(device, 0, tests[i].light);
924 ok(SUCCEEDED(hr), "Failed to set light parameters, hr %#x.\n", hr);
926 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LOCALVIEWER, tests[i].local_viewer);
927 ok(SUCCEEDED(hr), "Failed to set local viewer state, hr %#x.\n", hr);
929 memset(&material, 0, sizeof(material));
930 material.Specular.r = 1.0f;
931 material.Specular.g = 1.0f;
932 material.Specular.b = 1.0f;
933 material.Specular.a = 1.0f;
934 material.Power = tests[i].specular_power;
935 hr = IDirect3DDevice8_SetMaterial(device, &material);
936 ok(SUCCEEDED(hr), "Failed to set material, hr %#x.\n", hr);
938 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
939 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
941 hr = IDirect3DDevice8_BeginScene(device);
942 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
944 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST,
945 0, vertices_side * vertices_side, indices_count / 3, indices,
946 D3DFMT_INDEX16, quad, sizeof(quad[0]));
947 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
949 hr = IDirect3DDevice8_EndScene(device);
950 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
952 for (j = 0; j < tests[i].expected_count; ++j)
954 color = getPixelColor(device, tests[i].expected[j].x, tests[i].expected[j].y);
955 ok(color_match(color, tests[i].expected[j].color, 1),
956 "Expected color 0x%08x at location (%u, %u), got 0x%08x, case %u.\n",
957 tests[i].expected[j].color, tests[i].expected[j].x,
958 tests[i].expected[j].y, color, i);
962 refcount = IDirect3DDevice8_Release(device);
963 ok(!refcount, "Device has %u references left.\n", refcount);
964 done:
965 IDirect3D8_Release(d3d);
966 DestroyWindow(window);
967 HeapFree(GetProcessHeap(), 0, indices);
968 HeapFree(GetProcessHeap(), 0, quad);
971 static void clear_test(void)
973 /* Tests the correctness of clearing parameters */
974 D3DRECT rect_negneg, rect[2];
975 IDirect3DDevice8 *device;
976 IDirect3D8 *d3d;
977 D3DCOLOR color;
978 ULONG refcount;
979 HWND window;
980 HRESULT hr;
982 window = create_window();
983 d3d = Direct3DCreate8(D3D_SDK_VERSION);
984 ok(!!d3d, "Failed to create a D3D object.\n");
985 if (!(device = create_device(d3d, window, window, TRUE)))
987 skip("Failed to create a D3D device, skipping tests.\n");
988 goto done;
991 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
992 ok(hr == D3D_OK, "IDirect3DDevice8_Clear failed with %#08x\n", hr);
994 /* Positive x, negative y */
995 rect[0].x1 = 0;
996 rect[0].y1 = 480;
997 rect[0].x2 = 320;
998 rect[0].y2 = 240;
1000 /* Positive x, positive y */
1001 rect[1].x1 = 0;
1002 rect[1].y1 = 0;
1003 rect[1].x2 = 320;
1004 rect[1].y2 = 240;
1005 /* Clear 2 rectangles with one call. Shows that a positive value is returned, but the negative rectangle
1006 * is ignored, the positive is still cleared afterwards
1008 hr = IDirect3DDevice8_Clear(device, 2, rect, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1009 ok(hr == D3D_OK, "IDirect3DDevice8_Clear failed with %#08x\n", hr);
1011 /* negative x, negative y */
1012 rect_negneg.x1 = 640;
1013 rect_negneg.y1 = 240;
1014 rect_negneg.x2 = 320;
1015 rect_negneg.y2 = 0;
1016 hr = IDirect3DDevice8_Clear(device, 1, &rect_negneg, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
1017 ok(hr == D3D_OK, "IDirect3DDevice8_Clear failed with %#08x\n", hr);
1019 color = getPixelColor(device, 160, 360); /* lower left quad */
1020 ok(color == 0x00ffffff, "Clear rectangle 3(pos, neg) has color %08x\n", color);
1021 color = getPixelColor(device, 160, 120); /* upper left quad */
1022 ok(color == 0x00ff0000, "Clear rectangle 1(pos, pos) has color %08x\n", color);
1023 color = getPixelColor(device, 480, 360); /* lower right quad */
1024 ok(color == 0x00ffffff, "Clear rectangle 4(NULL) has color %08x\n", color);
1025 color = getPixelColor(device, 480, 120); /* upper right quad */
1026 ok(color == 0x00ffffff, "Clear rectangle 4(neg, neg) has color %08x\n", color);
1028 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
1030 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
1031 ok(SUCCEEDED(hr), "IDirect3DDevice8_Clear failed with %#08x\n", hr);
1033 rect[0].x1 = 0;
1034 rect[0].y1 = 0;
1035 rect[0].x2 = 640;
1036 rect[0].y2 = 480;
1037 hr = IDirect3DDevice8_Clear(device, 0, rect, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1038 ok(SUCCEEDED(hr), "IDirect3DDevice8_Clear failed with %#08x\n", hr);
1040 color = getPixelColor(device, 320, 240);
1041 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff), 1),
1042 "Clear with count = 0, rect != NULL has color %#08x\n", color);
1044 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
1046 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
1047 ok(SUCCEEDED(hr), "IDirect3DDevice8_Clear failed with %#08x\n", hr);
1048 hr = IDirect3DDevice8_Clear(device, 1, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
1049 ok(SUCCEEDED(hr), "IDirect3DDevice8_Clear failed with %#08x\n", hr);
1051 color = getPixelColor(device, 320, 240);
1052 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
1053 "Clear with count = 1, rect = NULL has color %#08x\n", color);
1055 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
1057 refcount = IDirect3DDevice8_Release(device);
1058 ok(!refcount, "Device has %u references left.\n", refcount);
1059 done:
1060 IDirect3D8_Release(d3d);
1061 DestroyWindow(window);
1064 static void fog_test(void)
1066 float start = 0.0f, end = 1.0f;
1067 IDirect3DDevice8 *device;
1068 IDirect3D8 *d3d;
1069 D3DCOLOR color;
1070 ULONG refcount;
1071 D3DCAPS8 caps;
1072 HWND window;
1073 HRESULT hr;
1075 /* Gets full z based fog with linear fog, no fog with specular color. */
1076 static const struct
1078 float x, y, z;
1079 D3DCOLOR diffuse;
1080 D3DCOLOR specular;
1082 untransformed_1[] =
1084 {-1.0f, -1.0f, 0.1f, 0xffff0000, 0xff000000},
1085 {-1.0f, 0.0f, 0.1f, 0xffff0000, 0xff000000},
1086 { 0.0f, 0.0f, 0.1f, 0xffff0000, 0xff000000},
1087 { 0.0f, -1.0f, 0.1f, 0xffff0000, 0xff000000},
1089 /* Ok, I am too lazy to deal with transform matrices. */
1090 untransformed_2[] =
1092 {-1.0f, 0.0f, 1.0f, 0xffff0000, 0xff000000},
1093 {-1.0f, 1.0f, 1.0f, 0xffff0000, 0xff000000},
1094 { 0.0f, 1.0f, 1.0f, 0xffff0000, 0xff000000},
1095 { 0.0f, 0.0f, 1.0f, 0xffff0000, 0xff000000},
1097 far_quad1[] =
1099 {-1.0f, -1.0f, 0.5f, 0xffff0000, 0xff000000},
1100 {-1.0f, 0.0f, 0.5f, 0xffff0000, 0xff000000},
1101 { 0.0f, 0.0f, 0.5f, 0xffff0000, 0xff000000},
1102 { 0.0f, -1.0f, 0.5f, 0xffff0000, 0xff000000},
1104 far_quad2[] =
1106 {-1.0f, 0.0f, 1.5f, 0xffff0000, 0xff000000},
1107 {-1.0f, 1.0f, 1.5f, 0xffff0000, 0xff000000},
1108 { 0.0f, 1.0f, 1.5f, 0xffff0000, 0xff000000},
1109 { 0.0f, 0.0f, 1.5f, 0xffff0000, 0xff000000},
1112 /* Untransformed ones. Give them a different diffuse color to make the
1113 * test look nicer. It also makes making sure that they are drawn
1114 * correctly easier. */
1115 static const struct
1117 float x, y, z, rhw;
1118 D3DCOLOR diffuse;
1119 D3DCOLOR specular;
1121 transformed_1[] =
1123 {320.0f, 0.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
1124 {640.0f, 0.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
1125 {640.0f, 240.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
1126 {320.0f, 240.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
1128 transformed_2[] =
1130 {320.0f, 240.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
1131 {640.0f, 240.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
1132 {640.0f, 480.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
1133 {320.0f, 480.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
1135 static const D3DMATRIX ident_mat =
1137 1.0f, 0.0f, 0.0f, 0.0f,
1138 0.0f, 1.0f, 0.0f, 0.0f,
1139 0.0f, 0.0f, 1.0f, 0.0f,
1140 0.0f, 0.0f, 0.0f, 1.0f,
1141 }}};
1142 static const D3DMATRIX world_mat1 =
1144 1.0f, 0.0f, 0.0f, 0.0f,
1145 0.0f, 1.0f, 0.0f, 0.0f,
1146 0.0f, 0.0f, 1.0f, 0.0f,
1147 0.0f, 0.0f, -0.5f, 1.0f,
1148 }}};
1149 static const D3DMATRIX world_mat2 =
1151 1.0f, 0.0f, 0.0f, 0.0f,
1152 0.0f, 1.0f, 0.0f, 0.0f,
1153 0.0f, 0.0f, 1.0f, 0.0f,
1154 0.0f, 0.0f, 1.0f, 1.0f,
1155 }}};
1156 static const D3DMATRIX proj_mat =
1158 1.0f, 0.0f, 0.0f, 0.0f,
1159 0.0f, 1.0f, 0.0f, 0.0f,
1160 0.0f, 0.0f, 1.0f, 0.0f,
1161 0.0f, 0.0f, -1.0f, 1.0f,
1162 }}};
1163 static const WORD Indices[] = {0, 1, 2, 2, 3, 0};
1165 window = create_window();
1166 d3d = Direct3DCreate8(D3D_SDK_VERSION);
1167 ok(!!d3d, "Failed to create a D3D object.\n");
1168 if (!(device = create_device(d3d, window, window, TRUE)))
1170 skip("Failed to create a D3D device, skipping tests.\n");
1171 goto done;
1174 memset(&caps, 0, sizeof(caps));
1175 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
1176 ok(hr == D3D_OK, "IDirect3DDevice8_GetDeviceCaps returned %08x\n", hr);
1177 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1178 ok(hr == D3D_OK, "IDirect3DDevice8_Clear returned %#08x\n", hr);
1180 /* Setup initial states: No lighting, fog on, fog color */
1181 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, FALSE);
1182 ok(SUCCEEDED(hr), "Failed to disable D3DRS_ZENABLE, hr %#x.\n", hr);
1183 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1184 ok(hr == D3D_OK, "Turning off lighting returned %#08x\n", hr);
1185 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
1186 ok(hr == D3D_OK, "Turning on fog calculations returned %#08x\n", hr);
1187 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
1188 ok(hr == D3D_OK, "Setting fog color returned %#08x\n", hr);
1189 /* Some of the tests seem to depend on the projection matrix explicitly
1190 * being set to an identity matrix, even though that's the default.
1191 * (AMD Radeon HD 6310, Windows 7) */
1192 hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, &ident_mat);
1193 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
1195 /* First test: Both table fog and vertex fog off */
1196 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1197 ok(hr == D3D_OK, "Turning off table fog returned %#08x\n", hr);
1198 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
1199 ok(hr == D3D_OK, "Turning off vertex fog returned %#08x\n", hr);
1201 /* Start = 0, end = 1. Should be default, but set them */
1202 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1203 ok(hr == D3D_OK, "Setting fog start returned %#08x\n", hr);
1204 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1205 ok(hr == D3D_OK, "Setting fog start returned %#08x\n", hr);
1207 hr = IDirect3DDevice8_BeginScene(device);
1208 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
1210 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1211 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
1212 /* Untransformed, vertex fog = NONE, table fog = NONE:
1213 * Read the fog weighting from the specular color. */
1214 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1215 2 /* PrimCount */, Indices, D3DFMT_INDEX16, untransformed_1, sizeof(untransformed_1[0]));
1216 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1218 /* This makes it use the Z value. */
1219 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1220 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
1221 /* Untransformed, vertex fog != none (or table fog != none):
1222 * Use the Z value as input into the equation. */
1223 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1224 2 /* PrimCount */, Indices, D3DFMT_INDEX16, untransformed_2, sizeof(untransformed_2[0]));
1225 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1227 /* Transformed vertices. */
1228 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1229 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
1230 /* Transformed, vertex fog != NONE, pixel fog == NONE:
1231 * Use specular color alpha component. */
1232 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1233 2 /* PrimCount */, Indices, D3DFMT_INDEX16, transformed_1, sizeof(transformed_1[0]));
1234 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1236 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
1237 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
1238 /* Transformed, table fog != none, vertex anything:
1239 * Use Z value as input to the fog equation. */
1240 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1241 2 /* PrimCount */, Indices, D3DFMT_INDEX16, transformed_2, sizeof(transformed_2[0]));
1242 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1244 hr = IDirect3DDevice8_EndScene(device);
1245 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
1247 color = getPixelColor(device, 160, 360);
1248 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xFF, 0x00, 0x00), 1),
1249 "Untransformed vertex with no table or vertex fog has color %08x\n", color);
1250 color = getPixelColor(device, 160, 120);
1251 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xFF, 0x00), 1),
1252 "Untransformed vertex with linear vertex fog has color %08x\n", color);
1253 color = getPixelColor(device, 480, 120);
1254 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xFF, 0xFF, 0x00), 1),
1255 "Transformed vertex with linear vertex fog has color %08x\n", color);
1256 color = getPixelColor(device, 480, 360);
1257 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xFF, 0x00), 1),
1258 "Transformed vertex with linear table fog has color %08x\n", color);
1260 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
1262 if (caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)
1264 /* A simple fog + non-identity world matrix test */
1265 hr = IDirect3DDevice8_SetTransform(device, D3DTS_WORLDMATRIX(0), &world_mat1);
1266 ok(hr == D3D_OK, "IDirect3DDevice8_SetTransform returned %#08x\n", hr);
1268 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
1269 ok(hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %#08x\n", hr);
1270 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
1271 ok(hr == D3D_OK, "Turning off vertex fog returned %#08x\n", hr);
1273 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1274 ok(hr == D3D_OK, "IDirect3DDevice8_Clear returned %#08x\n", hr);
1276 hr = IDirect3DDevice8_BeginScene(device);
1277 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
1278 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1279 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
1280 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
1281 2, Indices, D3DFMT_INDEX16, far_quad1, sizeof(far_quad1[0]));
1282 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1283 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
1284 2, Indices, D3DFMT_INDEX16, far_quad2, sizeof(far_quad2[0]));
1285 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1286 hr = IDirect3DDevice8_EndScene(device);
1287 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
1289 color = getPixelColor(device, 160, 360);
1290 ok(color_match(color, 0x00ff0000, 4), "Unfogged quad has color %08x\n", color);
1291 color = getPixelColor(device, 160, 120);
1292 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
1293 "Fogged out quad has color %08x\n", color);
1295 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
1297 /* Test fog behavior with an orthogonal (but not identity) projection matrix */
1298 hr = IDirect3DDevice8_SetTransform(device, D3DTS_WORLDMATRIX(0), &world_mat2);
1299 ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
1300 hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, &proj_mat);
1301 ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
1303 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1304 ok(hr == D3D_OK, "Clear returned %#08x\n", hr);
1306 hr = IDirect3DDevice8_BeginScene(device);
1307 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
1308 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1309 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
1310 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
1311 2, Indices, D3DFMT_INDEX16, untransformed_1, sizeof(untransformed_1[0]));
1312 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1313 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
1314 2, Indices, D3DFMT_INDEX16, untransformed_2, sizeof(untransformed_2[0]));
1315 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1316 hr = IDirect3DDevice8_EndScene(device);
1317 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
1319 color = getPixelColor(device, 160, 360);
1320 ok(color_match(color, 0x00e51900, 4), "Partially fogged quad has color %08x\n", color);
1321 color = getPixelColor(device, 160, 120);
1322 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
1323 "Fogged out quad has color %08x\n", color);
1325 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
1327 else
1329 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping some fog tests\n");
1332 refcount = IDirect3DDevice8_Release(device);
1333 ok(!refcount, "Device has %u references left.\n", refcount);
1334 done:
1335 IDirect3D8_Release(d3d);
1336 DestroyWindow(window);
1339 /* This tests fog in combination with shaders.
1340 * What's tested: linear fog (vertex and table) with pixel shader
1341 * linear table fog with non foggy vertex shader
1342 * vertex fog with foggy vertex shader, non-linear
1343 * fog with shader, non-linear fog with foggy shader,
1344 * linear table fog with foggy shader */
1345 static void fog_with_shader_test(void)
1347 /* Fill the null-shader entry with the FVF (SetVertexShader is "overloaded" on d3d8...) */
1348 DWORD vertex_shader[3] = {D3DFVF_XYZ | D3DFVF_DIFFUSE, 0, 0};
1349 DWORD pixel_shader[2] = {0, 0};
1350 IDirect3DDevice8 *device;
1351 unsigned int i, j;
1352 IDirect3D8 *d3d;
1353 D3DCOLOR color;
1354 ULONG refcount;
1355 D3DCAPS8 caps;
1356 HWND window;
1357 HRESULT hr;
1358 union
1360 float f;
1361 DWORD i;
1362 } start, end;
1364 /* Basic vertex shader without fog computation ("non foggy") */
1365 static const DWORD vertex_shader_code1[] =
1367 0xfffe0100, /* vs.1.0 */
1368 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1369 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
1370 0x0000ffff
1372 /* Basic vertex shader with reversed fog computation ("foggy") */
1373 static const DWORD vertex_shader_code2[] =
1375 0xfffe0100, /* vs.1.0 */
1376 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1377 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
1378 0x00000002, 0x800f0000, 0x90aa0000, 0xa0aa0000, /* add r0, v0.z, c0.z */
1379 0x00000005, 0xc00f0001, 0x80000000, 0xa0000000, /* mul oFog, r0.x, c0.x */
1380 0x0000ffff
1382 /* Basic pixel shader */
1383 static const DWORD pixel_shader_code[] =
1385 0xffff0101, /* ps_1_1 */
1386 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
1387 0x0000ffff
1389 static struct
1391 struct vec3 position;
1392 DWORD diffuse;
1394 quad[] =
1396 {{-1.0f, -1.0f, 0.0f}, 0xffff0000},
1397 {{-1.0f, 1.0f, 0.0f}, 0xffff0000},
1398 {{ 1.0f, -1.0f, 0.0f}, 0xffff0000},
1399 {{ 1.0f, 1.0f, 0.0f}, 0xffff0000},
1401 static const DWORD decl[] =
1403 D3DVSD_STREAM(0),
1404 D3DVSD_REG(0, D3DVSDT_FLOAT3), /* position, v0 */
1405 D3DVSD_REG(1, D3DVSDT_D3DCOLOR), /* diffuse color, v1 */
1406 D3DVSD_END()
1408 static const float vs_constant[4] = {-1.25f, 0.0f, -0.9f, 0.0f};
1409 /* This reference data was collected on a nVidia GeForce 7600GS
1410 * driver version 84.19 DirectX version 9.0c on Windows XP */
1411 static const struct test_data_t
1413 int vshader;
1414 int pshader;
1415 D3DFOGMODE vfog;
1416 D3DFOGMODE tfog;
1417 BOOL uninitialized_reg;
1418 unsigned int color[11];
1420 test_data[] =
1422 /* Only pixel shader */
1423 {0, 1, D3DFOG_NONE, D3DFOG_LINEAR, FALSE,
1424 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1425 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1426 {0, 1, D3DFOG_EXP, D3DFOG_LINEAR, FALSE,
1427 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1428 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1429 {0, 1, D3DFOG_EXP2, D3DFOG_LINEAR, FALSE,
1430 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1431 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1432 {0, 1, D3DFOG_LINEAR, D3DFOG_NONE, FALSE,
1433 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1434 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1435 {0, 1, D3DFOG_LINEAR, D3DFOG_LINEAR, FALSE,
1436 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1437 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1439 /* Vertex shader */
1440 {1, 0, D3DFOG_NONE, D3DFOG_NONE, TRUE,
1441 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1442 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1443 {1, 0, D3DFOG_NONE, D3DFOG_LINEAR, FALSE,
1444 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1445 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1446 {1, 0, D3DFOG_EXP, D3DFOG_LINEAR, FALSE,
1447 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1448 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1450 {1, 0, D3DFOG_EXP2, D3DFOG_LINEAR, FALSE,
1451 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1452 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1453 {1, 0, D3DFOG_LINEAR, D3DFOG_LINEAR, FALSE,
1454 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1455 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1457 /* Vertex shader and pixel shader */
1458 /* The next 4 tests would read the fog coord output, but it isn't available.
1459 * The result is a fully fogged quad, no matter what the Z coord is. */
1460 {1, 1, D3DFOG_NONE, D3DFOG_NONE, TRUE,
1461 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1462 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1463 {1, 1, D3DFOG_LINEAR, D3DFOG_NONE, TRUE,
1464 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1465 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1466 {1, 1, D3DFOG_EXP, D3DFOG_NONE, TRUE,
1467 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1468 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1469 {1, 1, D3DFOG_EXP2, D3DFOG_NONE, TRUE,
1470 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1471 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1473 /* These use the Z coordinate with linear table fog */
1474 {1, 1, D3DFOG_NONE, D3DFOG_LINEAR, FALSE,
1475 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1476 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1477 {1, 1, D3DFOG_EXP, D3DFOG_LINEAR, FALSE,
1478 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1479 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1480 {1, 1, D3DFOG_EXP2, D3DFOG_LINEAR, FALSE,
1481 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1482 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1483 {1, 1, D3DFOG_LINEAR, D3DFOG_LINEAR, FALSE,
1484 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1485 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1487 /* Non-linear table fog without fog coord */
1488 {1, 1, D3DFOG_NONE, D3DFOG_EXP, FALSE,
1489 {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
1490 0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
1491 {1, 1, D3DFOG_NONE, D3DFOG_EXP2, FALSE,
1492 {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
1493 0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
1495 /* These tests fail on older Nvidia drivers */
1496 /* Foggy vertex shader */
1497 {2, 0, D3DFOG_NONE, D3DFOG_NONE, FALSE,
1498 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1499 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1500 {2, 0, D3DFOG_EXP, D3DFOG_NONE, FALSE,
1501 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1502 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1503 {2, 0, D3DFOG_EXP2, D3DFOG_NONE, FALSE,
1504 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1505 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1506 {2, 0, D3DFOG_LINEAR, D3DFOG_NONE, FALSE,
1507 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1508 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1510 /* Foggy vertex shader and pixel shader. First 4 tests with vertex fog,
1511 * all using the fixed fog-coord linear fog */
1512 {2, 1, D3DFOG_NONE, D3DFOG_NONE, FALSE,
1513 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1514 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1515 {2, 1, D3DFOG_EXP, D3DFOG_NONE, FALSE,
1516 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1517 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1518 {2, 1, D3DFOG_EXP2, D3DFOG_NONE, FALSE,
1519 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1520 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1521 {2, 1, D3DFOG_LINEAR, D3DFOG_NONE, FALSE,
1522 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1523 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1525 /* These use table fog. Here the shader-provided fog coordinate is
1526 * ignored and the z coordinate used instead */
1527 {2, 1, D3DFOG_NONE, D3DFOG_EXP, FALSE,
1528 {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
1529 0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
1530 {2, 1, D3DFOG_NONE, D3DFOG_EXP2, FALSE,
1531 {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
1532 0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
1533 {2, 1, D3DFOG_NONE, D3DFOG_LINEAR, FALSE,
1534 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1535 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1537 static const D3DMATRIX identity =
1539 1.0f, 0.0f, 0.0f, 0.0f,
1540 0.0f, 1.0f, 0.0f, 0.0f,
1541 0.0f, 0.0f, 1.0f, 0.0f,
1542 0.0f, 0.0f, 0.0f, 1.0f,
1543 }}};
1545 window = create_window();
1546 d3d = Direct3DCreate8(D3D_SDK_VERSION);
1547 ok(!!d3d, "Failed to create a D3D object.\n");
1548 if (!(device = create_device(d3d, window, window, TRUE)))
1550 skip("Failed to create a D3D device, skipping tests.\n");
1551 goto done;
1554 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
1555 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
1556 if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1) || caps.PixelShaderVersion < D3DPS_VERSION(1, 1))
1558 skip("No vs_1_1 / ps_1_1 support, skipping tests.\n");
1559 IDirect3DDevice8_Release(device);
1560 goto done;
1563 /* NOTE: changing these values will not affect the tests with foggy vertex
1564 * shader, as the values are hardcoded in the shader constant. */
1565 start.f = 0.1f;
1566 end.f = 0.9f;
1568 /* Some of the tests seem to depend on the projection matrix explicitly
1569 * being set to an identity matrix, even though that's the default.
1570 * (AMD Radeon HD 6310, Windows 7) */
1571 hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, &identity);
1572 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
1574 hr = IDirect3DDevice8_CreateVertexShader(device, decl, vertex_shader_code1, &vertex_shader[1], 0);
1575 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1576 hr = IDirect3DDevice8_CreateVertexShader(device, decl, vertex_shader_code2, &vertex_shader[2], 0);
1577 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1578 hr = IDirect3DDevice8_CreatePixelShader(device, pixel_shader_code, &pixel_shader[1]);
1579 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1581 /* Set shader constant value */
1582 hr = IDirect3DDevice8_SetVertexShader(device, vertex_shader[2]);
1583 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1584 hr = IDirect3DDevice8_SetVertexShaderConstant(device, 0, vs_constant, 1);
1585 ok(hr == D3D_OK, "Setting vertex shader constant failed (%08x)\n", hr);
1587 /* Setup initial states: No lighting, fog on, fog color */
1588 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1589 ok(hr == D3D_OK, "Turning off lighting failed (%08x)\n", hr);
1590 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
1591 ok(hr == D3D_OK, "Turning on fog calculations failed (%08x)\n", hr);
1592 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
1593 ok(hr == D3D_OK, "Setting fog color failed (%08x)\n", hr);
1595 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1596 ok(hr == D3D_OK, "Turning off table fog failed (%08x)\n", hr);
1597 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
1598 ok(hr == D3D_OK, "Turning off vertex fog failed (%08x)\n", hr);
1600 /* Use fogtart = 0.1 and end = 0.9 to test behavior outside the fog transition phase, too */
1601 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGSTART, start.i);
1602 ok(hr == D3D_OK, "Setting fog start failed (%08x)\n", hr);
1603 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGEND, end.i);
1604 ok(hr == D3D_OK, "Setting fog end failed (%08x)\n", hr);
1606 for (i = 0; i < ARRAY_SIZE(test_data); ++i)
1608 hr = IDirect3DDevice8_SetVertexShader(device, vertex_shader[test_data[i].vshader]);
1609 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1610 hr = IDirect3DDevice8_SetPixelShader(device, pixel_shader[test_data[i].pshader]);
1611 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1612 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGVERTEXMODE, test_data[i].vfog);
1613 ok( hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1614 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGTABLEMODE, test_data[i].tfog);
1615 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1617 for(j = 0; j < 11; ++j)
1619 /* Don't use the whole zrange to prevent rounding errors */
1620 quad[0].position.z = 0.001f + j / 10.02f;
1621 quad[1].position.z = 0.001f + j / 10.02f;
1622 quad[2].position.z = 0.001f + j / 10.02f;
1623 quad[3].position.z = 0.001f + j / 10.02f;
1625 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff00ff, 1.0f, 0);
1626 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
1628 hr = IDirect3DDevice8_BeginScene(device);
1629 ok( hr == D3D_OK, "BeginScene returned failed (%08x)\n", hr);
1631 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1632 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
1634 hr = IDirect3DDevice8_EndScene(device);
1635 ok(hr == D3D_OK, "EndScene failed (%08x)\n", hr);
1637 /* As the red and green component are the result of blending use 5% tolerance on the expected value */
1638 color = getPixelColor(device, 128, 240);
1639 ok(color_match(color, test_data[i].color[j], 13) || broken(test_data[i].uninitialized_reg),
1640 "fog vs%i ps%i fvm%i ftm%i %d: got color %08x, expected %08x +-5%%\n",
1641 test_data[i].vshader, test_data[i].pshader,
1642 test_data[i].vfog, test_data[i].tfog, j, color, test_data[i].color[j]);
1645 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
1647 IDirect3DDevice8_DeleteVertexShader(device, vertex_shader[1]);
1648 IDirect3DDevice8_DeleteVertexShader(device, vertex_shader[2]);
1649 IDirect3DDevice8_DeleteVertexShader(device, pixel_shader[1]);
1650 refcount = IDirect3DDevice8_Release(device);
1651 ok(!refcount, "Device has %u references left.\n", refcount);
1652 done:
1653 IDirect3D8_Release(d3d);
1654 DestroyWindow(window);
1657 static void cnd_test(void)
1659 DWORD shader_11_coissue_2, shader_12_coissue_2, shader_13_coissue_2, shader_14_coissue_2;
1660 DWORD shader_11_coissue, shader_12_coissue, shader_13_coissue, shader_14_coissue;
1661 DWORD shader_11, shader_12, shader_13, shader_14;
1662 IDirect3DDevice8 *device;
1663 IDirect3D8 *d3d;
1664 ULONG refcount;
1665 D3DCAPS8 caps;
1666 DWORD color;
1667 HWND window;
1668 HRESULT hr;
1670 /* ps 1.x shaders are rather picky with writemasks and source swizzles.
1671 * The dp3 is used to copy r0.r to all components of r1, then copy r1.a to
1672 * r0.a. Essentially it does a mov r0.a, r0.r, which isn't allowed as-is
1673 * in 1.x pixel shaders. */
1674 static const DWORD shader_code_11[] =
1676 0xffff0101, /* ps_1_1 */
1677 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
1678 0x00000040, 0xb00f0000, /* texcoord t0 */
1679 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
1680 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3 r1, r0, c0 */
1681 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
1682 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
1683 0x0000ffff /* end */
1685 static const DWORD shader_code_12[] =
1687 0xffff0102, /* ps_1_2 */
1688 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
1689 0x00000040, 0xb00f0000, /* texcoord t0 */
1690 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
1691 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3 r1, r0, c0 */
1692 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
1693 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
1694 0x0000ffff /* end */
1696 static const DWORD shader_code_13[] =
1698 0xffff0103, /* ps_1_3 */
1699 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
1700 0x00000040, 0xb00f0000, /* texcoord t0 */
1701 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
1702 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3, r1, r0, c0 */
1703 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
1704 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
1705 0x0000ffff /* end */
1707 static const DWORD shader_code_14[] =
1709 0xffff0104, /* ps_1_3 */
1710 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
1711 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0, t0 */
1712 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
1713 0x00000050, 0x800f0000, 0x80e40000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0, c1, c2 */
1714 0x0000ffff /* end */
1717 /* Special fun: The coissue flag on cnd: Apparently cnd always selects the 2nd source,
1718 * as if the src0 comparison against 0.5 always evaluates to true. The coissue flag isn't
1719 * set by the compiler, it was added manually after compilation. Note that the COISSUE
1720 * flag on a color(.xyz) operation is only allowed after an alpha operation. DirectX doesn't
1721 * have proper docs, but GL_ATI_fragment_shader explains the pairing of color and alpha ops
1722 * well enough.
1724 * The shader attempts to test the range [-1;1] against coissued cnd, which is a bit tricky.
1725 * The input from t0 is [0;1]. 0.5 is subtracted, then we have to multiply with 2. Since
1726 * constants are clamped to [-1;1], a 2.0 is constructed by adding c0.r(=1.0) to c0.r into r1.r,
1727 * then r1(2.0, 0.0, 0.0, 0.0) is passed to dp3(explained above).
1729 static const DWORD shader_code_11_coissue[] =
1731 0xffff0101, /* ps_1_1 */
1732 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
1733 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
1734 0x00000040, 0xb00f0000, /* texcoord t0 */
1735 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
1736 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
1737 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
1738 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
1739 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
1740 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.xyz, r0.a, c1, c2*/
1741 0x0000ffff /* end */
1743 static const DWORD shader_code_11_coissue_2[] =
1745 0xffff0101, /* ps_1_1 */
1746 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
1747 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
1748 0x00000040, 0xb00f0000, /* texcoord t0 */
1749 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
1750 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
1751 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
1752 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
1753 0x00000001, 0x800f0000, 0x80e40001, /* mov r0, r1 */
1754 0x00000001, 0x80070000, 0x80ff0001, /* mov r0.xyz, r1.a */
1755 0x40000050, 0x80080000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.a, r0.a, c1, c2 */
1756 0x00000001, 0x80070000, 0x80ff0000, /* mov r0.xyz, r0.a */
1757 0x0000ffff /* end */
1759 static const DWORD shader_code_12_coissue[] =
1761 0xffff0102, /* ps_1_2 */
1762 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
1763 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
1764 0x00000040, 0xb00f0000, /* texcoord t0 */
1765 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
1766 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
1767 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
1768 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
1769 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
1770 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.xyz, r0.a, c1, c2*/
1771 0x0000ffff /* end */
1773 static const DWORD shader_code_12_coissue_2[] =
1775 0xffff0102, /* ps_1_2 */
1776 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
1777 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
1778 0x00000040, 0xb00f0000, /* texcoord t0 */
1779 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
1780 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
1781 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
1782 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
1783 0x00000001, 0x800f0000, 0x80e40001, /* mov r0, r1 */
1784 0x00000001, 0x80070000, 0x80ff0001, /* mov r0.xyz, r1.a */
1785 0x40000050, 0x80080000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.a, r0.a, c1, c2 */
1786 0x00000001, 0x80070000, 0x80ff0000, /* mov r0.xyz, r0.a */
1787 0x0000ffff /* end */
1789 static const DWORD shader_code_13_coissue[] =
1791 0xffff0103, /* ps_1_3 */
1792 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
1793 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
1794 0x00000040, 0xb00f0000, /* texcoord t0 */
1795 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
1796 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
1797 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
1798 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
1799 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
1800 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.xyz, r0.a, c1, c2*/
1801 0x0000ffff /* end */
1803 static const DWORD shader_code_13_coissue_2[] =
1805 0xffff0103, /* ps_1_3 */
1806 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
1807 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
1808 0x00000040, 0xb00f0000, /* texcoord t0 */
1809 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
1810 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
1811 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
1812 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
1813 0x00000001, 0x800f0000, 0x80e40001, /* mov r0, r1 */
1814 0x00000001, 0x80070000, 0x80ff0001, /* mov r0.xyz, r1.a */
1815 0x40000050, 0x80080000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.a, r0.a, c1, c2 */
1816 0x00000001, 0x80070000, 0x80ff0000, /* mov r0.xyz, r0.a */
1817 0x0000ffff /* end */
1819 /* ps_1_4 does not have a different cnd behavior, just pass the [0;1]
1820 * texcrd result to cnd, it will compare against 0.5. */
1821 static const DWORD shader_code_14_coissue[] =
1823 0xffff0104, /* ps_1_4 */
1824 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
1825 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0.xyz, t0 */
1826 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
1827 0x40000050, 0x80070000, 0x80e40000, 0xa0e40001, 0xa0e40002, /* +cnd r0.xyz, r0, c1, c2 */
1828 0x0000ffff /* end */
1830 static const DWORD shader_code_14_coissue_2[] =
1832 0xffff0104, /* ps_1_4 */
1833 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
1834 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0.xyz, t0 */
1835 0x00000001, 0x80080000, 0x80000000, /* mov r0.a, r0.x */
1836 0x00000001, 0x80070001, 0xa0ff0000, /* mov r1.xyz, c0.a */
1837 0x40000050, 0x80080001, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r1.a, r0.a, c1, c2 */
1838 0x00000001, 0x80070000, 0x80ff0001, /* mov r0.xyz, r1.a */
1839 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
1840 0x0000ffff /* end */
1842 static const float quad1[] =
1844 -1.0f, -1.0f, 0.1f, 0.0f, 0.0f, 1.0f,
1845 -1.0f, 0.0f, 0.1f, 0.0f, 1.0f, 0.0f,
1846 0.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f,
1847 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 0.0f
1849 static const float quad2[] =
1851 0.0f, -1.0f, 0.1f, 0.0f, 0.0f, 1.0f,
1852 0.0f, 0.0f, 0.1f, 0.0f, 1.0f, 0.0f,
1853 1.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f,
1854 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 0.0f
1856 static const float quad3[] =
1858 0.0f, 0.0f, 0.1f, 0.0f, 0.0f, 1.0f,
1859 0.0f, 1.0f, 0.1f, 0.0f, 1.0f, 0.0f,
1860 1.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f,
1861 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 0.0f
1863 static const float quad4[] =
1865 -1.0f, 0.0f, 0.1f, 0.0f, 0.0f, 1.0f,
1866 -1.0f, 1.0f, 0.1f, 0.0f, 1.0f, 0.0f,
1867 0.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f,
1868 0.0f, 1.0f, 0.1f, 1.0f, 1.0f, 0.0f
1870 static const float test_data_c1[4] = {0.0f, 0.0f, 0.0f, 0.0f};
1871 static const float test_data_c2[4] = {1.0f, 1.0f, 1.0f, 1.0f};
1872 static const float test_data_c1_coi[4] = {0.0f, 1.0f, 0.0f, 0.0f};
1873 static const float test_data_c2_coi[4] = {1.0f, 0.0f, 1.0f, 1.0f};
1875 window = create_window();
1876 d3d = Direct3DCreate8(D3D_SDK_VERSION);
1877 ok(!!d3d, "Failed to create a D3D object.\n");
1878 if (!(device = create_device(d3d, window, window, TRUE)))
1880 skip("Failed to create a D3D device, skipping tests.\n");
1881 goto done;
1884 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
1885 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
1886 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 4))
1888 skip("No ps_1_4 support, skipping tests.\n");
1889 IDirect3DDevice8_Release(device);
1890 goto done;
1893 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
1894 ok(hr == D3D_OK, "IDirect3DDevice8_Clear returned %08x\n", hr);
1896 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code_11, &shader_11);
1897 ok(hr == D3D_OK, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr);
1898 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code_12, &shader_12);
1899 ok(hr == D3D_OK, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr);
1900 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code_13, &shader_13);
1901 ok(hr == D3D_OK, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr);
1902 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code_14, &shader_14);
1903 ok(hr == D3D_OK, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr);
1904 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code_11_coissue, &shader_11_coissue);
1905 ok(hr == D3D_OK, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr);
1906 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code_12_coissue, &shader_12_coissue);
1907 ok(hr == D3D_OK, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr);
1908 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code_13_coissue, &shader_13_coissue);
1909 ok(hr == D3D_OK, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr);
1910 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code_14_coissue, &shader_14_coissue);
1911 ok(hr == D3D_OK, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr);
1912 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code_11_coissue_2, &shader_11_coissue_2);
1913 ok(hr == D3D_OK, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr);
1914 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code_12_coissue_2, &shader_12_coissue_2);
1915 ok(hr == D3D_OK, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr);
1916 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code_13_coissue_2, &shader_13_coissue_2);
1917 ok(hr == D3D_OK, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr);
1918 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code_14_coissue_2, &shader_14_coissue_2);
1919 ok(hr == D3D_OK, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr);
1921 hr = IDirect3DDevice8_SetPixelShaderConstant(device, 1, test_data_c1, 1);
1922 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShaderConstant returned %08x\n", hr);
1923 hr = IDirect3DDevice8_SetPixelShaderConstant(device, 2, test_data_c2, 1);
1924 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShaderConstant returned %08x\n", hr);
1925 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX1);
1926 ok(hr == D3D_OK, "IDirect3DDevice8_SetVertexShader returned %#08x\n", hr);
1928 hr = IDirect3DDevice8_BeginScene(device);
1929 ok(hr == D3D_OK, "IDirect3DDevice8_BeginScene returned %08x\n", hr);
1931 hr = IDirect3DDevice8_SetPixelShader(device, shader_11);
1932 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr);
1933 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
1934 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
1936 hr = IDirect3DDevice8_SetPixelShader(device, shader_12);
1937 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr);
1938 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
1939 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
1941 hr = IDirect3DDevice8_SetPixelShader(device, shader_13);
1942 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr);
1943 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
1944 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
1946 hr = IDirect3DDevice8_SetPixelShader(device, shader_14);
1947 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr);
1948 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
1949 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
1951 hr = IDirect3DDevice8_EndScene(device);
1952 ok(hr == D3D_OK, "IDirect3DDevice8_EndScene returned %08x\n", hr);
1954 hr = IDirect3DDevice8_SetPixelShader(device, 0);
1955 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr);
1957 /* This is the 1.4 test. Each component(r, g, b) is tested separately against 0.5 */
1958 color = getPixelColor(device, 158, 118);
1959 ok(color == 0x00ff00ff, "pixel 158, 118 has color %08x, expected 0x00ff00ff\n", color);
1960 color = getPixelColor(device, 162, 118);
1961 ok(color == 0x000000ff, "pixel 162, 118 has color %08x, expected 0x000000ff\n", color);
1962 color = getPixelColor(device, 158, 122);
1963 ok(color == 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color);
1964 color = getPixelColor(device, 162, 122);
1965 ok(color == 0x0000ffff, "pixel 162, 122 has color %08x, expected 0x0000ffff\n", color);
1967 /* 1.1 shader. All 3 components get set, based on the .w comparison */
1968 color = getPixelColor(device, 158, 358);
1969 ok(color == 0x00ffffff, "pixel 158, 358 has color %08x, expected 0x00ffffff\n", color);
1970 color = getPixelColor(device, 162, 358);
1971 ok(color_match(color, 0x00000000, 1),
1972 "pixel 162, 358 has color %08x, expected 0x00000000\n", color);
1973 color = getPixelColor(device, 158, 362);
1974 ok(color == 0x00ffffff, "pixel 158, 362 has color %08x, expected 0x00ffffff\n", color);
1975 color = getPixelColor(device, 162, 362);
1976 ok(color_match(color, 0x00000000, 1),
1977 "pixel 162, 362 has color %08x, expected 0x00000000\n", color);
1979 /* 1.2 shader */
1980 color = getPixelColor(device, 478, 358);
1981 ok(color == 0x00ffffff, "pixel 478, 358 has color %08x, expected 0x00ffffff\n", color);
1982 color = getPixelColor(device, 482, 358);
1983 ok(color_match(color, 0x00000000, 1),
1984 "pixel 482, 358 has color %08x, expected 0x00000000\n", color);
1985 color = getPixelColor(device, 478, 362);
1986 ok(color == 0x00ffffff, "pixel 478, 362 has color %08x, expected 0x00ffffff\n", color);
1987 color = getPixelColor(device, 482, 362);
1988 ok(color_match(color, 0x00000000, 1),
1989 "pixel 482, 362 has color %08x, expected 0x00000000\n", color);
1991 /* 1.3 shader */
1992 color = getPixelColor(device, 478, 118);
1993 ok(color == 0x00ffffff, "pixel 478, 118 has color %08x, expected 0x00ffffff\n", color);
1994 color = getPixelColor(device, 482, 118);
1995 ok(color_match(color, 0x00000000, 1),
1996 "pixel 482, 118 has color %08x, expected 0x00000000\n", color);
1997 color = getPixelColor(device, 478, 122);
1998 ok(color == 0x00ffffff, "pixel 478, 122 has color %08x, expected 0x00ffffff\n", color);
1999 color = getPixelColor(device, 482, 122);
2000 ok(color_match(color, 0x00000000, 1),
2001 "pixel 482, 122 has color %08x, expected 0x00000000\n", color);
2003 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
2004 ok(hr == D3D_OK, "IDirect3DDevice8_Present failed with %08x\n", hr);
2006 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0f, 0);
2007 ok(hr == D3D_OK, "IDirect3DDevice8_Clear returned %08x\n", hr);
2008 hr = IDirect3DDevice8_SetPixelShaderConstant(device, 1, test_data_c1_coi, 1);
2009 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShaderConstant returned %08x\n", hr);
2010 hr = IDirect3DDevice8_SetPixelShaderConstant(device, 2, test_data_c2_coi, 1);
2011 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShaderConstant returned %08x\n", hr);
2013 hr = IDirect3DDevice8_BeginScene(device);
2014 ok(hr == D3D_OK, "IDirect3DDevice8_BeginScene returned %08x\n", hr);
2016 hr = IDirect3DDevice8_SetPixelShader(device, shader_11_coissue);
2017 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr);
2018 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
2019 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
2021 hr = IDirect3DDevice8_SetPixelShader(device, shader_12_coissue);
2022 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr);
2023 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
2024 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
2026 hr = IDirect3DDevice8_SetPixelShader(device, shader_13_coissue);
2027 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr);
2028 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
2029 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
2031 hr = IDirect3DDevice8_SetPixelShader(device, shader_14_coissue);
2032 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr);
2033 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
2034 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
2036 hr = IDirect3DDevice8_EndScene(device);
2037 ok(hr == D3D_OK, "IDirect3DDevice8_EndScene returned %08x\n", hr);
2039 hr = IDirect3DDevice8_SetPixelShader(device, 0);
2040 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr);
2042 /* This is the 1.4 test. The coissue doesn't change the behavior here, but keep in mind
2043 * that we swapped the values in c1 and c2 to make the other tests return some color
2045 color = getPixelColor(device, 158, 118);
2046 ok(color == 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color);
2047 color = getPixelColor(device, 162, 118);
2048 ok(color == 0x0000ffff, "pixel 162, 118 has color %08x, expected 0x0000ffff\n", color);
2049 color = getPixelColor(device, 158, 122);
2050 ok(color == 0x00ff00ff, "pixel 162, 122 has color %08x, expected 0x00ff00ff\n", color);
2051 color = getPixelColor(device, 162, 122);
2052 ok(color == 0x000000ff, "pixel 162, 122 has color %08x, expected 0x000000ff\n", color);
2054 /* 1.1 shader. coissue flag changed the semantic of cnd, c1 is always selected
2055 * (The Win7 nvidia driver always selects c2)
2057 color = getPixelColor(device, 158, 358);
2058 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
2059 "pixel 158, 358 has color %08x, expected 0x0000ff00\n", color);
2060 color = getPixelColor(device, 162, 358);
2061 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
2062 "pixel 162, 358 has color %08x, expected 0x0000ff00\n", color);
2063 color = getPixelColor(device, 158, 362);
2064 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
2065 "pixel 158, 362 has color %08x, expected 0x0000ff00\n", color);
2066 color = getPixelColor(device, 162, 362);
2067 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
2068 "pixel 162, 362 has color %08x, expected 0x0000ff00\n", color);
2070 /* 1.2 shader */
2071 color = getPixelColor(device, 478, 358);
2072 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
2073 "pixel 478, 358 has color %08x, expected 0x0000ff00\n", color);
2074 color = getPixelColor(device, 482, 358);
2075 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
2076 "pixel 482, 358 has color %08x, expected 0x0000ff00\n", color);
2077 color = getPixelColor(device, 478, 362);
2078 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
2079 "pixel 478, 362 has color %08x, expected 0x0000ff00\n", color);
2080 color = getPixelColor(device, 482, 362);
2081 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
2082 "pixel 482, 362 has color %08x, expected 0x0000ff00\n", color);
2084 /* 1.3 shader */
2085 color = getPixelColor(device, 478, 118);
2086 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
2087 "pixel 478, 118 has color %08x, expected 0x0000ff00\n", color);
2088 color = getPixelColor(device, 482, 118);
2089 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
2090 "pixel 482, 118 has color %08x, expected 0x0000ff00\n", color);
2091 color = getPixelColor(device, 478, 122);
2092 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
2093 "pixel 478, 122 has color %08x, expected 0x0000ff00\n", color);
2094 color = getPixelColor(device, 482, 122);
2095 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
2096 "pixel 482, 122 has color %08x, expected 0x0000ff00\n", color);
2098 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
2099 ok(hr == D3D_OK, "IDirect3DDevice8_Present failed with %08x\n", hr);
2101 /* Retest with the coissue flag on the alpha instruction instead. This
2102 * works "as expected". The Windows 8 testbot (WARP) seems to handle this
2103 * the same as coissue on .rgb. */
2104 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0f, 0);
2105 ok(hr == D3D_OK, "IDirect3DDevice8_Clear returned %08x\n", hr);
2107 hr = IDirect3DDevice8_BeginScene(device);
2108 ok(hr == D3D_OK, "IDirect3DDevice8_BeginScene returned %08x\n", hr);
2110 hr = IDirect3DDevice8_SetPixelShader(device, shader_11_coissue_2);
2111 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr);
2112 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
2113 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
2115 hr = IDirect3DDevice8_SetPixelShader(device, shader_12_coissue_2);
2116 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr);
2117 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
2118 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
2120 hr = IDirect3DDevice8_SetPixelShader(device, shader_13_coissue_2);
2121 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr);
2122 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
2123 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
2125 hr = IDirect3DDevice8_SetPixelShader(device, shader_14_coissue_2);
2126 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr);
2127 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
2128 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
2130 hr = IDirect3DDevice8_EndScene(device);
2131 ok(hr == D3D_OK, "IDirect3DDevice8_EndScene returned %08x\n", hr);
2133 /* 1.4 shader */
2134 color = getPixelColor(device, 158, 118);
2135 ok(color == 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color);
2136 color = getPixelColor(device, 162, 118);
2137 ok(color == 0x00000000, "pixel 162, 118 has color %08x, expected 0x00000000\n", color);
2138 color = getPixelColor(device, 158, 122);
2139 ok(color == 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color);
2140 color = getPixelColor(device, 162, 122);
2141 ok(color == 0x00000000, "pixel 162, 122 has color %08x, expected 0x00000000\n", color);
2143 /* 1.1 shader */
2144 color = getPixelColor(device, 238, 358);
2145 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
2146 "pixel 238, 358 has color %08x, expected 0x00ffffff\n", color);
2147 color = getPixelColor(device, 242, 358);
2148 ok(color_match(color, 0x00000000, 1),
2149 "pixel 242, 358 has color %08x, expected 0x00000000\n", color);
2150 color = getPixelColor(device, 238, 362);
2151 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
2152 "pixel 238, 362 has color %08x, expected 0x00ffffff\n", color);
2153 color = getPixelColor(device, 242, 362);
2154 ok(color_match(color, 0x00000000, 1),
2155 "pixel 242, 362 has color %08x, expected 0x00000000\n", color);
2157 /* 1.2 shader */
2158 color = getPixelColor(device, 558, 358);
2159 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
2160 "pixel 558, 358 has color %08x, expected 0x00ffffff\n", color);
2161 color = getPixelColor(device, 562, 358);
2162 ok(color_match(color, 0x00000000, 1),
2163 "pixel 562, 358 has color %08x, expected 0x00000000\n", color);
2164 color = getPixelColor(device, 558, 362);
2165 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
2166 "pixel 558, 362 has color %08x, expected 0x00ffffff\n", color);
2167 color = getPixelColor(device, 562, 362);
2168 ok(color_match(color, 0x00000000, 1),
2169 "pixel 562, 362 has color %08x, expected 0x00000000\n", color);
2171 /* 1.3 shader */
2172 color = getPixelColor(device, 558, 118);
2173 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
2174 "pixel 558, 118 has color %08x, expected 0x00ffffff\n", color);
2175 color = getPixelColor(device, 562, 118);
2176 ok(color_match(color, 0x00000000, 1),
2177 "pixel 562, 118 has color %08x, expected 0x00000000\n", color);
2178 color = getPixelColor(device, 558, 122);
2179 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
2180 "pixel 558, 122 has color %08x, expected 0x00ffffff\n", color);
2181 color = getPixelColor(device, 562, 122);
2182 ok(color_match(color, 0x00000000, 1),
2183 "pixel 562, 122 has color %08x, expected 0x00000000\n", color);
2185 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
2186 ok(hr == D3D_OK, "IDirect3DDevice8_Present failed with %08x\n", hr);
2188 IDirect3DDevice8_DeletePixelShader(device, shader_14_coissue_2);
2189 IDirect3DDevice8_DeletePixelShader(device, shader_13_coissue_2);
2190 IDirect3DDevice8_DeletePixelShader(device, shader_12_coissue_2);
2191 IDirect3DDevice8_DeletePixelShader(device, shader_11_coissue_2);
2192 IDirect3DDevice8_DeletePixelShader(device, shader_14_coissue);
2193 IDirect3DDevice8_DeletePixelShader(device, shader_13_coissue);
2194 IDirect3DDevice8_DeletePixelShader(device, shader_12_coissue);
2195 IDirect3DDevice8_DeletePixelShader(device, shader_11_coissue);
2196 IDirect3DDevice8_DeletePixelShader(device, shader_14);
2197 IDirect3DDevice8_DeletePixelShader(device, shader_13);
2198 IDirect3DDevice8_DeletePixelShader(device, shader_12);
2199 IDirect3DDevice8_DeletePixelShader(device, shader_11);
2200 refcount = IDirect3DDevice8_Release(device);
2201 ok(!refcount, "Device has %u references left.\n", refcount);
2202 done:
2203 IDirect3D8_Release(d3d);
2204 DestroyWindow(window);
2207 static void z_range_test(void)
2209 IDirect3DDevice8 *device;
2210 IDirect3D8 *d3d;
2211 D3DCOLOR color;
2212 ULONG refcount;
2213 D3DCAPS8 caps;
2214 DWORD shader;
2215 HWND window;
2216 HRESULT hr;
2218 static const struct
2220 struct vec3 position;
2221 DWORD diffuse;
2223 quad[] =
2225 {{-1.0f, 0.0f, 1.1f}, 0xffff0000},
2226 {{-1.0f, 1.0f, 1.1f}, 0xffff0000},
2227 {{ 1.0f, 0.0f, -1.1f}, 0xffff0000},
2228 {{ 1.0f, 1.0f, -1.1f}, 0xffff0000},
2230 quad2[] =
2232 {{-1.0f, 0.0f, 1.1f}, 0xff0000ff},
2233 {{-1.0f, 1.0f, 1.1f}, 0xff0000ff},
2234 {{ 1.0f, 0.0f, -1.1f}, 0xff0000ff},
2235 {{ 1.0f, 1.0f, -1.1f}, 0xff0000ff},
2237 static const struct
2239 struct vec4 position;
2240 DWORD diffuse;
2242 quad3[] =
2244 {{640.0f, 240.0f, -1.1f, 1.0f}, 0xffffff00},
2245 {{640.0f, 480.0f, -1.1f, 1.0f}, 0xffffff00},
2246 {{ 0.0f, 240.0f, 1.1f, 1.0f}, 0xffffff00},
2247 {{ 0.0f, 480.0f, 1.1f, 1.0f}, 0xffffff00},
2249 quad4[] =
2251 {{640.0f, 240.0f, -1.1f, 1.0f}, 0xff00ff00},
2252 {{640.0f, 480.0f, -1.1f, 1.0f}, 0xff00ff00},
2253 {{ 0.0f, 240.0f, 1.1f, 1.0f}, 0xff00ff00},
2254 {{ 0.0f, 480.0f, 1.1f, 1.0f}, 0xff00ff00},
2256 static const DWORD shader_code[] =
2258 0xfffe0101, /* vs_1_1 */
2259 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
2260 0x00000001, 0xd00f0000, 0xa0e40000, /* mov oD0, c0 */
2261 0x0000ffff /* end */
2263 static const float color_const_1[] = {1.0f, 0.0f, 0.0f, 1.0f};
2264 static const float color_const_2[] = {0.0f, 0.0f, 1.0f, 1.0f};
2265 static const DWORD vertex_declaration[] =
2267 D3DVSD_STREAM(0),
2268 D3DVSD_REG(D3DVSDE_POSITION, D3DVSDT_FLOAT3),
2269 D3DVSD_END()
2272 window = create_window();
2273 d3d = Direct3DCreate8(D3D_SDK_VERSION);
2274 ok(!!d3d, "Failed to create a D3D object.\n");
2275 if (!(device = create_device(d3d, window, window, TRUE)))
2277 skip("Failed to create a D3D device, skipping tests.\n");
2278 goto done;
2281 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
2282 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
2284 /* Does the Present clear the depth stencil? Clear the depth buffer with some value != 0,
2285 * then call Present. Then clear the color buffer to make sure it has some defined content
2286 * after the Present with D3DSWAPEFFECT_DISCARD. After that draw a plane that is somewhere cut
2287 * by the depth value. */
2288 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.75f, 0);
2289 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
2290 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
2291 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
2292 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
2293 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
2295 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
2296 ok(SUCCEEDED(hr), "Failed to disabled lighting, hr %#x.\n", hr);
2297 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, TRUE);
2298 ok(SUCCEEDED(hr), "Failed to enable clipping, hr %#x.\n", hr);
2299 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
2300 ok(SUCCEEDED(hr), "Failed to enable z test, hr %#x.\n", hr);
2301 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
2302 ok(SUCCEEDED(hr), "Failed to disable z writes, hr %#x.\n", hr);
2303 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
2304 ok(SUCCEEDED(hr), "Failed to set z function, hr %#x.\n", hr);
2305 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
2306 ok(SUCCEEDED(hr), "Failed set FVF, hr %#x.\n", hr);
2308 hr = IDirect3DDevice8_BeginScene(device);
2309 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
2311 /* Test the untransformed vertex path */
2312 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
2313 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2314 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
2315 ok(SUCCEEDED(hr), "Failed to set z function, hr %#x.\n", hr);
2316 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
2317 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2319 /* Test the transformed vertex path */
2320 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
2321 ok(SUCCEEDED(hr), "Failed set FVF, hr %#x.\n", hr);
2323 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(quad4[0]));
2324 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2325 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
2326 ok(SUCCEEDED(hr), "Failed to set z function, hr %#x.\n", hr);
2327 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(quad3[0]));
2328 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2330 hr = IDirect3DDevice8_EndScene(device);
2331 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
2333 /* Do not test the exact corner pixels, but go pretty close to them */
2335 /* Clipped because z > 1.0 */
2336 color = getPixelColor(device, 28, 238);
2337 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2338 color = getPixelColor(device, 28, 241);
2339 if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
2340 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2341 else
2342 ok(color_match(color, 0x00ffff00, 0), "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2344 /* Not clipped, > z buffer clear value(0.75).
2346 * On the r500 driver on Windows D3DCMP_GREATER and D3DCMP_GREATEREQUAL are broken for depth
2347 * values > 0.5. The range appears to be distorted, apparently an incoming value of ~0.875 is
2348 * equal to a stored depth buffer value of 0.5. */
2349 color = getPixelColor(device, 31, 238);
2350 ok(color_match(color, 0x00ff0000, 0), "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2351 color = getPixelColor(device, 31, 241);
2352 ok(color_match(color, 0x00ffff00, 0), "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2353 color = getPixelColor(device, 100, 238);
2354 ok(color_match(color, 0x00ff0000, 0) || broken(color_match(color, 0x00ffffff, 0)),
2355 "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2356 color = getPixelColor(device, 100, 241);
2357 ok(color_match(color, 0x00ffff00, 0) || broken(color_match(color, 0x00ffffff, 0)),
2358 "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2360 /* Not clipped, < z buffer clear value */
2361 color = getPixelColor(device, 104, 238);
2362 ok(color_match(color, 0x000000ff, 0), "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2363 color = getPixelColor(device, 104, 241);
2364 ok(color_match(color, 0x0000ff00, 0), "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
2365 color = getPixelColor(device, 318, 238);
2366 ok(color_match(color, 0x000000ff, 0), "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2367 color = getPixelColor(device, 318, 241);
2368 ok(color_match(color, 0x0000ff00, 0), "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
2370 /* Clipped because z < 0.0 */
2371 color = getPixelColor(device, 321, 238);
2372 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2373 color = getPixelColor(device, 321, 241);
2374 if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
2375 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2376 else
2377 ok(color_match(color, 0x0000ff00, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2379 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
2380 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
2382 /* Test the shader path */
2383 if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1))
2385 skip("Vertex shaders not supported\n");
2386 IDirect3DDevice8_Release(device);
2387 goto done;
2389 hr = IDirect3DDevice8_CreateVertexShader(device, vertex_declaration, shader_code, &shader, 0);
2390 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
2392 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
2393 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
2395 hr = IDirect3DDevice8_SetVertexShader(device, shader);
2396 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
2398 hr = IDirect3DDevice8_BeginScene(device);
2399 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
2401 hr = IDirect3DDevice8_SetVertexShaderConstant(device, 0, color_const_1, 1);
2402 ok(SUCCEEDED(hr), "Failed to set vs constant 0, hr %#x.\n", hr);
2403 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
2404 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2406 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
2407 ok(SUCCEEDED(hr), "Failed to set z function, hr %#x.\n", hr);
2408 hr = IDirect3DDevice8_SetVertexShaderConstant(device, 0, color_const_2, 1);
2409 ok(SUCCEEDED(hr), "Failed to set vs constant 0, hr %#x.\n", hr);
2410 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
2411 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2413 hr = IDirect3DDevice8_EndScene(device);
2414 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
2416 hr = IDirect3DDevice8_SetVertexShader(device, 0);
2417 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
2419 hr = IDirect3DDevice8_DeleteVertexShader(device, shader);
2420 ok(SUCCEEDED(hr), "Failed to delete vertex shader, hr %#x.\n", hr);
2422 /* Z < 1.0 */
2423 color = getPixelColor(device, 28, 238);
2424 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2426 /* 1.0 < z < 0.75 */
2427 color = getPixelColor(device, 31, 238);
2428 ok(color_match(color, 0x00ff0000, 0), "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2429 color = getPixelColor(device, 100, 238);
2430 ok(color_match(color, 0x00ff0000, 0) || broken(color_match(color, 0x00ffffff, 0)),
2431 "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2433 /* 0.75 < z < 0.0 */
2434 color = getPixelColor(device, 104, 238);
2435 ok(color_match(color, 0x000000ff, 0), "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2436 color = getPixelColor(device, 318, 238);
2437 ok(color_match(color, 0x000000ff, 0), "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2439 /* 0.0 < z */
2440 color = getPixelColor(device, 321, 238);
2441 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2443 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
2444 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
2446 refcount = IDirect3DDevice8_Release(device);
2447 ok(!refcount, "Device has %u references left.\n", refcount);
2448 done:
2449 IDirect3D8_Release(d3d);
2450 DestroyWindow(window);
2453 static void test_scalar_instructions(void)
2455 IDirect3DDevice8 *device;
2456 IDirect3D8 *d3d;
2457 unsigned int i;
2458 D3DCOLOR color;
2459 ULONG refcount;
2460 D3DCAPS8 caps;
2461 DWORD shader;
2462 HWND window;
2463 HRESULT hr;
2465 static const struct vec3 quad[] =
2467 {-1.0f, -1.0f, 0.0f},
2468 {-1.0f, 1.0f, 0.0f},
2469 { 1.0f, -1.0f, 0.0f},
2470 { 1.0f, 1.0f, 0.0f},
2472 static const DWORD decl[] =
2474 D3DVSD_STREAM(0),
2475 D3DVSD_REG(D3DVSDE_POSITION, D3DVSDT_FLOAT3), /* dcl_position v0 */
2476 D3DVSD_CONST(0, 1), 0x3e800000, 0x3f000000, 0x3f800000, 0x40000000, /* def c0, 0.25, 0.5, 1.0, 2.0 */
2477 D3DVSD_END()
2479 static const DWORD rcp_test[] =
2481 0xfffe0101, /* vs_1_1 */
2482 0x0009fffe, 0x30303030, 0x30303030, /* Shaders have to have a minimal size. */
2483 0x30303030, 0x30303030, 0x30303030, /* Add a filler comment. Usually d3dx8's */
2484 0x30303030, 0x30303030, 0x30303030, /* version comment makes the shader big */
2485 0x00303030, /* enough to make Windows happy. */
2486 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
2487 0x00000006, 0xd00f0000, 0xa0e40000, /* rcp oD0, c0 */
2488 0x0000ffff /* END */
2490 static const DWORD rsq_test[] =
2492 0xfffe0101, /* vs_1_1 */
2493 0x0009fffe, 0x30303030, 0x30303030, /* Shaders have to have a minimal size. */
2494 0x30303030, 0x30303030, 0x30303030, /* Add a filler comment. Usually d3dx8's */
2495 0x30303030, 0x30303030, 0x30303030, /* version comment makes the shader big */
2496 0x00303030, /* enough to make Windows happy. */
2497 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
2498 0x00000007, 0xd00f0000, 0xa0e40000, /* rsq oD0, c0 */
2499 0x0000ffff /* END */
2501 static const DWORD exp_test[] =
2503 0xfffe0101, /* vs_1_1 */
2504 0x0009fffe, 0x30303030, 0x30303030, /* Shaders have to have a minimal size. */
2505 0x30303030, 0x30303030, 0x30303030, /* Add a filler comment. Usually d3dx8's */
2506 0x30303030, 0x30303030, 0x30303030, /* version comment makes the shader big */
2507 0x00303030, /* enough to make Windows happy. */
2508 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
2509 0x0000000e, 0x800f0000, 0xa0e40000, /* exp r0, c0 */
2510 0x00000006, 0xd00f0000, 0x80000000, /* rcp oD0, r0.x */
2511 0x0000ffff, /* END */
2513 static const DWORD expp_test[] =
2515 0xfffe0101, /* vs_1_1 */
2516 0x0009fffe, 0x30303030, 0x30303030, /* Shaders have to have a minimal size. */
2517 0x30303030, 0x30303030, 0x30303030, /* Add a filler comment. Usually d3dx8's */
2518 0x30303030, 0x30303030, 0x30303030, /* version comment makes the shader big */
2519 0x00303030, /* enough to make Windows happy. */
2520 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
2521 0x0000004e, 0x800f0000, 0xa0e40000, /* expp r0, c0 */
2522 0x00000006, 0xd00f0000, 0x80000000, /* rcp oD0, r0.x */
2523 0x0000ffff, /* END */
2525 static const DWORD log_test[] =
2527 0xfffe0101, /* vs_1_1 */
2528 0x0009fffe, 0x30303030, 0x30303030, /* Shaders have to have a minimal size. */
2529 0x30303030, 0x30303030, 0x30303030, /* Add a filler comment. Usually d3dx8's */
2530 0x30303030, 0x30303030, 0x30303030, /* version comment makes the shader big */
2531 0x00303030, /* enough to make Windows happy. */
2532 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
2533 0x0000000f, 0xd00f0000, 0xa0e40000, /* log oD0, c0 */
2534 0x0000ffff, /* END */
2536 static const DWORD logp_test[] =
2538 0xfffe0101, /* vs_1_1 */
2539 0x0009fffe, 0x30303030, 0x30303030, /* Shaders have to have a minimal size. */
2540 0x30303030, 0x30303030, 0x30303030, /* Add a filler comment. Usually d3dx8's */
2541 0x30303030, 0x30303030, 0x30303030, /* version comment makes the shader big */
2542 0x00303030, /* enough to make Windows happy. */
2543 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
2544 0x0000004f, 0xd00f0000, 0xa0e40000, /* logp oD0, c0 */
2545 0x0000ffff, /* END */
2547 static const struct
2549 const char *name;
2550 const DWORD *byte_code;
2551 D3DCOLOR color;
2552 /* Some drivers, including Intel HD4000 10.18.10.3345 and VMware SVGA
2553 * 3D 7.14.1.5025, use the .x component instead of the .w one. */
2554 D3DCOLOR broken_color;
2556 test_data[] =
2558 {"rcp_test", rcp_test, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x80), D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff)},
2559 {"rsq_test", rsq_test, D3DCOLOR_ARGB(0x00, 0xb4, 0xb4, 0xb4), D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff)},
2560 {"exp_test", exp_test, D3DCOLOR_ARGB(0x00, 0x40, 0x40, 0x40), D3DCOLOR_ARGB(0x00, 0xd6, 0xd6, 0xd6)},
2561 {"expp_test", expp_test, D3DCOLOR_ARGB(0x00, 0x40, 0x40, 0x40), D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff)},
2562 {"log_test", log_test, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff), D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
2563 {"logp_test", logp_test, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff), D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
2566 window = create_window();
2567 d3d = Direct3DCreate8(D3D_SDK_VERSION);
2568 ok(!!d3d, "Failed to create a D3D object.\n");
2569 if (!(device = create_device(d3d, window, window, TRUE)))
2571 skip("Failed to create a D3D device, skipping tests.\n");
2572 goto done;
2575 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
2576 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
2577 if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1))
2579 skip("No vs_1_1 support, skipping tests.\n");
2580 IDirect3DDevice8_Release(device);
2581 goto done;
2584 for (i = 0; i < ARRAY_SIZE(test_data); ++i)
2586 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff336699, 0.0f, 0);
2587 ok(SUCCEEDED(hr), "%s: Failed to clear, hr %#x.\n", test_data[i].name, hr);
2589 hr = IDirect3DDevice8_CreateVertexShader(device, decl, test_data[i].byte_code, &shader, 0);
2590 ok(SUCCEEDED(hr), "%s: Failed to create vertex shader, hr %#x.\n", test_data[i].name, hr);
2591 hr = IDirect3DDevice8_SetVertexShader(device, shader);
2592 ok(SUCCEEDED(hr), "%s: Failed to set vertex shader, hr %#x.\n", test_data[i].name, hr);
2594 hr = IDirect3DDevice8_BeginScene(device);
2595 ok(SUCCEEDED(hr), "%s: Failed to begin scene, hr %#x.\n", test_data[i].name, hr);
2596 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], 3 * sizeof(float));
2597 ok(SUCCEEDED(hr), "%s: Failed to draw primitive, hr %#x.\n", test_data[i].name, hr);
2598 hr = IDirect3DDevice8_EndScene(device);
2599 ok(SUCCEEDED(hr), "%s: Failed to end scene, hr %#x.\n", test_data[i].name, hr);
2601 color = getPixelColor(device, 320, 240);
2602 ok(color_match(color, test_data[i].color, 4) || broken(color_match(color, test_data[i].broken_color, 4)),
2603 "%s: Got unexpected color 0x%08x, expected 0x%08x.\n",
2604 test_data[i].name, color, test_data[i].color);
2606 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
2607 ok(SUCCEEDED(hr), "%s: Failed to present, hr %#x.\n", test_data[i].name, hr);
2609 hr = IDirect3DDevice8_SetVertexShader(device, 0);
2610 ok(SUCCEEDED(hr), "%s: Failed to set vertex shader, hr %#x.\n", test_data[i].name, hr);
2611 hr = IDirect3DDevice8_DeleteVertexShader(device, shader);
2612 ok(SUCCEEDED(hr), "%s: Failed to delete vertex shader, hr %#x.\n", test_data[i].name, hr);
2615 refcount = IDirect3DDevice8_Release(device);
2616 ok(!refcount, "Device has %u references left.\n", refcount);
2617 done:
2618 IDirect3D8_Release(d3d);
2619 DestroyWindow(window);
2622 static void offscreen_test(void)
2624 IDirect3DSurface8 *backbuffer, *offscreen, *depthstencil;
2625 IDirect3DTexture8 *offscreenTexture;
2626 IDirect3DDevice8 *device;
2627 IDirect3D8 *d3d;
2628 D3DCOLOR color;
2629 ULONG refcount;
2630 HWND window;
2631 HRESULT hr;
2633 static const float quad[][5] =
2635 {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
2636 {-0.5f, 0.5f, 0.1f, 0.0f, 1.0f},
2637 { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
2638 { 0.5f, 0.5f, 0.1f, 1.0f, 1.0f},
2641 window = create_window();
2642 d3d = Direct3DCreate8(D3D_SDK_VERSION);
2643 ok(!!d3d, "Failed to create a D3D object.\n");
2644 if (!(device = create_device(d3d, window, window, TRUE)))
2646 skip("Failed to create a D3D device, skipping tests.\n");
2647 goto done;
2650 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 1.0f, 0);
2651 ok(hr == D3D_OK, "Clear failed, hr = %#08x\n", hr);
2653 hr = IDirect3DDevice8_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET,
2654 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture);
2655 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %#08x\n", hr);
2656 if (!offscreenTexture)
2658 trace("Failed to create an X8R8G8B8 offscreen texture, trying R5G6B5\n");
2659 hr = IDirect3DDevice8_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET,
2660 D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &offscreenTexture);
2661 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %#08x\n", hr);
2662 if (!offscreenTexture)
2664 skip("Cannot create an offscreen render target.\n");
2665 IDirect3DDevice8_Release(device);
2666 goto done;
2670 hr = IDirect3DDevice8_GetDepthStencilSurface(device, &depthstencil);
2671 ok(hr == D3D_OK, "IDirect3DDevice8_GetDepthStencilSurface failed, hr = %#08x\n", hr);
2673 hr = IDirect3DDevice8_GetBackBuffer(device, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
2674 ok(hr == D3D_OK, "Can't get back buffer, hr = %#08x\n", hr);
2676 hr = IDirect3DTexture8_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
2677 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %#08x\n", hr);
2679 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX1);
2680 ok(hr == D3D_OK, "SetVertexShader failed, hr = %#08x\n", hr);
2682 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
2683 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %#08x\n", hr);
2684 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
2685 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %#08x\n", hr);
2686 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MINFILTER, D3DTEXF_NONE);
2687 ok(SUCCEEDED(hr), "SetTextureStageState D3DSAMP_MINFILTER failed (%#08x)\n", hr);
2688 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MAGFILTER, D3DTEXF_NONE);
2689 ok(SUCCEEDED(hr), "SetTextureStageState D3DSAMP_MAGFILTER failed (%#08x)\n", hr);
2690 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
2691 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %08x\n", hr);
2693 hr = IDirect3DDevice8_BeginScene(device);
2694 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
2696 hr = IDirect3DDevice8_SetRenderTarget(device, offscreen, depthstencil);
2697 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
2698 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 1.0f, 0);
2699 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
2701 /* Draw without textures - Should result in a white quad. */
2702 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
2703 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2705 hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, depthstencil);
2706 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
2707 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)offscreenTexture);
2708 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
2710 /* This time with the texture .*/
2711 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
2712 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2714 hr = IDirect3DDevice8_EndScene(device);
2715 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
2717 /* Center quad - should be white */
2718 color = getPixelColor(device, 320, 240);
2719 ok(color == 0x00ffffff, "Offscreen failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2720 /* Some quad in the cleared part of the texture */
2721 color = getPixelColor(device, 170, 240);
2722 ok(color == 0x00ff00ff, "Offscreen failed: Got color 0x%08x, expected 0x00ff00ff.\n", color);
2723 /* Part of the originally cleared back buffer */
2724 color = getPixelColor(device, 10, 10);
2725 ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2726 color = getPixelColor(device, 10, 470);
2727 ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2729 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
2731 IDirect3DSurface8_Release(backbuffer);
2732 IDirect3DTexture8_Release(offscreenTexture);
2733 IDirect3DSurface8_Release(offscreen);
2734 IDirect3DSurface8_Release(depthstencil);
2735 refcount = IDirect3DDevice8_Release(device);
2736 ok(!refcount, "Device has %u references left.\n", refcount);
2737 done:
2738 IDirect3D8_Release(d3d);
2739 DestroyWindow(window);
2742 static void test_blend(void)
2744 IDirect3DSurface8 *backbuffer, *offscreen, *depthstencil;
2745 IDirect3DTexture8 *offscreenTexture;
2746 IDirect3DDevice8 *device;
2747 IDirect3D8 *d3d;
2748 D3DCOLOR color;
2749 ULONG refcount;
2750 HWND window;
2751 HRESULT hr;
2753 static const struct
2755 struct vec3 position;
2756 DWORD diffuse;
2758 quad1[] =
2760 {{-1.0f, -1.0f, 0.1f}, 0x4000ff00},
2761 {{-1.0f, 0.0f, 0.1f}, 0x4000ff00},
2762 {{ 1.0f, -1.0f, 0.1f}, 0x4000ff00},
2763 {{ 1.0f, 0.0f, 0.1f}, 0x4000ff00},
2765 quad2[] =
2767 {{-1.0f, 0.0f, 0.1f}, 0xc00000ff},
2768 {{-1.0f, 1.0f, 0.1f}, 0xc00000ff},
2769 {{ 1.0f, 0.0f, 0.1f}, 0xc00000ff},
2770 {{ 1.0f, 1.0f, 0.1f}, 0xc00000ff},
2772 static const float composite_quad[][5] =
2774 { 0.0f, -1.0f, 0.1f, 0.0f, 1.0f},
2775 { 0.0f, 1.0f, 0.1f, 0.0f, 0.0f},
2776 { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f},
2777 { 1.0f, 1.0f, 0.1f, 1.0f, 0.0f},
2780 window = create_window();
2781 d3d = Direct3DCreate8(D3D_SDK_VERSION);
2782 ok(!!d3d, "Failed to create a D3D object.\n");
2783 if (!(device = create_device(d3d, window, window, TRUE)))
2785 skip("Failed to create a D3D device, skipping tests.\n");
2786 goto done;
2789 /* Clear the render target with alpha = 0.5 */
2790 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x80ff0000, 1.0f, 0);
2791 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
2793 hr = IDirect3DDevice8_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET,
2794 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture);
2795 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
2797 hr = IDirect3DDevice8_GetDepthStencilSurface(device, &depthstencil);
2798 ok(SUCCEEDED(hr), "Failed to get depth/stencil buffer, hr %#x.\n", hr);
2799 hr = IDirect3DDevice8_GetBackBuffer(device, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
2800 ok(SUCCEEDED(hr), "Failed to get back buffer, hr %#x.\n", hr);
2802 hr = IDirect3DTexture8_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
2803 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %#08x\n", hr);
2805 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
2806 ok(hr == D3D_OK, "SetVertexShader failed, hr = %#08x\n", hr);
2808 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
2809 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %#08x\n", hr);
2810 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
2811 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %#08x\n", hr);
2812 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MINFILTER, D3DTEXF_NONE);
2813 ok(SUCCEEDED(hr), "SetTextureStageState D3DSAMP_MINFILTER failed (%#08x)\n", hr);
2814 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MAGFILTER, D3DTEXF_NONE);
2815 ok(SUCCEEDED(hr), "SetTextureStageState D3DSAMP_MAGFILTER failed (%#08x)\n", hr);
2816 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
2817 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %08x\n", hr);
2819 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
2820 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
2821 hr = IDirect3DDevice8_BeginScene(device);
2822 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
2824 /* Draw two quads, one with src alpha blending, one with dest alpha blending. */
2825 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
2826 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
2827 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
2828 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
2829 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
2830 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2832 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
2833 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
2834 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
2835 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
2836 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
2837 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2839 /* Switch to the offscreen buffer, and redo the testing. The offscreen
2840 * render target doesn't have an alpha channel. DESTALPHA and INVDESTALPHA
2841 * "don't work" on render targets without alpha channel, they give
2842 * essentially ZERO and ONE blend factors. */
2843 hr = IDirect3DDevice8_SetRenderTarget(device, offscreen, 0);
2844 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
2845 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
2846 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
2848 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
2849 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
2850 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
2851 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
2852 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
2853 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2855 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
2856 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
2857 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
2858 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
2859 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
2860 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2862 hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, depthstencil);
2863 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
2865 /* Render the offscreen texture onto the frame buffer to be able to
2866 * compare it regularly. Disable alpha blending for the final
2867 * composition. */
2868 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
2869 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
2870 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX1);
2871 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
2873 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *) offscreenTexture);
2874 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
2875 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, composite_quad, sizeof(float) * 5);
2876 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2878 hr = IDirect3DDevice8_EndScene(device);
2879 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
2881 color = getPixelColor(device, 160, 360);
2882 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
2883 "SRCALPHA on frame buffer returned color %08x, expected 0x00bf4000\n", color);
2885 color = getPixelColor(device, 160, 120);
2886 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x00, 0x80), 2),
2887 "DSTALPHA on frame buffer returned color %08x, expected 0x007f0080\n", color);
2889 color = getPixelColor(device, 480, 360);
2890 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
2891 "SRCALPHA on texture returned color %08x, expected 0x00bf4000\n", color);
2893 color = getPixelColor(device, 480, 120);
2894 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
2895 "DSTALPHA on texture returned color %08x, expected 0x000000ff\n", color);
2897 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
2899 IDirect3DSurface8_Release(backbuffer);
2900 IDirect3DTexture8_Release(offscreenTexture);
2901 IDirect3DSurface8_Release(offscreen);
2902 IDirect3DSurface8_Release(depthstencil);
2903 refcount = IDirect3DDevice8_Release(device);
2904 ok(!refcount, "Device has %u references left.\n", refcount);
2905 done:
2906 IDirect3D8_Release(d3d);
2907 DestroyWindow(window);
2910 static void p8_texture_test(void)
2912 IDirect3DTexture8 *texture, *texture2;
2913 IDirect3DDevice8 *device;
2914 PALETTEENTRY table[256];
2915 unsigned char *data;
2916 D3DLOCKED_RECT lr;
2917 IDirect3D8 *d3d;
2918 D3DCOLOR color;
2919 ULONG refcount;
2920 D3DCAPS8 caps;
2921 HWND window;
2922 HRESULT hr;
2923 UINT i;
2925 static const float quad[] =
2927 -1.0f, 0.0f, 0.1f, 0.0f, 0.0f,
2928 -1.0f, 1.0f, 0.1f, 0.0f, 1.0f,
2929 1.0f, 0.0f, 0.1f, 1.0f, 0.0f,
2930 1.0f, 1.0f, 0.1f, 1.0f, 1.0f,
2932 static const float quad2[] =
2934 -1.0f, -1.0f, 0.1f, 0.0f, 0.0f,
2935 -1.0f, 0.0f, 0.1f, 0.0f, 1.0f,
2936 1.0f, -1.0f, 0.1f, 1.0f, 0.0f,
2937 1.0f, 0.0f, 0.1f, 1.0f, 1.0f,
2940 window = create_window();
2941 d3d = Direct3DCreate8(D3D_SDK_VERSION);
2942 ok(!!d3d, "Failed to create a D3D object.\n");
2943 if (!(device = create_device(d3d, window, window, TRUE)))
2945 skip("Failed to create a D3D device, skipping tests.\n");
2946 goto done;
2949 if (IDirect3D8_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
2950 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_P8) != D3D_OK)
2952 skip("D3DFMT_P8 textures not supported.\n");
2953 IDirect3DDevice8_Release(device);
2954 goto done;
2957 hr = IDirect3DDevice8_CreateTexture(device, 1, 1, 1, 0, D3DFMT_P8, D3DPOOL_MANAGED, &texture2);
2958 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
2959 memset(&lr, 0, sizeof(lr));
2960 hr = IDirect3DTexture8_LockRect(texture2, 0, &lr, NULL, 0);
2961 ok(hr == D3D_OK, "IDirect3DTexture8_LockRect failed, hr = %08x\n", hr);
2962 data = lr.pBits;
2963 *data = 1;
2964 hr = IDirect3DTexture8_UnlockRect(texture2, 0);
2965 ok(hr == D3D_OK, "IDirect3DTexture8_UnlockRect failed, hr = %08x\n", hr);
2967 hr = IDirect3DDevice8_CreateTexture(device, 1, 1, 1, 0, D3DFMT_P8, D3DPOOL_MANAGED, &texture);
2968 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
2969 memset(&lr, 0, sizeof(lr));
2970 hr = IDirect3DTexture8_LockRect(texture, 0, &lr, NULL, 0);
2971 ok(hr == D3D_OK, "IDirect3DTexture8_LockRect failed, hr = %08x\n", hr);
2972 data = lr.pBits;
2973 *data = 1;
2974 hr = IDirect3DTexture8_UnlockRect(texture, 0);
2975 ok(hr == D3D_OK, "IDirect3DTexture8_UnlockRect failed, hr = %08x\n", hr);
2977 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff000000, 1.0f, 0);
2978 ok(hr == D3D_OK, "IDirect3DDevice8_Clear failed, hr = %08x\n", hr);
2980 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
2981 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
2982 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
2983 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
2985 /* The first part of the test should work both with and without D3DPTEXTURECAPS_ALPHAPALETTE;
2986 alpha of every entry is set to 1.0, which MS says is required when there's no
2987 D3DPTEXTURECAPS_ALPHAPALETTE capability */
2988 for (i = 0; i < 256; i++) {
2989 table[i].peRed = table[i].peGreen = table[i].peBlue = 0;
2990 table[i].peFlags = 0xff;
2992 table[1].peRed = 0xff;
2993 hr = IDirect3DDevice8_SetPaletteEntries(device, 0, table);
2994 ok(hr == D3D_OK, "IDirect3DDevice8_SetPaletteEntries failed, hr = %08x\n", hr);
2996 table[1].peRed = 0;
2997 table[1].peBlue = 0xff;
2998 hr = IDirect3DDevice8_SetPaletteEntries(device, 1, table);
2999 ok(hr == D3D_OK, "IDirect3DDevice8_SetPaletteEntries failed, hr = %08x\n", hr);
3001 hr = IDirect3DDevice8_BeginScene(device);
3002 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
3004 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
3005 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
3006 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
3007 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
3008 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX1);
3009 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
3010 hr = IDirect3DDevice8_SetCurrentTexturePalette(device, 0);
3011 ok(SUCCEEDED(hr), "Failed to set texture palette, hr %#x.\n", hr);
3012 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture2);
3013 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
3014 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
3015 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
3017 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
3018 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
3019 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
3020 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
3022 hr = IDirect3DDevice8_SetCurrentTexturePalette(device, 1);
3023 ok(SUCCEEDED(hr), "Failed to set texture palette, hr %#x.\n", hr);
3024 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
3025 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
3027 hr = IDirect3DDevice8_EndScene(device);
3028 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
3030 color = getPixelColor(device, 32, 32);
3031 ok(color_match(color, 0x00ff0000, 0), "Got unexpected color 0x%08x.\n", color);
3032 color = getPixelColor(device, 32, 320);
3033 ok(color_match(color, 0x000000ff, 0), "Got unexpected color 0x%08x.\n", color);
3035 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
3036 ok(hr == D3D_OK, "IDirect3DDevice8_Present failed, hr = %08x\n", hr);
3038 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
3039 ok(hr == D3D_OK, "IDirect3DDevice8_Clear failed, hr = %08x\n", hr);
3041 hr = IDirect3DDevice8_BeginScene(device);
3042 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
3043 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture2);
3044 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
3045 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
3046 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
3047 hr = IDirect3DDevice8_EndScene(device);
3048 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
3050 color = getPixelColor(device, 32, 32);
3051 ok(color_match(color, 0x000000ff, 0), "Got unexpected color 0x%08x.\n", color);
3053 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
3054 ok(hr == D3D_OK, "IDirect3DDevice8_Present failed, hr = %08x\n", hr);
3056 /* Test palettes with alpha */
3057 IDirect3DDevice8_GetDeviceCaps(device, &caps);
3058 if (!(caps.TextureCaps & D3DPTEXTURECAPS_ALPHAPALETTE)) {
3059 skip("no D3DPTEXTURECAPS_ALPHAPALETTE capability, tests with alpha in palette will be skipped\n");
3060 } else {
3061 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
3062 ok(hr == D3D_OK, "IDirect3DDevice8_Clear failed, hr = %08x\n", hr);
3064 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
3065 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
3067 for (i = 0; i < 256; i++) {
3068 table[i].peRed = table[i].peGreen = table[i].peBlue = 0;
3069 table[i].peFlags = 0xff;
3071 table[1].peRed = 0xff;
3072 table[1].peFlags = 0x80;
3073 hr = IDirect3DDevice8_SetPaletteEntries(device, 0, table);
3074 ok(hr == D3D_OK, "IDirect3DDevice8_SetPaletteEntries failed, hr = %08x\n", hr);
3076 table[1].peRed = 0;
3077 table[1].peBlue = 0xff;
3078 table[1].peFlags = 0x80;
3079 hr = IDirect3DDevice8_SetPaletteEntries(device, 1, table);
3080 ok(hr == D3D_OK, "IDirect3DDevice8_SetPaletteEntries failed, hr = %08x\n", hr);
3082 hr = IDirect3DDevice8_BeginScene(device);
3083 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
3085 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
3086 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
3087 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
3088 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
3089 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX1);
3090 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
3092 hr = IDirect3DDevice8_SetCurrentTexturePalette(device, 0);
3093 ok(SUCCEEDED(hr), "Failed to set texture palette, hr %#x.\n", hr);
3094 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
3095 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
3097 hr = IDirect3DDevice8_SetCurrentTexturePalette(device, 1);
3098 ok(SUCCEEDED(hr), "Failed to set texture palette, hr %#x.\n", hr);
3099 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
3100 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
3102 hr = IDirect3DDevice8_EndScene(device);
3103 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
3105 color = getPixelColor(device, 32, 32);
3106 ok(color_match(color, 0x00800000, 1), "Got unexpected color 0x%08x.\n", color);
3107 color = getPixelColor(device, 32, 320);
3108 ok(color_match(color, 0x00000080, 1), "Got unexpected color 0x%08x.\n", color);
3110 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
3111 ok(hr == D3D_OK, "IDirect3DDevice8_Present failed, hr = %08x\n", hr);
3114 IDirect3DTexture8_Release(texture);
3115 IDirect3DTexture8_Release(texture2);
3116 refcount = IDirect3DDevice8_Release(device);
3117 ok(!refcount, "Device has %u references left.\n", refcount);
3118 done:
3119 IDirect3D8_Release(d3d);
3120 DestroyWindow(window);
3123 static void texop_test(void)
3125 IDirect3DTexture8 *texture;
3126 D3DLOCKED_RECT locked_rect;
3127 IDirect3DDevice8 *device;
3128 IDirect3D8 *d3d;
3129 unsigned int i;
3130 D3DCOLOR color;
3131 ULONG refcount;
3132 D3DCAPS8 caps;
3133 HWND window;
3134 HRESULT hr;
3136 static const struct {
3137 float x, y, z;
3138 D3DCOLOR diffuse;
3139 float s, t;
3140 } quad[] = {
3141 {-1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00), -1.0f, -1.0f},
3142 {-1.0f, 1.0f, 0.1f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00), -1.0f, 1.0f},
3143 { 1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00), 1.0f, -1.0f},
3144 { 1.0f, 1.0f, 0.1f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00), 1.0f, 1.0f}
3147 static const struct {
3148 D3DTEXTUREOP op;
3149 const char *name;
3150 DWORD caps_flag;
3151 D3DCOLOR result;
3152 } test_data[] = {
3153 {D3DTOP_SELECTARG1, "SELECTARG1", D3DTEXOPCAPS_SELECTARG1, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
3154 {D3DTOP_SELECTARG2, "SELECTARG2", D3DTEXOPCAPS_SELECTARG2, D3DCOLOR_ARGB(0x00, 0x33, 0x33, 0x33)},
3155 {D3DTOP_MODULATE, "MODULATE", D3DTEXOPCAPS_MODULATE, D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x00)},
3156 {D3DTOP_MODULATE2X, "MODULATE2X", D3DTEXOPCAPS_MODULATE2X, D3DCOLOR_ARGB(0x00, 0x00, 0x66, 0x00)},
3157 {D3DTOP_MODULATE4X, "MODULATE4X", D3DTEXOPCAPS_MODULATE4X, D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
3158 {D3DTOP_ADD, "ADD", D3DTEXOPCAPS_ADD, D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
3160 {D3DTOP_ADDSIGNED, "ADDSIGNED", D3DTEXOPCAPS_ADDSIGNED, D3DCOLOR_ARGB(0x00, 0x00, 0xb2, 0x00)},
3161 {D3DTOP_ADDSIGNED2X, "ADDSIGNED2X", D3DTEXOPCAPS_ADDSIGNED2X, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
3163 {D3DTOP_SUBTRACT, "SUBTRACT", D3DTEXOPCAPS_SUBTRACT, D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
3164 {D3DTOP_ADDSMOOTH, "ADDSMOOTH", D3DTEXOPCAPS_ADDSMOOTH, D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
3165 {D3DTOP_BLENDDIFFUSEALPHA, "BLENDDIFFUSEALPHA", D3DTEXOPCAPS_BLENDDIFFUSEALPHA, D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
3166 {D3DTOP_BLENDTEXTUREALPHA, "BLENDTEXTUREALPHA", D3DTEXOPCAPS_BLENDTEXTUREALPHA, D3DCOLOR_ARGB(0x00, 0x14, 0xad, 0x14)},
3167 {D3DTOP_BLENDFACTORALPHA, "BLENDFACTORALPHA", D3DTEXOPCAPS_BLENDFACTORALPHA, D3DCOLOR_ARGB(0x00, 0x07, 0xe4, 0x07)},
3168 {D3DTOP_BLENDTEXTUREALPHAPM, "BLENDTEXTUREALPHAPM", D3DTEXOPCAPS_BLENDTEXTUREALPHAPM, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
3169 {D3DTOP_BLENDCURRENTALPHA, "BLENDCURRENTALPHA", D3DTEXOPCAPS_BLENDCURRENTALPHA, D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
3170 {D3DTOP_MODULATEALPHA_ADDCOLOR, "MODULATEALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x1f, 0xff, 0x1f)},
3171 {D3DTOP_MODULATECOLOR_ADDALPHA, "MODULATECOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0x99, 0xcc, 0x99)},
3172 {D3DTOP_MODULATEINVALPHA_ADDCOLOR, "MODULATEINVALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
3173 {D3DTOP_MODULATEINVCOLOR_ADDALPHA, "MODULATEINVCOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0xcc, 0x99, 0xcc)},
3174 /* BUMPENVMAP & BUMPENVMAPLUMINANCE have their own tests */
3175 {D3DTOP_DOTPRODUCT3, "DOTPRODUCT2", D3DTEXOPCAPS_DOTPRODUCT3, D3DCOLOR_ARGB(0x00, 0x99, 0x99, 0x99)},
3176 {D3DTOP_MULTIPLYADD, "MULTIPLYADD", D3DTEXOPCAPS_MULTIPLYADD, D3DCOLOR_ARGB(0x00, 0xff, 0x33, 0x00)},
3177 {D3DTOP_LERP, "LERP", D3DTEXOPCAPS_LERP, D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x33)},
3180 window = create_window();
3181 d3d = Direct3DCreate8(D3D_SDK_VERSION);
3182 ok(!!d3d, "Failed to create a D3D object.\n");
3183 if (!(device = create_device(d3d, window, window, TRUE)))
3185 skip("Failed to create a D3D device, skipping tests.\n");
3186 goto done;
3189 memset(&caps, 0, sizeof(caps));
3190 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
3191 ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
3193 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX0);
3194 ok(SUCCEEDED(hr), "SetVertexShader failed with 0x%08x\n", hr);
3196 hr = IDirect3DDevice8_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture);
3197 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
3198 hr = IDirect3DTexture8_LockRect(texture, 0, &locked_rect, NULL, 0);
3199 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
3200 *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x99, 0x00, 0xff, 0x00);
3201 hr = IDirect3DTexture8_UnlockRect(texture, 0);
3202 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
3203 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
3204 ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
3206 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG0, D3DTA_DIFFUSE);
3207 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
3208 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
3209 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
3210 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
3211 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
3213 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
3214 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
3216 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3217 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
3218 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xdd333333);
3219 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
3220 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_ALPHA);
3221 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
3223 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
3224 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
3226 for (i = 0; i < ARRAY_SIZE(test_data); ++i)
3228 if (!(caps.TextureOpCaps & test_data[i].caps_flag))
3230 skip("tex operation %s not supported\n", test_data[i].name);
3231 continue;
3234 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLOROP, test_data[i].op);
3235 ok(SUCCEEDED(hr), "SetTextureStageState (%s) failed with 0x%08x\n", test_data[i].name, hr);
3237 hr = IDirect3DDevice8_BeginScene(device);
3238 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
3240 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
3241 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
3243 hr = IDirect3DDevice8_EndScene(device);
3244 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
3246 color = getPixelColor(device, 320, 240);
3247 ok(color_match(color, test_data[i].result, 3), "Operation %s returned color 0x%08x, expected 0x%08x\n",
3248 test_data[i].name, color, test_data[i].result);
3250 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
3251 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
3253 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
3254 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
3257 IDirect3DTexture8_Release(texture);
3258 refcount = IDirect3DDevice8_Release(device);
3259 ok(!refcount, "Device has %u references left.\n", refcount);
3260 done:
3261 IDirect3D8_Release(d3d);
3262 DestroyWindow(window);
3265 /* This test tests depth clamping / clipping behaviour:
3266 * - With software vertex processing, depth values are clamped to the
3267 * minimum / maximum z value when D3DRS_CLIPPING is disabled, and clipped
3268 * when D3DRS_CLIPPING is enabled. Pretransformed vertices behave the
3269 * same as regular vertices here.
3270 * - With hardware vertex processing, D3DRS_CLIPPING seems to be ignored.
3271 * Normal vertices are always clipped. Pretransformed vertices are
3272 * clipped when D3DPMISCCAPS_CLIPTLVERTS is set, clamped when it isn't.
3273 * - The viewport's MinZ/MaxZ is irrelevant for this.
3275 static void depth_clamp_test(void)
3277 IDirect3DDevice8 *device;
3278 D3DVIEWPORT8 vp;
3279 IDirect3D8 *d3d;
3280 D3DCOLOR color;
3281 ULONG refcount;
3282 D3DCAPS8 caps;
3283 HWND window;
3284 HRESULT hr;
3286 static const struct
3288 struct vec4 position;
3289 DWORD diffuse;
3291 quad1[] =
3293 {{ 0.0f, 0.0f, 5.0f, 1.0f}, 0xff002b7f},
3294 {{640.0f, 0.0f, 5.0f, 1.0f}, 0xff002b7f},
3295 {{ 0.0f, 480.0f, 5.0f, 1.0f}, 0xff002b7f},
3296 {{640.0f, 480.0f, 5.0f, 1.0f}, 0xff002b7f},
3298 quad2[] =
3300 {{ 0.0f, 300.0f, 10.0f, 1.0f}, 0xfff9e814},
3301 {{640.0f, 300.0f, 10.0f, 1.0f}, 0xfff9e814},
3302 {{ 0.0f, 360.0f, 10.0f, 1.0f}, 0xfff9e814},
3303 {{640.0f, 360.0f, 10.0f, 1.0f}, 0xfff9e814},
3305 quad3[] =
3307 {{112.0f, 108.0f, 5.0f, 1.0f}, 0xffffffff},
3308 {{208.0f, 108.0f, 5.0f, 1.0f}, 0xffffffff},
3309 {{112.0f, 204.0f, 5.0f, 1.0f}, 0xffffffff},
3310 {{208.0f, 204.0f, 5.0f, 1.0f}, 0xffffffff},
3312 quad4[] =
3314 {{ 42.0f, 41.0f, 10.0f, 1.0f}, 0xffffffff},
3315 {{112.0f, 41.0f, 10.0f, 1.0f}, 0xffffffff},
3316 {{ 42.0f, 108.0f, 10.0f, 1.0f}, 0xffffffff},
3317 {{112.0f, 108.0f, 10.0f, 1.0f}, 0xffffffff},
3319 static const struct
3321 struct vec3 position;
3322 DWORD diffuse;
3324 quad5[] =
3326 {{-0.5f, 0.5f, 10.0f}, 0xff14f914},
3327 {{ 0.5f, 0.5f, 10.0f}, 0xff14f914},
3328 {{-0.5f, -0.5f, 10.0f}, 0xff14f914},
3329 {{ 0.5f, -0.5f, 10.0f}, 0xff14f914},
3331 quad6[] =
3333 {{-1.0f, 0.5f, 10.0f}, 0xfff91414},
3334 {{ 1.0f, 0.5f, 10.0f}, 0xfff91414},
3335 {{-1.0f, 0.25f, 10.0f}, 0xfff91414},
3336 {{ 1.0f, 0.25f, 10.0f}, 0xfff91414},
3339 window = create_window();
3340 d3d = Direct3DCreate8(D3D_SDK_VERSION);
3341 ok(!!d3d, "Failed to create a D3D object.\n");
3342 if (!(device = create_device(d3d, window, window, TRUE)))
3344 skip("Failed to create a D3D device, skipping tests.\n");
3345 goto done;
3348 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
3349 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
3351 vp.X = 0;
3352 vp.Y = 0;
3353 vp.Width = 640;
3354 vp.Height = 480;
3355 vp.MinZ = 0.0;
3356 vp.MaxZ = 7.5;
3358 hr = IDirect3DDevice8_SetViewport(device, &vp);
3359 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
3361 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0, 0);
3362 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
3364 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, FALSE);
3365 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3366 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3367 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3368 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
3369 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3370 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
3371 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3373 hr = IDirect3DDevice8_BeginScene(device);
3374 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
3376 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
3377 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
3379 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
3380 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3381 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
3382 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3384 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, TRUE);
3385 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3387 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
3388 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3389 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(*quad4));
3390 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3392 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, FALSE);
3393 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3394 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
3395 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
3397 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad5, sizeof(*quad5));
3398 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3400 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, TRUE);
3401 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3403 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad6, sizeof(*quad6));
3404 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3406 hr = IDirect3DDevice8_EndScene(device);
3407 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
3409 if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
3411 color = getPixelColor(device, 75, 75);
3412 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
3413 color = getPixelColor(device, 150, 150);
3414 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
3415 color = getPixelColor(device, 320, 240);
3416 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
3417 color = getPixelColor(device, 320, 330);
3418 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
3419 color = getPixelColor(device, 320, 330);
3420 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
3422 else
3424 color = getPixelColor(device, 75, 75);
3425 ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
3426 color = getPixelColor(device, 150, 150);
3427 ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
3428 color = getPixelColor(device, 320, 240);
3429 ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);
3430 color = getPixelColor(device, 320, 330);
3431 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
3432 color = getPixelColor(device, 320, 330);
3433 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
3436 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
3437 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3439 refcount = IDirect3DDevice8_Release(device);
3440 ok(!refcount, "Device has %u references left.\n", refcount);
3441 done:
3442 IDirect3D8_Release(d3d);
3443 DestroyWindow(window);
3446 static void depth_buffer_test(void)
3448 IDirect3DSurface8 *backbuffer, *rt1, *rt2, *rt3;
3449 IDirect3DSurface8 *depth_stencil;
3450 IDirect3DDevice8 *device;
3451 unsigned int i, j;
3452 D3DVIEWPORT8 vp;
3453 IDirect3D8 *d3d;
3454 D3DCOLOR color;
3455 ULONG refcount;
3456 HWND window;
3457 HRESULT hr;
3459 static const struct
3461 struct vec3 position;
3462 DWORD diffuse;
3464 quad1[] =
3466 {{-1.0f, 1.0f, 0.33f}, 0xff00ff00},
3467 {{ 1.0f, 1.0f, 0.33f}, 0xff00ff00},
3468 {{-1.0f, -1.0f, 0.33f}, 0xff00ff00},
3469 {{ 1.0f, -1.0f, 0.33f}, 0xff00ff00},
3471 quad2[] =
3473 {{-1.0f, 1.0f, 0.50f}, 0xffff00ff},
3474 {{ 1.0f, 1.0f, 0.50f}, 0xffff00ff},
3475 {{-1.0f, -1.0f, 0.50f}, 0xffff00ff},
3476 {{ 1.0f, -1.0f, 0.50f}, 0xffff00ff},
3478 quad3[] =
3480 {{-1.0f, 1.0f, 0.66f}, 0xffff0000},
3481 {{ 1.0f, 1.0f, 0.66f}, 0xffff0000},
3482 {{-1.0f, -1.0f, 0.66f}, 0xffff0000},
3483 {{ 1.0f, -1.0f, 0.66f}, 0xffff0000},
3485 static const DWORD expected_colors[4][4] =
3487 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
3488 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
3489 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x00ff0000},
3490 {0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
3493 window = create_window();
3494 d3d = Direct3DCreate8(D3D_SDK_VERSION);
3495 ok(!!d3d, "Failed to create a D3D object.\n");
3496 if (!(device = create_device(d3d, window, window, TRUE)))
3498 skip("Failed to create a D3D device, skipping tests.\n");
3499 goto done;
3502 vp.X = 0;
3503 vp.Y = 0;
3504 vp.Width = 640;
3505 vp.Height = 480;
3506 vp.MinZ = 0.0;
3507 vp.MaxZ = 1.0;
3509 hr = IDirect3DDevice8_SetViewport(device, &vp);
3510 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
3512 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3513 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3514 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
3515 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3516 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
3517 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3518 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
3519 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3520 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
3521 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
3523 hr = IDirect3DDevice8_GetDepthStencilSurface(device, &depth_stencil);
3524 ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
3525 hr = IDirect3DDevice8_GetRenderTarget(device, &backbuffer);
3526 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
3527 hr = IDirect3DDevice8_CreateRenderTarget(device, 320, 240, D3DFMT_A8R8G8B8,
3528 D3DMULTISAMPLE_NONE, FALSE, &rt1);
3529 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
3530 hr = IDirect3DDevice8_CreateRenderTarget(device, 480, 360, D3DFMT_A8R8G8B8,
3531 D3DMULTISAMPLE_NONE, FALSE, &rt2);
3532 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
3533 hr = IDirect3DDevice8_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
3534 D3DMULTISAMPLE_NONE, FALSE, &rt3);
3535 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
3537 hr = IDirect3DDevice8_SetRenderTarget(device, rt3, depth_stencil);
3538 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
3539 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0f, 0);
3540 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
3542 hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, depth_stencil);
3543 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
3544 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
3545 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
3547 hr = IDirect3DDevice8_SetRenderTarget(device, rt1, depth_stencil);
3548 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
3549 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0f, 0);
3550 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
3552 hr = IDirect3DDevice8_SetRenderTarget(device, rt2, depth_stencil);
3553 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
3554 hr = IDirect3DDevice8_BeginScene(device);
3555 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
3556 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
3557 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3558 hr = IDirect3DDevice8_EndScene(device);
3559 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
3561 hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, depth_stencil);
3562 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
3564 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
3565 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3567 hr = IDirect3DDevice8_BeginScene(device);
3568 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
3569 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
3570 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3571 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
3572 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3573 hr = IDirect3DDevice8_EndScene(device);
3574 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
3576 for (i = 0; i < 4; ++i)
3578 for (j = 0; j < 4; ++j)
3580 unsigned int x = 80 * ((2 * j) + 1);
3581 unsigned int y = 60 * ((2 * i) + 1);
3582 color = getPixelColor(device, x, y);
3583 ok(color_match(color, expected_colors[i][j], 0),
3584 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors[i][j], x, y, color);
3588 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
3589 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3591 IDirect3DSurface8_Release(depth_stencil);
3592 IDirect3DSurface8_Release(backbuffer);
3593 IDirect3DSurface8_Release(rt3);
3594 IDirect3DSurface8_Release(rt2);
3595 IDirect3DSurface8_Release(rt1);
3596 refcount = IDirect3DDevice8_Release(device);
3597 ok(!refcount, "Device has %u references left.\n", refcount);
3598 done:
3599 IDirect3D8_Release(d3d);
3600 DestroyWindow(window);
3603 /* Test that partial depth copies work the way they're supposed to. The clear
3604 * on rt2 only needs a partial copy of the onscreen depth/stencil buffer, and
3605 * the following draw should only copy back the part that was modified. */
3606 static void depth_buffer2_test(void)
3608 IDirect3DSurface8 *backbuffer, *rt1, *rt2;
3609 IDirect3DSurface8 *depth_stencil;
3610 IDirect3DDevice8 *device;
3611 unsigned int i, j;
3612 D3DVIEWPORT8 vp;
3613 IDirect3D8 *d3d;
3614 D3DCOLOR color;
3615 ULONG refcount;
3616 HWND window;
3617 HRESULT hr;
3619 static const struct
3621 struct vec3 position;
3622 DWORD diffuse;
3624 quad[] =
3626 {{-1.0f, 1.0f, 0.66f}, 0xffff0000},
3627 {{ 1.0f, 1.0f, 0.66f}, 0xffff0000},
3628 {{-1.0f, -1.0f, 0.66f}, 0xffff0000},
3629 {{ 1.0f, -1.0f, 0.66f}, 0xffff0000},
3632 window = create_window();
3633 d3d = Direct3DCreate8(D3D_SDK_VERSION);
3634 ok(!!d3d, "Failed to create a D3D object.\n");
3635 if (!(device = create_device(d3d, window, window, TRUE)))
3637 skip("Failed to create a D3D device, skipping tests.\n");
3638 goto done;
3641 vp.X = 0;
3642 vp.Y = 0;
3643 vp.Width = 640;
3644 vp.Height = 480;
3645 vp.MinZ = 0.0;
3646 vp.MaxZ = 1.0;
3648 hr = IDirect3DDevice8_SetViewport(device, &vp);
3649 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
3651 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3652 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3653 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
3654 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3655 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
3656 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3657 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
3658 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3659 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
3660 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
3662 hr = IDirect3DDevice8_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
3663 D3DMULTISAMPLE_NONE, FALSE, &rt1);
3664 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
3665 hr = IDirect3DDevice8_CreateRenderTarget(device, 480, 360, D3DFMT_A8R8G8B8,
3666 D3DMULTISAMPLE_NONE, FALSE, &rt2);
3667 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
3668 hr = IDirect3DDevice8_GetDepthStencilSurface(device, &depth_stencil);
3669 ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
3670 hr = IDirect3DDevice8_GetRenderTarget(device, &backbuffer);
3671 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
3673 hr = IDirect3DDevice8_SetRenderTarget(device, rt1, depth_stencil);
3674 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
3675 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
3676 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
3678 hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, depth_stencil);
3679 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
3680 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 0.5f, 0);
3681 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
3683 hr = IDirect3DDevice8_SetRenderTarget(device, rt2, depth_stencil);
3684 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
3685 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0f, 0);
3686 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
3688 hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, depth_stencil);
3689 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
3691 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
3692 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3694 hr = IDirect3DDevice8_BeginScene(device);
3695 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
3696 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
3697 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3698 hr = IDirect3DDevice8_EndScene(device);
3699 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
3701 for (i = 0; i < 4; ++i)
3703 for (j = 0; j < 4; ++j)
3705 unsigned int x = 80 * ((2 * j) + 1);
3706 unsigned int y = 60 * ((2 * i) + 1);
3707 color = getPixelColor(device, x, y);
3708 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
3709 "Expected color 0x0000ff00 %u,%u, got 0x%08x.\n", x, y, color);
3713 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
3714 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3716 IDirect3DSurface8_Release(depth_stencil);
3717 IDirect3DSurface8_Release(backbuffer);
3718 IDirect3DSurface8_Release(rt2);
3719 IDirect3DSurface8_Release(rt1);
3720 refcount = IDirect3DDevice8_Release(device);
3721 ok(!refcount, "Device has %u references left.\n", refcount);
3722 done:
3723 IDirect3D8_Release(d3d);
3724 DestroyWindow(window);
3727 static void intz_test(void)
3729 IDirect3DSurface8 *original_rt, *rt;
3730 struct surface_readback rb;
3731 IDirect3DTexture8 *texture;
3732 IDirect3DDevice8 *device;
3733 IDirect3DSurface8 *ds;
3734 IDirect3D8 *d3d;
3735 ULONG refcount;
3736 D3DCAPS8 caps;
3737 HWND window;
3738 HRESULT hr;
3739 DWORD ps;
3740 UINT i;
3742 static const DWORD ps_code[] =
3744 0xffff0101, /* ps_1_1 */
3745 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c0, 1.0, 0.0, 1.0, 1.0 */
3746 0x00000051, 0xa00f0001, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c1, 0.0, 1.0, 0.0, 0.0 */
3747 0x00000042, 0xb00f0000, /* tex t0 */
3748 0x00000042, 0xb00f0001, /* tex t1 */
3749 0x00000005, 0xb00f0000, 0xa0e40000, 0xb0e40000, /* mul t0, c0, t0 */
3750 0x00000004, 0x800f0000, 0xa0e40001, 0xb0e40001, 0xb0e40000, /* mad r0, c1, t1, t0 */
3751 0x0000ffff, /* end */
3753 static const struct
3755 float x, y, z;
3756 float s0, t0, p0;
3757 float s1, t1, p1, q1;
3759 quad[] =
3761 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.5f},
3762 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
3763 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
3764 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.5f},
3766 half_quad_1[] =
3768 { -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.5f},
3769 { 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
3770 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
3771 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.5f},
3773 half_quad_2[] =
3775 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.5f},
3776 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
3777 { -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
3778 { 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.5f},
3780 static const struct
3782 UINT x, y;
3783 D3DCOLOR color;
3785 expected_colors[] =
3787 { 80, 100, 0x20204020},
3788 {240, 100, 0x6060bf60},
3789 {400, 100, 0x9f9f409f},
3790 {560, 100, 0xdfdfbfdf},
3791 { 80, 450, 0x20204020},
3792 {240, 450, 0x6060bf60},
3793 {400, 450, 0x9f9f409f},
3794 {560, 450, 0xdfdfbfdf},
3797 window = create_window();
3798 d3d = Direct3DCreate8(D3D_SDK_VERSION);
3799 ok(!!d3d, "Failed to create a D3D object.\n");
3800 if (!(device = create_device(d3d, window, window, TRUE)))
3802 skip("Failed to create a D3D device, skipping tests.\n");
3803 goto done;
3806 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
3807 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
3808 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 1))
3810 skip("No pixel shader 1.1 support, skipping INTZ test.\n");
3811 IDirect3DDevice8_Release(device);
3812 goto done;
3814 if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
3816 skip("No unconditional NP2 texture support, skipping INTZ test.\n");
3817 IDirect3DDevice8_Release(device);
3818 goto done;
3821 if (FAILED(hr = IDirect3D8_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
3822 D3DFMT_X8R8G8B8, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, MAKEFOURCC('I','N','T','Z'))))
3824 skip("No INTZ support, skipping INTZ test.\n");
3825 IDirect3DDevice8_Release(device);
3826 goto done;
3829 hr = IDirect3DDevice8_GetRenderTarget(device, &original_rt);
3830 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
3832 hr = IDirect3DDevice8_CreateTexture(device, 640, 480, 1,
3833 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture);
3834 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
3835 hr = IDirect3DDevice8_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
3836 D3DMULTISAMPLE_NONE, FALSE, &rt);
3837 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
3838 hr = IDirect3DDevice8_CreatePixelShader(device, ps_code, &ps);
3839 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
3841 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX2
3842 | D3DFVF_TEXCOORDSIZE3(0) | D3DFVF_TEXCOORDSIZE4(1));
3843 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
3844 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
3845 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3846 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
3847 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3848 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
3849 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3850 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3851 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3853 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MINFILTER, D3DTEXF_POINT);
3854 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3855 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MIPFILTER, D3DTEXF_POINT);
3856 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3857 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MAGFILTER, D3DTEXF_POINT);
3858 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3859 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
3860 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3862 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP);
3863 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3864 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP);
3865 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3866 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MAGFILTER, D3DTEXF_POINT);
3867 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3868 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MINFILTER, D3DTEXF_POINT);
3869 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3870 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MIPFILTER, D3DTEXF_POINT);
3871 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3872 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS,
3873 D3DTTFF_COUNT4 | D3DTTFF_PROJECTED);
3874 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3876 hr = IDirect3DTexture8_GetSurfaceLevel(texture, 0, &ds);
3877 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
3879 /* Render offscreen, using the INTZ texture as depth buffer */
3880 hr = IDirect3DDevice8_SetRenderTarget(device, rt, ds);
3881 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
3882 hr = IDirect3DDevice8_SetPixelShader(device, 0);
3883 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
3885 /* Setup the depth/stencil surface. */
3886 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
3887 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
3889 hr = IDirect3DDevice8_BeginScene(device);
3890 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
3891 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
3892 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3893 hr = IDirect3DDevice8_EndScene(device);
3894 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
3896 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, NULL);
3897 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
3898 IDirect3DSurface8_Release(ds);
3899 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
3900 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
3901 hr = IDirect3DDevice8_SetTexture(device, 1, (IDirect3DBaseTexture8 *)texture);
3902 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
3903 hr = IDirect3DDevice8_SetPixelShader(device, ps);
3904 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
3906 /* Read the depth values back. */
3907 hr = IDirect3DDevice8_BeginScene(device);
3908 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
3909 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
3910 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3911 hr = IDirect3DDevice8_EndScene(device);
3912 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
3914 get_rt_readback(original_rt, &rb);
3915 for (i = 0; i < ARRAY_SIZE(expected_colors); ++i)
3917 D3DCOLOR color = get_readback_color(&rb, expected_colors[i].x, expected_colors[i].y);
3918 ok(color_match(color, expected_colors[i].color, 1),
3919 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
3920 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
3922 release_surface_readback(&rb);
3924 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
3925 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
3927 hr = IDirect3DDevice8_SetTexture(device, 0, NULL);
3928 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
3929 hr = IDirect3DDevice8_SetTexture(device, 1, NULL);
3930 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
3931 IDirect3DTexture8_Release(texture);
3933 /* Render onscreen while using the INTZ texture as depth buffer */
3934 hr = IDirect3DDevice8_CreateTexture(device, 640, 480, 1,
3935 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture);
3936 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
3937 hr = IDirect3DTexture8_GetSurfaceLevel(texture, 0, &ds);
3938 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
3939 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, ds);
3940 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
3941 hr = IDirect3DDevice8_SetPixelShader(device, 0);
3942 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
3944 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
3945 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
3947 hr = IDirect3DDevice8_BeginScene(device);
3948 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
3949 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
3950 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3951 hr = IDirect3DDevice8_EndScene(device);
3952 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
3954 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, NULL);
3955 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
3956 IDirect3DSurface8_Release(ds);
3957 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
3958 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
3959 hr = IDirect3DDevice8_SetTexture(device, 1, (IDirect3DBaseTexture8 *)texture);
3960 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
3961 hr = IDirect3DDevice8_SetPixelShader(device, ps);
3962 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
3964 /* Read the depth values back. */
3965 hr = IDirect3DDevice8_BeginScene(device);
3966 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
3967 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
3968 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3969 hr = IDirect3DDevice8_EndScene(device);
3970 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
3972 get_rt_readback(original_rt, &rb);
3973 for (i = 0; i < ARRAY_SIZE(expected_colors); ++i)
3975 D3DCOLOR color = get_readback_color(&rb, expected_colors[i].x, expected_colors[i].y);
3976 ok(color_match(color, expected_colors[i].color, 1),
3977 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
3978 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
3980 release_surface_readback(&rb);
3982 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
3983 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
3985 hr = IDirect3DDevice8_SetTexture(device, 0, NULL);
3986 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
3987 hr = IDirect3DDevice8_SetTexture(device, 1, NULL);
3988 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
3989 IDirect3DTexture8_Release(texture);
3991 /* Render offscreen, then onscreen, and finally check the INTZ texture in both areas */
3992 hr = IDirect3DDevice8_CreateTexture(device, 640, 480, 1,
3993 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture);
3994 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
3995 hr = IDirect3DTexture8_GetSurfaceLevel(texture, 0, &ds);
3996 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
3997 hr = IDirect3DDevice8_SetRenderTarget(device, rt, ds);
3998 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
3999 hr = IDirect3DDevice8_SetPixelShader(device, 0);
4000 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
4002 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
4003 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
4005 hr = IDirect3DDevice8_BeginScene(device);
4006 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
4007 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, half_quad_1, sizeof(*half_quad_1));
4008 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
4009 hr = IDirect3DDevice8_EndScene(device);
4010 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
4012 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, ds);
4013 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
4015 hr = IDirect3DDevice8_BeginScene(device);
4016 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
4017 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, half_quad_2, sizeof(*half_quad_2));
4018 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
4019 hr = IDirect3DDevice8_EndScene(device);
4020 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
4022 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, NULL);
4023 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
4024 IDirect3DSurface8_Release(ds);
4025 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
4026 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
4027 hr = IDirect3DDevice8_SetTexture(device, 1, (IDirect3DBaseTexture8 *)texture);
4028 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
4029 hr = IDirect3DDevice8_SetPixelShader(device, ps);
4030 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
4032 /* Read the depth values back. */
4033 hr = IDirect3DDevice8_BeginScene(device);
4034 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
4035 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
4036 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
4037 hr = IDirect3DDevice8_EndScene(device);
4038 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
4040 get_rt_readback(original_rt, &rb);
4041 for (i = 0; i < ARRAY_SIZE(expected_colors); ++i)
4043 D3DCOLOR color = get_readback_color(&rb, expected_colors[i].x, expected_colors[i].y);
4044 ok(color_match(color, expected_colors[i].color, 1),
4045 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
4046 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
4048 release_surface_readback(&rb);
4050 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
4051 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
4053 IDirect3DTexture8_Release(texture);
4054 hr = IDirect3DDevice8_DeletePixelShader(device, ps);
4055 ok(SUCCEEDED(hr), "DeletePixelShader failed, hr %#x.\n", hr);
4056 IDirect3DSurface8_Release(original_rt);
4057 IDirect3DSurface8_Release(rt);
4058 refcount = IDirect3DDevice8_Release(device);
4059 ok(!refcount, "Device has %u references left.\n", refcount);
4060 done:
4061 IDirect3D8_Release(d3d);
4062 DestroyWindow(window);
4065 static void shadow_test(void)
4067 IDirect3DSurface8 *original_rt, *rt;
4068 struct surface_readback rb;
4069 IDirect3DDevice8 *device;
4070 IDirect3D8 *d3d;
4071 ULONG refcount;
4072 D3DCAPS8 caps;
4073 HWND window;
4074 HRESULT hr;
4075 DWORD ps;
4076 UINT i;
4078 static const DWORD ps_code[] =
4080 0xffff0101, /* ps_1_1 */
4081 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c0, 1.0, 0.0, 1.0, 1.0 */
4082 0x00000051, 0xa00f0001, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c1, 0.0, 1.0, 0.0, 0.0 */
4083 0x00000042, 0xb00f0000, /* tex t0 */
4084 0x00000042, 0xb00f0001, /* tex t1 */
4085 0x00000005, 0xb00f0000, 0xa0e40000, 0xb0e40000, /* mul t0, c0, t0 */
4086 0x00000004, 0x800f0000, 0xa0e40001, 0xb0e40001, 0xb0e40000, /* mad r0, c1, t1, t0 */
4087 0x0000ffff, /* end */
4089 static const struct
4091 D3DFORMAT format;
4092 const char *name;
4094 formats[] =
4096 {D3DFMT_D16_LOCKABLE, "D3DFMT_D16_LOCKABLE"},
4097 {D3DFMT_D32, "D3DFMT_D32"},
4098 {D3DFMT_D15S1, "D3DFMT_D15S1"},
4099 {D3DFMT_D24S8, "D3DFMT_D24S8"},
4100 {D3DFMT_D24X8, "D3DFMT_D24X8"},
4101 {D3DFMT_D24X4S4, "D3DFMT_D24X4S4"},
4102 {D3DFMT_D16, "D3DFMT_D16"},
4104 static const struct
4106 float x, y, z;
4107 float s0, t0, p0;
4108 float s1, t1, p1, q1;
4110 quad[] =
4112 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f},
4113 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f},
4114 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
4115 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f},
4117 static const struct
4119 UINT x, y;
4120 D3DCOLOR color;
4122 expected_colors[] =
4124 {400, 60, 0x00000000},
4125 {560, 180, 0xffff00ff},
4126 {560, 300, 0xffff00ff},
4127 {400, 420, 0xffffffff},
4128 {240, 420, 0xffffffff},
4129 { 80, 300, 0x00000000},
4130 { 80, 180, 0x00000000},
4131 {240, 60, 0x00000000},
4134 window = create_window();
4135 d3d = Direct3DCreate8(D3D_SDK_VERSION);
4136 ok(!!d3d, "Failed to create a D3D object.\n");
4137 if (!(device = create_device(d3d, window, window, TRUE)))
4139 skip("Failed to create a D3D device, skipping tests.\n");
4140 goto done;
4143 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
4144 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
4145 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 1))
4147 skip("No pixel shader 1.1 support, skipping shadow test.\n");
4148 IDirect3DDevice8_Release(device);
4149 goto done;
4152 hr = IDirect3DDevice8_GetRenderTarget(device, &original_rt);
4153 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
4155 hr = IDirect3DDevice8_CreateRenderTarget(device, 1024, 1024, D3DFMT_A8R8G8B8,
4156 D3DMULTISAMPLE_NONE, FALSE, &rt);
4157 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
4158 hr = IDirect3DDevice8_CreatePixelShader(device, ps_code, &ps);
4159 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
4161 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX2
4162 | D3DFVF_TEXCOORDSIZE3(0) | D3DFVF_TEXCOORDSIZE4(1));
4163 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
4164 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
4165 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
4166 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
4167 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
4168 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
4169 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
4170 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
4171 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
4173 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MINFILTER, D3DTEXF_POINT);
4174 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
4175 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MIPFILTER, D3DTEXF_POINT);
4176 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
4177 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MAGFILTER, D3DTEXF_POINT);
4178 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
4179 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
4180 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
4182 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP);
4183 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
4184 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP);
4185 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
4186 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MAGFILTER, D3DTEXF_POINT);
4187 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
4188 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MINFILTER, D3DTEXF_POINT);
4189 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
4190 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MIPFILTER, D3DTEXF_POINT);
4191 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
4192 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS,
4193 D3DTTFF_COUNT4 | D3DTTFF_PROJECTED);
4194 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
4196 for (i = 0; i < ARRAY_SIZE(formats); ++i)
4198 D3DFORMAT format = formats[i].format;
4199 IDirect3DTexture8 *texture;
4200 IDirect3DSurface8 *ds;
4201 unsigned int j;
4203 if (FAILED(IDirect3D8_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
4204 D3DFMT_X8R8G8B8, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, format)))
4205 continue;
4207 hr = IDirect3DDevice8_CreateTexture(device, 1024, 1024, 1,
4208 D3DUSAGE_DEPTHSTENCIL, format, D3DPOOL_DEFAULT, &texture);
4209 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
4211 hr = IDirect3DTexture8_GetSurfaceLevel(texture, 0, &ds);
4212 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
4214 hr = IDirect3DDevice8_SetRenderTarget(device, rt, ds);
4215 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
4217 hr = IDirect3DDevice8_SetPixelShader(device, 0);
4218 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
4220 /* Setup the depth/stencil surface. */
4221 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
4222 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
4224 hr = IDirect3DDevice8_BeginScene(device);
4225 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
4226 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
4227 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
4228 hr = IDirect3DDevice8_EndScene(device);
4229 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
4231 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, NULL);
4232 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
4233 IDirect3DSurface8_Release(ds);
4235 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
4236 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
4237 hr = IDirect3DDevice8_SetTexture(device, 1, (IDirect3DBaseTexture8 *)texture);
4238 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
4240 hr = IDirect3DDevice8_SetPixelShader(device, ps);
4241 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
4243 /* Do the actual shadow mapping. */
4244 hr = IDirect3DDevice8_BeginScene(device);
4245 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
4246 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
4247 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
4248 hr = IDirect3DDevice8_EndScene(device);
4249 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
4251 hr = IDirect3DDevice8_SetTexture(device, 0, NULL);
4252 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
4253 hr = IDirect3DDevice8_SetTexture(device, 1, NULL);
4254 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
4255 IDirect3DTexture8_Release(texture);
4257 get_rt_readback(original_rt, &rb);
4258 for (j = 0; j < ARRAY_SIZE(expected_colors); ++j)
4260 D3DCOLOR color = get_readback_color(&rb, expected_colors[j].x, expected_colors[j].y);
4261 /* Geforce 7 on Windows returns 1.0 in alpha when the depth format is D24S8 or D24X8,
4262 * whereas other GPUs (all AMD, newer Nvidia) return the same value they return in .rgb.
4263 * Accept alpha mismatches as broken but make sure to check the color channels. */
4264 ok(color_match(color, expected_colors[j].color, 0)
4265 || broken(color_match(color & 0x00ffffff, expected_colors[j].color & 0x00ffffff, 0)),
4266 "Expected color 0x%08x at (%u, %u) for format %s, got 0x%08x.\n",
4267 expected_colors[j].color, expected_colors[j].x, expected_colors[j].y,
4268 formats[i].name, color);
4270 release_surface_readback(&rb);
4272 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
4273 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
4276 hr = IDirect3DDevice8_DeletePixelShader(device, ps);
4277 ok(SUCCEEDED(hr), "DeletePixelShader failed, hr %#x.\n", hr);
4278 IDirect3DSurface8_Release(original_rt);
4279 IDirect3DSurface8_Release(rt);
4280 refcount = IDirect3DDevice8_Release(device);
4281 ok(!refcount, "Device has %u references left.\n", refcount);
4282 done:
4283 IDirect3D8_Release(d3d);
4284 DestroyWindow(window);
4287 static void multisample_copy_rects_test(void)
4289 IDirect3DSurface8 *ds, *ds_plain, *rt, *readback;
4290 RECT src_rect = {64, 64, 128, 128};
4291 POINT dst_point = {96, 96};
4292 D3DLOCKED_RECT locked_rect;
4293 IDirect3DDevice8 *device;
4294 IDirect3D8 *d3d;
4295 D3DCOLOR color;
4296 ULONG refcount;
4297 HWND window;
4298 HRESULT hr;
4300 window = create_window();
4301 d3d = Direct3DCreate8(D3D_SDK_VERSION);
4302 ok(!!d3d, "Failed to create a D3D object.\n");
4303 if (!(device = create_device(d3d, window, window, TRUE)))
4305 skip("Failed to create a D3D device, skipping tests.\n");
4306 goto done;
4309 if (FAILED(IDirect3D8_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT,
4310 D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES)))
4312 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping multisampled CopyRects test.\n");
4313 IDirect3DDevice8_Release(device);
4314 goto done;
4317 hr = IDirect3DDevice8_CreateRenderTarget(device, 256, 256, D3DFMT_A8R8G8B8,
4318 D3DMULTISAMPLE_2_SAMPLES, FALSE, &rt);
4319 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
4320 hr = IDirect3DDevice8_CreateDepthStencilSurface(device, 256, 256, D3DFMT_D24S8,
4321 D3DMULTISAMPLE_2_SAMPLES, &ds);
4322 ok(SUCCEEDED(hr), "Failed to create depth stencil surface, hr %#x.\n", hr);
4323 hr = IDirect3DDevice8_CreateDepthStencilSurface(device, 256, 256, D3DFMT_D24S8,
4324 D3DMULTISAMPLE_NONE, &ds_plain);
4325 ok(SUCCEEDED(hr), "Failed to create depth stencil surface, hr %#x.\n", hr);
4326 hr = IDirect3DDevice8_CreateImageSurface(device, 256, 256, D3DFMT_A8R8G8B8, &readback);
4327 ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
4329 hr = IDirect3DDevice8_SetRenderTarget(device, rt, ds);
4330 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
4332 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
4333 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
4335 hr = IDirect3DDevice8_CopyRects(device, rt, NULL, 0, readback, NULL);
4336 ok(SUCCEEDED(hr), "Failed to read render target back, hr %#x.\n", hr);
4338 hr = IDirect3DDevice8_CopyRects(device, ds, NULL, 0, ds_plain, NULL);
4339 ok(hr == D3DERR_INVALIDCALL, "Depth buffer copy, hr %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
4341 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4342 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
4344 hr = IDirect3DDevice8_CopyRects(device, rt, &src_rect, 1, readback, &dst_point);
4345 ok(SUCCEEDED(hr), "Failed to read render target back, hr %#x.\n", hr);
4347 hr = IDirect3DSurface8_LockRect(readback, &locked_rect, NULL, D3DLOCK_READONLY);
4348 ok(SUCCEEDED(hr), "Failed to lock readback surface, hr %#x.\n", hr);
4350 color = *(DWORD *)((BYTE *)locked_rect.pBits + 31 * locked_rect.Pitch + 31 * 4);
4351 ok(color == 0xff00ff00, "Got unexpected color 0x%08x.\n", color);
4353 color = *(DWORD *)((BYTE *)locked_rect.pBits + 127 * locked_rect.Pitch + 127 * 4);
4354 ok(color == 0xffff0000, "Got unexpected color 0x%08x.\n", color);
4356 hr = IDirect3DSurface8_UnlockRect(readback);
4357 ok(SUCCEEDED(hr), "Failed to unlock readback surface, hr %#x.\n", hr);
4359 IDirect3DSurface8_Release(readback);
4360 IDirect3DSurface8_Release(ds_plain);
4361 IDirect3DSurface8_Release(ds);
4362 IDirect3DSurface8_Release(rt);
4363 refcount = IDirect3DDevice8_Release(device);
4364 ok(!refcount, "Device has %u references left.\n", refcount);
4365 done:
4366 IDirect3D8_Release(d3d);
4367 DestroyWindow(window);
4370 static void resz_test(void)
4372 IDirect3DSurface8 *rt, *original_rt, *ds, *original_ds, *intz_ds;
4373 IDirect3DTexture8 *texture;
4374 IDirect3DDevice8 *device;
4375 IDirect3D8 *d3d;
4376 DWORD ps, value;
4377 unsigned int i;
4378 ULONG refcount;
4379 D3DCAPS8 caps;
4380 HWND window;
4381 HRESULT hr;
4383 static const DWORD ps_code[] =
4385 0xffff0101, /* ps_1_1 */
4386 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1.0, 0.0, 0.0, 0.0 */
4387 0x00000051, 0xa00f0001, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c1, 0.0, 1.0, 0.0, 0.0 */
4388 0x00000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c2, 0.0, 0.0, 1.0, 0.0 */
4389 0x00000042, 0xb00f0000, /* tex t0 */
4390 0x00000042, 0xb00f0001, /* tex t1 */
4391 0x00000008, 0xb0070001, 0xa0e40000, 0xb0e40001, /* dp3 t1.xyz, c0, t1 */
4392 0x00000005, 0x80070000, 0xa0e40001, 0xb0e40001, /* mul r0.xyz, c1, t1 */
4393 0x00000004, 0x80070000, 0xa0e40000, 0xb0e40000, 0x80e40000, /* mad r0.xyz, c0, t0, r0 */
4394 0x40000001, 0x80080000, 0xa0aa0002, /* +mov r0.w, c2.z */
4395 0x0000ffff, /* end */
4397 static const struct
4399 float x, y, z;
4400 float s0, t0, p0;
4401 float s1, t1, p1, q1;
4403 quad[] =
4405 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.5f},
4406 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
4407 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
4408 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.5f},
4410 static const struct
4412 UINT x, y;
4413 D3DCOLOR color;
4415 expected_colors[] =
4417 { 80, 100, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
4418 {240, 100, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
4419 {400, 100, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
4420 {560, 100, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
4421 { 80, 450, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
4422 {240, 450, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
4423 {400, 450, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
4424 {560, 450, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
4427 window = create_window();
4428 d3d = Direct3DCreate8(D3D_SDK_VERSION);
4429 ok(!!d3d, "Failed to create a D3D object.\n");
4430 if (!(device = create_device(d3d, window, window, TRUE)))
4432 skip("Failed to create a D3D device, skipping tests.\n");
4433 goto done;
4436 if (FAILED(IDirect3D8_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT,
4437 D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES)))
4439 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping RESZ test.\n");
4440 IDirect3DDevice8_Release(device);
4441 goto done;
4443 if (FAILED(IDirect3D8_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT,
4444 D3DDEVTYPE_HAL, D3DFMT_D24S8, TRUE, D3DMULTISAMPLE_2_SAMPLES)))
4446 skip("Multisampling not supported for D3DFMT_D24S8, skipping RESZ test.\n");
4447 IDirect3DDevice8_Release(device);
4448 goto done;
4450 if (FAILED(IDirect3D8_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
4451 D3DFMT_X8R8G8B8, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, MAKEFOURCC('I','N','T','Z'))))
4453 skip("No INTZ support, skipping RESZ test.\n");
4454 IDirect3DDevice8_Release(device);
4455 goto done;
4457 if (FAILED(IDirect3D8_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
4458 D3DFMT_X8R8G8B8, D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE, MAKEFOURCC('R','E','S','Z'))))
4460 skip("No RESZ support, skipping RESZ test.\n");
4461 IDirect3DDevice8_Release(device);
4462 goto done;
4465 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
4466 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
4467 if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
4469 skip("No unconditional NP2 texture support, skipping INTZ test.\n");
4470 IDirect3DDevice8_Release(device);
4471 goto done;
4474 hr = IDirect3DDevice8_GetRenderTarget(device, &original_rt);
4475 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
4476 hr = IDirect3DDevice8_GetDepthStencilSurface(device, &original_ds);
4477 ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#x.\n", hr);
4479 hr = IDirect3DDevice8_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
4480 D3DMULTISAMPLE_2_SAMPLES, FALSE, &rt);
4481 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
4482 hr = IDirect3DDevice8_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
4483 D3DMULTISAMPLE_2_SAMPLES, &ds);
4485 hr = IDirect3DDevice8_CreateTexture(device, 640, 480, 1,
4486 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture);
4487 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
4488 hr = IDirect3DTexture8_GetSurfaceLevel(texture, 0, &intz_ds);
4489 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
4491 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, intz_ds);
4492 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
4493 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
4494 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
4496 hr = IDirect3DDevice8_SetRenderTarget(device, rt, ds);
4497 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
4498 IDirect3DSurface8_Release(intz_ds);
4499 hr = IDirect3DDevice8_CreatePixelShader(device, ps_code, &ps);
4500 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
4502 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX2
4503 | D3DFVF_TEXCOORDSIZE3(0) | D3DFVF_TEXCOORDSIZE4(1));
4504 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
4505 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
4506 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
4507 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
4508 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
4509 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
4510 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
4511 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
4512 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
4514 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MINFILTER, D3DTEXF_POINT);
4515 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
4516 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MIPFILTER, D3DTEXF_POINT);
4517 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
4518 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MAGFILTER, D3DTEXF_POINT);
4519 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
4520 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
4521 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
4523 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP);
4524 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
4525 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP);
4526 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
4527 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MAGFILTER, D3DTEXF_POINT);
4528 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
4529 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MINFILTER, D3DTEXF_POINT);
4530 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
4531 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MIPFILTER, D3DTEXF_POINT);
4532 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
4533 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS,
4534 D3DTTFF_COUNT4 | D3DTTFF_PROJECTED);
4535 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
4537 /* Render offscreen (multisampled), blit the depth buffer into the INTZ texture and then check its contents. */
4538 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
4539 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
4541 hr = IDirect3DDevice8_BeginScene(device);
4542 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
4543 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
4544 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
4546 /* The destination depth texture has to be bound to sampler 0 */
4547 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
4548 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
4550 /* the ATI "spec" says you have to do a dummy draw to ensure correct commands ordering */
4551 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, FALSE);
4552 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
4553 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
4554 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
4555 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0);
4556 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
4557 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
4558 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
4559 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, TRUE);
4560 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
4561 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
4562 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
4563 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0xf);
4564 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
4566 /* The actual multisampled depth buffer resolve happens here */
4567 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
4568 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
4569 hr = IDirect3DDevice8_GetRenderState(device, D3DRS_POINTSIZE, &value);
4570 ok(SUCCEEDED(hr) && value == 0x7fa05000, "GetRenderState failed, hr %#x, value %#x.\n", hr, value);
4572 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, NULL);
4573 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
4574 hr = IDirect3DDevice8_SetTexture(device, 1, (IDirect3DBaseTexture8 *)texture);
4575 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
4576 hr = IDirect3DDevice8_SetPixelShader(device, ps);
4577 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
4579 /* Read the depth values back. */
4580 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
4581 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
4582 hr = IDirect3DDevice8_EndScene(device);
4583 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
4585 for (i = 0; i < ARRAY_SIZE(expected_colors); ++i)
4587 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
4588 ok(color_match(color, expected_colors[i].color, 1),
4589 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
4590 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
4593 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
4594 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
4596 /* Test edge cases - try with no texture at all */
4597 hr = IDirect3DDevice8_SetTexture(device, 0, NULL);
4598 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
4599 hr = IDirect3DDevice8_SetTexture(device, 1, NULL);
4600 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
4601 hr = IDirect3DDevice8_SetRenderTarget(device, rt, ds);
4602 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
4604 hr = IDirect3DDevice8_BeginScene(device);
4605 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
4606 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
4607 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
4608 hr = IDirect3DDevice8_EndScene(device);
4609 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
4611 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
4612 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
4614 /* With a non-multisampled depth buffer */
4615 IDirect3DSurface8_Release(ds);
4616 IDirect3DSurface8_Release(rt);
4617 hr = IDirect3DDevice8_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
4618 D3DMULTISAMPLE_NONE, &ds);
4620 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, ds);
4621 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
4622 hr = IDirect3DDevice8_SetPixelShader(device, 0);
4623 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
4625 hr = IDirect3DDevice8_BeginScene(device);
4626 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
4627 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
4628 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
4629 hr = IDirect3DDevice8_EndScene(device);
4630 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
4632 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
4633 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
4635 hr = IDirect3DDevice8_BeginScene(device);
4636 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
4637 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, FALSE);
4638 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
4639 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
4640 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
4641 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0);
4642 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
4643 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
4644 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
4645 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, TRUE);
4646 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
4647 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
4648 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
4649 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0xf);
4650 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
4651 hr = IDirect3DDevice8_EndScene(device);
4652 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
4654 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
4655 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
4657 hr = IDirect3DDevice8_SetTexture(device, 1, (IDirect3DBaseTexture8 *)texture);
4658 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
4659 hr = IDirect3DDevice8_SetPixelShader(device, ps);
4660 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
4662 /* Read the depth values back. */
4663 hr = IDirect3DDevice8_BeginScene(device);
4664 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
4665 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
4666 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
4667 hr = IDirect3DDevice8_EndScene(device);
4668 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
4670 for (i = 0; i < ARRAY_SIZE(expected_colors); ++i)
4672 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
4673 ok(color_match(color, expected_colors[i].color, 1),
4674 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
4675 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
4678 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
4679 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
4681 IDirect3DSurface8_Release(ds);
4682 IDirect3DTexture8_Release(texture);
4683 hr = IDirect3DDevice8_DeletePixelShader(device, ps);
4684 ok(SUCCEEDED(hr), "DeletePixelShader failed, hr %#x.\n", hr);
4685 IDirect3DSurface8_Release(original_ds);
4686 IDirect3DSurface8_Release(original_rt);
4688 refcount = IDirect3DDevice8_Release(device);
4689 ok(!refcount, "Device has %u references left.\n", refcount);
4690 done:
4691 IDirect3D8_Release(d3d);
4692 DestroyWindow(window);
4695 static void zenable_test(void)
4697 IDirect3DDevice8 *device;
4698 IDirect3D8 *d3d;
4699 D3DCOLOR color;
4700 ULONG refcount;
4701 D3DCAPS8 caps;
4702 HWND window;
4703 HRESULT hr;
4704 UINT x, y;
4705 UINT i, j;
4706 UINT test;
4707 IDirect3DSurface8 *ds, *rt;
4709 static const struct
4711 struct vec4 position;
4712 D3DCOLOR diffuse;
4714 tquad[] =
4716 {{ 0.0f, 480.0f, -0.5f, 1.0f}, 0xff00ff00},
4717 {{ 0.0f, 0.0f, -0.5f, 1.0f}, 0xff00ff00},
4718 {{640.0f, 480.0f, 1.5f, 1.0f}, 0xff00ff00},
4719 {{640.0f, 0.0f, 1.5f, 1.0f}, 0xff00ff00},
4722 window = create_window();
4723 d3d = Direct3DCreate8(D3D_SDK_VERSION);
4724 ok(!!d3d, "Failed to create a D3D object.\n");
4725 if (!(device = create_device(d3d, window, window, TRUE)))
4727 skip("Failed to create a D3D device, skipping tests.\n");
4728 goto done;
4731 hr = IDirect3DDevice8_GetDepthStencilSurface(device, &ds);
4732 ok(SUCCEEDED(hr), "Failed to get depth stencil surface, hr %#x.\n", hr);
4733 hr = IDirect3DDevice8_GetRenderTarget(device, &rt);
4734 ok(SUCCEEDED(hr), "Failed to get render target surface, hr %#x.\n", hr);
4736 for (test = 0; test < 2; ++test)
4738 /* The Windows 8 testbot (WARP) appears to clip with
4739 * ZENABLE = D3DZB_TRUE and no depth buffer set. */
4740 static const D3DCOLOR expected_broken[] =
4742 0x00ff0000, 0x0000ff00, 0x0000ff00, 0x00ff0000,
4743 0x00ff0000, 0x0000ff00, 0x0000ff00, 0x00ff0000,
4744 0x00ff0000, 0x0000ff00, 0x0000ff00, 0x00ff0000,
4745 0x00ff0000, 0x0000ff00, 0x0000ff00, 0x00ff0000,
4748 if (!test)
4750 hr = IDirect3DDevice8_SetRenderTarget(device, rt, NULL);
4751 ok(SUCCEEDED(hr), "Failed to set depth stencil surface, hr %#x.\n", hr);
4753 else
4755 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
4756 ok(SUCCEEDED(hr), "Failed to disable z-buffering, hr %#x.\n", hr);
4757 hr = IDirect3DDevice8_SetRenderTarget(device, rt, ds);
4758 ok(SUCCEEDED(hr), "Failed to set depth stencil surface, hr %#x.\n", hr);
4759 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 0.0f, 0);
4760 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
4762 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
4763 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
4765 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0f, 0);
4766 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
4767 hr = IDirect3DDevice8_BeginScene(device);
4768 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
4769 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, tquad, sizeof(*tquad));
4770 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4771 hr = IDirect3DDevice8_EndScene(device);
4772 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
4774 for (i = 0; i < 4; ++i)
4776 for (j = 0; j < 4; ++j)
4778 x = 80 * ((2 * j) + 1);
4779 y = 60 * ((2 * i) + 1);
4780 color = getPixelColor(device, x, y);
4781 ok(color_match(color, 0x0000ff00, 1)
4782 || broken(color_match(color, expected_broken[i * 4 + j], 1) && !test),
4783 "Expected color 0x0000ff00 at %u, %u, got 0x%08x.\n", x, y, color);
4787 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
4788 ok(SUCCEEDED(hr), "Failed to present backbuffer, hr %#x.\n", hr);
4791 IDirect3DSurface8_Release(ds);
4792 IDirect3DSurface8_Release(rt);
4794 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
4795 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
4797 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1)
4798 && caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
4800 static const DWORD vs_code[] =
4802 0xfffe0101, /* vs_1_1 */
4803 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4804 0x00000001, 0xd00f0000, 0x90e40000, /* mov oD0, v0 */
4805 0x0000ffff
4807 static const DWORD ps_code[] =
4809 0xffff0101, /* ps_1_1 */
4810 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
4811 0x0000ffff /* end */
4813 static const struct vec3 quad[] =
4815 {-1.0f, -1.0f, -0.5f},
4816 {-1.0f, 1.0f, -0.5f},
4817 { 1.0f, -1.0f, 1.5f},
4818 { 1.0f, 1.0f, 1.5f},
4820 static const D3DCOLOR expected[] =
4822 0x00ff0000, 0x0060df60, 0x009fdf9f, 0x00ff0000,
4823 0x00ff0000, 0x00609f60, 0x009f9f9f, 0x00ff0000,
4824 0x00ff0000, 0x00606060, 0x009f609f, 0x00ff0000,
4825 0x00ff0000, 0x00602060, 0x009f209f, 0x00ff0000,
4827 /* The Windows 8 testbot (WARP) appears to not clip z for regular
4828 * vertices either. */
4829 static const D3DCOLOR expected_broken[] =
4831 0x0020df20, 0x0060df60, 0x009fdf9f, 0x00dfdfdf,
4832 0x00209f20, 0x00609f60, 0x009f9f9f, 0x00df9fdf,
4833 0x00206020, 0x00606060, 0x009f609f, 0x00df60df,
4834 0x00202020, 0x00602060, 0x009f209f, 0x00df20df,
4836 static const DWORD decl[] =
4838 D3DVSD_STREAM(0),
4839 D3DVSD_REG(D3DVSDE_POSITION, D3DVSDT_FLOAT3),
4840 D3DVSD_END()
4842 DWORD vs, ps;
4844 hr = IDirect3DDevice8_CreateVertexShader(device, decl, vs_code, &vs, 0);
4845 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
4846 hr = IDirect3DDevice8_CreatePixelShader(device, ps_code, &ps);
4847 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
4848 hr = IDirect3DDevice8_SetVertexShader(device, vs);
4849 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
4850 hr = IDirect3DDevice8_SetPixelShader(device, ps);
4851 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
4853 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0f, 0);
4854 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
4855 hr = IDirect3DDevice8_BeginScene(device);
4856 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
4857 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
4858 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4859 hr = IDirect3DDevice8_EndScene(device);
4860 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
4862 for (i = 0; i < 4; ++i)
4864 for (j = 0; j < 4; ++j)
4866 x = 80 * ((2 * j) + 1);
4867 y = 60 * ((2 * i) + 1);
4868 color = getPixelColor(device, x, y);
4869 ok(color_match(color, expected[i * 4 + j], 1)
4870 || broken(color_match(color, expected_broken[i * 4 + j], 1)),
4871 "Expected color 0x%08x at %u, %u, got 0x%08x.\n", expected[i * 4 + j], x, y, color);
4875 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
4876 ok(SUCCEEDED(hr), "Failed to present backbuffer, hr %#x.\n", hr);
4878 hr = IDirect3DDevice8_DeletePixelShader(device, ps);
4879 ok(SUCCEEDED(hr), "Failed to delete pixel shader, hr %#x.\n", hr);
4880 hr = IDirect3DDevice8_DeleteVertexShader(device, vs);
4881 ok(SUCCEEDED(hr), "Failed to delete vertex shader, hr %#x.\n", hr);
4884 refcount = IDirect3DDevice8_Release(device);
4885 ok(!refcount, "Device has %u references left.\n", refcount);
4886 done:
4887 IDirect3D8_Release(d3d);
4888 DestroyWindow(window);
4891 static void fog_special_test(void)
4893 IDirect3DDevice8 *device;
4894 IDirect3D8 *d3d;
4895 unsigned int i;
4896 D3DCOLOR color;
4897 ULONG refcount;
4898 D3DCAPS8 caps;
4899 DWORD ps, vs;
4900 HWND window;
4901 HRESULT hr;
4902 union
4904 float f;
4905 DWORD d;
4906 } conv;
4908 static const struct
4910 struct vec3 position;
4911 D3DCOLOR diffuse;
4913 quad[] =
4915 {{ -1.0f, -1.0f, 0.0f}, 0xff00ff00},
4916 {{ -1.0f, 1.0f, 0.0f}, 0xff00ff00},
4917 {{ 1.0f, -1.0f, 1.0f}, 0xff00ff00},
4918 {{ 1.0f, 1.0f, 1.0f}, 0xff00ff00}
4920 static const struct
4922 DWORD vertexmode, tablemode;
4923 BOOL vs, ps;
4924 D3DCOLOR color_left, color_right;
4926 tests[] =
4928 {D3DFOG_LINEAR, D3DFOG_NONE, FALSE, FALSE, 0x00ff0000, 0x00ff0000},
4929 {D3DFOG_LINEAR, D3DFOG_NONE, FALSE, TRUE, 0x00ff0000, 0x00ff0000},
4930 {D3DFOG_LINEAR, D3DFOG_NONE, TRUE, FALSE, 0x00ff0000, 0x00ff0000},
4931 {D3DFOG_LINEAR, D3DFOG_NONE, TRUE, TRUE, 0x00ff0000, 0x00ff0000},
4933 {D3DFOG_NONE, D3DFOG_LINEAR, FALSE, FALSE, 0x0000ff00, 0x00ff0000},
4934 {D3DFOG_NONE, D3DFOG_LINEAR, FALSE, TRUE, 0x0000ff00, 0x00ff0000},
4935 {D3DFOG_NONE, D3DFOG_LINEAR, TRUE, FALSE, 0x0000ff00, 0x00ff0000},
4936 {D3DFOG_NONE, D3DFOG_LINEAR, TRUE, TRUE, 0x0000ff00, 0x00ff0000},
4938 static const DWORD pixel_shader_code[] =
4940 0xffff0101, /* ps.1.1 */
4941 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
4942 0x0000ffff
4944 static const DWORD vertex_decl[] =
4946 D3DVSD_STREAM(0),
4947 D3DVSD_REG(0, D3DVSDT_FLOAT3), /* position, v0 */
4948 D3DVSD_REG(1, D3DVSDT_D3DCOLOR), /* diffuse color, v1 */
4949 D3DVSD_END()
4951 static const DWORD vertex_shader_code[] =
4953 0xfffe0101, /* vs.1.1 */
4954 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4955 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
4956 0x0000ffff
4958 static const D3DMATRIX identity =
4960 1.0f, 0.0f, 0.0f, 0.0f,
4961 0.0f, 1.0f, 0.0f, 0.0f,
4962 0.0f, 0.0f, 1.0f, 0.0f,
4963 0.0f, 0.0f, 0.0f, 1.0f,
4964 }}};
4966 window = create_window();
4967 d3d = Direct3DCreate8(D3D_SDK_VERSION);
4968 ok(!!d3d, "Failed to create a D3D object.\n");
4969 if (!(device = create_device(d3d, window, window, TRUE)))
4971 skip("Failed to create a D3D device, skipping tests.\n");
4972 goto done;
4975 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
4976 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
4977 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
4979 hr = IDirect3DDevice8_CreateVertexShader(device, vertex_decl, vertex_shader_code, &vs, 0);
4980 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
4982 else
4984 skip("Vertex Shaders not supported, skipping some fog tests.\n");
4985 vs = 0;
4987 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
4989 hr = IDirect3DDevice8_CreatePixelShader(device, pixel_shader_code, &ps);
4990 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
4992 else
4994 skip("Pixel Shaders not supported, skipping some fog tests.\n");
4995 ps = 0;
4998 /* The table fog tests seem to depend on the projection matrix explicitly
4999 * being set to an identity matrix, even though that's the default.
5000 * (AMD Radeon HD 6310, Windows 7) */
5001 hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, &identity);
5002 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
5004 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
5005 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
5006 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
5007 ok(SUCCEEDED(hr), "Failed to enable fog, hr %#x.\n", hr);
5008 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGCOLOR, 0xffff0000);
5009 ok(SUCCEEDED(hr), "Failed to set fog color, hr %#x.\n", hr);
5011 conv.f = 0.5f;
5012 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGSTART, conv.d);
5013 ok(SUCCEEDED(hr), "Failed to set fog start, hr %#x.\n", hr);
5014 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGEND, conv.d);
5015 ok(SUCCEEDED(hr), "Failed to set fog end, hr %#x.\n", hr);
5017 for (i = 0; i < ARRAY_SIZE(tests); i++)
5019 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
5020 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
5022 if (!tests[i].vs)
5024 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
5025 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr);
5027 else if (vs)
5029 hr = IDirect3DDevice8_SetVertexShader(device, vs);
5030 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
5032 else
5034 continue;
5037 if (!tests[i].ps)
5039 hr = IDirect3DDevice8_SetPixelShader(device, 0);
5040 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
5042 else if (ps)
5044 hr = IDirect3DDevice8_SetPixelShader(device, ps);
5045 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
5047 else
5049 continue;
5052 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGVERTEXMODE, tests[i].vertexmode);
5053 ok(SUCCEEDED(hr), "Failed to set fogvertexmode, hr %#x.\n", hr);
5054 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGTABLEMODE, tests[i].tablemode);
5055 ok(SUCCEEDED(hr), "Failed to set fogtablemode, hr %#x.\n", hr);
5057 hr = IDirect3DDevice8_BeginScene(device);
5058 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5059 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
5060 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5061 hr = IDirect3DDevice8_EndScene(device);
5062 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5064 color = getPixelColor(device, 310, 240);
5065 ok(color_match(color, tests[i].color_left, 1),
5066 "Expected left color 0x%08x, got 0x%08x, case %u.\n", tests[i].color_left, color, i);
5067 color = getPixelColor(device, 330, 240);
5068 ok(color_match(color, tests[i].color_right, 1),
5069 "Expected right color 0x%08x, got 0x%08x, case %u.\n", tests[i].color_right, color, i);
5071 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5072 ok(SUCCEEDED(hr), "Failed to present backbuffer, hr %#x.\n", hr);
5075 if (vs)
5076 IDirect3DDevice8_DeleteVertexShader(device, vs);
5077 if (ps)
5078 IDirect3DDevice8_DeletePixelShader(device, ps);
5079 refcount = IDirect3DDevice8_Release(device);
5080 ok(!refcount, "Device has %u references left.\n", refcount);
5081 done:
5082 IDirect3D8_Release(d3d);
5083 DestroyWindow(window);
5086 static void volume_dxtn_test(void)
5088 IDirect3DVolumeTexture8 *texture;
5089 struct surface_readback rb;
5090 IDirect3DDevice8 *device;
5091 IDirect3DSurface8 *rt;
5092 D3DLOCKED_BOX box;
5093 unsigned int i, j;
5094 IDirect3D8 *d3d;
5095 ULONG refcount;
5096 DWORD colour;
5097 HWND window;
5098 HRESULT hr;
5100 static const BYTE dxt1_data[] =
5102 0x00, 0xf8, 0x00, 0xf8, 0xf0, 0xf0, 0xf0, 0xf0,
5103 0xe0, 0x07, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00,
5104 0x1f, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00,
5105 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00
5107 static const BYTE dxt3_data[] =
5109 0xff, 0xee, 0xff, 0xee, 0xff, 0xee, 0xff, 0xee, 0x00, 0xf8, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00,
5110 0xff, 0xdd, 0xff, 0xdd, 0xff, 0xdd, 0xff, 0xdd, 0xe0, 0x07, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00,
5111 0xff, 0xcc, 0xff, 0xcc, 0xff, 0xcc, 0xff, 0xcc, 0x1f, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00,
5112 0xff, 0xbb, 0xff, 0xbb, 0xff, 0xbb, 0xff, 0xbb, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00
5114 static const BYTE dxt5_data[] =
5116 /* A 8x4x2 texture consisting of 4 4x4 blocks. The colours of the
5117 * blocks are red, green, blue and white. */
5118 0xff, 0xff, 0x80, 0x0d, 0xd8, 0x80, 0x0d, 0xd8, 0x00, 0xf8, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00,
5119 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00,
5120 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00,
5121 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00
5123 static const DWORD dxt1_expected_colours[] =
5125 0xffff0000, 0x00000000, 0xff00ff00, 0xff00ff00,
5126 0xff0000ff, 0xff0000ff, 0xffffffff, 0xffffffff,
5128 static const DWORD dxt3_expected_colours[] =
5130 0xffff0000, 0xeeff0000, 0xff00ff00, 0xdd00ff00,
5131 0xff0000ff, 0xcc0000ff, 0xffffffff, 0xbbffffff,
5133 static const DWORD dxt5_expected_colours[] =
5135 0xffff0000, 0x00ff0000, 0xff00ff00, 0xff00ff00,
5136 0xff0000ff, 0xff0000ff, 0xffffffff, 0xffffffff
5139 static const struct
5141 const char *name;
5142 D3DFORMAT format;
5143 const BYTE *data;
5144 DWORD data_size;
5145 const DWORD *expected_colours;
5147 tests[] =
5149 {"DXT1", D3DFMT_DXT1, dxt1_data, sizeof(dxt1_data), dxt1_expected_colours},
5150 {"DXT3", D3DFMT_DXT3, dxt3_data, sizeof(dxt3_data), dxt3_expected_colours},
5151 {"DXT5", D3DFMT_DXT5, dxt5_data, sizeof(dxt5_data), dxt5_expected_colours},
5154 static const struct
5156 struct vec3 position;
5157 struct vec3 texcrd;
5159 quads[] =
5161 {{ -1.0f, -1.0f, 0.0f}, { 0.0f, 0.0f, 0.25f}},
5162 {{ -1.0f, 1.0f, 0.0f}, { 0.0f, 1.0f, 0.25f}},
5163 {{ 0.0f, -1.0f, 1.0f}, { 1.0f, 0.0f, 0.25f}},
5164 {{ 0.0f, 1.0f, 1.0f}, { 1.0f, 1.0f, 0.25f}},
5166 {{ 0.0f, -1.0f, 0.0f}, { 0.0f, 0.0f, 0.75f}},
5167 {{ 0.0f, 1.0f, 0.0f}, { 0.0f, 1.0f, 0.75f}},
5168 {{ 1.0f, -1.0f, 1.0f}, { 1.0f, 0.0f, 0.75f}},
5169 {{ 1.0f, 1.0f, 1.0f}, { 1.0f, 1.0f, 0.75f}},
5172 window = create_window();
5173 d3d = Direct3DCreate8(D3D_SDK_VERSION);
5174 ok(!!d3d, "Failed to create a D3D object.\n");
5176 if (!(device = create_device(d3d, window, window, TRUE)))
5178 skip("Failed to create a D3D device, skipping tests.\n");
5179 goto done;
5182 hr = IDirect3DDevice8_GetRenderTarget(device, &rt);
5183 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
5185 for (i = 0; i < ARRAY_SIZE(tests); ++i)
5187 if (FAILED(IDirect3D8_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
5188 D3DFMT_X8R8G8B8, 0, D3DRTYPE_VOLUMETEXTURE, tests[i].format)))
5190 skip("%s volume textures are not supported, skipping test.\n", tests[i].name);
5191 continue;
5193 hr = IDirect3DDevice8_CreateVolumeTexture(device, 8, 4, 2, 1, 0,
5194 tests[i].format, D3DPOOL_MANAGED, &texture);
5195 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
5197 hr = IDirect3DVolumeTexture8_LockBox(texture, 0, &box, NULL, 0);
5198 ok(SUCCEEDED(hr), "Failed to lock volume texture, hr %#x.\n", hr);
5199 memcpy(box.pBits, tests[i].data, tests[i].data_size);
5200 hr = IDirect3DVolumeTexture8_UnlockBox(texture, 0);
5201 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#x.\n", hr);
5203 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE3(0));
5204 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
5205 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
5206 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
5207 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
5208 ok(SUCCEEDED(hr), "Failed to set colour op, hr %#x.\n", hr);
5209 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
5210 ok(SUCCEEDED(hr), "Failed to set colour arg, hr %#x.\n", hr);
5211 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
5212 ok(SUCCEEDED(hr), "Failed to set colour op, hr %#x.\n", hr);
5213 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MAGFILTER, D3DTEXF_POINT);
5214 ok(SUCCEEDED(hr), "Failed to set mag filter, hr %#x.\n", hr);
5216 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff00ff, 1.0f, 0);
5217 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
5218 hr = IDirect3DDevice8_BeginScene(device);
5219 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5220 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads));
5221 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5222 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[4], sizeof(*quads));
5223 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5224 hr = IDirect3DDevice8_EndScene(device);
5225 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5227 get_rt_readback(rt, &rb);
5228 for (j = 0; j < ARRAY_SIZE(dxt1_expected_colours); ++j)
5230 colour = get_readback_color(&rb, 40 + 80 * j, 240);
5231 ok(color_match(colour, tests[i].expected_colours[j], 1),
5232 "Expected colour 0x%08x, got 0x%08x, case %u.\n", tests[i].expected_colours[j], colour, j);
5234 release_surface_readback(&rb);
5236 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5237 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5238 IDirect3DVolumeTexture8_Release(texture);
5241 IDirect3DSurface8_Release(rt);
5242 refcount = IDirect3DDevice8_Release(device);
5243 ok(!refcount, "Device has %u references left.\n", refcount);
5244 done:
5245 IDirect3D8_Release(d3d);
5246 DestroyWindow(window);
5249 static void volume_v16u16_test(void)
5251 IDirect3DVolumeTexture8 *texture;
5252 IDirect3DDevice8 *device;
5253 D3DLOCKED_BOX box;
5254 IDirect3D8 *d3d;
5255 unsigned int i;
5256 D3DCOLOR color;
5257 ULONG refcount;
5258 D3DCAPS8 caps;
5259 DWORD shader;
5260 SHORT *texel;
5261 HWND window;
5262 HRESULT hr;
5264 static const struct
5266 struct vec3 position;
5267 struct vec3 texcrd;
5269 quads[] =
5271 {{ -1.0f, -1.0f, 0.0f}, { 0.0f, 0.0f, 0.25f}},
5272 {{ -1.0f, 1.0f, 0.0f}, { 0.0f, 1.0f, 0.25f}},
5273 {{ 0.0f, -1.0f, 1.0f}, { 1.0f, 0.0f, 0.25f}},
5274 {{ 0.0f, 1.0f, 1.0f}, { 1.0f, 1.0f, 0.25f}},
5276 {{ 0.0f, -1.0f, 0.0f}, { 0.0f, 0.0f, 0.75f}},
5277 {{ 0.0f, 1.0f, 0.0f}, { 0.0f, 1.0f, 0.75f}},
5278 {{ 1.0f, -1.0f, 1.0f}, { 1.0f, 0.0f, 0.75f}},
5279 {{ 1.0f, 1.0f, 1.0f}, { 1.0f, 1.0f, 0.75f}},
5281 static const DWORD shader_code[] =
5283 0xffff0101, /* ps_1_1 */
5284 0x00000051, 0xa00f0000, 0x3f000000, 0x3f000000, /* def c0, 0.5, 0.5, */
5285 0x3f000000, 0x3f000000, /* 0.5, 0.5 */
5286 0x00000042, 0xb00f0000, /* tex t0 */
5287 0x00000004, 0x800f0000, 0xb0e40000, 0xa0e40000, 0xa0e40000, /* mad r0, t0, c0, c0 */
5288 0x0000ffff /* end */
5291 window = create_window();
5292 d3d = Direct3DCreate8(D3D_SDK_VERSION);
5293 ok(!!d3d, "Failed to create a D3D object.\n");
5294 if (!(device = create_device(d3d, window, window, TRUE)))
5296 skip("Failed to create a D3D device, skipping tests.\n");
5297 goto done;
5300 if (FAILED(IDirect3D8_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
5301 D3DFMT_X8R8G8B8, 0, D3DRTYPE_VOLUMETEXTURE, D3DFMT_V16U16)))
5303 skip("Volume V16U16 textures are not supported, skipping test.\n");
5304 IDirect3DDevice8_Release(device);
5305 goto done;
5307 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
5308 ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
5309 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 1))
5311 skip("No pixel shader 1.1 support, skipping test.\n");
5312 IDirect3DDevice8_Release(device);
5313 goto done;
5316 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE3(0));
5317 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
5318 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code, &shader);
5319 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
5320 hr = IDirect3DDevice8_SetPixelShader(device, shader);
5321 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
5322 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MAGFILTER, D3DTEXF_POINT);
5323 ok(SUCCEEDED(hr), "Failed to set filter, hr %#x.\n", hr);
5325 for (i = 0; i < 2; i++)
5327 D3DPOOL pool;
5329 if (i)
5330 pool = D3DPOOL_SYSTEMMEM;
5331 else
5332 pool = D3DPOOL_MANAGED;
5334 hr = IDirect3DDevice8_CreateVolumeTexture(device, 1, 2, 2, 1, 0, D3DFMT_V16U16,
5335 pool, &texture);
5336 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
5338 hr = IDirect3DVolumeTexture8_LockBox(texture, 0, &box, NULL, 0);
5339 ok(SUCCEEDED(hr), "Failed to lock volume texture, hr %#x.\n", hr);
5341 texel = (SHORT *)((BYTE *)box.pBits + 0 * box.RowPitch + 0 * box.SlicePitch);
5342 texel[0] = 32767;
5343 texel[1] = 32767;
5344 texel = (SHORT *)((BYTE *)box.pBits + 1 * box.RowPitch + 0 * box.SlicePitch);
5345 texel[0] = -32768;
5346 texel[1] = 0;
5347 texel = (SHORT *)((BYTE *)box.pBits + 0 * box.RowPitch + 1 * box.SlicePitch);
5348 texel[0] = -16384;
5349 texel[1] = 16384;
5350 texel = (SHORT *)((BYTE *)box.pBits + 1 * box.RowPitch + 1 * box.SlicePitch);
5351 texel[0] = 0;
5352 texel[1] = 0;
5354 hr = IDirect3DVolumeTexture8_UnlockBox(texture, 0);
5355 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#x.\n", hr);
5357 if (i)
5359 IDirect3DVolumeTexture8 *texture2;
5361 hr = IDirect3DDevice8_CreateVolumeTexture(device, 1, 2, 2, 1, 0, D3DFMT_V16U16,
5362 D3DPOOL_DEFAULT, &texture2);
5363 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
5365 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)texture,
5366 (IDirect3DBaseTexture8 *)texture2);
5367 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
5369 IDirect3DVolumeTexture8_Release(texture);
5370 texture = texture2;
5373 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *) texture);
5374 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
5376 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff00ff, 1.0f, 0);
5377 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
5378 hr = IDirect3DDevice8_BeginScene(device);
5379 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5380 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads));
5381 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5382 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[4], sizeof(*quads));
5383 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5384 hr = IDirect3DDevice8_EndScene(device);
5385 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5387 color = getPixelColor(device, 120, 160);
5388 ok (color_match(color, 0x000080ff, 2),
5389 "Expected color 0x000080ff, got 0x%08x, V16U16 input -32768, 0.\n", color);
5390 color = getPixelColor(device, 120, 400);
5391 ok (color_match(color, 0x00ffffff, 2),
5392 "Expected color 0x00ffffff, got 0x%08x, V16U16 input 32767, 32767.\n", color);
5393 color = getPixelColor(device, 360, 160);
5394 ok (color_match(color, 0x007f7fff, 2),
5395 "Expected color 0x007f7fff, got 0x%08x, V16U16 input 0, 0.\n", color);
5396 color = getPixelColor(device, 360, 400);
5397 ok (color_match(color, 0x0040c0ff, 2),
5398 "Expected color 0x0040c0ff, got 0x%08x, V16U16 input -16384, 16384.\n", color);
5400 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5401 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5403 IDirect3DVolumeTexture8_Release(texture);
5406 hr = IDirect3DDevice8_DeletePixelShader(device, shader);
5407 ok(SUCCEEDED(hr), "Failed delete pixel shader, hr %#x.\n", hr);
5408 refcount = IDirect3DDevice8_Release(device);
5409 ok(!refcount, "Device has %u references left.\n", refcount);
5410 done:
5411 IDirect3D8_Release(d3d);
5412 DestroyWindow(window);
5415 static void fill_surface(IDirect3DSurface8 *surface, DWORD color, DWORD flags)
5417 D3DSURFACE_DESC desc;
5418 D3DLOCKED_RECT l;
5419 HRESULT hr;
5420 unsigned int x, y;
5421 DWORD *mem;
5423 hr = IDirect3DSurface8_GetDesc(surface, &desc);
5424 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
5425 hr = IDirect3DSurface8_LockRect(surface, &l, NULL, flags);
5426 ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
5427 if (FAILED(hr))
5428 return;
5430 for (y = 0; y < desc.Height; y++)
5432 mem = (DWORD *)((BYTE *)l.pBits + y * l.Pitch);
5433 for (x = 0; x < l.Pitch / sizeof(DWORD); x++)
5435 mem[x] = color;
5438 hr = IDirect3DSurface8_UnlockRect(surface);
5439 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
5442 static void add_dirty_rect_test_draw(IDirect3DDevice8 *device)
5444 HRESULT hr;
5445 static const struct
5447 struct vec3 position;
5448 struct vec2 texcoord;
5450 quad[] =
5452 {{-1.0f, -1.0f, 0.0f}, {0.0f, 0.0f}},
5453 {{-1.0f, 1.0f, 0.0f}, {0.0f, 1.0f}},
5454 {{ 1.0f, -1.0f, 0.0f}, {1.0f, 0.0f}},
5455 {{ 1.0f, 1.0f, 0.0f}, {1.0f, 1.0f}},
5458 hr = IDirect3DDevice8_BeginScene(device);
5459 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5460 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad, sizeof(*quad));
5461 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5462 hr = IDirect3DDevice8_EndScene(device);
5463 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5466 static void add_dirty_rect_test(void)
5468 IDirect3DTexture8 *tex_dst1, *tex_dst2, *tex_src_red, *tex_src_green,
5469 *tex_managed, *tex_dynamic;
5470 IDirect3DSurface8 *surface_dst2, *surface_src_green, *surface_src_red,
5471 *surface_managed0, *surface_managed1, *surface_dynamic;
5472 D3DLOCKED_RECT locked_rect;
5473 IDirect3DDevice8 *device;
5474 IDirect3D8 *d3d;
5475 unsigned int i;
5476 D3DCOLOR color;
5477 ULONG refcount;
5478 DWORD *texel;
5479 HWND window;
5480 HRESULT hr;
5482 static const RECT part_rect = {96, 96, 160, 160};
5483 static const RECT oob_rect[] =
5485 { 0, 0, 200, 300},
5486 { 0, 0, 300, 200},
5487 {100, 100, 10, 10},
5488 {200, 300, 10, 10},
5489 {300, 200, 310, 210},
5490 { 0, 0, 0, 0},
5493 window = create_window();
5494 d3d = Direct3DCreate8(D3D_SDK_VERSION);
5495 ok(!!d3d, "Failed to create a D3D object.\n");
5496 if (!(device = create_device(d3d, window, window, TRUE)))
5498 skip("Failed to create a D3D device, skipping tests.\n");
5499 goto done;
5502 hr = IDirect3DDevice8_CreateTexture(device, 256, 256, 1, 0, D3DFMT_X8R8G8B8,
5503 D3DPOOL_DEFAULT, &tex_dst1);
5504 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
5505 hr = IDirect3DDevice8_CreateTexture(device, 256, 256, 1, 0, D3DFMT_X8R8G8B8,
5506 D3DPOOL_DEFAULT, &tex_dst2);
5507 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
5508 hr = IDirect3DDevice8_CreateTexture(device, 256, 256, 1, 0, D3DFMT_X8R8G8B8,
5509 D3DPOOL_SYSTEMMEM, &tex_src_red);
5510 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
5511 hr = IDirect3DDevice8_CreateTexture(device, 256, 256, 1, 0, D3DFMT_X8R8G8B8,
5512 D3DPOOL_SYSTEMMEM, &tex_src_green);
5513 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
5514 hr = IDirect3DDevice8_CreateTexture(device, 256, 256, 2, 0, D3DFMT_X8R8G8B8,
5515 D3DPOOL_MANAGED, &tex_managed);
5516 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
5517 hr = IDirect3DDevice8_CreateTexture(device, 256, 256, 1, D3DUSAGE_DYNAMIC,
5518 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &tex_dynamic);
5519 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
5521 hr = IDirect3DTexture8_GetSurfaceLevel(tex_dst2, 0, &surface_dst2);
5522 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
5523 hr = IDirect3DTexture8_GetSurfaceLevel(tex_src_green, 0, &surface_src_green);
5524 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
5525 hr = IDirect3DTexture8_GetSurfaceLevel(tex_src_red, 0, &surface_src_red);
5526 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
5527 hr = IDirect3DTexture8_GetSurfaceLevel(tex_managed, 0, &surface_managed0);
5528 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
5529 hr = IDirect3DTexture8_GetSurfaceLevel(tex_managed, 1, &surface_managed1);
5530 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
5531 hr = IDirect3DTexture8_GetSurfaceLevel(tex_dynamic, 0, &surface_dynamic);
5532 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
5534 fill_surface(surface_src_red, 0x00ff0000, 0);
5535 fill_surface(surface_src_green, 0x0000ff00, 0);
5537 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX1);
5538 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr);
5539 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
5540 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
5541 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
5542 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
5543 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MIPFILTER, D3DTEXF_POINT);
5544 ok(SUCCEEDED(hr), "Failed to set mip filter, hr %#x.\n", hr);
5546 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_green,
5547 (IDirect3DBaseTexture8 *)tex_dst1);
5548 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
5550 /* The second UpdateTexture call writing to tex_dst2 is ignored because tex_src_green is not dirty. */
5551 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_red,
5552 (IDirect3DBaseTexture8 *)tex_dst2);
5553 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
5554 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_green,
5555 (IDirect3DBaseTexture8 *)tex_dst2);
5556 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
5558 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)tex_dst1);
5559 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
5560 add_dirty_rect_test_draw(device);
5561 color = getPixelColor(device, 320, 240);
5562 ok(color_match(color, 0x0000ff00, 1),
5563 "Expected color 0x0000ff00, got 0x%08x.\n", color);
5564 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5565 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5567 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)tex_dst2);
5568 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
5569 add_dirty_rect_test_draw(device);
5570 color = getPixelColor(device, 320, 240);
5571 ok(color_match(color, 0x00ff0000, 1),
5572 "Expected color 0x00ff0000, got 0x%08x.\n", color);
5573 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5574 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5576 /* AddDirtyRect on the destination is ignored. */
5577 hr = IDirect3DTexture8_AddDirtyRect(tex_dst2, &part_rect);
5578 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
5579 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_green,
5580 (IDirect3DBaseTexture8 *)tex_dst2);
5581 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
5582 add_dirty_rect_test_draw(device);
5583 color = getPixelColor(device, 320, 240);
5584 ok(color_match(color, 0x00ff0000, 1),
5585 "Expected color 0x00ff0000, got 0x%08x.\n", color);
5586 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5587 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5589 hr = IDirect3DTexture8_AddDirtyRect(tex_dst2, NULL);
5590 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
5591 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_green,
5592 (IDirect3DBaseTexture8 *)tex_dst2);
5593 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
5594 add_dirty_rect_test_draw(device);
5595 color = getPixelColor(device, 320, 240);
5596 ok(color_match(color, 0x00ff0000, 1),
5597 "Expected color 0x00ff0000, got 0x%08x.\n", color);
5598 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5599 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5601 /* AddDirtyRect on the source makes UpdateTexture work. Partial rectangle
5602 * tracking is supported. */
5603 hr = IDirect3DTexture8_AddDirtyRect(tex_src_green, &part_rect);
5604 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
5605 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_green,
5606 (IDirect3DBaseTexture8 *)tex_dst2);
5607 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
5608 add_dirty_rect_test_draw(device);
5609 color = getPixelColor(device, 320, 240);
5610 ok(color_match(color, 0x0000ff00, 1),
5611 "Expected color 0x0000ff00, got 0x%08x.\n", color);
5612 color = getPixelColor(device, 1, 1);
5613 ok(color_match(color, 0x00ff0000, 1),
5614 "Expected color 0x00ff0000, got 0x%08x.\n", color);
5615 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5616 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5618 hr = IDirect3DTexture8_AddDirtyRect(tex_src_green, NULL);
5619 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
5620 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_green,
5621 (IDirect3DBaseTexture8 *)tex_dst2);
5622 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
5623 add_dirty_rect_test_draw(device);
5624 color = getPixelColor(device, 1, 1);
5625 ok(color_match(color, 0x0000ff00, 1),
5626 "Expected color 0x0000ff00, got 0x%08x.\n", color);
5628 /* Locks with NO_DIRTY_UPDATE are ignored. */
5629 fill_surface(surface_src_green, 0x00000080, D3DLOCK_NO_DIRTY_UPDATE);
5630 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_green,
5631 (IDirect3DBaseTexture8 *)tex_dst2);
5632 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
5633 add_dirty_rect_test_draw(device);
5634 color = getPixelColor(device, 320, 240);
5635 ok(color_match(color, 0x0000ff00, 1),
5636 "Expected color 0x0000ff00, got 0x%08x.\n", color);
5637 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5638 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5640 /* Readonly maps write to D3DPOOL_SYSTEMMEM, but don't record a dirty rectangle. */
5641 fill_surface(surface_src_green, 0x000000ff, D3DLOCK_READONLY);
5642 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_green,
5643 (IDirect3DBaseTexture8 *)tex_dst2);
5644 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
5645 add_dirty_rect_test_draw(device);
5646 color = getPixelColor(device, 320, 240);
5647 ok(color_match(color, 0x0000ff00, 1),
5648 "Expected color 0x0000ff00, got 0x%08x.\n", color);
5649 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5650 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5652 hr = IDirect3DTexture8_AddDirtyRect(tex_src_green, NULL);
5653 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_green,
5654 (IDirect3DBaseTexture8 *)tex_dst2);
5655 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
5656 add_dirty_rect_test_draw(device);
5657 color = getPixelColor(device, 320, 240);
5658 ok(color_match(color, 0x000000ff, 1),
5659 "Expected color 0x000000ff, got 0x%08x.\n", color);
5660 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5661 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5663 /* Maps without either of these flags record a dirty rectangle. */
5664 fill_surface(surface_src_green, 0x00ffffff, 0);
5665 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_green,
5666 (IDirect3DBaseTexture8 *)tex_dst2);
5667 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
5668 add_dirty_rect_test_draw(device);
5669 color = getPixelColor(device, 320, 240);
5670 ok(color_match(color, 0x00ffffff, 1),
5671 "Expected color 0x00ffffff, got 0x%08x.\n", color);
5672 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5673 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5675 /* Partial LockRect works just like a partial AddDirtyRect call. */
5676 hr = IDirect3DTexture8_LockRect(tex_src_green, 0, &locked_rect, &part_rect, 0);
5677 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
5678 texel = locked_rect.pBits;
5679 for (i = 0; i < 64; i++)
5680 texel[i] = 0x00ff00ff;
5681 for (i = 1; i < 64; i++)
5682 memcpy((BYTE *)locked_rect.pBits + i * locked_rect.Pitch, locked_rect.pBits, locked_rect.Pitch);
5683 hr = IDirect3DTexture8_UnlockRect(tex_src_green, 0);
5684 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
5685 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_green,
5686 (IDirect3DBaseTexture8 *)tex_dst2);
5687 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
5688 add_dirty_rect_test_draw(device);
5689 color = getPixelColor(device, 320, 240);
5690 ok(color_match(color, 0x00ff00ff, 1),
5691 "Expected color 0x00ff00ff, got 0x%08x.\n", color);
5692 color = getPixelColor(device, 1, 1);
5693 ok(color_match(color, 0x00ffffff, 1),
5694 "Expected color 0x00ffffff, got 0x%08x.\n", color);
5695 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5696 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5698 fill_surface(surface_src_red, 0x00ff0000, 0);
5699 fill_surface(surface_src_green, 0x0000ff00, 0);
5701 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_green,
5702 (IDirect3DBaseTexture8 *)tex_dst1);
5703 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
5704 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)tex_dst1);
5705 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
5706 add_dirty_rect_test_draw(device);
5707 color = getPixelColor(device, 320, 240);
5708 ok(color_match(color, 0x0000ff00, 1),
5709 "Expected color 0x0000ff00, got 0x%08x.\n", color);
5710 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5711 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5713 /* UpdateSurface ignores the missing dirty marker. */
5714 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_red,
5715 (IDirect3DBaseTexture8 *)tex_dst2);
5716 hr = IDirect3DDevice8_CopyRects(device, surface_src_green, NULL, 0, surface_dst2, NULL);
5717 ok(SUCCEEDED(hr), "Failed to update surface, hr %#x.\n", hr);
5718 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)tex_dst2);
5719 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
5720 add_dirty_rect_test_draw(device);
5721 color = getPixelColor(device, 320, 240);
5722 ok(color_match(color, 0x0000ff00, 1),
5723 "Expected color 0x0000ff00, got 0x%08x.\n", color);
5724 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5725 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5727 /* Tests with managed textures. */
5728 fill_surface(surface_managed0, 0x00ff0000, 0);
5729 fill_surface(surface_managed1, 0x00ff0000, 0);
5730 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)tex_managed);
5731 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
5732 add_dirty_rect_test_draw(device);
5733 color = getPixelColor(device, 320, 240);
5734 ok(color_match(color, 0x00ff0000, 1),
5735 "Expected color 0x00ff0000, got 0x%08x.\n", color);
5736 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5737 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5738 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MAXMIPLEVEL, 1);
5739 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
5740 add_dirty_rect_test_draw(device);
5741 color = getPixelColor(device, 320, 240);
5742 ok(color_match(color, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color);
5743 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5744 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5746 /* Managed textures also honor D3DLOCK_NO_DIRTY_UPDATE. */
5747 fill_surface(surface_managed0, 0x0000ff00, D3DLOCK_NO_DIRTY_UPDATE);
5748 fill_surface(surface_managed1, 0x000000ff, D3DLOCK_NO_DIRTY_UPDATE);
5749 add_dirty_rect_test_draw(device);
5750 color = getPixelColor(device, 320, 240);
5751 ok(color_match(color, 0x00ff0000, 1),
5752 "Expected color 0x00ff0000, got 0x%08x.\n", color);
5753 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5754 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5755 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MAXMIPLEVEL, 0);
5756 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
5757 add_dirty_rect_test_draw(device);
5758 color = getPixelColor(device, 320, 240);
5759 ok(color_match(color, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color);
5760 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5761 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5763 /* AddDirtyRect uploads the new contents.
5764 * Side note, not tested in the test: Partial surface updates work, and two separate
5765 * dirty rectangles are tracked individually. Tested on Nvidia Kepler, other drivers
5766 * untested. */
5767 hr = IDirect3DTexture8_AddDirtyRect(tex_managed, NULL);
5768 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
5769 add_dirty_rect_test_draw(device);
5770 color = getPixelColor(device, 320, 240);
5771 ok(color_match(color, 0x0000ff00, 1),
5772 "Expected color 0x0000ff00, got 0x%08x.\n", color);
5773 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5774 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5775 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MAXMIPLEVEL, 1);
5776 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
5777 add_dirty_rect_test_draw(device);
5778 color = getPixelColor(device, 320, 240);
5779 ok(color_match(color, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color);
5780 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5781 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5783 /* So does ResourceManagerDiscardBytes. */
5784 fill_surface(surface_managed0, 0x00ffff00, D3DLOCK_NO_DIRTY_UPDATE);
5785 fill_surface(surface_managed1, 0x00ff00ff, D3DLOCK_NO_DIRTY_UPDATE);
5786 hr = IDirect3DDevice8_ResourceManagerDiscardBytes(device, 0);
5787 ok(SUCCEEDED(hr), "Failed to evict managed resources, hr %#x.\n", hr);
5788 add_dirty_rect_test_draw(device);
5789 color = getPixelColor(device, 320, 240);
5790 ok(color_match(color, 0x00ff00ff, 1), "Got unexpected color 0x%08x.\n", color);
5791 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5792 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5793 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MAXMIPLEVEL, 0);
5794 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
5795 add_dirty_rect_test_draw(device);
5796 color = getPixelColor(device, 320, 240);
5797 ok(color_match(color, 0x00ffff00, 1), "Got unexpected color 0x%08x.\n", color);
5798 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5799 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5801 /* Tests with dynamic textures */
5802 fill_surface(surface_dynamic, 0x0000ffff, 0);
5803 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)tex_dynamic);
5804 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
5805 add_dirty_rect_test_draw(device);
5806 color = getPixelColor(device, 320, 240);
5807 ok(color_match(color, 0x0000ffff, 1),
5808 "Expected color 0x0000ffff, got 0x%08x.\n", color);
5809 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5810 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5812 /* Dynamic textures don't honor D3DLOCK_NO_DIRTY_UPDATE. */
5813 fill_surface(surface_dynamic, 0x00ffff00, D3DLOCK_NO_DIRTY_UPDATE);
5814 add_dirty_rect_test_draw(device);
5815 color = getPixelColor(device, 320, 240);
5816 ok(color_match(color, 0x00ffff00, 1),
5817 "Expected color 0x00ffff00, got 0x%08x.\n", color);
5818 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5819 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5821 /* AddDirtyRect on a locked texture is allowed. */
5822 hr = IDirect3DTexture8_LockRect(tex_src_red, 0, &locked_rect, NULL, 0);
5823 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
5824 hr = IDirect3DTexture8_AddDirtyRect(tex_src_red, NULL);
5825 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
5826 hr = IDirect3DTexture8_UnlockRect(tex_src_red, 0);
5827 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
5829 /* Redundant AddDirtyRect calls are ok. */
5830 hr = IDirect3DTexture8_AddDirtyRect(tex_managed, NULL);
5831 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
5832 hr = IDirect3DTexture8_AddDirtyRect(tex_managed, NULL);
5833 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
5835 /* Test out-of-bounds regions. */
5836 for (i = 0; i < ARRAY_SIZE(oob_rect); ++i)
5838 hr = IDirect3DTexture8_AddDirtyRect(tex_src_red, &oob_rect[i]);
5839 ok(hr == D3DERR_INVALIDCALL, "[%u] Got unexpected hr %#x.\n", i, hr);
5840 hr = IDirect3DTexture8_LockRect(tex_src_red, 0, &locked_rect, &oob_rect[i], 0);
5841 ok(SUCCEEDED(hr), "[%u] Got unexpected hr %#x.\n", i, hr);
5842 hr = IDirect3DTexture8_UnlockRect(tex_src_red, 0);
5843 ok(SUCCEEDED(hr), "[%u] Got unexpected hr %#x.\n", i, hr);
5846 IDirect3DSurface8_Release(surface_dst2);
5847 IDirect3DSurface8_Release(surface_managed1);
5848 IDirect3DSurface8_Release(surface_managed0);
5849 IDirect3DSurface8_Release(surface_src_red);
5850 IDirect3DSurface8_Release(surface_src_green);
5851 IDirect3DSurface8_Release(surface_dynamic);
5852 IDirect3DTexture8_Release(tex_src_red);
5853 IDirect3DTexture8_Release(tex_src_green);
5854 IDirect3DTexture8_Release(tex_dst1);
5855 IDirect3DTexture8_Release(tex_dst2);
5856 IDirect3DTexture8_Release(tex_managed);
5857 IDirect3DTexture8_Release(tex_dynamic);
5858 refcount = IDirect3DDevice8_Release(device);
5859 ok(!refcount, "Device has %u references left.\n", refcount);
5860 done:
5861 IDirect3D8_Release(d3d);
5862 DestroyWindow(window);
5865 static void test_3dc_formats(void)
5867 static const char ati1n_data[] =
5869 /* A 4x4 texture with the color component at 50%. */
5870 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5872 static const char ati2n_data[] =
5874 /* A 8x4 texture consisting of 2 4x4 blocks. The first block has 50% first color component,
5875 * 0% second component. Second block is the opposite. */
5876 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5877 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5879 static const struct
5881 struct vec3 position;
5882 struct vec2 texcoord;
5884 quads[] =
5886 {{-1.0f, -1.0f, 0.0f}, {0.0f, 0.0f}},
5887 {{-1.0f, 1.0f, 0.0f}, {0.0f, 1.0f}},
5888 {{ 0.0f, -1.0f, 1.0f}, {1.0f, 0.0f}},
5889 {{ 0.0f, 1.0f, 1.0f}, {1.0f, 1.0f}},
5891 {{ 0.0f, -1.0f, 0.0f}, {0.0f, 0.0f}},
5892 {{ 0.0f, 1.0f, 0.0f}, {0.0f, 1.0f}},
5893 {{ 1.0f, -1.0f, 1.0f}, {1.0f, 0.0f}},
5894 {{ 1.0f, 1.0f, 1.0f}, {1.0f, 1.0f}},
5896 static const DWORD ati1n_fourcc = MAKEFOURCC('A','T','I','1');
5897 static const DWORD ati2n_fourcc = MAKEFOURCC('A','T','I','2');
5898 static const struct
5900 struct vec2 position;
5901 D3DCOLOR amd_r500;
5902 D3DCOLOR amd_r600;
5903 D3DCOLOR nvidia_old;
5904 D3DCOLOR nvidia_new;
5906 expected_colors[] =
5908 {{ 80, 240}, 0x007fffff, 0x003f3f3f, 0x007f7f7f, 0x007f0000},
5909 {{240, 240}, 0x007fffff, 0x003f3f3f, 0x007f7f7f, 0x007f0000},
5910 {{400, 240}, 0x00007fff, 0x00007fff, 0x00007fff, 0x00007fff},
5911 {{560, 240}, 0x007f00ff, 0x007f00ff, 0x007f00ff, 0x007f00ff},
5913 IDirect3D8 *d3d;
5914 IDirect3DDevice8 *device;
5915 IDirect3DTexture8 *ati1n_texture, *ati2n_texture;
5916 D3DCAPS8 caps;
5917 D3DLOCKED_RECT rect;
5918 D3DCOLOR color;
5919 ULONG refcount;
5920 HWND window;
5921 HRESULT hr;
5922 unsigned int i;
5924 window = create_window();
5925 d3d = Direct3DCreate8(D3D_SDK_VERSION);
5926 ok(!!d3d, "Failed to create a D3D object.\n");
5927 if (FAILED(IDirect3D8_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
5928 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, ati1n_fourcc)))
5930 skip("ATI1N textures are not supported, skipping test.\n");
5931 goto done;
5933 if (FAILED(IDirect3D8_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
5934 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, ati2n_fourcc)))
5936 skip("ATI2N textures are not supported, skipping test.\n");
5937 goto done;
5939 if (!(device = create_device(d3d, window, window, TRUE)))
5941 skip("Failed to create a D3D device, skipping tests.\n");
5942 goto done;
5944 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
5945 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
5946 if (!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP))
5948 skip("D3DTA_TEMP not supported, skipping tests.\n");
5949 IDirect3DDevice8_Release(device);
5950 goto done;
5953 hr = IDirect3DDevice8_CreateTexture(device, 4, 4, 1, 0, ati1n_fourcc,
5954 D3DPOOL_MANAGED, &ati1n_texture);
5955 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
5957 hr = IDirect3DTexture8_LockRect(ati1n_texture, 0, &rect, NULL, 0);
5958 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
5959 memcpy(rect.pBits, ati1n_data, sizeof(ati1n_data));
5960 hr = IDirect3DTexture8_UnlockRect(ati1n_texture, 0);
5961 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
5963 hr = IDirect3DDevice8_CreateTexture(device, 8, 4, 1, 0, ati2n_fourcc,
5964 D3DPOOL_MANAGED, &ati2n_texture);
5965 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
5967 hr = IDirect3DTexture8_LockRect(ati2n_texture, 0, &rect, NULL, 0);
5968 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
5969 memcpy(rect.pBits, ati2n_data, sizeof(ati2n_data));
5970 hr = IDirect3DTexture8_UnlockRect(ati2n_texture, 0);
5971 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
5973 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE2(0));
5974 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
5975 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BLENDTEXTUREALPHA);
5976 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
5977 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
5978 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
5979 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TEMP);
5980 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
5981 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
5982 ok(SUCCEEDED(hr), "Failed to set alpha op, hr %#x.\n", hr);
5983 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
5984 ok(SUCCEEDED(hr), "Failed to set alpha arg, hr %#x.\n", hr);
5985 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
5986 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
5987 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MAGFILTER, D3DTEXF_POINT);
5988 ok(SUCCEEDED(hr), "Failed to set mag filter, hr %#x.\n", hr);
5990 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff00ff, 1.0f, 0);
5991 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
5992 hr = IDirect3DDevice8_BeginScene(device);
5993 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5994 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)ati1n_texture);
5995 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
5996 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads));
5997 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5998 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)ati2n_texture);
5999 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
6000 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[4], sizeof(*quads));
6001 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6002 hr = IDirect3DDevice8_EndScene(device);
6003 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6005 for (i = 0; i < 4; ++i)
6007 color = getPixelColor(device, expected_colors[i].position.x, expected_colors[i].position.y);
6008 ok (color_match(color, expected_colors[i].amd_r500, 1)
6009 || color_match(color, expected_colors[i].amd_r600, 1)
6010 || color_match(color, expected_colors[i].nvidia_old, 1)
6011 || color_match(color, expected_colors[i].nvidia_new, 1),
6012 "Got unexpected color 0x%08x, case %u.\n", color, i);
6015 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
6016 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
6017 IDirect3DTexture8_Release(ati2n_texture);
6018 IDirect3DTexture8_Release(ati1n_texture);
6019 refcount = IDirect3DDevice8_Release(device);
6020 ok(!refcount, "Device has %u references left.\n", refcount);
6022 done:
6023 IDirect3D8_Release(d3d);
6024 DestroyWindow(window);
6027 static void test_fog_interpolation(void)
6029 HRESULT hr;
6030 IDirect3DDevice8 *device;
6031 IDirect3D8 *d3d;
6032 ULONG refcount;
6033 HWND window;
6034 D3DCOLOR color;
6035 static const struct
6037 struct vec3 position;
6038 D3DCOLOR diffuse;
6039 D3DCOLOR specular;
6041 quad[] =
6043 {{-1.0f, -1.0f, 0.0f}, 0xffff0000, 0xff000000},
6044 {{-1.0f, 1.0f, 0.0f}, 0xffff0000, 0xff000000},
6045 {{ 1.0f, -1.0f, 1.0f}, 0xffff0000, 0x00000000},
6046 {{ 1.0f, 1.0f, 1.0f}, 0xffff0000, 0x00000000},
6048 union
6050 DWORD d;
6051 float f;
6052 } conv;
6053 unsigned int i;
6054 static const struct
6056 D3DFOGMODE vfog, tfog;
6057 D3DSHADEMODE shade;
6058 D3DCOLOR middle_color;
6059 BOOL todo;
6061 tests[] =
6063 {D3DFOG_NONE, D3DFOG_NONE, D3DSHADE_FLAT, 0x00007f80, FALSE},
6064 {D3DFOG_NONE, D3DFOG_NONE, D3DSHADE_GOURAUD, 0x00007f80, FALSE},
6065 {D3DFOG_EXP, D3DFOG_NONE, D3DSHADE_FLAT, 0x00007f80, TRUE},
6066 {D3DFOG_EXP, D3DFOG_NONE, D3DSHADE_GOURAUD, 0x00007f80, TRUE},
6067 {D3DFOG_NONE, D3DFOG_EXP, D3DSHADE_FLAT, 0x0000ea15, FALSE},
6068 {D3DFOG_NONE, D3DFOG_EXP, D3DSHADE_GOURAUD, 0x0000ea15, FALSE},
6069 {D3DFOG_EXP, D3DFOG_EXP, D3DSHADE_FLAT, 0x0000ea15, FALSE},
6070 {D3DFOG_EXP, D3DFOG_EXP, D3DSHADE_GOURAUD, 0x0000ea15, FALSE},
6072 static const D3DMATRIX ident_mat =
6074 1.0f, 0.0f, 0.0f, 0.0f,
6075 0.0f, 1.0f, 0.0f, 0.0f,
6076 0.0f, 0.0f, 1.0f, 0.0f,
6077 0.0f, 0.0f, 0.0f, 1.0f
6078 }}};
6079 D3DCAPS8 caps;
6081 window = create_window();
6082 d3d = Direct3DCreate8(D3D_SDK_VERSION);
6083 ok(!!d3d, "Failed to create a D3D object.\n");
6085 if (!(device = create_device(d3d, window, window, TRUE)))
6087 skip("Failed to create a D3D device, skipping tests.\n");
6088 IDirect3D8_Release(d3d);
6089 DestroyWindow(window);
6090 return;
6093 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
6094 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
6095 if (!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE))
6096 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping some fog tests\n");
6098 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
6099 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr);
6100 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6101 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6102 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, FALSE);
6103 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6104 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
6105 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6106 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGCOLOR, 0x0000ff00);
6107 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6108 conv.f = 5.0;
6109 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGDENSITY, conv.d);
6110 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6112 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
6113 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
6114 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TFACTOR);
6115 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
6116 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x000000ff);
6117 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6119 /* Some of the tests seem to depend on the projection matrix explicitly
6120 * being set to an identity matrix, even though that's the default.
6121 * (AMD Radeon X1600, AMD Radeon HD 6310, Windows 7). Without this,
6122 * the drivers seem to use a static z = 1.0 input for the fog equation.
6123 * The input value is independent of the actual z and w component of
6124 * the vertex position. */
6125 hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, &ident_mat);
6126 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
6128 for (i = 0; i < ARRAY_SIZE(tests); i++)
6130 if(!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE) && tests[i].tfog)
6131 continue;
6133 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00808080, 0.0f, 0);
6134 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
6136 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SHADEMODE, tests[i].shade);
6137 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6138 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGVERTEXMODE, tests[i].vfog);
6139 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6140 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGTABLEMODE, tests[i].tfog);
6141 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6142 hr = IDirect3DDevice8_BeginScene(device);
6143 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6144 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
6145 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6146 hr = IDirect3DDevice8_EndScene(device);
6147 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6149 color = getPixelColor(device, 0, 240);
6150 ok(color_match(color, 0x000000ff, 2), "Got unexpected color 0x%08x, case %u.\n", color, i);
6151 color = getPixelColor(device, 320, 240);
6152 todo_wine_if (tests[i].todo)
6153 ok(color_match(color, tests[i].middle_color, 2),
6154 "Got unexpected color 0x%08x, case %u.\n", color, i);
6155 color = getPixelColor(device, 639, 240);
6156 ok(color_match(color, 0x0000fd02, 2), "Got unexpected color 0x%08x, case %u.\n", color, i);
6157 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
6158 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
6161 refcount = IDirect3DDevice8_Release(device);
6162 ok(!refcount, "Device has %u references left.\n", refcount);
6163 IDirect3D8_Release(d3d);
6164 DestroyWindow(window);
6167 static void test_negative_fixedfunction_fog(void)
6169 HRESULT hr;
6170 IDirect3DDevice8 *device;
6171 IDirect3D8 *d3d;
6172 ULONG refcount;
6173 HWND window;
6174 D3DCOLOR color;
6175 static const struct
6177 struct vec3 position;
6178 D3DCOLOR diffuse;
6180 quad[] =
6182 {{-1.0f, -1.0f, -0.5f}, 0xffff0000},
6183 {{-1.0f, 1.0f, -0.5f}, 0xffff0000},
6184 {{ 1.0f, -1.0f, -0.5f}, 0xffff0000},
6185 {{ 1.0f, 1.0f, -0.5f}, 0xffff0000},
6187 static const struct
6189 struct vec4 position;
6190 D3DCOLOR diffuse;
6192 tquad[] =
6194 {{ 0.0f, 0.0f, -0.5f, 1.0f}, 0xffff0000},
6195 {{640.0f, 0.0f, -0.5f, 1.0f}, 0xffff0000},
6196 {{ 0.0f, 480.0f, -0.5f, 1.0f}, 0xffff0000},
6197 {{640.0f, 480.0f, -0.5f, 1.0f}, 0xffff0000},
6199 unsigned int i;
6200 static const D3DMATRIX zero =
6202 1.0f, 0.0f, 0.0f, 0.0f,
6203 0.0f, 1.0f, 0.0f, 0.0f,
6204 0.0f, 0.0f, 0.0f, 0.0f,
6205 0.0f, 0.0f, 0.0f, 1.0f
6206 }}};
6207 /* Needed to make AMD drivers happy. Yeah, it is not supposed to
6208 * have an effect on RHW draws. */
6209 static const D3DMATRIX identity =
6211 1.0f, 0.0f, 0.0f, 0.0f,
6212 0.0f, 1.0f, 0.0f, 0.0f,
6213 0.0f, 0.0f, 1.0f, 0.0f,
6214 0.0f, 0.0f, 0.0f, 1.0f
6215 }}};
6216 static const struct
6218 DWORD pos_type;
6219 const void *quad;
6220 size_t stride;
6221 const D3DMATRIX *matrix;
6222 union
6224 float f;
6225 DWORD d;
6226 } start, end;
6227 D3DFOGMODE vfog, tfog;
6228 DWORD color, color_broken, color_broken2;
6230 tests[] =
6232 /* Run the XYZRHW tests first. Depth clamping is broken after RHW draws on the testbot.
6234 * Geforce8+ GPUs on Windows abs() table fog, everything else does not. */
6235 {D3DFVF_XYZRHW, tquad, sizeof(*tquad), &identity, { 0.0f}, {1.0f},
6236 D3DFOG_NONE, D3DFOG_LINEAR, 0x00ff0000, 0x00808000, 0x00808000},
6237 /* r200 GPUs and presumably all d3d8 and older HW clamp the fog
6238 * parameters to 0.0 and 1.0 in the table fog case. */
6239 {D3DFVF_XYZRHW, tquad, sizeof(*tquad), &identity, {-1.0f}, {0.0f},
6240 D3DFOG_NONE, D3DFOG_LINEAR, 0x00808000, 0x00ff0000, 0x0000ff00},
6241 /* test_fog_interpolation shows that vertex fog evaluates the fog
6242 * equation in the vertex pipeline. Start = -1.0 && end = 0.0 shows
6243 * that the abs happens before the fog equation is evaluated.
6245 * Vertex fog abs() behavior is the same on all GPUs. */
6246 {D3DFVF_XYZ, quad, sizeof(*quad), &zero, { 0.0f}, {1.0f},
6247 D3DFOG_LINEAR, D3DFOG_NONE, 0x00808000, 0x00808000, 0x00808000},
6248 {D3DFVF_XYZ, quad, sizeof(*quad), &zero, {-1.0f}, {0.0f},
6249 D3DFOG_LINEAR, D3DFOG_NONE, 0x0000ff00, 0x0000ff00, 0x0000ff00},
6250 {D3DFVF_XYZ, quad, sizeof(*quad), &zero, { 0.0f}, {1.0f},
6251 D3DFOG_EXP, D3DFOG_NONE, 0x009b6400, 0x009b6400, 0x009b6400},
6253 D3DCAPS8 caps;
6255 window = create_window();
6256 d3d = Direct3DCreate8(D3D_SDK_VERSION);
6257 ok(!!d3d, "Failed to create a D3D object.\n");
6259 if (!(device = create_device(d3d, window, window, TRUE)))
6261 skip("Failed to create a D3D device, skipping tests.\n");
6262 IDirect3D8_Release(d3d);
6263 DestroyWindow(window);
6264 return;
6267 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
6268 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
6269 if (!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE))
6270 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping some fog tests.\n");
6272 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6273 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6274 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
6275 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6276 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
6277 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6278 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGCOLOR, 0x0000ff00);
6279 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6280 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, FALSE);
6281 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
6283 for (i = 0; i < ARRAY_SIZE(tests); i++)
6285 if (!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE) && tests[i].tfog)
6286 continue;
6288 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x000000ff, 0.0f, 0);
6289 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
6291 hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, tests[i].matrix);
6292 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
6293 hr = IDirect3DDevice8_SetVertexShader(device, tests[i].pos_type | D3DFVF_DIFFUSE);
6294 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr);
6295 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGSTART, tests[i].start.d);
6296 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6297 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGEND, tests[i].end.d);
6298 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6299 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGVERTEXMODE, tests[i].vfog);
6300 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6301 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGTABLEMODE, tests[i].tfog);
6302 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6304 hr = IDirect3DDevice8_BeginScene(device);
6305 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6306 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, tests[i].quad, tests[i].stride);
6307 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6308 hr = IDirect3DDevice8_EndScene(device);
6309 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6311 color = getPixelColor(device, 320, 240);
6312 ok(color_match(color, tests[i].color, 2) || broken(color_match(color, tests[i].color_broken, 2))
6313 || broken(color_match(color, tests[i].color_broken2, 2)),
6314 "Got unexpected color 0x%08x, case %u.\n", color, i);
6315 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
6316 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
6319 refcount = IDirect3DDevice8_Release(device);
6320 ok(!refcount, "Device has %u references left.\n", refcount);
6321 IDirect3D8_Release(d3d);
6322 DestroyWindow(window);
6325 static void test_table_fog_zw(void)
6327 HRESULT hr;
6328 IDirect3DDevice8 *device;
6329 IDirect3D8 *d3d;
6330 ULONG refcount;
6331 HWND window;
6332 D3DCOLOR color;
6333 D3DCAPS8 caps;
6334 static struct
6336 struct vec4 position;
6337 D3DCOLOR diffuse;
6339 quad[] =
6341 {{ 0.0f, 0.0f, 0.0f, 0.0f}, 0xffff0000},
6342 {{640.0f, 0.0f, 0.0f, 0.0f}, 0xffff0000},
6343 {{ 0.0f, 480.0f, 0.0f, 0.0f}, 0xffff0000},
6344 {{640.0f, 480.0f, 0.0f, 0.0f}, 0xffff0000},
6346 static const D3DMATRIX identity =
6348 1.0f, 0.0f, 0.0f, 0.0f,
6349 0.0f, 1.0f, 0.0f, 0.0f,
6350 0.0f, 0.0f, 1.0f, 0.0f,
6351 0.0f, 0.0f, 0.0f, 1.0f
6352 }}};
6353 static const struct
6355 float z, w;
6356 D3DZBUFFERTYPE z_test;
6357 D3DCOLOR color;
6359 tests[] =
6361 {0.7f, 0.0f, D3DZB_TRUE, 0x004cb200},
6362 {0.7f, 0.0f, D3DZB_FALSE, 0x004cb200},
6363 {0.7f, 0.3f, D3DZB_TRUE, 0x004cb200},
6364 {0.7f, 0.3f, D3DZB_FALSE, 0x004cb200},
6365 {0.7f, 3.0f, D3DZB_TRUE, 0x004cb200},
6366 {0.7f, 3.0f, D3DZB_FALSE, 0x004cb200},
6367 {0.3f, 0.0f, D3DZB_TRUE, 0x00b24c00},
6368 {0.3f, 0.0f, D3DZB_FALSE, 0x00b24c00},
6370 unsigned int i;
6372 window = create_window();
6373 d3d = Direct3DCreate8(D3D_SDK_VERSION);
6374 ok(!!d3d, "Failed to create a D3D object.\n");
6376 if (!(device = create_device(d3d, window, window, TRUE)))
6378 skip("Failed to create a D3D device, skipping tests.\n");
6379 IDirect3D8_Release(d3d);
6380 DestroyWindow(window);
6381 return;
6384 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
6385 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
6386 if (!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE))
6388 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping POSITIONT table fog test.\n");
6389 goto done;
6392 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6393 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6394 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
6395 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6396 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGCOLOR, 0x0000ff00);
6397 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6398 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, FALSE);
6399 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
6400 /* Work around an AMD Windows driver bug. Needs a proj matrix applied redundantly. */
6401 hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, &identity);
6402 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
6403 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
6404 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6405 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
6406 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr);
6408 for (i = 0; i < ARRAY_SIZE(tests); ++i)
6410 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
6411 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
6413 quad[0].position.z = tests[i].z;
6414 quad[1].position.z = tests[i].z;
6415 quad[2].position.z = tests[i].z;
6416 quad[3].position.z = tests[i].z;
6417 quad[0].position.w = tests[i].w;
6418 quad[1].position.w = tests[i].w;
6419 quad[2].position.w = tests[i].w;
6420 quad[3].position.w = tests[i].w;
6421 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, tests[i].z_test);
6422 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6424 hr = IDirect3DDevice8_BeginScene(device);
6425 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6426 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
6427 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6428 hr = IDirect3DDevice8_EndScene(device);
6429 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6431 color = getPixelColor(device, 320, 240);
6432 ok(color_match(color, tests[i].color, 2),
6433 "Got unexpected color 0x%08x, expected 0x%08x, case %u.\n", color, tests[i].color, i);
6434 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
6435 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
6438 done:
6439 refcount = IDirect3DDevice8_Release(device);
6440 ok(!refcount, "Device has %u references left.\n", refcount);
6441 IDirect3D8_Release(d3d);
6442 DestroyWindow(window);
6445 static void test_signed_formats(void)
6447 IDirect3DDevice8 *device;
6448 HWND window;
6449 HRESULT hr;
6450 unsigned int i, j, x, y;
6451 IDirect3DTexture8 *texture, *texture_sysmem;
6452 D3DLOCKED_RECT locked_rect;
6453 DWORD shader, shader_alpha;
6454 IDirect3D8 *d3d;
6455 D3DCOLOR color;
6456 D3DCAPS8 caps;
6457 ULONG refcount;
6459 /* See comments in the d3d9 version of this test for an
6460 * explanation of these values. */
6461 static const USHORT content_v8u8[4][4] =
6463 {0x0000, 0x7f7f, 0x8880, 0x0000},
6464 {0x0080, 0x8000, 0x7f00, 0x007f},
6465 {0x193b, 0xe8c8, 0x0808, 0xf8f8},
6466 {0x4444, 0xc0c0, 0xa066, 0x22e0},
6468 static const DWORD content_v16u16[4][4] =
6470 {0x00000000, 0x7fff7fff, 0x88008000, 0x00000000},
6471 {0x00008000, 0x80000000, 0x7fff0000, 0x00007fff},
6472 {0x19993bbb, 0xe800c800, 0x08880888, 0xf800f800},
6473 {0x44444444, 0xc000c000, 0xa0006666, 0x2222e000},
6475 static const DWORD content_q8w8v8u8[4][4] =
6477 {0x00000000, 0xff7f7f7f, 0x7f008880, 0x817f0000},
6478 {0x10000080, 0x20008000, 0x30007f00, 0x4000007f},
6479 {0x5020193b, 0x6028e8c8, 0x70020808, 0x807ff8f8},
6480 {0x90414444, 0xa000c0c0, 0x8261a066, 0x834922e0},
6482 static const DWORD content_x8l8v8u8[4][4] =
6484 {0x00000000, 0x00ff7f7f, 0x00008880, 0x00ff0000},
6485 {0x00000080, 0x00008000, 0x00007f00, 0x0000007f},
6486 {0x0041193b, 0x0051e8c8, 0x00040808, 0x00fff8f8},
6487 {0x00824444, 0x0000c0c0, 0x00c2a066, 0x009222e0},
6489 static const USHORT content_l6v5u5[4][4] =
6491 {0x0000, 0xfdef, 0x0230, 0xfc00},
6492 {0x0010, 0x0200, 0x01e0, 0x000f},
6493 {0x4067, 0x53b9, 0x0421, 0xffff},
6494 {0x8108, 0x0318, 0xc28c, 0x909c},
6496 static const struct
6498 D3DFORMAT format;
6499 const char *name;
6500 const void *content;
6501 SIZE_T pixel_size;
6502 BOOL blue, alpha;
6503 unsigned int slop, slop_broken, alpha_broken;
6505 formats[] =
6507 {D3DFMT_V8U8, "D3DFMT_V8U8", content_v8u8, sizeof(WORD), FALSE, FALSE, 1, 0, FALSE},
6508 {D3DFMT_V16U16, "D3DFMT_V16U16", content_v16u16, sizeof(DWORD), FALSE, FALSE, 1, 0, FALSE},
6509 {D3DFMT_Q8W8V8U8, "D3DFMT_Q8W8V8U8", content_q8w8v8u8, sizeof(DWORD), TRUE, TRUE, 1, 0, TRUE },
6510 {D3DFMT_X8L8V8U8, "D3DFMT_X8L8V8U8", content_x8l8v8u8, sizeof(DWORD), TRUE, FALSE, 1, 0, FALSE},
6511 {D3DFMT_L6V5U5, "D3DFMT_L6V5U5", content_l6v5u5, sizeof(WORD), TRUE, FALSE, 4, 7, FALSE},
6513 static const struct
6515 D3DPOOL pool;
6516 UINT width;
6518 tests[] =
6520 {D3DPOOL_SYSTEMMEM, 4},
6521 {D3DPOOL_SYSTEMMEM, 1},
6522 {D3DPOOL_MANAGED, 4},
6523 {D3DPOOL_MANAGED, 1},
6525 static const DWORD shader_code[] =
6527 0xffff0101, /* ps_1_1 */
6528 0x00000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, /* def c0, 0.5, 0.5, 0,5, 0,5 */
6529 0x00000042, 0xb00f0000, /* tex t0 */
6530 0x00000004, 0x800f0000, 0xb0e40000, 0xa0e40000, 0xa0e40000, /* mad r0, t0, c0, c0 */
6531 0x0000ffff /* end */
6533 static const DWORD shader_code_alpha[] =
6535 /* The idea of this shader is to replicate the alpha value in .rg, and set
6536 * blue to 1.0 iff the alpha value is < -1.0 and 0.0 otherwise. */
6537 0xffff0101, /* ps_1_1 */
6538 0x00000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, /* def c0, 0.5, 0.5, 0.5, 0.5 */
6539 0x00000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0 */
6540 0x00000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c2, 0.0, 0.0, 1.0, 0.0 */
6541 0x00000042, 0xb00f0000, /* tex t0 */
6542 0x00000004, 0x80070000, 0xb0ff0000, 0xa0e40000, 0xa0e40000, /* mad r0.rgb, t0.a, c0, c0 */
6543 0x00000003, 0x80080000, 0xb1ff0000, 0xa0e40000, /* sub r0.a, -t0.a, c0 */
6544 0x00000050, 0x80080000, 0x80ff0000, 0xa0ff0001, 0xa0ff0002, /* cnd r0.a, r0.a, c1.a, c2.a */
6545 0x00000005, 0x80070001, 0xa0e40001, 0x80e40000, /* mul r1.rgb, c1, r0 */
6546 0x00000004, 0x80070000, 0x80ff0000, 0xa0e40002, 0x80e40001, /* mad r0.rgb, r0.a, c2, r1 */
6547 0x0000ffff /* end */
6549 static const struct
6551 struct vec3 position;
6552 struct vec2 texcrd;
6554 quad[] =
6556 /* Flip the y coordinate to make the input and
6557 * output arrays easier to compare. */
6558 {{ -1.0f, -1.0f, 0.0f}, { 0.0f, 1.0f}},
6559 {{ -1.0f, 1.0f, 0.0f}, { 0.0f, 0.0f}},
6560 {{ 1.0f, -1.0f, 0.0f}, { 1.0f, 1.0f}},
6561 {{ 1.0f, 1.0f, 0.0f}, { 1.0f, 0.0f}},
6563 static const D3DCOLOR expected_alpha[4][4] =
6565 {0x00808000, 0x007f7f00, 0x00ffff00, 0x00000000},
6566 {0x00909000, 0x00a0a000, 0x00b0b000, 0x00c0c000},
6567 {0x00d0d000, 0x00e0e000, 0x00f0f000, 0x00000000},
6568 {0x00101000, 0x00202000, 0x00010100, 0x00020200},
6570 static const BOOL alpha_broken[4][4] =
6572 {FALSE, FALSE, FALSE, FALSE},
6573 {FALSE, FALSE, FALSE, FALSE},
6574 {FALSE, FALSE, FALSE, TRUE },
6575 {FALSE, FALSE, FALSE, FALSE},
6577 static const D3DCOLOR expected_colors[4][4] =
6579 {0x00808080, 0x00fefeff, 0x00010780, 0x008080ff},
6580 {0x00018080, 0x00800180, 0x0080fe80, 0x00fe8080},
6581 {0x00ba98a0, 0x004767a8, 0x00888881, 0x007878ff},
6582 {0x00c3c3c0, 0x003f3f80, 0x00e51fe1, 0x005fa2c8},
6584 D3DCOLOR expected_color;
6586 window = create_window();
6587 d3d = Direct3DCreate8(D3D_SDK_VERSION);
6588 ok(!!d3d, "Failed to create a D3D object.\n");
6590 if (!(device = create_device(d3d, window, window, TRUE)))
6592 skip("Failed to create a D3D device, skipping tests.\n");
6593 IDirect3D8_Release(d3d);
6594 DestroyWindow(window);
6595 return;
6598 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
6599 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
6601 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 1))
6603 skip("Pixel shaders not supported, skipping converted format test.\n");
6604 goto done;
6607 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
6608 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6609 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX1);
6610 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
6611 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code, &shader);
6612 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
6613 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code_alpha, &shader_alpha);
6614 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
6616 for (i = 0; i < ARRAY_SIZE(formats); i++)
6618 hr = IDirect3D8_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
6619 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, formats[i].format);
6620 if (FAILED(hr))
6622 skip("Format %s not supported, skipping.\n", formats[i].name);
6623 continue;
6626 for (j = 0; j < ARRAY_SIZE(tests); j++)
6628 texture_sysmem = NULL;
6629 hr = IDirect3DDevice8_CreateTexture(device, tests[j].width, 4, 1, 0,
6630 formats[i].format, tests[j].pool, &texture);
6631 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
6633 hr = IDirect3DTexture8_LockRect(texture, 0, &locked_rect, NULL, 0);
6634 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
6635 for (y = 0; y < 4; y++)
6637 memcpy((char *)locked_rect.pBits + y * locked_rect.Pitch,
6638 (char *)formats[i].content + y * 4 * formats[i].pixel_size,
6639 tests[j].width * formats[i].pixel_size);
6641 hr = IDirect3DTexture8_UnlockRect(texture, 0);
6642 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
6644 if (tests[j].pool == D3DPOOL_SYSTEMMEM)
6646 texture_sysmem = texture;
6647 hr = IDirect3DDevice8_CreateTexture(device, tests[j].width, 4, 1, 0,
6648 formats[i].format, D3DPOOL_DEFAULT, &texture);
6649 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
6651 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)texture_sysmem,
6652 (IDirect3DBaseTexture8 *)texture);
6653 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
6654 IDirect3DTexture8_Release(texture_sysmem);
6657 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
6658 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
6659 hr = IDirect3DDevice8_SetPixelShader(device, shader_alpha);
6660 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6662 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00330033, 0.0f, 0);
6663 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
6664 hr = IDirect3DDevice8_BeginScene(device);
6665 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6666 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(*quad));
6667 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6668 hr = IDirect3DDevice8_EndScene(device);
6669 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6671 for (y = 0; y < 4; y++)
6673 for (x = 0; x < tests[j].width; x++)
6675 BOOL r200_broken = formats[i].alpha_broken && alpha_broken[y][x];
6676 if (formats[i].alpha)
6677 expected_color = expected_alpha[y][x];
6678 else
6679 expected_color = 0x00ffff00;
6681 color = getPixelColor(device, 80 + 160 * x, 60 + 120 * y);
6682 ok(color_match(color, expected_color, 1) || broken(r200_broken),
6683 "Expected color 0x%08x, got 0x%08x, format %s, test %u, location %ux%u.\n",
6684 expected_color, color, formats[i].name, j, x, y);
6687 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
6688 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
6690 hr = IDirect3DDevice8_SetPixelShader(device, shader);
6691 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6693 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00330033, 0.0f, 0);
6694 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
6695 hr = IDirect3DDevice8_BeginScene(device);
6696 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6697 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(*quad));
6698 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6699 hr = IDirect3DDevice8_EndScene(device);
6700 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6702 for (y = 0; y < 4; y++)
6704 for (x = 0; x < tests[j].width; x++)
6706 expected_color = expected_colors[y][x];
6707 if (!formats[i].blue)
6708 expected_color |= 0x000000ff;
6710 color = getPixelColor(device, 80 + 160 * x, 60 + 120 * y);
6711 ok(color_match(color, expected_color, formats[i].slop)
6712 || broken(color_match(color, expected_color, formats[i].slop_broken)),
6713 "Expected color 0x%08x, got 0x%08x, format %s, test %u, location %ux%u.\n",
6714 expected_color, color, formats[i].name, j, x, y);
6717 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
6718 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
6720 IDirect3DTexture8_Release(texture);
6724 IDirect3DDevice8_DeletePixelShader(device, shader);
6725 IDirect3DDevice8_DeletePixelShader(device, shader_alpha);
6727 done:
6728 refcount = IDirect3DDevice8_Release(device);
6729 ok(!refcount, "Device has %u references left.\n", refcount);
6730 IDirect3D8_Release(d3d);
6731 DestroyWindow(window);
6734 static void test_updatetexture(void)
6736 IDirect3DDevice8 *device;
6737 IDirect3D8 *d3d;
6738 HWND window;
6739 HRESULT hr;
6740 IDirect3DBaseTexture8 *src, *dst;
6741 unsigned int t, i, f, l, x, y, z;
6742 D3DLOCKED_RECT locked_rect;
6743 D3DLOCKED_BOX locked_box;
6744 ULONG refcount;
6745 D3DCAPS8 caps;
6746 D3DCOLOR color;
6747 BOOL ati2n_supported, do_visual_test;
6748 static const struct
6750 struct vec3 pos;
6751 struct vec2 texcoord;
6753 quad[] =
6755 {{-1.0f, -1.0f, 0.0f}, {0.0f, 1.0f}},
6756 {{-1.0f, 1.0f, 0.0f}, {0.0f, 0.0f}},
6757 {{ 1.0f, -1.0f, 0.0f}, {1.0f, 1.0f}},
6758 {{ 1.0f, 1.0f, 0.0f}, {1.0f, 0.0f}},
6760 static const struct
6762 struct vec3 pos;
6763 struct vec3 texcoord;
6765 quad_cube_tex[] =
6767 {{-1.0f, -1.0f, 0.0f}, {1.0f, -0.5f, 0.5f}},
6768 {{-1.0f, 1.0f, 0.0f}, {1.0f, 0.5f, 0.5f}},
6769 {{ 1.0f, -1.0f, 0.0f}, {1.0f, -0.5f, -0.5f}},
6770 {{ 1.0f, 1.0f, 0.0f}, {1.0f, 0.5f, -0.5f}},
6772 static const struct
6774 UINT src_width, src_height;
6775 UINT dst_width, dst_height;
6776 UINT src_levels, dst_levels;
6777 D3DFORMAT src_format, dst_format;
6778 BOOL broken_result, broken_updatetex;
6780 tests[] =
6782 {8, 8, 8, 8, 0, 0, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 0 */
6783 {8, 8, 8, 8, 4, 4, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 1 */
6784 {8, 8, 8, 8, 2, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 2 */
6785 {8, 8, 8, 8, 1, 1, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 3 */
6786 {8, 8, 8, 8, 4, 0, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 4 */
6787 {8, 8, 2, 2, 4, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 5 */
6788 /* The WARP renderer doesn't handle these cases correctly. */
6789 {8, 8, 8, 8, 4, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, TRUE}, /* 6 */
6790 {8, 8, 4, 4, 4, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, TRUE}, /* 7 */
6791 /* Not clear what happens here on Windows, it doesn't make much sense
6792 * though (on Nvidia it seems to upload the 4x4 surface into the 7x7
6793 * one or something like that). */
6794 /* {8, 8, 7, 7, 4, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, */
6795 {8, 8, 8, 8, 1, 4, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 8 */
6796 /* For this one UpdateTexture() returns failure on WARP on > Win 10 1709. */
6797 {4, 4, 8, 8, 1, 1, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE, TRUE}, /* 9 */
6798 /* This one causes weird behavior on Windows (it probably writes out
6799 * of the texture memory). */
6800 /* {8, 8, 4, 4, 1, 1, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, */
6801 {8, 4, 4, 2, 4, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 10 */
6802 {8, 4, 2, 4, 4, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 11 */
6803 {8, 8, 8, 8, 4, 4, D3DFMT_A8R8G8B8, D3DFMT_X8R8G8B8, FALSE}, /* 12 */
6804 {8, 8, 8, 8, 4, 4, D3DFMT_X8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 13 */
6805 /* The data is converted correctly on AMD, on Nvidia nothing happens
6806 * (it draws a black quad). */
6807 {8, 8, 8, 8, 4, 4, D3DFMT_A8R8G8B8, D3DFMT_R5G6B5, TRUE}, /* 14 */
6808 /* This one doesn't seem to give the expected results on AMD. */
6809 /* {8, 8, 8, 8, 4, 4, D3DFMT_A8R8G8B8, D3DFMT_Q8W8V8U8, FALSE}, */
6810 {8, 8, 8, 8, 4, 4, MAKEFOURCC('A','T','I','2'), MAKEFOURCC('A','T','I','2'), FALSE}, /* 15 */
6811 {8, 8, 8, 8, 4, 2, MAKEFOURCC('A','T','I','2'), MAKEFOURCC('A','T','I','2'), FALSE}, /* 16 */
6812 {8, 8, 2, 2, 4, 2, MAKEFOURCC('A','T','I','2'), MAKEFOURCC('A','T','I','2'), FALSE}, /* 17 */
6814 static const struct
6816 D3DRESOURCETYPE type;
6817 DWORD fvf;
6818 const void *quad;
6819 unsigned int vertex_size;
6820 DWORD cap;
6821 const char *name;
6823 texture_types[] =
6825 {D3DRTYPE_TEXTURE, D3DFVF_XYZ | D3DFVF_TEX1,
6826 quad, sizeof(*quad), D3DPTEXTURECAPS_MIPMAP, "2D mipmapped"},
6828 {D3DRTYPE_CUBETEXTURE, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE3(0),
6829 quad_cube_tex, sizeof(*quad_cube_tex), D3DPTEXTURECAPS_CUBEMAP, "Cube"},
6831 {D3DRTYPE_VOLUMETEXTURE, D3DFVF_XYZ | D3DFVF_TEX1,
6832 quad, sizeof(*quad), D3DPTEXTURECAPS_VOLUMEMAP, "Volume"}
6835 window = create_window();
6836 d3d = Direct3DCreate8(D3D_SDK_VERSION);
6837 ok(!!d3d, "Failed to create a D3D object.\n");
6838 if (!(device = create_device(d3d, window, window, TRUE)))
6840 skip("Failed to create a D3D device, skipping tests.\n");
6841 IDirect3D8_Release(d3d);
6842 DestroyWindow(window);
6843 return;
6846 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
6847 ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
6849 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR);
6850 ok(SUCCEEDED(hr), "Failed to set texture filtering state, hr %#x.\n", hr);
6851 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP);
6852 ok(SUCCEEDED(hr), "Failed to set texture filtering state, hr %#x.\n", hr);
6853 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP);
6854 ok(SUCCEEDED(hr), "Failed to set texture filtering state, hr %#x.\n", hr);
6855 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_ADDRESSW, D3DTADDRESS_CLAMP);
6856 ok(SUCCEEDED(hr), "Failed to set texture filtering state, hr %#x.\n", hr);
6857 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6858 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6859 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
6860 ok(hr == D3D_OK, "Failed to set texture stage state, hr %#x.\n", hr);
6861 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
6862 ok(hr == D3D_OK, "Failed to set texture stage state, hr %#x.\n", hr);
6864 for (t = 0; t < ARRAY_SIZE(texture_types); ++t)
6866 if (!(caps.TextureCaps & texture_types[t].cap))
6868 skip("%s textures not supported, skipping some tests.\n", texture_types[t].name);
6869 continue;
6872 if (FAILED(IDirect3D8_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
6873 D3DFMT_X8R8G8B8, 0, texture_types[t].type, MAKEFOURCC('A','T','I','2'))))
6875 skip("%s ATI2N textures are not supported, skipping some tests.\n", texture_types[t].name);
6876 ati2n_supported = FALSE;
6878 else
6880 ati2n_supported = TRUE;
6883 hr = IDirect3DDevice8_SetVertexShader(device, texture_types[t].fvf);
6884 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
6886 for (i = 0; i < ARRAY_SIZE(tests); ++i)
6888 if (tests[i].src_format == MAKEFOURCC('A','T','I','2') && !ati2n_supported)
6889 continue;
6891 switch (texture_types[t].type)
6893 case D3DRTYPE_TEXTURE:
6894 hr = IDirect3DDevice8_CreateTexture(device,
6895 tests[i].src_width, tests[i].src_height,
6896 tests[i].src_levels, 0, tests[i].src_format, D3DPOOL_SYSTEMMEM,
6897 (IDirect3DTexture8 **)&src);
6898 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x, case %u, %u.\n", hr, t, i);
6899 hr = IDirect3DDevice8_CreateTexture(device,
6900 tests[i].dst_width, tests[i].dst_height,
6901 tests[i].dst_levels, 0, tests[i].dst_format, D3DPOOL_DEFAULT,
6902 (IDirect3DTexture8 **)&dst);
6903 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x, case %u, %u.\n", hr, t, i);
6904 break;
6905 case D3DRTYPE_CUBETEXTURE:
6906 hr = IDirect3DDevice8_CreateCubeTexture(device,
6907 tests[i].src_width,
6908 tests[i].src_levels, 0, tests[i].src_format, D3DPOOL_SYSTEMMEM,
6909 (IDirect3DCubeTexture8 **)&src);
6910 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x, case %u, %u.\n", hr, t, i);
6911 hr = IDirect3DDevice8_CreateCubeTexture(device,
6912 tests[i].dst_width,
6913 tests[i].dst_levels, 0, tests[i].dst_format, D3DPOOL_DEFAULT,
6914 (IDirect3DCubeTexture8 **)&dst);
6915 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x, case %u, %u.\n", hr, t, i);
6916 break;
6917 case D3DRTYPE_VOLUMETEXTURE:
6918 hr = IDirect3DDevice8_CreateVolumeTexture(device,
6919 tests[i].src_width, tests[i].src_height, tests[i].src_width,
6920 tests[i].src_levels, 0, tests[i].src_format, D3DPOOL_SYSTEMMEM,
6921 (IDirect3DVolumeTexture8 **)&src);
6922 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x, case %u, %u.\n", hr, t, i);
6923 hr = IDirect3DDevice8_CreateVolumeTexture(device,
6924 tests[i].dst_width, tests[i].dst_height, tests[i].dst_width,
6925 tests[i].dst_levels, 0, tests[i].dst_format, D3DPOOL_DEFAULT,
6926 (IDirect3DVolumeTexture8 **)&dst);
6927 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x, case %u, %u.\n", hr, t, i);
6928 break;
6929 default:
6930 trace("Unexpected resource type.\n");
6933 /* Skip the visual part of the test for ATI2N (laziness) and cases that
6934 * give a different (and unlikely to be useful) result. */
6935 do_visual_test = (tests[i].src_format == D3DFMT_A8R8G8B8 || tests[i].src_format == D3DFMT_X8R8G8B8)
6936 && tests[i].src_levels != 0
6937 && tests[i].src_width >= tests[i].dst_width && tests[i].src_height >= tests[i].dst_height
6938 && !(tests[i].src_width > tests[i].src_height && tests[i].dst_width < tests[i].dst_height);
6940 if (do_visual_test)
6942 DWORD *ptr = NULL;
6943 unsigned int width, height, depth, row_pitch = 0, slice_pitch = 0;
6945 for (f = 0; f < (texture_types[t].type == D3DRTYPE_CUBETEXTURE ? 6 : 1); ++f)
6947 width = tests[i].src_width;
6948 height = texture_types[t].type != D3DRTYPE_CUBETEXTURE ? tests[i].src_height : tests[i].src_width;
6949 depth = texture_types[t].type == D3DRTYPE_VOLUMETEXTURE ? width : 1;
6951 for (l = 0; l < tests[i].src_levels; ++l)
6953 switch (texture_types[t].type)
6955 case D3DRTYPE_TEXTURE:
6956 hr = IDirect3DTexture8_LockRect((IDirect3DTexture8 *)src,
6957 l, &locked_rect, NULL, 0);
6958 ptr = locked_rect.pBits;
6959 row_pitch = locked_rect.Pitch / sizeof(*ptr);
6960 break;
6961 case D3DRTYPE_CUBETEXTURE:
6962 hr = IDirect3DCubeTexture8_LockRect((IDirect3DCubeTexture8 *)src,
6963 f, l, &locked_rect, NULL, 0);
6964 ptr = locked_rect.pBits;
6965 row_pitch = locked_rect.Pitch / sizeof(*ptr);
6966 break;
6967 case D3DRTYPE_VOLUMETEXTURE:
6968 hr = IDirect3DVolumeTexture8_LockBox((IDirect3DVolumeTexture8 *)src,
6969 l, &locked_box, NULL, 0);
6970 ptr = locked_box.pBits;
6971 row_pitch = locked_box.RowPitch / sizeof(*ptr);
6972 slice_pitch = locked_box.SlicePitch / sizeof(*ptr);
6973 break;
6974 default:
6975 trace("Unexpected resource type.\n");
6977 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
6979 for (z = 0; z < depth; ++z)
6981 for (y = 0; y < height; ++y)
6983 for (x = 0; x < width; ++x)
6985 ptr[z * slice_pitch + y * row_pitch + x] = 0xff000000
6986 | (DWORD)(x / (width - 1.0f) * 255.0f) << 16
6987 | (DWORD)(y / (height - 1.0f) * 255.0f) << 8;
6992 switch (texture_types[t].type)
6994 case D3DRTYPE_TEXTURE:
6995 hr = IDirect3DTexture8_UnlockRect((IDirect3DTexture8 *)src, l);
6996 break;
6997 case D3DRTYPE_CUBETEXTURE:
6998 hr = IDirect3DCubeTexture8_UnlockRect((IDirect3DCubeTexture8 *)src, f, l);
6999 break;
7000 case D3DRTYPE_VOLUMETEXTURE:
7001 hr = IDirect3DVolumeTexture8_UnlockBox((IDirect3DVolumeTexture8 *)src, l);
7002 break;
7003 default:
7004 trace("Unexpected resource type.\n");
7006 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
7008 width >>= 1;
7009 if (!width)
7010 width = 1;
7011 height >>= 1;
7012 if (!height)
7013 height = 1;
7014 depth >>= 1;
7015 if (!depth)
7016 depth = 1;
7021 hr = IDirect3DDevice8_UpdateTexture(device, src, dst);
7022 if (FAILED(hr))
7024 todo_wine ok(SUCCEEDED(hr) || broken(tests[i].broken_updatetex),
7025 "Failed to update texture, hr %#x, case %u, %u.\n", hr, t, i);
7026 IDirect3DBaseTexture8_Release(src);
7027 IDirect3DBaseTexture8_Release(dst);
7028 continue;
7030 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x, case %u, %u.\n", hr, t, i);
7032 if (do_visual_test)
7034 hr = IDirect3DDevice8_SetTexture(device, 0, dst);
7035 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
7037 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 1.0f, 0);
7038 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
7040 hr = IDirect3DDevice8_BeginScene(device);
7041 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7042 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,
7043 texture_types[t].quad, texture_types[t].vertex_size);
7044 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7045 hr = IDirect3DDevice8_EndScene(device);
7046 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7048 color = getPixelColor(device, 320, 240);
7049 ok (color_match(color, 0x007f7f00, 3) || broken(tests[i].broken_result)
7050 || broken(color == 0x00adbeef), /* WARP device often just breaks down. */
7051 "Got unexpected color 0x%08x, case %u, %u.\n", color, t, i);
7054 IDirect3DBaseTexture8_Release(src);
7055 IDirect3DBaseTexture8_Release(dst);
7059 refcount = IDirect3DDevice8_Release(device);
7060 ok(!refcount, "Device has %u references left.\n", refcount);
7061 IDirect3D8_Release(d3d);
7062 DestroyWindow(window);
7065 static BOOL point_match(IDirect3DDevice8 *device, UINT x, UINT y, UINT r)
7067 D3DCOLOR color;
7069 color = D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff);
7070 if (!color_match(getPixelColor(device, x + r, y), color, 1))
7071 return FALSE;
7072 if (!color_match(getPixelColor(device, x - r, y), color, 1))
7073 return FALSE;
7074 if (!color_match(getPixelColor(device, x, y + r), color, 1))
7075 return FALSE;
7076 if (!color_match(getPixelColor(device, x, y - r), color, 1))
7077 return FALSE;
7079 ++r;
7080 color = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff);
7081 if (!color_match(getPixelColor(device, x + r, y), color, 1))
7082 return FALSE;
7083 if (!color_match(getPixelColor(device, x - r, y), color, 1))
7084 return FALSE;
7085 if (!color_match(getPixelColor(device, x, y + r), color, 1))
7086 return FALSE;
7087 if (!color_match(getPixelColor(device, x, y - r), color, 1))
7088 return FALSE;
7090 return TRUE;
7093 static void test_pointsize(void)
7095 static const float a = 0.5f, b = 0.5f, c = 0.5f;
7096 float ptsize, ptsizemax_orig, ptsizemin_orig;
7097 IDirect3DSurface8 *rt, *backbuffer, *depthstencil;
7098 IDirect3DTexture8 *tex1, *tex2;
7099 IDirect3DDevice8 *device;
7100 DWORD vs, ps;
7101 D3DLOCKED_RECT lr;
7102 IDirect3D8 *d3d;
7103 D3DCOLOR color;
7104 ULONG refcount;
7105 D3DCAPS8 caps;
7106 HWND window;
7107 HRESULT hr;
7108 unsigned int i, j;
7110 static const DWORD tex1_data[4] = {0x00ff0000, 0x00ff0000, 0x00000000, 0x00000000};
7111 static const DWORD tex2_data[4] = {0x00000000, 0x0000ff00, 0x00000000, 0x0000ff00};
7112 static const float vertices[] =
7114 64.0f, 64.0f, 0.1f,
7115 128.0f, 64.0f, 0.1f,
7116 192.0f, 64.0f, 0.1f,
7117 256.0f, 64.0f, 0.1f,
7118 320.0f, 64.0f, 0.1f,
7119 384.0f, 64.0f, 0.1f,
7120 448.0f, 64.0f, 0.1f,
7121 512.0f, 64.0f, 0.1f,
7123 static const struct
7125 float x, y, z;
7126 float point_size;
7128 vertex_pointsize = {64.0f, 64.0f, 0.1f, 48.0f},
7129 vertex_pointsize_scaled = {64.0f, 64.0f, 0.1f, 24.0f},
7130 vertex_pointsize_zero = {64.0f, 64.0f, 0.1f, 0.0f};
7131 static const DWORD decl[] =
7133 D3DVSD_STREAM(0),
7134 D3DVSD_REG(0, D3DVSDT_FLOAT3), /* position */
7135 D3DVSD_END()
7137 decl_psize[] =
7139 D3DVSD_STREAM(0),
7140 D3DVSD_REG(0, D3DVSDT_FLOAT3), /* position, v0 */
7141 D3DVSD_REG(1, D3DVSDT_FLOAT1), /* point size, v1 */
7142 D3DVSD_END()
7144 static const DWORD vshader_code[] =
7146 0xfffe0101, /* vs_1_1 */
7147 0x00000005, 0x800f0000, 0x90000000, 0xa0e40000, /* mul r0, v0.x, c0 */
7148 0x00000004, 0x800f0000, 0x90550000, 0xa0e40001, 0x80e40000, /* mad r0, v0.y, c1, r0 */
7149 0x00000004, 0x800f0000, 0x90aa0000, 0xa0e40002, 0x80e40000, /* mad r0, v0.z, c2, r0 */
7150 0x00000004, 0xc00f0000, 0x90ff0000, 0xa0e40003, 0x80e40000, /* mad oPos, v0.w, c3, r0 */
7151 0x0000ffff
7153 static const DWORD vshader_psize_code[] =
7155 0xfffe0101, /* vs_1_1 */
7156 0x00000005, 0x800f0000, 0x90000000, 0xa0e40000, /* mul r0, v0.x, c0 */
7157 0x00000004, 0x800f0000, 0x90550000, 0xa0e40001, 0x80e40000, /* mad r0, v0.y, c1, r0 */
7158 0x00000004, 0x800f0000, 0x90aa0000, 0xa0e40002, 0x80e40000, /* mad r0, v0.z, c2, r0 */
7159 0x00000004, 0xc00f0000, 0x90ff0000, 0xa0e40003, 0x80e40000, /* mad oPos, v0.w, c3, r0 */
7160 0x00000001, 0xc00f0002, 0x90000001, /* mov oPts, v1.x */
7161 0x0000ffff
7163 static const DWORD pshader_code[] =
7165 0xffff0101, /* ps_1_1 */
7166 0x00000042, 0xb00f0000, /* tex t0 */
7167 0x00000042, 0xb00f0001, /* tex t1 */
7168 0x00000002, 0x800f0000, 0xb0e40000, 0xb0e40001, /* add r0, t0, t1 */
7169 0x0000ffff
7171 static const struct test_shader
7173 DWORD version;
7174 const DWORD *code;
7176 novs = {0, NULL},
7177 vs1 = {D3DVS_VERSION(1, 1), vshader_code},
7178 vs1_psize = {D3DVS_VERSION(1, 1), vshader_psize_code},
7179 nops = {0, NULL},
7180 ps1 = {D3DPS_VERSION(1, 1), pshader_code};
7181 static const struct
7183 const DWORD *decl;
7184 const struct test_shader *vs;
7185 const struct test_shader *ps;
7186 DWORD accepted_fvf;
7187 unsigned int nonscaled_size, scaled_size;
7189 test_setups[] =
7191 {NULL, &novs, &nops, D3DFVF_XYZ, 32, 62},
7192 {decl, &vs1, &ps1, D3DFVF_XYZ, 32, 32},
7193 {NULL, &novs, &ps1, D3DFVF_XYZ, 32, 62},
7194 {decl, &vs1, &nops, D3DFVF_XYZ, 32, 32},
7195 {NULL, &novs, &nops, D3DFVF_XYZ | D3DFVF_PSIZE, 48, 48},
7196 {decl_psize, &vs1_psize, &ps1, D3DFVF_XYZ | D3DFVF_PSIZE, 48, 24},
7198 static const struct
7200 BOOL zero_size;
7201 BOOL scale;
7202 BOOL override_min;
7203 DWORD fvf;
7204 const void *vertex_data;
7205 unsigned int vertex_size;
7207 tests[] =
7209 {FALSE, FALSE, FALSE, D3DFVF_XYZ, vertices, sizeof(float) * 3},
7210 {FALSE, TRUE, FALSE, D3DFVF_XYZ, vertices, sizeof(float) * 3},
7211 {FALSE, FALSE, TRUE, D3DFVF_XYZ, vertices, sizeof(float) * 3},
7212 {TRUE, FALSE, FALSE, D3DFVF_XYZ, vertices, sizeof(float) * 3},
7213 {FALSE, FALSE, FALSE, D3DFVF_XYZ | D3DFVF_PSIZE, &vertex_pointsize, sizeof(vertex_pointsize)},
7214 {FALSE, TRUE, FALSE, D3DFVF_XYZ | D3DFVF_PSIZE, &vertex_pointsize_scaled, sizeof(vertex_pointsize_scaled)},
7215 {FALSE, FALSE, TRUE, D3DFVF_XYZ | D3DFVF_PSIZE, &vertex_pointsize, sizeof(vertex_pointsize)},
7216 {TRUE, FALSE, FALSE, D3DFVF_XYZ | D3DFVF_PSIZE, &vertex_pointsize_zero, sizeof(vertex_pointsize_zero)},
7218 /* Transforms the coordinate system [-1.0;1.0]x[1.0;-1.0] to
7219 * [0.0;0.0]x[640.0;480.0]. Z is untouched. */
7220 D3DMATRIX matrix =
7222 2.0f / 640.0f, 0.0f, 0.0f, 0.0f,
7223 0.0f, -2.0f / 480.0f, 0.0f, 0.0f,
7224 0.0f, 0.0f, 1.0f, 0.0f,
7225 -1.0f, 1.0f, 0.0f, 1.0f,
7226 }}};
7228 window = create_window();
7229 d3d = Direct3DCreate8(D3D_SDK_VERSION);
7230 ok(!!d3d, "Failed to create a D3D object.\n");
7231 if (!(device = create_device(d3d, window, window, TRUE)))
7233 skip("Failed to create a D3D device, skipping tests.\n");
7234 goto done;
7237 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
7238 ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
7239 if (caps.MaxPointSize < 32.0f)
7241 skip("MaxPointSize %f < 32.0, skipping.\n", caps.MaxPointSize);
7242 IDirect3DDevice8_Release(device);
7243 goto done;
7246 /* The r500 Windows driver needs a draw with regular texture coordinates at least once during the
7247 * device's lifetime, otherwise texture coordinate generation only works for texture 0. */
7248 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX1);
7249 ok(SUCCEEDED(hr), "Failed to set FVF, hr=%#x.\n", hr);
7250 hr = IDirect3DDevice8_BeginScene(device);
7251 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7252 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, vertices, sizeof(float) * 5);
7253 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7254 hr = IDirect3DDevice8_EndScene(device);
7255 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7257 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
7258 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
7259 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
7260 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
7261 hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, &matrix);
7262 ok(SUCCEEDED(hr), "Failed to set projection matrix, hr %#x.\n", hr);
7263 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ);
7264 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
7266 hr = IDirect3DDevice8_BeginScene(device);
7267 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7269 ptsize = 15.0f;
7270 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
7271 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
7272 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
7273 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7275 ptsize = 31.0f;
7276 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
7277 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
7278 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[3], sizeof(float) * 3);
7279 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7281 ptsize = 30.75f;
7282 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
7283 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
7284 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[6], sizeof(float) * 3);
7285 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7287 if (caps.MaxPointSize >= 63.0f)
7289 ptsize = 63.0f;
7290 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
7291 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
7292 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[9], sizeof(float) * 3);
7293 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7295 ptsize = 62.75f;
7296 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
7297 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
7298 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[15], sizeof(float) * 3);
7299 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7302 ptsize = 1.0f;
7303 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
7304 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
7305 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[12], sizeof(float) * 3);
7306 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7308 hr = IDirect3DDevice8_GetRenderState(device, D3DRS_POINTSIZE_MAX, (DWORD *)&ptsizemax_orig);
7309 ok(SUCCEEDED(hr), "Failed to get render state, hr %#x.\n", hr);
7310 hr = IDirect3DDevice8_GetRenderState(device, D3DRS_POINTSIZE_MIN, (DWORD *)&ptsizemin_orig);
7311 ok(SUCCEEDED(hr), "Failed to get render state, hr %#x.\n", hr);
7313 /* What happens if point scaling is disabled, and POINTSIZE_MAX < POINTSIZE? */
7314 ptsize = 15.0f;
7315 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
7316 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
7317 ptsize = 1.0f;
7318 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE_MAX, *(DWORD *)&ptsize);
7319 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
7320 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[18], sizeof(float) * 3);
7321 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7323 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE_MAX, *(DWORD *)&ptsizemax_orig);
7324 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
7326 /* pointsize < pointsize_min < pointsize_max?
7327 * pointsize = 1.0, pointsize_min = 15.0, pointsize_max = default(usually 64.0) */
7328 ptsize = 1.0f;
7329 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
7330 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
7331 ptsize = 15.0f;
7332 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE_MIN, *(DWORD *)&ptsize);
7333 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
7334 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[21], sizeof(float) * 3);
7335 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7337 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE_MIN, *(DWORD *)&ptsizemin_orig);
7338 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
7340 hr = IDirect3DDevice8_EndScene(device);
7341 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7343 ok(point_match(device, 64, 64, 7), "point_match(64, 64, 7) failed, expected point size 15.\n");
7344 ok(point_match(device, 128, 64, 15), "point_match(128, 64, 15) failed, expected point size 31.\n");
7345 ok(point_match(device, 192, 64, 15), "point_match(192, 64, 15) failed, expected point size 31.\n");
7347 if (caps.MaxPointSize >= 63.0f)
7349 ok(point_match(device, 256, 64, 31), "point_match(256, 64, 31) failed, expected point size 63.\n");
7350 ok(point_match(device, 384, 64, 31), "point_match(384, 64, 31) failed, expected point size 63.\n");
7353 ok(point_match(device, 320, 64, 0), "point_match(320, 64, 0) failed, expected point size 1.\n");
7354 /* ptsize = 15, ptsize_max = 1 --> point has size 1 */
7355 ok(point_match(device, 448, 64, 0), "point_match(448, 64, 0) failed, expected point size 1.\n");
7356 /* ptsize = 1, ptsize_max = default(64), ptsize_min = 15 --> point has size 15 */
7357 ok(point_match(device, 512, 64, 7), "point_match(512, 64, 7) failed, expected point size 15.\n");
7359 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
7361 /* The following code tests point sprites with two textures, to see if each texture coordinate unit
7362 * generates texture coordinates for the point(result: Yes, it does)
7364 * However, not all GL implementations support point sprites(they need GL_ARB_point_sprite), but there
7365 * is no point sprite cap bit in d3d because native d3d software emulates point sprites. Until the
7366 * SW emulation is implemented in wined3d, this test will fail on GL drivers that does not support them.
7368 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
7369 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
7371 hr = IDirect3DDevice8_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex1);
7372 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
7373 hr = IDirect3DDevice8_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex2);
7374 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
7375 memset(&lr, 0, sizeof(lr));
7376 hr = IDirect3DTexture8_LockRect(tex1, 0, &lr, NULL, 0);
7377 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
7378 memcpy(lr.pBits, tex1_data, sizeof(tex1_data));
7379 hr = IDirect3DTexture8_UnlockRect(tex1, 0);
7380 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
7381 memset(&lr, 0, sizeof(lr));
7382 hr = IDirect3DTexture8_LockRect(tex2, 0, &lr, NULL, 0);
7383 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
7384 memcpy(lr.pBits, tex2_data, sizeof(tex2_data));
7385 hr = IDirect3DTexture8_UnlockRect(tex2, 0);
7386 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
7387 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)tex1);
7388 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
7389 hr = IDirect3DDevice8_SetTexture(device, 1, (IDirect3DBaseTexture8 *)tex2);
7390 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
7391 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7392 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
7393 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7394 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
7395 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
7396 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
7397 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7398 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
7399 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
7400 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
7402 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSPRITEENABLE, TRUE);
7403 ok(SUCCEEDED(hr), "Failed to enable point sprites, hr %#x.\n", hr);
7404 ptsize = 32.0f;
7405 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
7406 ok(SUCCEEDED(hr), "Failed to set point size, hr %#x.\n", hr);
7408 hr = IDirect3DDevice8_BeginScene(device);
7409 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7410 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
7411 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7412 hr = IDirect3DDevice8_EndScene(device);
7413 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7415 color = getPixelColor(device, 64 - 4, 64 - 4);
7416 ok(color == 0x00ff0000, "pSprite: Pixel (64 - 4),(64 - 4) has color 0x%08x, expected 0x00ff0000\n", color);
7417 color = getPixelColor(device, 64 - 4, 64 + 4);
7418 ok(color == 0x00000000, "pSprite: Pixel (64 - 4),(64 + 4) has color 0x%08x, expected 0x00000000\n", color);
7419 color = getPixelColor(device, 64 + 4, 64 + 4);
7420 ok(color == 0x0000ff00, "pSprite: Pixel (64 + 4),(64 + 4) has color 0x%08x, expected 0x0000ff00\n", color);
7421 color = getPixelColor(device, 64 + 4, 64 - 4);
7422 ok(color == 0x00ffff00, "pSprite: Pixel (64 + 4),(64 - 4) has color 0x%08x, expected 0x00ffff00\n", color);
7423 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
7425 U(matrix).m[0][0] = 1.0f / 64.0f;
7426 U(matrix).m[1][1] = -1.0f / 64.0f;
7427 hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, &matrix);
7428 ok(SUCCEEDED(hr), "Failed to set projection matrix, hr %#x.\n", hr);
7430 hr = IDirect3DDevice8_GetRenderTarget(device, &backbuffer);
7431 ok(SUCCEEDED(hr), "Failed to get backbuffer, hr %#x.\n", hr);
7432 hr = IDirect3DDevice8_GetDepthStencilSurface(device, &depthstencil);
7433 ok(SUCCEEDED(hr), "Failed to get depth / stencil buffer, hr %#x.\n", hr);
7435 hr = IDirect3DDevice8_CreateRenderTarget(device, 128, 128, D3DFMT_A8R8G8B8,
7436 D3DMULTISAMPLE_NONE, TRUE, &rt);
7437 ok(SUCCEEDED(hr), "Failed to create a render target, hr %#x.\n", hr);
7439 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSCALE_A, *(DWORD *)&a);
7440 ok(SUCCEEDED(hr), "Failed setting point scale attenuation coefficient, hr %#x.\n", hr);
7441 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSCALE_B, *(DWORD *)&b);
7442 ok(SUCCEEDED(hr), "Failed setting point scale attenuation coefficient, hr %#x.\n", hr);
7443 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSCALE_C, *(DWORD *)&c);
7444 ok(SUCCEEDED(hr), "Failed setting point scale attenuation coefficient, hr %#x.\n", hr);
7445 hr = IDirect3DDevice8_SetVertexShaderConstant(device, 0, &S(U(matrix))._11, 4);
7446 ok(SUCCEEDED(hr), "Failed to set vertex shader constants, hr %#x.\n", hr);
7448 if (caps.MaxPointSize < 63.0f)
7450 skip("MaxPointSize %f < 63.0, skipping some tests.\n", caps.MaxPointSize);
7451 goto cleanup;
7454 hr = IDirect3DDevice8_SetRenderTarget(device, rt, depthstencil);
7455 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
7457 for (i = 0; i < ARRAY_SIZE(test_setups); ++i)
7459 if (caps.VertexShaderVersion < test_setups[i].vs->version
7460 || caps.PixelShaderVersion < test_setups[i].ps->version)
7462 skip("Vertex / pixel shader version not supported, skipping test.\n");
7463 continue;
7465 if (test_setups[i].vs->code)
7467 hr = IDirect3DDevice8_CreateVertexShader(device, test_setups[i].decl, test_setups[i].vs->code, &vs, 0);
7468 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x (case %u).\n", hr, i);
7470 else
7472 vs = 0;
7474 if (test_setups[i].ps->code)
7476 hr = IDirect3DDevice8_CreatePixelShader(device, test_setups[i].ps->code, &ps);
7477 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x (case %u).\n", hr, i);
7479 else
7481 ps = 0;
7484 hr = IDirect3DDevice8_SetVertexShader(device, vs ? vs : test_setups[i].accepted_fvf);
7485 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
7486 hr = IDirect3DDevice8_SetPixelShader(device, ps);
7487 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
7489 for (j = 0; j < ARRAY_SIZE(tests); ++j)
7491 unsigned int size = tests[j].override_min ? 63 : tests[j].zero_size ? 0 : tests[j].scale
7492 ? test_setups[i].scaled_size : test_setups[i].nonscaled_size;
7494 if (test_setups[i].accepted_fvf != tests[j].fvf)
7495 continue;
7497 ptsize = tests[j].zero_size ? 0.0f : 32.0f;
7498 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
7499 ok(SUCCEEDED(hr), "Failed to set pointsize, hr %#x.\n", hr);
7501 ptsize = tests[j].override_min ? 63.0f : tests[j].zero_size ? 0.0f : ptsizemin_orig;
7502 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE_MIN, *(DWORD *)&ptsize);
7503 ok(SUCCEEDED(hr), "Failed to set minimum pointsize, hr %#x.\n", hr);
7505 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSCALEENABLE, tests[j].scale);
7506 ok(SUCCEEDED(hr), "Failed setting point scale state, hr %#x.\n", hr);
7508 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
7509 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
7511 hr = IDirect3DDevice8_BeginScene(device);
7512 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7513 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1,
7514 tests[j].vertex_data, tests[j].vertex_size);
7515 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7516 hr = IDirect3DDevice8_EndScene(device);
7517 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7519 if (tests[j].zero_size)
7521 /* Technically 0 pointsize is undefined in OpenGL but in practice it seems like
7522 * it does the "useful" thing on all the drivers I tried. */
7523 /* On WARP it does draw some pixels, most of the time. */
7524 color = getPixelColor(device, 64, 64);
7525 ok(color_match(color, 0x0000ffff, 0)
7526 || broken(color_match(color, 0x00ff0000, 0))
7527 || broken(color_match(color, 0x00ffff00, 0))
7528 || broken(color_match(color, 0x00000000, 0))
7529 || broken(color_match(color, 0x0000ff00, 0)),
7530 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
7532 else
7534 struct surface_readback rb;
7536 get_rt_readback(rt, &rb);
7537 color = get_readback_color(&rb, 64 - size / 2 + 1, 64 - size / 2 + 1);
7538 ok(color_match(color, 0x00ff0000, 0),
7539 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
7540 color = get_readback_color(&rb, 64 + size / 2 - 1, 64 - size / 2 + 1);
7541 ok(color_match(color, 0x00ffff00, 0),
7542 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
7543 color = get_readback_color(&rb, 64 - size / 2 + 1, 64 + size / 2 - 1);
7544 ok(color_match(color, 0x00000000, 0),
7545 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
7546 color = get_readback_color(&rb, 64 + size / 2 - 1, 64 + size / 2 - 1);
7547 ok(color_match(color, 0x0000ff00, 0),
7548 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
7550 color = get_readback_color(&rb, 64 - size / 2 - 1, 64 - size / 2 - 1);
7551 ok(color_match(color, 0xff00ffff, 0),
7552 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
7553 color = get_readback_color(&rb, 64 + size / 2 + 1, 64 - size / 2 - 1);
7554 ok(color_match(color, 0xff00ffff, 0),
7555 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
7556 color = get_readback_color(&rb, 64 - size / 2 - 1, 64 + size / 2 + 1);
7557 ok(color_match(color, 0xff00ffff, 0),
7558 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
7559 color = get_readback_color(&rb, 64 + size / 2 + 1, 64 + size / 2 + 1);
7560 ok(color_match(color, 0xff00ffff, 0),
7561 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
7563 release_surface_readback(&rb);
7566 IDirect3DDevice8_SetVertexShader(device, 0);
7567 IDirect3DDevice8_SetPixelShader(device, 0);
7568 if (vs)
7569 IDirect3DDevice8_DeleteVertexShader(device, vs);
7570 if (ps)
7571 IDirect3DDevice8_DeletePixelShader(device, ps);
7573 hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, depthstencil);
7574 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
7576 cleanup:
7577 IDirect3DSurface8_Release(backbuffer);
7578 IDirect3DSurface8_Release(depthstencil);
7579 IDirect3DSurface8_Release(rt);
7581 IDirect3DTexture8_Release(tex1);
7582 IDirect3DTexture8_Release(tex2);
7583 refcount = IDirect3DDevice8_Release(device);
7584 ok(!refcount, "Device has %u references left.\n", refcount);
7585 done:
7586 IDirect3D8_Release(d3d);
7587 DestroyWindow(window);
7590 static void test_multisample_mismatch(void)
7592 IDirect3DDevice8 *device;
7593 IDirect3D8 *d3d;
7594 HWND window;
7595 HRESULT hr;
7596 ULONG refcount;
7597 IDirect3DSurface8 *rt_multi, *ds;
7599 window = create_window();
7600 d3d = Direct3DCreate8(D3D_SDK_VERSION);
7601 ok(!!d3d, "Failed to create a D3D object.\n");
7602 if (FAILED(IDirect3D8_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
7603 D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES)))
7605 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping multisample mismatch test.\n");
7606 IDirect3D8_Release(d3d);
7607 return;
7610 if (!(device = create_device(d3d, window, window, TRUE)))
7612 skip("Failed to create a D3D device, skipping tests.\n");
7613 goto done;
7616 hr = IDirect3DDevice8_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
7617 D3DMULTISAMPLE_2_SAMPLES, FALSE, &rt_multi);
7618 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
7619 hr = IDirect3DDevice8_GetDepthStencilSurface(device, &ds);
7620 ok(SUCCEEDED(hr), "Failed to get original depth/stencil, hr %#x.\n", hr);
7622 hr = IDirect3DDevice8_SetRenderTarget(device, rt_multi, ds);
7623 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
7625 IDirect3DSurface8_Release(ds);
7626 IDirect3DSurface8_Release(rt_multi);
7628 refcount = IDirect3DDevice8_Release(device);
7629 ok(!refcount, "Device has %u references left.\n", refcount);
7630 done:
7631 IDirect3D8_Release(d3d);
7632 DestroyWindow(window);
7635 static void test_texcoordindex(void)
7637 static const D3DMATRIX mat =
7639 1.0f, 0.0f, 0.0f, 0.0f,
7640 0.0f, 0.0f, 0.0f, 0.0f,
7641 0.0f, 0.0f, 0.0f, 0.0f,
7642 0.0f, 0.0f, 0.0f, 0.0f,
7643 }}};
7644 static const struct
7646 struct vec3 pos;
7647 struct vec2 texcoord1;
7648 struct vec2 texcoord2;
7649 struct vec2 texcoord3;
7651 quad[] =
7653 {{-1.0f, -1.0f, 0.0f}, {0.0f, 1.0f}, {0.0f, 0.0f}, {1.0f, 1.0f}},
7654 {{-1.0f, 1.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 1.0f}, {1.0f, 0.0f}},
7655 {{ 1.0f, -1.0f, 0.0f}, {1.0f, 1.0f}, {1.0f, 0.0f}, {0.0f, 1.0f}},
7656 {{ 1.0f, 1.0f, 0.0f}, {1.0f, 0.0f}, {1.0f, 1.0f}, {0.0f, 0.0f}},
7658 IDirect3DDevice8 *device;
7659 IDirect3D8 *d3d;
7660 HWND window;
7661 HRESULT hr;
7662 IDirect3DTexture8 *texture1, *texture2;
7663 D3DLOCKED_RECT locked_rect;
7664 ULONG refcount;
7665 D3DCOLOR color;
7666 DWORD *ptr;
7668 window = create_window();
7669 d3d = Direct3DCreate8(D3D_SDK_VERSION);
7670 ok(!!d3d, "Failed to create a D3D object.\n");
7671 if (!(device = create_device(d3d, window, window, TRUE)))
7673 skip("Failed to create a D3D device, skipping tests.\n");
7674 IDirect3D8_Release(d3d);
7675 DestroyWindow(window);
7676 return;
7679 hr = IDirect3DDevice8_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture1);
7680 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
7681 hr = IDirect3DDevice8_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture2);
7682 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
7684 hr = IDirect3DTexture8_LockRect(texture1, 0, &locked_rect, NULL, D3DLOCK_DISCARD);
7685 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
7686 ptr = locked_rect.pBits;
7687 ptr[0] = 0xff000000;
7688 ptr[1] = 0xff00ff00;
7689 ptr[2] = 0xff0000ff;
7690 ptr[3] = 0xff00ffff;
7691 hr = IDirect3DTexture8_UnlockRect(texture1, 0);
7692 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
7694 hr = IDirect3DTexture8_LockRect(texture2, 0, &locked_rect, NULL, D3DLOCK_DISCARD);
7695 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
7696 ptr = locked_rect.pBits;
7697 ptr[0] = 0xff000000;
7698 ptr[1] = 0xff0000ff;
7699 ptr[2] = 0xffff0000;
7700 ptr[3] = 0xffff00ff;
7701 hr = IDirect3DTexture8_UnlockRect(texture2, 0);
7702 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
7704 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture1);
7705 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
7706 hr = IDirect3DDevice8_SetTexture(device, 1, (IDirect3DBaseTexture8 *)texture2);
7707 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
7708 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX3);
7709 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
7710 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
7711 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
7712 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7713 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
7714 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7715 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
7716 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
7717 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
7718 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7719 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
7720 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
7721 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
7722 hr = IDirect3DDevice8_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
7723 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
7725 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_TEXCOORDINDEX, 1);
7726 ok(SUCCEEDED(hr), "Failed to set texcoord index, hr %#x.\n", hr);
7727 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_TEXCOORDINDEX, 0);
7728 ok(SUCCEEDED(hr), "Failed to set texcoord index, hr %#x.\n", hr);
7730 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 1.0f, 0);
7731 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
7733 hr = IDirect3DDevice8_BeginScene(device);
7734 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7735 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
7736 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7737 hr = IDirect3DDevice8_EndScene(device);
7738 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7740 color = getPixelColor(device, 160, 120);
7741 ok(color_match(color, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color);
7742 color = getPixelColor(device, 480, 120);
7743 ok(color_match(color, 0x0000ffff, 2), "Got unexpected color 0x%08x.\n", color);
7744 color = getPixelColor(device, 160, 360);
7745 ok(color_match(color, 0x00ff0000, 2), "Got unexpected color 0x%08x.\n", color);
7746 color = getPixelColor(device, 480, 360);
7747 ok(color_match(color, 0x00ffffff, 2), "Got unexpected color 0x%08x.\n", color);
7749 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
7750 ok(SUCCEEDED(hr), "Failed to set texture transform flags, hr %#x.\n", hr);
7751 hr = IDirect3DDevice8_SetTransform(device, D3DTS_TEXTURE1, &mat);
7752 ok(SUCCEEDED(hr), "Failed to set transformation matrix, hr %#x.\n", hr);
7754 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 1.0f, 0);
7755 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
7757 hr = IDirect3DDevice8_BeginScene(device);
7758 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7759 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
7760 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7761 hr = IDirect3DDevice8_EndScene(device);
7762 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7764 color = getPixelColor(device, 160, 120);
7765 ok(color_match(color, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color);
7766 color = getPixelColor(device, 480, 120);
7767 ok(color_match(color, 0x0000ffff, 2), "Got unexpected color 0x%08x.\n", color);
7768 color = getPixelColor(device, 160, 360);
7769 ok(color_match(color, 0x00000000, 2), "Got unexpected color 0x%08x.\n", color);
7770 color = getPixelColor(device, 480, 360);
7771 ok(color_match(color, 0x0000ffff, 2), "Got unexpected color 0x%08x.\n", color);
7773 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
7774 ok(SUCCEEDED(hr), "Failed to set texture transform flags, hr %#x.\n", hr);
7775 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_TEXCOORDINDEX, 2);
7776 ok(SUCCEEDED(hr), "Failed to set texcoord index, hr %#x.\n", hr);
7778 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 1.0f, 0);
7779 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
7781 hr = IDirect3DDevice8_BeginScene(device);
7782 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7783 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
7784 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7785 hr = IDirect3DDevice8_EndScene(device);
7786 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7788 color = getPixelColor(device, 160, 120);
7789 ok(color_match(color, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color);
7790 color = getPixelColor(device, 480, 120);
7791 ok(color_match(color, 0x0000ffff, 2), "Got unexpected color 0x%08x.\n", color);
7792 color = getPixelColor(device, 160, 360);
7793 ok(color_match(color, 0x00ff00ff, 2), "Got unexpected color 0x%08x.\n", color);
7794 color = getPixelColor(device, 480, 360);
7795 ok(color_match(color, 0x00ffff00, 2), "Got unexpected color 0x%08x.\n", color);
7797 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
7798 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
7800 IDirect3DTexture8_Release(texture1);
7801 IDirect3DTexture8_Release(texture2);
7803 refcount = IDirect3DDevice8_Release(device);
7804 ok(!refcount, "Device has %u references left.\n", refcount);
7805 IDirect3D8_Release(d3d);
7806 DestroyWindow(window);
7809 static void test_vshader_input(void)
7811 DWORD swapped_twotexcrd_shader, swapped_onetexcrd_shader = 0;
7812 DWORD swapped_twotex_wrongidx_shader = 0, swapped_twotexcrd_rightorder_shader;
7813 DWORD texcoord_color_shader, color_ubyte_shader, color_color_shader, color_float_shader;
7814 DWORD color_nocolor_shader = 0;
7815 IDirect3DDevice8 *device;
7816 IDirect3D8 *d3d;
7817 ULONG refcount;
7818 D3DCAPS8 caps;
7819 DWORD color;
7820 HWND window;
7821 HRESULT hr;
7823 static const DWORD swapped_shader_code[] =
7825 0xfffe0101, /* vs_1_1 */
7826 0x00000001, 0xc00f0000, 0x90e40000, /* mov o0, v0 */
7827 0x00000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
7828 0x00000002, 0xd00f0000, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
7829 0x0000ffff /* end */
7831 static const DWORD texcoord_color_shader_code[] =
7833 0xfffe0101, /* vs_1_1 */
7834 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
7835 0x00000001, 0xd00f0000, 0x90e40007, /* mov oD0, v7 */
7836 0x0000ffff /* end */
7838 static const DWORD color_color_shader_code[] =
7840 0xfffe0101, /* vs_1_1 */
7841 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
7842 0x00000005, 0xd00f0000, 0xa0e40000, 0x90e40005, /* mul oD0, c0, v5 */
7843 0x0000ffff /* end */
7845 static const float quad1[] =
7847 -1.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7848 -1.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7849 0.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7850 0.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7852 static const float quad4[] =
7854 0.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7855 0.0f, 1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7856 1.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7857 1.0f, 1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7859 static const struct
7861 struct vec3 position;
7862 DWORD diffuse;
7864 quad1_color[] =
7866 {{-1.0f, -1.0f, 0.1f}, 0x00ff8040},
7867 {{-1.0f, 0.0f, 0.1f}, 0x00ff8040},
7868 {{ 0.0f, -1.0f, 0.1f}, 0x00ff8040},
7869 {{ 0.0f, 0.0f, 0.1f}, 0x00ff8040},
7871 quad2_color[] =
7873 {{ 0.0f, -1.0f, 0.1f}, 0x00ff8040},
7874 {{ 0.0f, 0.0f, 0.1f}, 0x00ff8040},
7875 {{ 1.0f, -1.0f, 0.1f}, 0x00ff8040},
7876 {{ 1.0f, 0.0f, 0.1f}, 0x00ff8040},
7878 static const struct
7880 struct vec3 position;
7881 struct vec3 dummy; /* testing D3DVSD_SKIP */
7882 DWORD diffuse;
7884 quad3_color[] =
7886 {{-1.0f, 0.0f, 0.1f}, {0.0f}, 0x00ff8040},
7887 {{-1.0f, 1.0f, 0.1f}, {0.0f}, 0x00ff8040},
7888 {{ 0.0f, 0.0f, 0.1f}, {0.0f}, 0x00ff8040},
7889 {{ 0.0f, 1.0f, 0.1f}, {0.0f}, 0x00ff8040},
7891 static const float quad4_color[] =
7893 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 0.0f, 0.0f,
7894 0.0f, 1.0f, 0.1f, 1.0f, 1.0f, 0.0f, 0.0f,
7895 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 0.0f, 1.0f,
7896 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 0.0f, 1.0f,
7898 static const DWORD decl_twotexcrd[] =
7900 D3DVSD_STREAM(0),
7901 D3DVSD_REG(0, D3DVSDT_FLOAT3), /* position */
7902 D3DVSD_REG(1, D3DVSDT_FLOAT4), /* texcoord0 */
7903 D3DVSD_REG(2, D3DVSDT_FLOAT4), /* texcoord1 */
7904 D3DVSD_END()
7906 static const DWORD decl_twotexcrd_rightorder[] =
7908 D3DVSD_STREAM(0),
7909 D3DVSD_REG(0, D3DVSDT_FLOAT3), /* position */
7910 D3DVSD_REG(2, D3DVSDT_FLOAT4), /* texcoord0 */
7911 D3DVSD_REG(1, D3DVSDT_FLOAT4), /* texcoord1 */
7912 D3DVSD_END()
7914 static const DWORD decl_onetexcrd[] =
7916 D3DVSD_STREAM(0),
7917 D3DVSD_REG(0, D3DVSDT_FLOAT3), /* position */
7918 D3DVSD_REG(1, D3DVSDT_FLOAT4), /* texcoord0 */
7919 D3DVSD_END()
7921 static const DWORD decl_twotexcrd_wrongidx[] =
7923 D3DVSD_STREAM(0),
7924 D3DVSD_REG(0, D3DVSDT_FLOAT3), /* position */
7925 D3DVSD_REG(2, D3DVSDT_FLOAT4), /* texcoord1 */
7926 D3DVSD_REG(3, D3DVSDT_FLOAT4), /* texcoord2 */
7927 D3DVSD_END()
7929 static const DWORD decl_texcoord_color[] =
7931 D3DVSD_STREAM(0),
7932 D3DVSD_REG(0, D3DVSDT_FLOAT3), /* position */
7933 D3DVSD_REG(7, D3DVSDT_D3DCOLOR), /* texcoord0 */
7934 D3DVSD_END()
7936 static const DWORD decl_color_color[] =
7938 D3DVSD_STREAM(0),
7939 D3DVSD_REG(0, D3DVSDT_FLOAT3), /* position */
7940 D3DVSD_SKIP(3), /* not used */
7941 D3DVSD_REG(5, D3DVSDT_D3DCOLOR), /* diffuse */
7942 D3DVSD_END()
7944 static const DWORD decl_color_ubyte[] =
7946 D3DVSD_STREAM(0),
7947 D3DVSD_REG(0, D3DVSDT_FLOAT3),
7948 D3DVSD_REG(5, D3DVSDT_UBYTE4),
7949 D3DVSD_END()
7951 static const DWORD decl_color_float[] =
7953 D3DVSD_STREAM(0),
7954 D3DVSD_REG(0, D3DVSDT_FLOAT3),
7955 D3DVSD_REG(5, D3DVSDT_FLOAT4),
7956 D3DVSD_END()
7958 static const DWORD decl_nocolor[] =
7960 D3DVSD_STREAM(0),
7961 D3DVSD_REG(0, D3DVSDT_FLOAT3),
7962 D3DVSD_END()
7964 static const float normalize[4] = {1.0f / 256.0f, 1.0f / 256.0f, 1.0f / 256.0f, 1.0f / 256.0f};
7965 static const float no_normalize[4] = {1.0f, 1.0f, 1.0f, 1.0f};
7967 window = create_window();
7968 d3d = Direct3DCreate8(D3D_SDK_VERSION);
7969 ok(!!d3d, "Failed to create a D3D object.\n");
7970 if (!(device = create_device(d3d, window, window, TRUE)))
7972 skip("Failed to create a D3D device, skipping tests.\n");
7973 goto done;
7976 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
7977 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
7978 if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1))
7980 skip("No vs_1_1 support, skipping tests.\n");
7981 IDirect3DDevice8_Release(device);
7982 goto done;
7985 hr = IDirect3DDevice8_CreateVertexShader(device, decl_twotexcrd, swapped_shader_code, &swapped_twotexcrd_shader, 0);
7986 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
7987 hr = IDirect3DDevice8_CreateVertexShader(device, decl_onetexcrd, swapped_shader_code, &swapped_onetexcrd_shader, 0);
7988 todo_wine ok(hr == D3DERR_INVALIDCALL, "Unexpected error while creating vertex shader, hr %#x.\n", hr);
7989 hr = IDirect3DDevice8_CreateVertexShader(device, decl_twotexcrd_wrongidx, swapped_shader_code, &swapped_twotex_wrongidx_shader, 0);
7990 todo_wine ok(hr == D3DERR_INVALIDCALL, "Unexpected error while creating vertex shader, hr %#x.\n", hr);
7991 hr = IDirect3DDevice8_CreateVertexShader(device, decl_twotexcrd_rightorder, swapped_shader_code, &swapped_twotexcrd_rightorder_shader, 0);
7992 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
7994 hr = IDirect3DDevice8_CreateVertexShader(device, decl_texcoord_color, texcoord_color_shader_code, &texcoord_color_shader, 0);
7995 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
7996 hr = IDirect3DDevice8_CreateVertexShader(device, decl_color_ubyte, color_color_shader_code, &color_ubyte_shader, 0);
7997 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
7998 hr = IDirect3DDevice8_CreateVertexShader(device, decl_color_color, color_color_shader_code, &color_color_shader, 0);
7999 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
8000 hr = IDirect3DDevice8_CreateVertexShader(device, decl_color_float, color_color_shader_code, &color_float_shader, 0);
8001 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
8002 hr = IDirect3DDevice8_CreateVertexShader(device, decl_nocolor, color_color_shader_code, &color_nocolor_shader, 0);
8003 todo_wine ok(hr == D3DERR_INVALIDCALL, "Unexpected error while creating vertex shader, hr %#x.\n", hr);
8005 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 1.0f, 0);
8006 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
8008 hr = IDirect3DDevice8_BeginScene(device);
8009 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
8011 hr = IDirect3DDevice8_SetVertexShader(device, swapped_twotexcrd_shader);
8012 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
8014 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 11);
8015 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8017 hr = IDirect3DDevice8_SetVertexShader(device, swapped_twotexcrd_rightorder_shader);
8018 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
8019 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 11);
8020 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8022 hr = IDirect3DDevice8_EndScene(device);
8023 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
8025 color = getPixelColor(device, 160, 360);
8026 ok(color_match(color, 0x00ffff80, 1), "Got unexpected color 0x%08x for quad 1 (2crd).\n", color);
8027 color = getPixelColor(device, 480, 160);
8028 ok(color == 0x00000000, "Got unexpected color 0x%08x for quad 4 (2crd-rightorder).\n", color);
8030 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
8031 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
8033 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
8034 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
8036 hr = IDirect3DDevice8_BeginScene(device);
8037 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
8039 hr = IDirect3DDevice8_SetVertexShader(device, texcoord_color_shader);
8040 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
8041 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1_color, sizeof(quad1_color[0]));
8042 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8044 hr = IDirect3DDevice8_SetVertexShader(device, color_ubyte_shader);
8045 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
8047 hr = IDirect3DDevice8_SetVertexShaderConstant(device, 0, normalize, 1);
8048 ok(SUCCEEDED(hr), "Failed to set vertex shader constant, hr %#x.\n", hr);
8049 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_color, sizeof(quad2_color[0]));
8050 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8052 hr = IDirect3DDevice8_SetVertexShaderConstant(device, 0, no_normalize, 1);
8053 ok(SUCCEEDED(hr), "Failed to set vertex shader constant, hr %#x.\n", hr);
8054 hr = IDirect3DDevice8_SetVertexShader(device, color_color_shader);
8055 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
8056 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3_color, sizeof(quad3_color[0]));
8057 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8059 hr = IDirect3DDevice8_SetVertexShader(device, color_float_shader);
8060 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
8061 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4_color, sizeof(float) * 7);
8062 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8064 hr = IDirect3DDevice8_EndScene(device);
8065 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
8067 IDirect3DDevice8_SetVertexShader(device, 0);
8069 color = getPixelColor(device, 160, 360);
8070 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
8071 "Input test: Quad 1(color-texcoord) returned color 0x%08x, expected 0x00ff8040\n", color);
8072 color = getPixelColor(device, 480, 360);
8073 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x40, 0x80, 0xff), 1),
8074 "Input test: Quad 2(color-ubyte) returned color 0x%08x, expected 0x004080ff\n", color);
8075 color = getPixelColor(device, 160, 120);
8076 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
8077 "Input test: Quad 3(color-color) returned color 0x%08x, expected 0x00ff8040\n", color);
8078 color = getPixelColor(device, 480, 160);
8079 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 1),
8080 "Input test: Quad 4(color-float) returned color 0x%08x, expected 0x00ffff00\n", color);
8082 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
8083 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
8085 IDirect3DDevice8_DeleteVertexShader(device, swapped_twotexcrd_shader);
8086 IDirect3DDevice8_DeleteVertexShader(device, swapped_onetexcrd_shader);
8087 IDirect3DDevice8_DeleteVertexShader(device, swapped_twotex_wrongidx_shader);
8088 IDirect3DDevice8_DeleteVertexShader(device, swapped_twotexcrd_rightorder_shader);
8089 IDirect3DDevice8_DeleteVertexShader(device, texcoord_color_shader);
8090 IDirect3DDevice8_DeleteVertexShader(device, color_ubyte_shader);
8091 IDirect3DDevice8_DeleteVertexShader(device, color_color_shader);
8092 IDirect3DDevice8_DeleteVertexShader(device, color_float_shader);
8093 IDirect3DDevice8_DeleteVertexShader(device, color_nocolor_shader);
8095 refcount = IDirect3DDevice8_Release(device);
8096 ok(!refcount, "Device has %u references left.\n", refcount);
8097 done:
8098 IDirect3D8_Release(d3d);
8099 DestroyWindow(window);
8102 static void test_fixed_function_fvf(void)
8104 IDirect3DDevice8 *device;
8105 DWORD color;
8106 IDirect3D8 *d3d;
8107 ULONG refcount;
8108 D3DCAPS8 caps;
8109 HWND window;
8110 HRESULT hr;
8112 static const struct
8114 struct vec3 position;
8115 DWORD diffuse;
8117 quad1[] =
8119 {{-1.0f, -1.0f, 0.1f}, 0x00ffff00},
8120 {{-1.0f, 0.0f, 0.1f}, 0x00ffff00},
8121 {{ 0.0f, -1.0f, 0.1f}, 0x00ffff00},
8122 {{ 0.0f, 0.0f, 0.1f}, 0x00ffff00},
8124 static const struct vec3 quad2[] =
8126 {-1.0f, -1.0f, 0.1f},
8127 {-1.0f, 0.0f, 0.1f},
8128 { 0.0f, -1.0f, 0.1f},
8129 { 0.0f, 0.0f, 0.1f},
8131 static const struct
8133 struct vec4 position;
8134 DWORD diffuse;
8136 quad_transformed[] =
8138 {{ 90.0f, 110.0f, 0.1f, 2.0f}, 0x00ffff00},
8139 {{570.0f, 110.0f, 0.1f, 2.0f}, 0x00ffff00},
8140 {{ 90.0f, 300.0f, 0.1f, 2.0f}, 0x00ffff00},
8141 {{570.0f, 300.0f, 0.1f, 2.0f}, 0x00ffff00},
8144 window = create_window();
8145 d3d = Direct3DCreate8(D3D_SDK_VERSION);
8146 ok(!!d3d, "Failed to create a D3D object.\n");
8147 if (!(device = create_device(d3d, window, window, TRUE)))
8149 skip("Failed to create a D3D device, skipping tests.\n");
8150 goto done;
8153 memset(&caps, 0, sizeof(caps));
8154 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
8155 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
8157 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
8158 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
8160 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
8161 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
8163 hr = IDirect3DDevice8_BeginScene(device);
8164 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
8166 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8167 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
8168 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
8169 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8171 hr = IDirect3DDevice8_EndScene(device);
8172 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
8174 color = getPixelColor(device, 160, 360);
8175 ok(color == 0x00ffff00,
8176 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
8177 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
8179 /* Test with no diffuse color attribute. */
8180 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8181 ok(SUCCEEDED(hr), "IDirect3DDevice8_Clear failed with %08x\n", hr);
8183 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ);
8184 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
8185 hr = IDirect3DDevice8_BeginScene(device);
8186 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
8187 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad2, sizeof(quad2[0]));
8188 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8189 hr = IDirect3DDevice8_EndScene(device);
8190 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
8192 color = getPixelColor(device, 160, 360);
8193 ok(color == 0x00ffffff, "Got unexpected color 0x%08x in the no diffuse attribute test.\n", color);
8194 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
8196 /* Test what happens with specular lighting enabled and no specular color attribute. */
8197 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
8198 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
8199 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SPECULARENABLE, TRUE);
8200 ok(SUCCEEDED(hr), "Failed to enable specular lighting, hr %#x.\n", hr);
8201 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8202 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
8203 hr = IDirect3DDevice8_BeginScene(device);
8204 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
8206 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad1, sizeof(quad1[0]));
8207 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8209 hr = IDirect3DDevice8_EndScene(device);
8210 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
8211 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SPECULARENABLE, FALSE);
8212 ok(SUCCEEDED(hr), "Failed to disable specular lighting, hr %#x.\n", hr);
8214 color = getPixelColor(device, 160, 360);
8215 ok(color == 0x00ffff00, "Got unexpected color 0x%08x in the no specular attribute test.\n", color);
8217 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
8219 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
8220 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
8222 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8223 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
8225 hr = IDirect3DDevice8_BeginScene(device);
8226 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
8227 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad_transformed, sizeof(quad_transformed[0]));
8228 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8229 hr = IDirect3DDevice8_EndScene(device);
8230 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
8232 color = getPixelColor(device, 88, 108);
8233 ok(color == 0x000000ff,
8234 "pixel 88/108 has color %08x, expected 0x000000ff\n", color);
8235 color = getPixelColor(device, 92, 108);
8236 ok(color == 0x000000ff,
8237 "pixel 92/108 has color %08x, expected 0x000000ff\n", color);
8238 color = getPixelColor(device, 88, 112);
8239 ok(color == 0x000000ff,
8240 "pixel 88/112 has color %08x, expected 0x000000ff\n", color);
8241 color = getPixelColor(device, 92, 112);
8242 ok(color == 0x00ffff00,
8243 "pixel 92/112 has color %08x, expected 0x00ffff00\n", color);
8245 color = getPixelColor(device, 568, 108);
8246 ok(color == 0x000000ff,
8247 "pixel 568/108 has color %08x, expected 0x000000ff\n", color);
8248 color = getPixelColor(device, 572, 108);
8249 ok(color == 0x000000ff,
8250 "pixel 572/108 has color %08x, expected 0x000000ff\n", color);
8251 color = getPixelColor(device, 568, 112);
8252 ok(color == 0x00ffff00,
8253 "pixel 568/112 has color %08x, expected 0x00ffff00\n", color);
8254 color = getPixelColor(device, 572, 112);
8255 ok(color == 0x000000ff,
8256 "pixel 572/112 has color %08x, expected 0x000000ff\n", color);
8258 color = getPixelColor(device, 88, 298);
8259 ok(color == 0x000000ff,
8260 "pixel 88/298 has color %08x, expected 0x000000ff\n", color);
8261 color = getPixelColor(device, 92, 298);
8262 ok(color == 0x00ffff00,
8263 "pixel 92/298 has color %08x, expected 0x00ffff00\n", color);
8264 color = getPixelColor(device, 88, 302);
8265 ok(color == 0x000000ff,
8266 "pixel 88/302 has color %08x, expected 0x000000ff\n", color);
8267 color = getPixelColor(device, 92, 302);
8268 ok(color == 0x000000ff,
8269 "pixel 92/302 has color %08x, expected 0x000000ff\n", color);
8271 color = getPixelColor(device, 568, 298);
8272 ok(color == 0x00ffff00,
8273 "pixel 568/298 has color %08x, expected 0x00ffff00\n", color);
8274 color = getPixelColor(device, 572, 298);
8275 ok(color == 0x000000ff,
8276 "pixel 572/298 has color %08x, expected 0x000000ff\n", color);
8277 color = getPixelColor(device, 568, 302);
8278 ok(color == 0x000000ff,
8279 "pixel 568/302 has color %08x, expected 0x000000ff\n", color);
8280 color = getPixelColor(device, 572, 302);
8281 ok(color == 0x000000ff,
8282 "pixel 572/302 has color %08x, expected 0x000000ff\n", color);
8284 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
8286 refcount = IDirect3DDevice8_Release(device);
8287 ok(!refcount, "Device has %u references left.\n", refcount);
8288 done:
8289 IDirect3D8_Release(d3d);
8290 DestroyWindow(window);
8293 static void test_flip(void)
8295 IDirect3DDevice8 *device;
8296 IDirect3D8 *d3d;
8297 ULONG refcount;
8298 HWND window;
8299 HRESULT hr;
8300 IDirect3DSurface8 *back_buffers[3], *test_surface;
8301 unsigned int i;
8302 D3DCOLOR color;
8303 D3DPRESENT_PARAMETERS present_parameters = {0};
8305 window = create_window();
8306 d3d = Direct3DCreate8(D3D_SDK_VERSION);
8307 ok(!!d3d, "Failed to create a D3D object.\n");
8309 present_parameters.BackBufferWidth = 640;
8310 present_parameters.BackBufferHeight = 480;
8311 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
8312 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
8313 present_parameters.hDeviceWindow = window;
8314 present_parameters.Windowed = TRUE;
8315 present_parameters.BackBufferCount = 3;
8316 present_parameters.Flags = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER;
8317 if (FAILED(hr = IDirect3D8_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
8318 window, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device)))
8320 skip("Failed to create a D3D device, skipping tests.\n");
8321 IDirect3D8_Release(d3d);
8322 DestroyWindow(window);
8323 return;
8326 for (i = 0; i < ARRAY_SIZE(back_buffers); ++i)
8328 hr = IDirect3DDevice8_GetBackBuffer(device, i, D3DBACKBUFFER_TYPE_MONO, &back_buffers[i]);
8329 ok(SUCCEEDED(hr), "Failed to get back buffer, hr %#x.\n", hr);
8331 hr = IDirect3DDevice8_GetRenderTarget(device, &test_surface);
8332 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
8333 ok(test_surface == back_buffers[0], "Expected render target %p, got %p.\n", back_buffers[0], test_surface);
8334 IDirect3DSurface8_Release(test_surface);
8337 hr = IDirect3DDevice8_SetRenderTarget(device, back_buffers[0], NULL);
8338 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
8339 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0f, 0);
8340 ok(SUCCEEDED(hr), "Failed to clear, hr %#x\n", hr);
8342 hr = IDirect3DDevice8_SetRenderTarget(device, back_buffers[1], NULL);
8343 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
8344 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0f, 0);
8345 ok(SUCCEEDED(hr), "Failed to clear, hr %#x\n", hr);
8347 hr = IDirect3DDevice8_SetRenderTarget(device, back_buffers[2], NULL);
8348 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
8349 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0f, 0);
8350 ok(SUCCEEDED(hr), "Failed to clear, hr %#x\n", hr);
8352 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
8353 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
8355 /* Render target is unmodified. */
8356 hr = IDirect3DDevice8_GetRenderTarget(device, &test_surface);
8357 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
8358 ok(test_surface == back_buffers[2], "Expected render target %p, got %p.\n", back_buffers[2], test_surface);
8359 IDirect3DSurface8_Release(test_surface);
8361 /* Backbuffer surface pointers are unmodified */
8362 for (i = 0; i < ARRAY_SIZE(back_buffers); ++i)
8364 hr = IDirect3DDevice8_GetBackBuffer(device, i, D3DBACKBUFFER_TYPE_MONO, &test_surface);
8365 ok(SUCCEEDED(hr), "Failed to get back buffer, hr %#x.\n", hr);
8366 ok(test_surface == back_buffers[i], "Expected back buffer %u = %p, got %p.\n",
8367 i, back_buffers[i], test_surface);
8368 IDirect3DSurface8_Release(test_surface);
8371 /* Contents were changed. */
8372 color = get_surface_color(back_buffers[0], 1, 1);
8373 ok(color == 0xff00ff00, "Got unexpected color 0x%08x.\n", color);
8374 color = get_surface_color(back_buffers[1], 1, 1);
8375 ok(color == 0xff0000ff, "Got unexpected color 0x%08x.\n", color);
8377 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff808080, 0.0f, 0);
8378 ok(SUCCEEDED(hr), "Failed to clear, hr %#x\n", hr);
8380 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
8381 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
8383 color = get_surface_color(back_buffers[0], 1, 1);
8384 ok(color == 0xff0000ff, "Got unexpected color 0x%08x.\n", color);
8385 color = get_surface_color(back_buffers[1], 1, 1);
8386 ok(color == 0xff808080, "Got unexpected color 0x%08x.\n", color);
8388 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
8389 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
8391 color = get_surface_color(back_buffers[0], 1, 1);
8392 ok(color == 0xff808080, "Got unexpected color 0x%08x.\n", color);
8394 for (i = 0; i < ARRAY_SIZE(back_buffers); ++i)
8395 IDirect3DSurface8_Release(back_buffers[i]);
8397 refcount = IDirect3DDevice8_Release(device);
8398 ok(!refcount, "Device has %u references left.\n", refcount);
8400 if (FAILED(IDirect3D8_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
8401 D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES)))
8403 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping multisample flip test.\n");
8404 goto done;
8407 present_parameters.BackBufferCount = 2;
8408 present_parameters.MultiSampleType = D3DMULTISAMPLE_2_SAMPLES;
8409 present_parameters.Flags = 0;
8410 hr = IDirect3D8_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
8411 window, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device);
8413 for (i = 0; i < present_parameters.BackBufferCount; ++i)
8415 hr = IDirect3DDevice8_GetBackBuffer(device, i, D3DBACKBUFFER_TYPE_MONO, &back_buffers[i]);
8416 ok(SUCCEEDED(hr), "Failed to get back buffer, hr %#x.\n", hr);
8419 hr = IDirect3DDevice8_SetRenderTarget(device, back_buffers[1], NULL);
8420 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
8421 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff808080, 0.0f, 0);
8422 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
8424 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
8425 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
8427 hr = IDirect3DDevice8_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
8428 D3DMULTISAMPLE_NONE, TRUE, &test_surface);
8429 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
8430 hr = IDirect3DDevice8_CopyRects(device, back_buffers[0], NULL, 0, test_surface, NULL);
8431 ok(SUCCEEDED(hr), "CopyRects failed, hr %#x.\n", hr);
8433 color = get_surface_color(test_surface, 1, 1);
8434 ok(color == 0xff808080, "Got unexpected color 0x%08x.\n", color);
8436 IDirect3DSurface8_Release(test_surface);
8437 for (i = 0; i < present_parameters.BackBufferCount; ++i)
8438 IDirect3DSurface8_Release(back_buffers[i]);
8440 refcount = IDirect3DDevice8_Release(device);
8441 ok(!refcount, "Device has %u references left.\n", refcount);
8443 done:
8444 IDirect3D8_Release(d3d);
8445 DestroyWindow(window);
8448 static void test_uninitialized_varyings(void)
8450 static const D3DMATRIX mat =
8452 1.0f, 0.0f, 0.0f, 0.0f,
8453 0.0f, 1.0f, 0.0f, 0.0f,
8454 0.0f, 0.0f, 1.0f, 0.0f,
8455 0.0f, 0.0f, 0.0f, 1.0f,
8456 }}};
8457 static const struct vec3 quad[] =
8459 {-1.0f, -1.0f, 0.1f},
8460 {-1.0f, 1.0f, 0.1f},
8461 { 1.0f, -1.0f, 0.1f},
8462 { 1.0f, 1.0f, 0.1f},
8464 static const DWORD decl[] =
8466 D3DVSD_STREAM(0),
8467 D3DVSD_REG(0, D3DVSDT_FLOAT3),
8468 D3DVSD_CONST(0, 1), 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, /* def c0, 0.5, 0.5, 0.5, 0.5 */
8469 D3DVSD_END()
8471 static const DWORD vs1_code[] =
8473 0xfffe0101, /* vs_1_1 */
8474 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
8475 0x0000ffff
8477 static const DWORD vs1_partial_code[] =
8479 0xfffe0101, /* vs_1_1 */
8480 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
8481 0x00000001, 0xd0010000, 0xa0e40000, /* mov oD0.x, c0 */
8482 0x00000001, 0xd0010001, 0xa0e40000, /* mov oD1.x, c0 */
8483 0x00000001, 0xe0010000, 0xa0e40000, /* mov oT0.x, c0 */
8484 0x0000ffff
8486 static const DWORD ps1_diffuse_code[] =
8488 0xffff0101, /* ps_1_1 */
8489 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
8490 0x0000ffff
8492 static const DWORD ps1_specular_code[] =
8494 0xffff0101, /* ps_1_1 */
8495 0x00000001, 0x800f0000, 0x90e40001, /* mov r0, v1 */
8496 0x0000ffff
8498 static const DWORD ps1_texcoord_code[] =
8500 0xffff0101, /* ps_1_1 */
8501 0x00000040, 0xb00f0000, /* texcoord t0 */
8502 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
8503 0x0000ffff
8505 static const struct
8507 DWORD vs_version;
8508 const DWORD *vs;
8509 DWORD ps_version;
8510 const DWORD *ps;
8511 D3DCOLOR expected;
8512 BOOL allow_zero_alpha;
8513 BOOL partial;
8514 BOOL broken_warp;
8516 /* On AMD specular color is generally initialized to 0x00000000 and texcoords to 0xff000000
8517 * while on Nvidia it's the opposite. Just allow both.
8519 * Partially initialized varyings reliably handle the component that has been initialized.
8520 * The uninitialized components generally follow the rule above, with some exceptions on
8521 * radeon cards. r500 and r600 GPUs have been found to set uninitialized components to 0.0,
8522 * 0.5 and 1.0 without a sensible pattern. */
8523 tests[] =
8525 {D3DVS_VERSION(1, 1), vs1_code, 0, NULL, 0xffffffff},
8526 { 0, NULL, D3DPS_VERSION(1, 1), ps1_texcoord_code, 0xff000000, TRUE},
8527 {D3DVS_VERSION(1, 1), vs1_code, D3DPS_VERSION(1, 1), ps1_diffuse_code, 0xffffffff},
8528 {D3DVS_VERSION(1, 1), vs1_code, D3DPS_VERSION(1, 1), ps1_specular_code, 0xff000000, TRUE, FALSE, TRUE},
8529 {D3DVS_VERSION(1, 1), vs1_code, D3DPS_VERSION(1, 1), ps1_texcoord_code, 0xff000000, TRUE},
8530 {D3DVS_VERSION(1, 1), vs1_partial_code, 0, NULL, 0xff7fffff, FALSE, TRUE},
8531 {D3DVS_VERSION(1, 1), vs1_partial_code, D3DPS_VERSION(1, 1), ps1_diffuse_code, 0xff7fffff, FALSE, TRUE},
8532 {D3DVS_VERSION(1, 1), vs1_partial_code, D3DPS_VERSION(1, 1), ps1_specular_code, 0xff7f0000, TRUE, TRUE},
8533 {D3DVS_VERSION(1, 1), vs1_partial_code, D3DPS_VERSION(1, 1), ps1_texcoord_code, 0xff7f0000, TRUE, TRUE},
8535 IDirect3DDevice8 *device;
8536 IDirect3D8 *d3d;
8537 HWND window;
8538 HRESULT hr;
8539 DWORD vs, ps;
8540 unsigned int i;
8541 ULONG refcount;
8542 D3DCAPS8 caps;
8543 IDirect3DSurface8 *backbuffer;
8544 D3DADAPTER_IDENTIFIER8 identifier;
8545 struct surface_readback rb;
8546 D3DCOLOR color;
8547 BOOL warp;
8549 window = create_window();
8550 d3d = Direct3DCreate8(D3D_SDK_VERSION);
8551 ok(!!d3d, "Failed to create a D3D object.\n");
8552 if (!(device = create_device(d3d, window, window, TRUE)))
8554 skip("Failed to create a D3D device, skipping tests.\n");
8555 IDirect3D8_Release(d3d);
8556 DestroyWindow(window);
8557 return;
8560 hr = IDirect3D8_GetAdapterIdentifier(d3d, D3DADAPTER_DEFAULT, 0, &identifier);
8561 ok(SUCCEEDED(hr), "Failed to get adapter identifier, hr %#x.\n", hr);
8562 warp = adapter_is_warp(&identifier);
8564 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
8565 ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
8567 hr = IDirect3DDevice8_GetBackBuffer(device, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8568 ok(SUCCEEDED(hr), "Failed to get back buffer, hr %#x.\n", hr);
8570 hr = IDirect3DDevice8_SetTransform(device, D3DTS_WORLD, &mat);
8571 ok(SUCCEEDED(hr), "Failed to set world transform, hr %#x.\n", hr);
8572 hr = IDirect3DDevice8_SetTransform(device, D3DTS_VIEW, &mat);
8573 ok(SUCCEEDED(hr), "Failed to set view transform, hr %#x.\n", hr);
8574 hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, &mat);
8575 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
8576 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, FALSE);
8577 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#x.\n", hr);
8578 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, FALSE);
8579 ok(SUCCEEDED(hr), "Failed to disable Z test, hr %#x.\n", hr);
8580 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
8581 ok(SUCCEEDED(hr), "Failed to disable fog, hr %#x.\n", hr);
8582 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
8583 ok(SUCCEEDED(hr), "Failed to disable stencil test, hr %#x.\n", hr);
8584 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8585 ok(SUCCEEDED(hr), "Failed to disable culling, hr %#x.\n", hr);
8587 for (i = 0; i < ARRAY_SIZE(tests); ++i)
8589 if (caps.VertexShaderVersion < tests[i].vs_version
8590 || caps.PixelShaderVersion < tests[i].ps_version)
8592 skip("Vertex / pixel shader version not supported, skipping test %u.\n", i);
8593 continue;
8595 if (tests[i].vs)
8597 hr = IDirect3DDevice8_CreateVertexShader(device, decl, tests[i].vs, &vs, 0);
8598 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x (case %u).\n", hr, i);
8599 hr = IDirect3DDevice8_SetVertexShader(device, vs);
8600 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
8602 else
8604 vs = 0;
8605 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ);
8606 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
8608 if (tests[i].ps)
8610 hr = IDirect3DDevice8_CreatePixelShader(device, tests[i].ps, &ps);
8611 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x (case %u).\n", hr, i);
8613 else
8615 ps = 0;
8618 hr = IDirect3DDevice8_SetPixelShader(device, ps);
8619 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
8621 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0f, 0);
8622 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
8624 hr = IDirect3DDevice8_BeginScene(device);
8625 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
8627 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
8628 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8630 hr = IDirect3DDevice8_EndScene(device);
8631 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
8633 get_rt_readback(backbuffer, &rb);
8634 color = get_readback_color(&rb, 320, 240);
8635 ok(color_match(color, tests[i].expected, 1)
8636 || (tests[i].allow_zero_alpha && color_match(color, tests[i].expected & 0x00ffffff, 1))
8637 || (broken(warp && tests[i].broken_warp))
8638 || broken(tests[i].partial && color_match(color & 0x00ff0000, tests[i].expected & 0x00ff0000, 1)),
8639 "Got unexpected color 0x%08x, case %u.\n", color, i);
8640 release_surface_readback(&rb);
8642 if (vs)
8643 IDirect3DDevice8_DeleteVertexShader(device, vs);
8644 if (ps)
8645 IDirect3DDevice8_DeletePixelShader(device, ps);
8648 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
8649 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
8651 IDirect3DSurface8_Release(backbuffer);
8652 refcount = IDirect3DDevice8_Release(device);
8653 ok(!refcount, "Device has %u references left.\n", refcount);
8654 IDirect3D8_Release(d3d);
8655 DestroyWindow(window);
8658 static void test_shademode(void)
8660 IDirect3DVertexBuffer8 *vb_strip;
8661 IDirect3DVertexBuffer8 *vb_list;
8662 IDirect3DDevice8 *device;
8663 DWORD color0, color1;
8664 BYTE *data = NULL;
8665 IDirect3D8 *d3d;
8666 ULONG refcount;
8667 D3DCAPS8 caps;
8668 DWORD vs, ps;
8669 HWND window;
8670 HRESULT hr;
8671 UINT i;
8672 static const DWORD decl[] =
8674 D3DVSD_STREAM(0),
8675 D3DVSD_REG(D3DVSDE_POSITION, D3DVSDT_FLOAT3),
8676 D3DVSD_REG(D3DVSDE_DIFFUSE, D3DVSDT_D3DCOLOR),
8677 D3DVSD_END()
8679 static const DWORD vs1_code[] =
8681 0xfffe0101, /* vs_1_1 */
8682 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
8683 0x00000001, 0xd00f0000, 0x90e40005, /* mov oD0, v5 */
8684 0x0000ffff
8686 static const DWORD ps1_code[] =
8688 0xffff0101, /* ps_1_1 */
8689 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
8690 0x0000ffff
8692 static const struct
8694 struct vec3 position;
8695 DWORD diffuse;
8697 quad_strip[] =
8699 {{-1.0f, -1.0f, 0.0f}, 0xffff0000},
8700 {{-1.0f, 1.0f, 0.0f}, 0xff00ff00},
8701 {{ 1.0f, -1.0f, 0.0f}, 0xff0000ff},
8702 {{ 1.0f, 1.0f, 0.0f}, 0xffffffff},
8704 quad_list[] =
8706 {{-1.0f, -1.0f, 0.0f}, 0xffff0000},
8707 {{-1.0f, 1.0f, 0.0f}, 0xff00ff00},
8708 {{ 1.0f, -1.0f, 0.0f}, 0xff0000ff},
8710 {{ 1.0f, -1.0f, 0.0f}, 0xff0000ff},
8711 {{-1.0f, 1.0f, 0.0f}, 0xff00ff00},
8712 {{ 1.0f, 1.0f, 0.0f}, 0xffffffff},
8714 static const struct test_shader
8716 DWORD version;
8717 const DWORD *code;
8719 novs = {0, NULL},
8720 vs_1 = {D3DVS_VERSION(1, 1), vs1_code},
8721 nops = {0, NULL},
8722 ps_1 = {D3DPS_VERSION(1, 1), ps1_code};
8723 static const struct
8725 const struct test_shader *vs, *ps;
8726 DWORD primtype;
8727 DWORD shademode;
8728 DWORD color0, color1;
8730 tests[] =
8732 {&novs, &nops, D3DPT_TRIANGLESTRIP, D3DSHADE_FLAT, 0x00ff0000, 0x0000ff00},
8733 {&novs, &nops, D3DPT_TRIANGLESTRIP, D3DSHADE_PHONG, 0x000dca28, 0x000d45c7},
8734 {&novs, &nops, D3DPT_TRIANGLESTRIP, D3DSHADE_GOURAUD, 0x000dca28, 0x000d45c7},
8735 {&novs, &nops, D3DPT_TRIANGLESTRIP, D3DSHADE_PHONG, 0x000dca28, 0x000d45c7},
8736 {&novs, &nops, D3DPT_TRIANGLELIST, D3DSHADE_FLAT, 0x00ff0000, 0x000000ff},
8737 {&novs, &nops, D3DPT_TRIANGLELIST, D3DSHADE_GOURAUD, 0x000dca28, 0x000d45c7},
8738 {&vs_1, &ps_1, D3DPT_TRIANGLESTRIP, D3DSHADE_FLAT, 0x00ff0000, 0x0000ff00},
8739 {&vs_1, &ps_1, D3DPT_TRIANGLESTRIP, D3DSHADE_GOURAUD, 0x000dca28, 0x000d45c7},
8740 {&vs_1, &ps_1, D3DPT_TRIANGLELIST, D3DSHADE_FLAT, 0x00ff0000, 0x000000ff},
8741 {&vs_1, &ps_1, D3DPT_TRIANGLELIST, D3DSHADE_GOURAUD, 0x000dca28, 0x000d45c7},
8742 {&novs, &ps_1, D3DPT_TRIANGLESTRIP, D3DSHADE_FLAT, 0x00ff0000, 0x0000ff00},
8743 {&vs_1, &nops, D3DPT_TRIANGLESTRIP, D3DSHADE_FLAT, 0x00ff0000, 0x0000ff00},
8746 window = create_window();
8747 d3d = Direct3DCreate8(D3D_SDK_VERSION);
8748 ok(!!d3d, "Failed to create a D3D object.\n");
8749 if (!(device = create_device(d3d, window, window, TRUE)))
8751 skip("Failed to create a D3D device, skipping tests.\n");
8752 IDirect3D8_Release(d3d);
8753 DestroyWindow(window);
8754 return;
8757 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
8758 ok(hr == D3D_OK, "Failed to disable lighting, hr %#x.\n", hr);
8759 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
8760 ok(SUCCEEDED(hr), "Failed to disable fog, hr %#x.\n", hr);
8762 hr = IDirect3DDevice8_CreateVertexBuffer(device, sizeof(quad_strip), 0, 0, D3DPOOL_MANAGED, &vb_strip);
8763 ok(hr == D3D_OK, "Failed to create vertex buffer, hr %#x.\n", hr);
8764 hr = IDirect3DVertexBuffer8_Lock(vb_strip, 0, sizeof(quad_strip), &data, 0);
8765 ok(hr == D3D_OK, "Failed to lock vertex buffer, hr %#x.\n", hr);
8766 memcpy(data, quad_strip, sizeof(quad_strip));
8767 hr = IDirect3DVertexBuffer8_Unlock(vb_strip);
8768 ok(hr == D3D_OK, "Failed to unlock vertex buffer, hr %#x.\n", hr);
8770 hr = IDirect3DDevice8_CreateVertexBuffer(device, sizeof(quad_list), 0, 0, D3DPOOL_MANAGED, &vb_list);
8771 ok(hr == D3D_OK, "Failed to create vertex buffer, hr %#x.\n", hr);
8772 hr = IDirect3DVertexBuffer8_Lock(vb_list, 0, sizeof(quad_list), &data, 0);
8773 ok(hr == D3D_OK, "Failed to lock vertex buffer, hr %#x.\n", hr);
8774 memcpy(data, quad_list, sizeof(quad_list));
8775 hr = IDirect3DVertexBuffer8_Unlock(vb_list);
8776 ok(hr == D3D_OK, "Failed to unlock vertex buffer, hr %#x.\n", hr);
8778 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
8779 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
8781 /* Try it first with a TRIANGLESTRIP. Do it with different geometry because
8782 * the color fixups we have to do for FLAT shading will be dependent on that. */
8784 for (i = 0; i < ARRAY_SIZE(tests); ++i)
8786 if (tests[i].vs->version)
8788 if (caps.VertexShaderVersion >= tests[i].vs->version)
8790 hr = IDirect3DDevice8_CreateVertexShader(device, decl, tests[i].vs->code, &vs, 0);
8791 ok(hr == D3D_OK, "Failed to create vertex shader, hr %#x.\n", hr);
8792 hr = IDirect3DDevice8_SetVertexShader(device, vs);
8793 ok(hr == D3D_OK, "Failed to set vertex shader, hr %#x.\n", hr);
8795 else
8797 skip("Shader version unsupported, skipping some tests.\n");
8798 continue;
8801 else
8803 vs = 0;
8804 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8805 ok(hr == D3D_OK, "Failed to set FVF, hr %#x.\n", hr);
8807 if (tests[i].ps->version)
8809 if (caps.PixelShaderVersion >= tests[i].ps->version)
8811 hr = IDirect3DDevice8_CreatePixelShader(device, tests[i].ps->code, &ps);
8812 ok(hr == D3D_OK, "Failed to create pixel shader, hr %#x.\n", hr);
8813 hr = IDirect3DDevice8_SetPixelShader(device, ps);
8814 ok(hr == D3D_OK, "Failed to set pixel shader, hr %#x.\n", hr);
8816 else
8818 skip("Shader version unsupported, skipping some tests.\n");
8819 if (vs)
8821 IDirect3DDevice8_SetVertexShader(device, 0);
8822 IDirect3DDevice8_DeleteVertexShader(device, vs);
8824 continue;
8827 else
8829 ps = 0;
8832 hr = IDirect3DDevice8_SetStreamSource(device, 0,
8833 tests[i].primtype == D3DPT_TRIANGLESTRIP ? vb_strip : vb_list, sizeof(quad_strip[0]));
8834 ok(hr == D3D_OK, "Failed to set stream source, hr %#x.\n", hr);
8836 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
8837 ok(hr == D3D_OK, "Failed to clear, hr %#x.\n", hr);
8839 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SHADEMODE, tests[i].shademode);
8840 ok(hr == D3D_OK, "Failed to set shade mode, hr %#x.\n", hr);
8842 hr = IDirect3DDevice8_BeginScene(device);
8843 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
8844 hr = IDirect3DDevice8_DrawPrimitive(device, tests[i].primtype, 0, 2);
8845 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8846 hr = IDirect3DDevice8_EndScene(device);
8847 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
8849 color0 = getPixelColor(device, 100, 100); /* Inside first triangle */
8850 color1 = getPixelColor(device, 500, 350); /* Inside second triangle */
8852 /* For D3DSHADE_FLAT it should take the color of the first vertex of
8853 * each triangle. This requires EXT_provoking_vertex or similar
8854 * functionality being available. */
8855 /* PHONG should be the same as GOURAUD, since no hardware implements
8856 * this. */
8857 ok(color_match(color0, tests[i].color0, 1), "Test %u shading has color0 %08x, expected %08x.\n",
8858 i, color0, tests[i].color0);
8859 ok(color_match(color1, tests[i].color1, 1), "Test %u shading has color1 %08x, expected %08x.\n",
8860 i, color1, tests[i].color1);
8862 IDirect3DDevice8_SetVertexShader(device, 0);
8863 IDirect3DDevice8_SetPixelShader(device, 0);
8865 if (ps)
8866 IDirect3DDevice8_DeletePixelShader(device, ps);
8867 if (vs)
8868 IDirect3DDevice8_DeleteVertexShader(device, vs);
8871 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
8872 ok(hr == D3D_OK, "Failed to present, hr %#x.\n", hr);
8874 IDirect3DVertexBuffer8_Release(vb_strip);
8875 IDirect3DVertexBuffer8_Release(vb_list);
8876 refcount = IDirect3DDevice8_Release(device);
8877 ok(!refcount, "Device has %u references left.\n", refcount);
8878 IDirect3D8_Release(d3d);
8879 DestroyWindow(window);
8882 static void test_multisample_init(void)
8884 IDirect3DDevice8 *device;
8885 IDirect3D8 *d3d;
8886 IDirect3DSurface8 *back, *multi;
8887 ULONG refcount;
8888 HWND window;
8889 HRESULT hr;
8890 D3DCOLOR color;
8891 unsigned int x, y;
8892 struct surface_readback rb;
8893 BOOL all_zero = TRUE;
8895 window = create_window();
8896 d3d = Direct3DCreate8(D3D_SDK_VERSION);
8897 ok(!!d3d, "Failed to create a D3D object.\n");
8899 if (FAILED(IDirect3D8_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
8900 D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES)))
8902 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping multisample init test.\n");
8903 goto done;
8906 if (!(device = create_device(d3d, window, window, TRUE)))
8908 skip("Failed to create a D3D device, skipping tests.\n");
8909 goto done;
8912 hr = IDirect3DDevice8_GetBackBuffer(device, 0, D3DBACKBUFFER_TYPE_MONO, &back);
8913 ok(SUCCEEDED(hr), "Failed to get back buffer, hr %#x.\n", hr);
8914 hr = IDirect3DDevice8_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
8915 D3DMULTISAMPLE_2_SAMPLES, FALSE, &multi);
8916 ok(SUCCEEDED(hr), "Failed to create multisampled render target, hr %#x.\n", hr);
8918 hr = IDirect3DDevice8_CopyRects(device, multi, NULL, 0, back, NULL);
8919 ok(SUCCEEDED(hr), "CopyRects failed, hr %#x.\n", hr);
8921 get_rt_readback(back, &rb);
8922 for (y = 0; y < 480; ++y)
8924 for (x = 0; x < 640; ++x)
8926 color = get_readback_color(&rb, x, y);
8927 if (!color_match(color, 0x00000000, 0))
8929 all_zero = FALSE;
8930 break;
8933 if (!all_zero)
8934 break;
8936 release_surface_readback(&rb);
8937 ok(all_zero, "Got unexpected color 0x%08x, position %ux%u.\n", color, x, y);
8939 IDirect3DSurface8_Release(multi);
8940 IDirect3DSurface8_Release(back);
8942 refcount = IDirect3DDevice8_Release(device);
8943 ok(!refcount, "Device has %u references left.\n", refcount);
8945 done:
8946 IDirect3D8_Release(d3d);
8947 DestroyWindow(window);
8950 static void test_texture_blending(void)
8952 #define STATE_END() {0xffffffff, 0xffffffff}
8953 #define IS_STATE_END(s) (s.name == 0xffffffff && s.value == 0xffffffff)
8955 IDirect3DTexture8 *texture_bumpmap, *texture_red;
8956 IDirect3DSurface8 *backbuffer;
8957 struct surface_readback rb;
8958 D3DLOCKED_RECT locked_rect;
8959 IDirect3DDevice8 *device;
8960 unsigned int i, j, k;
8961 IDirect3D8 *d3d;
8962 D3DCOLOR color;
8963 ULONG refcount;
8964 D3DCAPS8 caps;
8965 HWND window;
8966 HRESULT hr;
8968 static const struct
8970 struct vec3 position;
8971 DWORD diffuse;
8973 quad[] =
8975 {{-1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0x80, 0xff, 0xff, 0x02)},
8976 {{-1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0x80, 0xff, 0xff, 0x02)},
8977 {{ 1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0x80, 0xff, 0xff, 0x02)},
8978 {{ 1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0x80, 0xff, 0xff, 0x02)},
8981 static const float bumpenvmat[4] = {1.0f, 1.0f, 0.0f, 0.0f};
8983 struct texture_stage_state
8985 D3DTEXTURESTAGESTATETYPE name;
8986 DWORD value;
8989 struct texture_stage
8991 enum
8993 TEXTURE_INVALID,
8994 TEXTURE_NONE,
8995 TEXTURE_BUMPMAP,
8996 TEXTURE_RED,
8998 texture;
8999 struct texture_stage_state state[20];
9002 static const struct texture_stage default_stage_state =
9004 TEXTURE_NONE,
9006 {D3DTSS_COLOROP, D3DTOP_DISABLE},
9007 {D3DTSS_COLORARG1, D3DTA_TEXTURE},
9008 {D3DTSS_COLORARG2, D3DTA_CURRENT},
9009 {D3DTSS_ALPHAOP, D3DTOP_DISABLE},
9010 {D3DTSS_ALPHAARG1, D3DTA_TEXTURE},
9011 {D3DTSS_ALPHAARG2, D3DTA_CURRENT},
9012 {D3DTSS_BUMPENVMAT00, 0},
9013 {D3DTSS_BUMPENVMAT01, 0},
9014 {D3DTSS_BUMPENVMAT10, 0},
9015 {D3DTSS_BUMPENVMAT11, 0},
9016 {D3DTSS_BUMPENVLSCALE, 0},
9017 {D3DTSS_BUMPENVLOFFSET, 0},
9018 {D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE},
9019 {D3DTSS_COLORARG0, D3DTA_CURRENT},
9020 {D3DTSS_ALPHAARG0, D3DTA_CURRENT},
9021 {D3DTSS_RESULTARG, D3DTA_CURRENT},
9022 STATE_END(),
9026 const struct test
9028 DWORD tex_op_caps;
9029 D3DCOLOR expected_color;
9030 struct texture_stage stage[8];
9032 tests[] =
9035 D3DTEXOPCAPS_DISABLE,
9036 0x80ffff02,
9039 TEXTURE_NONE,
9041 STATE_END(),
9047 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1,
9048 0x80ffff02,
9051 TEXTURE_NONE,
9053 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
9054 {D3DTSS_COLORARG1, D3DTA_CURRENT},
9055 STATE_END(),
9058 {TEXTURE_INVALID}
9062 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1,
9063 0x80ffff02,
9066 TEXTURE_NONE,
9068 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
9069 {D3DTSS_COLORARG1, D3DTA_CURRENT},
9070 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
9071 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
9072 STATE_END(),
9078 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1,
9079 0x80ffff02,
9082 TEXTURE_NONE,
9084 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
9085 {D3DTSS_COLORARG1, D3DTA_DIFFUSE},
9086 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
9087 {D3DTSS_ALPHAARG1, D3DTA_DIFFUSE},
9088 STATE_END(),
9094 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1,
9095 0x00000000,
9098 TEXTURE_NONE,
9100 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
9101 {D3DTSS_COLORARG1, D3DTA_TEMP},
9102 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
9103 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
9104 STATE_END(),
9111 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE,
9112 0x80ff0000,
9115 TEXTURE_BUMPMAP,
9117 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
9118 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
9119 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
9120 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
9121 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
9122 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
9123 {D3DTSS_ALPHAARG1, D3DTA_TEXTURE},
9124 STATE_END(),
9129 TEXTURE_RED,
9131 {D3DTSS_COLOROP, D3DTOP_MODULATE},
9132 STATE_END(),
9135 {TEXTURE_INVALID}
9139 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE,
9140 0x80ff0000,
9143 TEXTURE_BUMPMAP,
9145 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
9146 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
9147 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
9148 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
9149 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
9150 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
9151 {D3DTSS_ALPHAARG1, D3DTA_DIFFUSE},
9152 STATE_END(),
9156 TEXTURE_RED,
9158 {D3DTSS_COLOROP, D3DTOP_MODULATE},
9159 STATE_END(),
9162 {TEXTURE_INVALID}
9166 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE,
9167 0x80ff0000,
9170 TEXTURE_BUMPMAP,
9172 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
9173 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
9174 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
9175 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
9176 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
9177 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
9178 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
9179 STATE_END(),
9183 TEXTURE_RED,
9185 {D3DTSS_COLOROP, D3DTOP_MODULATE},
9186 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
9187 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
9188 STATE_END(),
9191 {TEXTURE_INVALID}
9195 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE,
9196 0x00ff0000,
9199 TEXTURE_BUMPMAP,
9201 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
9202 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
9203 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
9204 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
9205 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
9206 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
9207 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
9208 STATE_END(),
9212 TEXTURE_RED,
9214 {D3DTSS_COLOROP, D3DTOP_MODULATE},
9215 {D3DTSS_COLORARG1, D3DTA_TEXTURE},
9216 {D3DTSS_COLORARG2, D3DTA_CURRENT},
9217 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
9218 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
9219 STATE_END(),
9222 {TEXTURE_INVALID}
9226 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE,
9227 0x80ff0000,
9230 TEXTURE_BUMPMAP,
9232 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
9233 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
9234 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
9235 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
9236 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
9237 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
9238 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
9239 STATE_END(),
9243 TEXTURE_RED,
9245 {D3DTSS_COLOROP, D3DTOP_MODULATE},
9246 {D3DTSS_COLORARG1, D3DTA_TEXTURE},
9247 {D3DTSS_COLORARG2, D3DTA_CURRENT},
9248 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
9249 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
9250 STATE_END(),
9253 {TEXTURE_INVALID}
9258 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE
9259 | D3DTEXOPCAPS_ADD,
9260 0x80ff0000,
9263 TEXTURE_BUMPMAP,
9265 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
9266 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
9267 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
9268 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
9269 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
9270 {D3DTSS_ALPHAOP, D3DTOP_ADD},
9271 {D3DTSS_ALPHAARG1, D3DTA_DIFFUSE},
9272 {D3DTSS_ALPHAARG2, D3DTA_CURRENT},
9273 STATE_END(),
9277 TEXTURE_RED,
9279 {D3DTSS_COLOROP, D3DTOP_MODULATE},
9280 {D3DTSS_COLORARG1, D3DTA_TEXTURE},
9281 {D3DTSS_COLORARG2, D3DTA_CURRENT},
9282 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
9283 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
9284 STATE_END(),
9287 {TEXTURE_INVALID}
9291 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE
9292 | D3DTEXOPCAPS_MODULATE2X,
9293 0x80ffff00,
9296 TEXTURE_BUMPMAP,
9298 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
9299 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
9300 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
9301 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
9302 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
9303 {D3DTSS_ALPHAOP, D3DTOP_MODULATE2X},
9304 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
9305 {D3DTSS_ALPHAARG2, D3DTA_DIFFUSE},
9306 STATE_END(),
9310 TEXTURE_RED,
9312 {D3DTSS_COLOROP, D3DTOP_MODULATE},
9313 {D3DTSS_COLORARG1, D3DTA_CURRENT},
9314 {D3DTSS_COLORARG2, D3DTA_CURRENT},
9315 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
9316 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
9317 STATE_END(),
9320 {TEXTURE_INVALID}
9324 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP,
9325 0x80ffff02,
9328 TEXTURE_NONE,
9330 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
9331 {D3DTSS_COLORARG1, D3DTA_DIFFUSE},
9332 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
9333 {D3DTSS_ALPHAARG1, D3DTA_DIFFUSE},
9334 {D3DTSS_RESULTARG, D3DTA_TEMP},
9335 STATE_END(),
9339 TEXTURE_BUMPMAP,
9341 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
9342 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
9343 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
9344 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
9345 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
9346 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
9347 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
9348 {D3DTSS_RESULTARG, D3DTA_TEMP},
9349 STATE_END(),
9353 TEXTURE_RED,
9355 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
9356 {D3DTSS_COLORARG1, D3DTA_TEXTURE},
9357 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
9358 {D3DTSS_ALPHAARG1, D3DTA_TEXTURE},
9359 STATE_END(),
9363 TEXTURE_NONE,
9365 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
9366 {D3DTSS_COLORARG1, D3DTA_TEMP},
9367 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
9368 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
9369 STATE_END(),
9372 {TEXTURE_INVALID}
9377 window = create_window();
9378 d3d = Direct3DCreate8(D3D_SDK_VERSION);
9379 ok(!!d3d, "Failed to create a D3D object.\n");
9380 if (!(device = create_device(d3d, window, window, TRUE)))
9382 skip("Failed to create a D3D device.\n");
9383 goto done;
9386 memset(&caps, 0, sizeof(caps));
9387 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
9388 ok(hr == D3D_OK, "IDirect3DDevice8_GetDeviceCaps failed hr %#x.\n", hr);
9390 if(!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP))
9392 skip("D3DPMISCCAPS_TSSARGTEMP not supported.\n");
9393 IDirect3DDevice8_Release(device);
9394 goto done;
9397 if (FAILED(IDirect3D8_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
9398 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_V8U8)))
9400 skip("D3DFMT_V8U8 not supported for legacy bump mapping.\n");
9401 IDirect3DDevice8_Release(device);
9402 goto done;
9405 hr = IDirect3DDevice8_GetBackBuffer(device, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9406 ok(hr == D3D_OK, "Can't get back buffer, hr %#x.\n", hr);
9408 hr = IDirect3DDevice8_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture_bumpmap);
9409 ok(hr == D3D_OK, "IDirect3DDevice8_CreateTexture failed, hr %#x.\n", hr);
9410 hr = IDirect3DDevice8_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture_red);
9411 ok(hr == D3D_OK, "IDirect3DDevice8_CreateTexture failed, hr %#x.\n", hr);
9413 memset(&locked_rect, 0, sizeof(locked_rect));
9414 hr = IDirect3DTexture8_LockRect(texture_bumpmap, 0, &locked_rect, NULL, 0);
9415 ok(SUCCEEDED(hr), "LockRect failed, hr %#x.\n", hr);
9416 *((WORD *)locked_rect.pBits) = 0xff00;
9417 hr = IDirect3DTexture8_UnlockRect(texture_bumpmap, 0);
9418 ok(SUCCEEDED(hr), "UnlockRect failed, hr %#x.\n", hr);
9420 memset(&locked_rect, 0, sizeof(locked_rect));
9421 hr = IDirect3DTexture8_LockRect(texture_red, 0, &locked_rect, NULL, 0);
9422 ok(SUCCEEDED(hr), "LockRect failed, hr %#x.\n", hr);
9423 *((DWORD *)locked_rect.pBits) = 0x00ff0000;
9424 hr = IDirect3DTexture8_UnlockRect(texture_red, 0);
9425 ok(SUCCEEDED(hr), "UnlockRect failed, hr %#x.\n", hr);
9427 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9428 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
9429 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9430 ok(hr == D3D_OK, "Failed to disable lighting, hr %#x.\n", hr);
9432 for (i = 0; i < ARRAY_SIZE(tests); ++i)
9434 const struct test *current_test = &tests[i];
9436 if ((caps.TextureOpCaps & current_test->tex_op_caps) != current_test->tex_op_caps)
9438 skip("Texture operations %#x not supported.\n", current_test->tex_op_caps);
9439 continue;
9442 for (j = 0; j < caps.MaxTextureBlendStages; ++j)
9444 IDirect3DTexture8 *current_texture = NULL;
9446 for (k = 0; !IS_STATE_END(default_stage_state.state[k]); ++k)
9448 hr = IDirect3DDevice8_SetTextureStageState(device, j,
9449 default_stage_state.state[k].name, default_stage_state.state[k].value);
9450 ok(SUCCEEDED(hr), "Test %u: SetTextureStageState failed, hr %#x.\n", i, hr);
9453 if (current_test->stage[j].texture != TEXTURE_INVALID)
9455 const struct texture_stage_state *current_state = current_test->stage[j].state;
9457 switch (current_test->stage[j].texture)
9459 case TEXTURE_RED:
9460 current_texture = texture_red;
9461 break;
9462 case TEXTURE_BUMPMAP:
9463 current_texture = texture_bumpmap;
9464 break;
9465 default:
9466 current_texture = NULL;
9467 break;
9470 for (k = 0; !IS_STATE_END(current_state[k]); ++k)
9472 hr = IDirect3DDevice8_SetTextureStageState(device, j,
9473 current_state[k].name, current_state[k].value);
9474 ok(SUCCEEDED(hr), "Test %u: SetTextureStageState failed, hr %#x.\n", i, hr);
9478 hr = IDirect3DDevice8_SetTexture(device, j, (IDirect3DBaseTexture8 *)current_texture);
9479 ok(SUCCEEDED(hr), "Test %u: SetTexture failed, hr %#x.\n", i, hr);
9482 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
9483 ok(hr == D3D_OK, "Test %u: IDirect3DDevice8_Clear failed, hr %#x.\n", i, hr);
9485 hr = IDirect3DDevice8_BeginScene(device);
9486 ok(SUCCEEDED(hr), "Test %u: BeginScene failed, hr %#x.\n", i, hr);
9487 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
9488 ok(SUCCEEDED(hr), "Test %u: DrawPrimitiveUP failed, hr %#x.\n", i, hr);
9489 hr = IDirect3DDevice8_EndScene(device);
9490 ok(SUCCEEDED(hr), "Test %u: EndScene failed, hr %#x.\n", i, hr);
9492 get_rt_readback(backbuffer, &rb);
9493 color = get_readback_color(&rb, 320, 240);
9494 ok(color_match(color, current_test->expected_color, 1),
9495 "Test %u: Got color 0x%08x, expected 0x%08x.\n", i, color, current_test->expected_color);
9496 release_surface_readback(&rb);
9497 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
9498 ok(SUCCEEDED(hr), "Test %u: Present failed, hr %#x.\n", i, hr);
9501 IDirect3DTexture8_Release(texture_bumpmap);
9502 IDirect3DTexture8_Release(texture_red);
9503 IDirect3DSurface8_Release(backbuffer);
9504 refcount = IDirect3DDevice8_Release(device);
9505 ok(!refcount, "Device has %u references left.\n", refcount);
9506 done:
9507 IDirect3D8_Release(d3d);
9508 DestroyWindow(window);
9511 static void test_color_clamping(void)
9513 static const D3DMATRIX mat =
9515 1.0f, 0.0f, 0.0f, 0.0f,
9516 0.0f, 1.0f, 0.0f, 0.0f,
9517 0.0f, 0.0f, 1.0f, 0.0f,
9518 0.0f, 0.0f, 0.0f, 1.0f,
9519 }}};
9520 static const struct vec3 quad[] =
9522 {-1.0f, -1.0f, 0.1f},
9523 {-1.0f, 1.0f, 0.1f},
9524 { 1.0f, -1.0f, 0.1f},
9525 { 1.0f, 1.0f, 0.1f},
9527 static const DWORD decl[] =
9529 D3DVSD_STREAM(0),
9530 D3DVSD_REG(D3DVSDE_POSITION, D3DVSDT_FLOAT3),
9531 D3DVSD_CONST(0, 1), 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c0, 1.0, 1.0, 1.0, 1.0 */
9532 D3DVSD_END()
9534 static const DWORD vs1_code[] =
9536 0xfffe0101, /* vs_1_1 */
9537 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
9538 0x00000002, 0xd00f0000, 0xa0e40000, 0xa0e40000, /* add oD0, c0, c0 */
9539 0x00000002, 0xd00f0001, 0xa0e40000, 0xa0e40000, /* add oD1, c0, c0 */
9540 0x0000ffff
9542 static const DWORD ps1_code[] =
9544 0xffff0101, /* ps_1_1 */
9545 0x00000051, 0xa00f0000, 0x3e800000, 0x3e800000, 0x3e800000, 0x3e800000, /* def c0, 0.25, 0.25, 0.25, 0.25 */
9546 0x00000002, 0x800f0000, 0x90e40000, 0x90e40001, /* add r0, v0, v1 */
9547 0x00000005, 0x800f0000, 0x80e40000, 0xa0e40000, /* mul r0, r0, c0 */
9548 0x0000ffff
9550 static const struct
9552 DWORD vs_version;
9553 const DWORD *vs;
9554 DWORD ps_version;
9555 const DWORD *ps;
9556 D3DCOLOR expected, broken;
9558 tests[] =
9560 {0, NULL, 0, NULL, 0x00404040},
9561 {0, NULL, D3DPS_VERSION(1, 1), ps1_code, 0x00404040, 0x00808080},
9562 {D3DVS_VERSION(1, 1), vs1_code, 0, NULL, 0x00404040},
9563 {D3DVS_VERSION(1, 1), vs1_code, D3DPS_VERSION(1, 1), ps1_code, 0x007f7f7f},
9565 IDirect3DDevice8 *device;
9566 IDirect3D8 *d3d;
9567 unsigned int i;
9568 ULONG refcount;
9569 D3DCOLOR color;
9570 D3DCAPS8 caps;
9571 DWORD vs, ps;
9572 HWND window;
9573 HRESULT hr;
9575 window = create_window();
9576 d3d = Direct3DCreate8(D3D_SDK_VERSION);
9577 ok(!!d3d, "Failed to create a D3D object.\n");
9578 if (!(device = create_device(d3d, window, window, TRUE)))
9580 skip("Failed to create a D3D device, skipping tests.\n");
9581 IDirect3D8_Release(d3d);
9582 DestroyWindow(window);
9583 return;
9586 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
9587 ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
9589 hr = IDirect3DDevice8_SetTransform(device, D3DTS_WORLD, &mat);
9590 ok(SUCCEEDED(hr), "Failed to set world transform, hr %#x.\n", hr);
9591 hr = IDirect3DDevice8_SetTransform(device, D3DTS_VIEW, &mat);
9592 ok(SUCCEEDED(hr), "Failed to set view transform, hr %#x.\n", hr);
9593 hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, &mat);
9594 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
9595 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, FALSE);
9596 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#x.\n", hr);
9597 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, FALSE);
9598 ok(SUCCEEDED(hr), "Failed to disable Z test, hr %#x.\n", hr);
9599 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
9600 ok(SUCCEEDED(hr), "Failed to disable fog, hr %#x.\n", hr);
9601 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
9602 ok(SUCCEEDED(hr), "Failed to disable stencil test, hr %#x.\n", hr);
9603 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
9604 ok(SUCCEEDED(hr), "Failed to disable culling, hr %#x.\n", hr);
9605 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9606 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
9608 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xff404040);
9609 ok(SUCCEEDED(hr), "Failed to set texture factor, hr %#x.\n", hr);
9610 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
9611 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
9612 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9613 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
9614 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_SPECULAR);
9615 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
9616 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_MODULATE);
9617 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
9618 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TFACTOR);
9619 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
9620 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
9621 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
9623 for (i = 0; i < ARRAY_SIZE(tests); ++i)
9625 if (caps.VertexShaderVersion < tests[i].vs_version
9626 || caps.PixelShaderVersion < tests[i].ps_version)
9628 skip("Vertex / pixel shader version not supported, skipping test %u.\n", i);
9629 continue;
9631 if (tests[i].vs)
9633 hr = IDirect3DDevice8_CreateVertexShader(device, decl, tests[i].vs, &vs, 0);
9634 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x (case %u).\n", hr, i);
9636 else
9638 vs = D3DFVF_XYZ;
9640 if (tests[i].ps)
9642 hr = IDirect3DDevice8_CreatePixelShader(device, tests[i].ps, &ps);
9643 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x (case %u).\n", hr, i);
9645 else
9647 ps = 0;
9650 hr = IDirect3DDevice8_SetVertexShader(device, vs);
9651 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
9652 hr = IDirect3DDevice8_SetPixelShader(device, ps);
9653 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
9655 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0f, 0);
9656 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
9658 hr = IDirect3DDevice8_BeginScene(device);
9659 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9661 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
9662 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9664 hr = IDirect3DDevice8_EndScene(device);
9665 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9667 color = getPixelColor(device, 320, 240);
9668 ok(color_match(color, tests[i].expected, 1) || broken(color_match(color, tests[i].broken, 1)),
9669 "Got unexpected color 0x%08x, case %u.\n", color, i);
9671 if (vs != D3DFVF_XYZ)
9672 IDirect3DDevice8_DeleteVertexShader(device, vs);
9673 if (ps)
9674 IDirect3DDevice8_DeletePixelShader(device, ps);
9677 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
9678 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
9680 refcount = IDirect3DDevice8_Release(device);
9681 ok(!refcount, "Device has %u references left.\n", refcount);
9682 IDirect3D8_Release(d3d);
9683 DestroyWindow(window);
9686 static void test_edge_antialiasing_blending(void)
9688 IDirect3DDevice8 *device;
9689 IDirect3D8 *d3d8;
9690 ULONG refcount;
9691 D3DCOLOR color;
9692 D3DCAPS8 caps;
9693 HWND window;
9694 HRESULT hr;
9696 static const struct
9698 struct vec3 position;
9699 DWORD diffuse;
9701 green_quad[] =
9703 {{-1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0x7f, 0x00, 0xff, 0x00)},
9704 {{-1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0x7f, 0x00, 0xff, 0x00)},
9705 {{ 1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0x7f, 0x00, 0xff, 0x00)},
9706 {{ 1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0x7f, 0x00, 0xff, 0x00)},
9708 static const struct
9710 struct vec3 position;
9711 DWORD diffuse;
9713 red_quad[] =
9715 {{-1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0xcc, 0xff, 0x00, 0x00)},
9716 {{-1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0xcc, 0xff, 0x00, 0x00)},
9717 {{ 1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0xcc, 0xff, 0x00, 0x00)},
9718 {{ 1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0xcc, 0xff, 0x00, 0x00)},
9721 window = create_window();
9722 d3d8 = Direct3DCreate8(D3D_SDK_VERSION);
9723 ok(!!d3d8, "Failed to create a D3D object.\n");
9724 if (!(device = create_device(d3d8, window, window, TRUE)))
9726 skip("Failed to create a D3D device.\n");
9727 IDirect3D8_Release(d3d8);
9728 DestroyWindow(window);
9729 return;
9732 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
9733 ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
9734 trace("Edge antialiasing support: %#x.\n", caps.RasterCaps & D3DPRASTERCAPS_ANTIALIASEDGES);
9736 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, FALSE);
9737 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#x.\n", hr);
9738 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, FALSE);
9739 ok(SUCCEEDED(hr), "Failed to disable Z test, hr %#x.\n", hr);
9740 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9741 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
9743 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
9744 ok(SUCCEEDED(hr), "Failed to enable blending, hr %#x.\n", hr);
9745 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_BLENDOP, D3DBLENDOP_ADD);
9746 ok(SUCCEEDED(hr), "Failed to set blend op, hr %#x.\n", hr);
9747 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
9748 ok(SUCCEEDED(hr), "Failed to set src blend, hr %#x.\n", hr);
9749 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_DESTALPHA);
9750 ok(SUCCEEDED(hr), "Failed to set dest blend, hr %#x.\n", hr);
9752 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9753 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
9754 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9755 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
9756 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
9757 ok(SUCCEEDED(hr), "Failed to set alpha op, hr %#x.\n", hr);
9758 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
9759 ok(SUCCEEDED(hr), "Failed to set alpha arg, hr %#x.\n", hr);
9761 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9762 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
9764 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xccff0000, 0.0f, 0);
9765 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
9766 hr = IDirect3DDevice8_BeginScene(device);
9767 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9768 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, green_quad, sizeof(*green_quad));
9769 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9770 hr = IDirect3DDevice8_EndScene(device);
9771 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9772 color = getPixelColor(device, 320, 240);
9773 ok(color_match(color, 0x00cc7f00, 1), "Got unexpected color 0x%08x.\n", color);
9775 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x7f00ff00, 0.0f, 0);
9776 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
9777 hr = IDirect3DDevice8_BeginScene(device);
9778 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9779 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, red_quad, sizeof(*red_quad));
9780 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9781 hr = IDirect3DDevice8_EndScene(device);
9782 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9783 color = getPixelColor(device, 320, 240);
9784 ok(color_match(color, 0x00cc7f00, 1), "Got unexpected color 0x%08x.\n", color);
9786 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
9787 ok(SUCCEEDED(hr), "Failed to disable blending, hr %#x.\n", hr);
9789 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xccff0000, 0.0f, 0);
9790 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
9791 hr = IDirect3DDevice8_BeginScene(device);
9792 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9793 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, green_quad, sizeof(*green_quad));
9794 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9795 hr = IDirect3DDevice8_EndScene(device);
9796 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9797 color = getPixelColor(device, 320, 240);
9798 ok(color_match(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
9800 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x7f00ff00, 0.0f, 0);
9801 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
9802 hr = IDirect3DDevice8_BeginScene(device);
9803 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9804 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, red_quad, sizeof(*red_quad));
9805 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9806 hr = IDirect3DDevice8_EndScene(device);
9807 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9808 color = getPixelColor(device, 320, 240);
9809 ok(color_match(color, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color);
9811 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_EDGEANTIALIAS, TRUE);
9812 ok(SUCCEEDED(hr), "Failed to enable edge antialiasing, hr %#x.\n", hr);
9814 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xccff0000, 0.0f, 0);
9815 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
9816 hr = IDirect3DDevice8_BeginScene(device);
9817 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9818 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, green_quad, sizeof(*green_quad));
9819 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9820 hr = IDirect3DDevice8_EndScene(device);
9821 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9822 color = getPixelColor(device, 320, 240);
9823 ok(color_match(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
9825 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x7f00ff00, 0.0f, 0);
9826 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
9827 hr = IDirect3DDevice8_BeginScene(device);
9828 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9829 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, red_quad, sizeof(*red_quad));
9830 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9831 hr = IDirect3DDevice8_EndScene(device);
9832 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9833 color = getPixelColor(device, 320, 240);
9834 ok(color_match(color, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color);
9836 refcount = IDirect3DDevice8_Release(device);
9837 ok(!refcount, "Device has %u references left.\n", refcount);
9838 IDirect3D8_Release(d3d8);
9839 DestroyWindow(window);
9842 /* This test shows that 0xffff is valid index in D3D8. */
9843 static void test_max_index16(void)
9845 static const struct vertex
9847 struct vec3 position;
9848 DWORD diffuse;
9850 green_quad[] =
9852 {{-1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
9853 {{-1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
9854 {{ 1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
9855 {{ 1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
9857 static const unsigned short indices[] = {0, 1, 2, 0xffff};
9858 static const unsigned int vertex_count = 0xffff + 1;
9860 D3DADAPTER_IDENTIFIER8 identifier;
9861 IDirect3DVertexBuffer8 *vb;
9862 IDirect3DIndexBuffer8 *ib;
9863 IDirect3DDevice8 *device;
9864 struct vertex *vb_data;
9865 IDirect3D8 *d3d8;
9866 ULONG refcount;
9867 D3DCOLOR color;
9868 D3DCAPS8 caps;
9869 HWND window;
9870 BYTE *data;
9871 HRESULT hr;
9872 BOOL warp;
9874 window = create_window();
9875 d3d8 = Direct3DCreate8(D3D_SDK_VERSION);
9876 ok(!!d3d8, "Failed to create a D3D object.\n");
9878 hr = IDirect3D8_GetAdapterIdentifier(d3d8, D3DADAPTER_DEFAULT, 0, &identifier);
9879 ok(SUCCEEDED(hr), "Failed to get adapter identifier, hr %#x.\n", hr);
9880 warp = adapter_is_warp(&identifier);
9882 if (!(device = create_device(d3d8, window, window, TRUE)))
9884 skip("Failed to create a D3D device.\n");
9885 IDirect3D8_Release(d3d8);
9886 DestroyWindow(window);
9887 return;
9890 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
9891 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
9892 if (caps.MaxVertexIndex < 0xffff)
9894 skip("Max vertex index is lower than 0xffff (%#x).\n", caps.MaxVertexIndex);
9895 IDirect3DDevice8_Release(device);
9896 IDirect3D8_Release(d3d8);
9897 DestroyWindow(window);
9898 return;
9901 hr = IDirect3DDevice8_CreateVertexBuffer(device, vertex_count * sizeof(*green_quad), 0,
9902 D3DFVF_XYZ | D3DFVF_DIFFUSE, D3DPOOL_MANAGED, &vb);
9903 ok(SUCCEEDED(hr), "Failed to create vertex buffer, hr %#x.\n", hr);
9905 hr = IDirect3DDevice8_CreateIndexBuffer(device, sizeof(indices), 0,
9906 D3DFMT_INDEX16, D3DPOOL_MANAGED, &ib);
9907 ok(SUCCEEDED(hr), "Failed to create index buffer, hr %#x.\n", hr);
9909 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, FALSE);
9910 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#x.\n", hr);
9911 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, FALSE);
9912 ok(SUCCEEDED(hr), "Failed to disable Z test, hr %#x.\n", hr);
9913 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9914 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
9916 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9917 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
9919 hr = IDirect3DVertexBuffer8_Lock(vb, 0, sizeof(green_quad), (BYTE **)&vb_data, 0);
9920 ok(hr == D3D_OK, "Failed to lock vertex buffer, hr %#x.\n", hr);
9921 vb_data[0] = green_quad[0];
9922 vb_data[1] = green_quad[1];
9923 vb_data[2] = green_quad[2];
9924 vb_data[0xffff] = green_quad[3];
9925 hr = IDirect3DVertexBuffer8_Unlock(vb);
9926 ok(hr == D3D_OK, "Failed to unlock vertex buffer, hr %#x.\n", hr);
9928 hr = IDirect3DIndexBuffer8_Lock(ib, 0, sizeof(indices), &data, 0);
9929 ok(hr == D3D_OK, "Failed to lock index buffer, hr %#x.\n", hr);
9930 memcpy(data, indices, sizeof(indices));
9931 hr = IDirect3DIndexBuffer8_Unlock(ib);
9932 ok(hr == D3D_OK, "Failed to unlock index buffer, hr %#x.\n", hr);
9934 hr = IDirect3DDevice8_SetIndices(device, ib, 0);
9935 ok(hr == D3D_OK, "Failed to set index buffer, hr %#x.\n", hr);
9936 hr = IDirect3DDevice8_SetStreamSource(device, 0, vb, sizeof(struct vertex));
9937 ok(hr == D3D_OK, "Failed to set stream source, hr %#x.\n", hr);
9939 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
9940 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
9941 hr = IDirect3DDevice8_BeginScene(device);
9942 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9943 hr = IDirect3DDevice8_DrawIndexedPrimitive(device, D3DPT_TRIANGLESTRIP, 0, vertex_count, 0, 2);
9944 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9945 hr = IDirect3DDevice8_EndScene(device);
9946 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9947 color = getPixelColor(device, 20, 20);
9948 ok(color_match(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
9949 color = getPixelColor(device, 320, 240);
9950 ok(color_match(color, 0x0000ff00, 1) || broken(warp), "Got unexpected color 0x%08x.\n", color);
9951 color = getPixelColor(device, 620, 460);
9952 ok(color_match(color, 0x0000ff00, 1) || broken(warp), "Got unexpected color 0x%08x.\n", color);
9954 IDirect3DIndexBuffer8_Release(ib);
9955 IDirect3DVertexBuffer8_Release(vb);
9956 refcount = IDirect3DDevice8_Release(device);
9957 ok(!refcount, "Device has %u references left.\n", refcount);
9958 IDirect3D8_Release(d3d8);
9959 DestroyWindow(window);
9962 static void test_backbuffer_resize(void)
9964 D3DPRESENT_PARAMETERS present_parameters = {0};
9965 IDirect3DSurface8 *backbuffer;
9966 IDirect3DDevice8 *device;
9967 IDirect3D8 *d3d;
9968 D3DCOLOR color;
9969 ULONG refcount;
9970 HWND window;
9971 HRESULT hr;
9973 static const struct
9975 struct vec3 position;
9976 DWORD diffuse;
9978 quad[] =
9980 {{-1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
9981 {{-1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
9982 {{ 1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
9983 {{ 1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
9986 window = create_window();
9987 d3d = Direct3DCreate8(D3D_SDK_VERSION);
9988 ok(!!d3d, "Failed to create a D3D object.\n");
9989 if (!(device = create_device(d3d, window, window, TRUE)))
9991 skip("Failed to create a D3D device.\n");
9992 goto done;
9995 /* Wine d3d8 implementation had a bug which was triggered by a
9996 * SetRenderTarget() call with an unreferenced surface. */
9997 hr = IDirect3DDevice8_GetBackBuffer(device, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9998 ok(SUCCEEDED(hr), "Failed to get backbuffer, hr %#x.\n", hr);
9999 refcount = IDirect3DSurface8_Release(backbuffer);
10000 ok(!refcount, "Surface has %u references left.\n", refcount);
10001 hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, NULL);
10002 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
10003 hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, NULL);
10004 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
10006 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 1.0f, 0);
10007 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
10008 color = getPixelColor(device, 1, 1);
10009 ok(color == 0x00ff0000, "Got unexpected color 0x%08x.\n", color);
10011 present_parameters.BackBufferWidth = 800;
10012 present_parameters.BackBufferHeight = 600;
10013 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
10014 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
10015 present_parameters.hDeviceWindow = NULL;
10016 present_parameters.Windowed = TRUE;
10017 present_parameters.EnableAutoDepthStencil = TRUE;
10018 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
10019 hr = IDirect3DDevice8_Reset(device, &present_parameters);
10020 ok(SUCCEEDED(hr), "Failed to reset, hr %#x.\n", hr);
10022 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, FALSE);
10023 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#x.\n", hr);
10024 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, FALSE);
10025 ok(SUCCEEDED(hr), "Failed to disable Z test, hr %#x.\n", hr);
10026 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10027 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
10028 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10029 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
10031 hr = IDirect3DDevice8_GetBackBuffer(device, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
10032 ok(SUCCEEDED(hr), "Failed to get backbuffer, hr %#x.\n", hr);
10033 hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, NULL);
10034 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
10035 IDirect3DSurface8_Release(backbuffer);
10037 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 1.0f, 0);
10038 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
10039 color = getPixelColor(device, 1, 1);
10040 ok(color == 0x00ffff00, "Got unexpected color 0x%08x.\n", color);
10041 color = getPixelColor(device, 700, 500);
10042 ok(color == 0x00ffff00, "Got unexpected color 0x%08x.\n", color);
10044 hr = IDirect3DDevice8_BeginScene(device);
10045 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
10046 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10047 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10048 hr = IDirect3DDevice8_EndScene(device);
10049 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
10050 color = getPixelColor(device, 1, 1);
10051 ok(color == 0x0000ff00, "Got unexpected color 0x%08x.\n", color);
10052 color = getPixelColor(device, 700, 500);
10053 ok(color == 0x0000ff00, "Got unexpected color 0x%08x.\n", color);
10055 refcount = IDirect3DDevice8_Release(device);
10056 ok(!refcount, "Device has %u references left.\n", refcount);
10057 done:
10058 IDirect3D8_Release(d3d);
10059 DestroyWindow(window);
10062 static void test_drawindexedprimitiveup(void)
10064 static const struct vertex
10066 struct vec3 position;
10067 DWORD diffuse;
10069 quad[] =
10071 {{-1.0f, -1.0f, 0.1f}, 0xff00ff00},
10072 {{-1.0f, 1.0f, 0.1f}, 0xff0000ff},
10073 {{ 1.0f, -1.0f, 0.1f}, 0xffff0000},
10074 {{ 1.0f, 1.0f, 0.1f}, 0xff0000ff},
10076 {{-1.0f, -1.0f, 0.1f}, 0xff0000ff},
10077 {{-1.0f, 1.0f, 0.1f}, 0xff00ff00},
10078 {{ 1.0f, -1.0f, 0.1f}, 0xffff0000},
10079 {{ 1.0f, 1.0f, 0.1f}, 0xff00ff00},
10081 static const unsigned short indices[] = {0, 1, 2, 3, 4, 5, 6, 7};
10082 IDirect3DDevice8 *device;
10083 IDirect3D8 *d3d;
10084 ULONG refcount;
10085 D3DCOLOR color;
10086 HWND window;
10087 HRESULT hr;
10089 window = create_window();
10090 d3d = Direct3DCreate8(D3D_SDK_VERSION);
10091 ok(!!d3d, "Failed to create a D3D object.\n");
10093 if (!(device = create_device(d3d, window, window, TRUE)))
10095 skip("Failed to create a D3D device.\n");
10096 IDirect3D8_Release(d3d);
10097 DestroyWindow(window);
10098 return;
10101 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, FALSE);
10102 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#x.\n", hr);
10103 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, FALSE);
10104 ok(SUCCEEDED(hr), "Failed to disable Z test, hr %#x.\n", hr);
10105 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10106 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
10108 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
10109 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
10110 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
10111 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
10112 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
10113 ok(SUCCEEDED(hr), "Failed to set alpha op, hr %#x.\n", hr);
10114 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
10115 ok(SUCCEEDED(hr), "Failed to set alpha arg, hr %#x.\n", hr);
10117 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10118 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
10120 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
10121 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
10123 hr = IDirect3DDevice8_BeginScene(device);
10124 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
10125 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 4, 4, 2, indices + 4, D3DFMT_INDEX16, quad, sizeof(*quad));
10126 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10127 hr = IDirect3DDevice8_EndScene(device);
10128 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
10130 color = getPixelColor(device, 160, 120);
10131 ok(color_match(color, 0x0040bf00, 1), "Got unexpected color 0x%08x.\n", color);
10132 color = getPixelColor(device, 480, 120);
10133 ok(color_match(color, 0x0040bf00, 1), "Got unexpected color 0x%08x.\n", color);
10134 color = getPixelColor(device, 160, 360);
10135 ok(color_match(color, 0x00404080, 1), "Got unexpected color 0x%08x.\n", color);
10136 color = getPixelColor(device, 480, 360);
10137 ok(color_match(color, 0x00bf4000, 1), "Got unexpected color 0x%08x.\n", color);
10139 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
10140 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
10142 hr = IDirect3DDevice8_BeginScene(device);
10143 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
10144 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 0, 4, 2, indices, D3DFMT_INDEX16, quad, sizeof(*quad));
10145 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10146 hr = IDirect3DDevice8_EndScene(device);
10147 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
10149 color = getPixelColor(device, 160, 120);
10150 ok(color_match(color, 0x004000bf, 1), "Got unexpected color 0x%08x.\n", color);
10151 color = getPixelColor(device, 480, 120);
10152 ok(color_match(color, 0x004000bf, 1), "Got unexpected color 0x%08x.\n", color);
10153 color = getPixelColor(device, 160, 360);
10154 ok(color_match(color, 0x00408040, 1), "Got unexpected color 0x%08x.\n", color);
10155 color = getPixelColor(device, 480, 360);
10156 ok(color_match(color, 0x00bf0040, 1), "Got unexpected color 0x%08x.\n", color);
10158 refcount = IDirect3DDevice8_Release(device);
10159 ok(!refcount, "Device has %u references left.\n", refcount);
10160 IDirect3D8_Release(d3d);
10161 DestroyWindow(window);
10164 static void test_map_synchronisation(void)
10166 LARGE_INTEGER frequency, diff, ts[3];
10167 unsigned int i, j, tri_count, size;
10168 D3DADAPTER_IDENTIFIER8 identifier;
10169 IDirect3DVertexBuffer8 *buffer;
10170 IDirect3DDevice8 *device;
10171 BOOL unsynchronised, ret;
10172 IDirect3D8 *d3d;
10173 D3DCOLOR colour;
10174 ULONG refcount;
10175 D3DCAPS8 caps;
10176 HWND window;
10177 HRESULT hr;
10179 static const struct
10181 unsigned int flags;
10182 BOOL unsynchronised;
10184 tests[] =
10186 {0, FALSE},
10187 {D3DLOCK_NOOVERWRITE, TRUE},
10188 {D3DLOCK_DISCARD, FALSE},
10189 {D3DLOCK_NOOVERWRITE | D3DLOCK_DISCARD, TRUE},
10192 static const struct quad
10194 struct
10196 struct vec3 position;
10197 DWORD diffuse;
10198 } strip[4];
10200 quad1 =
10203 {{-1.0f, -1.0f, 0.0f}, 0xffff0000},
10204 {{-1.0f, 1.0f, 0.0f}, 0xff00ff00},
10205 {{ 1.0f, -1.0f, 0.0f}, 0xff0000ff},
10206 {{ 1.0f, 1.0f, 0.0f}, 0xffffffff},
10209 quad2 =
10212 {{-1.0f, -1.0f, 0.0f}, 0xffffff00},
10213 {{-1.0f, 1.0f, 0.0f}, 0xffffff00},
10214 {{ 1.0f, -1.0f, 0.0f}, 0xffffff00},
10215 {{ 1.0f, 1.0f, 0.0f}, 0xffffff00},
10218 struct quad *quads;
10220 window = create_window();
10221 ok(!!window, "Failed to create a window.\n");
10223 d3d = Direct3DCreate8(D3D_SDK_VERSION);
10224 ok(!!d3d, "Failed to create a D3D object.\n");
10225 if (!(device = create_device(d3d, window, window, TRUE)))
10227 skip("Failed to create a D3D device, skipping tests.\n");
10228 IDirect3D8_Release(d3d);
10229 DestroyWindow(window);
10230 return;
10233 hr = IDirect3D8_GetAdapterIdentifier(d3d, D3DADAPTER_DEFAULT, 0, &identifier);
10234 ok(SUCCEEDED(hr), "Failed to get adapter identifier, hr %#x.\n", hr);
10235 /* Maps are always synchronised on WARP. */
10236 if (adapter_is_warp(&identifier))
10238 skip("Running on WARP, skipping test.\n");
10239 goto done;
10242 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
10243 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
10245 tri_count = 0x1000;
10246 if (tri_count > caps.MaxPrimitiveCount)
10248 skip("Device supports only %u primitives, skipping test.\n", caps.MaxPrimitiveCount);
10249 goto done;
10251 size = (tri_count + 2) * sizeof(*quad1.strip);
10253 ret = QueryPerformanceFrequency(&frequency);
10254 ok(ret, "Failed to get performance counter frequency.\n");
10256 hr = IDirect3DDevice8_CreateVertexBuffer(device, size,
10257 D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, 0, D3DPOOL_DEFAULT, &buffer);
10258 ok(SUCCEEDED(hr), "Failed to create vertex buffer, hr %#x.\n", hr);
10259 hr = IDirect3DVertexBuffer8_Lock(buffer, 0, size, (BYTE **)&quads, D3DLOCK_DISCARD);
10260 ok(SUCCEEDED(hr), "Failed to lock vertex buffer, hr %#x.\n", hr);
10261 for (j = 0; j < size / sizeof(*quads); ++j)
10263 quads[j] = quad1;
10265 hr = IDirect3DVertexBuffer8_Unlock(buffer);
10266 ok(SUCCEEDED(hr), "Failed to unlock vertex buffer, hr %#x.\n", hr);
10268 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10269 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10270 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10271 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
10272 hr = IDirect3DDevice8_SetStreamSource(device, 0, buffer, sizeof(*quads->strip));
10273 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
10275 /* Initial draw to initialise states, compile shaders, etc. */
10276 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0f, 0);
10277 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
10278 hr = IDirect3DDevice8_BeginScene(device);
10279 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
10280 hr = IDirect3DDevice8_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, tri_count);
10281 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10282 hr = IDirect3DDevice8_EndScene(device);
10283 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
10284 /* Read the result to ensure the GPU has finished drawing. */
10285 colour = getPixelColor(device, 320, 240);
10287 /* Time drawing tri_count triangles. */
10288 ret = QueryPerformanceCounter(&ts[0]);
10289 ok(ret, "Failed to read performance counter.\n");
10290 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0f, 0);
10291 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
10292 hr = IDirect3DDevice8_BeginScene(device);
10293 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
10294 hr = IDirect3DDevice8_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, tri_count);
10295 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10296 hr = IDirect3DDevice8_EndScene(device);
10297 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
10298 colour = getPixelColor(device, 320, 240);
10299 /* Time drawing a single triangle. */
10300 ret = QueryPerformanceCounter(&ts[1]);
10301 ok(ret, "Failed to read performance counter.\n");
10302 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0f, 0);
10303 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
10304 hr = IDirect3DDevice8_BeginScene(device);
10305 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
10306 hr = IDirect3DDevice8_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 1);
10307 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10308 hr = IDirect3DDevice8_EndScene(device);
10309 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
10310 colour = getPixelColor(device, 320, 240);
10311 ret = QueryPerformanceCounter(&ts[2]);
10312 ok(ret, "Failed to read performance counter.\n");
10314 IDirect3DVertexBuffer8_Release(buffer);
10316 /* Estimate the number of triangles we can draw in 100ms. */
10317 diff.QuadPart = ts[1].QuadPart - ts[0].QuadPart + ts[1].QuadPart - ts[2].QuadPart;
10318 tri_count = (tri_count * frequency.QuadPart) / (diff.QuadPart * 10);
10319 tri_count = ((tri_count + 2 + 3) & ~3) - 2;
10320 if (tri_count > caps.MaxPrimitiveCount)
10322 skip("Would need to draw %u triangles, but the device only supports %u primitives.\n",
10323 tri_count, caps.MaxPrimitiveCount);
10324 goto done;
10326 size = (tri_count + 2) * sizeof(*quad1.strip);
10328 for (i = 0; i < ARRAY_SIZE(tests); ++i)
10330 hr = IDirect3DDevice8_CreateVertexBuffer(device, size,
10331 D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, 0, D3DPOOL_DEFAULT, &buffer);
10332 ok(SUCCEEDED(hr), "Failed to create vertex buffer, hr %#x.\n", hr);
10333 hr = IDirect3DVertexBuffer8_Lock(buffer, 0, size, (BYTE **)&quads, D3DLOCK_DISCARD);
10334 ok(SUCCEEDED(hr), "Failed to lock vertex buffer, hr %#x.\n", hr);
10335 for (j = 0; j < size / sizeof(*quads); ++j)
10337 quads[j] = quad1;
10339 hr = IDirect3DVertexBuffer8_Unlock(buffer);
10340 ok(SUCCEEDED(hr), "Failed to unlock vertex buffer, hr %#x.\n", hr);
10342 hr = IDirect3DDevice8_SetStreamSource(device, 0, buffer, sizeof(*quads->strip));
10343 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
10345 /* Start a draw operation. */
10346 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0f, 0);
10347 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
10348 hr = IDirect3DDevice8_BeginScene(device);
10349 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
10350 hr = IDirect3DDevice8_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, tri_count);
10351 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10352 hr = IDirect3DDevice8_EndScene(device);
10353 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
10355 /* Map the last quad while the draw is in progress. */
10356 hr = IDirect3DVertexBuffer8_Lock(buffer, size - sizeof(quad2),
10357 sizeof(quad2), (BYTE **)&quads, tests[i].flags);
10358 ok(SUCCEEDED(hr), "Failed to lock vertex buffer, hr %#x.\n", hr);
10359 *quads = quad2;
10360 hr = IDirect3DVertexBuffer8_Unlock(buffer);
10361 ok(SUCCEEDED(hr), "Failed to unlock vertex buffer, hr %#x.\n", hr);
10363 colour = getPixelColor(device, 320, 240);
10364 unsynchronised = color_match(colour, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 1);
10365 ok(tests[i].unsynchronised == unsynchronised, "Expected %s map for flags %#x.\n",
10366 tests[i].unsynchronised ? "unsynchronised" : "synchronised", tests[i].flags);
10368 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
10369 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
10371 IDirect3DVertexBuffer8_Release(buffer);
10374 done:
10375 refcount = IDirect3DDevice8_Release(device);
10376 ok(!refcount, "Device has %u references left.\n", refcount);
10377 IDirect3D8_Release(d3d);
10378 DestroyWindow(window);
10381 static void test_viewport(void)
10383 static const struct
10385 D3DVIEWPORT8 vp;
10386 RECT expected_rect;
10387 const char *message;
10389 tests[] =
10391 {{ 0, 0, 640, 480}, { 0, 120, 479, 359}, "Viewport (0, 0) - (640, 480)"},
10392 {{ 0, 0, 320, 240}, { 0, 60, 239, 179}, "Viewport (0, 0) - (320, 240)"},
10393 {{ 0, 0, 1280, 960}, { 0, 240, 639, 479}, "Viewport (0, 0) - (1280, 960)"},
10394 {{ 0, 0, 2000, 1600}, {-10, -10, -10, -10}, "Viewport (0, 0) - (2000, 1600)"},
10395 {{100, 100, 640, 480}, {100, 220, 579, 459}, "Viewport (100, 100) - (640, 480)"},
10396 {{ 0, 0, 8192, 8192}, {-10, -10, -10, -10}, "Viewport (0, 0) - (8192, 8192)"},
10398 static const struct vec3 quad[] =
10400 {-1.5f, -0.5f, 0.1f},
10401 {-1.5f, 0.5f, 0.1f},
10402 { 0.5f, -0.5f, 0.1f},
10403 { 0.5f, 0.5f, 0.1f},
10405 static const struct vec2 rt_sizes[] =
10407 {640, 480}, {1280, 960}, {320, 240}, {800, 600},
10409 struct surface_readback rb;
10410 IDirect3DDevice8 *device;
10411 IDirect3DSurface8 *rt;
10412 unsigned int i, j;
10413 IDirect3D8 *d3d;
10414 ULONG refcount;
10415 HWND window;
10416 HRESULT hr;
10418 window = create_window();
10419 d3d = Direct3DCreate8(D3D_SDK_VERSION);
10420 ok(!!d3d, "Failed to create a D3D object.\n");
10421 if (!(device = create_device(d3d, window, window, TRUE)))
10423 skip("Failed to create a D3D device, skipping tests.\n");
10424 goto done;
10427 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
10428 ok(SUCCEEDED(hr), "Failed to disable depth test, hr %#x.\n", hr);
10429 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10430 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
10432 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ);
10433 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
10435 /* This crashes on Windows. */
10436 /* hr = IDirect3DDevice8_SetViewport(device, NULL); */
10438 for (i = 0; i < ARRAY_SIZE(rt_sizes); ++i)
10440 if (i)
10442 hr = IDirect3DDevice8_CreateRenderTarget(device, rt_sizes[i].x, rt_sizes[i].y,
10443 D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, TRUE, &rt);
10444 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x (i %u).\n", hr, i);
10445 hr = IDirect3DDevice8_SetRenderTarget(device, rt, NULL);
10446 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x (i %u).\n", hr, i);
10448 else
10450 hr = IDirect3DDevice8_GetBackBuffer(device, 0, D3DBACKBUFFER_TYPE_MONO, &rt);
10451 ok(SUCCEEDED(hr), "Failed to get backbuffer, hr %#x.\n", hr);
10454 for (j = 0; j < ARRAY_SIZE(tests); ++j)
10456 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 1.0f, 0);
10457 ok(SUCCEEDED(hr), "Failed to clear, hr %#x (i %u, j %u).\n", hr, i, j);
10459 hr = IDirect3DDevice8_SetViewport(device, &tests[j].vp);
10460 if (tests[j].vp.X + tests[j].vp.Width > rt_sizes[i].x
10461 || tests[j].vp.Y + tests[j].vp.Height > rt_sizes[i].y)
10463 ok(hr == D3DERR_INVALIDCALL,
10464 "Setting the viewport returned unexpected hr %#x (i %u, j %u).\n", hr, i, j);
10465 continue;
10467 else
10469 ok(SUCCEEDED(hr), "Failed to set the viewport, hr %#x (i %u, j %u).\n", hr, i, j);
10472 hr = IDirect3DDevice8_BeginScene(device);
10473 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x (i %u, j %u).\n", hr, i, j);
10474 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
10475 ok(SUCCEEDED(hr), "Got unexpected hr %#x (i %u, j %u).\n", hr, i, j);
10476 hr = IDirect3DDevice8_EndScene(device);
10477 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x (i %u, j %u).\n", hr, i, j);
10479 get_rt_readback(rt, &rb);
10480 check_rect(&rb, tests[j].expected_rect, tests[j].message);
10481 release_surface_readback(&rb);
10484 IDirect3DSurface8_Release(rt);
10487 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
10488 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
10490 refcount = IDirect3DDevice8_Release(device);
10491 ok(!refcount, "Device has %u references left.\n", refcount);
10492 done:
10493 IDirect3D8_Release(d3d);
10494 DestroyWindow(window);
10497 static void test_color_vertex(void)
10499 IDirect3DDevice8 *device;
10500 D3DMATERIAL8 material;
10501 IDirect3D8 *d3d;
10502 D3DCOLOR colour;
10503 unsigned int i;
10504 ULONG refcount;
10505 HWND window;
10506 HRESULT hr;
10508 /* The idea here is to set up ambient light parameters in a way that the
10509 * ambient colour from the material is just passed through. The emissive
10510 * colour is just passed through anyway. The sum of ambient + emissive
10511 * should allow deduction of where the material colour came from.
10513 * Note that in cases without a D3DFVF_DIFFUSE flag the first colour value
10514 * in the struct will be fed into the specular vertex colour slot. */
10515 static const struct
10517 DWORD fvf, color_vertex, ambient, emissive, result;
10519 tests[] =
10521 {D3DFVF_DIFFUSE | D3DFVF_SPECULAR, FALSE, D3DMCS_COLOR1, D3DMCS_COLOR2, 0x000000c0},
10523 {D3DFVF_DIFFUSE | D3DFVF_SPECULAR, TRUE, D3DMCS_COLOR1, D3DMCS_COLOR2, 0x00ffff00},
10524 {D3DFVF_DIFFUSE | D3DFVF_SPECULAR, TRUE, D3DMCS_MATERIAL, D3DMCS_COLOR2, 0x0000ff80},
10525 {D3DFVF_DIFFUSE | D3DFVF_SPECULAR, TRUE, D3DMCS_COLOR1, D3DMCS_MATERIAL, 0x00ff0040},
10526 {D3DFVF_DIFFUSE | D3DFVF_SPECULAR, TRUE, D3DMCS_COLOR1, D3DMCS_COLOR1, 0x00ff0000},
10527 {D3DFVF_DIFFUSE | D3DFVF_SPECULAR, TRUE, D3DMCS_COLOR2, D3DMCS_COLOR2, 0x0000ff00},
10529 {D3DFVF_SPECULAR, TRUE, D3DMCS_COLOR1, D3DMCS_COLOR2, 0x00ff0080},
10530 {D3DFVF_SPECULAR, TRUE, D3DMCS_COLOR1, D3DMCS_MATERIAL, 0x000000c0},
10531 {D3DFVF_SPECULAR, TRUE, D3DMCS_MATERIAL, D3DMCS_COLOR2, 0x00ff0080},
10532 {D3DFVF_DIFFUSE, TRUE, D3DMCS_COLOR1, D3DMCS_COLOR2, 0x00ff0040},
10533 {D3DFVF_DIFFUSE, TRUE, D3DMCS_COLOR1, D3DMCS_MATERIAL, 0x00ff0040},
10534 {D3DFVF_DIFFUSE, TRUE, D3DMCS_COLOR2, D3DMCS_MATERIAL, 0x000000c0},
10536 {0, TRUE, D3DMCS_COLOR1, D3DMCS_COLOR2, 0x000000c0},
10538 static const struct
10540 struct vec3 position;
10541 DWORD diffuse;
10542 DWORD specular;
10544 quad[] =
10546 {{-1.0f, -1.0f, 0.0f}, 0xffff0000, 0xff00ff00},
10547 {{-1.0f, 1.0f, 0.0f}, 0xffff0000, 0xff00ff00},
10548 {{ 1.0f, -1.0f, 0.0f}, 0xffff0000, 0xff00ff00},
10549 {{ 1.0f, 1.0f, 0.0f}, 0xffff0000, 0xff00ff00},
10552 window = create_window();
10553 ok(!!window, "Failed to create a window.\n");
10555 d3d = Direct3DCreate8(D3D_SDK_VERSION);
10556 ok(!!d3d, "Failed to create a D3D object.\n");
10557 if (!(device = create_device(d3d, window, window, TRUE)))
10559 skip("Failed to create a D3D device, skipping tests.\n");
10560 IDirect3D8_Release(d3d);
10561 DestroyWindow(window);
10562 return;
10565 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, TRUE);
10566 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10567 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_AMBIENT, 0xffffffff);
10568 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10570 memset(&material, 0, sizeof(material));
10571 material.Ambient.b = 0.5f;
10572 material.Emissive.b = 0.25f;
10573 hr = IDirect3DDevice8_SetMaterial(device, &material);
10574 ok(SUCCEEDED(hr), "Failed to set material, hr %#x\n", hr);
10576 for (i = 0; i < ARRAY_SIZE(tests); ++i)
10578 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_COLORVERTEX, tests[i].color_vertex);
10579 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10580 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_AMBIENTMATERIALSOURCE, tests[i].ambient);
10581 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10582 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_EMISSIVEMATERIALSOURCE, tests[i].emissive);
10583 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10584 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | tests[i].fvf);
10585 ok(SUCCEEDED(hr), "Failed to set vertex format, hr %#x.\n", hr);
10587 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x77777777, 0.0f, 0);
10588 ok(SUCCEEDED(hr), "Failed to clear depth/stencil, hr %#x.\n", hr);
10590 hr = IDirect3DDevice8_BeginScene(device);
10591 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
10592 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10593 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10594 hr = IDirect3DDevice8_EndScene(device);
10595 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
10597 colour = getPixelColor(device, 320, 240);
10598 ok(color_match(colour, tests[i].result, 1),
10599 "Expected colour 0x%08x for test %u, got 0x%08x.\n",
10600 tests[i].result, i, colour);
10603 refcount = IDirect3DDevice8_Release(device);
10604 ok(!refcount, "Device has %u references left.\n", refcount);
10605 IDirect3D8_Release(d3d);
10606 DestroyWindow(window);
10609 static void test_sysmem_draw(void)
10611 IDirect3DVertexBuffer8 *vb, *vb_s0, *vb_s1, *dst_vb, *get_vb;
10612 D3DPRESENT_PARAMETERS present_parameters = {0};
10613 IDirect3DTexture8 *texture;
10614 IDirect3DIndexBuffer8 *ib;
10615 IDirect3DDevice8 *device;
10616 unsigned int i, stride;
10617 struct vec4 *dst_data;
10618 D3DLOCKED_RECT lr;
10619 IDirect3D8 *d3d;
10620 D3DCOLOR colour;
10621 ULONG refcount;
10622 HWND window;
10623 HRESULT hr;
10624 BYTE *data;
10625 DWORD vs;
10627 static const DWORD texture_data[4] = {0xffff0000, 0xff00ff00, 0xff0000ff, 0xffffffff};
10628 static const DWORD decl[] =
10630 D3DVSD_STREAM(0),
10631 D3DVSD_REG(D3DVSDE_POSITION, D3DVSDT_FLOAT3),
10632 D3DVSD_STREAM(1),
10633 D3DVSD_REG(D3DVSDE_DIFFUSE, D3DVSDT_D3DCOLOR),
10634 D3DVSD_END()
10636 static const struct
10638 struct vec3 position;
10639 DWORD diffuse;
10641 quad[] =
10643 {{-0.5f, -0.5f, 0.0f}, 0xffff0000},
10644 {{-0.5f, 0.5f, 0.0f}, 0xff00ff00},
10645 {{ 0.5f, -0.5f, 0.0f}, 0xff0000ff},
10646 {{ 0.5f, 0.5f, 0.0f}, 0xffffffff},
10648 static const struct vec3 quad_s0[] =
10650 {-1.0f, -1.0f, 0.0f},
10651 {-1.0f, 1.0f, 0.0f},
10652 { 1.0f, -1.0f, 0.0f},
10653 { 1.0f, 1.0f, 0.0f},
10655 {-1.0f, -1.0f, 0.0f},
10656 {-1.0f, 1.0f, 0.0f},
10657 { 1.0f, -1.0f, 0.0f},
10658 { 1.0f, 1.0f, 0.0f},
10660 static const DWORD quad_s1[] =
10662 0xffff0000,
10663 0xff00ff00,
10664 0xff0000ff,
10665 0xffffffff,
10667 0xff443322,
10668 0xff443322,
10669 0xff443322,
10670 0xff443322,
10672 static const short indices[] = {0, 1, 2, 3};
10674 window = create_window();
10675 ok(!!window, "Failed to create a window.\n");
10677 d3d = Direct3DCreate8(D3D_SDK_VERSION);
10678 ok(!!d3d, "Failed to create a D3D object.\n");
10680 present_parameters.BackBufferWidth = 640;
10681 present_parameters.BackBufferHeight = 480;
10682 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
10683 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
10684 present_parameters.hDeviceWindow = window;
10685 present_parameters.Windowed = TRUE;
10686 present_parameters.EnableAutoDepthStencil = TRUE;
10687 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
10688 if (FAILED(hr = IDirect3D8_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
10689 window, D3DCREATE_MIXED_VERTEXPROCESSING, &present_parameters, &device)))
10691 skip("Failed to create a D3D device, skipping tests.\n");
10692 IDirect3D8_Release(d3d);
10693 DestroyWindow(window);
10694 return;
10697 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10698 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10700 hr = IDirect3DDevice8_CreateVertexBuffer(device, sizeof(quad), 0, 0, D3DPOOL_SYSTEMMEM, &vb);
10701 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10702 hr = IDirect3DVertexBuffer8_Lock(vb, 0, sizeof(quad), &data, 0);
10703 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10704 memcpy(data, quad, sizeof(quad));
10705 hr = IDirect3DVertexBuffer8_Unlock(vb);
10706 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10708 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x77777777, 0.0f, 0);
10709 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10711 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10712 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10713 hr = IDirect3DDevice8_SetStreamSource(device, 0, vb, sizeof(*quad));
10714 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10716 hr = IDirect3DDevice8_BeginScene(device);
10717 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10718 hr = IDirect3DDevice8_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
10719 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10720 hr = IDirect3DDevice8_EndScene(device);
10721 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10723 colour = getPixelColor(device, 320, 240);
10724 ok(color_match(colour, 0x00007f7f, 1), "Got unexpected colour 0x%08x.\n", colour);
10726 hr = IDirect3DDevice8_CreateVertexBuffer(device, ARRAY_SIZE(quad) * sizeof(*dst_data),
10727 0, D3DFVF_XYZRHW, D3DPOOL_SYSTEMMEM, &dst_vb);
10728 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10729 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SOFTWAREVERTEXPROCESSING, TRUE);
10730 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10731 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10732 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10733 hr = IDirect3DDevice8_SetStreamSource(device, 0, vb, sizeof(*quad));
10734 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10736 hr = IDirect3DDevice8_ProcessVertices(device, 0, 0, ARRAY_SIZE(quad), dst_vb, 0);
10737 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10738 hr = IDirect3DVertexBuffer8_Lock(dst_vb, 0, 0, (BYTE **)&dst_data, 0);
10739 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10740 for (i = 0; i < ARRAY_SIZE(quad); ++i)
10742 ok(compare_vec4(&dst_data[i], quad[i].position.x * 320.0f + 320.0f,
10743 -quad[i].position.y * 240.0f + 240.0f, 0.0f, 1.0f, 4),
10744 "Got unexpected vertex %u {%.8e, %.8e, %.8e, %.8e}.\n",
10745 i, dst_data[i].x, dst_data[i].y, dst_data[i].z, dst_data[i].w);
10747 hr = IDirect3DVertexBuffer8_Unlock(dst_vb);
10748 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10750 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SOFTWAREVERTEXPROCESSING, FALSE);
10751 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10752 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10753 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10754 hr = IDirect3DDevice8_SetStreamSource(device, 0, vb, sizeof(*quad));
10755 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10757 hr = IDirect3DDevice8_CreateIndexBuffer(device, sizeof(indices), 0,
10758 D3DFMT_INDEX16, D3DPOOL_SYSTEMMEM, &ib);
10759 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10760 hr = IDirect3DIndexBuffer8_Lock(ib, 0, sizeof(indices), &data, 0);
10761 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10762 memcpy(data, indices, sizeof(indices));
10763 hr = IDirect3DIndexBuffer8_Unlock(ib);
10764 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10766 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x77777777, 0.0f, 0);
10767 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10769 hr = IDirect3DDevice8_SetIndices(device, ib, 0);
10770 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10772 hr = IDirect3DDevice8_BeginScene(device);
10773 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10774 hr = IDirect3DDevice8_DrawIndexedPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 4, 0, 2);
10775 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10776 hr = IDirect3DDevice8_EndScene(device);
10777 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10779 colour = getPixelColor(device, 320, 240);
10780 ok(color_match(colour, 0x00007f7f, 1), "Got unexpected colour 0x%08x.\n", colour);
10782 hr = IDirect3DDevice8_CreateVertexShader(device, decl, NULL, &vs, 0);
10783 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10784 hr = IDirect3DDevice8_SetVertexShader(device, vs);
10785 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10787 hr = IDirect3DDevice8_CreateVertexBuffer(device, sizeof(quad_s0), 0, 0, D3DPOOL_SYSTEMMEM, &vb_s0);
10788 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10789 hr = IDirect3DVertexBuffer8_Lock(vb_s0, 0, sizeof(quad_s0), &data, 0);
10790 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10791 memcpy(data, quad_s0, sizeof(quad_s0));
10792 hr = IDirect3DVertexBuffer8_Unlock(vb_s0);
10793 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10794 hr = IDirect3DDevice8_CreateVertexBuffer(device, sizeof(quad_s1), 0, 0, D3DPOOL_SYSTEMMEM, &vb_s1);
10795 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10796 hr = IDirect3DVertexBuffer8_Lock(vb_s1, 0, sizeof(quad_s1), &data, 0);
10797 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10798 memcpy(data, quad_s1, sizeof(quad_s1));
10799 hr = IDirect3DVertexBuffer8_Unlock(vb_s1);
10800 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10802 hr = IDirect3DDevice8_SetStreamSource(device, 0, vb_s0, sizeof(*quad_s0));
10803 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10804 hr = IDirect3DDevice8_SetStreamSource(device, 1, vb_s1, sizeof(*quad_s1));
10805 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10807 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x77777777, 0.0f, 0);
10808 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10810 hr = IDirect3DDevice8_BeginScene(device);
10811 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10812 hr = IDirect3DDevice8_DrawIndexedPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 4, 0, 2);
10813 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10814 hr = IDirect3DDevice8_EndScene(device);
10815 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10817 colour = getPixelColor(device, 320, 240);
10818 ok(color_match(colour, 0x00007f7f, 1), "Got unexpected colour 0x%08x.\n", colour);
10820 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x77777777, 0.0f, 0);
10821 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10823 hr = IDirect3DDevice8_SetIndices(device, ib, 4);
10824 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10826 hr = IDirect3DDevice8_BeginScene(device);
10827 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10828 hr = IDirect3DDevice8_DrawIndexedPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 5, 0, 2);
10829 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10830 hr = IDirect3DDevice8_EndScene(device);
10831 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10833 colour = getPixelColor(device, 320, 240);
10834 ok(color_match(colour, 0x00443322, 1), "Got unexpected colour 0x%08x.\n", colour);
10836 /* Test that releasing but not unbinding a vertex buffer doesn't break. */
10837 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10838 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10839 hr = IDirect3DDevice8_SetStreamSource(device, 0, vb, sizeof(*quad));
10840 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10841 hr = IDirect3DDevice8_SetIndices(device, ib, 0);
10842 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10844 refcount = IDirect3DVertexBuffer8_Release(vb_s1);
10845 ok(!refcount, "Unexpected refcount %u.\n", refcount);
10846 hr = IDirect3DDevice8_GetStreamSource(device, 1, &get_vb, &stride);
10847 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
10848 ok(get_vb == vb_s1, "Got unexpected vertex buffer %p.\n", get_vb);
10849 refcount = IDirect3DVertexBuffer8_Release(get_vb);
10850 ok(!refcount, "Unexpected refcount %u.\n", refcount);
10852 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x77777777, 0.0f, 0);
10853 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10855 hr = IDirect3DDevice8_BeginScene(device);
10856 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10857 hr = IDirect3DDevice8_DrawIndexedPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 4, 0, 2);
10858 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10859 hr = IDirect3DDevice8_EndScene(device);
10860 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10862 colour = getPixelColor(device, 320, 240);
10863 ok(color_match(colour, 0x00007f7f, 1), "Got unexpected colour 0x%08x.\n", colour);
10865 hr = IDirect3DDevice8_SetVertexShader(device, vs);
10866 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10867 hr = IDirect3DDevice8_SetStreamSource(device, 0, vb_s0, sizeof(*quad_s0));
10868 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10870 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x77777777, 0.0f, 0);
10871 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10873 hr = IDirect3DDevice8_BeginScene(device);
10874 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10875 hr = IDirect3DDevice8_DrawIndexedPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 4, 0, 2);
10876 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10877 hr = IDirect3DDevice8_EndScene(device);
10878 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10880 colour = getPixelColor(device, 320, 240);
10881 ok(color_match(colour, 0x00007f7f, 1), "Got unexpected colour 0x%08x.\n", colour);
10883 hr = IDirect3DDevice8_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &texture);
10884 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10885 memset(&lr, 0, sizeof(lr));
10886 hr = IDirect3DTexture8_LockRect(texture, 0, &lr, NULL, 0);
10887 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10888 memcpy(lr.pBits, texture_data, sizeof(texture_data));
10889 hr = IDirect3DTexture8_UnlockRect(texture, 0);
10890 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10892 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
10893 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10895 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x77777777, 0.0f, 0);
10896 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10898 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ);
10899 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10901 hr = IDirect3DDevice8_BeginScene(device);
10902 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10903 hr = IDirect3DDevice8_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
10904 ok(hr == D3D_OK || hr == E_FAIL, "Got unexpected hr %#x.\n", hr);
10905 hr = IDirect3DDevice8_EndScene(device);
10906 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10908 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
10909 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10911 IDirect3DTexture8_Release(texture);
10912 IDirect3DVertexBuffer8_Release(vb_s0);
10913 IDirect3DDevice8_DeleteVertexShader(device, vs);
10914 IDirect3DIndexBuffer8_Release(ib);
10915 IDirect3DVertexBuffer8_Release(dst_vb);
10916 IDirect3DVertexBuffer8_Release(vb);
10917 refcount = IDirect3DDevice8_Release(device);
10918 ok(!refcount, "Device has %u references left.\n", refcount);
10919 IDirect3D8_Release(d3d);
10920 DestroyWindow(window);
10923 static void test_alphatest(void)
10925 #define ALPHATEST_PASSED 0x0000ff00
10926 #define ALPHATEST_FAILED 0x00ff0000
10927 IDirect3DDevice8 *device;
10928 unsigned int i, j;
10929 IDirect3D8 *d3d;
10930 D3DCOLOR color;
10931 ULONG refcount;
10932 D3DCAPS8 caps;
10933 DWORD value;
10934 HWND window;
10935 HRESULT hr;
10936 DWORD ps;
10938 static const struct
10940 D3DCMPFUNC func;
10941 D3DCOLOR color_less;
10942 D3DCOLOR color_equal;
10943 D3DCOLOR color_greater;
10945 test_data[] =
10947 {D3DCMP_NEVER, ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_FAILED},
10948 {D3DCMP_LESS, ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_FAILED},
10949 {D3DCMP_EQUAL, ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_FAILED},
10950 {D3DCMP_LESSEQUAL, ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_FAILED},
10951 {D3DCMP_GREATER, ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_PASSED},
10952 {D3DCMP_NOTEQUAL, ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_PASSED},
10953 {D3DCMP_GREATEREQUAL, ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_PASSED},
10954 {D3DCMP_ALWAYS, ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_PASSED},
10956 static const struct
10958 struct vec3 position;
10959 DWORD diffuse;
10961 quad[] =
10963 {{-1.0f, -1.0f, 0.1f}, ALPHATEST_PASSED | 0x80000000},
10964 {{-1.0f, 1.0f, 0.1f}, ALPHATEST_PASSED | 0x80000000},
10965 {{ 1.0f, -1.0f, 0.1f}, ALPHATEST_PASSED | 0x80000000},
10966 {{ 1.0f, 1.0f, 0.1f}, ALPHATEST_PASSED | 0x80000000},
10969 window = create_window();
10970 ok(!!window, "Failed to create a window.\n");
10972 d3d = Direct3DCreate8(D3D_SDK_VERSION);
10973 ok(!!d3d, "Failed to create a D3D object.\n");
10975 if (!(device = create_device(d3d, window, window, TRUE)))
10977 skip("Failed to create a D3D device, skipping tests.\n");
10978 goto done;
10981 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
10982 ok(hr == D3D_OK, "Failed to clear, hr %#x.\n", hr);
10984 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10985 ok(hr == D3D_OK, "Failed to disable lighting, hr %#x.\n", hr);
10986 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ALPHATESTENABLE, TRUE);
10987 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState, hr %#x.\n", hr);
10988 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10989 ok(hr == D3D_OK, "IDirect3DDevice8_SetVertexShader failed, hr %#x.\n", hr);
10991 ps = 0;
10992 for (j = 0; j < 2; ++j)
10994 if (j == 1)
10996 /* Try a pixel shader instead of fixed function. The wined3d code
10997 * may emulate the alpha test either for performance reasons
10998 * (floating point RTs) or to work around driver bugs (GeForce
10999 * 7x00 cards on MacOS). There may be a different codepath for ffp
11000 * and shader in this case, and the test should cover both. */
11001 static const DWORD shader_code[] =
11003 0xffff0101, /* ps_1_1 */
11004 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
11005 0x0000ffff /* end */
11007 memset(&caps, 0, sizeof(caps));
11008 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
11009 ok(hr == D3D_OK, "IDirect3DDevice8_GetDeviceCaps failed, hr %#x.\n", hr);
11010 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 1))
11011 break;
11013 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code, &ps);
11014 ok(hr == D3D_OK, "IDirect3DDevice8_CreatePixelShader failed, hr %#x.\n", hr);
11015 hr = IDirect3DDevice8_SetPixelShader(device, ps);
11016 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShader failed, hr %#x.\n", hr);
11019 for (i = 0; i < ARRAY_SIZE(test_data); ++i)
11021 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ALPHAFUNC, test_data[i].func);
11022 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr %#x.\n", hr);
11024 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0f, 0);
11025 ok(hr == D3D_OK, "IDirect3DDevice8_Clear failed, hr %#x.\n", hr);
11026 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ALPHAREF, 0x70);
11027 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr %#x.\n", hr);
11028 hr = IDirect3DDevice8_BeginScene(device);
11029 ok(hr == D3D_OK, "IDirect3DDevice8_BeginScene failed, hr %#x.\n", hr);
11030 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11031 ok(hr == D3D_OK, "IDirect3DDevice8_DrawPrimitiveUP failed, hr %#x.\n", hr);
11032 hr = IDirect3DDevice8_EndScene(device);
11033 ok(hr == D3D_OK, "IDirect3DDevice8_EndScene failed, hr %#x.\n", hr);
11034 color = getPixelColor(device, 320, 240);
11035 ok(color_match(color, test_data[i].color_greater, 0),
11036 "Alphatest failed, color 0x%08x, expected 0x%08x, alpha > ref, func %u.\n",
11037 color, test_data[i].color_greater, test_data[i].func);
11038 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
11039 ok(hr == D3D_OK, "IDirect3DDevice8_Present failed, hr %#x.\n", hr);
11041 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0f, 0);
11042 ok(hr == D3D_OK, "IDirect3DDevice8_Clear failed, hr %#x.\n", hr);
11043 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ALPHAREF, 0xff70);
11044 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr %#x.\n", hr);
11045 hr = IDirect3DDevice8_GetRenderState(device, D3DRS_ALPHAREF, &value);
11046 ok(hr == D3D_OK, "IDirect3DDevice8_GetRenderState failed, hr %#x.\n", hr);
11047 ok(value == 0xff70, "Unexpected D3DRS_ALPHAREF value %#x.\n", value);
11048 hr = IDirect3DDevice8_BeginScene(device);
11049 ok(hr == D3D_OK, "IDirect3DDevice8_BeginScene failed, hr %#x.\n", hr);
11050 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11051 ok(hr == D3D_OK, "IDirect3DDevice8_DrawPrimitiveUP failed, hr %#x.\n", hr);
11052 hr = IDirect3DDevice8_EndScene(device);
11053 ok(hr == D3D_OK, "IDirect3DDevice8_EndScene failed, hr %#x.\n", hr);
11054 color = getPixelColor(device, 320, 240);
11055 ok(color_match(color, test_data[i].color_greater, 0),
11056 "Alphatest failed, color 0x%08x, expected 0x%08x, alpha > ref, func %u.\n",
11057 color, test_data[i].color_greater, test_data[i].func);
11058 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
11059 ok(hr == D3D_OK, "IDirect3DDevice8_Present failed, hr %#x.\n", hr);
11062 if (ps)
11063 IDirect3DDevice8_DeletePixelShader(device, ps);
11065 refcount = IDirect3DDevice8_Release(device);
11066 ok(!refcount, "Device has %u references left.\n", refcount);
11067 done:
11068 IDirect3D8_Release(d3d);
11069 DestroyWindow(window);
11072 static void test_desktop_window(void)
11074 IDirect3DDevice8 *device;
11075 IDirect3D8 *d3d;
11076 D3DCOLOR color;
11077 ULONG refcount;
11078 HWND window;
11079 HRESULT hr;
11081 window = create_window();
11082 d3d = Direct3DCreate8(D3D_SDK_VERSION);
11083 ok(!!d3d, "Failed to create a D3D object.\n");
11084 if (!(device = create_device(d3d, window, window, TRUE)))
11086 skip("Failed to create a D3D device, skipping tests.\n");
11087 IDirect3D8_Release(d3d);
11088 DestroyWindow(window);
11089 return;
11091 IDirect3DDevice8_Release(device);
11092 DestroyWindow(window);
11094 device = create_device(d3d, GetDesktopWindow(), GetDesktopWindow(), TRUE);
11095 ok(!!device, "Failed to create a D3D device.\n");
11097 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 1.0f, 0);
11098 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
11099 color = getPixelColor(device, 1, 1);
11100 ok(color == 0x00ff0000, "Got unexpected color 0x%08x.\n", color);
11102 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
11103 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
11105 refcount = IDirect3DDevice8_Release(device);
11106 ok(!refcount, "Device has %u references left.\n", refcount);
11108 IDirect3D8_Release(d3d);
11111 static void test_sample_mask(void)
11113 IDirect3DSurface8 *rt, *ms_rt;
11114 struct surface_readback rb;
11115 IDirect3DDevice8 *device;
11116 IDirect3D8 *d3d;
11117 ULONG refcount;
11118 DWORD colour;
11119 HWND window;
11120 HRESULT hr;
11122 static const struct
11124 struct vec3 position;
11125 DWORD diffuse;
11127 quad[] =
11129 {{-1.0f, -1.0f, 0.1f}, 0xffffffff},
11130 {{-1.0f, 1.0f, 0.1f}, 0xffffffff},
11131 {{ 1.0f, -1.0f, 0.1f}, 0xffffffff},
11132 {{ 1.0f, 1.0f, 0.1f}, 0xffffffff},
11135 window = create_window();
11136 d3d = Direct3DCreate8(D3D_SDK_VERSION);
11137 ok(!!d3d, "Failed to create a D3D object.\n");
11139 if (FAILED(IDirect3D8_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
11140 D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES)))
11142 skip("Multisampling not supported for D3DFMT_A8R8G8B8.\n");
11143 IDirect3D8_Release(d3d);
11144 DestroyWindow(window);
11145 return;
11148 if (!(device = create_device(d3d, window, window, TRUE)))
11150 skip("Failed to create a 3D device.\n");
11151 IDirect3D8_Release(d3d);
11152 DestroyWindow(window);
11153 return;
11156 hr = IDirect3DDevice8_CreateRenderTarget(device, 128, 128, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, FALSE, &rt);
11157 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
11158 hr = IDirect3DDevice8_CreateRenderTarget(device, 128, 128,
11159 D3DFMT_A8R8G8B8, D3DMULTISAMPLE_2_SAMPLES, FALSE, &ms_rt);
11160 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
11162 hr = IDirect3DDevice8_SetRenderTarget(device, ms_rt, NULL);
11163 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
11165 hr = IDirect3DDevice8_BeginScene(device);
11166 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
11168 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11169 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
11170 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_MULTISAMPLEMASK, 0x5);
11171 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
11173 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0f, 0);
11174 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
11175 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11176 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
11177 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
11178 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
11180 hr = IDirect3DDevice8_CopyRects(device, ms_rt, NULL, 0, rt, NULL);
11181 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
11182 get_rt_readback(rt, &rb);
11183 colour = get_readback_color(&rb, 64, 64);
11184 /* Multiple generations of Nvidia cards return broken results.
11185 * A mask with no bits or all bits set produce the expected results (0x00 / 0xff),
11186 * but any other mask behaves almost as if the result is 0.5 + (enabled / total)
11187 * samples. It's not quite that though (you'd expect 0xbf or 0xc0 instead of 0xbc).
11189 * I looked at a few other possible problems: Incorrectly enabled Z test, alpha test,
11190 * culling, the multisample mask affecting CopyRects. Neither of these make a difference. */
11191 ok(color_match(colour, 0xffff8080, 1) || broken(color_match(colour, 0xffffbcbc, 1)),
11192 "Got unexpected colour %08x.\n", colour);
11193 release_surface_readback(&rb);
11195 hr = IDirect3DDevice8_EndScene(device);
11196 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
11198 IDirect3DSurface8_Release(ms_rt);
11199 IDirect3DSurface8_Release(rt);
11200 refcount = IDirect3DDevice8_Release(device);
11201 ok(!refcount, "Device has %u references left.\n", refcount);
11202 IDirect3D8_Release(d3d);
11203 DestroyWindow(window);
11206 struct dynamic_vb_vertex
11208 struct vec3 position;
11209 DWORD diffuse;
11212 static void fill_dynamic_vb_quad(struct dynamic_vb_vertex *quad, unsigned int x, unsigned int y)
11214 unsigned int i;
11216 memset(quad, 0, 4 * sizeof(*quad));
11218 quad[0].position.x = quad[1].position.x = -1.0f + 0.01f * x;
11219 quad[2].position.x = quad[3].position.x = -1.0f + 0.01f * (x + 1);
11221 quad[0].position.y = quad[2].position.y = -1.0f + 0.01f * y;
11222 quad[1].position.y = quad[3].position.y = -1.0f + 0.01f * (y + 1);
11224 for (i = 0; i < 4; ++i)
11225 quad[i].diffuse = 0xff00ff00;
11228 static void test_dynamic_map_synchronization(void)
11230 IDirect3DVertexBuffer8 *buffer;
11231 IDirect3DDevice8 *device;
11232 IDirect3DSurface8 *rt;
11233 unsigned int x, y;
11234 IDirect3D8 *d3d;
11235 ULONG refcount;
11236 HWND window;
11237 HRESULT hr;
11238 BYTE *data;
11240 window = create_window();
11241 d3d = Direct3DCreate8(D3D_SDK_VERSION);
11242 ok(!!d3d, "Failed to create a D3D object.\n");
11243 if (!(device = create_device(d3d, window, window, TRUE)))
11245 skip("Failed to create a D3D device, skipping tests.\n");
11246 IDirect3D8_Release(d3d);
11247 DestroyWindow(window);
11248 return;
11251 hr = IDirect3DDevice8_CreateVertexBuffer(device, 200 * 4 * sizeof(struct dynamic_vb_vertex),
11252 D3DUSAGE_DYNAMIC, D3DFVF_XYZ, D3DPOOL_DEFAULT, &buffer);
11253 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
11255 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0f, 0);
11256 ok(hr == D3D_OK, "Failed to clear, hr %#x.\n", hr);
11258 hr = IDirect3DDevice8_BeginScene(device);
11259 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
11260 hr = IDirect3DDevice8_SetStreamSource(device, 0, buffer, sizeof(struct dynamic_vb_vertex));
11261 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
11262 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11263 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
11264 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, FALSE);
11265 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
11266 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11267 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
11269 for (y = 0; y < 200; ++y)
11271 hr = IDirect3DVertexBuffer8_Lock(buffer, 0, 0, &data, D3DLOCK_DISCARD);
11272 ok(hr == D3D_OK, "Failed to map buffer, hr %#x.\n", hr);
11274 fill_dynamic_vb_quad((struct dynamic_vb_vertex *)data, 0, y);
11276 hr = IDirect3DVertexBuffer8_Unlock(buffer);
11277 ok(hr == D3D_OK, "Failed to map buffer, hr %#x.\n", hr);
11279 hr = IDirect3DDevice8_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
11280 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
11282 for (x = 1; x < 200; ++x)
11284 hr = IDirect3DVertexBuffer8_Lock(buffer, 4 * sizeof(struct dynamic_vb_vertex) * x,
11285 4 * sizeof(struct dynamic_vb_vertex), &data, D3DLOCK_NOOVERWRITE);
11286 ok(hr == D3D_OK, "Failed to map buffer, hr %#x.\n", hr);
11288 fill_dynamic_vb_quad((struct dynamic_vb_vertex *)data, x, y);
11290 hr = IDirect3DVertexBuffer8_Unlock(buffer);
11291 ok(hr == D3D_OK, "Failed to map buffer, hr %#x.\n", hr);
11293 hr = IDirect3DDevice8_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4 * x, 2);
11294 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
11298 hr = IDirect3DDevice8_GetRenderTarget(device, &rt);
11299 ok(hr == S_OK, "Failed to get render target, hr %#x.\n", hr);
11300 check_rt_color(rt, 0x0000ff00);
11301 IDirect3DSurface8_Release(rt);
11303 hr = IDirect3DDevice8_EndScene(device);
11304 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
11306 IDirect3DVertexBuffer8_Release(buffer);
11307 refcount = IDirect3DDevice8_Release(device);
11308 ok(!refcount, "Device has %u references left.\n", refcount);
11309 IDirect3D8_Release(d3d);
11310 DestroyWindow(window);
11313 static void test_filling_convention(void)
11315 static const DWORD colour_bottom = 0x00ffff00;
11316 static const DWORD colour_clear = 0x000000ff;
11317 static const DWORD colour_right = 0x00000000;
11318 static const DWORD colour_left = 0x00ff0000;
11319 static const DWORD colour_top = 0x0000ff00;
11320 IDirect3DSurface8 *rt, *backbuffer, *cur;
11321 struct surface_readback rb;
11322 IDirect3DDevice8 *device;
11323 unsigned int i, j, x, y;
11324 DWORD colour, expected;
11325 DWORD shader = 0;
11326 IDirect3D8 *d3d;
11327 ULONG refcount;
11328 D3DCAPS8 caps;
11329 HWND window;
11330 HRESULT hr;
11331 BOOL todo;
11333 static const unsigned int vp_size = 8;
11334 const D3DVIEWPORT8 vp = { 0, 0, vp_size, vp_size, 0.0, 1.0 };
11335 static const DWORD vs_code[] =
11337 0xfffe0101, /* vs_1_1 */
11338 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
11339 0x00000001, 0xd00f0000, 0x90e40005, /* mov oD0, v5 */
11340 0x0000ffff /* end */
11342 static const DWORD decl[] =
11344 D3DVSD_STREAM(0),
11345 D3DVSD_REG(D3DVSDE_POSITION, D3DVSDT_FLOAT3),
11346 D3DVSD_REG(D3DVSDE_DIFFUSE, D3DVSDT_D3DCOLOR),
11347 D3DVSD_END()
11350 /* This test data follows the examples in MSDN's
11351 * "Rasterization Rules (Direct3D 9)" article.
11353 * See the d3d9 test for a comment about the eps value. */
11354 static const float eps = 1.0f / 64.0f;
11355 const struct
11357 struct vec3 position;
11358 DWORD diffuse;
11360 center_tris[] =
11362 /* left */
11363 {{-2.5f / 4.0f, -1.5f / 4.0f, 0.0f}, colour_left},
11364 {{-2.5f / 4.0f, 2.5f / 4.0f, 0.0f}, colour_left},
11365 {{-1.5f / 4.0f, 0.5f / 4.0f, 0.0f}, colour_left},
11367 /* top */
11368 {{-1.5f / 4.0f, 0.5f / 4.0f, 0.0f}, colour_top},
11369 {{-2.5f / 4.0f, 2.5f / 4.0f, 0.0f}, colour_top},
11370 {{-0.5f / 4.0f, 2.5f / 4.0f, 0.0f}, colour_top},
11372 /* right */
11373 {{-0.5f / 4.0f, -1.5f / 4.0f, 0.0f}, colour_right},
11374 {{-1.5f / 4.0f, 0.5f / 4.0f, 0.0f}, colour_right},
11375 {{-0.5f / 4.0f, 2.5f / 4.0f, 0.0f}, colour_right},
11377 /* bottom */
11378 {{-2.5f / 4.0f, -1.5f / 4.0f, 0.0f}, colour_bottom},
11379 {{-1.5f / 4.0f, 0.5f / 4.0f, 0.0f}, colour_bottom},
11380 {{-0.5f / 4.0f, -1.5f / 4.0f, 0.0f}, colour_bottom},
11383 edge_tris[] =
11385 /* left */
11386 {{-2.0f / 4.0f, -1.0f / 4.0f, 0.0f}, colour_left},
11387 {{-2.0f / 4.0f, 3.0f / 4.0f, 0.0f}, colour_left},
11388 {{-1.0f / 4.0f, 1.0f / 4.0f, 0.0f}, colour_left},
11390 /* top */
11391 {{-1.0f / 4.0f, 1.0f / 4.0f, 0.0f}, colour_top},
11392 {{-2.0f / 4.0f, 3.0f / 4.0f, 0.0f}, colour_top},
11393 {{ 0.0f / 4.0f, 3.0f / 4.0f, 0.0f}, colour_top},
11395 /* right */
11396 {{ 0.0f / 4.0f, -1.0f / 4.0f, 0.0f}, colour_right},
11397 {{-1.0f / 4.0f, 1.0f / 4.0f, 0.0f}, colour_right},
11398 {{ 0.0f / 4.0f, 3.0f / 4.0f, 0.0f}, colour_right},
11400 /* bottom */
11401 {{-2.0f / 4.0f, -1.0f / 4.0f, 0.0f}, colour_bottom},
11402 {{-1.0f / 4.0f, 1.0f / 4.0f, 0.0f}, colour_bottom},
11403 {{ 0.0f / 4.0f, -1.0f / 4.0f, 0.0f}, colour_bottom},
11405 nudge_right_tris[] =
11407 /* left */
11408 {{eps - 2.0f / 4.0f, -1.0f / 4.0f, 0.0f}, colour_left},
11409 {{eps - 2.0f / 4.0f, 3.0f / 4.0f, 0.0f}, colour_left},
11410 {{eps - 1.0f / 4.0f, 1.0f / 4.0f, 0.0f}, colour_left},
11412 /* top */
11413 {{eps - 1.0f / 4.0f, 1.0f / 4.0f, 0.0f}, colour_top},
11414 {{eps - 2.0f / 4.0f, 3.0f / 4.0f, 0.0f}, colour_top},
11415 {{eps - 0.0f / 4.0f, 3.0f / 4.0f, 0.0f}, colour_top},
11417 /* right */
11418 {{eps - 0.0f / 4.0f, -1.0f / 4.0f, 0.0f}, colour_right},
11419 {{eps - 1.0f / 4.0f, 1.0f / 4.0f, 0.0f}, colour_right},
11420 {{eps - 0.0f / 4.0f, 3.0f / 4.0f, 0.0f}, colour_right},
11422 /* bottom */
11423 {{eps - 2.0f / 4.0f, -1.0f / 4.0f, 0.0f}, colour_bottom},
11424 {{eps - 1.0f / 4.0f, 1.0f / 4.0f, 0.0f}, colour_bottom},
11425 {{eps - 0.0f / 4.0f, -1.0f / 4.0f, 0.0f}, colour_bottom},
11427 nudge_left_tris[] =
11429 {{-eps - 2.0f / 4.0f, -1.0f / 4.0f, 0.0f}, colour_left},
11430 {{-eps - 2.0f / 4.0f, 3.0f / 4.0f, 0.0f}, colour_left},
11431 {{-eps - 1.0f / 4.0f, 1.0f / 4.0f, 0.0f}, colour_left},
11433 /* top */
11434 {{-eps - 1.0f / 4.0f, 1.0f / 4.0f, 0.0f}, colour_top},
11435 {{-eps - 2.0f / 4.0f, 3.0f / 4.0f, 0.0f}, colour_top},
11436 {{-eps - 0.0f / 4.0f, 3.0f / 4.0f, 0.0f}, colour_top},
11438 /* right */
11439 {{-eps - 0.0f / 4.0f, -1.0f / 4.0f, 0.0f}, colour_right},
11440 {{-eps - 1.0f / 4.0f, 1.0f / 4.0f, 0.0f}, colour_right},
11441 {{-eps - 0.0f / 4.0f, 3.0f / 4.0f, 0.0f}, colour_right},
11443 /* bottom */
11444 {{-eps - 2.0f / 4.0f, -1.0f / 4.0f, 0.0f}, colour_bottom},
11445 {{-eps - 1.0f / 4.0f, 1.0f / 4.0f, 0.0f}, colour_bottom},
11446 {{-eps - 0.0f / 4.0f, -1.0f / 4.0f, 0.0f}, colour_bottom},
11448 nudge_top_tris[] =
11450 /* left */
11451 {{-2.0f / 4.0f, eps - 1.0f / 4.0f, 0.0f}, colour_left},
11452 {{-2.0f / 4.0f, eps + 3.0f / 4.0f, 0.0f}, colour_left},
11453 {{-1.0f / 4.0f, eps + 1.0f / 4.0f, 0.0f}, colour_left},
11455 /* top */
11456 {{-1.0f / 4.0f, eps + 1.0f / 4.0f, 0.0f}, colour_top},
11457 {{-2.0f / 4.0f, eps + 3.0f / 4.0f, 0.0f}, colour_top},
11458 {{ 0.0f / 4.0f, eps + 3.0f / 4.0f, 0.0f}, colour_top},
11460 /* right */
11461 {{ 0.0f / 4.0f, eps - 1.0f / 4.0f, 0.0f}, colour_right},
11462 {{-1.0f / 4.0f, eps + 1.0f / 4.0f, 0.0f}, colour_right},
11463 {{ 0.0f / 4.0f, eps + 3.0f / 4.0f, 0.0f}, colour_right},
11465 /* bottom */
11466 {{-2.0f / 4.0f, eps - 1.0f / 4.0f, 0.0f}, colour_bottom},
11467 {{-1.0f / 4.0f, eps + 1.0f / 4.0f, 0.0f}, colour_bottom},
11468 {{ 0.0f / 4.0f, eps - 1.0f / 4.0f, 0.0f}, colour_bottom},
11470 nudge_bottom_tris[] =
11472 /* left */
11473 {{-2.0f / 4.0f, -eps - 1.0f / 4.0f, 0.0f}, colour_left},
11474 {{-2.0f / 4.0f, -eps + 3.0f / 4.0f, 0.0f}, colour_left},
11475 {{-1.0f / 4.0f, -eps + 1.0f / 4.0f, 0.0f}, colour_left},
11477 /* top */
11478 {{-1.0f / 4.0f, -eps + 1.0f / 4.0f, 0.0f}, colour_top},
11479 {{-2.0f / 4.0f, -eps + 3.0f / 4.0f, 0.0f}, colour_top},
11480 {{ 0.0f / 4.0f, -eps + 3.0f / 4.0f, 0.0f}, colour_top},
11482 /* right */
11483 {{ 0.0f / 4.0f, -eps - 1.0f / 4.0f, 0.0f}, colour_right},
11484 {{-1.0f / 4.0f, -eps + 1.0f / 4.0f, 0.0f}, colour_right},
11485 {{ 0.0f / 4.0f, -eps + 3.0f / 4.0f, 0.0f}, colour_right},
11487 /* bottom */
11488 {{-2.0f / 4.0f, -eps - 1.0f / 4.0f, 0.0f}, colour_bottom},
11489 {{-1.0f / 4.0f, -eps + 1.0f / 4.0f, 0.0f}, colour_bottom},
11490 {{ 0.0f / 4.0f, -eps - 1.0f / 4.0f, 0.0f}, colour_bottom},
11493 const struct
11495 struct vec4 position;
11496 DWORD diffuse;
11498 center_tris_t[] =
11500 /* left */
11501 {{ 1.5f, 1.5f, 0.0f, 1.0f}, colour_left},
11502 {{ 2.5f, 3.5f, 0.0f, 1.0f}, colour_left},
11503 {{ 1.5f, 5.5f, 0.0f, 1.0f}, colour_left},
11505 /* top */
11506 {{ 1.5f, 1.5f, 0.0f, 1.0f}, colour_top},
11507 {{ 3.5f, 1.5f, 0.0f, 1.0f}, colour_top},
11508 {{ 2.5f, 3.5f, 0.0f, 1.0f}, colour_top},
11510 /* right */
11511 {{ 3.5f, 1.5f, 0.0f, 1.0f}, colour_right},
11512 {{ 3.5f, 5.5f, 0.0f, 1.0f}, colour_right},
11513 {{ 2.5f, 3.5f, 0.0f, 1.0f}, colour_right},
11515 /* bottom */
11516 {{ 2.5f, 3.5f, 0.0f, 1.0f}, colour_bottom},
11517 {{ 3.5f, 5.5f, 0.0f, 1.0f}, colour_bottom},
11518 {{ 1.5f, 5.5f, 0.0f, 1.0f}, colour_bottom},
11520 edge_tris_t[] =
11522 /* left */
11523 {{ 2.0f, 1.0f, 0.0f, 1.0f}, colour_left},
11524 {{ 3.0f, 3.0f, 0.0f, 1.0f}, colour_left},
11525 {{ 2.0f, 5.0f, 0.0f, 1.0f}, colour_left},
11527 /* top */
11528 {{ 2.0f, 1.0f, 0.0f, 1.0f}, colour_top},
11529 {{ 4.0f, 1.0f, 0.0f, 1.0f}, colour_top},
11530 {{ 3.0f, 3.0f, 0.0f, 1.0f}, colour_top},
11532 /* right */
11533 {{ 4.0f, 1.0f, 0.0f, 1.0f}, colour_right},
11534 {{ 4.0f, 5.0f, 0.0f, 1.0f}, colour_right},
11535 {{ 3.0f, 3.0f, 0.0f, 1.0f}, colour_right},
11537 /* bottom */
11538 {{ 3.0f, 3.0f, 0.0f, 1.0f}, colour_bottom},
11539 {{ 4.0f, 5.0f, 0.0f, 1.0f}, colour_bottom},
11540 {{ 2.0f, 5.0f, 0.0f, 1.0f}, colour_bottom},
11543 const struct
11545 const void *geometry;
11546 size_t stride;
11547 DWORD fvf;
11548 const char *expected[8];
11550 tests[] =
11553 center_tris,
11554 sizeof(center_tris[0]),
11555 D3DFVF_XYZ | D3DFVF_DIFFUSE,
11557 " ",
11558 " ",
11559 " TT ",
11560 " LR ",
11561 " LR ",
11562 " BB ",
11563 " ",
11568 edge_tris,
11569 sizeof(edge_tris[0]),
11570 D3DFVF_XYZ | D3DFVF_DIFFUSE,
11572 " ",
11573 " TT ",
11574 " LT ",
11575 " LR ",
11576 " LB ",
11577 " ",
11578 " ",
11583 nudge_right_tris,
11584 sizeof(nudge_right_tris[0]),
11585 D3DFVF_XYZ | D3DFVF_DIFFUSE,
11587 " ",
11588 " TT ",
11589 " TR ",
11590 " LR ",
11591 " BR ",
11592 " ",
11593 " ",
11598 nudge_left_tris,
11599 sizeof(nudge_left_tris[0]),
11600 D3DFVF_XYZ | D3DFVF_DIFFUSE,
11602 " ",
11603 " TT ",
11604 " LT ",
11605 " LR ",
11606 " LB ",
11607 " ",
11608 " ",
11613 nudge_top_tris,
11614 sizeof(nudge_top_tris[0]),
11615 D3DFVF_XYZ | D3DFVF_DIFFUSE,
11617 " ",
11618 " LT ",
11619 " LT ",
11620 " LB ",
11621 " LB ",
11622 " ",
11623 " ",
11628 nudge_bottom_tris,
11629 sizeof(nudge_bottom_tris[0]),
11630 D3DFVF_XYZ | D3DFVF_DIFFUSE,
11632 " ",
11633 " ",
11634 " LT ",
11635 " Lt ",
11636 " LB ",
11637 " lB ",
11638 " ",
11643 center_tris_t,
11644 sizeof(center_tris_t[0]),
11645 D3DFVF_XYZRHW | D3DFVF_DIFFUSE,
11647 " ",
11648 " ",
11649 " TT ",
11650 " LR ",
11651 " LR ",
11652 " BB ",
11653 " ",
11658 edge_tris_t,
11659 sizeof(edge_tris_t[0]),
11660 D3DFVF_XYZRHW | D3DFVF_DIFFUSE,
11662 " ",
11663 " TT ",
11664 " LT ",
11665 " LR ",
11666 " LB ",
11667 " ",
11668 " ",
11674 window = create_window();
11675 d3d = Direct3DCreate8(D3D_SDK_VERSION);
11676 ok(!!d3d, "Failed to create a D3D object.\n");
11678 if (!(device = create_device(d3d, window, window, TRUE)))
11680 skip("Failed to create a 3D device.\n");
11681 IDirect3D8_Release(d3d);
11682 DestroyWindow(window);
11683 return;
11686 hr = IDirect3DDevice8_CreateRenderTarget(device, vp_size, vp_size,
11687 D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, FALSE, &rt);
11688 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
11689 hr = IDirect3DDevice8_GetBackBuffer(device, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
11690 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
11692 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
11693 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
11694 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
11696 hr = IDirect3DDevice8_CreateVertexShader(device, decl, vs_code, &shader, 0);
11697 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
11699 else
11700 skip("Skipping vertex shader codepath in filling convention test.\n");
11702 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11703 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
11704 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
11705 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
11707 for (i = 0; i < ARRAY_SIZE(tests); ++i)
11709 /* Run tests with shader and fixed function vertex processing if shaders are
11710 * supported. There's no point in running the XYZRHW tests with a VS though. */
11711 if (shader && ((tests[i].fvf & D3DFVF_POSITION_MASK) == D3DFVF_XYZ))
11712 j = 0;
11713 else
11714 j = 2;
11716 for (; j < 4; ++j)
11718 cur = (j & 1) ? rt : backbuffer;
11720 hr = IDirect3DDevice8_SetVertexShader(device, (j & 2) ? tests[i].fvf : shader);
11721 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
11723 hr = IDirect3DDevice8_SetRenderTarget(device, cur, NULL);
11724 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
11725 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, colour_clear, 0.0f, 0);
11726 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
11727 hr = IDirect3DDevice8_SetViewport(device, &vp);
11728 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
11730 hr = IDirect3DDevice8_BeginScene(device);
11731 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
11732 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, tests[i].geometry, tests[i].stride);
11733 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
11734 hr = IDirect3DDevice8_EndScene(device);
11735 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
11737 get_rt_readback(cur, &rb);
11738 for (y = 0; y < 8; y++)
11740 for (x = 0; x < 8; x++)
11742 todo = FALSE;
11743 switch (tests[i].expected[y][x])
11745 case 'l': todo = TRUE;
11746 case 'L':
11747 expected = colour_left;
11748 break;
11749 case 't': todo = TRUE;
11750 case 'T':
11751 expected = colour_top;
11752 break;
11753 case 'r': todo = TRUE;
11754 case 'R':
11755 expected = colour_right;
11756 break;
11757 case 'b': todo = TRUE;
11758 case 'B':
11759 expected = colour_bottom;
11760 break;
11761 case ' ':
11762 expected = colour_clear;
11763 break;
11764 default:
11765 ok(0, "Unexpected entry in expected test char\n");
11766 expected = 0xdeadbeef;
11768 colour = get_readback_color(&rb, x, y);
11769 /* The nudge-to-bottom test fails on cards that give us a bottom-left
11770 * filling convention. The cause isn't the bottom part of the filling
11771 * convention, but because wined3d will nudge geometry to the left to
11772 * keep diagonals (the 'R' in test case 'edge_tris') intact. */
11773 todo_wine_if(todo && !color_match(colour, expected, 1))
11774 ok(color_match(colour, expected, 1), "Got unexpected colour %08x, %ux%u, case %u, j %u.\n",
11775 colour, x, y, i, j);
11778 release_surface_readback(&rb);
11780 /* IDirect3DDevice8::CopyRects can't stretch, so don't bother making the offscreen surface
11781 * visible. Use the d3d9 test if you need to see visual output. */
11782 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
11783 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
11787 if (shader)
11788 IDirect3DDevice8_DeleteVertexShader(device, shader);
11789 IDirect3DSurface8_Release(backbuffer);
11790 IDirect3DSurface8_Release(rt);
11791 refcount = IDirect3DDevice8_Release(device);
11792 ok(!refcount, "Device has %u references left.\n", refcount);
11793 IDirect3D8_Release(d3d);
11794 DestroyWindow(window);
11797 START_TEST(visual)
11799 D3DADAPTER_IDENTIFIER8 identifier;
11800 IDirect3D8 *d3d;
11801 HRESULT hr;
11803 if (!(d3d = Direct3DCreate8(D3D_SDK_VERSION)))
11805 skip("Failed to create D3D8 object.\n");
11806 return;
11809 memset(&identifier, 0, sizeof(identifier));
11810 hr = IDirect3D8_GetAdapterIdentifier(d3d, D3DADAPTER_DEFAULT, 0, &identifier);
11811 ok(SUCCEEDED(hr), "Failed to get adapter identifier, hr %#x.\n", hr);
11812 trace("Driver string: \"%s\"\n", identifier.Driver);
11813 trace("Description string: \"%s\"\n", identifier.Description);
11814 /* Only Windows XP's default VGA driver should have an empty description */
11815 ok(identifier.Description[0] || broken(!strcmp(identifier.Driver, "vga.dll")), "Empty driver description.\n");
11816 trace("Driver version %d.%d.%d.%d\n",
11817 HIWORD(U(identifier.DriverVersion).HighPart), LOWORD(U(identifier.DriverVersion).HighPart),
11818 HIWORD(U(identifier.DriverVersion).LowPart), LOWORD(U(identifier.DriverVersion).LowPart));
11820 IDirect3D8_Release(d3d);
11822 test_sanity();
11823 depth_clamp_test();
11824 lighting_test();
11825 test_specular_lighting();
11826 clear_test();
11827 fog_test();
11828 z_range_test();
11829 offscreen_test();
11830 test_blend();
11831 test_scalar_instructions();
11832 fog_with_shader_test();
11833 cnd_test();
11834 p8_texture_test();
11835 texop_test();
11836 depth_buffer_test();
11837 depth_buffer2_test();
11838 intz_test();
11839 shadow_test();
11840 multisample_copy_rects_test();
11841 zenable_test();
11842 resz_test();
11843 fog_special_test();
11844 volume_dxtn_test();
11845 volume_v16u16_test();
11846 add_dirty_rect_test();
11847 test_3dc_formats();
11848 test_fog_interpolation();
11849 test_negative_fixedfunction_fog();
11850 test_table_fog_zw();
11851 test_signed_formats();
11852 test_updatetexture();
11853 test_pointsize();
11854 test_multisample_mismatch();
11855 test_texcoordindex();
11856 test_vshader_input();
11857 test_fixed_function_fvf();
11858 test_flip();
11859 test_uninitialized_varyings();
11860 test_shademode();
11861 test_multisample_init();
11862 test_texture_blending();
11863 test_color_clamping();
11864 test_edge_antialiasing_blending();
11865 test_max_index16();
11866 test_backbuffer_resize();
11867 test_drawindexedprimitiveup();
11868 test_map_synchronisation();
11869 test_viewport();
11870 test_color_vertex();
11871 test_sysmem_draw();
11872 test_alphatest();
11873 test_desktop_window();
11874 test_sample_mask();
11875 test_dynamic_map_synchronization();
11876 test_filling_convention();