d3d8/tests: Add out-of-bounds region tests.
[wine.git] / dlls / d3d8 / tests / visual.c
blob96ab4596a76de9c0dfe6dadfd6d726da77cd090e
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 color_match(D3DCOLOR c1, D3DCOLOR c2, BYTE max_diff)
56 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
57 c1 >>= 8; c2 >>= 8;
58 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
59 c1 >>= 8; c2 >>= 8;
60 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
61 c1 >>= 8; c2 >>= 8;
62 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
63 return TRUE;
66 static BOOL compare_float(float f, float g, unsigned int ulps)
68 int x = *(int *)&f;
69 int y = *(int *)&g;
71 if (x < 0)
72 x = INT_MIN - x;
73 if (y < 0)
74 y = INT_MIN - y;
76 if (abs(x - y) > ulps)
77 return FALSE;
79 return TRUE;
82 static BOOL compare_vec4(const struct vec4 *vec, float x, float y, float z, float w, unsigned int ulps)
84 return compare_float(vec->x, x, ulps)
85 && compare_float(vec->y, y, ulps)
86 && compare_float(vec->z, z, ulps)
87 && compare_float(vec->w, w, ulps);
90 static BOOL adapter_is_warp(const D3DADAPTER_IDENTIFIER8 *identifier)
92 return !strcmp(identifier->Driver, "d3d10warp.dll");
95 struct surface_readback
97 IDirect3DSurface8 *surface;
98 D3DLOCKED_RECT locked_rect;
101 static void get_rt_readback(IDirect3DSurface8 *surface, struct surface_readback *rb)
103 IDirect3DTexture8 *tex = NULL;
104 IDirect3DDevice8 *device;
105 D3DSURFACE_DESC desc;
106 HRESULT hr;
108 memset(rb, 0, sizeof(*rb));
109 hr = IDirect3DSurface8_GetDevice(surface, &device);
110 ok(SUCCEEDED(hr), "Failed to get device, hr %#x.\n", hr);
111 hr = IDirect3DSurface8_GetDesc(surface, &desc);
112 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
113 hr = IDirect3DDevice8_CreateTexture(device, desc.Width, desc.Height, 1, 0, desc.Format, D3DPOOL_SYSTEMMEM, &tex);
114 if (FAILED(hr) || !tex)
116 trace("Can't create an offscreen plain surface to read the render target data, hr %#x.\n", hr);
117 goto error;
119 hr = IDirect3DTexture8_GetSurfaceLevel(tex, 0, &rb->surface);
120 if (FAILED(hr))
122 trace("Can't get surface from texture, hr %#x.\n", hr);
123 goto error;
125 hr = IDirect3DDevice8_CopyRects(device, surface, NULL, 0, rb->surface, NULL);
126 if (FAILED(hr))
128 trace("Can't read the render target, hr %#x.\n", hr);
129 goto error;
131 hr = IDirect3DSurface8_LockRect(rb->surface, &rb->locked_rect, NULL, D3DLOCK_READONLY);
132 if (FAILED(hr))
134 trace("Can't lock the offscreen surface, hr %#x.\n", hr);
135 goto error;
137 IDirect3DTexture8_Release(tex);
138 IDirect3DDevice8_Release(device);
139 return;
141 error:
142 if (rb->surface)
143 IDirect3DSurface8_Release(rb->surface);
144 rb->surface = NULL;
145 if (tex)
146 IDirect3DTexture8_Release(tex);
147 IDirect3DDevice8_Release(device);
150 static DWORD get_readback_color(struct surface_readback *rb, unsigned int x, unsigned int y)
152 return rb->locked_rect.pBits
153 ? ((DWORD *)rb->locked_rect.pBits)[y * rb->locked_rect.Pitch / sizeof(DWORD) + x] : 0xdeadbeef;
156 static void release_surface_readback(struct surface_readback *rb)
158 HRESULT hr;
160 if (!rb->surface)
161 return;
162 if (rb->locked_rect.pBits && FAILED(hr = IDirect3DSurface8_UnlockRect(rb->surface)))
163 trace("Can't unlock the offscreen surface, hr %#x.\n", hr);
164 IDirect3DSurface8_Release(rb->surface);
167 static DWORD getPixelColor(IDirect3DDevice8 *device, UINT x, UINT y)
169 DWORD ret;
170 IDirect3DSurface8 *rt;
171 struct surface_readback rb;
172 HRESULT hr;
174 hr = IDirect3DDevice8_GetRenderTarget(device, &rt);
175 if (FAILED(hr))
177 trace("Can't get the render target, hr %#x.\n", hr);
178 return 0xdeadbeef;
181 get_rt_readback(rt, &rb);
182 /* Remove the X channel for now. DirectX and OpenGL have different ideas how to treat it apparently, and it isn't
183 * really important for these tests
185 ret = get_readback_color(&rb, x, y) & 0x00ffffff;
186 release_surface_readback(&rb);
188 IDirect3DSurface8_Release(rt);
189 return ret;
192 static D3DCOLOR get_surface_color(IDirect3DSurface8 *surface, UINT x, UINT y)
194 DWORD color;
195 HRESULT hr;
196 D3DSURFACE_DESC desc;
197 RECT rectToLock = {x, y, x+1, y+1};
198 D3DLOCKED_RECT lockedRect;
200 hr = IDirect3DSurface8_GetDesc(surface, &desc);
201 ok(SUCCEEDED(hr), "Failed to get surface description, hr=%#x.\n", hr);
203 hr = IDirect3DSurface8_LockRect(surface, &lockedRect, &rectToLock, D3DLOCK_READONLY);
204 ok(SUCCEEDED(hr), "Failed to lock surface, hr=%#x.\n", hr);
206 switch(desc.Format)
208 case D3DFMT_A8R8G8B8:
209 color = ((D3DCOLOR *)lockedRect.pBits)[0];
210 break;
212 default:
213 trace("Error: unknown surface format: %u.\n", desc.Format);
214 color = 0xdeadbeef;
215 break;
218 hr = IDirect3DSurface8_UnlockRect(surface);
219 ok(SUCCEEDED(hr), "Failed to unlock surface, hr=%#x.\n", hr);
221 return color;
224 static void check_rect(struct surface_readback *rb, RECT r, const char *message)
226 LONG x_coords[2][2] =
228 {r.left - 1, r.left + 1},
229 {r.right + 1, r.right - 1},
231 LONG y_coords[2][2] =
233 {r.top - 1, r.top + 1},
234 {r.bottom + 1, r.bottom - 1}
236 unsigned int i, j, x_side, y_side;
237 DWORD color;
238 LONG x, y;
240 for (i = 0; i < 2; ++i)
242 for (j = 0; j < 2; ++j)
244 for (x_side = 0; x_side < 2; ++x_side)
246 for (y_side = 0; y_side < 2; ++y_side)
248 DWORD expected = (x_side == 1 && y_side == 1) ? 0xffffffff : 0xff000000;
250 x = x_coords[i][x_side];
251 y = y_coords[j][y_side];
252 if (x < 0 || x >= 640 || y < 0 || y >= 480)
253 continue;
254 color = get_readback_color(rb, x, y);
255 ok(color == expected, "%s: Pixel (%d, %d) has color %08x, expected %08x.\n",
256 message, x, y, color, expected);
263 static IDirect3DDevice8 *create_device(IDirect3D8 *d3d, HWND device_window, HWND focus_window, BOOL windowed)
265 D3DPRESENT_PARAMETERS present_parameters = {0};
266 IDirect3DDevice8 *device;
268 present_parameters.Windowed = windowed;
269 present_parameters.hDeviceWindow = device_window;
270 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
271 present_parameters.BackBufferWidth = 640;
272 present_parameters.BackBufferHeight = 480;
273 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
274 present_parameters.EnableAutoDepthStencil = TRUE;
275 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
277 if (SUCCEEDED(IDirect3D8_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, focus_window,
278 D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device)))
279 return device;
281 return NULL;
284 static void test_sanity(void)
286 IDirect3DDevice8 *device;
287 IDirect3D8 *d3d;
288 D3DCOLOR color;
289 ULONG refcount;
290 HWND window;
291 HRESULT hr;
293 window = create_window();
294 d3d = Direct3DCreate8(D3D_SDK_VERSION);
295 ok(!!d3d, "Failed to create a D3D object.\n");
296 if (!(device = create_device(d3d, window, window, TRUE)))
298 skip("Failed to create a D3D device, skipping tests.\n");
299 goto done;
302 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 1.0f, 0);
303 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
304 color = getPixelColor(device, 1, 1);
305 ok(color == 0x00ff0000, "Got unexpected color 0x%08x.\n", color);
307 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
308 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
310 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ddee, 1.0f, 0);
311 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
312 color = getPixelColor(device, 639, 479);
313 ok(color == 0x0000ddee, "Got unexpected color 0x%08x.\n", color);
315 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
316 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
318 refcount = IDirect3DDevice8_Release(device);
319 ok(!refcount, "Device has %u references left.\n", refcount);
320 done:
321 IDirect3D8_Release(d3d);
322 DestroyWindow(window);
325 static void lighting_test(void)
327 DWORD nfvf = D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_NORMAL;
328 DWORD fvf = D3DFVF_XYZ | D3DFVF_DIFFUSE;
329 IDirect3DDevice8 *device;
330 IDirect3D8 *d3d;
331 D3DCOLOR color;
332 ULONG refcount;
333 HWND window;
334 HRESULT hr;
335 unsigned int i;
337 static const struct
339 struct vec3 position;
340 DWORD diffuse;
342 unlitquad[] =
344 {{-1.0f, -1.0f, 0.1f}, 0xffff0000},
345 {{-1.0f, 0.0f, 0.1f}, 0xffff0000},
346 {{ 0.0f, 0.0f, 0.1f}, 0xffff0000},
347 {{ 0.0f, -1.0f, 0.1f}, 0xffff0000},
349 litquad[] =
351 {{-1.0f, 0.0f, 0.1f}, 0xff00ff00},
352 {{-1.0f, 1.0f, 0.1f}, 0xff00ff00},
353 {{ 0.0f, 1.0f, 0.1f}, 0xff00ff00},
354 {{ 0.0f, 0.0f, 0.1f}, 0xff00ff00},
356 static const struct
358 struct vec3 position;
359 struct vec3 normal;
360 DWORD diffuse;
362 unlitnquad[] =
364 {{0.0f, -1.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xff0000ff},
365 {{0.0f, 0.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xff0000ff},
366 {{1.0f, 0.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xff0000ff},
367 {{1.0f, -1.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xff0000ff},
369 litnquad[] =
371 {{0.0f, 0.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xffffff00},
372 {{0.0f, 1.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xffffff00},
373 {{1.0f, 1.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xffffff00},
374 {{1.0f, 0.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xffffff00},
376 nquad[] =
378 {{-1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
379 {{-1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
380 {{ 1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
381 {{ 1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
383 rotatedquad[] =
385 {{-10.0f, -11.0f, 11.0f}, {-1.0f, 0.0f, 0.0f}, 0xff0000ff},
386 {{-10.0f, -9.0f, 11.0f}, {-1.0f, 0.0f, 0.0f}, 0xff0000ff},
387 {{-10.0f, -9.0f, 9.0f}, {-1.0f, 0.0f, 0.0f}, 0xff0000ff},
388 {{-10.0f, -11.0f, 9.0f}, {-1.0f, 0.0f, 0.0f}, 0xff0000ff},
390 translatedquad[] =
392 {{-11.0f, -11.0f, -10.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
393 {{-11.0f, -9.0f, -10.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
394 {{ -9.0f, -9.0f, -10.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
395 {{ -9.0f, -11.0f, -10.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
397 static const WORD indices[] = {0, 1, 2, 2, 3, 0};
398 static const D3DMATRIX mat =
400 1.0f, 0.0f, 0.0f, 0.0f,
401 0.0f, 1.0f, 0.0f, 0.0f,
402 0.0f, 0.0f, 1.0f, 0.0f,
403 0.0f, 0.0f, 0.0f, 1.0f,
404 }}},
405 mat_singular =
407 1.0f, 0.0f, 1.0f, 0.0f,
408 0.0f, 1.0f, 0.0f, 0.0f,
409 1.0f, 0.0f, 1.0f, 0.0f,
410 0.0f, 0.0f, 0.5f, 1.0f,
411 }}},
412 mat_transf =
414 0.0f, 0.0f, 1.0f, 0.0f,
415 0.0f, 1.0f, 0.0f, 0.0f,
416 -1.0f, 0.0f, 0.0f, 0.0f,
417 10.f, 10.0f, 10.0f, 1.0f,
418 }}},
419 mat_nonaffine =
421 1.0f, 0.0f, 0.0f, 0.0f,
422 0.0f, 1.0f, 0.0f, 0.0f,
423 0.0f, 0.0f, 1.0f, -1.0f,
424 10.f, 10.0f, 10.0f, 0.0f,
425 }}};
426 static const struct
428 const D3DMATRIX *world_matrix;
429 const void *quad;
430 unsigned int size;
431 DWORD expected;
432 const char *message;
434 tests[] =
436 {&mat, nquad, sizeof(nquad[0]), 0x000000ff, "Lit quad with light"},
437 {&mat_singular, nquad, sizeof(nquad[0]), 0x000000ff, "Lit quad with singular world matrix"},
438 {&mat_transf, rotatedquad, sizeof(rotatedquad[0]), 0x000000ff, "Lit quad with transformation matrix"},
439 {&mat_nonaffine, translatedquad, sizeof(translatedquad[0]), 0x00000000, "Lit quad with non-affine matrix"},
442 window = create_window();
443 d3d = Direct3DCreate8(D3D_SDK_VERSION);
444 ok(!!d3d, "Failed to create a D3D object.\n");
445 if (!(device = create_device(d3d, window, window, TRUE)))
447 skip("Failed to create a D3D device, skipping tests.\n");
448 goto done;
451 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
452 ok(hr == D3D_OK, "IDirect3DDevice8_Clear failed with %#08x\n", hr);
454 hr = IDirect3DDevice8_SetTransform(device, D3DTS_WORLDMATRIX(0), &mat);
455 ok(hr == D3D_OK, "IDirect3DDevice8_SetTransform returned %#08x\n", hr);
456 hr = IDirect3DDevice8_SetTransform(device, D3DTS_VIEW, &mat);
457 ok(hr == D3D_OK, "IDirect3DDevice8_SetTransform returned %#08x\n", hr);
458 hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, &mat);
459 ok(hr == D3D_OK, "IDirect3DDevice8_SetTransform returned %#08x\n", hr);
460 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, FALSE);
461 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %#08x\n", hr);
462 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, FALSE);
463 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %#08x\n", hr);
464 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
465 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %#08x\n", hr);
466 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
467 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %#08x\n", hr);
468 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
469 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed with %#08x\n", hr);
471 hr = IDirect3DDevice8_SetVertexShader(device, fvf);
472 ok(hr == D3D_OK, "IDirect3DDevice8_SetVertexShader returned %#08x\n", hr);
474 hr = IDirect3DDevice8_BeginScene(device);
475 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
477 /* No lights are defined... That means, lit vertices should be entirely black. */
478 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
479 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
480 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
481 2, indices, D3DFMT_INDEX16, unlitquad, sizeof(unlitquad[0]));
482 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
484 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, TRUE);
485 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
486 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
487 2, indices, D3DFMT_INDEX16, litquad, sizeof(litquad[0]));
488 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
490 hr = IDirect3DDevice8_SetVertexShader(device, nfvf);
491 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
493 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
494 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
495 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
496 2, indices, D3DFMT_INDEX16, unlitnquad, sizeof(unlitnquad[0]));
497 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
499 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, TRUE);
500 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
501 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
502 2, indices, D3DFMT_INDEX16, litnquad, sizeof(litnquad[0]));
503 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
505 hr = IDirect3DDevice8_EndScene(device);
506 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
508 color = getPixelColor(device, 160, 360); /* Lower left quad - unlit without normals */
509 ok(color == 0x00ff0000, "Unlit quad without normals has color 0x%08x, expected 0x00ff0000.\n", color);
510 color = getPixelColor(device, 160, 120); /* Upper left quad - lit without normals */
511 ok(color == 0x00000000, "Lit quad without normals has color 0x%08x, expected 0x00000000.\n", color);
512 color = getPixelColor(device, 480, 360); /* Lower right quad - unlit with normals */
513 ok(color == 0x000000ff, "Unlit quad with normals has color 0x%08x, expected 0x000000ff.\n", color);
514 color = getPixelColor(device, 480, 120); /* Upper right quad - lit with normals */
515 ok(color == 0x00000000, "Lit quad with normals has color 0x%08x, expected 0x00000000.\n", color);
517 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
519 hr = IDirect3DDevice8_LightEnable(device, 0, TRUE);
520 ok(SUCCEEDED(hr), "Failed to enable light 0, hr %#x.\n", hr);
522 for (i = 0; i < ARRAY_SIZE(tests); ++i)
524 hr = IDirect3DDevice8_SetTransform(device, D3DTS_WORLD, tests[i].world_matrix);
525 ok(SUCCEEDED(hr), "Failed to set world transform, hr %#x.\n", hr);
527 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
528 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
530 hr = IDirect3DDevice8_BeginScene(device);
531 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
533 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
534 2, indices, D3DFMT_INDEX16, tests[i].quad, tests[i].size);
535 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
537 hr = IDirect3DDevice8_EndScene(device);
538 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
540 color = getPixelColor(device, 320, 240);
541 ok(color == tests[i].expected, "%s has color 0x%08x.\n", tests[i].message, color);
544 refcount = IDirect3DDevice8_Release(device);
545 ok(!refcount, "Device has %u references left.\n", refcount);
546 done:
547 IDirect3D8_Release(d3d);
548 DestroyWindow(window);
551 static void test_specular_lighting(void)
553 static const unsigned int vertices_side = 5;
554 const unsigned int indices_count = (vertices_side - 1) * (vertices_side - 1) * 2 * 3;
555 static const DWORD fvf = D3DFVF_XYZ | D3DFVF_NORMAL;
556 static const D3DMATRIX mat =
558 1.0f, 0.0f, 0.0f, 0.0f,
559 0.0f, 1.0f, 0.0f, 0.0f,
560 0.0f, 0.0f, 1.0f, 0.0f,
561 0.0f, 0.0f, 0.0f, 1.0f,
562 }}};
563 static const D3DLIGHT8 directional =
565 D3DLIGHT_DIRECTIONAL,
566 {0.0f, 0.0f, 0.0f, 0.0f},
567 {1.0f, 1.0f, 1.0f, 0.0f},
568 {0.0f, 0.0f, 0.0f, 0.0f},
569 {0.0f, 0.0f, 0.0f},
570 {0.0f, 0.0f, 1.0f},
572 point =
574 D3DLIGHT_POINT,
575 {0.0f, 0.0f, 0.0f, 0.0f},
576 {1.0f, 1.0f, 1.0f, 0.0f},
577 {0.0f, 0.0f, 0.0f, 0.0f},
578 {0.0f, 0.0f, 0.0f},
579 {0.0f, 0.0f, 0.0f},
580 100.0f,
581 0.0f,
582 0.0f, 0.0f, 1.0f,
584 spot =
586 D3DLIGHT_SPOT,
587 {0.0f, 0.0f, 0.0f, 0.0f},
588 {1.0f, 1.0f, 1.0f, 0.0f},
589 {0.0f, 0.0f, 0.0f, 0.0f},
590 {0.0f, 0.0f, 0.0f},
591 {0.0f, 0.0f, 1.0f},
592 100.0f,
593 1.0f,
594 0.0f, 0.0f, 1.0f,
595 M_PI / 12.0f, M_PI / 3.0f
597 /* The chosen range value makes the test fail when using a manhattan
598 * distance metric vs the correct euclidean distance. */
599 point_range =
601 D3DLIGHT_POINT,
602 {0.0f, 0.0f, 0.0f, 0.0f},
603 {1.0f, 1.0f, 1.0f, 0.0f},
604 {0.0f, 0.0f, 0.0f, 0.0f},
605 {0.0f, 0.0f, 0.0f},
606 {0.0f, 0.0f, 0.0f},
607 1.2f,
608 0.0f,
609 0.0f, 0.0f, 1.0f,
611 point_side =
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 {-1.1f, 0.0f, 1.1f},
618 {0.0f, 0.0f, 0.0f},
619 100.0f,
620 0.0f,
621 0.0f, 0.0f, 1.0f,
623 static const struct expected_color
625 unsigned int x, y;
626 D3DCOLOR color;
628 expected_directional[] =
630 {160, 120, 0x00ffffff},
631 {320, 120, 0x00ffffff},
632 {480, 120, 0x00ffffff},
633 {160, 240, 0x00ffffff},
634 {320, 240, 0x00ffffff},
635 {480, 240, 0x00ffffff},
636 {160, 360, 0x00ffffff},
637 {320, 360, 0x00ffffff},
638 {480, 360, 0x00ffffff},
640 expected_directional_local[] =
642 {160, 120, 0x003c3c3c},
643 {320, 120, 0x00717171},
644 {480, 120, 0x003c3c3c},
645 {160, 240, 0x00717171},
646 {320, 240, 0x00ffffff},
647 {480, 240, 0x00717171},
648 {160, 360, 0x003c3c3c},
649 {320, 360, 0x00717171},
650 {480, 360, 0x003c3c3c},
652 expected_point[] =
654 {160, 120, 0x00282828},
655 {320, 120, 0x005a5a5a},
656 {480, 120, 0x00282828},
657 {160, 240, 0x005a5a5a},
658 {320, 240, 0x00ffffff},
659 {480, 240, 0x005a5a5a},
660 {160, 360, 0x00282828},
661 {320, 360, 0x005a5a5a},
662 {480, 360, 0x00282828},
664 expected_point_local[] =
666 {160, 120, 0x00000000},
667 {320, 120, 0x00070707},
668 {480, 120, 0x00000000},
669 {160, 240, 0x00070707},
670 {320, 240, 0x00ffffff},
671 {480, 240, 0x00070707},
672 {160, 360, 0x00000000},
673 {320, 360, 0x00070707},
674 {480, 360, 0x00000000},
676 expected_spot[] =
678 {160, 120, 0x00000000},
679 {320, 120, 0x00141414},
680 {480, 120, 0x00000000},
681 {160, 240, 0x00141414},
682 {320, 240, 0x00ffffff},
683 {480, 240, 0x00141414},
684 {160, 360, 0x00000000},
685 {320, 360, 0x00141414},
686 {480, 360, 0x00000000},
688 expected_spot_local[] =
690 {160, 120, 0x00000000},
691 {320, 120, 0x00020202},
692 {480, 120, 0x00000000},
693 {160, 240, 0x00020202},
694 {320, 240, 0x00ffffff},
695 {480, 240, 0x00020202},
696 {160, 360, 0x00000000},
697 {320, 360, 0x00020202},
698 {480, 360, 0x00000000},
700 expected_point_range[] =
702 {160, 120, 0x00000000},
703 {320, 120, 0x005a5a5a},
704 {480, 120, 0x00000000},
705 {160, 240, 0x005a5a5a},
706 {320, 240, 0x00ffffff},
707 {480, 240, 0x005a5a5a},
708 {160, 360, 0x00000000},
709 {320, 360, 0x005a5a5a},
710 {480, 360, 0x00000000},
712 expected_point_side[] =
714 {160, 120, 0x00000000},
715 {320, 120, 0x00000000},
716 {480, 120, 0x00000000},
717 {160, 240, 0x00000000},
718 {320, 240, 0x00000000},
719 {480, 240, 0x00000000},
720 {160, 360, 0x00000000},
721 {320, 360, 0x00000000},
722 {480, 360, 0x00000000},
724 expected_directional_0[] =
726 {160, 120, 0x00ffffff},
727 {320, 120, 0x00ffffff},
728 {480, 120, 0x00ffffff},
729 {160, 240, 0x00ffffff},
730 {320, 240, 0x00ffffff},
731 {480, 240, 0x00ffffff},
732 {160, 360, 0x00ffffff},
733 {320, 360, 0x00ffffff},
734 {480, 360, 0x00ffffff},
736 expected_directional_local_0[] =
738 {160, 120, 0x00ffffff},
739 {320, 120, 0x00ffffff},
740 {480, 120, 0x00ffffff},
741 {160, 240, 0x00ffffff},
742 {320, 240, 0x00ffffff},
743 {480, 240, 0x00ffffff},
744 {160, 360, 0x00ffffff},
745 {320, 360, 0x00ffffff},
746 {480, 360, 0x00ffffff},
748 expected_point_0[] =
750 {160, 120, 0x00aaaaaa},
751 {320, 120, 0x00cccccc},
752 {480, 120, 0x00aaaaaa},
753 {160, 240, 0x00cccccc},
754 {320, 240, 0x00ffffff},
755 {480, 240, 0x00cccccc},
756 {160, 360, 0x00aaaaaa},
757 {320, 360, 0x00cccccc},
758 {480, 360, 0x00aaaaaa},
760 expected_spot_0[] =
762 {160, 120, 0x00000000},
763 {320, 120, 0x002e2e2e},
764 {480, 120, 0x00000000},
765 {160, 240, 0x002e2e2e},
766 {320, 240, 0x00ffffff},
767 {480, 240, 0x002e2e2e},
768 {160, 360, 0x00000000},
769 {320, 360, 0x002e2e2e},
770 {480, 360, 0x00000000},
772 expected_point_range_0[] =
774 {160, 120, 0x00000000},
775 {320, 120, 0x00cccccc},
776 {480, 120, 0x00000000},
777 {160, 240, 0x00cccccc},
778 {320, 240, 0x00ffffff},
779 {480, 240, 0x00cccccc},
780 {160, 360, 0x00000000},
781 {320, 360, 0x00cccccc},
782 {480, 360, 0x00000000},
784 static const struct
786 const D3DLIGHT8 *light;
787 BOOL local_viewer;
788 float specular_power;
789 const struct expected_color *expected;
790 unsigned int expected_count;
792 tests[] =
794 {&directional, FALSE, 30.0f, expected_directional, ARRAY_SIZE(expected_directional)},
795 {&directional, TRUE, 30.0f, expected_directional_local, ARRAY_SIZE(expected_directional_local)},
796 {&point, FALSE, 30.0f, expected_point, ARRAY_SIZE(expected_point)},
797 {&point, TRUE, 30.0f, expected_point_local, ARRAY_SIZE(expected_point_local)},
798 {&spot, FALSE, 30.0f, expected_spot, ARRAY_SIZE(expected_spot)},
799 {&spot, TRUE, 30.0f, expected_spot_local, ARRAY_SIZE(expected_spot_local)},
800 {&point_range, FALSE, 30.0f, expected_point_range, ARRAY_SIZE(expected_point_range)},
801 {&point_side, TRUE, 0.0f, expected_point_side, ARRAY_SIZE(expected_point_side)},
802 {&directional, FALSE, 0.0f, expected_directional_0, ARRAY_SIZE(expected_directional_0)},
803 {&directional, TRUE, 0.0f, expected_directional_local_0, ARRAY_SIZE(expected_directional_local_0)},
804 {&point, FALSE, 0.0f, expected_point_0, ARRAY_SIZE(expected_point_0)},
805 {&point, TRUE, 0.0f, expected_point_0, ARRAY_SIZE(expected_point_0)},
806 {&spot, FALSE, 0.0f, expected_spot_0, ARRAY_SIZE(expected_spot_0)},
807 {&spot, TRUE, 0.0f, expected_spot_0, ARRAY_SIZE(expected_spot_0)},
808 {&point_range, FALSE, 0.0f, expected_point_range_0, ARRAY_SIZE(expected_point_range_0)},
810 IDirect3DDevice8 *device;
811 D3DMATERIAL8 material;
812 IDirect3D8 *d3d;
813 D3DCOLOR color;
814 ULONG refcount;
815 HWND window;
816 HRESULT hr;
817 unsigned int i, j, x, y;
818 struct
820 struct vec3 position;
821 struct vec3 normal;
822 } *quad;
823 WORD *indices;
825 quad = HeapAlloc(GetProcessHeap(), 0, vertices_side * vertices_side * sizeof(*quad));
826 indices = HeapAlloc(GetProcessHeap(), 0, indices_count * sizeof(*indices));
827 for (i = 0, y = 0; y < vertices_side; ++y)
829 for (x = 0; x < vertices_side; ++x)
831 quad[i].position.x = x * 2.0f / (vertices_side - 1) - 1.0f;
832 quad[i].position.y = y * 2.0f / (vertices_side - 1) - 1.0f;
833 quad[i].position.z = 1.0f;
834 quad[i].normal.x = 0.0f;
835 quad[i].normal.y = 0.0f;
836 quad[i++].normal.z = -1.0f;
839 for (i = 0, y = 0; y < (vertices_side - 1); ++y)
841 for (x = 0; x < (vertices_side - 1); ++x)
843 indices[i++] = y * vertices_side + x + 1;
844 indices[i++] = y * vertices_side + x;
845 indices[i++] = (y + 1) * vertices_side + x;
846 indices[i++] = y * vertices_side + x + 1;
847 indices[i++] = (y + 1) * vertices_side + x;
848 indices[i++] = (y + 1) * vertices_side + x + 1;
852 window = create_window();
853 d3d = Direct3DCreate8(D3D_SDK_VERSION);
854 ok(!!d3d, "Failed to create a D3D object.\n");
855 if (!(device = create_device(d3d, window, window, TRUE)))
857 skip("Failed to create a D3D device, skipping tests.\n");
858 goto done;
861 hr = IDirect3DDevice8_SetTransform(device, D3DTS_WORLD, &mat);
862 ok(SUCCEEDED(hr), "Failed to set world transform, hr %#x.\n", hr);
863 hr = IDirect3DDevice8_SetTransform(device, D3DTS_VIEW, &mat);
864 ok(SUCCEEDED(hr), "Failed to set view transform, hr %#x.\n", hr);
865 hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, &mat);
866 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
867 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, FALSE);
868 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#x.\n", hr);
869 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, FALSE);
870 ok(SUCCEEDED(hr), "Failed to disable z test, hr %#x.\n", hr);
871 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
872 ok(SUCCEEDED(hr), "Failed to disable fog, hr %#x.\n", hr);
874 hr = IDirect3DDevice8_SetVertexShader(device, fvf);
875 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
877 hr = IDirect3DDevice8_LightEnable(device, 0, TRUE);
878 ok(SUCCEEDED(hr), "Failed to enable light 0, hr %#x.\n", hr);
879 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SPECULARENABLE, TRUE);
880 ok(SUCCEEDED(hr), "Failed to enable specular lighting, hr %#x.\n", hr);
882 for (i = 0; i < ARRAY_SIZE(tests); ++i)
884 hr = IDirect3DDevice8_SetLight(device, 0, tests[i].light);
885 ok(SUCCEEDED(hr), "Failed to set light parameters, hr %#x.\n", hr);
887 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LOCALVIEWER, tests[i].local_viewer);
888 ok(SUCCEEDED(hr), "Failed to set local viewer state, hr %#x.\n", hr);
890 memset(&material, 0, sizeof(material));
891 material.Specular.r = 1.0f;
892 material.Specular.g = 1.0f;
893 material.Specular.b = 1.0f;
894 material.Specular.a = 1.0f;
895 material.Power = tests[i].specular_power;
896 hr = IDirect3DDevice8_SetMaterial(device, &material);
897 ok(SUCCEEDED(hr), "Failed to set material, hr %#x.\n", hr);
899 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
900 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
902 hr = IDirect3DDevice8_BeginScene(device);
903 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
905 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST,
906 0, vertices_side * vertices_side, indices_count / 3, indices,
907 D3DFMT_INDEX16, quad, sizeof(quad[0]));
908 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
910 hr = IDirect3DDevice8_EndScene(device);
911 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
913 for (j = 0; j < tests[i].expected_count; ++j)
915 color = getPixelColor(device, tests[i].expected[j].x, tests[i].expected[j].y);
916 ok(color_match(color, tests[i].expected[j].color, 1),
917 "Expected color 0x%08x at location (%u, %u), got 0x%08x, case %u.\n",
918 tests[i].expected[j].color, tests[i].expected[j].x,
919 tests[i].expected[j].y, color, i);
923 refcount = IDirect3DDevice8_Release(device);
924 ok(!refcount, "Device has %u references left.\n", refcount);
925 done:
926 IDirect3D8_Release(d3d);
927 DestroyWindow(window);
928 HeapFree(GetProcessHeap(), 0, indices);
929 HeapFree(GetProcessHeap(), 0, quad);
932 static void clear_test(void)
934 /* Tests the correctness of clearing parameters */
935 D3DRECT rect_negneg, rect[2];
936 IDirect3DDevice8 *device;
937 IDirect3D8 *d3d;
938 D3DCOLOR color;
939 ULONG refcount;
940 HWND window;
941 HRESULT hr;
943 window = create_window();
944 d3d = Direct3DCreate8(D3D_SDK_VERSION);
945 ok(!!d3d, "Failed to create a D3D object.\n");
946 if (!(device = create_device(d3d, window, window, TRUE)))
948 skip("Failed to create a D3D device, skipping tests.\n");
949 goto done;
952 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
953 ok(hr == D3D_OK, "IDirect3DDevice8_Clear failed with %#08x\n", hr);
955 /* Positive x, negative y */
956 rect[0].x1 = 0;
957 rect[0].y1 = 480;
958 rect[0].x2 = 320;
959 rect[0].y2 = 240;
961 /* Positive x, positive y */
962 rect[1].x1 = 0;
963 rect[1].y1 = 0;
964 rect[1].x2 = 320;
965 rect[1].y2 = 240;
966 /* Clear 2 rectangles with one call. Shows that a positive value is returned, but the negative rectangle
967 * is ignored, the positive is still cleared afterwards
969 hr = IDirect3DDevice8_Clear(device, 2, rect, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
970 ok(hr == D3D_OK, "IDirect3DDevice8_Clear failed with %#08x\n", hr);
972 /* negative x, negative y */
973 rect_negneg.x1 = 640;
974 rect_negneg.y1 = 240;
975 rect_negneg.x2 = 320;
976 rect_negneg.y2 = 0;
977 hr = IDirect3DDevice8_Clear(device, 1, &rect_negneg, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
978 ok(hr == D3D_OK, "IDirect3DDevice8_Clear failed with %#08x\n", hr);
980 color = getPixelColor(device, 160, 360); /* lower left quad */
981 ok(color == 0x00ffffff, "Clear rectangle 3(pos, neg) has color %08x\n", color);
982 color = getPixelColor(device, 160, 120); /* upper left quad */
983 ok(color == 0x00ff0000, "Clear rectangle 1(pos, pos) has color %08x\n", color);
984 color = getPixelColor(device, 480, 360); /* lower right quad */
985 ok(color == 0x00ffffff, "Clear rectangle 4(NULL) has color %08x\n", color);
986 color = getPixelColor(device, 480, 120); /* upper right quad */
987 ok(color == 0x00ffffff, "Clear rectangle 4(neg, neg) has color %08x\n", color);
989 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
991 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
992 ok(SUCCEEDED(hr), "IDirect3DDevice8_Clear failed with %#08x\n", hr);
994 rect[0].x1 = 0;
995 rect[0].y1 = 0;
996 rect[0].x2 = 640;
997 rect[0].y2 = 480;
998 hr = IDirect3DDevice8_Clear(device, 0, rect, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
999 ok(SUCCEEDED(hr), "IDirect3DDevice8_Clear failed with %#08x\n", hr);
1001 color = getPixelColor(device, 320, 240);
1002 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff), 1),
1003 "Clear with count = 0, rect != NULL has color %#08x\n", color);
1005 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
1007 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
1008 ok(SUCCEEDED(hr), "IDirect3DDevice8_Clear failed with %#08x\n", hr);
1009 hr = IDirect3DDevice8_Clear(device, 1, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
1010 ok(SUCCEEDED(hr), "IDirect3DDevice8_Clear failed with %#08x\n", hr);
1012 color = getPixelColor(device, 320, 240);
1013 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
1014 "Clear with count = 1, rect = NULL has color %#08x\n", color);
1016 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
1018 refcount = IDirect3DDevice8_Release(device);
1019 ok(!refcount, "Device has %u references left.\n", refcount);
1020 done:
1021 IDirect3D8_Release(d3d);
1022 DestroyWindow(window);
1025 static void fog_test(void)
1027 float start = 0.0f, end = 1.0f;
1028 IDirect3DDevice8 *device;
1029 IDirect3D8 *d3d;
1030 D3DCOLOR color;
1031 ULONG refcount;
1032 D3DCAPS8 caps;
1033 HWND window;
1034 HRESULT hr;
1036 /* Gets full z based fog with linear fog, no fog with specular color. */
1037 static const struct
1039 float x, y, z;
1040 D3DCOLOR diffuse;
1041 D3DCOLOR specular;
1043 untransformed_1[] =
1045 {-1.0f, -1.0f, 0.1f, 0xffff0000, 0xff000000},
1046 {-1.0f, 0.0f, 0.1f, 0xffff0000, 0xff000000},
1047 { 0.0f, 0.0f, 0.1f, 0xffff0000, 0xff000000},
1048 { 0.0f, -1.0f, 0.1f, 0xffff0000, 0xff000000},
1050 /* Ok, I am too lazy to deal with transform matrices. */
1051 untransformed_2[] =
1053 {-1.0f, 0.0f, 1.0f, 0xffff0000, 0xff000000},
1054 {-1.0f, 1.0f, 1.0f, 0xffff0000, 0xff000000},
1055 { 0.0f, 1.0f, 1.0f, 0xffff0000, 0xff000000},
1056 { 0.0f, 0.0f, 1.0f, 0xffff0000, 0xff000000},
1058 far_quad1[] =
1060 {-1.0f, -1.0f, 0.5f, 0xffff0000, 0xff000000},
1061 {-1.0f, 0.0f, 0.5f, 0xffff0000, 0xff000000},
1062 { 0.0f, 0.0f, 0.5f, 0xffff0000, 0xff000000},
1063 { 0.0f, -1.0f, 0.5f, 0xffff0000, 0xff000000},
1065 far_quad2[] =
1067 {-1.0f, 0.0f, 1.5f, 0xffff0000, 0xff000000},
1068 {-1.0f, 1.0f, 1.5f, 0xffff0000, 0xff000000},
1069 { 0.0f, 1.0f, 1.5f, 0xffff0000, 0xff000000},
1070 { 0.0f, 0.0f, 1.5f, 0xffff0000, 0xff000000},
1073 /* Untransformed ones. Give them a different diffuse color to make the
1074 * test look nicer. It also makes making sure that they are drawn
1075 * correctly easier. */
1076 static const struct
1078 float x, y, z, rhw;
1079 D3DCOLOR diffuse;
1080 D3DCOLOR specular;
1082 transformed_1[] =
1084 {320.0f, 0.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
1085 {640.0f, 0.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
1086 {640.0f, 240.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
1087 {320.0f, 240.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
1089 transformed_2[] =
1091 {320.0f, 240.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
1092 {640.0f, 240.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
1093 {640.0f, 480.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
1094 {320.0f, 480.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
1096 static const D3DMATRIX ident_mat =
1098 1.0f, 0.0f, 0.0f, 0.0f,
1099 0.0f, 1.0f, 0.0f, 0.0f,
1100 0.0f, 0.0f, 1.0f, 0.0f,
1101 0.0f, 0.0f, 0.0f, 1.0f,
1102 }}};
1103 static const D3DMATRIX world_mat1 =
1105 1.0f, 0.0f, 0.0f, 0.0f,
1106 0.0f, 1.0f, 0.0f, 0.0f,
1107 0.0f, 0.0f, 1.0f, 0.0f,
1108 0.0f, 0.0f, -0.5f, 1.0f,
1109 }}};
1110 static const D3DMATRIX world_mat2 =
1112 1.0f, 0.0f, 0.0f, 0.0f,
1113 0.0f, 1.0f, 0.0f, 0.0f,
1114 0.0f, 0.0f, 1.0f, 0.0f,
1115 0.0f, 0.0f, 1.0f, 1.0f,
1116 }}};
1117 static const D3DMATRIX proj_mat =
1119 1.0f, 0.0f, 0.0f, 0.0f,
1120 0.0f, 1.0f, 0.0f, 0.0f,
1121 0.0f, 0.0f, 1.0f, 0.0f,
1122 0.0f, 0.0f, -1.0f, 1.0f,
1123 }}};
1124 static const WORD Indices[] = {0, 1, 2, 2, 3, 0};
1126 window = create_window();
1127 d3d = Direct3DCreate8(D3D_SDK_VERSION);
1128 ok(!!d3d, "Failed to create a D3D object.\n");
1129 if (!(device = create_device(d3d, window, window, TRUE)))
1131 skip("Failed to create a D3D device, skipping tests.\n");
1132 goto done;
1135 memset(&caps, 0, sizeof(caps));
1136 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
1137 ok(hr == D3D_OK, "IDirect3DDevice8_GetDeviceCaps returned %08x\n", hr);
1138 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1139 ok(hr == D3D_OK, "IDirect3DDevice8_Clear returned %#08x\n", hr);
1141 /* Setup initial states: No lighting, fog on, fog color */
1142 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, FALSE);
1143 ok(SUCCEEDED(hr), "Failed to disable D3DRS_ZENABLE, hr %#x.\n", hr);
1144 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1145 ok(hr == D3D_OK, "Turning off lighting returned %#08x\n", hr);
1146 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
1147 ok(hr == D3D_OK, "Turning on fog calculations returned %#08x\n", hr);
1148 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
1149 ok(hr == D3D_OK, "Setting fog color returned %#08x\n", hr);
1150 /* Some of the tests seem to depend on the projection matrix explicitly
1151 * being set to an identity matrix, even though that's the default.
1152 * (AMD Radeon HD 6310, Windows 7) */
1153 hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, &ident_mat);
1154 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
1156 /* First test: Both table fog and vertex fog off */
1157 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1158 ok(hr == D3D_OK, "Turning off table fog returned %#08x\n", hr);
1159 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
1160 ok(hr == D3D_OK, "Turning off vertex fog returned %#08x\n", hr);
1162 /* Start = 0, end = 1. Should be default, but set them */
1163 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1164 ok(hr == D3D_OK, "Setting fog start returned %#08x\n", hr);
1165 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1166 ok(hr == D3D_OK, "Setting fog start returned %#08x\n", hr);
1168 hr = IDirect3DDevice8_BeginScene(device);
1169 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
1171 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1172 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
1173 /* Untransformed, vertex fog = NONE, table fog = NONE:
1174 * Read the fog weighting from the specular color. */
1175 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1176 2 /* PrimCount */, Indices, D3DFMT_INDEX16, untransformed_1, sizeof(untransformed_1[0]));
1177 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1179 /* This makes it use the Z value. */
1180 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1181 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
1182 /* Untransformed, vertex fog != none (or table fog != none):
1183 * Use the Z value as input into the equation. */
1184 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1185 2 /* PrimCount */, Indices, D3DFMT_INDEX16, untransformed_2, sizeof(untransformed_2[0]));
1186 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1188 /* Transformed vertices. */
1189 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1190 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
1191 /* Transformed, vertex fog != NONE, pixel fog == NONE:
1192 * Use specular color alpha component. */
1193 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1194 2 /* PrimCount */, Indices, D3DFMT_INDEX16, transformed_1, sizeof(transformed_1[0]));
1195 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1197 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
1198 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
1199 /* Transformed, table fog != none, vertex anything:
1200 * Use Z value as input to the fog equation. */
1201 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1202 2 /* PrimCount */, Indices, D3DFMT_INDEX16, transformed_2, sizeof(transformed_2[0]));
1203 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1205 hr = IDirect3DDevice8_EndScene(device);
1206 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
1208 color = getPixelColor(device, 160, 360);
1209 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xFF, 0x00, 0x00), 1),
1210 "Untransformed vertex with no table or vertex fog has color %08x\n", color);
1211 color = getPixelColor(device, 160, 120);
1212 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xFF, 0x00), 1),
1213 "Untransformed vertex with linear vertex fog has color %08x\n", color);
1214 color = getPixelColor(device, 480, 120);
1215 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xFF, 0xFF, 0x00), 1),
1216 "Transformed vertex with linear vertex fog has color %08x\n", color);
1217 color = getPixelColor(device, 480, 360);
1218 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xFF, 0x00), 1),
1219 "Transformed vertex with linear table fog has color %08x\n", color);
1221 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
1223 if (caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)
1225 /* A simple fog + non-identity world matrix test */
1226 hr = IDirect3DDevice8_SetTransform(device, D3DTS_WORLDMATRIX(0), &world_mat1);
1227 ok(hr == D3D_OK, "IDirect3DDevice8_SetTransform returned %#08x\n", hr);
1229 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
1230 ok(hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %#08x\n", hr);
1231 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
1232 ok(hr == D3D_OK, "Turning off vertex fog returned %#08x\n", hr);
1234 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1235 ok(hr == D3D_OK, "IDirect3DDevice8_Clear returned %#08x\n", hr);
1237 hr = IDirect3DDevice8_BeginScene(device);
1238 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
1239 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1240 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
1241 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
1242 2, Indices, D3DFMT_INDEX16, far_quad1, sizeof(far_quad1[0]));
1243 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1244 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
1245 2, Indices, D3DFMT_INDEX16, far_quad2, sizeof(far_quad2[0]));
1246 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1247 hr = IDirect3DDevice8_EndScene(device);
1248 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
1250 color = getPixelColor(device, 160, 360);
1251 ok(color_match(color, 0x00ff0000, 4), "Unfogged quad has color %08x\n", color);
1252 color = getPixelColor(device, 160, 120);
1253 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
1254 "Fogged out quad has color %08x\n", color);
1256 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
1258 /* Test fog behavior with an orthogonal (but not identity) projection matrix */
1259 hr = IDirect3DDevice8_SetTransform(device, D3DTS_WORLDMATRIX(0), &world_mat2);
1260 ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
1261 hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, &proj_mat);
1262 ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
1264 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1265 ok(hr == D3D_OK, "Clear returned %#08x\n", hr);
1267 hr = IDirect3DDevice8_BeginScene(device);
1268 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
1269 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1270 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
1271 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
1272 2, Indices, D3DFMT_INDEX16, untransformed_1, sizeof(untransformed_1[0]));
1273 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1274 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
1275 2, Indices, D3DFMT_INDEX16, untransformed_2, sizeof(untransformed_2[0]));
1276 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1277 hr = IDirect3DDevice8_EndScene(device);
1278 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
1280 color = getPixelColor(device, 160, 360);
1281 ok(color_match(color, 0x00e51900, 4), "Partially fogged quad has color %08x\n", color);
1282 color = getPixelColor(device, 160, 120);
1283 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
1284 "Fogged out quad has color %08x\n", color);
1286 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
1288 else
1290 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping some fog tests\n");
1293 refcount = IDirect3DDevice8_Release(device);
1294 ok(!refcount, "Device has %u references left.\n", refcount);
1295 done:
1296 IDirect3D8_Release(d3d);
1297 DestroyWindow(window);
1300 /* This tests fog in combination with shaders.
1301 * What's tested: linear fog (vertex and table) with pixel shader
1302 * linear table fog with non foggy vertex shader
1303 * vertex fog with foggy vertex shader, non-linear
1304 * fog with shader, non-linear fog with foggy shader,
1305 * linear table fog with foggy shader */
1306 static void fog_with_shader_test(void)
1308 /* Fill the null-shader entry with the FVF (SetVertexShader is "overloaded" on d3d8...) */
1309 DWORD vertex_shader[3] = {D3DFVF_XYZ | D3DFVF_DIFFUSE, 0, 0};
1310 DWORD pixel_shader[2] = {0, 0};
1311 IDirect3DDevice8 *device;
1312 unsigned int i, j;
1313 IDirect3D8 *d3d;
1314 D3DCOLOR color;
1315 ULONG refcount;
1316 D3DCAPS8 caps;
1317 HWND window;
1318 HRESULT hr;
1319 union
1321 float f;
1322 DWORD i;
1323 } start, end;
1325 /* Basic vertex shader without fog computation ("non foggy") */
1326 static const DWORD vertex_shader_code1[] =
1328 0xfffe0100, /* vs.1.0 */
1329 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1330 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
1331 0x0000ffff
1333 /* Basic vertex shader with reversed fog computation ("foggy") */
1334 static const DWORD vertex_shader_code2[] =
1336 0xfffe0100, /* vs.1.0 */
1337 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1338 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
1339 0x00000002, 0x800f0000, 0x90aa0000, 0xa0aa0000, /* add r0, v0.z, c0.z */
1340 0x00000005, 0xc00f0001, 0x80000000, 0xa0000000, /* mul oFog, r0.x, c0.x */
1341 0x0000ffff
1343 /* Basic pixel shader */
1344 static const DWORD pixel_shader_code[] =
1346 0xffff0101, /* ps_1_1 */
1347 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
1348 0x0000ffff
1350 static struct
1352 struct vec3 position;
1353 DWORD diffuse;
1355 quad[] =
1357 {{-1.0f, -1.0f, 0.0f}, 0xffff0000},
1358 {{-1.0f, 1.0f, 0.0f}, 0xffff0000},
1359 {{ 1.0f, -1.0f, 0.0f}, 0xffff0000},
1360 {{ 1.0f, 1.0f, 0.0f}, 0xffff0000},
1362 static const DWORD decl[] =
1364 D3DVSD_STREAM(0),
1365 D3DVSD_REG(0, D3DVSDT_FLOAT3), /* position, v0 */
1366 D3DVSD_REG(1, D3DVSDT_D3DCOLOR), /* diffuse color, v1 */
1367 D3DVSD_END()
1369 static const float vs_constant[4] = {-1.25f, 0.0f, -0.9f, 0.0f};
1370 /* This reference data was collected on a nVidia GeForce 7600GS
1371 * driver version 84.19 DirectX version 9.0c on Windows XP */
1372 static const struct test_data_t
1374 int vshader;
1375 int pshader;
1376 D3DFOGMODE vfog;
1377 D3DFOGMODE tfog;
1378 BOOL uninitialized_reg;
1379 unsigned int color[11];
1381 test_data[] =
1383 /* Only pixel shader */
1384 {0, 1, D3DFOG_NONE, D3DFOG_LINEAR, FALSE,
1385 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1386 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1387 {0, 1, D3DFOG_EXP, D3DFOG_LINEAR, FALSE,
1388 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1389 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1390 {0, 1, D3DFOG_EXP2, D3DFOG_LINEAR, FALSE,
1391 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1392 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1393 {0, 1, D3DFOG_LINEAR, D3DFOG_NONE, FALSE,
1394 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1395 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1396 {0, 1, D3DFOG_LINEAR, D3DFOG_LINEAR, FALSE,
1397 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1398 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1400 /* Vertex shader */
1401 {1, 0, D3DFOG_NONE, D3DFOG_NONE, TRUE,
1402 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1403 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1404 {1, 0, D3DFOG_NONE, D3DFOG_LINEAR, FALSE,
1405 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1406 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1407 {1, 0, D3DFOG_EXP, D3DFOG_LINEAR, FALSE,
1408 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1409 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1411 {1, 0, D3DFOG_EXP2, D3DFOG_LINEAR, FALSE,
1412 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1413 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1414 {1, 0, D3DFOG_LINEAR, D3DFOG_LINEAR, FALSE,
1415 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1416 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1418 /* Vertex shader and pixel shader */
1419 /* The next 4 tests would read the fog coord output, but it isn't available.
1420 * The result is a fully fogged quad, no matter what the Z coord is. */
1421 {1, 1, D3DFOG_NONE, D3DFOG_NONE, TRUE,
1422 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1423 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1424 {1, 1, D3DFOG_LINEAR, D3DFOG_NONE, TRUE,
1425 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1426 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1427 {1, 1, D3DFOG_EXP, D3DFOG_NONE, TRUE,
1428 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1429 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1430 {1, 1, D3DFOG_EXP2, D3DFOG_NONE, TRUE,
1431 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1432 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1434 /* These use the Z coordinate with linear table fog */
1435 {1, 1, D3DFOG_NONE, D3DFOG_LINEAR, FALSE,
1436 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1437 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1438 {1, 1, D3DFOG_EXP, D3DFOG_LINEAR, FALSE,
1439 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1440 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1441 {1, 1, D3DFOG_EXP2, D3DFOG_LINEAR, FALSE,
1442 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1443 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1444 {1, 1, D3DFOG_LINEAR, D3DFOG_LINEAR, FALSE,
1445 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1446 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1448 /* Non-linear table fog without fog coord */
1449 {1, 1, D3DFOG_NONE, D3DFOG_EXP, FALSE,
1450 {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
1451 0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
1452 {1, 1, D3DFOG_NONE, D3DFOG_EXP2, FALSE,
1453 {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
1454 0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
1456 /* These tests fail on older Nvidia drivers */
1457 /* Foggy vertex shader */
1458 {2, 0, D3DFOG_NONE, D3DFOG_NONE, FALSE,
1459 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1460 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1461 {2, 0, D3DFOG_EXP, D3DFOG_NONE, FALSE,
1462 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1463 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1464 {2, 0, D3DFOG_EXP2, D3DFOG_NONE, FALSE,
1465 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1466 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1467 {2, 0, D3DFOG_LINEAR, D3DFOG_NONE, FALSE,
1468 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1469 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1471 /* Foggy vertex shader and pixel shader. First 4 tests with vertex fog,
1472 * all using the fixed fog-coord linear fog */
1473 {2, 1, D3DFOG_NONE, D3DFOG_NONE, FALSE,
1474 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1475 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1476 {2, 1, D3DFOG_EXP, D3DFOG_NONE, FALSE,
1477 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1478 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1479 {2, 1, D3DFOG_EXP2, D3DFOG_NONE, FALSE,
1480 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1481 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1482 {2, 1, D3DFOG_LINEAR, D3DFOG_NONE, FALSE,
1483 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1484 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1486 /* These use table fog. Here the shader-provided fog coordinate is
1487 * ignored and the z coordinate used instead */
1488 {2, 1, D3DFOG_NONE, D3DFOG_EXP, FALSE,
1489 {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
1490 0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
1491 {2, 1, D3DFOG_NONE, D3DFOG_EXP2, FALSE,
1492 {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
1493 0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
1494 {2, 1, D3DFOG_NONE, D3DFOG_LINEAR, FALSE,
1495 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1496 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1498 static const D3DMATRIX identity =
1500 1.0f, 0.0f, 0.0f, 0.0f,
1501 0.0f, 1.0f, 0.0f, 0.0f,
1502 0.0f, 0.0f, 1.0f, 0.0f,
1503 0.0f, 0.0f, 0.0f, 1.0f,
1504 }}};
1506 window = create_window();
1507 d3d = Direct3DCreate8(D3D_SDK_VERSION);
1508 ok(!!d3d, "Failed to create a D3D object.\n");
1509 if (!(device = create_device(d3d, window, window, TRUE)))
1511 skip("Failed to create a D3D device, skipping tests.\n");
1512 goto done;
1515 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
1516 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
1517 if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1) || caps.PixelShaderVersion < D3DPS_VERSION(1, 1))
1519 skip("No vs_1_1 / ps_1_1 support, skipping tests.\n");
1520 IDirect3DDevice8_Release(device);
1521 goto done;
1524 /* NOTE: changing these values will not affect the tests with foggy vertex
1525 * shader, as the values are hardcoded in the shader constant. */
1526 start.f = 0.1f;
1527 end.f = 0.9f;
1529 /* Some of the tests seem to depend on the projection matrix explicitly
1530 * being set to an identity matrix, even though that's the default.
1531 * (AMD Radeon HD 6310, Windows 7) */
1532 hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, &identity);
1533 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
1535 hr = IDirect3DDevice8_CreateVertexShader(device, decl, vertex_shader_code1, &vertex_shader[1], 0);
1536 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1537 hr = IDirect3DDevice8_CreateVertexShader(device, decl, vertex_shader_code2, &vertex_shader[2], 0);
1538 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1539 hr = IDirect3DDevice8_CreatePixelShader(device, pixel_shader_code, &pixel_shader[1]);
1540 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1542 /* Set shader constant value */
1543 hr = IDirect3DDevice8_SetVertexShader(device, vertex_shader[2]);
1544 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1545 hr = IDirect3DDevice8_SetVertexShaderConstant(device, 0, vs_constant, 1);
1546 ok(hr == D3D_OK, "Setting vertex shader constant failed (%08x)\n", hr);
1548 /* Setup initial states: No lighting, fog on, fog color */
1549 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1550 ok(hr == D3D_OK, "Turning off lighting failed (%08x)\n", hr);
1551 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
1552 ok(hr == D3D_OK, "Turning on fog calculations failed (%08x)\n", hr);
1553 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
1554 ok(hr == D3D_OK, "Setting fog color failed (%08x)\n", hr);
1556 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1557 ok(hr == D3D_OK, "Turning off table fog failed (%08x)\n", hr);
1558 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
1559 ok(hr == D3D_OK, "Turning off vertex fog failed (%08x)\n", hr);
1561 /* Use fogtart = 0.1 and end = 0.9 to test behavior outside the fog transition phase, too */
1562 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGSTART, start.i);
1563 ok(hr == D3D_OK, "Setting fog start failed (%08x)\n", hr);
1564 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGEND, end.i);
1565 ok(hr == D3D_OK, "Setting fog end failed (%08x)\n", hr);
1567 for (i = 0; i < ARRAY_SIZE(test_data); ++i)
1569 hr = IDirect3DDevice8_SetVertexShader(device, vertex_shader[test_data[i].vshader]);
1570 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1571 hr = IDirect3DDevice8_SetPixelShader(device, pixel_shader[test_data[i].pshader]);
1572 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1573 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGVERTEXMODE, test_data[i].vfog);
1574 ok( hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1575 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGTABLEMODE, test_data[i].tfog);
1576 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1578 for(j = 0; j < 11; ++j)
1580 /* Don't use the whole zrange to prevent rounding errors */
1581 quad[0].position.z = 0.001f + j / 10.02f;
1582 quad[1].position.z = 0.001f + j / 10.02f;
1583 quad[2].position.z = 0.001f + j / 10.02f;
1584 quad[3].position.z = 0.001f + j / 10.02f;
1586 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff00ff, 1.0f, 0);
1587 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
1589 hr = IDirect3DDevice8_BeginScene(device);
1590 ok( hr == D3D_OK, "BeginScene returned failed (%08x)\n", hr);
1592 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1593 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
1595 hr = IDirect3DDevice8_EndScene(device);
1596 ok(hr == D3D_OK, "EndScene failed (%08x)\n", hr);
1598 /* As the red and green component are the result of blending use 5% tolerance on the expected value */
1599 color = getPixelColor(device, 128, 240);
1600 ok(color_match(color, test_data[i].color[j], 13) || broken(test_data[i].uninitialized_reg),
1601 "fog vs%i ps%i fvm%i ftm%i %d: got color %08x, expected %08x +-5%%\n",
1602 test_data[i].vshader, test_data[i].pshader,
1603 test_data[i].vfog, test_data[i].tfog, j, color, test_data[i].color[j]);
1606 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
1608 IDirect3DDevice8_DeleteVertexShader(device, vertex_shader[1]);
1609 IDirect3DDevice8_DeleteVertexShader(device, vertex_shader[2]);
1610 IDirect3DDevice8_DeleteVertexShader(device, pixel_shader[1]);
1611 refcount = IDirect3DDevice8_Release(device);
1612 ok(!refcount, "Device has %u references left.\n", refcount);
1613 done:
1614 IDirect3D8_Release(d3d);
1615 DestroyWindow(window);
1618 static void cnd_test(void)
1620 DWORD shader_11_coissue_2, shader_12_coissue_2, shader_13_coissue_2, shader_14_coissue_2;
1621 DWORD shader_11_coissue, shader_12_coissue, shader_13_coissue, shader_14_coissue;
1622 DWORD shader_11, shader_12, shader_13, shader_14;
1623 IDirect3DDevice8 *device;
1624 IDirect3D8 *d3d;
1625 ULONG refcount;
1626 D3DCAPS8 caps;
1627 DWORD color;
1628 HWND window;
1629 HRESULT hr;
1631 /* ps 1.x shaders are rather picky with writemasks and source swizzles.
1632 * The dp3 is used to copy r0.r to all components of r1, then copy r1.a to
1633 * r0.a. Essentially it does a mov r0.a, r0.r, which isn't allowed as-is
1634 * in 1.x pixel shaders. */
1635 static const DWORD shader_code_11[] =
1637 0xffff0101, /* ps_1_1 */
1638 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
1639 0x00000040, 0xb00f0000, /* texcoord t0 */
1640 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
1641 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3 r1, r0, c0 */
1642 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
1643 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
1644 0x0000ffff /* end */
1646 static const DWORD shader_code_12[] =
1648 0xffff0102, /* ps_1_2 */
1649 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
1650 0x00000040, 0xb00f0000, /* texcoord t0 */
1651 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
1652 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3 r1, r0, c0 */
1653 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
1654 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
1655 0x0000ffff /* end */
1657 static const DWORD shader_code_13[] =
1659 0xffff0103, /* ps_1_3 */
1660 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
1661 0x00000040, 0xb00f0000, /* texcoord t0 */
1662 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
1663 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3, r1, r0, c0 */
1664 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
1665 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
1666 0x0000ffff /* end */
1668 static const DWORD shader_code_14[] =
1670 0xffff0104, /* ps_1_3 */
1671 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
1672 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0, t0 */
1673 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
1674 0x00000050, 0x800f0000, 0x80e40000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0, c1, c2 */
1675 0x0000ffff /* end */
1678 /* Special fun: The coissue flag on cnd: Apparently cnd always selects the 2nd source,
1679 * as if the src0 comparison against 0.5 always evaluates to true. The coissue flag isn't
1680 * set by the compiler, it was added manually after compilation. Note that the COISSUE
1681 * flag on a color(.xyz) operation is only allowed after an alpha operation. DirectX doesn't
1682 * have proper docs, but GL_ATI_fragment_shader explains the pairing of color and alpha ops
1683 * well enough.
1685 * The shader attempts to test the range [-1;1] against coissued cnd, which is a bit tricky.
1686 * The input from t0 is [0;1]. 0.5 is subtracted, then we have to multiply with 2. Since
1687 * constants are clamped to [-1;1], a 2.0 is constructed by adding c0.r(=1.0) to c0.r into r1.r,
1688 * then r1(2.0, 0.0, 0.0, 0.0) is passed to dp3(explained above).
1690 static const DWORD shader_code_11_coissue[] =
1692 0xffff0101, /* ps_1_1 */
1693 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
1694 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
1695 0x00000040, 0xb00f0000, /* texcoord t0 */
1696 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
1697 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
1698 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
1699 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
1700 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
1701 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.xyz, r0.a, c1, c2*/
1702 0x0000ffff /* end */
1704 static const DWORD shader_code_11_coissue_2[] =
1706 0xffff0101, /* ps_1_1 */
1707 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
1708 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
1709 0x00000040, 0xb00f0000, /* texcoord t0 */
1710 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
1711 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
1712 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
1713 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
1714 0x00000001, 0x800f0000, 0x80e40001, /* mov r0, r1 */
1715 0x00000001, 0x80070000, 0x80ff0001, /* mov r0.xyz, r1.a */
1716 0x40000050, 0x80080000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.a, r0.a, c1, c2 */
1717 0x00000001, 0x80070000, 0x80ff0000, /* mov r0.xyz, r0.a */
1718 0x0000ffff /* end */
1720 static const DWORD shader_code_12_coissue[] =
1722 0xffff0102, /* ps_1_2 */
1723 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
1724 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
1725 0x00000040, 0xb00f0000, /* texcoord t0 */
1726 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
1727 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
1728 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
1729 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
1730 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
1731 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.xyz, r0.a, c1, c2*/
1732 0x0000ffff /* end */
1734 static const DWORD shader_code_12_coissue_2[] =
1736 0xffff0102, /* ps_1_2 */
1737 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
1738 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
1739 0x00000040, 0xb00f0000, /* texcoord t0 */
1740 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
1741 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
1742 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
1743 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
1744 0x00000001, 0x800f0000, 0x80e40001, /* mov r0, r1 */
1745 0x00000001, 0x80070000, 0x80ff0001, /* mov r0.xyz, r1.a */
1746 0x40000050, 0x80080000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.a, r0.a, c1, c2 */
1747 0x00000001, 0x80070000, 0x80ff0000, /* mov r0.xyz, r0.a */
1748 0x0000ffff /* end */
1750 static const DWORD shader_code_13_coissue[] =
1752 0xffff0103, /* ps_1_3 */
1753 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
1754 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
1755 0x00000040, 0xb00f0000, /* texcoord t0 */
1756 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
1757 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
1758 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
1759 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
1760 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
1761 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.xyz, r0.a, c1, c2*/
1762 0x0000ffff /* end */
1764 static const DWORD shader_code_13_coissue_2[] =
1766 0xffff0103, /* ps_1_3 */
1767 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
1768 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
1769 0x00000040, 0xb00f0000, /* texcoord t0 */
1770 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
1771 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
1772 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
1773 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
1774 0x00000001, 0x800f0000, 0x80e40001, /* mov r0, r1 */
1775 0x00000001, 0x80070000, 0x80ff0001, /* mov r0.xyz, r1.a */
1776 0x40000050, 0x80080000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.a, r0.a, c1, c2 */
1777 0x00000001, 0x80070000, 0x80ff0000, /* mov r0.xyz, r0.a */
1778 0x0000ffff /* end */
1780 /* ps_1_4 does not have a different cnd behavior, just pass the [0;1]
1781 * texcrd result to cnd, it will compare against 0.5. */
1782 static const DWORD shader_code_14_coissue[] =
1784 0xffff0104, /* ps_1_4 */
1785 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
1786 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0.xyz, t0 */
1787 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
1788 0x40000050, 0x80070000, 0x80e40000, 0xa0e40001, 0xa0e40002, /* +cnd r0.xyz, r0, c1, c2 */
1789 0x0000ffff /* end */
1791 static const DWORD shader_code_14_coissue_2[] =
1793 0xffff0104, /* ps_1_4 */
1794 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
1795 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0.xyz, t0 */
1796 0x00000001, 0x80080000, 0x80000000, /* mov r0.a, r0.x */
1797 0x00000001, 0x80070001, 0xa0ff0000, /* mov r1.xyz, c0.a */
1798 0x40000050, 0x80080001, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r1.a, r0.a, c1, c2 */
1799 0x00000001, 0x80070000, 0x80ff0001, /* mov r0.xyz, r1.a */
1800 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
1801 0x0000ffff /* end */
1803 static const float quad1[] =
1805 -1.0f, -1.0f, 0.1f, 0.0f, 0.0f, 1.0f,
1806 -1.0f, 0.0f, 0.1f, 0.0f, 1.0f, 0.0f,
1807 0.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f,
1808 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 0.0f
1810 static const float quad2[] =
1812 0.0f, -1.0f, 0.1f, 0.0f, 0.0f, 1.0f,
1813 0.0f, 0.0f, 0.1f, 0.0f, 1.0f, 0.0f,
1814 1.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f,
1815 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 0.0f
1817 static const float quad3[] =
1819 0.0f, 0.0f, 0.1f, 0.0f, 0.0f, 1.0f,
1820 0.0f, 1.0f, 0.1f, 0.0f, 1.0f, 0.0f,
1821 1.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f,
1822 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 0.0f
1824 static const float quad4[] =
1826 -1.0f, 0.0f, 0.1f, 0.0f, 0.0f, 1.0f,
1827 -1.0f, 1.0f, 0.1f, 0.0f, 1.0f, 0.0f,
1828 0.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f,
1829 0.0f, 1.0f, 0.1f, 1.0f, 1.0f, 0.0f
1831 static const float test_data_c1[4] = {0.0f, 0.0f, 0.0f, 0.0f};
1832 static const float test_data_c2[4] = {1.0f, 1.0f, 1.0f, 1.0f};
1833 static const float test_data_c1_coi[4] = {0.0f, 1.0f, 0.0f, 0.0f};
1834 static const float test_data_c2_coi[4] = {1.0f, 0.0f, 1.0f, 1.0f};
1836 window = create_window();
1837 d3d = Direct3DCreate8(D3D_SDK_VERSION);
1838 ok(!!d3d, "Failed to create a D3D object.\n");
1839 if (!(device = create_device(d3d, window, window, TRUE)))
1841 skip("Failed to create a D3D device, skipping tests.\n");
1842 goto done;
1845 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
1846 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
1847 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 4))
1849 skip("No ps_1_4 support, skipping tests.\n");
1850 IDirect3DDevice8_Release(device);
1851 goto done;
1854 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
1855 ok(hr == D3D_OK, "IDirect3DDevice8_Clear returned %08x\n", hr);
1857 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code_11, &shader_11);
1858 ok(hr == D3D_OK, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr);
1859 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code_12, &shader_12);
1860 ok(hr == D3D_OK, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr);
1861 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code_13, &shader_13);
1862 ok(hr == D3D_OK, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr);
1863 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code_14, &shader_14);
1864 ok(hr == D3D_OK, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr);
1865 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code_11_coissue, &shader_11_coissue);
1866 ok(hr == D3D_OK, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr);
1867 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code_12_coissue, &shader_12_coissue);
1868 ok(hr == D3D_OK, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr);
1869 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code_13_coissue, &shader_13_coissue);
1870 ok(hr == D3D_OK, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr);
1871 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code_14_coissue, &shader_14_coissue);
1872 ok(hr == D3D_OK, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr);
1873 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code_11_coissue_2, &shader_11_coissue_2);
1874 ok(hr == D3D_OK, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr);
1875 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code_12_coissue_2, &shader_12_coissue_2);
1876 ok(hr == D3D_OK, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr);
1877 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code_13_coissue_2, &shader_13_coissue_2);
1878 ok(hr == D3D_OK, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr);
1879 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code_14_coissue_2, &shader_14_coissue_2);
1880 ok(hr == D3D_OK, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr);
1882 hr = IDirect3DDevice8_SetPixelShaderConstant(device, 1, test_data_c1, 1);
1883 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShaderConstant returned %08x\n", hr);
1884 hr = IDirect3DDevice8_SetPixelShaderConstant(device, 2, test_data_c2, 1);
1885 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShaderConstant returned %08x\n", hr);
1886 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX1);
1887 ok(hr == D3D_OK, "IDirect3DDevice8_SetVertexShader returned %#08x\n", hr);
1889 hr = IDirect3DDevice8_BeginScene(device);
1890 ok(hr == D3D_OK, "IDirect3DDevice8_BeginScene returned %08x\n", hr);
1892 hr = IDirect3DDevice8_SetPixelShader(device, shader_11);
1893 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr);
1894 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
1895 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
1897 hr = IDirect3DDevice8_SetPixelShader(device, shader_12);
1898 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr);
1899 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
1900 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
1902 hr = IDirect3DDevice8_SetPixelShader(device, shader_13);
1903 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr);
1904 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
1905 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
1907 hr = IDirect3DDevice8_SetPixelShader(device, shader_14);
1908 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr);
1909 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
1910 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
1912 hr = IDirect3DDevice8_EndScene(device);
1913 ok(hr == D3D_OK, "IDirect3DDevice8_EndScene returned %08x\n", hr);
1915 hr = IDirect3DDevice8_SetPixelShader(device, 0);
1916 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr);
1918 /* This is the 1.4 test. Each component(r, g, b) is tested separately against 0.5 */
1919 color = getPixelColor(device, 158, 118);
1920 ok(color == 0x00ff00ff, "pixel 158, 118 has color %08x, expected 0x00ff00ff\n", color);
1921 color = getPixelColor(device, 162, 118);
1922 ok(color == 0x000000ff, "pixel 162, 118 has color %08x, expected 0x000000ff\n", color);
1923 color = getPixelColor(device, 158, 122);
1924 ok(color == 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color);
1925 color = getPixelColor(device, 162, 122);
1926 ok(color == 0x0000ffff, "pixel 162, 122 has color %08x, expected 0x0000ffff\n", color);
1928 /* 1.1 shader. All 3 components get set, based on the .w comparison */
1929 color = getPixelColor(device, 158, 358);
1930 ok(color == 0x00ffffff, "pixel 158, 358 has color %08x, expected 0x00ffffff\n", color);
1931 color = getPixelColor(device, 162, 358);
1932 ok(color_match(color, 0x00000000, 1),
1933 "pixel 162, 358 has color %08x, expected 0x00000000\n", color);
1934 color = getPixelColor(device, 158, 362);
1935 ok(color == 0x00ffffff, "pixel 158, 362 has color %08x, expected 0x00ffffff\n", color);
1936 color = getPixelColor(device, 162, 362);
1937 ok(color_match(color, 0x00000000, 1),
1938 "pixel 162, 362 has color %08x, expected 0x00000000\n", color);
1940 /* 1.2 shader */
1941 color = getPixelColor(device, 478, 358);
1942 ok(color == 0x00ffffff, "pixel 478, 358 has color %08x, expected 0x00ffffff\n", color);
1943 color = getPixelColor(device, 482, 358);
1944 ok(color_match(color, 0x00000000, 1),
1945 "pixel 482, 358 has color %08x, expected 0x00000000\n", color);
1946 color = getPixelColor(device, 478, 362);
1947 ok(color == 0x00ffffff, "pixel 478, 362 has color %08x, expected 0x00ffffff\n", color);
1948 color = getPixelColor(device, 482, 362);
1949 ok(color_match(color, 0x00000000, 1),
1950 "pixel 482, 362 has color %08x, expected 0x00000000\n", color);
1952 /* 1.3 shader */
1953 color = getPixelColor(device, 478, 118);
1954 ok(color == 0x00ffffff, "pixel 478, 118 has color %08x, expected 0x00ffffff\n", color);
1955 color = getPixelColor(device, 482, 118);
1956 ok(color_match(color, 0x00000000, 1),
1957 "pixel 482, 118 has color %08x, expected 0x00000000\n", color);
1958 color = getPixelColor(device, 478, 122);
1959 ok(color == 0x00ffffff, "pixel 478, 122 has color %08x, expected 0x00ffffff\n", color);
1960 color = getPixelColor(device, 482, 122);
1961 ok(color_match(color, 0x00000000, 1),
1962 "pixel 482, 122 has color %08x, expected 0x00000000\n", color);
1964 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
1965 ok(hr == D3D_OK, "IDirect3DDevice8_Present failed with %08x\n", hr);
1967 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0f, 0);
1968 ok(hr == D3D_OK, "IDirect3DDevice8_Clear returned %08x\n", hr);
1969 hr = IDirect3DDevice8_SetPixelShaderConstant(device, 1, test_data_c1_coi, 1);
1970 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShaderConstant returned %08x\n", hr);
1971 hr = IDirect3DDevice8_SetPixelShaderConstant(device, 2, test_data_c2_coi, 1);
1972 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShaderConstant returned %08x\n", hr);
1974 hr = IDirect3DDevice8_BeginScene(device);
1975 ok(hr == D3D_OK, "IDirect3DDevice8_BeginScene returned %08x\n", hr);
1977 hr = IDirect3DDevice8_SetPixelShader(device, shader_11_coissue);
1978 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr);
1979 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
1980 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
1982 hr = IDirect3DDevice8_SetPixelShader(device, shader_12_coissue);
1983 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr);
1984 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
1985 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
1987 hr = IDirect3DDevice8_SetPixelShader(device, shader_13_coissue);
1988 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr);
1989 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
1990 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
1992 hr = IDirect3DDevice8_SetPixelShader(device, shader_14_coissue);
1993 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr);
1994 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
1995 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
1997 hr = IDirect3DDevice8_EndScene(device);
1998 ok(hr == D3D_OK, "IDirect3DDevice8_EndScene returned %08x\n", hr);
2000 hr = IDirect3DDevice8_SetPixelShader(device, 0);
2001 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr);
2003 /* This is the 1.4 test. The coissue doesn't change the behavior here, but keep in mind
2004 * that we swapped the values in c1 and c2 to make the other tests return some color
2006 color = getPixelColor(device, 158, 118);
2007 ok(color == 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color);
2008 color = getPixelColor(device, 162, 118);
2009 ok(color == 0x0000ffff, "pixel 162, 118 has color %08x, expected 0x0000ffff\n", color);
2010 color = getPixelColor(device, 158, 122);
2011 ok(color == 0x00ff00ff, "pixel 162, 122 has color %08x, expected 0x00ff00ff\n", color);
2012 color = getPixelColor(device, 162, 122);
2013 ok(color == 0x000000ff, "pixel 162, 122 has color %08x, expected 0x000000ff\n", color);
2015 /* 1.1 shader. coissue flag changed the semantic of cnd, c1 is always selected
2016 * (The Win7 nvidia driver always selects c2)
2018 color = getPixelColor(device, 158, 358);
2019 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
2020 "pixel 158, 358 has color %08x, expected 0x0000ff00\n", color);
2021 color = getPixelColor(device, 162, 358);
2022 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
2023 "pixel 162, 358 has color %08x, expected 0x0000ff00\n", color);
2024 color = getPixelColor(device, 158, 362);
2025 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
2026 "pixel 158, 362 has color %08x, expected 0x0000ff00\n", color);
2027 color = getPixelColor(device, 162, 362);
2028 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
2029 "pixel 162, 362 has color %08x, expected 0x0000ff00\n", color);
2031 /* 1.2 shader */
2032 color = getPixelColor(device, 478, 358);
2033 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
2034 "pixel 478, 358 has color %08x, expected 0x0000ff00\n", color);
2035 color = getPixelColor(device, 482, 358);
2036 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
2037 "pixel 482, 358 has color %08x, expected 0x0000ff00\n", color);
2038 color = getPixelColor(device, 478, 362);
2039 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
2040 "pixel 478, 362 has color %08x, expected 0x0000ff00\n", color);
2041 color = getPixelColor(device, 482, 362);
2042 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
2043 "pixel 482, 362 has color %08x, expected 0x0000ff00\n", color);
2045 /* 1.3 shader */
2046 color = getPixelColor(device, 478, 118);
2047 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
2048 "pixel 478, 118 has color %08x, expected 0x0000ff00\n", color);
2049 color = getPixelColor(device, 482, 118);
2050 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
2051 "pixel 482, 118 has color %08x, expected 0x0000ff00\n", color);
2052 color = getPixelColor(device, 478, 122);
2053 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
2054 "pixel 478, 122 has color %08x, expected 0x0000ff00\n", color);
2055 color = getPixelColor(device, 482, 122);
2056 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
2057 "pixel 482, 122 has color %08x, expected 0x0000ff00\n", color);
2059 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
2060 ok(hr == D3D_OK, "IDirect3DDevice8_Present failed with %08x\n", hr);
2062 /* Retest with the coissue flag on the alpha instruction instead. This
2063 * works "as expected". The Windows 8 testbot (WARP) seems to handle this
2064 * the same as coissue on .rgb. */
2065 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0f, 0);
2066 ok(hr == D3D_OK, "IDirect3DDevice8_Clear returned %08x\n", hr);
2068 hr = IDirect3DDevice8_BeginScene(device);
2069 ok(hr == D3D_OK, "IDirect3DDevice8_BeginScene returned %08x\n", hr);
2071 hr = IDirect3DDevice8_SetPixelShader(device, shader_11_coissue_2);
2072 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr);
2073 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
2074 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
2076 hr = IDirect3DDevice8_SetPixelShader(device, shader_12_coissue_2);
2077 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr);
2078 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
2079 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
2081 hr = IDirect3DDevice8_SetPixelShader(device, shader_13_coissue_2);
2082 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr);
2083 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
2084 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
2086 hr = IDirect3DDevice8_SetPixelShader(device, shader_14_coissue_2);
2087 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr);
2088 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
2089 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
2091 hr = IDirect3DDevice8_EndScene(device);
2092 ok(hr == D3D_OK, "IDirect3DDevice8_EndScene returned %08x\n", hr);
2094 /* 1.4 shader */
2095 color = getPixelColor(device, 158, 118);
2096 ok(color == 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color);
2097 color = getPixelColor(device, 162, 118);
2098 ok(color == 0x00000000, "pixel 162, 118 has color %08x, expected 0x00000000\n", color);
2099 color = getPixelColor(device, 158, 122);
2100 ok(color == 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color);
2101 color = getPixelColor(device, 162, 122);
2102 ok(color == 0x00000000, "pixel 162, 122 has color %08x, expected 0x00000000\n", color);
2104 /* 1.1 shader */
2105 color = getPixelColor(device, 238, 358);
2106 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
2107 "pixel 238, 358 has color %08x, expected 0x00ffffff\n", color);
2108 color = getPixelColor(device, 242, 358);
2109 ok(color_match(color, 0x00000000, 1),
2110 "pixel 242, 358 has color %08x, expected 0x00000000\n", color);
2111 color = getPixelColor(device, 238, 362);
2112 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
2113 "pixel 238, 362 has color %08x, expected 0x00ffffff\n", color);
2114 color = getPixelColor(device, 242, 362);
2115 ok(color_match(color, 0x00000000, 1),
2116 "pixel 242, 362 has color %08x, expected 0x00000000\n", color);
2118 /* 1.2 shader */
2119 color = getPixelColor(device, 558, 358);
2120 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
2121 "pixel 558, 358 has color %08x, expected 0x00ffffff\n", color);
2122 color = getPixelColor(device, 562, 358);
2123 ok(color_match(color, 0x00000000, 1),
2124 "pixel 562, 358 has color %08x, expected 0x00000000\n", color);
2125 color = getPixelColor(device, 558, 362);
2126 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
2127 "pixel 558, 362 has color %08x, expected 0x00ffffff\n", color);
2128 color = getPixelColor(device, 562, 362);
2129 ok(color_match(color, 0x00000000, 1),
2130 "pixel 562, 362 has color %08x, expected 0x00000000\n", color);
2132 /* 1.3 shader */
2133 color = getPixelColor(device, 558, 118);
2134 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
2135 "pixel 558, 118 has color %08x, expected 0x00ffffff\n", color);
2136 color = getPixelColor(device, 562, 118);
2137 ok(color_match(color, 0x00000000, 1),
2138 "pixel 562, 118 has color %08x, expected 0x00000000\n", color);
2139 color = getPixelColor(device, 558, 122);
2140 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
2141 "pixel 558, 122 has color %08x, expected 0x00ffffff\n", color);
2142 color = getPixelColor(device, 562, 122);
2143 ok(color_match(color, 0x00000000, 1),
2144 "pixel 562, 122 has color %08x, expected 0x00000000\n", color);
2146 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
2147 ok(hr == D3D_OK, "IDirect3DDevice8_Present failed with %08x\n", hr);
2149 IDirect3DDevice8_DeletePixelShader(device, shader_14_coissue_2);
2150 IDirect3DDevice8_DeletePixelShader(device, shader_13_coissue_2);
2151 IDirect3DDevice8_DeletePixelShader(device, shader_12_coissue_2);
2152 IDirect3DDevice8_DeletePixelShader(device, shader_11_coissue_2);
2153 IDirect3DDevice8_DeletePixelShader(device, shader_14_coissue);
2154 IDirect3DDevice8_DeletePixelShader(device, shader_13_coissue);
2155 IDirect3DDevice8_DeletePixelShader(device, shader_12_coissue);
2156 IDirect3DDevice8_DeletePixelShader(device, shader_11_coissue);
2157 IDirect3DDevice8_DeletePixelShader(device, shader_14);
2158 IDirect3DDevice8_DeletePixelShader(device, shader_13);
2159 IDirect3DDevice8_DeletePixelShader(device, shader_12);
2160 IDirect3DDevice8_DeletePixelShader(device, shader_11);
2161 refcount = IDirect3DDevice8_Release(device);
2162 ok(!refcount, "Device has %u references left.\n", refcount);
2163 done:
2164 IDirect3D8_Release(d3d);
2165 DestroyWindow(window);
2168 static void z_range_test(void)
2170 IDirect3DDevice8 *device;
2171 IDirect3D8 *d3d;
2172 D3DCOLOR color;
2173 ULONG refcount;
2174 D3DCAPS8 caps;
2175 DWORD shader;
2176 HWND window;
2177 HRESULT hr;
2179 static const struct
2181 struct vec3 position;
2182 DWORD diffuse;
2184 quad[] =
2186 {{-1.0f, 0.0f, 1.1f}, 0xffff0000},
2187 {{-1.0f, 1.0f, 1.1f}, 0xffff0000},
2188 {{ 1.0f, 0.0f, -1.1f}, 0xffff0000},
2189 {{ 1.0f, 1.0f, -1.1f}, 0xffff0000},
2191 quad2[] =
2193 {{-1.0f, 0.0f, 1.1f}, 0xff0000ff},
2194 {{-1.0f, 1.0f, 1.1f}, 0xff0000ff},
2195 {{ 1.0f, 0.0f, -1.1f}, 0xff0000ff},
2196 {{ 1.0f, 1.0f, -1.1f}, 0xff0000ff},
2198 static const struct
2200 struct vec4 position;
2201 DWORD diffuse;
2203 quad3[] =
2205 {{640.0f, 240.0f, -1.1f, 1.0f}, 0xffffff00},
2206 {{640.0f, 480.0f, -1.1f, 1.0f}, 0xffffff00},
2207 {{ 0.0f, 240.0f, 1.1f, 1.0f}, 0xffffff00},
2208 {{ 0.0f, 480.0f, 1.1f, 1.0f}, 0xffffff00},
2210 quad4[] =
2212 {{640.0f, 240.0f, -1.1f, 1.0f}, 0xff00ff00},
2213 {{640.0f, 480.0f, -1.1f, 1.0f}, 0xff00ff00},
2214 {{ 0.0f, 240.0f, 1.1f, 1.0f}, 0xff00ff00},
2215 {{ 0.0f, 480.0f, 1.1f, 1.0f}, 0xff00ff00},
2217 static const DWORD shader_code[] =
2219 0xfffe0101, /* vs_1_1 */
2220 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
2221 0x00000001, 0xd00f0000, 0xa0e40000, /* mov oD0, c0 */
2222 0x0000ffff /* end */
2224 static const float color_const_1[] = {1.0f, 0.0f, 0.0f, 1.0f};
2225 static const float color_const_2[] = {0.0f, 0.0f, 1.0f, 1.0f};
2226 static const DWORD vertex_declaration[] =
2228 D3DVSD_STREAM(0),
2229 D3DVSD_REG(D3DVSDE_POSITION, D3DVSDT_FLOAT3),
2230 D3DVSD_END()
2233 window = create_window();
2234 d3d = Direct3DCreate8(D3D_SDK_VERSION);
2235 ok(!!d3d, "Failed to create a D3D object.\n");
2236 if (!(device = create_device(d3d, window, window, TRUE)))
2238 skip("Failed to create a D3D device, skipping tests.\n");
2239 goto done;
2242 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
2243 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
2245 /* Does the Present clear the depth stencil? Clear the depth buffer with some value != 0,
2246 * then call Present. Then clear the color buffer to make sure it has some defined content
2247 * after the Present with D3DSWAPEFFECT_DISCARD. After that draw a plane that is somewhere cut
2248 * by the depth value. */
2249 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.75f, 0);
2250 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
2251 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
2252 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
2253 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
2254 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
2256 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
2257 ok(SUCCEEDED(hr), "Failed to disabled lighting, hr %#x.\n", hr);
2258 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, TRUE);
2259 ok(SUCCEEDED(hr), "Failed to enable clipping, hr %#x.\n", hr);
2260 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
2261 ok(SUCCEEDED(hr), "Failed to enable z test, hr %#x.\n", hr);
2262 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
2263 ok(SUCCEEDED(hr), "Failed to disable z writes, hr %#x.\n", hr);
2264 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
2265 ok(SUCCEEDED(hr), "Failed to set z function, hr %#x.\n", hr);
2266 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
2267 ok(SUCCEEDED(hr), "Failed set FVF, hr %#x.\n", hr);
2269 hr = IDirect3DDevice8_BeginScene(device);
2270 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
2272 /* Test the untransformed vertex path */
2273 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
2274 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2275 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
2276 ok(SUCCEEDED(hr), "Failed to set z function, hr %#x.\n", hr);
2277 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
2278 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2280 /* Test the transformed vertex path */
2281 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
2282 ok(SUCCEEDED(hr), "Failed set FVF, hr %#x.\n", hr);
2284 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(quad4[0]));
2285 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2286 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
2287 ok(SUCCEEDED(hr), "Failed to set z function, hr %#x.\n", hr);
2288 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(quad3[0]));
2289 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2291 hr = IDirect3DDevice8_EndScene(device);
2292 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
2294 /* Do not test the exact corner pixels, but go pretty close to them */
2296 /* Clipped because z > 1.0 */
2297 color = getPixelColor(device, 28, 238);
2298 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2299 color = getPixelColor(device, 28, 241);
2300 if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
2301 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2302 else
2303 ok(color_match(color, 0x00ffff00, 0), "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2305 /* Not clipped, > z buffer clear value(0.75).
2307 * On the r500 driver on Windows D3DCMP_GREATER and D3DCMP_GREATEREQUAL are broken for depth
2308 * values > 0.5. The range appears to be distorted, apparently an incoming value of ~0.875 is
2309 * equal to a stored depth buffer value of 0.5. */
2310 color = getPixelColor(device, 31, 238);
2311 ok(color_match(color, 0x00ff0000, 0), "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2312 color = getPixelColor(device, 31, 241);
2313 ok(color_match(color, 0x00ffff00, 0), "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2314 color = getPixelColor(device, 100, 238);
2315 ok(color_match(color, 0x00ff0000, 0) || broken(color_match(color, 0x00ffffff, 0)),
2316 "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2317 color = getPixelColor(device, 100, 241);
2318 ok(color_match(color, 0x00ffff00, 0) || broken(color_match(color, 0x00ffffff, 0)),
2319 "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2321 /* Not clipped, < z buffer clear value */
2322 color = getPixelColor(device, 104, 238);
2323 ok(color_match(color, 0x000000ff, 0), "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2324 color = getPixelColor(device, 104, 241);
2325 ok(color_match(color, 0x0000ff00, 0), "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
2326 color = getPixelColor(device, 318, 238);
2327 ok(color_match(color, 0x000000ff, 0), "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2328 color = getPixelColor(device, 318, 241);
2329 ok(color_match(color, 0x0000ff00, 0), "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
2331 /* Clipped because z < 0.0 */
2332 color = getPixelColor(device, 321, 238);
2333 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2334 color = getPixelColor(device, 321, 241);
2335 if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
2336 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2337 else
2338 ok(color_match(color, 0x0000ff00, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2340 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
2341 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
2343 /* Test the shader path */
2344 if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1))
2346 skip("Vertex shaders not supported\n");
2347 IDirect3DDevice8_Release(device);
2348 goto done;
2350 hr = IDirect3DDevice8_CreateVertexShader(device, vertex_declaration, shader_code, &shader, 0);
2351 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
2353 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
2354 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
2356 hr = IDirect3DDevice8_SetVertexShader(device, shader);
2357 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
2359 hr = IDirect3DDevice8_BeginScene(device);
2360 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
2362 hr = IDirect3DDevice8_SetVertexShaderConstant(device, 0, color_const_1, 1);
2363 ok(SUCCEEDED(hr), "Failed to set vs constant 0, hr %#x.\n", hr);
2364 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
2365 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2367 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
2368 ok(SUCCEEDED(hr), "Failed to set z function, hr %#x.\n", hr);
2369 hr = IDirect3DDevice8_SetVertexShaderConstant(device, 0, color_const_2, 1);
2370 ok(SUCCEEDED(hr), "Failed to set vs constant 0, hr %#x.\n", hr);
2371 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
2372 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2374 hr = IDirect3DDevice8_EndScene(device);
2375 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
2377 hr = IDirect3DDevice8_SetVertexShader(device, 0);
2378 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
2380 hr = IDirect3DDevice8_DeleteVertexShader(device, shader);
2381 ok(SUCCEEDED(hr), "Failed to delete vertex shader, hr %#x.\n", hr);
2383 /* Z < 1.0 */
2384 color = getPixelColor(device, 28, 238);
2385 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2387 /* 1.0 < z < 0.75 */
2388 color = getPixelColor(device, 31, 238);
2389 ok(color_match(color, 0x00ff0000, 0), "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2390 color = getPixelColor(device, 100, 238);
2391 ok(color_match(color, 0x00ff0000, 0) || broken(color_match(color, 0x00ffffff, 0)),
2392 "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2394 /* 0.75 < z < 0.0 */
2395 color = getPixelColor(device, 104, 238);
2396 ok(color_match(color, 0x000000ff, 0), "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2397 color = getPixelColor(device, 318, 238);
2398 ok(color_match(color, 0x000000ff, 0), "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2400 /* 0.0 < z */
2401 color = getPixelColor(device, 321, 238);
2402 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2404 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
2405 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
2407 refcount = IDirect3DDevice8_Release(device);
2408 ok(!refcount, "Device has %u references left.\n", refcount);
2409 done:
2410 IDirect3D8_Release(d3d);
2411 DestroyWindow(window);
2414 static void test_scalar_instructions(void)
2416 IDirect3DDevice8 *device;
2417 IDirect3D8 *d3d;
2418 unsigned int i;
2419 D3DCOLOR color;
2420 ULONG refcount;
2421 D3DCAPS8 caps;
2422 DWORD shader;
2423 HWND window;
2424 HRESULT hr;
2426 static const struct vec3 quad[] =
2428 {-1.0f, -1.0f, 0.0f},
2429 {-1.0f, 1.0f, 0.0f},
2430 { 1.0f, -1.0f, 0.0f},
2431 { 1.0f, 1.0f, 0.0f},
2433 static const DWORD decl[] =
2435 D3DVSD_STREAM(0),
2436 D3DVSD_REG(D3DVSDE_POSITION, D3DVSDT_FLOAT3), /* dcl_position v0 */
2437 D3DVSD_CONST(0, 1), 0x3e800000, 0x3f000000, 0x3f800000, 0x40000000, /* def c0, 0.25, 0.5, 1.0, 2.0 */
2438 D3DVSD_END()
2440 static const DWORD rcp_test[] =
2442 0xfffe0101, /* vs_1_1 */
2443 0x0009fffe, 0x30303030, 0x30303030, /* Shaders have to have a minimal size. */
2444 0x30303030, 0x30303030, 0x30303030, /* Add a filler comment. Usually d3dx8's */
2445 0x30303030, 0x30303030, 0x30303030, /* version comment makes the shader big */
2446 0x00303030, /* enough to make Windows happy. */
2447 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
2448 0x00000006, 0xd00f0000, 0xa0e40000, /* rcp oD0, c0 */
2449 0x0000ffff /* END */
2451 static const DWORD rsq_test[] =
2453 0xfffe0101, /* vs_1_1 */
2454 0x0009fffe, 0x30303030, 0x30303030, /* Shaders have to have a minimal size. */
2455 0x30303030, 0x30303030, 0x30303030, /* Add a filler comment. Usually d3dx8's */
2456 0x30303030, 0x30303030, 0x30303030, /* version comment makes the shader big */
2457 0x00303030, /* enough to make Windows happy. */
2458 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
2459 0x00000007, 0xd00f0000, 0xa0e40000, /* rsq oD0, c0 */
2460 0x0000ffff /* END */
2462 static const DWORD exp_test[] =
2464 0xfffe0101, /* vs_1_1 */
2465 0x0009fffe, 0x30303030, 0x30303030, /* Shaders have to have a minimal size. */
2466 0x30303030, 0x30303030, 0x30303030, /* Add a filler comment. Usually d3dx8's */
2467 0x30303030, 0x30303030, 0x30303030, /* version comment makes the shader big */
2468 0x00303030, /* enough to make Windows happy. */
2469 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
2470 0x0000000e, 0x800f0000, 0xa0e40000, /* exp r0, c0 */
2471 0x00000006, 0xd00f0000, 0x80000000, /* rcp oD0, r0.x */
2472 0x0000ffff, /* END */
2474 static const DWORD expp_test[] =
2476 0xfffe0101, /* vs_1_1 */
2477 0x0009fffe, 0x30303030, 0x30303030, /* Shaders have to have a minimal size. */
2478 0x30303030, 0x30303030, 0x30303030, /* Add a filler comment. Usually d3dx8's */
2479 0x30303030, 0x30303030, 0x30303030, /* version comment makes the shader big */
2480 0x00303030, /* enough to make Windows happy. */
2481 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
2482 0x0000004e, 0x800f0000, 0xa0e40000, /* expp r0, c0 */
2483 0x00000006, 0xd00f0000, 0x80000000, /* rcp oD0, r0.x */
2484 0x0000ffff, /* END */
2486 static const DWORD log_test[] =
2488 0xfffe0101, /* vs_1_1 */
2489 0x0009fffe, 0x30303030, 0x30303030, /* Shaders have to have a minimal size. */
2490 0x30303030, 0x30303030, 0x30303030, /* Add a filler comment. Usually d3dx8's */
2491 0x30303030, 0x30303030, 0x30303030, /* version comment makes the shader big */
2492 0x00303030, /* enough to make Windows happy. */
2493 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
2494 0x0000000f, 0xd00f0000, 0xa0e40000, /* log oD0, c0 */
2495 0x0000ffff, /* END */
2497 static const DWORD logp_test[] =
2499 0xfffe0101, /* vs_1_1 */
2500 0x0009fffe, 0x30303030, 0x30303030, /* Shaders have to have a minimal size. */
2501 0x30303030, 0x30303030, 0x30303030, /* Add a filler comment. Usually d3dx8's */
2502 0x30303030, 0x30303030, 0x30303030, /* version comment makes the shader big */
2503 0x00303030, /* enough to make Windows happy. */
2504 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
2505 0x0000004f, 0xd00f0000, 0xa0e40000, /* logp oD0, c0 */
2506 0x0000ffff, /* END */
2508 static const struct
2510 const char *name;
2511 const DWORD *byte_code;
2512 D3DCOLOR color;
2513 /* Some drivers, including Intel HD4000 10.18.10.3345 and VMware SVGA
2514 * 3D 7.14.1.5025, use the .x component instead of the .w one. */
2515 D3DCOLOR broken_color;
2517 test_data[] =
2519 {"rcp_test", rcp_test, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x80), D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff)},
2520 {"rsq_test", rsq_test, D3DCOLOR_ARGB(0x00, 0xb4, 0xb4, 0xb4), D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff)},
2521 {"exp_test", exp_test, D3DCOLOR_ARGB(0x00, 0x40, 0x40, 0x40), D3DCOLOR_ARGB(0x00, 0xd6, 0xd6, 0xd6)},
2522 {"expp_test", expp_test, D3DCOLOR_ARGB(0x00, 0x40, 0x40, 0x40), D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff)},
2523 {"log_test", log_test, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff), D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
2524 {"logp_test", logp_test, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff), D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
2527 window = create_window();
2528 d3d = Direct3DCreate8(D3D_SDK_VERSION);
2529 ok(!!d3d, "Failed to create a D3D object.\n");
2530 if (!(device = create_device(d3d, window, window, TRUE)))
2532 skip("Failed to create a D3D device, skipping tests.\n");
2533 goto done;
2536 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
2537 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
2538 if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1))
2540 skip("No vs_1_1 support, skipping tests.\n");
2541 IDirect3DDevice8_Release(device);
2542 goto done;
2545 for (i = 0; i < ARRAY_SIZE(test_data); ++i)
2547 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff336699, 0.0f, 0);
2548 ok(SUCCEEDED(hr), "%s: Failed to clear, hr %#x.\n", test_data[i].name, hr);
2550 hr = IDirect3DDevice8_CreateVertexShader(device, decl, test_data[i].byte_code, &shader, 0);
2551 ok(SUCCEEDED(hr), "%s: Failed to create vertex shader, hr %#x.\n", test_data[i].name, hr);
2552 hr = IDirect3DDevice8_SetVertexShader(device, shader);
2553 ok(SUCCEEDED(hr), "%s: Failed to set vertex shader, hr %#x.\n", test_data[i].name, hr);
2555 hr = IDirect3DDevice8_BeginScene(device);
2556 ok(SUCCEEDED(hr), "%s: Failed to begin scene, hr %#x.\n", test_data[i].name, hr);
2557 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], 3 * sizeof(float));
2558 ok(SUCCEEDED(hr), "%s: Failed to draw primitive, hr %#x.\n", test_data[i].name, hr);
2559 hr = IDirect3DDevice8_EndScene(device);
2560 ok(SUCCEEDED(hr), "%s: Failed to end scene, hr %#x.\n", test_data[i].name, hr);
2562 color = getPixelColor(device, 320, 240);
2563 ok(color_match(color, test_data[i].color, 4) || broken(color_match(color, test_data[i].broken_color, 4)),
2564 "%s: Got unexpected color 0x%08x, expected 0x%08x.\n",
2565 test_data[i].name, color, test_data[i].color);
2567 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
2568 ok(SUCCEEDED(hr), "%s: Failed to present, hr %#x.\n", test_data[i].name, hr);
2570 hr = IDirect3DDevice8_SetVertexShader(device, 0);
2571 ok(SUCCEEDED(hr), "%s: Failed to set vertex shader, hr %#x.\n", test_data[i].name, hr);
2572 hr = IDirect3DDevice8_DeleteVertexShader(device, shader);
2573 ok(SUCCEEDED(hr), "%s: Failed to delete vertex shader, hr %#x.\n", test_data[i].name, hr);
2576 refcount = IDirect3DDevice8_Release(device);
2577 ok(!refcount, "Device has %u references left.\n", refcount);
2578 done:
2579 IDirect3D8_Release(d3d);
2580 DestroyWindow(window);
2583 static void offscreen_test(void)
2585 IDirect3DSurface8 *backbuffer, *offscreen, *depthstencil;
2586 IDirect3DTexture8 *offscreenTexture;
2587 IDirect3DDevice8 *device;
2588 IDirect3D8 *d3d;
2589 D3DCOLOR color;
2590 ULONG refcount;
2591 HWND window;
2592 HRESULT hr;
2594 static const float quad[][5] =
2596 {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
2597 {-0.5f, 0.5f, 0.1f, 0.0f, 1.0f},
2598 { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
2599 { 0.5f, 0.5f, 0.1f, 1.0f, 1.0f},
2602 window = create_window();
2603 d3d = Direct3DCreate8(D3D_SDK_VERSION);
2604 ok(!!d3d, "Failed to create a D3D object.\n");
2605 if (!(device = create_device(d3d, window, window, TRUE)))
2607 skip("Failed to create a D3D device, skipping tests.\n");
2608 goto done;
2611 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 1.0f, 0);
2612 ok(hr == D3D_OK, "Clear failed, hr = %#08x\n", hr);
2614 hr = IDirect3DDevice8_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET,
2615 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture);
2616 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %#08x\n", hr);
2617 if (!offscreenTexture)
2619 trace("Failed to create an X8R8G8B8 offscreen texture, trying R5G6B5\n");
2620 hr = IDirect3DDevice8_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET,
2621 D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &offscreenTexture);
2622 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %#08x\n", hr);
2623 if (!offscreenTexture)
2625 skip("Cannot create an offscreen render target.\n");
2626 IDirect3DDevice8_Release(device);
2627 goto done;
2631 hr = IDirect3DDevice8_GetDepthStencilSurface(device, &depthstencil);
2632 ok(hr == D3D_OK, "IDirect3DDevice8_GetDepthStencilSurface failed, hr = %#08x\n", hr);
2634 hr = IDirect3DDevice8_GetBackBuffer(device, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
2635 ok(hr == D3D_OK, "Can't get back buffer, hr = %#08x\n", hr);
2637 hr = IDirect3DTexture8_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
2638 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %#08x\n", hr);
2640 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX1);
2641 ok(hr == D3D_OK, "SetVertexShader failed, hr = %#08x\n", hr);
2643 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
2644 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %#08x\n", hr);
2645 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
2646 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %#08x\n", hr);
2647 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MINFILTER, D3DTEXF_NONE);
2648 ok(SUCCEEDED(hr), "SetTextureStageState D3DSAMP_MINFILTER failed (%#08x)\n", hr);
2649 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MAGFILTER, D3DTEXF_NONE);
2650 ok(SUCCEEDED(hr), "SetTextureStageState D3DSAMP_MAGFILTER failed (%#08x)\n", hr);
2651 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
2652 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %08x\n", hr);
2654 hr = IDirect3DDevice8_BeginScene(device);
2655 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
2657 hr = IDirect3DDevice8_SetRenderTarget(device, offscreen, depthstencil);
2658 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
2659 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 1.0f, 0);
2660 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
2662 /* Draw without textures - Should result in a white quad. */
2663 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
2664 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2666 hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, depthstencil);
2667 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
2668 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)offscreenTexture);
2669 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
2671 /* This time with the texture .*/
2672 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
2673 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2675 hr = IDirect3DDevice8_EndScene(device);
2676 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
2678 /* Center quad - should be white */
2679 color = getPixelColor(device, 320, 240);
2680 ok(color == 0x00ffffff, "Offscreen failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2681 /* Some quad in the cleared part of the texture */
2682 color = getPixelColor(device, 170, 240);
2683 ok(color == 0x00ff00ff, "Offscreen failed: Got color 0x%08x, expected 0x00ff00ff.\n", color);
2684 /* Part of the originally cleared back buffer */
2685 color = getPixelColor(device, 10, 10);
2686 ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2687 color = getPixelColor(device, 10, 470);
2688 ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2690 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
2692 IDirect3DSurface8_Release(backbuffer);
2693 IDirect3DTexture8_Release(offscreenTexture);
2694 IDirect3DSurface8_Release(offscreen);
2695 IDirect3DSurface8_Release(depthstencil);
2696 refcount = IDirect3DDevice8_Release(device);
2697 ok(!refcount, "Device has %u references left.\n", refcount);
2698 done:
2699 IDirect3D8_Release(d3d);
2700 DestroyWindow(window);
2703 static void test_blend(void)
2705 IDirect3DSurface8 *backbuffer, *offscreen, *depthstencil;
2706 IDirect3DTexture8 *offscreenTexture;
2707 IDirect3DDevice8 *device;
2708 IDirect3D8 *d3d;
2709 D3DCOLOR color;
2710 ULONG refcount;
2711 HWND window;
2712 HRESULT hr;
2714 static const struct
2716 struct vec3 position;
2717 DWORD diffuse;
2719 quad1[] =
2721 {{-1.0f, -1.0f, 0.1f}, 0x4000ff00},
2722 {{-1.0f, 0.0f, 0.1f}, 0x4000ff00},
2723 {{ 1.0f, -1.0f, 0.1f}, 0x4000ff00},
2724 {{ 1.0f, 0.0f, 0.1f}, 0x4000ff00},
2726 quad2[] =
2728 {{-1.0f, 0.0f, 0.1f}, 0xc00000ff},
2729 {{-1.0f, 1.0f, 0.1f}, 0xc00000ff},
2730 {{ 1.0f, 0.0f, 0.1f}, 0xc00000ff},
2731 {{ 1.0f, 1.0f, 0.1f}, 0xc00000ff},
2733 static const float composite_quad[][5] =
2735 { 0.0f, -1.0f, 0.1f, 0.0f, 1.0f},
2736 { 0.0f, 1.0f, 0.1f, 0.0f, 0.0f},
2737 { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f},
2738 { 1.0f, 1.0f, 0.1f, 1.0f, 0.0f},
2741 window = create_window();
2742 d3d = Direct3DCreate8(D3D_SDK_VERSION);
2743 ok(!!d3d, "Failed to create a D3D object.\n");
2744 if (!(device = create_device(d3d, window, window, TRUE)))
2746 skip("Failed to create a D3D device, skipping tests.\n");
2747 goto done;
2750 /* Clear the render target with alpha = 0.5 */
2751 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x80ff0000, 1.0f, 0);
2752 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
2754 hr = IDirect3DDevice8_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET,
2755 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture);
2756 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
2758 hr = IDirect3DDevice8_GetDepthStencilSurface(device, &depthstencil);
2759 ok(SUCCEEDED(hr), "Failed to get depth/stencil buffer, hr %#x.\n", hr);
2760 hr = IDirect3DDevice8_GetBackBuffer(device, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
2761 ok(SUCCEEDED(hr), "Failed to get back buffer, hr %#x.\n", hr);
2763 hr = IDirect3DTexture8_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
2764 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %#08x\n", hr);
2766 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
2767 ok(hr == D3D_OK, "SetVertexShader failed, hr = %#08x\n", hr);
2769 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
2770 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %#08x\n", hr);
2771 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
2772 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %#08x\n", hr);
2773 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MINFILTER, D3DTEXF_NONE);
2774 ok(SUCCEEDED(hr), "SetTextureStageState D3DSAMP_MINFILTER failed (%#08x)\n", hr);
2775 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MAGFILTER, D3DTEXF_NONE);
2776 ok(SUCCEEDED(hr), "SetTextureStageState D3DSAMP_MAGFILTER failed (%#08x)\n", hr);
2777 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
2778 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %08x\n", hr);
2780 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
2781 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
2782 hr = IDirect3DDevice8_BeginScene(device);
2783 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
2785 /* Draw two quads, one with src alpha blending, one with dest alpha blending. */
2786 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
2787 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
2788 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
2789 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
2790 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
2791 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2793 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
2794 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
2795 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
2796 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
2797 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
2798 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2800 /* Switch to the offscreen buffer, and redo the testing. The offscreen
2801 * render target doesn't have an alpha channel. DESTALPHA and INVDESTALPHA
2802 * "don't work" on render targets without alpha channel, they give
2803 * essentially ZERO and ONE blend factors. */
2804 hr = IDirect3DDevice8_SetRenderTarget(device, offscreen, 0);
2805 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
2806 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
2807 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
2809 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
2810 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
2811 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
2812 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
2813 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
2814 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2816 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
2817 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
2818 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
2819 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
2820 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
2821 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2823 hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, depthstencil);
2824 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
2826 /* Render the offscreen texture onto the frame buffer to be able to
2827 * compare it regularly. Disable alpha blending for the final
2828 * composition. */
2829 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
2830 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
2831 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX1);
2832 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
2834 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *) offscreenTexture);
2835 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
2836 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, composite_quad, sizeof(float) * 5);
2837 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2839 hr = IDirect3DDevice8_EndScene(device);
2840 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
2842 color = getPixelColor(device, 160, 360);
2843 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
2844 "SRCALPHA on frame buffer returned color %08x, expected 0x00bf4000\n", color);
2846 color = getPixelColor(device, 160, 120);
2847 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x00, 0x80), 2),
2848 "DSTALPHA on frame buffer returned color %08x, expected 0x007f0080\n", color);
2850 color = getPixelColor(device, 480, 360);
2851 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
2852 "SRCALPHA on texture returned color %08x, expected 0x00bf4000\n", color);
2854 color = getPixelColor(device, 480, 120);
2855 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
2856 "DSTALPHA on texture returned color %08x, expected 0x000000ff\n", color);
2858 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
2860 IDirect3DSurface8_Release(backbuffer);
2861 IDirect3DTexture8_Release(offscreenTexture);
2862 IDirect3DSurface8_Release(offscreen);
2863 IDirect3DSurface8_Release(depthstencil);
2864 refcount = IDirect3DDevice8_Release(device);
2865 ok(!refcount, "Device has %u references left.\n", refcount);
2866 done:
2867 IDirect3D8_Release(d3d);
2868 DestroyWindow(window);
2871 static void p8_texture_test(void)
2873 IDirect3DTexture8 *texture, *texture2;
2874 IDirect3DDevice8 *device;
2875 PALETTEENTRY table[256];
2876 unsigned char *data;
2877 D3DLOCKED_RECT lr;
2878 IDirect3D8 *d3d;
2879 D3DCOLOR color;
2880 ULONG refcount;
2881 D3DCAPS8 caps;
2882 HWND window;
2883 HRESULT hr;
2884 UINT i;
2886 static const float quad[] =
2888 -1.0f, 0.0f, 0.1f, 0.0f, 0.0f,
2889 -1.0f, 1.0f, 0.1f, 0.0f, 1.0f,
2890 1.0f, 0.0f, 0.1f, 1.0f, 0.0f,
2891 1.0f, 1.0f, 0.1f, 1.0f, 1.0f,
2893 static const float quad2[] =
2895 -1.0f, -1.0f, 0.1f, 0.0f, 0.0f,
2896 -1.0f, 0.0f, 0.1f, 0.0f, 1.0f,
2897 1.0f, -1.0f, 0.1f, 1.0f, 0.0f,
2898 1.0f, 0.0f, 0.1f, 1.0f, 1.0f,
2901 window = create_window();
2902 d3d = Direct3DCreate8(D3D_SDK_VERSION);
2903 ok(!!d3d, "Failed to create a D3D object.\n");
2904 if (!(device = create_device(d3d, window, window, TRUE)))
2906 skip("Failed to create a D3D device, skipping tests.\n");
2907 goto done;
2910 if (IDirect3D8_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
2911 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_P8) != D3D_OK)
2913 skip("D3DFMT_P8 textures not supported.\n");
2914 IDirect3DDevice8_Release(device);
2915 goto done;
2918 hr = IDirect3DDevice8_CreateTexture(device, 1, 1, 1, 0, D3DFMT_P8, D3DPOOL_MANAGED, &texture2);
2919 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
2920 memset(&lr, 0, sizeof(lr));
2921 hr = IDirect3DTexture8_LockRect(texture2, 0, &lr, NULL, 0);
2922 ok(hr == D3D_OK, "IDirect3DTexture8_LockRect failed, hr = %08x\n", hr);
2923 data = lr.pBits;
2924 *data = 1;
2925 hr = IDirect3DTexture8_UnlockRect(texture2, 0);
2926 ok(hr == D3D_OK, "IDirect3DTexture8_UnlockRect failed, hr = %08x\n", hr);
2928 hr = IDirect3DDevice8_CreateTexture(device, 1, 1, 1, 0, D3DFMT_P8, D3DPOOL_MANAGED, &texture);
2929 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
2930 memset(&lr, 0, sizeof(lr));
2931 hr = IDirect3DTexture8_LockRect(texture, 0, &lr, NULL, 0);
2932 ok(hr == D3D_OK, "IDirect3DTexture8_LockRect failed, hr = %08x\n", hr);
2933 data = lr.pBits;
2934 *data = 1;
2935 hr = IDirect3DTexture8_UnlockRect(texture, 0);
2936 ok(hr == D3D_OK, "IDirect3DTexture8_UnlockRect failed, hr = %08x\n", hr);
2938 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff000000, 1.0f, 0);
2939 ok(hr == D3D_OK, "IDirect3DDevice8_Clear failed, hr = %08x\n", hr);
2941 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
2942 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
2943 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
2944 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
2946 /* The first part of the test should work both with and without D3DPTEXTURECAPS_ALPHAPALETTE;
2947 alpha of every entry is set to 1.0, which MS says is required when there's no
2948 D3DPTEXTURECAPS_ALPHAPALETTE capability */
2949 for (i = 0; i < 256; i++) {
2950 table[i].peRed = table[i].peGreen = table[i].peBlue = 0;
2951 table[i].peFlags = 0xff;
2953 table[1].peRed = 0xff;
2954 hr = IDirect3DDevice8_SetPaletteEntries(device, 0, table);
2955 ok(hr == D3D_OK, "IDirect3DDevice8_SetPaletteEntries failed, hr = %08x\n", hr);
2957 table[1].peRed = 0;
2958 table[1].peBlue = 0xff;
2959 hr = IDirect3DDevice8_SetPaletteEntries(device, 1, table);
2960 ok(hr == D3D_OK, "IDirect3DDevice8_SetPaletteEntries failed, hr = %08x\n", hr);
2962 hr = IDirect3DDevice8_BeginScene(device);
2963 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
2965 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
2966 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
2967 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
2968 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
2969 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX1);
2970 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
2971 hr = IDirect3DDevice8_SetCurrentTexturePalette(device, 0);
2972 ok(SUCCEEDED(hr), "Failed to set texture palette, hr %#x.\n", hr);
2973 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture2);
2974 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
2975 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
2976 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2978 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
2979 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
2980 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
2981 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2983 hr = IDirect3DDevice8_SetCurrentTexturePalette(device, 1);
2984 ok(SUCCEEDED(hr), "Failed to set texture palette, hr %#x.\n", hr);
2985 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
2986 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2988 hr = IDirect3DDevice8_EndScene(device);
2989 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
2991 color = getPixelColor(device, 32, 32);
2992 ok(color_match(color, 0x00ff0000, 0), "Got unexpected color 0x%08x.\n", color);
2993 color = getPixelColor(device, 32, 320);
2994 ok(color_match(color, 0x000000ff, 0), "Got unexpected color 0x%08x.\n", color);
2996 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
2997 ok(hr == D3D_OK, "IDirect3DDevice8_Present failed, hr = %08x\n", hr);
2999 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
3000 ok(hr == D3D_OK, "IDirect3DDevice8_Clear failed, hr = %08x\n", hr);
3002 hr = IDirect3DDevice8_BeginScene(device);
3003 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
3004 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture2);
3005 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
3006 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
3007 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
3008 hr = IDirect3DDevice8_EndScene(device);
3009 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
3011 color = getPixelColor(device, 32, 32);
3012 ok(color_match(color, 0x000000ff, 0), "Got unexpected color 0x%08x.\n", color);
3014 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
3015 ok(hr == D3D_OK, "IDirect3DDevice8_Present failed, hr = %08x\n", hr);
3017 /* Test palettes with alpha */
3018 IDirect3DDevice8_GetDeviceCaps(device, &caps);
3019 if (!(caps.TextureCaps & D3DPTEXTURECAPS_ALPHAPALETTE)) {
3020 skip("no D3DPTEXTURECAPS_ALPHAPALETTE capability, tests with alpha in palette will be skipped\n");
3021 } else {
3022 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
3023 ok(hr == D3D_OK, "IDirect3DDevice8_Clear failed, hr = %08x\n", hr);
3025 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
3026 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
3028 for (i = 0; i < 256; i++) {
3029 table[i].peRed = table[i].peGreen = table[i].peBlue = 0;
3030 table[i].peFlags = 0xff;
3032 table[1].peRed = 0xff;
3033 table[1].peFlags = 0x80;
3034 hr = IDirect3DDevice8_SetPaletteEntries(device, 0, table);
3035 ok(hr == D3D_OK, "IDirect3DDevice8_SetPaletteEntries failed, hr = %08x\n", hr);
3037 table[1].peRed = 0;
3038 table[1].peBlue = 0xff;
3039 table[1].peFlags = 0x80;
3040 hr = IDirect3DDevice8_SetPaletteEntries(device, 1, table);
3041 ok(hr == D3D_OK, "IDirect3DDevice8_SetPaletteEntries failed, hr = %08x\n", hr);
3043 hr = IDirect3DDevice8_BeginScene(device);
3044 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
3046 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
3047 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
3048 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
3049 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
3050 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX1);
3051 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
3053 hr = IDirect3DDevice8_SetCurrentTexturePalette(device, 0);
3054 ok(SUCCEEDED(hr), "Failed to set texture palette, hr %#x.\n", hr);
3055 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
3056 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
3058 hr = IDirect3DDevice8_SetCurrentTexturePalette(device, 1);
3059 ok(SUCCEEDED(hr), "Failed to set texture palette, hr %#x.\n", hr);
3060 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
3061 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
3063 hr = IDirect3DDevice8_EndScene(device);
3064 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
3066 color = getPixelColor(device, 32, 32);
3067 ok(color_match(color, 0x00800000, 1), "Got unexpected color 0x%08x.\n", color);
3068 color = getPixelColor(device, 32, 320);
3069 ok(color_match(color, 0x00000080, 1), "Got unexpected color 0x%08x.\n", color);
3071 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
3072 ok(hr == D3D_OK, "IDirect3DDevice8_Present failed, hr = %08x\n", hr);
3075 IDirect3DTexture8_Release(texture);
3076 IDirect3DTexture8_Release(texture2);
3077 refcount = IDirect3DDevice8_Release(device);
3078 ok(!refcount, "Device has %u references left.\n", refcount);
3079 done:
3080 IDirect3D8_Release(d3d);
3081 DestroyWindow(window);
3084 static void texop_test(void)
3086 IDirect3DTexture8 *texture;
3087 D3DLOCKED_RECT locked_rect;
3088 IDirect3DDevice8 *device;
3089 IDirect3D8 *d3d;
3090 unsigned int i;
3091 D3DCOLOR color;
3092 ULONG refcount;
3093 D3DCAPS8 caps;
3094 HWND window;
3095 HRESULT hr;
3097 static const struct {
3098 float x, y, z;
3099 D3DCOLOR diffuse;
3100 float s, t;
3101 } quad[] = {
3102 {-1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00), -1.0f, -1.0f},
3103 {-1.0f, 1.0f, 0.1f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00), -1.0f, 1.0f},
3104 { 1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00), 1.0f, -1.0f},
3105 { 1.0f, 1.0f, 0.1f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00), 1.0f, 1.0f}
3108 static const struct {
3109 D3DTEXTUREOP op;
3110 const char *name;
3111 DWORD caps_flag;
3112 D3DCOLOR result;
3113 } test_data[] = {
3114 {D3DTOP_SELECTARG1, "SELECTARG1", D3DTEXOPCAPS_SELECTARG1, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
3115 {D3DTOP_SELECTARG2, "SELECTARG2", D3DTEXOPCAPS_SELECTARG2, D3DCOLOR_ARGB(0x00, 0x33, 0x33, 0x33)},
3116 {D3DTOP_MODULATE, "MODULATE", D3DTEXOPCAPS_MODULATE, D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x00)},
3117 {D3DTOP_MODULATE2X, "MODULATE2X", D3DTEXOPCAPS_MODULATE2X, D3DCOLOR_ARGB(0x00, 0x00, 0x66, 0x00)},
3118 {D3DTOP_MODULATE4X, "MODULATE4X", D3DTEXOPCAPS_MODULATE4X, D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
3119 {D3DTOP_ADD, "ADD", D3DTEXOPCAPS_ADD, D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
3121 {D3DTOP_ADDSIGNED, "ADDSIGNED", D3DTEXOPCAPS_ADDSIGNED, D3DCOLOR_ARGB(0x00, 0x00, 0xb2, 0x00)},
3122 {D3DTOP_ADDSIGNED2X, "ADDSIGNED2X", D3DTEXOPCAPS_ADDSIGNED2X, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
3124 {D3DTOP_SUBTRACT, "SUBTRACT", D3DTEXOPCAPS_SUBTRACT, D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
3125 {D3DTOP_ADDSMOOTH, "ADDSMOOTH", D3DTEXOPCAPS_ADDSMOOTH, D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
3126 {D3DTOP_BLENDDIFFUSEALPHA, "BLENDDIFFUSEALPHA", D3DTEXOPCAPS_BLENDDIFFUSEALPHA, D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
3127 {D3DTOP_BLENDTEXTUREALPHA, "BLENDTEXTUREALPHA", D3DTEXOPCAPS_BLENDTEXTUREALPHA, D3DCOLOR_ARGB(0x00, 0x14, 0xad, 0x14)},
3128 {D3DTOP_BLENDFACTORALPHA, "BLENDFACTORALPHA", D3DTEXOPCAPS_BLENDFACTORALPHA, D3DCOLOR_ARGB(0x00, 0x07, 0xe4, 0x07)},
3129 {D3DTOP_BLENDTEXTUREALPHAPM, "BLENDTEXTUREALPHAPM", D3DTEXOPCAPS_BLENDTEXTUREALPHAPM, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
3130 {D3DTOP_BLENDCURRENTALPHA, "BLENDCURRENTALPHA", D3DTEXOPCAPS_BLENDCURRENTALPHA, D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
3131 {D3DTOP_MODULATEALPHA_ADDCOLOR, "MODULATEALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x1f, 0xff, 0x1f)},
3132 {D3DTOP_MODULATECOLOR_ADDALPHA, "MODULATECOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0x99, 0xcc, 0x99)},
3133 {D3DTOP_MODULATEINVALPHA_ADDCOLOR, "MODULATEINVALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
3134 {D3DTOP_MODULATEINVCOLOR_ADDALPHA, "MODULATEINVCOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0xcc, 0x99, 0xcc)},
3135 /* BUMPENVMAP & BUMPENVMAPLUMINANCE have their own tests */
3136 {D3DTOP_DOTPRODUCT3, "DOTPRODUCT2", D3DTEXOPCAPS_DOTPRODUCT3, D3DCOLOR_ARGB(0x00, 0x99, 0x99, 0x99)},
3137 {D3DTOP_MULTIPLYADD, "MULTIPLYADD", D3DTEXOPCAPS_MULTIPLYADD, D3DCOLOR_ARGB(0x00, 0xff, 0x33, 0x00)},
3138 {D3DTOP_LERP, "LERP", D3DTEXOPCAPS_LERP, D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x33)},
3141 window = create_window();
3142 d3d = Direct3DCreate8(D3D_SDK_VERSION);
3143 ok(!!d3d, "Failed to create a D3D object.\n");
3144 if (!(device = create_device(d3d, window, window, TRUE)))
3146 skip("Failed to create a D3D device, skipping tests.\n");
3147 goto done;
3150 memset(&caps, 0, sizeof(caps));
3151 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
3152 ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
3154 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX0);
3155 ok(SUCCEEDED(hr), "SetVertexShader failed with 0x%08x\n", hr);
3157 hr = IDirect3DDevice8_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture);
3158 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
3159 hr = IDirect3DTexture8_LockRect(texture, 0, &locked_rect, NULL, 0);
3160 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
3161 *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x99, 0x00, 0xff, 0x00);
3162 hr = IDirect3DTexture8_UnlockRect(texture, 0);
3163 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
3164 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
3165 ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
3167 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG0, D3DTA_DIFFUSE);
3168 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
3169 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
3170 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
3171 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
3172 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
3174 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
3175 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
3177 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3178 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
3179 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xdd333333);
3180 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
3181 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_ALPHA);
3182 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
3184 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
3185 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
3187 for (i = 0; i < ARRAY_SIZE(test_data); ++i)
3189 if (!(caps.TextureOpCaps & test_data[i].caps_flag))
3191 skip("tex operation %s not supported\n", test_data[i].name);
3192 continue;
3195 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLOROP, test_data[i].op);
3196 ok(SUCCEEDED(hr), "SetTextureStageState (%s) failed with 0x%08x\n", test_data[i].name, hr);
3198 hr = IDirect3DDevice8_BeginScene(device);
3199 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
3201 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
3202 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
3204 hr = IDirect3DDevice8_EndScene(device);
3205 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
3207 color = getPixelColor(device, 320, 240);
3208 ok(color_match(color, test_data[i].result, 3), "Operation %s returned color 0x%08x, expected 0x%08x\n",
3209 test_data[i].name, color, test_data[i].result);
3211 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
3212 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
3214 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
3215 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
3218 IDirect3DTexture8_Release(texture);
3219 refcount = IDirect3DDevice8_Release(device);
3220 ok(!refcount, "Device has %u references left.\n", refcount);
3221 done:
3222 IDirect3D8_Release(d3d);
3223 DestroyWindow(window);
3226 /* This test tests depth clamping / clipping behaviour:
3227 * - With software vertex processing, depth values are clamped to the
3228 * minimum / maximum z value when D3DRS_CLIPPING is disabled, and clipped
3229 * when D3DRS_CLIPPING is enabled. Pretransformed vertices behave the
3230 * same as regular vertices here.
3231 * - With hardware vertex processing, D3DRS_CLIPPING seems to be ignored.
3232 * Normal vertices are always clipped. Pretransformed vertices are
3233 * clipped when D3DPMISCCAPS_CLIPTLVERTS is set, clamped when it isn't.
3234 * - The viewport's MinZ/MaxZ is irrelevant for this.
3236 static void depth_clamp_test(void)
3238 IDirect3DDevice8 *device;
3239 D3DVIEWPORT8 vp;
3240 IDirect3D8 *d3d;
3241 D3DCOLOR color;
3242 ULONG refcount;
3243 D3DCAPS8 caps;
3244 HWND window;
3245 HRESULT hr;
3247 static const struct
3249 struct vec4 position;
3250 DWORD diffuse;
3252 quad1[] =
3254 {{ 0.0f, 0.0f, 5.0f, 1.0f}, 0xff002b7f},
3255 {{640.0f, 0.0f, 5.0f, 1.0f}, 0xff002b7f},
3256 {{ 0.0f, 480.0f, 5.0f, 1.0f}, 0xff002b7f},
3257 {{640.0f, 480.0f, 5.0f, 1.0f}, 0xff002b7f},
3259 quad2[] =
3261 {{ 0.0f, 300.0f, 10.0f, 1.0f}, 0xfff9e814},
3262 {{640.0f, 300.0f, 10.0f, 1.0f}, 0xfff9e814},
3263 {{ 0.0f, 360.0f, 10.0f, 1.0f}, 0xfff9e814},
3264 {{640.0f, 360.0f, 10.0f, 1.0f}, 0xfff9e814},
3266 quad3[] =
3268 {{112.0f, 108.0f, 5.0f, 1.0f}, 0xffffffff},
3269 {{208.0f, 108.0f, 5.0f, 1.0f}, 0xffffffff},
3270 {{112.0f, 204.0f, 5.0f, 1.0f}, 0xffffffff},
3271 {{208.0f, 204.0f, 5.0f, 1.0f}, 0xffffffff},
3273 quad4[] =
3275 {{ 42.0f, 41.0f, 10.0f, 1.0f}, 0xffffffff},
3276 {{112.0f, 41.0f, 10.0f, 1.0f}, 0xffffffff},
3277 {{ 42.0f, 108.0f, 10.0f, 1.0f}, 0xffffffff},
3278 {{112.0f, 108.0f, 10.0f, 1.0f}, 0xffffffff},
3280 static const struct
3282 struct vec3 position;
3283 DWORD diffuse;
3285 quad5[] =
3287 {{-0.5f, 0.5f, 10.0f}, 0xff14f914},
3288 {{ 0.5f, 0.5f, 10.0f}, 0xff14f914},
3289 {{-0.5f, -0.5f, 10.0f}, 0xff14f914},
3290 {{ 0.5f, -0.5f, 10.0f}, 0xff14f914},
3292 quad6[] =
3294 {{-1.0f, 0.5f, 10.0f}, 0xfff91414},
3295 {{ 1.0f, 0.5f, 10.0f}, 0xfff91414},
3296 {{-1.0f, 0.25f, 10.0f}, 0xfff91414},
3297 {{ 1.0f, 0.25f, 10.0f}, 0xfff91414},
3300 window = create_window();
3301 d3d = Direct3DCreate8(D3D_SDK_VERSION);
3302 ok(!!d3d, "Failed to create a D3D object.\n");
3303 if (!(device = create_device(d3d, window, window, TRUE)))
3305 skip("Failed to create a D3D device, skipping tests.\n");
3306 goto done;
3309 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
3310 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
3312 vp.X = 0;
3313 vp.Y = 0;
3314 vp.Width = 640;
3315 vp.Height = 480;
3316 vp.MinZ = 0.0;
3317 vp.MaxZ = 7.5;
3319 hr = IDirect3DDevice8_SetViewport(device, &vp);
3320 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
3322 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0, 0);
3323 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
3325 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, FALSE);
3326 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3327 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3328 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3329 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
3330 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3331 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
3332 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3334 hr = IDirect3DDevice8_BeginScene(device);
3335 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
3337 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
3338 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
3340 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
3341 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3342 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
3343 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3345 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, TRUE);
3346 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3348 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
3349 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3350 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(*quad4));
3351 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3353 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, FALSE);
3354 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3355 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
3356 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
3358 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad5, sizeof(*quad5));
3359 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3361 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, TRUE);
3362 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3364 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad6, sizeof(*quad6));
3365 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3367 hr = IDirect3DDevice8_EndScene(device);
3368 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
3370 if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
3372 color = getPixelColor(device, 75, 75);
3373 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
3374 color = getPixelColor(device, 150, 150);
3375 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
3376 color = getPixelColor(device, 320, 240);
3377 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
3378 color = getPixelColor(device, 320, 330);
3379 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
3380 color = getPixelColor(device, 320, 330);
3381 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
3383 else
3385 color = getPixelColor(device, 75, 75);
3386 ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
3387 color = getPixelColor(device, 150, 150);
3388 ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
3389 color = getPixelColor(device, 320, 240);
3390 ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);
3391 color = getPixelColor(device, 320, 330);
3392 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
3393 color = getPixelColor(device, 320, 330);
3394 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
3397 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
3398 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3400 refcount = IDirect3DDevice8_Release(device);
3401 ok(!refcount, "Device has %u references left.\n", refcount);
3402 done:
3403 IDirect3D8_Release(d3d);
3404 DestroyWindow(window);
3407 static void depth_buffer_test(void)
3409 IDirect3DSurface8 *backbuffer, *rt1, *rt2, *rt3;
3410 IDirect3DSurface8 *depth_stencil;
3411 IDirect3DDevice8 *device;
3412 unsigned int i, j;
3413 D3DVIEWPORT8 vp;
3414 IDirect3D8 *d3d;
3415 D3DCOLOR color;
3416 ULONG refcount;
3417 HWND window;
3418 HRESULT hr;
3420 static const struct
3422 struct vec3 position;
3423 DWORD diffuse;
3425 quad1[] =
3427 {{-1.0f, 1.0f, 0.33f}, 0xff00ff00},
3428 {{ 1.0f, 1.0f, 0.33f}, 0xff00ff00},
3429 {{-1.0f, -1.0f, 0.33f}, 0xff00ff00},
3430 {{ 1.0f, -1.0f, 0.33f}, 0xff00ff00},
3432 quad2[] =
3434 {{-1.0f, 1.0f, 0.50f}, 0xffff00ff},
3435 {{ 1.0f, 1.0f, 0.50f}, 0xffff00ff},
3436 {{-1.0f, -1.0f, 0.50f}, 0xffff00ff},
3437 {{ 1.0f, -1.0f, 0.50f}, 0xffff00ff},
3439 quad3[] =
3441 {{-1.0f, 1.0f, 0.66f}, 0xffff0000},
3442 {{ 1.0f, 1.0f, 0.66f}, 0xffff0000},
3443 {{-1.0f, -1.0f, 0.66f}, 0xffff0000},
3444 {{ 1.0f, -1.0f, 0.66f}, 0xffff0000},
3446 static const DWORD expected_colors[4][4] =
3448 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
3449 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
3450 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x00ff0000},
3451 {0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
3454 window = create_window();
3455 d3d = Direct3DCreate8(D3D_SDK_VERSION);
3456 ok(!!d3d, "Failed to create a D3D object.\n");
3457 if (!(device = create_device(d3d, window, window, TRUE)))
3459 skip("Failed to create a D3D device, skipping tests.\n");
3460 goto done;
3463 vp.X = 0;
3464 vp.Y = 0;
3465 vp.Width = 640;
3466 vp.Height = 480;
3467 vp.MinZ = 0.0;
3468 vp.MaxZ = 1.0;
3470 hr = IDirect3DDevice8_SetViewport(device, &vp);
3471 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
3473 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3474 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3475 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
3476 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3477 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
3478 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3479 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
3480 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3481 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
3482 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
3484 hr = IDirect3DDevice8_GetDepthStencilSurface(device, &depth_stencil);
3485 ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
3486 hr = IDirect3DDevice8_GetRenderTarget(device, &backbuffer);
3487 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
3488 hr = IDirect3DDevice8_CreateRenderTarget(device, 320, 240, D3DFMT_A8R8G8B8,
3489 D3DMULTISAMPLE_NONE, FALSE, &rt1);
3490 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
3491 hr = IDirect3DDevice8_CreateRenderTarget(device, 480, 360, D3DFMT_A8R8G8B8,
3492 D3DMULTISAMPLE_NONE, FALSE, &rt2);
3493 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
3494 hr = IDirect3DDevice8_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
3495 D3DMULTISAMPLE_NONE, FALSE, &rt3);
3496 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
3498 hr = IDirect3DDevice8_SetRenderTarget(device, rt3, depth_stencil);
3499 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
3500 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0f, 0);
3501 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
3503 hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, depth_stencil);
3504 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
3505 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
3506 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
3508 hr = IDirect3DDevice8_SetRenderTarget(device, rt1, depth_stencil);
3509 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
3510 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0f, 0);
3511 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
3513 hr = IDirect3DDevice8_SetRenderTarget(device, rt2, depth_stencil);
3514 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
3515 hr = IDirect3DDevice8_BeginScene(device);
3516 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
3517 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
3518 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3519 hr = IDirect3DDevice8_EndScene(device);
3520 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
3522 hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, depth_stencil);
3523 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
3525 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
3526 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3528 hr = IDirect3DDevice8_BeginScene(device);
3529 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
3530 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
3531 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3532 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
3533 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3534 hr = IDirect3DDevice8_EndScene(device);
3535 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
3537 for (i = 0; i < 4; ++i)
3539 for (j = 0; j < 4; ++j)
3541 unsigned int x = 80 * ((2 * j) + 1);
3542 unsigned int y = 60 * ((2 * i) + 1);
3543 color = getPixelColor(device, x, y);
3544 ok(color_match(color, expected_colors[i][j], 0),
3545 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors[i][j], x, y, color);
3549 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
3550 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3552 IDirect3DSurface8_Release(depth_stencil);
3553 IDirect3DSurface8_Release(backbuffer);
3554 IDirect3DSurface8_Release(rt3);
3555 IDirect3DSurface8_Release(rt2);
3556 IDirect3DSurface8_Release(rt1);
3557 refcount = IDirect3DDevice8_Release(device);
3558 ok(!refcount, "Device has %u references left.\n", refcount);
3559 done:
3560 IDirect3D8_Release(d3d);
3561 DestroyWindow(window);
3564 /* Test that partial depth copies work the way they're supposed to. The clear
3565 * on rt2 only needs a partial copy of the onscreen depth/stencil buffer, and
3566 * the following draw should only copy back the part that was modified. */
3567 static void depth_buffer2_test(void)
3569 IDirect3DSurface8 *backbuffer, *rt1, *rt2;
3570 IDirect3DSurface8 *depth_stencil;
3571 IDirect3DDevice8 *device;
3572 unsigned int i, j;
3573 D3DVIEWPORT8 vp;
3574 IDirect3D8 *d3d;
3575 D3DCOLOR color;
3576 ULONG refcount;
3577 HWND window;
3578 HRESULT hr;
3580 static const struct
3582 struct vec3 position;
3583 DWORD diffuse;
3585 quad[] =
3587 {{-1.0f, 1.0f, 0.66f}, 0xffff0000},
3588 {{ 1.0f, 1.0f, 0.66f}, 0xffff0000},
3589 {{-1.0f, -1.0f, 0.66f}, 0xffff0000},
3590 {{ 1.0f, -1.0f, 0.66f}, 0xffff0000},
3593 window = create_window();
3594 d3d = Direct3DCreate8(D3D_SDK_VERSION);
3595 ok(!!d3d, "Failed to create a D3D object.\n");
3596 if (!(device = create_device(d3d, window, window, TRUE)))
3598 skip("Failed to create a D3D device, skipping tests.\n");
3599 goto done;
3602 vp.X = 0;
3603 vp.Y = 0;
3604 vp.Width = 640;
3605 vp.Height = 480;
3606 vp.MinZ = 0.0;
3607 vp.MaxZ = 1.0;
3609 hr = IDirect3DDevice8_SetViewport(device, &vp);
3610 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
3612 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3613 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3614 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
3615 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3616 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
3617 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3618 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
3619 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3620 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
3621 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
3623 hr = IDirect3DDevice8_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
3624 D3DMULTISAMPLE_NONE, FALSE, &rt1);
3625 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
3626 hr = IDirect3DDevice8_CreateRenderTarget(device, 480, 360, D3DFMT_A8R8G8B8,
3627 D3DMULTISAMPLE_NONE, FALSE, &rt2);
3628 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
3629 hr = IDirect3DDevice8_GetDepthStencilSurface(device, &depth_stencil);
3630 ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
3631 hr = IDirect3DDevice8_GetRenderTarget(device, &backbuffer);
3632 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
3634 hr = IDirect3DDevice8_SetRenderTarget(device, rt1, depth_stencil);
3635 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
3636 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
3637 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
3639 hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, depth_stencil);
3640 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
3641 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 0.5f, 0);
3642 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
3644 hr = IDirect3DDevice8_SetRenderTarget(device, rt2, depth_stencil);
3645 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
3646 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0f, 0);
3647 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
3649 hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, depth_stencil);
3650 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
3652 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
3653 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3655 hr = IDirect3DDevice8_BeginScene(device);
3656 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
3657 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
3658 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3659 hr = IDirect3DDevice8_EndScene(device);
3660 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
3662 for (i = 0; i < 4; ++i)
3664 for (j = 0; j < 4; ++j)
3666 unsigned int x = 80 * ((2 * j) + 1);
3667 unsigned int y = 60 * ((2 * i) + 1);
3668 color = getPixelColor(device, x, y);
3669 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
3670 "Expected color 0x0000ff00 %u,%u, got 0x%08x.\n", x, y, color);
3674 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
3675 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3677 IDirect3DSurface8_Release(depth_stencil);
3678 IDirect3DSurface8_Release(backbuffer);
3679 IDirect3DSurface8_Release(rt2);
3680 IDirect3DSurface8_Release(rt1);
3681 refcount = IDirect3DDevice8_Release(device);
3682 ok(!refcount, "Device has %u references left.\n", refcount);
3683 done:
3684 IDirect3D8_Release(d3d);
3685 DestroyWindow(window);
3688 static void intz_test(void)
3690 IDirect3DSurface8 *original_rt, *rt;
3691 struct surface_readback rb;
3692 IDirect3DTexture8 *texture;
3693 IDirect3DDevice8 *device;
3694 IDirect3DSurface8 *ds;
3695 IDirect3D8 *d3d;
3696 ULONG refcount;
3697 D3DCAPS8 caps;
3698 HWND window;
3699 HRESULT hr;
3700 DWORD ps;
3701 UINT i;
3703 static const DWORD ps_code[] =
3705 0xffff0101, /* ps_1_1 */
3706 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c0, 1.0, 0.0, 1.0, 1.0 */
3707 0x00000051, 0xa00f0001, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c1, 0.0, 1.0, 0.0, 0.0 */
3708 0x00000042, 0xb00f0000, /* tex t0 */
3709 0x00000042, 0xb00f0001, /* tex t1 */
3710 0x00000005, 0xb00f0000, 0xa0e40000, 0xb0e40000, /* mul t0, c0, t0 */
3711 0x00000004, 0x800f0000, 0xa0e40001, 0xb0e40001, 0xb0e40000, /* mad r0, c1, t1, t0 */
3712 0x0000ffff, /* end */
3714 static const struct
3716 float x, y, z;
3717 float s0, t0, p0;
3718 float s1, t1, p1, q1;
3720 quad[] =
3722 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.5f},
3723 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
3724 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
3725 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.5f},
3727 half_quad_1[] =
3729 { -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.5f},
3730 { 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
3731 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
3732 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.5f},
3734 half_quad_2[] =
3736 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.5f},
3737 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
3738 { -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
3739 { 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.5f},
3741 static const struct
3743 UINT x, y;
3744 D3DCOLOR color;
3746 expected_colors[] =
3748 { 80, 100, 0x20204020},
3749 {240, 100, 0x6060bf60},
3750 {400, 100, 0x9f9f409f},
3751 {560, 100, 0xdfdfbfdf},
3752 { 80, 450, 0x20204020},
3753 {240, 450, 0x6060bf60},
3754 {400, 450, 0x9f9f409f},
3755 {560, 450, 0xdfdfbfdf},
3758 window = create_window();
3759 d3d = Direct3DCreate8(D3D_SDK_VERSION);
3760 ok(!!d3d, "Failed to create a D3D object.\n");
3761 if (!(device = create_device(d3d, window, window, TRUE)))
3763 skip("Failed to create a D3D device, skipping tests.\n");
3764 goto done;
3767 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
3768 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
3769 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 1))
3771 skip("No pixel shader 1.1 support, skipping INTZ test.\n");
3772 IDirect3DDevice8_Release(device);
3773 goto done;
3775 if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
3777 skip("No unconditional NP2 texture support, skipping INTZ test.\n");
3778 IDirect3DDevice8_Release(device);
3779 goto done;
3782 if (FAILED(hr = IDirect3D8_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
3783 D3DFMT_X8R8G8B8, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, MAKEFOURCC('I','N','T','Z'))))
3785 skip("No INTZ support, skipping INTZ test.\n");
3786 IDirect3DDevice8_Release(device);
3787 goto done;
3790 hr = IDirect3DDevice8_GetRenderTarget(device, &original_rt);
3791 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
3793 hr = IDirect3DDevice8_CreateTexture(device, 640, 480, 1,
3794 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture);
3795 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
3796 hr = IDirect3DDevice8_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
3797 D3DMULTISAMPLE_NONE, FALSE, &rt);
3798 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
3799 hr = IDirect3DDevice8_CreatePixelShader(device, ps_code, &ps);
3800 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
3802 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX2
3803 | D3DFVF_TEXCOORDSIZE3(0) | D3DFVF_TEXCOORDSIZE4(1));
3804 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
3805 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
3806 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3807 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
3808 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3809 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
3810 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3811 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3812 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3814 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MINFILTER, D3DTEXF_POINT);
3815 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3816 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MIPFILTER, D3DTEXF_POINT);
3817 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3818 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MAGFILTER, D3DTEXF_POINT);
3819 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3820 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
3821 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3823 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP);
3824 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3825 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP);
3826 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3827 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MAGFILTER, D3DTEXF_POINT);
3828 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3829 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MINFILTER, D3DTEXF_POINT);
3830 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3831 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MIPFILTER, D3DTEXF_POINT);
3832 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3833 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS,
3834 D3DTTFF_COUNT4 | D3DTTFF_PROJECTED);
3835 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3837 hr = IDirect3DTexture8_GetSurfaceLevel(texture, 0, &ds);
3838 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
3840 /* Render offscreen, using the INTZ texture as depth buffer */
3841 hr = IDirect3DDevice8_SetRenderTarget(device, rt, ds);
3842 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
3843 hr = IDirect3DDevice8_SetPixelShader(device, 0);
3844 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
3846 /* Setup the depth/stencil surface. */
3847 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
3848 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
3850 hr = IDirect3DDevice8_BeginScene(device);
3851 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
3852 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
3853 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3854 hr = IDirect3DDevice8_EndScene(device);
3855 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
3857 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, NULL);
3858 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
3859 IDirect3DSurface8_Release(ds);
3860 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
3861 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
3862 hr = IDirect3DDevice8_SetTexture(device, 1, (IDirect3DBaseTexture8 *)texture);
3863 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
3864 hr = IDirect3DDevice8_SetPixelShader(device, ps);
3865 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
3867 /* Read the depth values back. */
3868 hr = IDirect3DDevice8_BeginScene(device);
3869 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
3870 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
3871 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3872 hr = IDirect3DDevice8_EndScene(device);
3873 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
3875 get_rt_readback(original_rt, &rb);
3876 for (i = 0; i < ARRAY_SIZE(expected_colors); ++i)
3878 D3DCOLOR color = get_readback_color(&rb, expected_colors[i].x, expected_colors[i].y);
3879 ok(color_match(color, expected_colors[i].color, 1),
3880 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
3881 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
3883 release_surface_readback(&rb);
3885 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
3886 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
3888 hr = IDirect3DDevice8_SetTexture(device, 0, NULL);
3889 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
3890 hr = IDirect3DDevice8_SetTexture(device, 1, NULL);
3891 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
3892 IDirect3DTexture8_Release(texture);
3894 /* Render onscreen while using the INTZ texture as depth buffer */
3895 hr = IDirect3DDevice8_CreateTexture(device, 640, 480, 1,
3896 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture);
3897 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
3898 hr = IDirect3DTexture8_GetSurfaceLevel(texture, 0, &ds);
3899 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
3900 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, ds);
3901 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
3902 hr = IDirect3DDevice8_SetPixelShader(device, 0);
3903 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
3905 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
3906 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
3908 hr = IDirect3DDevice8_BeginScene(device);
3909 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
3910 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
3911 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3912 hr = IDirect3DDevice8_EndScene(device);
3913 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
3915 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, NULL);
3916 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
3917 IDirect3DSurface8_Release(ds);
3918 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
3919 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
3920 hr = IDirect3DDevice8_SetTexture(device, 1, (IDirect3DBaseTexture8 *)texture);
3921 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
3922 hr = IDirect3DDevice8_SetPixelShader(device, ps);
3923 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
3925 /* Read the depth values back. */
3926 hr = IDirect3DDevice8_BeginScene(device);
3927 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
3928 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
3929 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3930 hr = IDirect3DDevice8_EndScene(device);
3931 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
3933 get_rt_readback(original_rt, &rb);
3934 for (i = 0; i < ARRAY_SIZE(expected_colors); ++i)
3936 D3DCOLOR color = get_readback_color(&rb, expected_colors[i].x, expected_colors[i].y);
3937 ok(color_match(color, expected_colors[i].color, 1),
3938 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
3939 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
3941 release_surface_readback(&rb);
3943 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
3944 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
3946 hr = IDirect3DDevice8_SetTexture(device, 0, NULL);
3947 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
3948 hr = IDirect3DDevice8_SetTexture(device, 1, NULL);
3949 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
3950 IDirect3DTexture8_Release(texture);
3952 /* Render offscreen, then onscreen, and finally check the INTZ texture in both areas */
3953 hr = IDirect3DDevice8_CreateTexture(device, 640, 480, 1,
3954 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture);
3955 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
3956 hr = IDirect3DTexture8_GetSurfaceLevel(texture, 0, &ds);
3957 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
3958 hr = IDirect3DDevice8_SetRenderTarget(device, rt, ds);
3959 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
3960 hr = IDirect3DDevice8_SetPixelShader(device, 0);
3961 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
3963 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
3964 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
3966 hr = IDirect3DDevice8_BeginScene(device);
3967 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
3968 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, half_quad_1, sizeof(*half_quad_1));
3969 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3970 hr = IDirect3DDevice8_EndScene(device);
3971 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
3973 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, ds);
3974 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
3976 hr = IDirect3DDevice8_BeginScene(device);
3977 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
3978 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, half_quad_2, sizeof(*half_quad_2));
3979 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3980 hr = IDirect3DDevice8_EndScene(device);
3981 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
3983 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, NULL);
3984 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
3985 IDirect3DSurface8_Release(ds);
3986 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
3987 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
3988 hr = IDirect3DDevice8_SetTexture(device, 1, (IDirect3DBaseTexture8 *)texture);
3989 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
3990 hr = IDirect3DDevice8_SetPixelShader(device, ps);
3991 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
3993 /* Read the depth values back. */
3994 hr = IDirect3DDevice8_BeginScene(device);
3995 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
3996 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
3997 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3998 hr = IDirect3DDevice8_EndScene(device);
3999 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
4001 get_rt_readback(original_rt, &rb);
4002 for (i = 0; i < ARRAY_SIZE(expected_colors); ++i)
4004 D3DCOLOR color = get_readback_color(&rb, expected_colors[i].x, expected_colors[i].y);
4005 ok(color_match(color, expected_colors[i].color, 1),
4006 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
4007 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
4009 release_surface_readback(&rb);
4011 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
4012 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
4014 IDirect3DTexture8_Release(texture);
4015 hr = IDirect3DDevice8_DeletePixelShader(device, ps);
4016 ok(SUCCEEDED(hr), "DeletePixelShader failed, hr %#x.\n", hr);
4017 IDirect3DSurface8_Release(original_rt);
4018 IDirect3DSurface8_Release(rt);
4019 refcount = IDirect3DDevice8_Release(device);
4020 ok(!refcount, "Device has %u references left.\n", refcount);
4021 done:
4022 IDirect3D8_Release(d3d);
4023 DestroyWindow(window);
4026 static void shadow_test(void)
4028 IDirect3DSurface8 *original_rt, *rt;
4029 struct surface_readback rb;
4030 IDirect3DDevice8 *device;
4031 IDirect3D8 *d3d;
4032 ULONG refcount;
4033 D3DCAPS8 caps;
4034 HWND window;
4035 HRESULT hr;
4036 DWORD ps;
4037 UINT i;
4039 static const DWORD ps_code[] =
4041 0xffff0101, /* ps_1_1 */
4042 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c0, 1.0, 0.0, 1.0, 1.0 */
4043 0x00000051, 0xa00f0001, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c1, 0.0, 1.0, 0.0, 0.0 */
4044 0x00000042, 0xb00f0000, /* tex t0 */
4045 0x00000042, 0xb00f0001, /* tex t1 */
4046 0x00000005, 0xb00f0000, 0xa0e40000, 0xb0e40000, /* mul t0, c0, t0 */
4047 0x00000004, 0x800f0000, 0xa0e40001, 0xb0e40001, 0xb0e40000, /* mad r0, c1, t1, t0 */
4048 0x0000ffff, /* end */
4050 static const struct
4052 D3DFORMAT format;
4053 const char *name;
4055 formats[] =
4057 {D3DFMT_D16_LOCKABLE, "D3DFMT_D16_LOCKABLE"},
4058 {D3DFMT_D32, "D3DFMT_D32"},
4059 {D3DFMT_D15S1, "D3DFMT_D15S1"},
4060 {D3DFMT_D24S8, "D3DFMT_D24S8"},
4061 {D3DFMT_D24X8, "D3DFMT_D24X8"},
4062 {D3DFMT_D24X4S4, "D3DFMT_D24X4S4"},
4063 {D3DFMT_D16, "D3DFMT_D16"},
4065 static const struct
4067 float x, y, z;
4068 float s0, t0, p0;
4069 float s1, t1, p1, q1;
4071 quad[] =
4073 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f},
4074 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f},
4075 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
4076 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f},
4078 static const struct
4080 UINT x, y;
4081 D3DCOLOR color;
4083 expected_colors[] =
4085 {400, 60, 0x00000000},
4086 {560, 180, 0xffff00ff},
4087 {560, 300, 0xffff00ff},
4088 {400, 420, 0xffffffff},
4089 {240, 420, 0xffffffff},
4090 { 80, 300, 0x00000000},
4091 { 80, 180, 0x00000000},
4092 {240, 60, 0x00000000},
4095 window = create_window();
4096 d3d = Direct3DCreate8(D3D_SDK_VERSION);
4097 ok(!!d3d, "Failed to create a D3D object.\n");
4098 if (!(device = create_device(d3d, window, window, TRUE)))
4100 skip("Failed to create a D3D device, skipping tests.\n");
4101 goto done;
4104 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
4105 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
4106 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 1))
4108 skip("No pixel shader 1.1 support, skipping shadow test.\n");
4109 IDirect3DDevice8_Release(device);
4110 goto done;
4113 hr = IDirect3DDevice8_GetRenderTarget(device, &original_rt);
4114 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
4116 hr = IDirect3DDevice8_CreateRenderTarget(device, 1024, 1024, D3DFMT_A8R8G8B8,
4117 D3DMULTISAMPLE_NONE, FALSE, &rt);
4118 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
4119 hr = IDirect3DDevice8_CreatePixelShader(device, ps_code, &ps);
4120 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
4122 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX2
4123 | D3DFVF_TEXCOORDSIZE3(0) | D3DFVF_TEXCOORDSIZE4(1));
4124 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
4125 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
4126 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
4127 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
4128 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
4129 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
4130 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
4131 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
4132 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
4134 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MINFILTER, D3DTEXF_POINT);
4135 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
4136 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MIPFILTER, D3DTEXF_POINT);
4137 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
4138 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MAGFILTER, D3DTEXF_POINT);
4139 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
4140 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
4141 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
4143 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP);
4144 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
4145 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP);
4146 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
4147 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MAGFILTER, D3DTEXF_POINT);
4148 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
4149 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MINFILTER, D3DTEXF_POINT);
4150 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
4151 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MIPFILTER, D3DTEXF_POINT);
4152 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
4153 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS,
4154 D3DTTFF_COUNT4 | D3DTTFF_PROJECTED);
4155 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
4157 for (i = 0; i < ARRAY_SIZE(formats); ++i)
4159 D3DFORMAT format = formats[i].format;
4160 IDirect3DTexture8 *texture;
4161 IDirect3DSurface8 *ds;
4162 unsigned int j;
4164 if (FAILED(IDirect3D8_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
4165 D3DFMT_X8R8G8B8, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, format)))
4166 continue;
4168 hr = IDirect3DDevice8_CreateTexture(device, 1024, 1024, 1,
4169 D3DUSAGE_DEPTHSTENCIL, format, D3DPOOL_DEFAULT, &texture);
4170 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
4172 hr = IDirect3DTexture8_GetSurfaceLevel(texture, 0, &ds);
4173 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
4175 hr = IDirect3DDevice8_SetRenderTarget(device, rt, ds);
4176 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
4178 hr = IDirect3DDevice8_SetPixelShader(device, 0);
4179 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
4181 /* Setup the depth/stencil surface. */
4182 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
4183 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
4185 hr = IDirect3DDevice8_BeginScene(device);
4186 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
4187 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
4188 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
4189 hr = IDirect3DDevice8_EndScene(device);
4190 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
4192 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, NULL);
4193 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
4194 IDirect3DSurface8_Release(ds);
4196 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
4197 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
4198 hr = IDirect3DDevice8_SetTexture(device, 1, (IDirect3DBaseTexture8 *)texture);
4199 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
4201 hr = IDirect3DDevice8_SetPixelShader(device, ps);
4202 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
4204 /* Do the actual shadow mapping. */
4205 hr = IDirect3DDevice8_BeginScene(device);
4206 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
4207 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
4208 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
4209 hr = IDirect3DDevice8_EndScene(device);
4210 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
4212 hr = IDirect3DDevice8_SetTexture(device, 0, NULL);
4213 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
4214 hr = IDirect3DDevice8_SetTexture(device, 1, NULL);
4215 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
4216 IDirect3DTexture8_Release(texture);
4218 get_rt_readback(original_rt, &rb);
4219 for (j = 0; j < ARRAY_SIZE(expected_colors); ++j)
4221 D3DCOLOR color = get_readback_color(&rb, expected_colors[j].x, expected_colors[j].y);
4222 /* Geforce 7 on Windows returns 1.0 in alpha when the depth format is D24S8 or D24X8,
4223 * whereas other GPUs (all AMD, newer Nvidia) return the same value they return in .rgb.
4224 * Accept alpha mismatches as broken but make sure to check the color channels. */
4225 ok(color_match(color, expected_colors[j].color, 0)
4226 || broken(color_match(color & 0x00ffffff, expected_colors[j].color & 0x00ffffff, 0)),
4227 "Expected color 0x%08x at (%u, %u) for format %s, got 0x%08x.\n",
4228 expected_colors[j].color, expected_colors[j].x, expected_colors[j].y,
4229 formats[i].name, color);
4231 release_surface_readback(&rb);
4233 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
4234 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
4237 hr = IDirect3DDevice8_DeletePixelShader(device, ps);
4238 ok(SUCCEEDED(hr), "DeletePixelShader failed, hr %#x.\n", hr);
4239 IDirect3DSurface8_Release(original_rt);
4240 IDirect3DSurface8_Release(rt);
4241 refcount = IDirect3DDevice8_Release(device);
4242 ok(!refcount, "Device has %u references left.\n", refcount);
4243 done:
4244 IDirect3D8_Release(d3d);
4245 DestroyWindow(window);
4248 static void multisample_copy_rects_test(void)
4250 IDirect3DSurface8 *ds, *ds_plain, *rt, *readback;
4251 RECT src_rect = {64, 64, 128, 128};
4252 POINT dst_point = {96, 96};
4253 D3DLOCKED_RECT locked_rect;
4254 IDirect3DDevice8 *device;
4255 IDirect3D8 *d3d;
4256 D3DCOLOR color;
4257 ULONG refcount;
4258 HWND window;
4259 HRESULT hr;
4261 window = create_window();
4262 d3d = Direct3DCreate8(D3D_SDK_VERSION);
4263 ok(!!d3d, "Failed to create a D3D object.\n");
4264 if (!(device = create_device(d3d, window, window, TRUE)))
4266 skip("Failed to create a D3D device, skipping tests.\n");
4267 goto done;
4270 if (FAILED(IDirect3D8_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT,
4271 D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES)))
4273 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping multisampled CopyRects test.\n");
4274 IDirect3DDevice8_Release(device);
4275 goto done;
4278 hr = IDirect3DDevice8_CreateRenderTarget(device, 256, 256, D3DFMT_A8R8G8B8,
4279 D3DMULTISAMPLE_2_SAMPLES, FALSE, &rt);
4280 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
4281 hr = IDirect3DDevice8_CreateDepthStencilSurface(device, 256, 256, D3DFMT_D24S8,
4282 D3DMULTISAMPLE_2_SAMPLES, &ds);
4283 ok(SUCCEEDED(hr), "Failed to create depth stencil surface, hr %#x.\n", hr);
4284 hr = IDirect3DDevice8_CreateDepthStencilSurface(device, 256, 256, D3DFMT_D24S8,
4285 D3DMULTISAMPLE_NONE, &ds_plain);
4286 ok(SUCCEEDED(hr), "Failed to create depth stencil surface, hr %#x.\n", hr);
4287 hr = IDirect3DDevice8_CreateImageSurface(device, 256, 256, D3DFMT_A8R8G8B8, &readback);
4288 ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
4290 hr = IDirect3DDevice8_SetRenderTarget(device, rt, ds);
4291 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
4293 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
4294 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
4296 hr = IDirect3DDevice8_CopyRects(device, rt, NULL, 0, readback, NULL);
4297 ok(SUCCEEDED(hr), "Failed to read render target back, hr %#x.\n", hr);
4299 hr = IDirect3DDevice8_CopyRects(device, ds, NULL, 0, ds_plain, NULL);
4300 ok(hr == D3DERR_INVALIDCALL, "Depth buffer copy, hr %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
4302 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4303 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
4305 hr = IDirect3DDevice8_CopyRects(device, rt, &src_rect, 1, readback, &dst_point);
4306 ok(SUCCEEDED(hr), "Failed to read render target back, hr %#x.\n", hr);
4308 hr = IDirect3DSurface8_LockRect(readback, &locked_rect, NULL, D3DLOCK_READONLY);
4309 ok(SUCCEEDED(hr), "Failed to lock readback surface, hr %#x.\n", hr);
4311 color = *(DWORD *)((BYTE *)locked_rect.pBits + 31 * locked_rect.Pitch + 31 * 4);
4312 ok(color == 0xff00ff00, "Got unexpected color 0x%08x.\n", color);
4314 color = *(DWORD *)((BYTE *)locked_rect.pBits + 127 * locked_rect.Pitch + 127 * 4);
4315 ok(color == 0xffff0000, "Got unexpected color 0x%08x.\n", color);
4317 hr = IDirect3DSurface8_UnlockRect(readback);
4318 ok(SUCCEEDED(hr), "Failed to unlock readback surface, hr %#x.\n", hr);
4320 IDirect3DSurface8_Release(readback);
4321 IDirect3DSurface8_Release(ds_plain);
4322 IDirect3DSurface8_Release(ds);
4323 IDirect3DSurface8_Release(rt);
4324 refcount = IDirect3DDevice8_Release(device);
4325 ok(!refcount, "Device has %u references left.\n", refcount);
4326 done:
4327 IDirect3D8_Release(d3d);
4328 DestroyWindow(window);
4331 static void resz_test(void)
4333 IDirect3DSurface8 *rt, *original_rt, *ds, *original_ds, *intz_ds;
4334 IDirect3DTexture8 *texture;
4335 IDirect3DDevice8 *device;
4336 IDirect3D8 *d3d;
4337 DWORD ps, value;
4338 unsigned int i;
4339 ULONG refcount;
4340 D3DCAPS8 caps;
4341 HWND window;
4342 HRESULT hr;
4344 static const DWORD ps_code[] =
4346 0xffff0101, /* ps_1_1 */
4347 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1.0, 0.0, 0.0, 0.0 */
4348 0x00000051, 0xa00f0001, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c1, 0.0, 1.0, 0.0, 0.0 */
4349 0x00000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c2, 0.0, 0.0, 1.0, 0.0 */
4350 0x00000042, 0xb00f0000, /* tex t0 */
4351 0x00000042, 0xb00f0001, /* tex t1 */
4352 0x00000008, 0xb0070001, 0xa0e40000, 0xb0e40001, /* dp3 t1.xyz, c0, t1 */
4353 0x00000005, 0x80070000, 0xa0e40001, 0xb0e40001, /* mul r0.xyz, c1, t1 */
4354 0x00000004, 0x80070000, 0xa0e40000, 0xb0e40000, 0x80e40000, /* mad r0.xyz, c0, t0, r0 */
4355 0x40000001, 0x80080000, 0xa0aa0002, /* +mov r0.w, c2.z */
4356 0x0000ffff, /* end */
4358 static const struct
4360 float x, y, z;
4361 float s0, t0, p0;
4362 float s1, t1, p1, q1;
4364 quad[] =
4366 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.5f},
4367 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
4368 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
4369 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.5f},
4371 static const struct
4373 UINT x, y;
4374 D3DCOLOR color;
4376 expected_colors[] =
4378 { 80, 100, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
4379 {240, 100, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
4380 {400, 100, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
4381 {560, 100, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
4382 { 80, 450, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
4383 {240, 450, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
4384 {400, 450, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
4385 {560, 450, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
4388 window = create_window();
4389 d3d = Direct3DCreate8(D3D_SDK_VERSION);
4390 ok(!!d3d, "Failed to create a D3D object.\n");
4391 if (!(device = create_device(d3d, window, window, TRUE)))
4393 skip("Failed to create a D3D device, skipping tests.\n");
4394 goto done;
4397 if (FAILED(IDirect3D8_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT,
4398 D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES)))
4400 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping RESZ test.\n");
4401 IDirect3DDevice8_Release(device);
4402 goto done;
4404 if (FAILED(IDirect3D8_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT,
4405 D3DDEVTYPE_HAL, D3DFMT_D24S8, TRUE, D3DMULTISAMPLE_2_SAMPLES)))
4407 skip("Multisampling not supported for D3DFMT_D24S8, skipping RESZ test.\n");
4408 IDirect3DDevice8_Release(device);
4409 goto done;
4411 if (FAILED(IDirect3D8_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
4412 D3DFMT_X8R8G8B8, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, MAKEFOURCC('I','N','T','Z'))))
4414 skip("No INTZ support, skipping RESZ test.\n");
4415 IDirect3DDevice8_Release(device);
4416 goto done;
4418 if (FAILED(IDirect3D8_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
4419 D3DFMT_X8R8G8B8, D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE, MAKEFOURCC('R','E','S','Z'))))
4421 skip("No RESZ support, skipping RESZ test.\n");
4422 IDirect3DDevice8_Release(device);
4423 goto done;
4426 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
4427 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
4428 if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
4430 skip("No unconditional NP2 texture support, skipping INTZ test.\n");
4431 IDirect3DDevice8_Release(device);
4432 goto done;
4435 hr = IDirect3DDevice8_GetRenderTarget(device, &original_rt);
4436 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
4437 hr = IDirect3DDevice8_GetDepthStencilSurface(device, &original_ds);
4438 ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#x.\n", hr);
4440 hr = IDirect3DDevice8_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
4441 D3DMULTISAMPLE_2_SAMPLES, FALSE, &rt);
4442 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
4443 hr = IDirect3DDevice8_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
4444 D3DMULTISAMPLE_2_SAMPLES, &ds);
4446 hr = IDirect3DDevice8_CreateTexture(device, 640, 480, 1,
4447 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture);
4448 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
4449 hr = IDirect3DTexture8_GetSurfaceLevel(texture, 0, &intz_ds);
4450 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
4452 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, intz_ds);
4453 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
4454 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
4455 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
4457 hr = IDirect3DDevice8_SetRenderTarget(device, rt, ds);
4458 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
4459 IDirect3DSurface8_Release(intz_ds);
4460 hr = IDirect3DDevice8_CreatePixelShader(device, ps_code, &ps);
4461 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
4463 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX2
4464 | D3DFVF_TEXCOORDSIZE3(0) | D3DFVF_TEXCOORDSIZE4(1));
4465 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
4466 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
4467 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
4468 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
4469 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
4470 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
4471 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
4472 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
4473 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
4475 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MINFILTER, D3DTEXF_POINT);
4476 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
4477 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MIPFILTER, D3DTEXF_POINT);
4478 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
4479 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MAGFILTER, D3DTEXF_POINT);
4480 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
4481 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
4482 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
4484 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP);
4485 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
4486 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP);
4487 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
4488 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MAGFILTER, D3DTEXF_POINT);
4489 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
4490 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MINFILTER, D3DTEXF_POINT);
4491 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
4492 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MIPFILTER, D3DTEXF_POINT);
4493 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
4494 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS,
4495 D3DTTFF_COUNT4 | D3DTTFF_PROJECTED);
4496 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
4498 /* Render offscreen (multisampled), blit the depth buffer into the INTZ texture and then check its contents. */
4499 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
4500 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
4502 hr = IDirect3DDevice8_BeginScene(device);
4503 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
4504 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
4505 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
4507 /* The destination depth texture has to be bound to sampler 0 */
4508 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
4509 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
4511 /* the ATI "spec" says you have to do a dummy draw to ensure correct commands ordering */
4512 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, FALSE);
4513 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
4514 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
4515 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
4516 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0);
4517 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
4518 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
4519 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
4520 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, TRUE);
4521 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
4522 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
4523 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
4524 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0xf);
4525 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
4527 /* The actual multisampled depth buffer resolve happens here */
4528 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
4529 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
4530 hr = IDirect3DDevice8_GetRenderState(device, D3DRS_POINTSIZE, &value);
4531 ok(SUCCEEDED(hr) && value == 0x7fa05000, "GetRenderState failed, hr %#x, value %#x.\n", hr, value);
4533 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, NULL);
4534 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
4535 hr = IDirect3DDevice8_SetTexture(device, 1, (IDirect3DBaseTexture8 *)texture);
4536 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
4537 hr = IDirect3DDevice8_SetPixelShader(device, ps);
4538 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
4540 /* Read the depth values back. */
4541 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
4542 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
4543 hr = IDirect3DDevice8_EndScene(device);
4544 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
4546 for (i = 0; i < ARRAY_SIZE(expected_colors); ++i)
4548 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
4549 ok(color_match(color, expected_colors[i].color, 1),
4550 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
4551 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
4554 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
4555 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
4557 /* Test edge cases - try with no texture at all */
4558 hr = IDirect3DDevice8_SetTexture(device, 0, NULL);
4559 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
4560 hr = IDirect3DDevice8_SetTexture(device, 1, NULL);
4561 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
4562 hr = IDirect3DDevice8_SetRenderTarget(device, rt, ds);
4563 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
4565 hr = IDirect3DDevice8_BeginScene(device);
4566 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
4567 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
4568 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
4569 hr = IDirect3DDevice8_EndScene(device);
4570 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
4572 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
4573 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
4575 /* With a non-multisampled depth buffer */
4576 IDirect3DSurface8_Release(ds);
4577 IDirect3DSurface8_Release(rt);
4578 hr = IDirect3DDevice8_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
4579 D3DMULTISAMPLE_NONE, &ds);
4581 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, ds);
4582 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
4583 hr = IDirect3DDevice8_SetPixelShader(device, 0);
4584 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
4586 hr = IDirect3DDevice8_BeginScene(device);
4587 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
4588 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
4589 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
4590 hr = IDirect3DDevice8_EndScene(device);
4591 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
4593 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
4594 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
4596 hr = IDirect3DDevice8_BeginScene(device);
4597 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
4598 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, FALSE);
4599 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
4600 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
4601 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
4602 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0);
4603 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
4604 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
4605 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
4606 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, TRUE);
4607 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
4608 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
4609 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
4610 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0xf);
4611 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
4612 hr = IDirect3DDevice8_EndScene(device);
4613 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
4615 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
4616 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
4618 hr = IDirect3DDevice8_SetTexture(device, 1, (IDirect3DBaseTexture8 *)texture);
4619 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
4620 hr = IDirect3DDevice8_SetPixelShader(device, ps);
4621 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
4623 /* Read the depth values back. */
4624 hr = IDirect3DDevice8_BeginScene(device);
4625 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
4626 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
4627 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
4628 hr = IDirect3DDevice8_EndScene(device);
4629 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
4631 for (i = 0; i < ARRAY_SIZE(expected_colors); ++i)
4633 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
4634 ok(color_match(color, expected_colors[i].color, 1),
4635 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
4636 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
4639 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
4640 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
4642 IDirect3DSurface8_Release(ds);
4643 IDirect3DTexture8_Release(texture);
4644 hr = IDirect3DDevice8_DeletePixelShader(device, ps);
4645 ok(SUCCEEDED(hr), "DeletePixelShader failed, hr %#x.\n", hr);
4646 IDirect3DSurface8_Release(original_ds);
4647 IDirect3DSurface8_Release(original_rt);
4649 refcount = IDirect3DDevice8_Release(device);
4650 ok(!refcount, "Device has %u references left.\n", refcount);
4651 done:
4652 IDirect3D8_Release(d3d);
4653 DestroyWindow(window);
4656 static void zenable_test(void)
4658 IDirect3DDevice8 *device;
4659 IDirect3D8 *d3d;
4660 D3DCOLOR color;
4661 ULONG refcount;
4662 D3DCAPS8 caps;
4663 HWND window;
4664 HRESULT hr;
4665 UINT x, y;
4666 UINT i, j;
4667 UINT test;
4668 IDirect3DSurface8 *ds, *rt;
4670 static const struct
4672 struct vec4 position;
4673 D3DCOLOR diffuse;
4675 tquad[] =
4677 {{ 0.0f, 480.0f, -0.5f, 1.0f}, 0xff00ff00},
4678 {{ 0.0f, 0.0f, -0.5f, 1.0f}, 0xff00ff00},
4679 {{640.0f, 480.0f, 1.5f, 1.0f}, 0xff00ff00},
4680 {{640.0f, 0.0f, 1.5f, 1.0f}, 0xff00ff00},
4683 window = create_window();
4684 d3d = Direct3DCreate8(D3D_SDK_VERSION);
4685 ok(!!d3d, "Failed to create a D3D object.\n");
4686 if (!(device = create_device(d3d, window, window, TRUE)))
4688 skip("Failed to create a D3D device, skipping tests.\n");
4689 goto done;
4692 hr = IDirect3DDevice8_GetDepthStencilSurface(device, &ds);
4693 ok(SUCCEEDED(hr), "Failed to get depth stencil surface, hr %#x.\n", hr);
4694 hr = IDirect3DDevice8_GetRenderTarget(device, &rt);
4695 ok(SUCCEEDED(hr), "Failed to get render target surface, hr %#x.\n", hr);
4697 for (test = 0; test < 2; ++test)
4699 /* The Windows 8 testbot (WARP) appears to clip with
4700 * ZENABLE = D3DZB_TRUE and no depth buffer set. */
4701 static const D3DCOLOR expected_broken[] =
4703 0x00ff0000, 0x0000ff00, 0x0000ff00, 0x00ff0000,
4704 0x00ff0000, 0x0000ff00, 0x0000ff00, 0x00ff0000,
4705 0x00ff0000, 0x0000ff00, 0x0000ff00, 0x00ff0000,
4706 0x00ff0000, 0x0000ff00, 0x0000ff00, 0x00ff0000,
4709 if (!test)
4711 hr = IDirect3DDevice8_SetRenderTarget(device, rt, NULL);
4712 ok(SUCCEEDED(hr), "Failed to set depth stencil surface, hr %#x.\n", hr);
4714 else
4716 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
4717 ok(SUCCEEDED(hr), "Failed to disable z-buffering, hr %#x.\n", hr);
4718 hr = IDirect3DDevice8_SetRenderTarget(device, rt, ds);
4719 ok(SUCCEEDED(hr), "Failed to set depth stencil surface, hr %#x.\n", hr);
4720 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 0.0f, 0);
4721 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
4723 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
4724 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
4726 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0f, 0);
4727 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
4728 hr = IDirect3DDevice8_BeginScene(device);
4729 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
4730 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, tquad, sizeof(*tquad));
4731 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4732 hr = IDirect3DDevice8_EndScene(device);
4733 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
4735 for (i = 0; i < 4; ++i)
4737 for (j = 0; j < 4; ++j)
4739 x = 80 * ((2 * j) + 1);
4740 y = 60 * ((2 * i) + 1);
4741 color = getPixelColor(device, x, y);
4742 ok(color_match(color, 0x0000ff00, 1)
4743 || broken(color_match(color, expected_broken[i * 4 + j], 1) && !test),
4744 "Expected color 0x0000ff00 at %u, %u, got 0x%08x.\n", x, y, color);
4748 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
4749 ok(SUCCEEDED(hr), "Failed to present backbuffer, hr %#x.\n", hr);
4752 IDirect3DSurface8_Release(ds);
4753 IDirect3DSurface8_Release(rt);
4755 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
4756 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
4758 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1)
4759 && caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
4761 static const DWORD vs_code[] =
4763 0xfffe0101, /* vs_1_1 */
4764 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4765 0x00000001, 0xd00f0000, 0x90e40000, /* mov oD0, v0 */
4766 0x0000ffff
4768 static const DWORD ps_code[] =
4770 0xffff0101, /* ps_1_1 */
4771 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
4772 0x0000ffff /* end */
4774 static const struct vec3 quad[] =
4776 {-1.0f, -1.0f, -0.5f},
4777 {-1.0f, 1.0f, -0.5f},
4778 { 1.0f, -1.0f, 1.5f},
4779 { 1.0f, 1.0f, 1.5f},
4781 static const D3DCOLOR expected[] =
4783 0x00ff0000, 0x0060df60, 0x009fdf9f, 0x00ff0000,
4784 0x00ff0000, 0x00609f60, 0x009f9f9f, 0x00ff0000,
4785 0x00ff0000, 0x00606060, 0x009f609f, 0x00ff0000,
4786 0x00ff0000, 0x00602060, 0x009f209f, 0x00ff0000,
4788 /* The Windows 8 testbot (WARP) appears to not clip z for regular
4789 * vertices either. */
4790 static const D3DCOLOR expected_broken[] =
4792 0x0020df20, 0x0060df60, 0x009fdf9f, 0x00dfdfdf,
4793 0x00209f20, 0x00609f60, 0x009f9f9f, 0x00df9fdf,
4794 0x00206020, 0x00606060, 0x009f609f, 0x00df60df,
4795 0x00202020, 0x00602060, 0x009f209f, 0x00df20df,
4797 static const DWORD decl[] =
4799 D3DVSD_STREAM(0),
4800 D3DVSD_REG(D3DVSDE_POSITION, D3DVSDT_FLOAT3),
4801 D3DVSD_END()
4803 DWORD vs, ps;
4805 hr = IDirect3DDevice8_CreateVertexShader(device, decl, vs_code, &vs, 0);
4806 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
4807 hr = IDirect3DDevice8_CreatePixelShader(device, ps_code, &ps);
4808 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
4809 hr = IDirect3DDevice8_SetVertexShader(device, vs);
4810 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
4811 hr = IDirect3DDevice8_SetPixelShader(device, ps);
4812 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
4814 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0f, 0);
4815 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
4816 hr = IDirect3DDevice8_BeginScene(device);
4817 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
4818 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
4819 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4820 hr = IDirect3DDevice8_EndScene(device);
4821 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
4823 for (i = 0; i < 4; ++i)
4825 for (j = 0; j < 4; ++j)
4827 x = 80 * ((2 * j) + 1);
4828 y = 60 * ((2 * i) + 1);
4829 color = getPixelColor(device, x, y);
4830 ok(color_match(color, expected[i * 4 + j], 1)
4831 || broken(color_match(color, expected_broken[i * 4 + j], 1)),
4832 "Expected color 0x%08x at %u, %u, got 0x%08x.\n", expected[i * 4 + j], x, y, color);
4836 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
4837 ok(SUCCEEDED(hr), "Failed to present backbuffer, hr %#x.\n", hr);
4839 hr = IDirect3DDevice8_DeletePixelShader(device, ps);
4840 ok(SUCCEEDED(hr), "Failed to delete pixel shader, hr %#x.\n", hr);
4841 hr = IDirect3DDevice8_DeleteVertexShader(device, vs);
4842 ok(SUCCEEDED(hr), "Failed to delete vertex shader, hr %#x.\n", hr);
4845 refcount = IDirect3DDevice8_Release(device);
4846 ok(!refcount, "Device has %u references left.\n", refcount);
4847 done:
4848 IDirect3D8_Release(d3d);
4849 DestroyWindow(window);
4852 static void fog_special_test(void)
4854 IDirect3DDevice8 *device;
4855 IDirect3D8 *d3d;
4856 unsigned int i;
4857 D3DCOLOR color;
4858 ULONG refcount;
4859 D3DCAPS8 caps;
4860 DWORD ps, vs;
4861 HWND window;
4862 HRESULT hr;
4863 union
4865 float f;
4866 DWORD d;
4867 } conv;
4869 static const struct
4871 struct vec3 position;
4872 D3DCOLOR diffuse;
4874 quad[] =
4876 {{ -1.0f, -1.0f, 0.0f}, 0xff00ff00},
4877 {{ -1.0f, 1.0f, 0.0f}, 0xff00ff00},
4878 {{ 1.0f, -1.0f, 1.0f}, 0xff00ff00},
4879 {{ 1.0f, 1.0f, 1.0f}, 0xff00ff00}
4881 static const struct
4883 DWORD vertexmode, tablemode;
4884 BOOL vs, ps;
4885 D3DCOLOR color_left, color_right;
4887 tests[] =
4889 {D3DFOG_LINEAR, D3DFOG_NONE, FALSE, FALSE, 0x00ff0000, 0x00ff0000},
4890 {D3DFOG_LINEAR, D3DFOG_NONE, FALSE, TRUE, 0x00ff0000, 0x00ff0000},
4891 {D3DFOG_LINEAR, D3DFOG_NONE, TRUE, FALSE, 0x00ff0000, 0x00ff0000},
4892 {D3DFOG_LINEAR, D3DFOG_NONE, TRUE, TRUE, 0x00ff0000, 0x00ff0000},
4894 {D3DFOG_NONE, D3DFOG_LINEAR, FALSE, FALSE, 0x0000ff00, 0x00ff0000},
4895 {D3DFOG_NONE, D3DFOG_LINEAR, FALSE, TRUE, 0x0000ff00, 0x00ff0000},
4896 {D3DFOG_NONE, D3DFOG_LINEAR, TRUE, FALSE, 0x0000ff00, 0x00ff0000},
4897 {D3DFOG_NONE, D3DFOG_LINEAR, TRUE, TRUE, 0x0000ff00, 0x00ff0000},
4899 static const DWORD pixel_shader_code[] =
4901 0xffff0101, /* ps.1.1 */
4902 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
4903 0x0000ffff
4905 static const DWORD vertex_decl[] =
4907 D3DVSD_STREAM(0),
4908 D3DVSD_REG(0, D3DVSDT_FLOAT3), /* position, v0 */
4909 D3DVSD_REG(1, D3DVSDT_D3DCOLOR), /* diffuse color, v1 */
4910 D3DVSD_END()
4912 static const DWORD vertex_shader_code[] =
4914 0xfffe0101, /* vs.1.1 */
4915 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4916 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
4917 0x0000ffff
4919 static const D3DMATRIX identity =
4921 1.0f, 0.0f, 0.0f, 0.0f,
4922 0.0f, 1.0f, 0.0f, 0.0f,
4923 0.0f, 0.0f, 1.0f, 0.0f,
4924 0.0f, 0.0f, 0.0f, 1.0f,
4925 }}};
4927 window = create_window();
4928 d3d = Direct3DCreate8(D3D_SDK_VERSION);
4929 ok(!!d3d, "Failed to create a D3D object.\n");
4930 if (!(device = create_device(d3d, window, window, TRUE)))
4932 skip("Failed to create a D3D device, skipping tests.\n");
4933 goto done;
4936 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
4937 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
4938 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
4940 hr = IDirect3DDevice8_CreateVertexShader(device, vertex_decl, vertex_shader_code, &vs, 0);
4941 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
4943 else
4945 skip("Vertex Shaders not supported, skipping some fog tests.\n");
4946 vs = 0;
4948 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
4950 hr = IDirect3DDevice8_CreatePixelShader(device, pixel_shader_code, &ps);
4951 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
4953 else
4955 skip("Pixel Shaders not supported, skipping some fog tests.\n");
4956 ps = 0;
4959 /* The table fog tests seem to depend on the projection matrix explicitly
4960 * being set to an identity matrix, even though that's the default.
4961 * (AMD Radeon HD 6310, Windows 7) */
4962 hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, &identity);
4963 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
4965 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
4966 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
4967 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
4968 ok(SUCCEEDED(hr), "Failed to enable fog, hr %#x.\n", hr);
4969 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGCOLOR, 0xffff0000);
4970 ok(SUCCEEDED(hr), "Failed to set fog color, hr %#x.\n", hr);
4972 conv.f = 0.5f;
4973 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGSTART, conv.d);
4974 ok(SUCCEEDED(hr), "Failed to set fog start, hr %#x.\n", hr);
4975 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGEND, conv.d);
4976 ok(SUCCEEDED(hr), "Failed to set fog end, hr %#x.\n", hr);
4978 for (i = 0; i < ARRAY_SIZE(tests); i++)
4980 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
4981 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
4983 if (!tests[i].vs)
4985 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
4986 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr);
4988 else if (vs)
4990 hr = IDirect3DDevice8_SetVertexShader(device, vs);
4991 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
4993 else
4995 continue;
4998 if (!tests[i].ps)
5000 hr = IDirect3DDevice8_SetPixelShader(device, 0);
5001 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
5003 else if (ps)
5005 hr = IDirect3DDevice8_SetPixelShader(device, ps);
5006 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
5008 else
5010 continue;
5013 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGVERTEXMODE, tests[i].vertexmode);
5014 ok(SUCCEEDED(hr), "Failed to set fogvertexmode, hr %#x.\n", hr);
5015 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGTABLEMODE, tests[i].tablemode);
5016 ok(SUCCEEDED(hr), "Failed to set fogtablemode, hr %#x.\n", hr);
5018 hr = IDirect3DDevice8_BeginScene(device);
5019 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5020 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
5021 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5022 hr = IDirect3DDevice8_EndScene(device);
5023 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5025 color = getPixelColor(device, 310, 240);
5026 ok(color_match(color, tests[i].color_left, 1),
5027 "Expected left color 0x%08x, got 0x%08x, case %u.\n", tests[i].color_left, color, i);
5028 color = getPixelColor(device, 330, 240);
5029 ok(color_match(color, tests[i].color_right, 1),
5030 "Expected right color 0x%08x, got 0x%08x, case %u.\n", tests[i].color_right, color, i);
5032 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5033 ok(SUCCEEDED(hr), "Failed to present backbuffer, hr %#x.\n", hr);
5036 if (vs)
5037 IDirect3DDevice8_DeleteVertexShader(device, vs);
5038 if (ps)
5039 IDirect3DDevice8_DeletePixelShader(device, ps);
5040 refcount = IDirect3DDevice8_Release(device);
5041 ok(!refcount, "Device has %u references left.\n", refcount);
5042 done:
5043 IDirect3D8_Release(d3d);
5044 DestroyWindow(window);
5047 static void volume_dxtn_test(void)
5049 IDirect3DVolumeTexture8 *texture;
5050 struct surface_readback rb;
5051 IDirect3DDevice8 *device;
5052 IDirect3DSurface8 *rt;
5053 D3DLOCKED_BOX box;
5054 unsigned int i, j;
5055 IDirect3D8 *d3d;
5056 ULONG refcount;
5057 DWORD colour;
5058 HWND window;
5059 HRESULT hr;
5061 static const BYTE dxt1_data[] =
5063 0x00, 0xf8, 0x00, 0xf8, 0xf0, 0xf0, 0xf0, 0xf0,
5064 0xe0, 0x07, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00,
5065 0x1f, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00,
5066 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00
5068 static const BYTE dxt3_data[] =
5070 0xff, 0xee, 0xff, 0xee, 0xff, 0xee, 0xff, 0xee, 0x00, 0xf8, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00,
5071 0xff, 0xdd, 0xff, 0xdd, 0xff, 0xdd, 0xff, 0xdd, 0xe0, 0x07, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00,
5072 0xff, 0xcc, 0xff, 0xcc, 0xff, 0xcc, 0xff, 0xcc, 0x1f, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00,
5073 0xff, 0xbb, 0xff, 0xbb, 0xff, 0xbb, 0xff, 0xbb, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00
5075 static const BYTE dxt5_data[] =
5077 /* A 8x4x2 texture consisting of 4 4x4 blocks. The colours of the
5078 * blocks are red, green, blue and white. */
5079 0xff, 0xff, 0x80, 0x0d, 0xd8, 0x80, 0x0d, 0xd8, 0x00, 0xf8, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00,
5080 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00,
5081 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00,
5082 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00
5084 static const DWORD dxt1_expected_colours[] =
5086 0xffff0000, 0x00000000, 0xff00ff00, 0xff00ff00,
5087 0xff0000ff, 0xff0000ff, 0xffffffff, 0xffffffff,
5089 static const DWORD dxt3_expected_colours[] =
5091 0xffff0000, 0xeeff0000, 0xff00ff00, 0xdd00ff00,
5092 0xff0000ff, 0xcc0000ff, 0xffffffff, 0xbbffffff,
5094 static const DWORD dxt5_expected_colours[] =
5096 0xffff0000, 0x00ff0000, 0xff00ff00, 0xff00ff00,
5097 0xff0000ff, 0xff0000ff, 0xffffffff, 0xffffffff
5100 static const struct
5102 const char *name;
5103 D3DFORMAT format;
5104 const BYTE *data;
5105 DWORD data_size;
5106 const DWORD *expected_colours;
5108 tests[] =
5110 {"DXT1", D3DFMT_DXT1, dxt1_data, sizeof(dxt1_data), dxt1_expected_colours},
5111 {"DXT3", D3DFMT_DXT3, dxt3_data, sizeof(dxt3_data), dxt3_expected_colours},
5112 {"DXT5", D3DFMT_DXT5, dxt5_data, sizeof(dxt5_data), dxt5_expected_colours},
5115 static const struct
5117 struct vec3 position;
5118 struct vec3 texcrd;
5120 quads[] =
5122 {{ -1.0f, -1.0f, 0.0f}, { 0.0f, 0.0f, 0.25f}},
5123 {{ -1.0f, 1.0f, 0.0f}, { 0.0f, 1.0f, 0.25f}},
5124 {{ 0.0f, -1.0f, 1.0f}, { 1.0f, 0.0f, 0.25f}},
5125 {{ 0.0f, 1.0f, 1.0f}, { 1.0f, 1.0f, 0.25f}},
5127 {{ 0.0f, -1.0f, 0.0f}, { 0.0f, 0.0f, 0.75f}},
5128 {{ 0.0f, 1.0f, 0.0f}, { 0.0f, 1.0f, 0.75f}},
5129 {{ 1.0f, -1.0f, 1.0f}, { 1.0f, 0.0f, 0.75f}},
5130 {{ 1.0f, 1.0f, 1.0f}, { 1.0f, 1.0f, 0.75f}},
5133 window = create_window();
5134 d3d = Direct3DCreate8(D3D_SDK_VERSION);
5135 ok(!!d3d, "Failed to create a D3D object.\n");
5137 if (!(device = create_device(d3d, window, window, TRUE)))
5139 skip("Failed to create a D3D device, skipping tests.\n");
5140 goto done;
5143 hr = IDirect3DDevice8_GetRenderTarget(device, &rt);
5144 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
5146 for (i = 0; i < ARRAY_SIZE(tests); ++i)
5148 if (FAILED(IDirect3D8_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
5149 D3DFMT_X8R8G8B8, 0, D3DRTYPE_VOLUMETEXTURE, tests[i].format)))
5151 skip("%s volume textures are not supported, skipping test.\n", tests[i].name);
5152 continue;
5154 hr = IDirect3DDevice8_CreateVolumeTexture(device, 8, 4, 2, 1, 0,
5155 tests[i].format, D3DPOOL_MANAGED, &texture);
5156 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
5158 hr = IDirect3DVolumeTexture8_LockBox(texture, 0, &box, NULL, 0);
5159 ok(SUCCEEDED(hr), "Failed to lock volume texture, hr %#x.\n", hr);
5160 memcpy(box.pBits, tests[i].data, tests[i].data_size);
5161 hr = IDirect3DVolumeTexture8_UnlockBox(texture, 0);
5162 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#x.\n", hr);
5164 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE3(0));
5165 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
5166 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
5167 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
5168 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
5169 ok(SUCCEEDED(hr), "Failed to set colour op, hr %#x.\n", hr);
5170 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
5171 ok(SUCCEEDED(hr), "Failed to set colour arg, hr %#x.\n", hr);
5172 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
5173 ok(SUCCEEDED(hr), "Failed to set colour op, hr %#x.\n", hr);
5174 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MAGFILTER, D3DTEXF_POINT);
5175 ok(SUCCEEDED(hr), "Failed to set mag filter, hr %#x.\n", hr);
5177 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff00ff, 1.0f, 0);
5178 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
5179 hr = IDirect3DDevice8_BeginScene(device);
5180 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5181 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads));
5182 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5183 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[4], sizeof(*quads));
5184 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5185 hr = IDirect3DDevice8_EndScene(device);
5186 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5188 get_rt_readback(rt, &rb);
5189 for (j = 0; j < ARRAY_SIZE(dxt1_expected_colours); ++j)
5191 colour = get_readback_color(&rb, 40 + 80 * j, 240);
5192 ok(color_match(colour, tests[i].expected_colours[j], 1),
5193 "Expected colour 0x%08x, got 0x%08x, case %u.\n", tests[i].expected_colours[j], colour, j);
5195 release_surface_readback(&rb);
5197 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5198 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5199 IDirect3DVolumeTexture8_Release(texture);
5202 IDirect3DSurface8_Release(rt);
5203 refcount = IDirect3DDevice8_Release(device);
5204 ok(!refcount, "Device has %u references left.\n", refcount);
5205 done:
5206 IDirect3D8_Release(d3d);
5207 DestroyWindow(window);
5210 static void volume_v16u16_test(void)
5212 IDirect3DVolumeTexture8 *texture;
5213 IDirect3DDevice8 *device;
5214 D3DLOCKED_BOX box;
5215 IDirect3D8 *d3d;
5216 unsigned int i;
5217 D3DCOLOR color;
5218 ULONG refcount;
5219 D3DCAPS8 caps;
5220 DWORD shader;
5221 SHORT *texel;
5222 HWND window;
5223 HRESULT hr;
5225 static const struct
5227 struct vec3 position;
5228 struct vec3 texcrd;
5230 quads[] =
5232 {{ -1.0f, -1.0f, 0.0f}, { 0.0f, 0.0f, 0.25f}},
5233 {{ -1.0f, 1.0f, 0.0f}, { 0.0f, 1.0f, 0.25f}},
5234 {{ 0.0f, -1.0f, 1.0f}, { 1.0f, 0.0f, 0.25f}},
5235 {{ 0.0f, 1.0f, 1.0f}, { 1.0f, 1.0f, 0.25f}},
5237 {{ 0.0f, -1.0f, 0.0f}, { 0.0f, 0.0f, 0.75f}},
5238 {{ 0.0f, 1.0f, 0.0f}, { 0.0f, 1.0f, 0.75f}},
5239 {{ 1.0f, -1.0f, 1.0f}, { 1.0f, 0.0f, 0.75f}},
5240 {{ 1.0f, 1.0f, 1.0f}, { 1.0f, 1.0f, 0.75f}},
5242 static const DWORD shader_code[] =
5244 0xffff0101, /* ps_1_1 */
5245 0x00000051, 0xa00f0000, 0x3f000000, 0x3f000000, /* def c0, 0.5, 0.5, */
5246 0x3f000000, 0x3f000000, /* 0.5, 0.5 */
5247 0x00000042, 0xb00f0000, /* tex t0 */
5248 0x00000004, 0x800f0000, 0xb0e40000, 0xa0e40000, 0xa0e40000, /* mad r0, t0, c0, c0 */
5249 0x0000ffff /* end */
5252 window = create_window();
5253 d3d = Direct3DCreate8(D3D_SDK_VERSION);
5254 ok(!!d3d, "Failed to create a D3D object.\n");
5255 if (!(device = create_device(d3d, window, window, TRUE)))
5257 skip("Failed to create a D3D device, skipping tests.\n");
5258 goto done;
5261 if (FAILED(IDirect3D8_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
5262 D3DFMT_X8R8G8B8, 0, D3DRTYPE_VOLUMETEXTURE, D3DFMT_V16U16)))
5264 skip("Volume V16U16 textures are not supported, skipping test.\n");
5265 IDirect3DDevice8_Release(device);
5266 goto done;
5268 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
5269 ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
5270 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 1))
5272 skip("No pixel shader 1.1 support, skipping test.\n");
5273 IDirect3DDevice8_Release(device);
5274 goto done;
5277 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE3(0));
5278 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
5279 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code, &shader);
5280 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
5281 hr = IDirect3DDevice8_SetPixelShader(device, shader);
5282 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
5283 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MAGFILTER, D3DTEXF_POINT);
5284 ok(SUCCEEDED(hr), "Failed to set filter, hr %#x.\n", hr);
5286 for (i = 0; i < 2; i++)
5288 D3DPOOL pool;
5290 if (i)
5291 pool = D3DPOOL_SYSTEMMEM;
5292 else
5293 pool = D3DPOOL_MANAGED;
5295 hr = IDirect3DDevice8_CreateVolumeTexture(device, 1, 2, 2, 1, 0, D3DFMT_V16U16,
5296 pool, &texture);
5297 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
5299 hr = IDirect3DVolumeTexture8_LockBox(texture, 0, &box, NULL, 0);
5300 ok(SUCCEEDED(hr), "Failed to lock volume texture, hr %#x.\n", hr);
5302 texel = (SHORT *)((BYTE *)box.pBits + 0 * box.RowPitch + 0 * box.SlicePitch);
5303 texel[0] = 32767;
5304 texel[1] = 32767;
5305 texel = (SHORT *)((BYTE *)box.pBits + 1 * box.RowPitch + 0 * box.SlicePitch);
5306 texel[0] = -32768;
5307 texel[1] = 0;
5308 texel = (SHORT *)((BYTE *)box.pBits + 0 * box.RowPitch + 1 * box.SlicePitch);
5309 texel[0] = -16384;
5310 texel[1] = 16384;
5311 texel = (SHORT *)((BYTE *)box.pBits + 1 * box.RowPitch + 1 * box.SlicePitch);
5312 texel[0] = 0;
5313 texel[1] = 0;
5315 hr = IDirect3DVolumeTexture8_UnlockBox(texture, 0);
5316 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#x.\n", hr);
5318 if (i)
5320 IDirect3DVolumeTexture8 *texture2;
5322 hr = IDirect3DDevice8_CreateVolumeTexture(device, 1, 2, 2, 1, 0, D3DFMT_V16U16,
5323 D3DPOOL_DEFAULT, &texture2);
5324 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
5326 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)texture,
5327 (IDirect3DBaseTexture8 *)texture2);
5328 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
5330 IDirect3DVolumeTexture8_Release(texture);
5331 texture = texture2;
5334 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *) texture);
5335 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
5337 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff00ff, 1.0f, 0);
5338 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
5339 hr = IDirect3DDevice8_BeginScene(device);
5340 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5341 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads));
5342 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5343 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[4], sizeof(*quads));
5344 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5345 hr = IDirect3DDevice8_EndScene(device);
5346 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5348 color = getPixelColor(device, 120, 160);
5349 ok (color_match(color, 0x000080ff, 2),
5350 "Expected color 0x000080ff, got 0x%08x, V16U16 input -32768, 0.\n", color);
5351 color = getPixelColor(device, 120, 400);
5352 ok (color_match(color, 0x00ffffff, 2),
5353 "Expected color 0x00ffffff, got 0x%08x, V16U16 input 32767, 32767.\n", color);
5354 color = getPixelColor(device, 360, 160);
5355 ok (color_match(color, 0x007f7fff, 2),
5356 "Expected color 0x007f7fff, got 0x%08x, V16U16 input 0, 0.\n", color);
5357 color = getPixelColor(device, 360, 400);
5358 ok (color_match(color, 0x0040c0ff, 2),
5359 "Expected color 0x0040c0ff, got 0x%08x, V16U16 input -16384, 16384.\n", color);
5361 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5362 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5364 IDirect3DVolumeTexture8_Release(texture);
5367 hr = IDirect3DDevice8_DeletePixelShader(device, shader);
5368 ok(SUCCEEDED(hr), "Failed delete pixel shader, hr %#x.\n", hr);
5369 refcount = IDirect3DDevice8_Release(device);
5370 ok(!refcount, "Device has %u references left.\n", refcount);
5371 done:
5372 IDirect3D8_Release(d3d);
5373 DestroyWindow(window);
5376 static void fill_surface(IDirect3DSurface8 *surface, DWORD color, DWORD flags)
5378 D3DSURFACE_DESC desc;
5379 D3DLOCKED_RECT l;
5380 HRESULT hr;
5381 unsigned int x, y;
5382 DWORD *mem;
5384 hr = IDirect3DSurface8_GetDesc(surface, &desc);
5385 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
5386 hr = IDirect3DSurface8_LockRect(surface, &l, NULL, flags);
5387 ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
5388 if (FAILED(hr))
5389 return;
5391 for (y = 0; y < desc.Height; y++)
5393 mem = (DWORD *)((BYTE *)l.pBits + y * l.Pitch);
5394 for (x = 0; x < l.Pitch / sizeof(DWORD); x++)
5396 mem[x] = color;
5399 hr = IDirect3DSurface8_UnlockRect(surface);
5400 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
5403 static void add_dirty_rect_test_draw(IDirect3DDevice8 *device)
5405 HRESULT hr;
5406 static const struct
5408 struct vec3 position;
5409 struct vec2 texcoord;
5411 quad[] =
5413 {{-1.0f, -1.0f, 0.0f}, {0.0f, 0.0f}},
5414 {{-1.0f, 1.0f, 0.0f}, {0.0f, 1.0f}},
5415 {{ 1.0f, -1.0f, 0.0f}, {1.0f, 0.0f}},
5416 {{ 1.0f, 1.0f, 0.0f}, {1.0f, 1.0f}},
5419 hr = IDirect3DDevice8_BeginScene(device);
5420 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5421 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad, sizeof(*quad));
5422 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5423 hr = IDirect3DDevice8_EndScene(device);
5424 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5427 static void add_dirty_rect_test(void)
5429 IDirect3DTexture8 *tex_dst1, *tex_dst2, *tex_src_red, *tex_src_green,
5430 *tex_managed, *tex_dynamic;
5431 IDirect3DSurface8 *surface_dst2, *surface_src_green, *surface_src_red,
5432 *surface_managed0, *surface_managed1, *surface_dynamic;
5433 D3DLOCKED_RECT locked_rect;
5434 IDirect3DDevice8 *device;
5435 IDirect3D8 *d3d;
5436 unsigned int i;
5437 D3DCOLOR color;
5438 ULONG refcount;
5439 DWORD *texel;
5440 HWND window;
5441 HRESULT hr;
5443 static const RECT part_rect = {96, 96, 160, 160};
5444 static const RECT oob_rect[] =
5446 { 0, 0, 200, 300},
5447 { 0, 0, 300, 200},
5448 {100, 100, 10, 10},
5449 {200, 300, 10, 10},
5450 {300, 200, 310, 210},
5451 { 0, 0, 0, 0},
5454 window = create_window();
5455 d3d = Direct3DCreate8(D3D_SDK_VERSION);
5456 ok(!!d3d, "Failed to create a D3D object.\n");
5457 if (!(device = create_device(d3d, window, window, TRUE)))
5459 skip("Failed to create a D3D device, skipping tests.\n");
5460 goto done;
5463 hr = IDirect3DDevice8_CreateTexture(device, 256, 256, 1, 0, D3DFMT_X8R8G8B8,
5464 D3DPOOL_DEFAULT, &tex_dst1);
5465 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
5466 hr = IDirect3DDevice8_CreateTexture(device, 256, 256, 1, 0, D3DFMT_X8R8G8B8,
5467 D3DPOOL_DEFAULT, &tex_dst2);
5468 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
5469 hr = IDirect3DDevice8_CreateTexture(device, 256, 256, 1, 0, D3DFMT_X8R8G8B8,
5470 D3DPOOL_SYSTEMMEM, &tex_src_red);
5471 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
5472 hr = IDirect3DDevice8_CreateTexture(device, 256, 256, 1, 0, D3DFMT_X8R8G8B8,
5473 D3DPOOL_SYSTEMMEM, &tex_src_green);
5474 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
5475 hr = IDirect3DDevice8_CreateTexture(device, 256, 256, 2, 0, D3DFMT_X8R8G8B8,
5476 D3DPOOL_MANAGED, &tex_managed);
5477 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
5478 hr = IDirect3DDevice8_CreateTexture(device, 256, 256, 1, D3DUSAGE_DYNAMIC,
5479 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &tex_dynamic);
5480 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
5482 hr = IDirect3DTexture8_GetSurfaceLevel(tex_dst2, 0, &surface_dst2);
5483 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
5484 hr = IDirect3DTexture8_GetSurfaceLevel(tex_src_green, 0, &surface_src_green);
5485 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
5486 hr = IDirect3DTexture8_GetSurfaceLevel(tex_src_red, 0, &surface_src_red);
5487 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
5488 hr = IDirect3DTexture8_GetSurfaceLevel(tex_managed, 0, &surface_managed0);
5489 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
5490 hr = IDirect3DTexture8_GetSurfaceLevel(tex_managed, 1, &surface_managed1);
5491 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
5492 hr = IDirect3DTexture8_GetSurfaceLevel(tex_dynamic, 0, &surface_dynamic);
5493 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
5495 fill_surface(surface_src_red, 0x00ff0000, 0);
5496 fill_surface(surface_src_green, 0x0000ff00, 0);
5498 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX1);
5499 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr);
5500 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
5501 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
5502 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
5503 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
5504 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MIPFILTER, D3DTEXF_POINT);
5505 ok(SUCCEEDED(hr), "Failed to set mip filter, hr %#x.\n", hr);
5507 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_green,
5508 (IDirect3DBaseTexture8 *)tex_dst1);
5509 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
5511 /* The second UpdateTexture call writing to tex_dst2 is ignored because tex_src_green is not dirty. */
5512 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_red,
5513 (IDirect3DBaseTexture8 *)tex_dst2);
5514 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
5515 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_green,
5516 (IDirect3DBaseTexture8 *)tex_dst2);
5517 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
5519 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)tex_dst1);
5520 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
5521 add_dirty_rect_test_draw(device);
5522 color = getPixelColor(device, 320, 240);
5523 ok(color_match(color, 0x0000ff00, 1),
5524 "Expected color 0x0000ff00, got 0x%08x.\n", color);
5525 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5526 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5528 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)tex_dst2);
5529 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
5530 add_dirty_rect_test_draw(device);
5531 color = getPixelColor(device, 320, 240);
5532 todo_wine ok(color_match(color, 0x00ff0000, 1),
5533 "Expected color 0x00ff0000, got 0x%08x.\n", color);
5534 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5535 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5537 /* AddDirtyRect on the destination is ignored. */
5538 hr = IDirect3DTexture8_AddDirtyRect(tex_dst2, &part_rect);
5539 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
5540 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_green,
5541 (IDirect3DBaseTexture8 *)tex_dst2);
5542 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
5543 add_dirty_rect_test_draw(device);
5544 color = getPixelColor(device, 320, 240);
5545 todo_wine ok(color_match(color, 0x00ff0000, 1),
5546 "Expected color 0x00ff0000, got 0x%08x.\n", color);
5547 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5548 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5550 hr = IDirect3DTexture8_AddDirtyRect(tex_dst2, NULL);
5551 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
5552 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_green,
5553 (IDirect3DBaseTexture8 *)tex_dst2);
5554 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
5555 add_dirty_rect_test_draw(device);
5556 color = getPixelColor(device, 320, 240);
5557 todo_wine ok(color_match(color, 0x00ff0000, 1),
5558 "Expected color 0x00ff0000, got 0x%08x.\n", color);
5559 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5560 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5562 /* AddDirtyRect on the source makes UpdateTexture work. Partial rectangle
5563 * tracking is supported. */
5564 hr = IDirect3DTexture8_AddDirtyRect(tex_src_green, &part_rect);
5565 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
5566 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_green,
5567 (IDirect3DBaseTexture8 *)tex_dst2);
5568 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
5569 add_dirty_rect_test_draw(device);
5570 color = getPixelColor(device, 320, 240);
5571 ok(color_match(color, 0x0000ff00, 1),
5572 "Expected color 0x0000ff00, got 0x%08x.\n", color);
5573 color = getPixelColor(device, 1, 1);
5574 todo_wine ok(color_match(color, 0x00ff0000, 1),
5575 "Expected color 0x00ff0000, got 0x%08x.\n", color);
5576 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5577 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5579 hr = IDirect3DTexture8_AddDirtyRect(tex_src_green, NULL);
5580 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
5581 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_green,
5582 (IDirect3DBaseTexture8 *)tex_dst2);
5583 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
5584 add_dirty_rect_test_draw(device);
5585 color = getPixelColor(device, 1, 1);
5586 ok(color_match(color, 0x0000ff00, 1),
5587 "Expected color 0x0000ff00, got 0x%08x.\n", color);
5589 /* Locks with NO_DIRTY_UPDATE are ignored. */
5590 fill_surface(surface_src_green, 0x00000080, D3DLOCK_NO_DIRTY_UPDATE);
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 todo_wine ok(color_match(color, 0x0000ff00, 1),
5597 "Expected color 0x0000ff00, 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 /* Readonly maps write to D3DPOOL_SYSTEMMEM, but don't record a dirty rectangle. */
5602 fill_surface(surface_src_green, 0x000000ff, D3DLOCK_READONLY);
5603 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_green,
5604 (IDirect3DBaseTexture8 *)tex_dst2);
5605 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
5606 add_dirty_rect_test_draw(device);
5607 color = getPixelColor(device, 320, 240);
5608 todo_wine ok(color_match(color, 0x0000ff00, 1),
5609 "Expected color 0x0000ff00, got 0x%08x.\n", color);
5610 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5611 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5613 hr = IDirect3DTexture8_AddDirtyRect(tex_src_green, NULL);
5614 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_green,
5615 (IDirect3DBaseTexture8 *)tex_dst2);
5616 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
5617 add_dirty_rect_test_draw(device);
5618 color = getPixelColor(device, 320, 240);
5619 ok(color_match(color, 0x000000ff, 1),
5620 "Expected color 0x000000ff, got 0x%08x.\n", color);
5621 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5622 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5624 /* Maps without either of these flags record a dirty rectangle. */
5625 fill_surface(surface_src_green, 0x00ffffff, 0);
5626 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_green,
5627 (IDirect3DBaseTexture8 *)tex_dst2);
5628 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
5629 add_dirty_rect_test_draw(device);
5630 color = getPixelColor(device, 320, 240);
5631 ok(color_match(color, 0x00ffffff, 1),
5632 "Expected color 0x00ffffff, got 0x%08x.\n", color);
5633 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5634 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5636 /* Partial LockRect works just like a partial AddDirtyRect call. */
5637 hr = IDirect3DTexture8_LockRect(tex_src_green, 0, &locked_rect, &part_rect, 0);
5638 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
5639 texel = locked_rect.pBits;
5640 for (i = 0; i < 64; i++)
5641 texel[i] = 0x00ff00ff;
5642 for (i = 1; i < 64; i++)
5643 memcpy((BYTE *)locked_rect.pBits + i * locked_rect.Pitch, locked_rect.pBits, locked_rect.Pitch);
5644 hr = IDirect3DTexture8_UnlockRect(tex_src_green, 0);
5645 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
5646 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_green,
5647 (IDirect3DBaseTexture8 *)tex_dst2);
5648 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
5649 add_dirty_rect_test_draw(device);
5650 color = getPixelColor(device, 320, 240);
5651 ok(color_match(color, 0x00ff00ff, 1),
5652 "Expected color 0x00ff00ff, got 0x%08x.\n", color);
5653 color = getPixelColor(device, 1, 1);
5654 ok(color_match(color, 0x00ffffff, 1),
5655 "Expected color 0x00ffffff, got 0x%08x.\n", color);
5656 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5657 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5659 fill_surface(surface_src_red, 0x00ff0000, 0);
5660 fill_surface(surface_src_green, 0x0000ff00, 0);
5662 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_green,
5663 (IDirect3DBaseTexture8 *)tex_dst1);
5664 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
5665 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)tex_dst1);
5666 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
5667 add_dirty_rect_test_draw(device);
5668 color = getPixelColor(device, 320, 240);
5669 ok(color_match(color, 0x0000ff00, 1),
5670 "Expected color 0x0000ff00, got 0x%08x.\n", color);
5671 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5672 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5674 /* UpdateSurface ignores the missing dirty marker. */
5675 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_red,
5676 (IDirect3DBaseTexture8 *)tex_dst2);
5677 hr = IDirect3DDevice8_CopyRects(device, surface_src_green, NULL, 0, surface_dst2, NULL);
5678 ok(SUCCEEDED(hr), "Failed to update surface, hr %#x.\n", hr);
5679 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)tex_dst2);
5680 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
5681 add_dirty_rect_test_draw(device);
5682 color = getPixelColor(device, 320, 240);
5683 ok(color_match(color, 0x0000ff00, 1),
5684 "Expected color 0x0000ff00, got 0x%08x.\n", color);
5685 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5686 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5688 /* Tests with managed textures. */
5689 fill_surface(surface_managed0, 0x00ff0000, 0);
5690 fill_surface(surface_managed1, 0x00ff0000, 0);
5691 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)tex_managed);
5692 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
5693 add_dirty_rect_test_draw(device);
5694 color = getPixelColor(device, 320, 240);
5695 ok(color_match(color, 0x00ff0000, 1),
5696 "Expected color 0x00ff0000, got 0x%08x.\n", color);
5697 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5698 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5699 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MAXMIPLEVEL, 1);
5700 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
5701 add_dirty_rect_test_draw(device);
5702 color = getPixelColor(device, 320, 240);
5703 ok(color_match(color, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color);
5704 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5705 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5707 /* Managed textures also honor D3DLOCK_NO_DIRTY_UPDATE. */
5708 fill_surface(surface_managed0, 0x0000ff00, D3DLOCK_NO_DIRTY_UPDATE);
5709 fill_surface(surface_managed1, 0x000000ff, D3DLOCK_NO_DIRTY_UPDATE);
5710 add_dirty_rect_test_draw(device);
5711 color = getPixelColor(device, 320, 240);
5712 ok(color_match(color, 0x00ff0000, 1),
5713 "Expected color 0x00ff0000, got 0x%08x.\n", color);
5714 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5715 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5716 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MAXMIPLEVEL, 0);
5717 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
5718 add_dirty_rect_test_draw(device);
5719 color = getPixelColor(device, 320, 240);
5720 ok(color_match(color, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color);
5721 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5722 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5724 /* AddDirtyRect uploads the new contents.
5725 * Side note, not tested in the test: Partial surface updates work, and two separate
5726 * dirty rectangles are tracked individually. Tested on Nvidia Kepler, other drivers
5727 * untested. */
5728 hr = IDirect3DTexture8_AddDirtyRect(tex_managed, NULL);
5729 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
5730 add_dirty_rect_test_draw(device);
5731 color = getPixelColor(device, 320, 240);
5732 ok(color_match(color, 0x0000ff00, 1),
5733 "Expected color 0x0000ff00, got 0x%08x.\n", color);
5734 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5735 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5736 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MAXMIPLEVEL, 1);
5737 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
5738 add_dirty_rect_test_draw(device);
5739 color = getPixelColor(device, 320, 240);
5740 ok(color_match(color, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color);
5741 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5742 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5744 /* So does ResourceManagerDiscardBytes. */
5745 fill_surface(surface_managed0, 0x00ffff00, D3DLOCK_NO_DIRTY_UPDATE);
5746 fill_surface(surface_managed1, 0x00ff00ff, D3DLOCK_NO_DIRTY_UPDATE);
5747 hr = IDirect3DDevice8_ResourceManagerDiscardBytes(device, 0);
5748 ok(SUCCEEDED(hr), "Failed to evict managed resources, hr %#x.\n", hr);
5749 add_dirty_rect_test_draw(device);
5750 color = getPixelColor(device, 320, 240);
5751 ok(color_match(color, 0x00ff00ff, 1), "Got unexpected color 0x%08x.\n", color);
5752 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5753 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5754 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MAXMIPLEVEL, 0);
5755 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
5756 add_dirty_rect_test_draw(device);
5757 color = getPixelColor(device, 320, 240);
5758 ok(color_match(color, 0x00ffff00, 1), "Got unexpected color 0x%08x.\n", color);
5759 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5760 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5762 /* Tests with dynamic textures */
5763 fill_surface(surface_dynamic, 0x0000ffff, 0);
5764 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)tex_dynamic);
5765 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
5766 add_dirty_rect_test_draw(device);
5767 color = getPixelColor(device, 320, 240);
5768 ok(color_match(color, 0x0000ffff, 1),
5769 "Expected color 0x0000ffff, got 0x%08x.\n", color);
5770 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5771 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5773 /* Dynamic textures don't honor D3DLOCK_NO_DIRTY_UPDATE. */
5774 fill_surface(surface_dynamic, 0x00ffff00, D3DLOCK_NO_DIRTY_UPDATE);
5775 add_dirty_rect_test_draw(device);
5776 color = getPixelColor(device, 320, 240);
5777 ok(color_match(color, 0x00ffff00, 1),
5778 "Expected color 0x00ffff00, got 0x%08x.\n", color);
5779 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5780 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5782 /* AddDirtyRect on a locked texture is allowed. */
5783 hr = IDirect3DTexture8_LockRect(tex_src_red, 0, &locked_rect, NULL, 0);
5784 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
5785 hr = IDirect3DTexture8_AddDirtyRect(tex_src_red, NULL);
5786 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
5787 hr = IDirect3DTexture8_UnlockRect(tex_src_red, 0);
5788 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
5790 /* Redundant AddDirtyRect calls are ok. */
5791 hr = IDirect3DTexture8_AddDirtyRect(tex_managed, NULL);
5792 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
5793 hr = IDirect3DTexture8_AddDirtyRect(tex_managed, NULL);
5794 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
5796 /* Test out-of-bounds regions. */
5797 for (i = 0; i < ARRAY_SIZE(oob_rect); ++i)
5799 hr = IDirect3DTexture8_AddDirtyRect(tex_src_red, &oob_rect[i]);
5800 todo_wine ok(hr == D3DERR_INVALIDCALL, "[%u] Got unexpected hr %#x.\n", i, hr);
5801 hr = IDirect3DTexture8_LockRect(tex_src_red, 0, &locked_rect, &oob_rect[i], 0);
5802 ok(SUCCEEDED(hr), "[%u] Got unexpected hr %#x.\n", i, hr);
5803 hr = IDirect3DTexture8_UnlockRect(tex_src_red, 0);
5804 ok(SUCCEEDED(hr), "[%u] Got unexpected hr %#x.\n", i, hr);
5807 IDirect3DSurface8_Release(surface_dst2);
5808 IDirect3DSurface8_Release(surface_managed1);
5809 IDirect3DSurface8_Release(surface_managed0);
5810 IDirect3DSurface8_Release(surface_src_red);
5811 IDirect3DSurface8_Release(surface_src_green);
5812 IDirect3DSurface8_Release(surface_dynamic);
5813 IDirect3DTexture8_Release(tex_src_red);
5814 IDirect3DTexture8_Release(tex_src_green);
5815 IDirect3DTexture8_Release(tex_dst1);
5816 IDirect3DTexture8_Release(tex_dst2);
5817 IDirect3DTexture8_Release(tex_managed);
5818 IDirect3DTexture8_Release(tex_dynamic);
5819 refcount = IDirect3DDevice8_Release(device);
5820 ok(!refcount, "Device has %u references left.\n", refcount);
5821 done:
5822 IDirect3D8_Release(d3d);
5823 DestroyWindow(window);
5826 static void test_3dc_formats(void)
5828 static const char ati1n_data[] =
5830 /* A 4x4 texture with the color component at 50%. */
5831 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5833 static const char ati2n_data[] =
5835 /* A 8x4 texture consisting of 2 4x4 blocks. The first block has 50% first color component,
5836 * 0% second component. Second block is the opposite. */
5837 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5838 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5840 static const struct
5842 struct vec3 position;
5843 struct vec2 texcoord;
5845 quads[] =
5847 {{-1.0f, -1.0f, 0.0f}, {0.0f, 0.0f}},
5848 {{-1.0f, 1.0f, 0.0f}, {0.0f, 1.0f}},
5849 {{ 0.0f, -1.0f, 1.0f}, {1.0f, 0.0f}},
5850 {{ 0.0f, 1.0f, 1.0f}, {1.0f, 1.0f}},
5852 {{ 0.0f, -1.0f, 0.0f}, {0.0f, 0.0f}},
5853 {{ 0.0f, 1.0f, 0.0f}, {0.0f, 1.0f}},
5854 {{ 1.0f, -1.0f, 1.0f}, {1.0f, 0.0f}},
5855 {{ 1.0f, 1.0f, 1.0f}, {1.0f, 1.0f}},
5857 static const DWORD ati1n_fourcc = MAKEFOURCC('A','T','I','1');
5858 static const DWORD ati2n_fourcc = MAKEFOURCC('A','T','I','2');
5859 static const struct
5861 struct vec2 position;
5862 D3DCOLOR amd_r500;
5863 D3DCOLOR amd_r600;
5864 D3DCOLOR nvidia_old;
5865 D3DCOLOR nvidia_new;
5867 expected_colors[] =
5869 {{ 80, 240}, 0x007fffff, 0x003f3f3f, 0x007f7f7f, 0x007f0000},
5870 {{240, 240}, 0x007fffff, 0x003f3f3f, 0x007f7f7f, 0x007f0000},
5871 {{400, 240}, 0x00007fff, 0x00007fff, 0x00007fff, 0x00007fff},
5872 {{560, 240}, 0x007f00ff, 0x007f00ff, 0x007f00ff, 0x007f00ff},
5874 IDirect3D8 *d3d;
5875 IDirect3DDevice8 *device;
5876 IDirect3DTexture8 *ati1n_texture, *ati2n_texture;
5877 D3DCAPS8 caps;
5878 D3DLOCKED_RECT rect;
5879 D3DCOLOR color;
5880 ULONG refcount;
5881 HWND window;
5882 HRESULT hr;
5883 unsigned int i;
5885 window = create_window();
5886 d3d = Direct3DCreate8(D3D_SDK_VERSION);
5887 ok(!!d3d, "Failed to create a D3D object.\n");
5888 if (FAILED(IDirect3D8_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
5889 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, ati1n_fourcc)))
5891 skip("ATI1N textures are not supported, skipping test.\n");
5892 goto done;
5894 if (FAILED(IDirect3D8_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
5895 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, ati2n_fourcc)))
5897 skip("ATI2N textures are not supported, skipping test.\n");
5898 goto done;
5900 if (!(device = create_device(d3d, window, window, TRUE)))
5902 skip("Failed to create a D3D device, skipping tests.\n");
5903 goto done;
5905 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
5906 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
5907 if (!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP))
5909 skip("D3DTA_TEMP not supported, skipping tests.\n");
5910 IDirect3DDevice8_Release(device);
5911 goto done;
5914 hr = IDirect3DDevice8_CreateTexture(device, 4, 4, 1, 0, ati1n_fourcc,
5915 D3DPOOL_MANAGED, &ati1n_texture);
5916 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
5918 hr = IDirect3DTexture8_LockRect(ati1n_texture, 0, &rect, NULL, 0);
5919 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
5920 memcpy(rect.pBits, ati1n_data, sizeof(ati1n_data));
5921 hr = IDirect3DTexture8_UnlockRect(ati1n_texture, 0);
5922 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
5924 hr = IDirect3DDevice8_CreateTexture(device, 8, 4, 1, 0, ati2n_fourcc,
5925 D3DPOOL_MANAGED, &ati2n_texture);
5926 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
5928 hr = IDirect3DTexture8_LockRect(ati2n_texture, 0, &rect, NULL, 0);
5929 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
5930 memcpy(rect.pBits, ati2n_data, sizeof(ati2n_data));
5931 hr = IDirect3DTexture8_UnlockRect(ati2n_texture, 0);
5932 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
5934 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE2(0));
5935 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
5936 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BLENDTEXTUREALPHA);
5937 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
5938 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
5939 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
5940 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TEMP);
5941 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
5942 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
5943 ok(SUCCEEDED(hr), "Failed to set alpha op, hr %#x.\n", hr);
5944 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
5945 ok(SUCCEEDED(hr), "Failed to set alpha arg, hr %#x.\n", hr);
5946 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
5947 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
5948 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MAGFILTER, D3DTEXF_POINT);
5949 ok(SUCCEEDED(hr), "Failed to set mag filter, hr %#x.\n", hr);
5951 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff00ff, 1.0f, 0);
5952 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
5953 hr = IDirect3DDevice8_BeginScene(device);
5954 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5955 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)ati1n_texture);
5956 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
5957 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads));
5958 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5959 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)ati2n_texture);
5960 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
5961 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[4], sizeof(*quads));
5962 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5963 hr = IDirect3DDevice8_EndScene(device);
5964 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5966 for (i = 0; i < 4; ++i)
5968 color = getPixelColor(device, expected_colors[i].position.x, expected_colors[i].position.y);
5969 ok (color_match(color, expected_colors[i].amd_r500, 1)
5970 || color_match(color, expected_colors[i].amd_r600, 1)
5971 || color_match(color, expected_colors[i].nvidia_old, 1)
5972 || color_match(color, expected_colors[i].nvidia_new, 1),
5973 "Got unexpected color 0x%08x, case %u.\n", color, i);
5976 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5977 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5978 IDirect3DTexture8_Release(ati2n_texture);
5979 IDirect3DTexture8_Release(ati1n_texture);
5980 refcount = IDirect3DDevice8_Release(device);
5981 ok(!refcount, "Device has %u references left.\n", refcount);
5983 done:
5984 IDirect3D8_Release(d3d);
5985 DestroyWindow(window);
5988 static void test_fog_interpolation(void)
5990 HRESULT hr;
5991 IDirect3DDevice8 *device;
5992 IDirect3D8 *d3d;
5993 ULONG refcount;
5994 HWND window;
5995 D3DCOLOR color;
5996 static const struct
5998 struct vec3 position;
5999 D3DCOLOR diffuse;
6000 D3DCOLOR specular;
6002 quad[] =
6004 {{-1.0f, -1.0f, 0.0f}, 0xffff0000, 0xff000000},
6005 {{-1.0f, 1.0f, 0.0f}, 0xffff0000, 0xff000000},
6006 {{ 1.0f, -1.0f, 1.0f}, 0xffff0000, 0x00000000},
6007 {{ 1.0f, 1.0f, 1.0f}, 0xffff0000, 0x00000000},
6009 union
6011 DWORD d;
6012 float f;
6013 } conv;
6014 unsigned int i;
6015 static const struct
6017 D3DFOGMODE vfog, tfog;
6018 D3DSHADEMODE shade;
6019 D3DCOLOR middle_color;
6020 BOOL todo;
6022 tests[] =
6024 {D3DFOG_NONE, D3DFOG_NONE, D3DSHADE_FLAT, 0x00007f80, FALSE},
6025 {D3DFOG_NONE, D3DFOG_NONE, D3DSHADE_GOURAUD, 0x00007f80, FALSE},
6026 {D3DFOG_EXP, D3DFOG_NONE, D3DSHADE_FLAT, 0x00007f80, TRUE},
6027 {D3DFOG_EXP, D3DFOG_NONE, D3DSHADE_GOURAUD, 0x00007f80, TRUE},
6028 {D3DFOG_NONE, D3DFOG_EXP, D3DSHADE_FLAT, 0x0000ea15, FALSE},
6029 {D3DFOG_NONE, D3DFOG_EXP, D3DSHADE_GOURAUD, 0x0000ea15, FALSE},
6030 {D3DFOG_EXP, D3DFOG_EXP, D3DSHADE_FLAT, 0x0000ea15, FALSE},
6031 {D3DFOG_EXP, D3DFOG_EXP, D3DSHADE_GOURAUD, 0x0000ea15, FALSE},
6033 static const D3DMATRIX ident_mat =
6035 1.0f, 0.0f, 0.0f, 0.0f,
6036 0.0f, 1.0f, 0.0f, 0.0f,
6037 0.0f, 0.0f, 1.0f, 0.0f,
6038 0.0f, 0.0f, 0.0f, 1.0f
6039 }}};
6040 D3DCAPS8 caps;
6042 window = create_window();
6043 d3d = Direct3DCreate8(D3D_SDK_VERSION);
6044 ok(!!d3d, "Failed to create a D3D object.\n");
6046 if (!(device = create_device(d3d, window, window, TRUE)))
6048 skip("Failed to create a D3D device, skipping tests.\n");
6049 IDirect3D8_Release(d3d);
6050 DestroyWindow(window);
6051 return;
6054 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
6055 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
6056 if (!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE))
6057 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping some fog tests\n");
6059 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
6060 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr);
6061 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6062 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6063 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, FALSE);
6064 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6065 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
6066 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6067 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGCOLOR, 0x0000ff00);
6068 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6069 conv.f = 5.0;
6070 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGDENSITY, conv.d);
6071 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6073 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
6074 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
6075 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TFACTOR);
6076 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
6077 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x000000ff);
6078 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6080 /* Some of the tests seem to depend on the projection matrix explicitly
6081 * being set to an identity matrix, even though that's the default.
6082 * (AMD Radeon X1600, AMD Radeon HD 6310, Windows 7). Without this,
6083 * the drivers seem to use a static z = 1.0 input for the fog equation.
6084 * The input value is independent of the actual z and w component of
6085 * the vertex position. */
6086 hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, &ident_mat);
6087 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
6089 for (i = 0; i < ARRAY_SIZE(tests); i++)
6091 if(!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE) && tests[i].tfog)
6092 continue;
6094 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00808080, 0.0f, 0);
6095 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
6097 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SHADEMODE, tests[i].shade);
6098 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6099 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGVERTEXMODE, tests[i].vfog);
6100 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6101 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGTABLEMODE, tests[i].tfog);
6102 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6103 hr = IDirect3DDevice8_BeginScene(device);
6104 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6105 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
6106 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6107 hr = IDirect3DDevice8_EndScene(device);
6108 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6110 color = getPixelColor(device, 0, 240);
6111 ok(color_match(color, 0x000000ff, 2), "Got unexpected color 0x%08x, case %u.\n", color, i);
6112 color = getPixelColor(device, 320, 240);
6113 todo_wine_if (tests[i].todo)
6114 ok(color_match(color, tests[i].middle_color, 2),
6115 "Got unexpected color 0x%08x, case %u.\n", color, i);
6116 color = getPixelColor(device, 639, 240);
6117 ok(color_match(color, 0x0000fd02, 2), "Got unexpected color 0x%08x, case %u.\n", color, i);
6118 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
6119 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
6122 refcount = IDirect3DDevice8_Release(device);
6123 ok(!refcount, "Device has %u references left.\n", refcount);
6124 IDirect3D8_Release(d3d);
6125 DestroyWindow(window);
6128 static void test_negative_fixedfunction_fog(void)
6130 HRESULT hr;
6131 IDirect3DDevice8 *device;
6132 IDirect3D8 *d3d;
6133 ULONG refcount;
6134 HWND window;
6135 D3DCOLOR color;
6136 static const struct
6138 struct vec3 position;
6139 D3DCOLOR diffuse;
6141 quad[] =
6143 {{-1.0f, -1.0f, -0.5f}, 0xffff0000},
6144 {{-1.0f, 1.0f, -0.5f}, 0xffff0000},
6145 {{ 1.0f, -1.0f, -0.5f}, 0xffff0000},
6146 {{ 1.0f, 1.0f, -0.5f}, 0xffff0000},
6148 static const struct
6150 struct vec4 position;
6151 D3DCOLOR diffuse;
6153 tquad[] =
6155 {{ 0.0f, 0.0f, -0.5f, 1.0f}, 0xffff0000},
6156 {{640.0f, 0.0f, -0.5f, 1.0f}, 0xffff0000},
6157 {{ 0.0f, 480.0f, -0.5f, 1.0f}, 0xffff0000},
6158 {{640.0f, 480.0f, -0.5f, 1.0f}, 0xffff0000},
6160 unsigned int i;
6161 static const D3DMATRIX zero =
6163 1.0f, 0.0f, 0.0f, 0.0f,
6164 0.0f, 1.0f, 0.0f, 0.0f,
6165 0.0f, 0.0f, 0.0f, 0.0f,
6166 0.0f, 0.0f, 0.0f, 1.0f
6167 }}};
6168 /* Needed to make AMD drivers happy. Yeah, it is not supposed to
6169 * have an effect on RHW draws. */
6170 static const D3DMATRIX identity =
6172 1.0f, 0.0f, 0.0f, 0.0f,
6173 0.0f, 1.0f, 0.0f, 0.0f,
6174 0.0f, 0.0f, 1.0f, 0.0f,
6175 0.0f, 0.0f, 0.0f, 1.0f
6176 }}};
6177 static const struct
6179 DWORD pos_type;
6180 const void *quad;
6181 size_t stride;
6182 const D3DMATRIX *matrix;
6183 union
6185 float f;
6186 DWORD d;
6187 } start, end;
6188 D3DFOGMODE vfog, tfog;
6189 DWORD color, color_broken, color_broken2;
6191 tests[] =
6193 /* Run the XYZRHW tests first. Depth clamping is broken after RHW draws on the testbot.
6195 * Geforce8+ GPUs on Windows abs() table fog, everything else does not. */
6196 {D3DFVF_XYZRHW, tquad, sizeof(*tquad), &identity, { 0.0f}, {1.0f},
6197 D3DFOG_NONE, D3DFOG_LINEAR, 0x00ff0000, 0x00808000, 0x00808000},
6198 /* r200 GPUs and presumably all d3d8 and older HW clamp the fog
6199 * parameters to 0.0 and 1.0 in the table fog case. */
6200 {D3DFVF_XYZRHW, tquad, sizeof(*tquad), &identity, {-1.0f}, {0.0f},
6201 D3DFOG_NONE, D3DFOG_LINEAR, 0x00808000, 0x00ff0000, 0x0000ff00},
6202 /* test_fog_interpolation shows that vertex fog evaluates the fog
6203 * equation in the vertex pipeline. Start = -1.0 && end = 0.0 shows
6204 * that the abs happens before the fog equation is evaluated.
6206 * Vertex fog abs() behavior is the same on all GPUs. */
6207 {D3DFVF_XYZ, quad, sizeof(*quad), &zero, { 0.0f}, {1.0f},
6208 D3DFOG_LINEAR, D3DFOG_NONE, 0x00808000, 0x00808000, 0x00808000},
6209 {D3DFVF_XYZ, quad, sizeof(*quad), &zero, {-1.0f}, {0.0f},
6210 D3DFOG_LINEAR, D3DFOG_NONE, 0x0000ff00, 0x0000ff00, 0x0000ff00},
6211 {D3DFVF_XYZ, quad, sizeof(*quad), &zero, { 0.0f}, {1.0f},
6212 D3DFOG_EXP, D3DFOG_NONE, 0x009b6400, 0x009b6400, 0x009b6400},
6214 D3DCAPS8 caps;
6216 window = create_window();
6217 d3d = Direct3DCreate8(D3D_SDK_VERSION);
6218 ok(!!d3d, "Failed to create a D3D object.\n");
6220 if (!(device = create_device(d3d, window, window, TRUE)))
6222 skip("Failed to create a D3D device, skipping tests.\n");
6223 IDirect3D8_Release(d3d);
6224 DestroyWindow(window);
6225 return;
6228 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
6229 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
6230 if (!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE))
6231 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping some fog tests.\n");
6233 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6234 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6235 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
6236 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6237 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
6238 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6239 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGCOLOR, 0x0000ff00);
6240 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6241 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, FALSE);
6242 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
6244 for (i = 0; i < ARRAY_SIZE(tests); i++)
6246 if (!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE) && tests[i].tfog)
6247 continue;
6249 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x000000ff, 0.0f, 0);
6250 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
6252 hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, tests[i].matrix);
6253 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
6254 hr = IDirect3DDevice8_SetVertexShader(device, tests[i].pos_type | D3DFVF_DIFFUSE);
6255 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr);
6256 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGSTART, tests[i].start.d);
6257 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6258 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGEND, tests[i].end.d);
6259 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6260 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGVERTEXMODE, tests[i].vfog);
6261 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6262 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGTABLEMODE, tests[i].tfog);
6263 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6265 hr = IDirect3DDevice8_BeginScene(device);
6266 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6267 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, tests[i].quad, tests[i].stride);
6268 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6269 hr = IDirect3DDevice8_EndScene(device);
6270 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6272 color = getPixelColor(device, 320, 240);
6273 ok(color_match(color, tests[i].color, 2) || broken(color_match(color, tests[i].color_broken, 2))
6274 || broken(color_match(color, tests[i].color_broken2, 2)),
6275 "Got unexpected color 0x%08x, case %u.\n", color, i);
6276 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
6277 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
6280 refcount = IDirect3DDevice8_Release(device);
6281 ok(!refcount, "Device has %u references left.\n", refcount);
6282 IDirect3D8_Release(d3d);
6283 DestroyWindow(window);
6286 static void test_table_fog_zw(void)
6288 HRESULT hr;
6289 IDirect3DDevice8 *device;
6290 IDirect3D8 *d3d;
6291 ULONG refcount;
6292 HWND window;
6293 D3DCOLOR color;
6294 D3DCAPS8 caps;
6295 static struct
6297 struct vec4 position;
6298 D3DCOLOR diffuse;
6300 quad[] =
6302 {{ 0.0f, 0.0f, 0.0f, 0.0f}, 0xffff0000},
6303 {{640.0f, 0.0f, 0.0f, 0.0f}, 0xffff0000},
6304 {{ 0.0f, 480.0f, 0.0f, 0.0f}, 0xffff0000},
6305 {{640.0f, 480.0f, 0.0f, 0.0f}, 0xffff0000},
6307 static const D3DMATRIX identity =
6309 1.0f, 0.0f, 0.0f, 0.0f,
6310 0.0f, 1.0f, 0.0f, 0.0f,
6311 0.0f, 0.0f, 1.0f, 0.0f,
6312 0.0f, 0.0f, 0.0f, 1.0f
6313 }}};
6314 static const struct
6316 float z, w;
6317 D3DZBUFFERTYPE z_test;
6318 D3DCOLOR color;
6320 tests[] =
6322 {0.7f, 0.0f, D3DZB_TRUE, 0x004cb200},
6323 {0.7f, 0.0f, D3DZB_FALSE, 0x004cb200},
6324 {0.7f, 0.3f, D3DZB_TRUE, 0x004cb200},
6325 {0.7f, 0.3f, D3DZB_FALSE, 0x004cb200},
6326 {0.7f, 3.0f, D3DZB_TRUE, 0x004cb200},
6327 {0.7f, 3.0f, D3DZB_FALSE, 0x004cb200},
6328 {0.3f, 0.0f, D3DZB_TRUE, 0x00b24c00},
6329 {0.3f, 0.0f, D3DZB_FALSE, 0x00b24c00},
6331 unsigned int i;
6333 window = create_window();
6334 d3d = Direct3DCreate8(D3D_SDK_VERSION);
6335 ok(!!d3d, "Failed to create a D3D object.\n");
6337 if (!(device = create_device(d3d, window, window, TRUE)))
6339 skip("Failed to create a D3D device, skipping tests.\n");
6340 IDirect3D8_Release(d3d);
6341 DestroyWindow(window);
6342 return;
6345 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
6346 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
6347 if (!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE))
6349 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping POSITIONT table fog test.\n");
6350 goto done;
6353 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6354 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6355 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
6356 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6357 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGCOLOR, 0x0000ff00);
6358 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6359 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, FALSE);
6360 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
6361 /* Work around an AMD Windows driver bug. Needs a proj matrix applied redundantly. */
6362 hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, &identity);
6363 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
6364 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
6365 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6366 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
6367 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr);
6369 for (i = 0; i < ARRAY_SIZE(tests); ++i)
6371 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
6372 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
6374 quad[0].position.z = tests[i].z;
6375 quad[1].position.z = tests[i].z;
6376 quad[2].position.z = tests[i].z;
6377 quad[3].position.z = tests[i].z;
6378 quad[0].position.w = tests[i].w;
6379 quad[1].position.w = tests[i].w;
6380 quad[2].position.w = tests[i].w;
6381 quad[3].position.w = tests[i].w;
6382 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, tests[i].z_test);
6383 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6385 hr = IDirect3DDevice8_BeginScene(device);
6386 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6387 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
6388 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6389 hr = IDirect3DDevice8_EndScene(device);
6390 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6392 color = getPixelColor(device, 320, 240);
6393 ok(color_match(color, tests[i].color, 2),
6394 "Got unexpected color 0x%08x, expected 0x%08x, case %u.\n", color, tests[i].color, i);
6395 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
6396 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
6399 done:
6400 refcount = IDirect3DDevice8_Release(device);
6401 ok(!refcount, "Device has %u references left.\n", refcount);
6402 IDirect3D8_Release(d3d);
6403 DestroyWindow(window);
6406 static void test_signed_formats(void)
6408 IDirect3DDevice8 *device;
6409 HWND window;
6410 HRESULT hr;
6411 unsigned int i, j, x, y;
6412 IDirect3DTexture8 *texture, *texture_sysmem;
6413 D3DLOCKED_RECT locked_rect;
6414 DWORD shader, shader_alpha;
6415 IDirect3D8 *d3d;
6416 D3DCOLOR color;
6417 D3DCAPS8 caps;
6418 ULONG refcount;
6420 /* See comments in the d3d9 version of this test for an
6421 * explanation of these values. */
6422 static const USHORT content_v8u8[4][4] =
6424 {0x0000, 0x7f7f, 0x8880, 0x0000},
6425 {0x0080, 0x8000, 0x7f00, 0x007f},
6426 {0x193b, 0xe8c8, 0x0808, 0xf8f8},
6427 {0x4444, 0xc0c0, 0xa066, 0x22e0},
6429 static const DWORD content_v16u16[4][4] =
6431 {0x00000000, 0x7fff7fff, 0x88008000, 0x00000000},
6432 {0x00008000, 0x80000000, 0x7fff0000, 0x00007fff},
6433 {0x19993bbb, 0xe800c800, 0x08880888, 0xf800f800},
6434 {0x44444444, 0xc000c000, 0xa0006666, 0x2222e000},
6436 static const DWORD content_q8w8v8u8[4][4] =
6438 {0x00000000, 0xff7f7f7f, 0x7f008880, 0x817f0000},
6439 {0x10000080, 0x20008000, 0x30007f00, 0x4000007f},
6440 {0x5020193b, 0x6028e8c8, 0x70020808, 0x807ff8f8},
6441 {0x90414444, 0xa000c0c0, 0x8261a066, 0x834922e0},
6443 static const DWORD content_x8l8v8u8[4][4] =
6445 {0x00000000, 0x00ff7f7f, 0x00008880, 0x00ff0000},
6446 {0x00000080, 0x00008000, 0x00007f00, 0x0000007f},
6447 {0x0041193b, 0x0051e8c8, 0x00040808, 0x00fff8f8},
6448 {0x00824444, 0x0000c0c0, 0x00c2a066, 0x009222e0},
6450 static const USHORT content_l6v5u5[4][4] =
6452 {0x0000, 0xfdef, 0x0230, 0xfc00},
6453 {0x0010, 0x0200, 0x01e0, 0x000f},
6454 {0x4067, 0x53b9, 0x0421, 0xffff},
6455 {0x8108, 0x0318, 0xc28c, 0x909c},
6457 static const struct
6459 D3DFORMAT format;
6460 const char *name;
6461 const void *content;
6462 SIZE_T pixel_size;
6463 BOOL blue, alpha;
6464 unsigned int slop, slop_broken, alpha_broken;
6466 formats[] =
6468 {D3DFMT_V8U8, "D3DFMT_V8U8", content_v8u8, sizeof(WORD), FALSE, FALSE, 1, 0, FALSE},
6469 {D3DFMT_V16U16, "D3DFMT_V16U16", content_v16u16, sizeof(DWORD), FALSE, FALSE, 1, 0, FALSE},
6470 {D3DFMT_Q8W8V8U8, "D3DFMT_Q8W8V8U8", content_q8w8v8u8, sizeof(DWORD), TRUE, TRUE, 1, 0, TRUE },
6471 {D3DFMT_X8L8V8U8, "D3DFMT_X8L8V8U8", content_x8l8v8u8, sizeof(DWORD), TRUE, FALSE, 1, 0, FALSE},
6472 {D3DFMT_L6V5U5, "D3DFMT_L6V5U5", content_l6v5u5, sizeof(WORD), TRUE, FALSE, 4, 7, FALSE},
6474 static const struct
6476 D3DPOOL pool;
6477 UINT width;
6479 tests[] =
6481 {D3DPOOL_SYSTEMMEM, 4},
6482 {D3DPOOL_SYSTEMMEM, 1},
6483 {D3DPOOL_MANAGED, 4},
6484 {D3DPOOL_MANAGED, 1},
6486 static const DWORD shader_code[] =
6488 0xffff0101, /* ps_1_1 */
6489 0x00000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, /* def c0, 0.5, 0.5, 0,5, 0,5 */
6490 0x00000042, 0xb00f0000, /* tex t0 */
6491 0x00000004, 0x800f0000, 0xb0e40000, 0xa0e40000, 0xa0e40000, /* mad r0, t0, c0, c0 */
6492 0x0000ffff /* end */
6494 static const DWORD shader_code_alpha[] =
6496 /* The idea of this shader is to replicate the alpha value in .rg, and set
6497 * blue to 1.0 iff the alpha value is < -1.0 and 0.0 otherwise. */
6498 0xffff0101, /* ps_1_1 */
6499 0x00000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, /* def c0, 0.5, 0.5, 0.5, 0.5 */
6500 0x00000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0 */
6501 0x00000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c2, 0.0, 0.0, 1.0, 0.0 */
6502 0x00000042, 0xb00f0000, /* tex t0 */
6503 0x00000004, 0x80070000, 0xb0ff0000, 0xa0e40000, 0xa0e40000, /* mad r0.rgb, t0.a, c0, c0 */
6504 0x00000003, 0x80080000, 0xb1ff0000, 0xa0e40000, /* sub r0.a, -t0.a, c0 */
6505 0x00000050, 0x80080000, 0x80ff0000, 0xa0ff0001, 0xa0ff0002, /* cnd r0.a, r0.a, c1.a, c2.a */
6506 0x00000005, 0x80070001, 0xa0e40001, 0x80e40000, /* mul r1.rgb, c1, r0 */
6507 0x00000004, 0x80070000, 0x80ff0000, 0xa0e40002, 0x80e40001, /* mad r0.rgb, r0.a, c2, r1 */
6508 0x0000ffff /* end */
6510 static const struct
6512 struct vec3 position;
6513 struct vec2 texcrd;
6515 quad[] =
6517 /* Flip the y coordinate to make the input and
6518 * output arrays easier to compare. */
6519 {{ -1.0f, -1.0f, 0.0f}, { 0.0f, 1.0f}},
6520 {{ -1.0f, 1.0f, 0.0f}, { 0.0f, 0.0f}},
6521 {{ 1.0f, -1.0f, 0.0f}, { 1.0f, 1.0f}},
6522 {{ 1.0f, 1.0f, 0.0f}, { 1.0f, 0.0f}},
6524 static const D3DCOLOR expected_alpha[4][4] =
6526 {0x00808000, 0x007f7f00, 0x00ffff00, 0x00000000},
6527 {0x00909000, 0x00a0a000, 0x00b0b000, 0x00c0c000},
6528 {0x00d0d000, 0x00e0e000, 0x00f0f000, 0x00000000},
6529 {0x00101000, 0x00202000, 0x00010100, 0x00020200},
6531 static const BOOL alpha_broken[4][4] =
6533 {FALSE, FALSE, FALSE, FALSE},
6534 {FALSE, FALSE, FALSE, FALSE},
6535 {FALSE, FALSE, FALSE, TRUE },
6536 {FALSE, FALSE, FALSE, FALSE},
6538 static const D3DCOLOR expected_colors[4][4] =
6540 {0x00808080, 0x00fefeff, 0x00010780, 0x008080ff},
6541 {0x00018080, 0x00800180, 0x0080fe80, 0x00fe8080},
6542 {0x00ba98a0, 0x004767a8, 0x00888881, 0x007878ff},
6543 {0x00c3c3c0, 0x003f3f80, 0x00e51fe1, 0x005fa2c8},
6545 D3DCOLOR expected_color;
6547 window = create_window();
6548 d3d = Direct3DCreate8(D3D_SDK_VERSION);
6549 ok(!!d3d, "Failed to create a D3D object.\n");
6551 if (!(device = create_device(d3d, window, window, TRUE)))
6553 skip("Failed to create a D3D device, skipping tests.\n");
6554 IDirect3D8_Release(d3d);
6555 DestroyWindow(window);
6556 return;
6559 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
6560 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
6562 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 1))
6564 skip("Pixel shaders not supported, skipping converted format test.\n");
6565 goto done;
6568 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
6569 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6570 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX1);
6571 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
6572 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code, &shader);
6573 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
6574 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code_alpha, &shader_alpha);
6575 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
6577 for (i = 0; i < ARRAY_SIZE(formats); i++)
6579 hr = IDirect3D8_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
6580 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, formats[i].format);
6581 if (FAILED(hr))
6583 skip("Format %s not supported, skipping.\n", formats[i].name);
6584 continue;
6587 for (j = 0; j < ARRAY_SIZE(tests); j++)
6589 texture_sysmem = NULL;
6590 hr = IDirect3DDevice8_CreateTexture(device, tests[j].width, 4, 1, 0,
6591 formats[i].format, tests[j].pool, &texture);
6592 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
6594 hr = IDirect3DTexture8_LockRect(texture, 0, &locked_rect, NULL, 0);
6595 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
6596 for (y = 0; y < 4; y++)
6598 memcpy((char *)locked_rect.pBits + y * locked_rect.Pitch,
6599 (char *)formats[i].content + y * 4 * formats[i].pixel_size,
6600 tests[j].width * formats[i].pixel_size);
6602 hr = IDirect3DTexture8_UnlockRect(texture, 0);
6603 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
6605 if (tests[j].pool == D3DPOOL_SYSTEMMEM)
6607 texture_sysmem = texture;
6608 hr = IDirect3DDevice8_CreateTexture(device, tests[j].width, 4, 1, 0,
6609 formats[i].format, D3DPOOL_DEFAULT, &texture);
6610 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
6612 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)texture_sysmem,
6613 (IDirect3DBaseTexture8 *)texture);
6614 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
6615 IDirect3DTexture8_Release(texture_sysmem);
6618 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
6619 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
6620 hr = IDirect3DDevice8_SetPixelShader(device, shader_alpha);
6621 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6623 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00330033, 0.0f, 0);
6624 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
6625 hr = IDirect3DDevice8_BeginScene(device);
6626 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6627 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(*quad));
6628 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6629 hr = IDirect3DDevice8_EndScene(device);
6630 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6632 for (y = 0; y < 4; y++)
6634 for (x = 0; x < tests[j].width; x++)
6636 BOOL r200_broken = formats[i].alpha_broken && alpha_broken[y][x];
6637 if (formats[i].alpha)
6638 expected_color = expected_alpha[y][x];
6639 else
6640 expected_color = 0x00ffff00;
6642 color = getPixelColor(device, 80 + 160 * x, 60 + 120 * y);
6643 ok(color_match(color, expected_color, 1) || broken(r200_broken),
6644 "Expected color 0x%08x, got 0x%08x, format %s, test %u, location %ux%u.\n",
6645 expected_color, color, formats[i].name, j, x, y);
6648 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
6649 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
6651 hr = IDirect3DDevice8_SetPixelShader(device, shader);
6652 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6654 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00330033, 0.0f, 0);
6655 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
6656 hr = IDirect3DDevice8_BeginScene(device);
6657 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6658 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(*quad));
6659 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6660 hr = IDirect3DDevice8_EndScene(device);
6661 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6663 for (y = 0; y < 4; y++)
6665 for (x = 0; x < tests[j].width; x++)
6667 expected_color = expected_colors[y][x];
6668 if (!formats[i].blue)
6669 expected_color |= 0x000000ff;
6671 color = getPixelColor(device, 80 + 160 * x, 60 + 120 * y);
6672 ok(color_match(color, expected_color, formats[i].slop)
6673 || broken(color_match(color, expected_color, formats[i].slop_broken)),
6674 "Expected color 0x%08x, got 0x%08x, format %s, test %u, location %ux%u.\n",
6675 expected_color, color, formats[i].name, j, x, y);
6678 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
6679 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
6681 IDirect3DTexture8_Release(texture);
6685 IDirect3DDevice8_DeletePixelShader(device, shader);
6686 IDirect3DDevice8_DeletePixelShader(device, shader_alpha);
6688 done:
6689 refcount = IDirect3DDevice8_Release(device);
6690 ok(!refcount, "Device has %u references left.\n", refcount);
6691 IDirect3D8_Release(d3d);
6692 DestroyWindow(window);
6695 static void test_updatetexture(void)
6697 IDirect3DDevice8 *device;
6698 IDirect3D8 *d3d;
6699 HWND window;
6700 HRESULT hr;
6701 IDirect3DBaseTexture8 *src, *dst;
6702 unsigned int t, i, f, l, x, y, z;
6703 D3DLOCKED_RECT locked_rect;
6704 D3DLOCKED_BOX locked_box;
6705 ULONG refcount;
6706 D3DCAPS8 caps;
6707 D3DCOLOR color;
6708 BOOL ati2n_supported, do_visual_test;
6709 static const struct
6711 struct vec3 pos;
6712 struct vec2 texcoord;
6714 quad[] =
6716 {{-1.0f, -1.0f, 0.0f}, {0.0f, 1.0f}},
6717 {{-1.0f, 1.0f, 0.0f}, {0.0f, 0.0f}},
6718 {{ 1.0f, -1.0f, 0.0f}, {1.0f, 1.0f}},
6719 {{ 1.0f, 1.0f, 0.0f}, {1.0f, 0.0f}},
6721 static const struct
6723 struct vec3 pos;
6724 struct vec3 texcoord;
6726 quad_cube_tex[] =
6728 {{-1.0f, -1.0f, 0.0f}, {1.0f, -0.5f, 0.5f}},
6729 {{-1.0f, 1.0f, 0.0f}, {1.0f, 0.5f, 0.5f}},
6730 {{ 1.0f, -1.0f, 0.0f}, {1.0f, -0.5f, -0.5f}},
6731 {{ 1.0f, 1.0f, 0.0f}, {1.0f, 0.5f, -0.5f}},
6733 static const struct
6735 UINT src_width, src_height;
6736 UINT dst_width, dst_height;
6737 UINT src_levels, dst_levels;
6738 D3DFORMAT src_format, dst_format;
6739 BOOL broken;
6741 tests[] =
6743 {8, 8, 8, 8, 0, 0, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 0 */
6744 {8, 8, 8, 8, 4, 4, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 1 */
6745 {8, 8, 8, 8, 2, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 2 */
6746 {8, 8, 8, 8, 1, 1, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 3 */
6747 {8, 8, 8, 8, 4, 0, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 4 */
6748 {8, 8, 2, 2, 4, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 5 */
6749 /* The WARP renderer doesn't handle these cases correctly. */
6750 {8, 8, 8, 8, 4, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, TRUE}, /* 6 */
6751 {8, 8, 4, 4, 4, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, TRUE}, /* 7 */
6752 /* Not clear what happens here on Windows, it doesn't make much sense
6753 * though (on Nvidia it seems to upload the 4x4 surface into the 7x7
6754 * one or something like that). */
6755 /* {8, 8, 7, 7, 4, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, */
6756 {8, 8, 8, 8, 1, 4, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 8 */
6757 {4, 4, 8, 8, 1, 1, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 9 */
6758 /* This one causes weird behavior on Windows (it probably writes out
6759 * of the texture memory). */
6760 /* {8, 8, 4, 4, 1, 1, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, */
6761 {8, 4, 4, 2, 4, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 10 */
6762 {8, 4, 2, 4, 4, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 11 */
6763 {8, 8, 8, 8, 4, 4, D3DFMT_A8R8G8B8, D3DFMT_X8R8G8B8, FALSE}, /* 12 */
6764 {8, 8, 8, 8, 4, 4, D3DFMT_X8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 13 */
6765 /* The data is converted correctly on AMD, on Nvidia nothing happens
6766 * (it draws a black quad). */
6767 {8, 8, 8, 8, 4, 4, D3DFMT_A8R8G8B8, D3DFMT_R5G6B5, TRUE}, /* 14 */
6768 /* This one doesn't seem to give the expected results on AMD. */
6769 /* {8, 8, 8, 8, 4, 4, D3DFMT_A8R8G8B8, D3DFMT_Q8W8V8U8, FALSE}, */
6770 {8, 8, 8, 8, 4, 4, MAKEFOURCC('A','T','I','2'), MAKEFOURCC('A','T','I','2'), FALSE}, /* 15 */
6771 {8, 8, 8, 8, 4, 2, MAKEFOURCC('A','T','I','2'), MAKEFOURCC('A','T','I','2'), FALSE}, /* 16 */
6772 {8, 8, 2, 2, 4, 2, MAKEFOURCC('A','T','I','2'), MAKEFOURCC('A','T','I','2'), FALSE}, /* 17 */
6774 static const struct
6776 D3DRESOURCETYPE type;
6777 DWORD fvf;
6778 const void *quad;
6779 unsigned int vertex_size;
6780 DWORD cap;
6781 const char *name;
6783 texture_types[] =
6785 {D3DRTYPE_TEXTURE, D3DFVF_XYZ | D3DFVF_TEX1,
6786 quad, sizeof(*quad), D3DPTEXTURECAPS_MIPMAP, "2D mipmapped"},
6788 {D3DRTYPE_CUBETEXTURE, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE3(0),
6789 quad_cube_tex, sizeof(*quad_cube_tex), D3DPTEXTURECAPS_CUBEMAP, "Cube"},
6791 {D3DRTYPE_VOLUMETEXTURE, D3DFVF_XYZ | D3DFVF_TEX1,
6792 quad, sizeof(*quad), D3DPTEXTURECAPS_VOLUMEMAP, "Volume"}
6795 window = create_window();
6796 d3d = Direct3DCreate8(D3D_SDK_VERSION);
6797 ok(!!d3d, "Failed to create a D3D object.\n");
6798 if (!(device = create_device(d3d, window, window, TRUE)))
6800 skip("Failed to create a D3D device, skipping tests.\n");
6801 IDirect3D8_Release(d3d);
6802 DestroyWindow(window);
6803 return;
6806 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
6807 ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
6809 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR);
6810 ok(SUCCEEDED(hr), "Failed to set texture filtering state, hr %#x.\n", hr);
6811 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP);
6812 ok(SUCCEEDED(hr), "Failed to set texture filtering state, hr %#x.\n", hr);
6813 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP);
6814 ok(SUCCEEDED(hr), "Failed to set texture filtering state, hr %#x.\n", hr);
6815 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_ADDRESSW, D3DTADDRESS_CLAMP);
6816 ok(SUCCEEDED(hr), "Failed to set texture filtering state, hr %#x.\n", hr);
6817 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6818 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6819 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
6820 ok(hr == D3D_OK, "Failed to set texture stage state, hr %#x.\n", hr);
6821 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
6822 ok(hr == D3D_OK, "Failed to set texture stage state, hr %#x.\n", hr);
6824 for (t = 0; t < ARRAY_SIZE(texture_types); ++t)
6826 if (!(caps.TextureCaps & texture_types[t].cap))
6828 skip("%s textures not supported, skipping some tests.\n", texture_types[t].name);
6829 continue;
6832 if (FAILED(IDirect3D8_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
6833 D3DFMT_X8R8G8B8, 0, texture_types[t].type, MAKEFOURCC('A','T','I','2'))))
6835 skip("%s ATI2N textures are not supported, skipping some tests.\n", texture_types[t].name);
6836 ati2n_supported = FALSE;
6838 else
6840 ati2n_supported = TRUE;
6843 hr = IDirect3DDevice8_SetVertexShader(device, texture_types[t].fvf);
6844 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
6846 for (i = 0; i < ARRAY_SIZE(tests); ++i)
6848 if (tests[i].src_format == MAKEFOURCC('A','T','I','2') && !ati2n_supported)
6849 continue;
6851 switch (texture_types[t].type)
6853 case D3DRTYPE_TEXTURE:
6854 hr = IDirect3DDevice8_CreateTexture(device,
6855 tests[i].src_width, tests[i].src_height,
6856 tests[i].src_levels, 0, tests[i].src_format, D3DPOOL_SYSTEMMEM,
6857 (IDirect3DTexture8 **)&src);
6858 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x, case %u, %u.\n", hr, t, i);
6859 hr = IDirect3DDevice8_CreateTexture(device,
6860 tests[i].dst_width, tests[i].dst_height,
6861 tests[i].dst_levels, 0, tests[i].dst_format, D3DPOOL_DEFAULT,
6862 (IDirect3DTexture8 **)&dst);
6863 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x, case %u, %u.\n", hr, t, i);
6864 break;
6865 case D3DRTYPE_CUBETEXTURE:
6866 hr = IDirect3DDevice8_CreateCubeTexture(device,
6867 tests[i].src_width,
6868 tests[i].src_levels, 0, tests[i].src_format, D3DPOOL_SYSTEMMEM,
6869 (IDirect3DCubeTexture8 **)&src);
6870 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x, case %u, %u.\n", hr, t, i);
6871 hr = IDirect3DDevice8_CreateCubeTexture(device,
6872 tests[i].dst_width,
6873 tests[i].dst_levels, 0, tests[i].dst_format, D3DPOOL_DEFAULT,
6874 (IDirect3DCubeTexture8 **)&dst);
6875 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x, case %u, %u.\n", hr, t, i);
6876 break;
6877 case D3DRTYPE_VOLUMETEXTURE:
6878 hr = IDirect3DDevice8_CreateVolumeTexture(device,
6879 tests[i].src_width, tests[i].src_height, tests[i].src_width,
6880 tests[i].src_levels, 0, tests[i].src_format, D3DPOOL_SYSTEMMEM,
6881 (IDirect3DVolumeTexture8 **)&src);
6882 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x, case %u, %u.\n", hr, t, i);
6883 hr = IDirect3DDevice8_CreateVolumeTexture(device,
6884 tests[i].dst_width, tests[i].dst_height, tests[i].dst_width,
6885 tests[i].dst_levels, 0, tests[i].dst_format, D3DPOOL_DEFAULT,
6886 (IDirect3DVolumeTexture8 **)&dst);
6887 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x, case %u, %u.\n", hr, t, i);
6888 break;
6889 default:
6890 trace("Unexpected resource type.\n");
6893 /* Skip the visual part of the test for ATI2N (laziness) and cases that
6894 * give a different (and unlikely to be useful) result. */
6895 do_visual_test = (tests[i].src_format == D3DFMT_A8R8G8B8 || tests[i].src_format == D3DFMT_X8R8G8B8)
6896 && tests[i].src_levels != 0
6897 && tests[i].src_width >= tests[i].dst_width && tests[i].src_height >= tests[i].dst_height
6898 && !(tests[i].src_width > tests[i].src_height && tests[i].dst_width < tests[i].dst_height);
6900 if (do_visual_test)
6902 DWORD *ptr = NULL;
6903 unsigned int width, height, depth, row_pitch = 0, slice_pitch = 0;
6905 for (f = 0; f < (texture_types[t].type == D3DRTYPE_CUBETEXTURE ? 6 : 1); ++f)
6907 width = tests[i].src_width;
6908 height = texture_types[t].type != D3DRTYPE_CUBETEXTURE ? tests[i].src_height : tests[i].src_width;
6909 depth = texture_types[t].type == D3DRTYPE_VOLUMETEXTURE ? width : 1;
6911 for (l = 0; l < tests[i].src_levels; ++l)
6913 switch (texture_types[t].type)
6915 case D3DRTYPE_TEXTURE:
6916 hr = IDirect3DTexture8_LockRect((IDirect3DTexture8 *)src,
6917 l, &locked_rect, NULL, 0);
6918 ptr = locked_rect.pBits;
6919 row_pitch = locked_rect.Pitch / sizeof(*ptr);
6920 break;
6921 case D3DRTYPE_CUBETEXTURE:
6922 hr = IDirect3DCubeTexture8_LockRect((IDirect3DCubeTexture8 *)src,
6923 f, l, &locked_rect, NULL, 0);
6924 ptr = locked_rect.pBits;
6925 row_pitch = locked_rect.Pitch / sizeof(*ptr);
6926 break;
6927 case D3DRTYPE_VOLUMETEXTURE:
6928 hr = IDirect3DVolumeTexture8_LockBox((IDirect3DVolumeTexture8 *)src,
6929 l, &locked_box, NULL, 0);
6930 ptr = locked_box.pBits;
6931 row_pitch = locked_box.RowPitch / sizeof(*ptr);
6932 slice_pitch = locked_box.SlicePitch / sizeof(*ptr);
6933 break;
6934 default:
6935 trace("Unexpected resource type.\n");
6937 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
6939 for (z = 0; z < depth; ++z)
6941 for (y = 0; y < height; ++y)
6943 for (x = 0; x < width; ++x)
6945 ptr[z * slice_pitch + y * row_pitch + x] = 0xff000000
6946 | (DWORD)(x / (width - 1.0f) * 255.0f) << 16
6947 | (DWORD)(y / (height - 1.0f) * 255.0f) << 8;
6952 switch (texture_types[t].type)
6954 case D3DRTYPE_TEXTURE:
6955 hr = IDirect3DTexture8_UnlockRect((IDirect3DTexture8 *)src, l);
6956 break;
6957 case D3DRTYPE_CUBETEXTURE:
6958 hr = IDirect3DCubeTexture8_UnlockRect((IDirect3DCubeTexture8 *)src, f, l);
6959 break;
6960 case D3DRTYPE_VOLUMETEXTURE:
6961 hr = IDirect3DVolumeTexture8_UnlockBox((IDirect3DVolumeTexture8 *)src, l);
6962 break;
6963 default:
6964 trace("Unexpected resource type.\n");
6966 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
6968 width >>= 1;
6969 if (!width)
6970 width = 1;
6971 height >>= 1;
6972 if (!height)
6973 height = 1;
6974 depth >>= 1;
6975 if (!depth)
6976 depth = 1;
6981 hr = IDirect3DDevice8_UpdateTexture(device, src, dst);
6982 if (FAILED(hr))
6984 todo_wine ok(SUCCEEDED(hr), "Failed to update texture, hr %#x, case %u, %u.\n", hr, t, i);
6985 IDirect3DBaseTexture8_Release(src);
6986 IDirect3DBaseTexture8_Release(dst);
6987 continue;
6989 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x, case %u, %u.\n", hr, t, i);
6991 if (do_visual_test)
6993 hr = IDirect3DDevice8_SetTexture(device, 0, dst);
6994 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
6996 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 1.0f, 0);
6997 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
6999 hr = IDirect3DDevice8_BeginScene(device);
7000 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7001 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,
7002 texture_types[t].quad, texture_types[t].vertex_size);
7003 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7004 hr = IDirect3DDevice8_EndScene(device);
7005 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7007 color = getPixelColor(device, 320, 240);
7008 ok (color_match(color, 0x007f7f00, 3) || broken(tests[i].broken)
7009 || broken(color == 0x00adbeef), /* WARP device often just breaks down. */
7010 "Got unexpected color 0x%08x, case %u, %u.\n", color, t, i);
7013 IDirect3DBaseTexture8_Release(src);
7014 IDirect3DBaseTexture8_Release(dst);
7018 refcount = IDirect3DDevice8_Release(device);
7019 ok(!refcount, "Device has %u references left.\n", refcount);
7020 IDirect3D8_Release(d3d);
7021 DestroyWindow(window);
7024 static BOOL point_match(IDirect3DDevice8 *device, UINT x, UINT y, UINT r)
7026 D3DCOLOR color;
7028 color = D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff);
7029 if (!color_match(getPixelColor(device, x + r, y), color, 1))
7030 return FALSE;
7031 if (!color_match(getPixelColor(device, x - r, y), color, 1))
7032 return FALSE;
7033 if (!color_match(getPixelColor(device, x, y + r), color, 1))
7034 return FALSE;
7035 if (!color_match(getPixelColor(device, x, y - r), color, 1))
7036 return FALSE;
7038 ++r;
7039 color = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff);
7040 if (!color_match(getPixelColor(device, x + r, y), color, 1))
7041 return FALSE;
7042 if (!color_match(getPixelColor(device, x - r, y), color, 1))
7043 return FALSE;
7044 if (!color_match(getPixelColor(device, x, y + r), color, 1))
7045 return FALSE;
7046 if (!color_match(getPixelColor(device, x, y - r), color, 1))
7047 return FALSE;
7049 return TRUE;
7052 static void test_pointsize(void)
7054 static const float a = 0.5f, b = 0.5f, c = 0.5f;
7055 float ptsize, ptsizemax_orig, ptsizemin_orig;
7056 IDirect3DSurface8 *rt, *backbuffer, *depthstencil;
7057 IDirect3DTexture8 *tex1, *tex2;
7058 IDirect3DDevice8 *device;
7059 DWORD vs, ps;
7060 D3DLOCKED_RECT lr;
7061 IDirect3D8 *d3d;
7062 D3DCOLOR color;
7063 ULONG refcount;
7064 D3DCAPS8 caps;
7065 HWND window;
7066 HRESULT hr;
7067 unsigned int i, j;
7069 static const DWORD tex1_data[4] = {0x00ff0000, 0x00ff0000, 0x00000000, 0x00000000};
7070 static const DWORD tex2_data[4] = {0x00000000, 0x0000ff00, 0x00000000, 0x0000ff00};
7071 static const float vertices[] =
7073 64.0f, 64.0f, 0.1f,
7074 128.0f, 64.0f, 0.1f,
7075 192.0f, 64.0f, 0.1f,
7076 256.0f, 64.0f, 0.1f,
7077 320.0f, 64.0f, 0.1f,
7078 384.0f, 64.0f, 0.1f,
7079 448.0f, 64.0f, 0.1f,
7080 512.0f, 64.0f, 0.1f,
7082 static const struct
7084 float x, y, z;
7085 float point_size;
7087 vertex_pointsize = {64.0f, 64.0f, 0.1f, 48.0f},
7088 vertex_pointsize_scaled = {64.0f, 64.0f, 0.1f, 24.0f},
7089 vertex_pointsize_zero = {64.0f, 64.0f, 0.1f, 0.0f};
7090 static const DWORD decl[] =
7092 D3DVSD_STREAM(0),
7093 D3DVSD_REG(0, D3DVSDT_FLOAT3), /* position */
7094 D3DVSD_END()
7096 decl_psize[] =
7098 D3DVSD_STREAM(0),
7099 D3DVSD_REG(0, D3DVSDT_FLOAT3), /* position, v0 */
7100 D3DVSD_REG(1, D3DVSDT_FLOAT1), /* point size, v1 */
7101 D3DVSD_END()
7103 static const DWORD vshader_code[] =
7105 0xfffe0101, /* vs_1_1 */
7106 0x00000005, 0x800f0000, 0x90000000, 0xa0e40000, /* mul r0, v0.x, c0 */
7107 0x00000004, 0x800f0000, 0x90550000, 0xa0e40001, 0x80e40000, /* mad r0, v0.y, c1, r0 */
7108 0x00000004, 0x800f0000, 0x90aa0000, 0xa0e40002, 0x80e40000, /* mad r0, v0.z, c2, r0 */
7109 0x00000004, 0xc00f0000, 0x90ff0000, 0xa0e40003, 0x80e40000, /* mad oPos, v0.w, c3, r0 */
7110 0x0000ffff
7112 static const DWORD vshader_psize_code[] =
7114 0xfffe0101, /* vs_1_1 */
7115 0x00000005, 0x800f0000, 0x90000000, 0xa0e40000, /* mul r0, v0.x, c0 */
7116 0x00000004, 0x800f0000, 0x90550000, 0xa0e40001, 0x80e40000, /* mad r0, v0.y, c1, r0 */
7117 0x00000004, 0x800f0000, 0x90aa0000, 0xa0e40002, 0x80e40000, /* mad r0, v0.z, c2, r0 */
7118 0x00000004, 0xc00f0000, 0x90ff0000, 0xa0e40003, 0x80e40000, /* mad oPos, v0.w, c3, r0 */
7119 0x00000001, 0xc00f0002, 0x90000001, /* mov oPts, v1.x */
7120 0x0000ffff
7122 static const DWORD pshader_code[] =
7124 0xffff0101, /* ps_1_1 */
7125 0x00000042, 0xb00f0000, /* tex t0 */
7126 0x00000042, 0xb00f0001, /* tex t1 */
7127 0x00000002, 0x800f0000, 0xb0e40000, 0xb0e40001, /* add r0, t0, t1 */
7128 0x0000ffff
7130 static const struct test_shader
7132 DWORD version;
7133 const DWORD *code;
7135 novs = {0, NULL},
7136 vs1 = {D3DVS_VERSION(1, 1), vshader_code},
7137 vs1_psize = {D3DVS_VERSION(1, 1), vshader_psize_code},
7138 nops = {0, NULL},
7139 ps1 = {D3DPS_VERSION(1, 1), pshader_code};
7140 static const struct
7142 const DWORD *decl;
7143 const struct test_shader *vs;
7144 const struct test_shader *ps;
7145 DWORD accepted_fvf;
7146 unsigned int nonscaled_size, scaled_size;
7148 test_setups[] =
7150 {NULL, &novs, &nops, D3DFVF_XYZ, 32, 62},
7151 {decl, &vs1, &ps1, D3DFVF_XYZ, 32, 32},
7152 {NULL, &novs, &ps1, D3DFVF_XYZ, 32, 62},
7153 {decl, &vs1, &nops, D3DFVF_XYZ, 32, 32},
7154 {NULL, &novs, &nops, D3DFVF_XYZ | D3DFVF_PSIZE, 48, 48},
7155 {decl_psize, &vs1_psize, &ps1, D3DFVF_XYZ | D3DFVF_PSIZE, 48, 24},
7157 static const struct
7159 BOOL zero_size;
7160 BOOL scale;
7161 BOOL override_min;
7162 DWORD fvf;
7163 const void *vertex_data;
7164 unsigned int vertex_size;
7166 tests[] =
7168 {FALSE, FALSE, FALSE, D3DFVF_XYZ, vertices, sizeof(float) * 3},
7169 {FALSE, TRUE, FALSE, D3DFVF_XYZ, vertices, sizeof(float) * 3},
7170 {FALSE, FALSE, TRUE, D3DFVF_XYZ, vertices, sizeof(float) * 3},
7171 {TRUE, FALSE, FALSE, D3DFVF_XYZ, vertices, sizeof(float) * 3},
7172 {FALSE, FALSE, FALSE, D3DFVF_XYZ | D3DFVF_PSIZE, &vertex_pointsize, sizeof(vertex_pointsize)},
7173 {FALSE, TRUE, FALSE, D3DFVF_XYZ | D3DFVF_PSIZE, &vertex_pointsize_scaled, sizeof(vertex_pointsize_scaled)},
7174 {FALSE, FALSE, TRUE, D3DFVF_XYZ | D3DFVF_PSIZE, &vertex_pointsize, sizeof(vertex_pointsize)},
7175 {TRUE, FALSE, FALSE, D3DFVF_XYZ | D3DFVF_PSIZE, &vertex_pointsize_zero, sizeof(vertex_pointsize_zero)},
7177 /* Transforms the coordinate system [-1.0;1.0]x[1.0;-1.0] to
7178 * [0.0;0.0]x[640.0;480.0]. Z is untouched. */
7179 D3DMATRIX matrix =
7181 2.0f / 640.0f, 0.0f, 0.0f, 0.0f,
7182 0.0f, -2.0f / 480.0f, 0.0f, 0.0f,
7183 0.0f, 0.0f, 1.0f, 0.0f,
7184 -1.0f, 1.0f, 0.0f, 1.0f,
7185 }}};
7187 window = create_window();
7188 d3d = Direct3DCreate8(D3D_SDK_VERSION);
7189 ok(!!d3d, "Failed to create a D3D object.\n");
7190 if (!(device = create_device(d3d, window, window, TRUE)))
7192 skip("Failed to create a D3D device, skipping tests.\n");
7193 goto done;
7196 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
7197 ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
7198 if (caps.MaxPointSize < 32.0f)
7200 skip("MaxPointSize %f < 32.0, skipping.\n", caps.MaxPointSize);
7201 IDirect3DDevice8_Release(device);
7202 goto done;
7205 /* The r500 Windows driver needs a draw with regular texture coordinates at least once during the
7206 * device's lifetime, otherwise texture coordinate generation only works for texture 0. */
7207 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX1);
7208 ok(SUCCEEDED(hr), "Failed to set FVF, hr=%#x.\n", hr);
7209 hr = IDirect3DDevice8_BeginScene(device);
7210 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7211 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, vertices, sizeof(float) * 5);
7212 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7213 hr = IDirect3DDevice8_EndScene(device);
7214 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7216 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
7217 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
7218 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
7219 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
7220 hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, &matrix);
7221 ok(SUCCEEDED(hr), "Failed to set projection matrix, hr %#x.\n", hr);
7222 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ);
7223 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
7225 hr = IDirect3DDevice8_BeginScene(device);
7226 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7228 ptsize = 15.0f;
7229 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
7230 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
7231 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
7232 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7234 ptsize = 31.0f;
7235 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
7236 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
7237 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[3], sizeof(float) * 3);
7238 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7240 ptsize = 30.75f;
7241 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
7242 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
7243 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[6], sizeof(float) * 3);
7244 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7246 if (caps.MaxPointSize >= 63.0f)
7248 ptsize = 63.0f;
7249 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
7250 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
7251 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[9], sizeof(float) * 3);
7252 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7254 ptsize = 62.75f;
7255 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
7256 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
7257 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[15], sizeof(float) * 3);
7258 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7261 ptsize = 1.0f;
7262 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
7263 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
7264 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[12], sizeof(float) * 3);
7265 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7267 hr = IDirect3DDevice8_GetRenderState(device, D3DRS_POINTSIZE_MAX, (DWORD *)&ptsizemax_orig);
7268 ok(SUCCEEDED(hr), "Failed to get render state, hr %#x.\n", hr);
7269 hr = IDirect3DDevice8_GetRenderState(device, D3DRS_POINTSIZE_MIN, (DWORD *)&ptsizemin_orig);
7270 ok(SUCCEEDED(hr), "Failed to get render state, hr %#x.\n", hr);
7272 /* What happens if point scaling is disabled, and POINTSIZE_MAX < POINTSIZE? */
7273 ptsize = 15.0f;
7274 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
7275 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
7276 ptsize = 1.0f;
7277 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE_MAX, *(DWORD *)&ptsize);
7278 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
7279 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[18], sizeof(float) * 3);
7280 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7282 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE_MAX, *(DWORD *)&ptsizemax_orig);
7283 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
7285 /* pointsize < pointsize_min < pointsize_max?
7286 * pointsize = 1.0, pointsize_min = 15.0, pointsize_max = default(usually 64.0) */
7287 ptsize = 1.0f;
7288 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
7289 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
7290 ptsize = 15.0f;
7291 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE_MIN, *(DWORD *)&ptsize);
7292 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
7293 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[21], sizeof(float) * 3);
7294 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7296 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE_MIN, *(DWORD *)&ptsizemin_orig);
7297 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
7299 hr = IDirect3DDevice8_EndScene(device);
7300 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7302 ok(point_match(device, 64, 64, 7), "point_match(64, 64, 7) failed, expected point size 15.\n");
7303 ok(point_match(device, 128, 64, 15), "point_match(128, 64, 15) failed, expected point size 31.\n");
7304 ok(point_match(device, 192, 64, 15), "point_match(192, 64, 15) failed, expected point size 31.\n");
7306 if (caps.MaxPointSize >= 63.0f)
7308 ok(point_match(device, 256, 64, 31), "point_match(256, 64, 31) failed, expected point size 63.\n");
7309 ok(point_match(device, 384, 64, 31), "point_match(384, 64, 31) failed, expected point size 63.\n");
7312 ok(point_match(device, 320, 64, 0), "point_match(320, 64, 0) failed, expected point size 1.\n");
7313 /* ptsize = 15, ptsize_max = 1 --> point has size 1 */
7314 ok(point_match(device, 448, 64, 0), "point_match(448, 64, 0) failed, expected point size 1.\n");
7315 /* ptsize = 1, ptsize_max = default(64), ptsize_min = 15 --> point has size 15 */
7316 ok(point_match(device, 512, 64, 7), "point_match(512, 64, 7) failed, expected point size 15.\n");
7318 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
7320 /* The following code tests point sprites with two textures, to see if each texture coordinate unit
7321 * generates texture coordinates for the point(result: Yes, it does)
7323 * However, not all GL implementations support point sprites(they need GL_ARB_point_sprite), but there
7324 * is no point sprite cap bit in d3d because native d3d software emulates point sprites. Until the
7325 * SW emulation is implemented in wined3d, this test will fail on GL drivers that does not support them.
7327 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
7328 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
7330 hr = IDirect3DDevice8_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex1);
7331 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
7332 hr = IDirect3DDevice8_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex2);
7333 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
7334 memset(&lr, 0, sizeof(lr));
7335 hr = IDirect3DTexture8_LockRect(tex1, 0, &lr, NULL, 0);
7336 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
7337 memcpy(lr.pBits, tex1_data, sizeof(tex1_data));
7338 hr = IDirect3DTexture8_UnlockRect(tex1, 0);
7339 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
7340 memset(&lr, 0, sizeof(lr));
7341 hr = IDirect3DTexture8_LockRect(tex2, 0, &lr, NULL, 0);
7342 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
7343 memcpy(lr.pBits, tex2_data, sizeof(tex2_data));
7344 hr = IDirect3DTexture8_UnlockRect(tex2, 0);
7345 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
7346 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)tex1);
7347 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
7348 hr = IDirect3DDevice8_SetTexture(device, 1, (IDirect3DBaseTexture8 *)tex2);
7349 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
7350 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7351 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
7352 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7353 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
7354 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
7355 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
7356 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7357 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
7358 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
7359 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
7361 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSPRITEENABLE, TRUE);
7362 ok(SUCCEEDED(hr), "Failed to enable point sprites, hr %#x.\n", hr);
7363 ptsize = 32.0f;
7364 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
7365 ok(SUCCEEDED(hr), "Failed to set point size, hr %#x.\n", hr);
7367 hr = IDirect3DDevice8_BeginScene(device);
7368 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7369 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
7370 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7371 hr = IDirect3DDevice8_EndScene(device);
7372 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7374 color = getPixelColor(device, 64 - 4, 64 - 4);
7375 ok(color == 0x00ff0000, "pSprite: Pixel (64 - 4),(64 - 4) has color 0x%08x, expected 0x00ff0000\n", color);
7376 color = getPixelColor(device, 64 - 4, 64 + 4);
7377 ok(color == 0x00000000, "pSprite: Pixel (64 - 4),(64 + 4) has color 0x%08x, expected 0x00000000\n", color);
7378 color = getPixelColor(device, 64 + 4, 64 + 4);
7379 ok(color == 0x0000ff00, "pSprite: Pixel (64 + 4),(64 + 4) has color 0x%08x, expected 0x0000ff00\n", color);
7380 color = getPixelColor(device, 64 + 4, 64 - 4);
7381 ok(color == 0x00ffff00, "pSprite: Pixel (64 + 4),(64 - 4) has color 0x%08x, expected 0x00ffff00\n", color);
7382 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
7384 U(matrix).m[0][0] = 1.0f / 64.0f;
7385 U(matrix).m[1][1] = -1.0f / 64.0f;
7386 hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, &matrix);
7387 ok(SUCCEEDED(hr), "Failed to set projection matrix, hr %#x.\n", hr);
7389 hr = IDirect3DDevice8_GetRenderTarget(device, &backbuffer);
7390 ok(SUCCEEDED(hr), "Failed to get backbuffer, hr %#x.\n", hr);
7391 hr = IDirect3DDevice8_GetDepthStencilSurface(device, &depthstencil);
7392 ok(SUCCEEDED(hr), "Failed to get depth / stencil buffer, hr %#x.\n", hr);
7394 hr = IDirect3DDevice8_CreateRenderTarget(device, 128, 128, D3DFMT_A8R8G8B8,
7395 D3DMULTISAMPLE_NONE, TRUE, &rt);
7396 ok(SUCCEEDED(hr), "Failed to create a render target, hr %#x.\n", hr);
7398 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSCALE_A, *(DWORD *)&a);
7399 ok(SUCCEEDED(hr), "Failed setting point scale attenuation coefficient, hr %#x.\n", hr);
7400 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSCALE_B, *(DWORD *)&b);
7401 ok(SUCCEEDED(hr), "Failed setting point scale attenuation coefficient, hr %#x.\n", hr);
7402 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSCALE_C, *(DWORD *)&c);
7403 ok(SUCCEEDED(hr), "Failed setting point scale attenuation coefficient, hr %#x.\n", hr);
7404 hr = IDirect3DDevice8_SetVertexShaderConstant(device, 0, &S(U(matrix))._11, 4);
7405 ok(SUCCEEDED(hr), "Failed to set vertex shader constants, hr %#x.\n", hr);
7407 if (caps.MaxPointSize < 63.0f)
7409 skip("MaxPointSize %f < 63.0, skipping some tests.\n", caps.MaxPointSize);
7410 goto cleanup;
7413 hr = IDirect3DDevice8_SetRenderTarget(device, rt, depthstencil);
7414 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
7416 for (i = 0; i < ARRAY_SIZE(test_setups); ++i)
7418 if (caps.VertexShaderVersion < test_setups[i].vs->version
7419 || caps.PixelShaderVersion < test_setups[i].ps->version)
7421 skip("Vertex / pixel shader version not supported, skipping test.\n");
7422 continue;
7424 if (test_setups[i].vs->code)
7426 hr = IDirect3DDevice8_CreateVertexShader(device, test_setups[i].decl, test_setups[i].vs->code, &vs, 0);
7427 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x (case %u).\n", hr, i);
7429 else
7431 vs = 0;
7433 if (test_setups[i].ps->code)
7435 hr = IDirect3DDevice8_CreatePixelShader(device, test_setups[i].ps->code, &ps);
7436 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x (case %u).\n", hr, i);
7438 else
7440 ps = 0;
7443 hr = IDirect3DDevice8_SetVertexShader(device, vs ? vs : test_setups[i].accepted_fvf);
7444 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
7445 hr = IDirect3DDevice8_SetPixelShader(device, ps);
7446 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
7448 for (j = 0; j < ARRAY_SIZE(tests); ++j)
7450 unsigned int size = tests[j].override_min ? 63 : tests[j].zero_size ? 0 : tests[j].scale
7451 ? test_setups[i].scaled_size : test_setups[i].nonscaled_size;
7453 if (test_setups[i].accepted_fvf != tests[j].fvf)
7454 continue;
7456 ptsize = tests[j].zero_size ? 0.0f : 32.0f;
7457 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
7458 ok(SUCCEEDED(hr), "Failed to set pointsize, hr %#x.\n", hr);
7460 ptsize = tests[j].override_min ? 63.0f : tests[j].zero_size ? 0.0f : ptsizemin_orig;
7461 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE_MIN, *(DWORD *)&ptsize);
7462 ok(SUCCEEDED(hr), "Failed to set minimum pointsize, hr %#x.\n", hr);
7464 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSCALEENABLE, tests[j].scale);
7465 ok(SUCCEEDED(hr), "Failed setting point scale state, hr %#x.\n", hr);
7467 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
7468 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
7470 hr = IDirect3DDevice8_BeginScene(device);
7471 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7472 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1,
7473 tests[j].vertex_data, tests[j].vertex_size);
7474 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7475 hr = IDirect3DDevice8_EndScene(device);
7476 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7478 if (tests[j].zero_size)
7480 /* Technically 0 pointsize is undefined in OpenGL but in practice it seems like
7481 * it does the "useful" thing on all the drivers I tried. */
7482 /* On WARP it does draw some pixels, most of the time. */
7483 color = getPixelColor(device, 64, 64);
7484 ok(color_match(color, 0x0000ffff, 0)
7485 || broken(color_match(color, 0x00ff0000, 0))
7486 || broken(color_match(color, 0x00ffff00, 0))
7487 || broken(color_match(color, 0x00000000, 0))
7488 || broken(color_match(color, 0x0000ff00, 0)),
7489 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
7491 else
7493 struct surface_readback rb;
7495 get_rt_readback(rt, &rb);
7496 color = get_readback_color(&rb, 64 - size / 2 + 1, 64 - size / 2 + 1);
7497 ok(color_match(color, 0x00ff0000, 0),
7498 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
7499 color = get_readback_color(&rb, 64 + size / 2 - 1, 64 - size / 2 + 1);
7500 ok(color_match(color, 0x00ffff00, 0),
7501 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
7502 color = get_readback_color(&rb, 64 - size / 2 + 1, 64 + size / 2 - 1);
7503 ok(color_match(color, 0x00000000, 0),
7504 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
7505 color = get_readback_color(&rb, 64 + size / 2 - 1, 64 + size / 2 - 1);
7506 ok(color_match(color, 0x0000ff00, 0),
7507 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
7509 color = get_readback_color(&rb, 64 - size / 2 - 1, 64 - size / 2 - 1);
7510 ok(color_match(color, 0xff00ffff, 0),
7511 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
7512 color = get_readback_color(&rb, 64 + size / 2 + 1, 64 - size / 2 - 1);
7513 ok(color_match(color, 0xff00ffff, 0),
7514 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
7515 color = get_readback_color(&rb, 64 - size / 2 - 1, 64 + size / 2 + 1);
7516 ok(color_match(color, 0xff00ffff, 0),
7517 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
7518 color = get_readback_color(&rb, 64 + size / 2 + 1, 64 + size / 2 + 1);
7519 ok(color_match(color, 0xff00ffff, 0),
7520 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
7522 release_surface_readback(&rb);
7525 IDirect3DDevice8_SetVertexShader(device, 0);
7526 IDirect3DDevice8_SetPixelShader(device, 0);
7527 if (vs)
7528 IDirect3DDevice8_DeleteVertexShader(device, vs);
7529 if (ps)
7530 IDirect3DDevice8_DeletePixelShader(device, ps);
7532 hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, depthstencil);
7533 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
7535 cleanup:
7536 IDirect3DSurface8_Release(backbuffer);
7537 IDirect3DSurface8_Release(depthstencil);
7538 IDirect3DSurface8_Release(rt);
7540 IDirect3DTexture8_Release(tex1);
7541 IDirect3DTexture8_Release(tex2);
7542 refcount = IDirect3DDevice8_Release(device);
7543 ok(!refcount, "Device has %u references left.\n", refcount);
7544 done:
7545 IDirect3D8_Release(d3d);
7546 DestroyWindow(window);
7549 static void test_multisample_mismatch(void)
7551 IDirect3DDevice8 *device;
7552 IDirect3D8 *d3d;
7553 HWND window;
7554 HRESULT hr;
7555 ULONG refcount;
7556 IDirect3DSurface8 *rt_multi, *ds;
7558 window = create_window();
7559 d3d = Direct3DCreate8(D3D_SDK_VERSION);
7560 ok(!!d3d, "Failed to create a D3D object.\n");
7561 if (FAILED(IDirect3D8_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
7562 D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES)))
7564 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping multisample mismatch test.\n");
7565 IDirect3D8_Release(d3d);
7566 return;
7569 if (!(device = create_device(d3d, window, window, TRUE)))
7571 skip("Failed to create a D3D device, skipping tests.\n");
7572 goto done;
7575 hr = IDirect3DDevice8_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
7576 D3DMULTISAMPLE_2_SAMPLES, FALSE, &rt_multi);
7577 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
7578 hr = IDirect3DDevice8_GetDepthStencilSurface(device, &ds);
7579 ok(SUCCEEDED(hr), "Failed to get original depth/stencil, hr %#x.\n", hr);
7581 hr = IDirect3DDevice8_SetRenderTarget(device, rt_multi, ds);
7582 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
7584 IDirect3DSurface8_Release(ds);
7585 IDirect3DSurface8_Release(rt_multi);
7587 refcount = IDirect3DDevice8_Release(device);
7588 ok(!refcount, "Device has %u references left.\n", refcount);
7589 done:
7590 IDirect3D8_Release(d3d);
7591 DestroyWindow(window);
7594 static void test_texcoordindex(void)
7596 static const D3DMATRIX mat =
7598 1.0f, 0.0f, 0.0f, 0.0f,
7599 0.0f, 0.0f, 0.0f, 0.0f,
7600 0.0f, 0.0f, 0.0f, 0.0f,
7601 0.0f, 0.0f, 0.0f, 0.0f,
7602 }}};
7603 static const struct
7605 struct vec3 pos;
7606 struct vec2 texcoord1;
7607 struct vec2 texcoord2;
7608 struct vec2 texcoord3;
7610 quad[] =
7612 {{-1.0f, -1.0f, 0.0f}, {0.0f, 1.0f}, {0.0f, 0.0f}, {1.0f, 1.0f}},
7613 {{-1.0f, 1.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 1.0f}, {1.0f, 0.0f}},
7614 {{ 1.0f, -1.0f, 0.0f}, {1.0f, 1.0f}, {1.0f, 0.0f}, {0.0f, 1.0f}},
7615 {{ 1.0f, 1.0f, 0.0f}, {1.0f, 0.0f}, {1.0f, 1.0f}, {0.0f, 0.0f}},
7617 IDirect3DDevice8 *device;
7618 IDirect3D8 *d3d;
7619 HWND window;
7620 HRESULT hr;
7621 IDirect3DTexture8 *texture1, *texture2;
7622 D3DLOCKED_RECT locked_rect;
7623 ULONG refcount;
7624 D3DCOLOR color;
7625 DWORD *ptr;
7627 window = create_window();
7628 d3d = Direct3DCreate8(D3D_SDK_VERSION);
7629 ok(!!d3d, "Failed to create a D3D object.\n");
7630 if (!(device = create_device(d3d, window, window, TRUE)))
7632 skip("Failed to create a D3D device, skipping tests.\n");
7633 IDirect3D8_Release(d3d);
7634 DestroyWindow(window);
7635 return;
7638 hr = IDirect3DDevice8_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture1);
7639 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
7640 hr = IDirect3DDevice8_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture2);
7641 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
7643 hr = IDirect3DTexture8_LockRect(texture1, 0, &locked_rect, NULL, D3DLOCK_DISCARD);
7644 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
7645 ptr = locked_rect.pBits;
7646 ptr[0] = 0xff000000;
7647 ptr[1] = 0xff00ff00;
7648 ptr[2] = 0xff0000ff;
7649 ptr[3] = 0xff00ffff;
7650 hr = IDirect3DTexture8_UnlockRect(texture1, 0);
7651 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
7653 hr = IDirect3DTexture8_LockRect(texture2, 0, &locked_rect, NULL, D3DLOCK_DISCARD);
7654 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
7655 ptr = locked_rect.pBits;
7656 ptr[0] = 0xff000000;
7657 ptr[1] = 0xff0000ff;
7658 ptr[2] = 0xffff0000;
7659 ptr[3] = 0xffff00ff;
7660 hr = IDirect3DTexture8_UnlockRect(texture2, 0);
7661 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
7663 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture1);
7664 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
7665 hr = IDirect3DDevice8_SetTexture(device, 1, (IDirect3DBaseTexture8 *)texture2);
7666 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
7667 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX3);
7668 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
7669 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
7670 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
7671 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7672 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
7673 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7674 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
7675 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
7676 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
7677 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7678 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
7679 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
7680 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
7681 hr = IDirect3DDevice8_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
7682 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
7684 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_TEXCOORDINDEX, 1);
7685 ok(SUCCEEDED(hr), "Failed to set texcoord index, hr %#x.\n", hr);
7686 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_TEXCOORDINDEX, 0);
7687 ok(SUCCEEDED(hr), "Failed to set texcoord index, hr %#x.\n", hr);
7689 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 1.0f, 0);
7690 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
7692 hr = IDirect3DDevice8_BeginScene(device);
7693 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7694 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
7695 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7696 hr = IDirect3DDevice8_EndScene(device);
7697 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7699 color = getPixelColor(device, 160, 120);
7700 ok(color_match(color, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color);
7701 color = getPixelColor(device, 480, 120);
7702 ok(color_match(color, 0x0000ffff, 2), "Got unexpected color 0x%08x.\n", color);
7703 color = getPixelColor(device, 160, 360);
7704 ok(color_match(color, 0x00ff0000, 2), "Got unexpected color 0x%08x.\n", color);
7705 color = getPixelColor(device, 480, 360);
7706 ok(color_match(color, 0x00ffffff, 2), "Got unexpected color 0x%08x.\n", color);
7708 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
7709 ok(SUCCEEDED(hr), "Failed to set texture transform flags, hr %#x.\n", hr);
7710 hr = IDirect3DDevice8_SetTransform(device, D3DTS_TEXTURE1, &mat);
7711 ok(SUCCEEDED(hr), "Failed to set transformation matrix, hr %#x.\n", hr);
7713 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 1.0f, 0);
7714 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
7716 hr = IDirect3DDevice8_BeginScene(device);
7717 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7718 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
7719 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7720 hr = IDirect3DDevice8_EndScene(device);
7721 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7723 color = getPixelColor(device, 160, 120);
7724 ok(color_match(color, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color);
7725 color = getPixelColor(device, 480, 120);
7726 ok(color_match(color, 0x0000ffff, 2), "Got unexpected color 0x%08x.\n", color);
7727 color = getPixelColor(device, 160, 360);
7728 ok(color_match(color, 0x00000000, 2), "Got unexpected color 0x%08x.\n", color);
7729 color = getPixelColor(device, 480, 360);
7730 ok(color_match(color, 0x0000ffff, 2), "Got unexpected color 0x%08x.\n", color);
7732 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
7733 ok(SUCCEEDED(hr), "Failed to set texture transform flags, hr %#x.\n", hr);
7734 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_TEXCOORDINDEX, 2);
7735 ok(SUCCEEDED(hr), "Failed to set texcoord index, hr %#x.\n", hr);
7737 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 1.0f, 0);
7738 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
7740 hr = IDirect3DDevice8_BeginScene(device);
7741 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7742 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
7743 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7744 hr = IDirect3DDevice8_EndScene(device);
7745 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7747 color = getPixelColor(device, 160, 120);
7748 ok(color_match(color, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color);
7749 color = getPixelColor(device, 480, 120);
7750 ok(color_match(color, 0x0000ffff, 2), "Got unexpected color 0x%08x.\n", color);
7751 color = getPixelColor(device, 160, 360);
7752 ok(color_match(color, 0x00ff00ff, 2), "Got unexpected color 0x%08x.\n", color);
7753 color = getPixelColor(device, 480, 360);
7754 ok(color_match(color, 0x00ffff00, 2), "Got unexpected color 0x%08x.\n", color);
7756 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
7757 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
7759 IDirect3DTexture8_Release(texture1);
7760 IDirect3DTexture8_Release(texture2);
7762 refcount = IDirect3DDevice8_Release(device);
7763 ok(!refcount, "Device has %u references left.\n", refcount);
7764 IDirect3D8_Release(d3d);
7765 DestroyWindow(window);
7768 static void test_vshader_input(void)
7770 DWORD swapped_twotexcrd_shader, swapped_onetexcrd_shader = 0;
7771 DWORD swapped_twotex_wrongidx_shader = 0, swapped_twotexcrd_rightorder_shader;
7772 DWORD texcoord_color_shader, color_ubyte_shader, color_color_shader, color_float_shader;
7773 DWORD color_nocolor_shader = 0;
7774 IDirect3DDevice8 *device;
7775 IDirect3D8 *d3d;
7776 ULONG refcount;
7777 D3DCAPS8 caps;
7778 DWORD color;
7779 HWND window;
7780 HRESULT hr;
7782 static const DWORD swapped_shader_code[] =
7784 0xfffe0101, /* vs_1_1 */
7785 0x00000001, 0xc00f0000, 0x90e40000, /* mov o0, v0 */
7786 0x00000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
7787 0x00000002, 0xd00f0000, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
7788 0x0000ffff /* end */
7790 static const DWORD texcoord_color_shader_code[] =
7792 0xfffe0101, /* vs_1_1 */
7793 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
7794 0x00000001, 0xd00f0000, 0x90e40007, /* mov oD0, v7 */
7795 0x0000ffff /* end */
7797 static const DWORD color_color_shader_code[] =
7799 0xfffe0101, /* vs_1_1 */
7800 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
7801 0x00000005, 0xd00f0000, 0xa0e40000, 0x90e40005, /* mul oD0, c0, v5 */
7802 0x0000ffff /* end */
7804 static const float quad1[] =
7806 -1.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7807 -1.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7808 0.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7809 0.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7811 static const float quad4[] =
7813 0.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7814 0.0f, 1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7815 1.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7816 1.0f, 1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7818 static const struct
7820 struct vec3 position;
7821 DWORD diffuse;
7823 quad1_color[] =
7825 {{-1.0f, -1.0f, 0.1f}, 0x00ff8040},
7826 {{-1.0f, 0.0f, 0.1f}, 0x00ff8040},
7827 {{ 0.0f, -1.0f, 0.1f}, 0x00ff8040},
7828 {{ 0.0f, 0.0f, 0.1f}, 0x00ff8040},
7830 quad2_color[] =
7832 {{ 0.0f, -1.0f, 0.1f}, 0x00ff8040},
7833 {{ 0.0f, 0.0f, 0.1f}, 0x00ff8040},
7834 {{ 1.0f, -1.0f, 0.1f}, 0x00ff8040},
7835 {{ 1.0f, 0.0f, 0.1f}, 0x00ff8040},
7837 static const struct
7839 struct vec3 position;
7840 struct vec3 dummy; /* testing D3DVSD_SKIP */
7841 DWORD diffuse;
7843 quad3_color[] =
7845 {{-1.0f, 0.0f, 0.1f}, {0.0f}, 0x00ff8040},
7846 {{-1.0f, 1.0f, 0.1f}, {0.0f}, 0x00ff8040},
7847 {{ 0.0f, 0.0f, 0.1f}, {0.0f}, 0x00ff8040},
7848 {{ 0.0f, 1.0f, 0.1f}, {0.0f}, 0x00ff8040},
7850 static const float quad4_color[] =
7852 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 0.0f, 0.0f,
7853 0.0f, 1.0f, 0.1f, 1.0f, 1.0f, 0.0f, 0.0f,
7854 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 0.0f, 1.0f,
7855 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 0.0f, 1.0f,
7857 static const DWORD decl_twotexcrd[] =
7859 D3DVSD_STREAM(0),
7860 D3DVSD_REG(0, D3DVSDT_FLOAT3), /* position */
7861 D3DVSD_REG(1, D3DVSDT_FLOAT4), /* texcoord0 */
7862 D3DVSD_REG(2, D3DVSDT_FLOAT4), /* texcoord1 */
7863 D3DVSD_END()
7865 static const DWORD decl_twotexcrd_rightorder[] =
7867 D3DVSD_STREAM(0),
7868 D3DVSD_REG(0, D3DVSDT_FLOAT3), /* position */
7869 D3DVSD_REG(2, D3DVSDT_FLOAT4), /* texcoord0 */
7870 D3DVSD_REG(1, D3DVSDT_FLOAT4), /* texcoord1 */
7871 D3DVSD_END()
7873 static const DWORD decl_onetexcrd[] =
7875 D3DVSD_STREAM(0),
7876 D3DVSD_REG(0, D3DVSDT_FLOAT3), /* position */
7877 D3DVSD_REG(1, D3DVSDT_FLOAT4), /* texcoord0 */
7878 D3DVSD_END()
7880 static const DWORD decl_twotexcrd_wrongidx[] =
7882 D3DVSD_STREAM(0),
7883 D3DVSD_REG(0, D3DVSDT_FLOAT3), /* position */
7884 D3DVSD_REG(2, D3DVSDT_FLOAT4), /* texcoord1 */
7885 D3DVSD_REG(3, D3DVSDT_FLOAT4), /* texcoord2 */
7886 D3DVSD_END()
7888 static const DWORD decl_texcoord_color[] =
7890 D3DVSD_STREAM(0),
7891 D3DVSD_REG(0, D3DVSDT_FLOAT3), /* position */
7892 D3DVSD_REG(7, D3DVSDT_D3DCOLOR), /* texcoord0 */
7893 D3DVSD_END()
7895 static const DWORD decl_color_color[] =
7897 D3DVSD_STREAM(0),
7898 D3DVSD_REG(0, D3DVSDT_FLOAT3), /* position */
7899 D3DVSD_SKIP(3), /* not used */
7900 D3DVSD_REG(5, D3DVSDT_D3DCOLOR), /* diffuse */
7901 D3DVSD_END()
7903 static const DWORD decl_color_ubyte[] =
7905 D3DVSD_STREAM(0),
7906 D3DVSD_REG(0, D3DVSDT_FLOAT3),
7907 D3DVSD_REG(5, D3DVSDT_UBYTE4),
7908 D3DVSD_END()
7910 static const DWORD decl_color_float[] =
7912 D3DVSD_STREAM(0),
7913 D3DVSD_REG(0, D3DVSDT_FLOAT3),
7914 D3DVSD_REG(5, D3DVSDT_FLOAT4),
7915 D3DVSD_END()
7917 static const DWORD decl_nocolor[] =
7919 D3DVSD_STREAM(0),
7920 D3DVSD_REG(0, D3DVSDT_FLOAT3),
7921 D3DVSD_END()
7923 static const float normalize[4] = {1.0f / 256.0f, 1.0f / 256.0f, 1.0f / 256.0f, 1.0f / 256.0f};
7924 static const float no_normalize[4] = {1.0f, 1.0f, 1.0f, 1.0f};
7926 window = create_window();
7927 d3d = Direct3DCreate8(D3D_SDK_VERSION);
7928 ok(!!d3d, "Failed to create a D3D object.\n");
7929 if (!(device = create_device(d3d, window, window, TRUE)))
7931 skip("Failed to create a D3D device, skipping tests.\n");
7932 goto done;
7935 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
7936 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
7937 if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1))
7939 skip("No vs_1_1 support, skipping tests.\n");
7940 IDirect3DDevice8_Release(device);
7941 goto done;
7944 hr = IDirect3DDevice8_CreateVertexShader(device, decl_twotexcrd, swapped_shader_code, &swapped_twotexcrd_shader, 0);
7945 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
7946 hr = IDirect3DDevice8_CreateVertexShader(device, decl_onetexcrd, swapped_shader_code, &swapped_onetexcrd_shader, 0);
7947 todo_wine ok(hr == D3DERR_INVALIDCALL, "Unexpected error while creating vertex shader, hr %#x.\n", hr);
7948 hr = IDirect3DDevice8_CreateVertexShader(device, decl_twotexcrd_wrongidx, swapped_shader_code, &swapped_twotex_wrongidx_shader, 0);
7949 todo_wine ok(hr == D3DERR_INVALIDCALL, "Unexpected error while creating vertex shader, hr %#x.\n", hr);
7950 hr = IDirect3DDevice8_CreateVertexShader(device, decl_twotexcrd_rightorder, swapped_shader_code, &swapped_twotexcrd_rightorder_shader, 0);
7951 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
7953 hr = IDirect3DDevice8_CreateVertexShader(device, decl_texcoord_color, texcoord_color_shader_code, &texcoord_color_shader, 0);
7954 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
7955 hr = IDirect3DDevice8_CreateVertexShader(device, decl_color_ubyte, color_color_shader_code, &color_ubyte_shader, 0);
7956 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
7957 hr = IDirect3DDevice8_CreateVertexShader(device, decl_color_color, color_color_shader_code, &color_color_shader, 0);
7958 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
7959 hr = IDirect3DDevice8_CreateVertexShader(device, decl_color_float, color_color_shader_code, &color_float_shader, 0);
7960 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
7961 hr = IDirect3DDevice8_CreateVertexShader(device, decl_nocolor, color_color_shader_code, &color_nocolor_shader, 0);
7962 todo_wine ok(hr == D3DERR_INVALIDCALL, "Unexpected error while creating vertex shader, hr %#x.\n", hr);
7964 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 1.0f, 0);
7965 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
7967 hr = IDirect3DDevice8_BeginScene(device);
7968 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7970 hr = IDirect3DDevice8_SetVertexShader(device, swapped_twotexcrd_shader);
7971 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
7973 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 11);
7974 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7976 hr = IDirect3DDevice8_SetVertexShader(device, swapped_twotexcrd_rightorder_shader);
7977 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
7978 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 11);
7979 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7981 hr = IDirect3DDevice8_EndScene(device);
7982 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7984 color = getPixelColor(device, 160, 360);
7985 ok(color_match(color, 0x00ffff80, 1), "Got unexpected color 0x%08x for quad 1 (2crd).\n", color);
7986 color = getPixelColor(device, 480, 160);
7987 ok(color == 0x00000000, "Got unexpected color 0x%08x for quad 4 (2crd-rightorder).\n", color);
7989 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
7990 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
7992 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
7993 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
7995 hr = IDirect3DDevice8_BeginScene(device);
7996 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7998 hr = IDirect3DDevice8_SetVertexShader(device, texcoord_color_shader);
7999 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
8000 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1_color, sizeof(quad1_color[0]));
8001 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8003 hr = IDirect3DDevice8_SetVertexShader(device, color_ubyte_shader);
8004 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
8006 hr = IDirect3DDevice8_SetVertexShaderConstant(device, 0, normalize, 1);
8007 ok(SUCCEEDED(hr), "Failed to set vertex shader constant, hr %#x.\n", hr);
8008 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_color, sizeof(quad2_color[0]));
8009 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8011 hr = IDirect3DDevice8_SetVertexShaderConstant(device, 0, no_normalize, 1);
8012 ok(SUCCEEDED(hr), "Failed to set vertex shader constant, hr %#x.\n", hr);
8013 hr = IDirect3DDevice8_SetVertexShader(device, color_color_shader);
8014 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
8015 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3_color, sizeof(quad3_color[0]));
8016 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8018 hr = IDirect3DDevice8_SetVertexShader(device, color_float_shader);
8019 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
8020 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4_color, sizeof(float) * 7);
8021 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8023 hr = IDirect3DDevice8_EndScene(device);
8024 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
8026 IDirect3DDevice8_SetVertexShader(device, 0);
8028 color = getPixelColor(device, 160, 360);
8029 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
8030 "Input test: Quad 1(color-texcoord) returned color 0x%08x, expected 0x00ff8040\n", color);
8031 color = getPixelColor(device, 480, 360);
8032 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x40, 0x80, 0xff), 1),
8033 "Input test: Quad 2(color-ubyte) returned color 0x%08x, expected 0x004080ff\n", color);
8034 color = getPixelColor(device, 160, 120);
8035 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
8036 "Input test: Quad 3(color-color) returned color 0x%08x, expected 0x00ff8040\n", color);
8037 color = getPixelColor(device, 480, 160);
8038 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 1),
8039 "Input test: Quad 4(color-float) returned color 0x%08x, expected 0x00ffff00\n", color);
8041 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
8042 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
8044 IDirect3DDevice8_DeleteVertexShader(device, swapped_twotexcrd_shader);
8045 IDirect3DDevice8_DeleteVertexShader(device, swapped_onetexcrd_shader);
8046 IDirect3DDevice8_DeleteVertexShader(device, swapped_twotex_wrongidx_shader);
8047 IDirect3DDevice8_DeleteVertexShader(device, swapped_twotexcrd_rightorder_shader);
8048 IDirect3DDevice8_DeleteVertexShader(device, texcoord_color_shader);
8049 IDirect3DDevice8_DeleteVertexShader(device, color_ubyte_shader);
8050 IDirect3DDevice8_DeleteVertexShader(device, color_color_shader);
8051 IDirect3DDevice8_DeleteVertexShader(device, color_float_shader);
8052 IDirect3DDevice8_DeleteVertexShader(device, color_nocolor_shader);
8054 refcount = IDirect3DDevice8_Release(device);
8055 ok(!refcount, "Device has %u references left.\n", refcount);
8056 done:
8057 IDirect3D8_Release(d3d);
8058 DestroyWindow(window);
8061 static void test_fixed_function_fvf(void)
8063 IDirect3DDevice8 *device;
8064 DWORD color;
8065 IDirect3D8 *d3d;
8066 ULONG refcount;
8067 D3DCAPS8 caps;
8068 HWND window;
8069 HRESULT hr;
8071 static const struct
8073 struct vec3 position;
8074 DWORD diffuse;
8076 quad1[] =
8078 {{-1.0f, -1.0f, 0.1f}, 0x00ffff00},
8079 {{-1.0f, 0.0f, 0.1f}, 0x00ffff00},
8080 {{ 0.0f, -1.0f, 0.1f}, 0x00ffff00},
8081 {{ 0.0f, 0.0f, 0.1f}, 0x00ffff00},
8083 static const struct vec3 quad2[] =
8085 {-1.0f, -1.0f, 0.1f},
8086 {-1.0f, 0.0f, 0.1f},
8087 { 0.0f, -1.0f, 0.1f},
8088 { 0.0f, 0.0f, 0.1f},
8090 static const struct
8092 struct vec4 position;
8093 DWORD diffuse;
8095 quad_transformed[] =
8097 {{ 90.0f, 110.0f, 0.1f, 2.0f}, 0x00ffff00},
8098 {{570.0f, 110.0f, 0.1f, 2.0f}, 0x00ffff00},
8099 {{ 90.0f, 300.0f, 0.1f, 2.0f}, 0x00ffff00},
8100 {{570.0f, 300.0f, 0.1f, 2.0f}, 0x00ffff00},
8103 window = create_window();
8104 d3d = Direct3DCreate8(D3D_SDK_VERSION);
8105 ok(!!d3d, "Failed to create a D3D object.\n");
8106 if (!(device = create_device(d3d, window, window, TRUE)))
8108 skip("Failed to create a D3D device, skipping tests.\n");
8109 goto done;
8112 memset(&caps, 0, sizeof(caps));
8113 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
8114 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
8116 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
8117 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
8119 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
8120 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
8122 hr = IDirect3DDevice8_BeginScene(device);
8123 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
8125 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8126 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
8127 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
8128 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8130 hr = IDirect3DDevice8_EndScene(device);
8131 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
8133 color = getPixelColor(device, 160, 360);
8134 ok(color == 0x00ffff00,
8135 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
8136 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
8138 /* Test with no diffuse color attribute. */
8139 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8140 ok(SUCCEEDED(hr), "IDirect3DDevice8_Clear failed with %08x\n", hr);
8142 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ);
8143 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
8144 hr = IDirect3DDevice8_BeginScene(device);
8145 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
8146 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad2, sizeof(quad2[0]));
8147 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8148 hr = IDirect3DDevice8_EndScene(device);
8149 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
8151 color = getPixelColor(device, 160, 360);
8152 ok(color == 0x00ffffff, "Got unexpected color 0x%08x in the no diffuse attribute test.\n", color);
8153 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
8155 /* Test what happens with specular lighting enabled and no specular color attribute. */
8156 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
8157 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
8158 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SPECULARENABLE, TRUE);
8159 ok(SUCCEEDED(hr), "Failed to enable specular lighting, hr %#x.\n", hr);
8160 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8161 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
8162 hr = IDirect3DDevice8_BeginScene(device);
8163 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
8165 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad1, sizeof(quad1[0]));
8166 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8168 hr = IDirect3DDevice8_EndScene(device);
8169 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
8170 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SPECULARENABLE, FALSE);
8171 ok(SUCCEEDED(hr), "Failed to disable specular lighting, hr %#x.\n", hr);
8173 color = getPixelColor(device, 160, 360);
8174 ok(color == 0x00ffff00, "Got unexpected color 0x%08x in the no specular attribute test.\n", color);
8176 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
8178 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
8179 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
8181 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8182 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
8184 hr = IDirect3DDevice8_BeginScene(device);
8185 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
8186 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad_transformed, sizeof(quad_transformed[0]));
8187 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8188 hr = IDirect3DDevice8_EndScene(device);
8189 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
8191 color = getPixelColor(device, 88, 108);
8192 ok(color == 0x000000ff,
8193 "pixel 88/108 has color %08x, expected 0x000000ff\n", color);
8194 color = getPixelColor(device, 92, 108);
8195 ok(color == 0x000000ff,
8196 "pixel 92/108 has color %08x, expected 0x000000ff\n", color);
8197 color = getPixelColor(device, 88, 112);
8198 ok(color == 0x000000ff,
8199 "pixel 88/112 has color %08x, expected 0x000000ff\n", color);
8200 color = getPixelColor(device, 92, 112);
8201 ok(color == 0x00ffff00,
8202 "pixel 92/112 has color %08x, expected 0x00ffff00\n", color);
8204 color = getPixelColor(device, 568, 108);
8205 ok(color == 0x000000ff,
8206 "pixel 568/108 has color %08x, expected 0x000000ff\n", color);
8207 color = getPixelColor(device, 572, 108);
8208 ok(color == 0x000000ff,
8209 "pixel 572/108 has color %08x, expected 0x000000ff\n", color);
8210 color = getPixelColor(device, 568, 112);
8211 ok(color == 0x00ffff00,
8212 "pixel 568/112 has color %08x, expected 0x00ffff00\n", color);
8213 color = getPixelColor(device, 572, 112);
8214 ok(color == 0x000000ff,
8215 "pixel 572/112 has color %08x, expected 0x000000ff\n", color);
8217 color = getPixelColor(device, 88, 298);
8218 ok(color == 0x000000ff,
8219 "pixel 88/298 has color %08x, expected 0x000000ff\n", color);
8220 color = getPixelColor(device, 92, 298);
8221 ok(color == 0x00ffff00,
8222 "pixel 92/298 has color %08x, expected 0x00ffff00\n", color);
8223 color = getPixelColor(device, 88, 302);
8224 ok(color == 0x000000ff,
8225 "pixel 88/302 has color %08x, expected 0x000000ff\n", color);
8226 color = getPixelColor(device, 92, 302);
8227 ok(color == 0x000000ff,
8228 "pixel 92/302 has color %08x, expected 0x000000ff\n", color);
8230 color = getPixelColor(device, 568, 298);
8231 ok(color == 0x00ffff00,
8232 "pixel 568/298 has color %08x, expected 0x00ffff00\n", color);
8233 color = getPixelColor(device, 572, 298);
8234 ok(color == 0x000000ff,
8235 "pixel 572/298 has color %08x, expected 0x000000ff\n", color);
8236 color = getPixelColor(device, 568, 302);
8237 ok(color == 0x000000ff,
8238 "pixel 568/302 has color %08x, expected 0x000000ff\n", color);
8239 color = getPixelColor(device, 572, 302);
8240 ok(color == 0x000000ff,
8241 "pixel 572/302 has color %08x, expected 0x000000ff\n", color);
8243 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
8245 refcount = IDirect3DDevice8_Release(device);
8246 ok(!refcount, "Device has %u references left.\n", refcount);
8247 done:
8248 IDirect3D8_Release(d3d);
8249 DestroyWindow(window);
8252 static void test_flip(void)
8254 IDirect3DDevice8 *device;
8255 IDirect3D8 *d3d;
8256 ULONG refcount;
8257 HWND window;
8258 HRESULT hr;
8259 IDirect3DSurface8 *back_buffers[3], *test_surface;
8260 unsigned int i;
8261 D3DCOLOR color;
8262 D3DPRESENT_PARAMETERS present_parameters = {0};
8264 window = create_window();
8265 d3d = Direct3DCreate8(D3D_SDK_VERSION);
8266 ok(!!d3d, "Failed to create a D3D object.\n");
8268 present_parameters.BackBufferWidth = 640;
8269 present_parameters.BackBufferHeight = 480;
8270 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
8271 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
8272 present_parameters.hDeviceWindow = window;
8273 present_parameters.Windowed = TRUE;
8274 present_parameters.BackBufferCount = 3;
8275 present_parameters.Flags = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER;
8276 if (FAILED(hr = IDirect3D8_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
8277 window, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device)))
8279 skip("Failed to create a D3D device, skipping tests.\n");
8280 IDirect3D8_Release(d3d);
8281 DestroyWindow(window);
8282 return;
8285 for (i = 0; i < ARRAY_SIZE(back_buffers); ++i)
8287 hr = IDirect3DDevice8_GetBackBuffer(device, i, D3DBACKBUFFER_TYPE_MONO, &back_buffers[i]);
8288 ok(SUCCEEDED(hr), "Failed to get back buffer, hr %#x.\n", hr);
8290 hr = IDirect3DDevice8_GetRenderTarget(device, &test_surface);
8291 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
8292 ok(test_surface == back_buffers[0], "Expected render target %p, got %p.\n", back_buffers[0], test_surface);
8293 IDirect3DSurface8_Release(test_surface);
8296 hr = IDirect3DDevice8_SetRenderTarget(device, back_buffers[0], NULL);
8297 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
8298 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0f, 0);
8299 ok(SUCCEEDED(hr), "Failed to clear, hr %#x\n", hr);
8301 hr = IDirect3DDevice8_SetRenderTarget(device, back_buffers[1], NULL);
8302 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
8303 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0f, 0);
8304 ok(SUCCEEDED(hr), "Failed to clear, hr %#x\n", hr);
8306 hr = IDirect3DDevice8_SetRenderTarget(device, back_buffers[2], NULL);
8307 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
8308 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0f, 0);
8309 ok(SUCCEEDED(hr), "Failed to clear, hr %#x\n", hr);
8311 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
8312 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
8314 /* Render target is unmodified. */
8315 hr = IDirect3DDevice8_GetRenderTarget(device, &test_surface);
8316 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
8317 ok(test_surface == back_buffers[2], "Expected render target %p, got %p.\n", back_buffers[2], test_surface);
8318 IDirect3DSurface8_Release(test_surface);
8320 /* Backbuffer surface pointers are unmodified */
8321 for (i = 0; i < ARRAY_SIZE(back_buffers); ++i)
8323 hr = IDirect3DDevice8_GetBackBuffer(device, i, D3DBACKBUFFER_TYPE_MONO, &test_surface);
8324 ok(SUCCEEDED(hr), "Failed to get back buffer, hr %#x.\n", hr);
8325 ok(test_surface == back_buffers[i], "Expected back buffer %u = %p, got %p.\n",
8326 i, back_buffers[i], test_surface);
8327 IDirect3DSurface8_Release(test_surface);
8330 /* Contents were changed. */
8331 color = get_surface_color(back_buffers[0], 1, 1);
8332 ok(color == 0xff00ff00, "Got unexpected color 0x%08x.\n", color);
8333 color = get_surface_color(back_buffers[1], 1, 1);
8334 ok(color == 0xff0000ff, "Got unexpected color 0x%08x.\n", color);
8336 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff808080, 0.0f, 0);
8337 ok(SUCCEEDED(hr), "Failed to clear, hr %#x\n", hr);
8339 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
8340 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
8342 color = get_surface_color(back_buffers[0], 1, 1);
8343 ok(color == 0xff0000ff, "Got unexpected color 0x%08x.\n", color);
8344 color = get_surface_color(back_buffers[1], 1, 1);
8345 ok(color == 0xff808080, "Got unexpected color 0x%08x.\n", color);
8347 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
8348 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
8350 color = get_surface_color(back_buffers[0], 1, 1);
8351 ok(color == 0xff808080, "Got unexpected color 0x%08x.\n", color);
8353 for (i = 0; i < ARRAY_SIZE(back_buffers); ++i)
8354 IDirect3DSurface8_Release(back_buffers[i]);
8356 refcount = IDirect3DDevice8_Release(device);
8357 ok(!refcount, "Device has %u references left.\n", refcount);
8359 if (FAILED(IDirect3D8_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
8360 D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES)))
8362 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping multisample flip test.\n");
8363 goto done;
8366 present_parameters.BackBufferCount = 2;
8367 present_parameters.MultiSampleType = D3DMULTISAMPLE_2_SAMPLES;
8368 present_parameters.Flags = 0;
8369 hr = IDirect3D8_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
8370 window, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device);
8372 for (i = 0; i < present_parameters.BackBufferCount; ++i)
8374 hr = IDirect3DDevice8_GetBackBuffer(device, i, D3DBACKBUFFER_TYPE_MONO, &back_buffers[i]);
8375 ok(SUCCEEDED(hr), "Failed to get back buffer, hr %#x.\n", hr);
8378 hr = IDirect3DDevice8_SetRenderTarget(device, back_buffers[1], NULL);
8379 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
8380 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff808080, 0.0f, 0);
8381 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
8383 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
8384 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
8386 hr = IDirect3DDevice8_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
8387 D3DMULTISAMPLE_NONE, TRUE, &test_surface);
8388 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
8389 hr = IDirect3DDevice8_CopyRects(device, back_buffers[0], NULL, 0, test_surface, NULL);
8390 ok(SUCCEEDED(hr), "CopyRects failed, hr %#x.\n", hr);
8392 color = get_surface_color(test_surface, 1, 1);
8393 ok(color == 0xff808080, "Got unexpected color 0x%08x.\n", color);
8395 IDirect3DSurface8_Release(test_surface);
8396 for (i = 0; i < present_parameters.BackBufferCount; ++i)
8397 IDirect3DSurface8_Release(back_buffers[i]);
8399 refcount = IDirect3DDevice8_Release(device);
8400 ok(!refcount, "Device has %u references left.\n", refcount);
8402 done:
8403 IDirect3D8_Release(d3d);
8404 DestroyWindow(window);
8407 static void test_uninitialized_varyings(void)
8409 static const D3DMATRIX mat =
8411 1.0f, 0.0f, 0.0f, 0.0f,
8412 0.0f, 1.0f, 0.0f, 0.0f,
8413 0.0f, 0.0f, 1.0f, 0.0f,
8414 0.0f, 0.0f, 0.0f, 1.0f,
8415 }}};
8416 static const struct vec3 quad[] =
8418 {-1.0f, -1.0f, 0.1f},
8419 {-1.0f, 1.0f, 0.1f},
8420 { 1.0f, -1.0f, 0.1f},
8421 { 1.0f, 1.0f, 0.1f},
8423 static const DWORD decl[] =
8425 D3DVSD_STREAM(0),
8426 D3DVSD_REG(0, D3DVSDT_FLOAT3),
8427 D3DVSD_CONST(0, 1), 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, /* def c0, 0.5, 0.5, 0.5, 0.5 */
8428 D3DVSD_END()
8430 static const DWORD vs1_code[] =
8432 0xfffe0101, /* vs_1_1 */
8433 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
8434 0x0000ffff
8436 static const DWORD vs1_partial_code[] =
8438 0xfffe0101, /* vs_1_1 */
8439 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
8440 0x00000001, 0xd0010000, 0xa0e40000, /* mov oD0.x, c0 */
8441 0x00000001, 0xd0010001, 0xa0e40000, /* mov oD1.x, c0 */
8442 0x00000001, 0xe0010000, 0xa0e40000, /* mov oT0.x, c0 */
8443 0x0000ffff
8445 static const DWORD ps1_diffuse_code[] =
8447 0xffff0101, /* ps_1_1 */
8448 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
8449 0x0000ffff
8451 static const DWORD ps1_specular_code[] =
8453 0xffff0101, /* ps_1_1 */
8454 0x00000001, 0x800f0000, 0x90e40001, /* mov r0, v1 */
8455 0x0000ffff
8457 static const DWORD ps1_texcoord_code[] =
8459 0xffff0101, /* ps_1_1 */
8460 0x00000040, 0xb00f0000, /* texcoord t0 */
8461 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
8462 0x0000ffff
8464 static const struct
8466 DWORD vs_version;
8467 const DWORD *vs;
8468 DWORD ps_version;
8469 const DWORD *ps;
8470 D3DCOLOR expected;
8471 BOOL allow_zero_alpha;
8472 BOOL partial;
8473 BOOL broken_warp;
8475 /* On AMD specular color is generally initialized to 0x00000000 and texcoords to 0xff000000
8476 * while on Nvidia it's the opposite. Just allow both.
8478 * Partially initialized varyings reliably handle the component that has been initialized.
8479 * The uninitialized components generally follow the rule above, with some exceptions on
8480 * radeon cards. r500 and r600 GPUs have been found to set uninitialized components to 0.0,
8481 * 0.5 and 1.0 without a sensible pattern. */
8482 tests[] =
8484 {D3DVS_VERSION(1, 1), vs1_code, 0, NULL, 0xffffffff},
8485 { 0, NULL, D3DPS_VERSION(1, 1), ps1_texcoord_code, 0xff000000, TRUE},
8486 {D3DVS_VERSION(1, 1), vs1_code, D3DPS_VERSION(1, 1), ps1_diffuse_code, 0xffffffff},
8487 {D3DVS_VERSION(1, 1), vs1_code, D3DPS_VERSION(1, 1), ps1_specular_code, 0xff000000, TRUE, FALSE, TRUE},
8488 {D3DVS_VERSION(1, 1), vs1_code, D3DPS_VERSION(1, 1), ps1_texcoord_code, 0xff000000, TRUE},
8489 {D3DVS_VERSION(1, 1), vs1_partial_code, 0, NULL, 0xff7fffff, FALSE, TRUE},
8490 {D3DVS_VERSION(1, 1), vs1_partial_code, D3DPS_VERSION(1, 1), ps1_diffuse_code, 0xff7fffff, FALSE, TRUE},
8491 {D3DVS_VERSION(1, 1), vs1_partial_code, D3DPS_VERSION(1, 1), ps1_specular_code, 0xff7f0000, TRUE, TRUE},
8492 {D3DVS_VERSION(1, 1), vs1_partial_code, D3DPS_VERSION(1, 1), ps1_texcoord_code, 0xff7f0000, TRUE, TRUE},
8494 IDirect3DDevice8 *device;
8495 IDirect3D8 *d3d;
8496 HWND window;
8497 HRESULT hr;
8498 DWORD vs, ps;
8499 unsigned int i;
8500 ULONG refcount;
8501 D3DCAPS8 caps;
8502 IDirect3DSurface8 *backbuffer;
8503 D3DADAPTER_IDENTIFIER8 identifier;
8504 struct surface_readback rb;
8505 D3DCOLOR color;
8506 BOOL warp;
8508 window = create_window();
8509 d3d = Direct3DCreate8(D3D_SDK_VERSION);
8510 ok(!!d3d, "Failed to create a D3D object.\n");
8511 if (!(device = create_device(d3d, window, window, TRUE)))
8513 skip("Failed to create a D3D device, skipping tests.\n");
8514 IDirect3D8_Release(d3d);
8515 DestroyWindow(window);
8516 return;
8519 hr = IDirect3D8_GetAdapterIdentifier(d3d, D3DADAPTER_DEFAULT, 0, &identifier);
8520 ok(SUCCEEDED(hr), "Failed to get adapter identifier, hr %#x.\n", hr);
8521 warp = adapter_is_warp(&identifier);
8523 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
8524 ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
8526 hr = IDirect3DDevice8_GetBackBuffer(device, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8527 ok(SUCCEEDED(hr), "Failed to get back buffer, hr %#x.\n", hr);
8529 hr = IDirect3DDevice8_SetTransform(device, D3DTS_WORLD, &mat);
8530 ok(SUCCEEDED(hr), "Failed to set world transform, hr %#x.\n", hr);
8531 hr = IDirect3DDevice8_SetTransform(device, D3DTS_VIEW, &mat);
8532 ok(SUCCEEDED(hr), "Failed to set view transform, hr %#x.\n", hr);
8533 hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, &mat);
8534 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
8535 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, FALSE);
8536 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#x.\n", hr);
8537 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, FALSE);
8538 ok(SUCCEEDED(hr), "Failed to disable Z test, hr %#x.\n", hr);
8539 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
8540 ok(SUCCEEDED(hr), "Failed to disable fog, hr %#x.\n", hr);
8541 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
8542 ok(SUCCEEDED(hr), "Failed to disable stencil test, hr %#x.\n", hr);
8543 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8544 ok(SUCCEEDED(hr), "Failed to disable culling, hr %#x.\n", hr);
8546 for (i = 0; i < ARRAY_SIZE(tests); ++i)
8548 if (caps.VertexShaderVersion < tests[i].vs_version
8549 || caps.PixelShaderVersion < tests[i].ps_version)
8551 skip("Vertex / pixel shader version not supported, skipping test %u.\n", i);
8552 continue;
8554 if (tests[i].vs)
8556 hr = IDirect3DDevice8_CreateVertexShader(device, decl, tests[i].vs, &vs, 0);
8557 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x (case %u).\n", hr, i);
8558 hr = IDirect3DDevice8_SetVertexShader(device, vs);
8559 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
8561 else
8563 vs = 0;
8564 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ);
8565 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
8567 if (tests[i].ps)
8569 hr = IDirect3DDevice8_CreatePixelShader(device, tests[i].ps, &ps);
8570 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x (case %u).\n", hr, i);
8572 else
8574 ps = 0;
8577 hr = IDirect3DDevice8_SetPixelShader(device, ps);
8578 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
8580 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0f, 0);
8581 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
8583 hr = IDirect3DDevice8_BeginScene(device);
8584 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
8586 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
8587 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8589 hr = IDirect3DDevice8_EndScene(device);
8590 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
8592 get_rt_readback(backbuffer, &rb);
8593 color = get_readback_color(&rb, 320, 240);
8594 ok(color_match(color, tests[i].expected, 1)
8595 || (tests[i].allow_zero_alpha && color_match(color, tests[i].expected & 0x00ffffff, 1))
8596 || (broken(warp && tests[i].broken_warp))
8597 || broken(tests[i].partial && color_match(color & 0x00ff0000, tests[i].expected & 0x00ff0000, 1)),
8598 "Got unexpected color 0x%08x, case %u.\n", color, i);
8599 release_surface_readback(&rb);
8601 if (vs)
8602 IDirect3DDevice8_DeleteVertexShader(device, vs);
8603 if (ps)
8604 IDirect3DDevice8_DeletePixelShader(device, ps);
8607 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
8608 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
8610 IDirect3DSurface8_Release(backbuffer);
8611 refcount = IDirect3DDevice8_Release(device);
8612 ok(!refcount, "Device has %u references left.\n", refcount);
8613 IDirect3D8_Release(d3d);
8614 DestroyWindow(window);
8617 static void test_shademode(void)
8619 IDirect3DVertexBuffer8 *vb_strip;
8620 IDirect3DVertexBuffer8 *vb_list;
8621 IDirect3DDevice8 *device;
8622 DWORD color0, color1;
8623 BYTE *data = NULL;
8624 IDirect3D8 *d3d;
8625 ULONG refcount;
8626 D3DCAPS8 caps;
8627 DWORD vs, ps;
8628 HWND window;
8629 HRESULT hr;
8630 UINT i;
8631 static const DWORD decl[] =
8633 D3DVSD_STREAM(0),
8634 D3DVSD_REG(D3DVSDE_POSITION, D3DVSDT_FLOAT3),
8635 D3DVSD_REG(D3DVSDE_DIFFUSE, D3DVSDT_D3DCOLOR),
8636 D3DVSD_END()
8638 static const DWORD vs1_code[] =
8640 0xfffe0101, /* vs_1_1 */
8641 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
8642 0x00000001, 0xd00f0000, 0x90e40005, /* mov oD0, v5 */
8643 0x0000ffff
8645 static const DWORD ps1_code[] =
8647 0xffff0101, /* ps_1_1 */
8648 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
8649 0x0000ffff
8651 static const struct
8653 struct vec3 position;
8654 DWORD diffuse;
8656 quad_strip[] =
8658 {{-1.0f, -1.0f, 0.0f}, 0xffff0000},
8659 {{-1.0f, 1.0f, 0.0f}, 0xff00ff00},
8660 {{ 1.0f, -1.0f, 0.0f}, 0xff0000ff},
8661 {{ 1.0f, 1.0f, 0.0f}, 0xffffffff},
8663 quad_list[] =
8665 {{-1.0f, -1.0f, 0.0f}, 0xffff0000},
8666 {{-1.0f, 1.0f, 0.0f}, 0xff00ff00},
8667 {{ 1.0f, -1.0f, 0.0f}, 0xff0000ff},
8669 {{ 1.0f, -1.0f, 0.0f}, 0xff0000ff},
8670 {{-1.0f, 1.0f, 0.0f}, 0xff00ff00},
8671 {{ 1.0f, 1.0f, 0.0f}, 0xffffffff},
8673 static const struct test_shader
8675 DWORD version;
8676 const DWORD *code;
8678 novs = {0, NULL},
8679 vs_1 = {D3DVS_VERSION(1, 1), vs1_code},
8680 nops = {0, NULL},
8681 ps_1 = {D3DPS_VERSION(1, 1), ps1_code};
8682 static const struct
8684 const struct test_shader *vs, *ps;
8685 DWORD primtype;
8686 DWORD shademode;
8687 DWORD color0, color1;
8689 tests[] =
8691 {&novs, &nops, D3DPT_TRIANGLESTRIP, D3DSHADE_FLAT, 0x00ff0000, 0x0000ff00},
8692 {&novs, &nops, D3DPT_TRIANGLESTRIP, D3DSHADE_PHONG, 0x000dca28, 0x000d45c7},
8693 {&novs, &nops, D3DPT_TRIANGLESTRIP, D3DSHADE_GOURAUD, 0x000dca28, 0x000d45c7},
8694 {&novs, &nops, D3DPT_TRIANGLESTRIP, D3DSHADE_PHONG, 0x000dca28, 0x000d45c7},
8695 {&novs, &nops, D3DPT_TRIANGLELIST, D3DSHADE_FLAT, 0x00ff0000, 0x000000ff},
8696 {&novs, &nops, D3DPT_TRIANGLELIST, D3DSHADE_GOURAUD, 0x000dca28, 0x000d45c7},
8697 {&vs_1, &ps_1, D3DPT_TRIANGLESTRIP, D3DSHADE_FLAT, 0x00ff0000, 0x0000ff00},
8698 {&vs_1, &ps_1, D3DPT_TRIANGLESTRIP, D3DSHADE_GOURAUD, 0x000dca28, 0x000d45c7},
8699 {&vs_1, &ps_1, D3DPT_TRIANGLELIST, D3DSHADE_FLAT, 0x00ff0000, 0x000000ff},
8700 {&vs_1, &ps_1, D3DPT_TRIANGLELIST, D3DSHADE_GOURAUD, 0x000dca28, 0x000d45c7},
8701 {&novs, &ps_1, D3DPT_TRIANGLESTRIP, D3DSHADE_FLAT, 0x00ff0000, 0x0000ff00},
8702 {&vs_1, &nops, D3DPT_TRIANGLESTRIP, D3DSHADE_FLAT, 0x00ff0000, 0x0000ff00},
8705 window = create_window();
8706 d3d = Direct3DCreate8(D3D_SDK_VERSION);
8707 ok(!!d3d, "Failed to create a D3D object.\n");
8708 if (!(device = create_device(d3d, window, window, TRUE)))
8710 skip("Failed to create a D3D device, skipping tests.\n");
8711 IDirect3D8_Release(d3d);
8712 DestroyWindow(window);
8713 return;
8716 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
8717 ok(hr == D3D_OK, "Failed to disable lighting, hr %#x.\n", hr);
8718 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
8719 ok(SUCCEEDED(hr), "Failed to disable fog, hr %#x.\n", hr);
8721 hr = IDirect3DDevice8_CreateVertexBuffer(device, sizeof(quad_strip), 0, 0, D3DPOOL_MANAGED, &vb_strip);
8722 ok(hr == D3D_OK, "Failed to create vertex buffer, hr %#x.\n", hr);
8723 hr = IDirect3DVertexBuffer8_Lock(vb_strip, 0, sizeof(quad_strip), &data, 0);
8724 ok(hr == D3D_OK, "Failed to lock vertex buffer, hr %#x.\n", hr);
8725 memcpy(data, quad_strip, sizeof(quad_strip));
8726 hr = IDirect3DVertexBuffer8_Unlock(vb_strip);
8727 ok(hr == D3D_OK, "Failed to unlock vertex buffer, hr %#x.\n", hr);
8729 hr = IDirect3DDevice8_CreateVertexBuffer(device, sizeof(quad_list), 0, 0, D3DPOOL_MANAGED, &vb_list);
8730 ok(hr == D3D_OK, "Failed to create vertex buffer, hr %#x.\n", hr);
8731 hr = IDirect3DVertexBuffer8_Lock(vb_list, 0, sizeof(quad_list), &data, 0);
8732 ok(hr == D3D_OK, "Failed to lock vertex buffer, hr %#x.\n", hr);
8733 memcpy(data, quad_list, sizeof(quad_list));
8734 hr = IDirect3DVertexBuffer8_Unlock(vb_list);
8735 ok(hr == D3D_OK, "Failed to unlock vertex buffer, hr %#x.\n", hr);
8737 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
8738 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
8740 /* Try it first with a TRIANGLESTRIP. Do it with different geometry because
8741 * the color fixups we have to do for FLAT shading will be dependent on that. */
8743 for (i = 0; i < ARRAY_SIZE(tests); ++i)
8745 if (tests[i].vs->version)
8747 if (caps.VertexShaderVersion >= tests[i].vs->version)
8749 hr = IDirect3DDevice8_CreateVertexShader(device, decl, tests[i].vs->code, &vs, 0);
8750 ok(hr == D3D_OK, "Failed to create vertex shader, hr %#x.\n", hr);
8751 hr = IDirect3DDevice8_SetVertexShader(device, vs);
8752 ok(hr == D3D_OK, "Failed to set vertex shader, hr %#x.\n", hr);
8754 else
8756 skip("Shader version unsupported, skipping some tests.\n");
8757 continue;
8760 else
8762 vs = 0;
8763 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8764 ok(hr == D3D_OK, "Failed to set FVF, hr %#x.\n", hr);
8766 if (tests[i].ps->version)
8768 if (caps.PixelShaderVersion >= tests[i].ps->version)
8770 hr = IDirect3DDevice8_CreatePixelShader(device, tests[i].ps->code, &ps);
8771 ok(hr == D3D_OK, "Failed to create pixel shader, hr %#x.\n", hr);
8772 hr = IDirect3DDevice8_SetPixelShader(device, ps);
8773 ok(hr == D3D_OK, "Failed to set pixel shader, hr %#x.\n", hr);
8775 else
8777 skip("Shader version unsupported, skipping some tests.\n");
8778 if (vs)
8780 IDirect3DDevice8_SetVertexShader(device, 0);
8781 IDirect3DDevice8_DeleteVertexShader(device, vs);
8783 continue;
8786 else
8788 ps = 0;
8791 hr = IDirect3DDevice8_SetStreamSource(device, 0,
8792 tests[i].primtype == D3DPT_TRIANGLESTRIP ? vb_strip : vb_list, sizeof(quad_strip[0]));
8793 ok(hr == D3D_OK, "Failed to set stream source, hr %#x.\n", hr);
8795 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
8796 ok(hr == D3D_OK, "Failed to clear, hr %#x.\n", hr);
8798 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SHADEMODE, tests[i].shademode);
8799 ok(hr == D3D_OK, "Failed to set shade mode, hr %#x.\n", hr);
8801 hr = IDirect3DDevice8_BeginScene(device);
8802 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
8803 hr = IDirect3DDevice8_DrawPrimitive(device, tests[i].primtype, 0, 2);
8804 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8805 hr = IDirect3DDevice8_EndScene(device);
8806 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
8808 color0 = getPixelColor(device, 100, 100); /* Inside first triangle */
8809 color1 = getPixelColor(device, 500, 350); /* Inside second triangle */
8811 /* For D3DSHADE_FLAT it should take the color of the first vertex of
8812 * each triangle. This requires EXT_provoking_vertex or similar
8813 * functionality being available. */
8814 /* PHONG should be the same as GOURAUD, since no hardware implements
8815 * this. */
8816 ok(color_match(color0, tests[i].color0, 1), "Test %u shading has color0 %08x, expected %08x.\n",
8817 i, color0, tests[i].color0);
8818 ok(color_match(color1, tests[i].color1, 1), "Test %u shading has color1 %08x, expected %08x.\n",
8819 i, color1, tests[i].color1);
8821 IDirect3DDevice8_SetVertexShader(device, 0);
8822 IDirect3DDevice8_SetPixelShader(device, 0);
8824 if (ps)
8825 IDirect3DDevice8_DeletePixelShader(device, ps);
8826 if (vs)
8827 IDirect3DDevice8_DeleteVertexShader(device, vs);
8830 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
8831 ok(hr == D3D_OK, "Failed to present, hr %#x.\n", hr);
8833 IDirect3DVertexBuffer8_Release(vb_strip);
8834 IDirect3DVertexBuffer8_Release(vb_list);
8835 refcount = IDirect3DDevice8_Release(device);
8836 ok(!refcount, "Device has %u references left.\n", refcount);
8837 IDirect3D8_Release(d3d);
8838 DestroyWindow(window);
8841 static void test_multisample_init(void)
8843 IDirect3DDevice8 *device;
8844 IDirect3D8 *d3d;
8845 IDirect3DSurface8 *back, *multi;
8846 ULONG refcount;
8847 HWND window;
8848 HRESULT hr;
8849 D3DCOLOR color;
8850 unsigned int x, y;
8851 struct surface_readback rb;
8852 BOOL all_zero = TRUE;
8854 window = create_window();
8855 d3d = Direct3DCreate8(D3D_SDK_VERSION);
8856 ok(!!d3d, "Failed to create a D3D object.\n");
8858 if (FAILED(IDirect3D8_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
8859 D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES)))
8861 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping multisample init test.\n");
8862 goto done;
8865 if (!(device = create_device(d3d, window, window, TRUE)))
8867 skip("Failed to create a D3D device, skipping tests.\n");
8868 goto done;
8871 hr = IDirect3DDevice8_GetBackBuffer(device, 0, D3DBACKBUFFER_TYPE_MONO, &back);
8872 ok(SUCCEEDED(hr), "Failed to get back buffer, hr %#x.\n", hr);
8873 hr = IDirect3DDevice8_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
8874 D3DMULTISAMPLE_2_SAMPLES, FALSE, &multi);
8875 ok(SUCCEEDED(hr), "Failed to create multisampled render target, hr %#x.\n", hr);
8877 hr = IDirect3DDevice8_CopyRects(device, multi, NULL, 0, back, NULL);
8878 ok(SUCCEEDED(hr), "CopyRects failed, hr %#x.\n", hr);
8880 get_rt_readback(back, &rb);
8881 for (y = 0; y < 480; ++y)
8883 for (x = 0; x < 640; ++x)
8885 color = get_readback_color(&rb, x, y);
8886 if (!color_match(color, 0x00000000, 0))
8888 all_zero = FALSE;
8889 break;
8892 if (!all_zero)
8893 break;
8895 release_surface_readback(&rb);
8896 ok(all_zero, "Got unexpected color 0x%08x, position %ux%u.\n", color, x, y);
8898 IDirect3DSurface8_Release(multi);
8899 IDirect3DSurface8_Release(back);
8901 refcount = IDirect3DDevice8_Release(device);
8902 ok(!refcount, "Device has %u references left.\n", refcount);
8904 done:
8905 IDirect3D8_Release(d3d);
8906 DestroyWindow(window);
8909 static void test_texture_blending(void)
8911 #define STATE_END() {0xffffffff, 0xffffffff}
8912 #define IS_STATE_END(s) (s.name == 0xffffffff && s.value == 0xffffffff)
8914 IDirect3DTexture8 *texture_bumpmap, *texture_red;
8915 IDirect3DSurface8 *backbuffer;
8916 struct surface_readback rb;
8917 D3DLOCKED_RECT locked_rect;
8918 IDirect3DDevice8 *device;
8919 unsigned int i, j, k;
8920 IDirect3D8 *d3d;
8921 D3DCOLOR color;
8922 ULONG refcount;
8923 D3DCAPS8 caps;
8924 HWND window;
8925 HRESULT hr;
8927 static const struct
8929 struct vec3 position;
8930 DWORD diffuse;
8932 quad[] =
8934 {{-1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0x80, 0xff, 0xff, 0x02)},
8935 {{-1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0x80, 0xff, 0xff, 0x02)},
8936 {{ 1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0x80, 0xff, 0xff, 0x02)},
8937 {{ 1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0x80, 0xff, 0xff, 0x02)},
8940 static const float bumpenvmat[4] = {1.0f, 1.0f, 0.0f, 0.0f};
8942 struct texture_stage_state
8944 D3DTEXTURESTAGESTATETYPE name;
8945 DWORD value;
8948 struct texture_stage
8950 enum
8952 TEXTURE_INVALID,
8953 TEXTURE_NONE,
8954 TEXTURE_BUMPMAP,
8955 TEXTURE_RED,
8957 texture;
8958 struct texture_stage_state state[20];
8961 static const struct texture_stage default_stage_state =
8963 TEXTURE_NONE,
8965 {D3DTSS_COLOROP, D3DTOP_DISABLE},
8966 {D3DTSS_COLORARG1, D3DTA_TEXTURE},
8967 {D3DTSS_COLORARG2, D3DTA_CURRENT},
8968 {D3DTSS_ALPHAOP, D3DTOP_DISABLE},
8969 {D3DTSS_ALPHAARG1, D3DTA_TEXTURE},
8970 {D3DTSS_ALPHAARG2, D3DTA_CURRENT},
8971 {D3DTSS_BUMPENVMAT00, 0},
8972 {D3DTSS_BUMPENVMAT01, 0},
8973 {D3DTSS_BUMPENVMAT10, 0},
8974 {D3DTSS_BUMPENVMAT11, 0},
8975 {D3DTSS_BUMPENVLSCALE, 0},
8976 {D3DTSS_BUMPENVLOFFSET, 0},
8977 {D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE},
8978 {D3DTSS_COLORARG0, D3DTA_CURRENT},
8979 {D3DTSS_ALPHAARG0, D3DTA_CURRENT},
8980 {D3DTSS_RESULTARG, D3DTA_CURRENT},
8981 STATE_END(),
8985 const struct test
8987 DWORD tex_op_caps;
8988 D3DCOLOR expected_color;
8989 struct texture_stage stage[8];
8991 tests[] =
8994 D3DTEXOPCAPS_DISABLE,
8995 0x80ffff02,
8998 TEXTURE_NONE,
9000 STATE_END(),
9006 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1,
9007 0x80ffff02,
9010 TEXTURE_NONE,
9012 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
9013 {D3DTSS_COLORARG1, D3DTA_CURRENT},
9014 STATE_END(),
9017 {TEXTURE_INVALID}
9021 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1,
9022 0x80ffff02,
9025 TEXTURE_NONE,
9027 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
9028 {D3DTSS_COLORARG1, D3DTA_CURRENT},
9029 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
9030 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
9031 STATE_END(),
9037 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1,
9038 0x80ffff02,
9041 TEXTURE_NONE,
9043 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
9044 {D3DTSS_COLORARG1, D3DTA_DIFFUSE},
9045 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
9046 {D3DTSS_ALPHAARG1, D3DTA_DIFFUSE},
9047 STATE_END(),
9053 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1,
9054 0x00000000,
9057 TEXTURE_NONE,
9059 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
9060 {D3DTSS_COLORARG1, D3DTA_TEMP},
9061 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
9062 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
9063 STATE_END(),
9070 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE,
9071 0x80ff0000,
9074 TEXTURE_BUMPMAP,
9076 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
9077 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
9078 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
9079 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
9080 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
9081 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
9082 {D3DTSS_ALPHAARG1, D3DTA_TEXTURE},
9083 STATE_END(),
9088 TEXTURE_RED,
9090 {D3DTSS_COLOROP, D3DTOP_MODULATE},
9091 STATE_END(),
9094 {TEXTURE_INVALID}
9098 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE,
9099 0x80ff0000,
9102 TEXTURE_BUMPMAP,
9104 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
9105 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
9106 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
9107 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
9108 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
9109 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
9110 {D3DTSS_ALPHAARG1, D3DTA_DIFFUSE},
9111 STATE_END(),
9115 TEXTURE_RED,
9117 {D3DTSS_COLOROP, D3DTOP_MODULATE},
9118 STATE_END(),
9121 {TEXTURE_INVALID}
9125 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE,
9126 0x80ff0000,
9129 TEXTURE_BUMPMAP,
9131 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
9132 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
9133 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
9134 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
9135 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
9136 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
9137 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
9138 STATE_END(),
9142 TEXTURE_RED,
9144 {D3DTSS_COLOROP, D3DTOP_MODULATE},
9145 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
9146 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
9147 STATE_END(),
9150 {TEXTURE_INVALID}
9154 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE,
9155 0x00ff0000,
9158 TEXTURE_BUMPMAP,
9160 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
9161 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
9162 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
9163 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
9164 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
9165 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
9166 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
9167 STATE_END(),
9171 TEXTURE_RED,
9173 {D3DTSS_COLOROP, D3DTOP_MODULATE},
9174 {D3DTSS_COLORARG1, D3DTA_TEXTURE},
9175 {D3DTSS_COLORARG2, D3DTA_CURRENT},
9176 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
9177 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
9178 STATE_END(),
9181 {TEXTURE_INVALID}
9185 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE,
9186 0x80ff0000,
9189 TEXTURE_BUMPMAP,
9191 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
9192 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
9193 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
9194 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
9195 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
9196 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
9197 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
9198 STATE_END(),
9202 TEXTURE_RED,
9204 {D3DTSS_COLOROP, D3DTOP_MODULATE},
9205 {D3DTSS_COLORARG1, D3DTA_TEXTURE},
9206 {D3DTSS_COLORARG2, D3DTA_CURRENT},
9207 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
9208 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
9209 STATE_END(),
9212 {TEXTURE_INVALID}
9217 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE
9218 | D3DTEXOPCAPS_ADD,
9219 0x80ff0000,
9222 TEXTURE_BUMPMAP,
9224 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
9225 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
9226 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
9227 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
9228 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
9229 {D3DTSS_ALPHAOP, D3DTOP_ADD},
9230 {D3DTSS_ALPHAARG1, D3DTA_DIFFUSE},
9231 {D3DTSS_ALPHAARG2, D3DTA_CURRENT},
9232 STATE_END(),
9236 TEXTURE_RED,
9238 {D3DTSS_COLOROP, D3DTOP_MODULATE},
9239 {D3DTSS_COLORARG1, D3DTA_TEXTURE},
9240 {D3DTSS_COLORARG2, D3DTA_CURRENT},
9241 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
9242 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
9243 STATE_END(),
9246 {TEXTURE_INVALID}
9250 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE
9251 | D3DTEXOPCAPS_MODULATE2X,
9252 0x80ffff00,
9255 TEXTURE_BUMPMAP,
9257 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
9258 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
9259 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
9260 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
9261 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
9262 {D3DTSS_ALPHAOP, D3DTOP_MODULATE2X},
9263 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
9264 {D3DTSS_ALPHAARG2, D3DTA_DIFFUSE},
9265 STATE_END(),
9269 TEXTURE_RED,
9271 {D3DTSS_COLOROP, D3DTOP_MODULATE},
9272 {D3DTSS_COLORARG1, D3DTA_CURRENT},
9273 {D3DTSS_COLORARG2, D3DTA_CURRENT},
9274 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
9275 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
9276 STATE_END(),
9279 {TEXTURE_INVALID}
9283 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP,
9284 0x80ffff02,
9287 TEXTURE_NONE,
9289 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
9290 {D3DTSS_COLORARG1, D3DTA_DIFFUSE},
9291 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
9292 {D3DTSS_ALPHAARG1, D3DTA_DIFFUSE},
9293 {D3DTSS_RESULTARG, D3DTA_TEMP},
9294 STATE_END(),
9298 TEXTURE_BUMPMAP,
9300 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
9301 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
9302 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
9303 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
9304 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
9305 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
9306 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
9307 {D3DTSS_RESULTARG, D3DTA_TEMP},
9308 STATE_END(),
9312 TEXTURE_RED,
9314 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
9315 {D3DTSS_COLORARG1, D3DTA_TEXTURE},
9316 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
9317 {D3DTSS_ALPHAARG1, D3DTA_TEXTURE},
9318 STATE_END(),
9322 TEXTURE_NONE,
9324 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
9325 {D3DTSS_COLORARG1, D3DTA_TEMP},
9326 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
9327 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
9328 STATE_END(),
9331 {TEXTURE_INVALID}
9336 window = create_window();
9337 d3d = Direct3DCreate8(D3D_SDK_VERSION);
9338 ok(!!d3d, "Failed to create a D3D object.\n");
9339 if (!(device = create_device(d3d, window, window, TRUE)))
9341 skip("Failed to create a D3D device.\n");
9342 goto done;
9345 memset(&caps, 0, sizeof(caps));
9346 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
9347 ok(hr == D3D_OK, "IDirect3DDevice8_GetDeviceCaps failed hr %#x.\n", hr);
9349 if(!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP))
9351 skip("D3DPMISCCAPS_TSSARGTEMP not supported.\n");
9352 IDirect3DDevice8_Release(device);
9353 goto done;
9356 if (FAILED(IDirect3D8_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
9357 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_V8U8)))
9359 skip("D3DFMT_V8U8 not supported for legacy bump mapping.\n");
9360 IDirect3DDevice8_Release(device);
9361 goto done;
9364 hr = IDirect3DDevice8_GetBackBuffer(device, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9365 ok(hr == D3D_OK, "Can't get back buffer, hr %#x.\n", hr);
9367 hr = IDirect3DDevice8_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture_bumpmap);
9368 ok(hr == D3D_OK, "IDirect3DDevice8_CreateTexture failed, hr %#x.\n", hr);
9369 hr = IDirect3DDevice8_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture_red);
9370 ok(hr == D3D_OK, "IDirect3DDevice8_CreateTexture failed, hr %#x.\n", hr);
9372 memset(&locked_rect, 0, sizeof(locked_rect));
9373 hr = IDirect3DTexture8_LockRect(texture_bumpmap, 0, &locked_rect, NULL, 0);
9374 ok(SUCCEEDED(hr), "LockRect failed, hr %#x.\n", hr);
9375 *((WORD *)locked_rect.pBits) = 0xff00;
9376 hr = IDirect3DTexture8_UnlockRect(texture_bumpmap, 0);
9377 ok(SUCCEEDED(hr), "UnlockRect failed, hr %#x.\n", hr);
9379 memset(&locked_rect, 0, sizeof(locked_rect));
9380 hr = IDirect3DTexture8_LockRect(texture_red, 0, &locked_rect, NULL, 0);
9381 ok(SUCCEEDED(hr), "LockRect failed, hr %#x.\n", hr);
9382 *((DWORD *)locked_rect.pBits) = 0x00ff0000;
9383 hr = IDirect3DTexture8_UnlockRect(texture_red, 0);
9384 ok(SUCCEEDED(hr), "UnlockRect failed, hr %#x.\n", hr);
9386 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9387 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
9388 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9389 ok(hr == D3D_OK, "Failed to disable lighting, hr %#x.\n", hr);
9391 for (i = 0; i < ARRAY_SIZE(tests); ++i)
9393 const struct test *current_test = &tests[i];
9395 if ((caps.TextureOpCaps & current_test->tex_op_caps) != current_test->tex_op_caps)
9397 skip("Texture operations %#x not supported.\n", current_test->tex_op_caps);
9398 continue;
9401 for (j = 0; j < caps.MaxTextureBlendStages; ++j)
9403 IDirect3DTexture8 *current_texture = NULL;
9405 for (k = 0; !IS_STATE_END(default_stage_state.state[k]); ++k)
9407 hr = IDirect3DDevice8_SetTextureStageState(device, j,
9408 default_stage_state.state[k].name, default_stage_state.state[k].value);
9409 ok(SUCCEEDED(hr), "Test %u: SetTextureStageState failed, hr %#x.\n", i, hr);
9412 if (current_test->stage[j].texture != TEXTURE_INVALID)
9414 const struct texture_stage_state *current_state = current_test->stage[j].state;
9416 switch (current_test->stage[j].texture)
9418 case TEXTURE_RED:
9419 current_texture = texture_red;
9420 break;
9421 case TEXTURE_BUMPMAP:
9422 current_texture = texture_bumpmap;
9423 break;
9424 default:
9425 current_texture = NULL;
9426 break;
9429 for (k = 0; !IS_STATE_END(current_state[k]); ++k)
9431 hr = IDirect3DDevice8_SetTextureStageState(device, j,
9432 current_state[k].name, current_state[k].value);
9433 ok(SUCCEEDED(hr), "Test %u: SetTextureStageState failed, hr %#x.\n", i, hr);
9437 hr = IDirect3DDevice8_SetTexture(device, j, (IDirect3DBaseTexture8 *)current_texture);
9438 ok(SUCCEEDED(hr), "Test %u: SetTexture failed, hr %#x.\n", i, hr);
9441 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
9442 ok(hr == D3D_OK, "Test %u: IDirect3DDevice8_Clear failed, hr %#x.\n", i, hr);
9444 hr = IDirect3DDevice8_BeginScene(device);
9445 ok(SUCCEEDED(hr), "Test %u: BeginScene failed, hr %#x.\n", i, hr);
9446 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
9447 ok(SUCCEEDED(hr), "Test %u: DrawPrimitiveUP failed, hr %#x.\n", i, hr);
9448 hr = IDirect3DDevice8_EndScene(device);
9449 ok(SUCCEEDED(hr), "Test %u: EndScene failed, hr %#x.\n", i, hr);
9451 get_rt_readback(backbuffer, &rb);
9452 color = get_readback_color(&rb, 320, 240);
9453 ok(color_match(color, current_test->expected_color, 1),
9454 "Test %u: Got color 0x%08x, expected 0x%08x.\n", i, color, current_test->expected_color);
9455 release_surface_readback(&rb);
9456 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
9457 ok(SUCCEEDED(hr), "Test %u: Present failed, hr %#x.\n", i, hr);
9460 IDirect3DTexture8_Release(texture_bumpmap);
9461 IDirect3DTexture8_Release(texture_red);
9462 IDirect3DSurface8_Release(backbuffer);
9463 refcount = IDirect3DDevice8_Release(device);
9464 ok(!refcount, "Device has %u references left.\n", refcount);
9465 done:
9466 IDirect3D8_Release(d3d);
9467 DestroyWindow(window);
9470 static void test_color_clamping(void)
9472 static const D3DMATRIX mat =
9474 1.0f, 0.0f, 0.0f, 0.0f,
9475 0.0f, 1.0f, 0.0f, 0.0f,
9476 0.0f, 0.0f, 1.0f, 0.0f,
9477 0.0f, 0.0f, 0.0f, 1.0f,
9478 }}};
9479 static const struct vec3 quad[] =
9481 {-1.0f, -1.0f, 0.1f},
9482 {-1.0f, 1.0f, 0.1f},
9483 { 1.0f, -1.0f, 0.1f},
9484 { 1.0f, 1.0f, 0.1f},
9486 static const DWORD decl[] =
9488 D3DVSD_STREAM(0),
9489 D3DVSD_REG(D3DVSDE_POSITION, D3DVSDT_FLOAT3),
9490 D3DVSD_CONST(0, 1), 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c0, 1.0, 1.0, 1.0, 1.0 */
9491 D3DVSD_END()
9493 static const DWORD vs1_code[] =
9495 0xfffe0101, /* vs_1_1 */
9496 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
9497 0x00000002, 0xd00f0000, 0xa0e40000, 0xa0e40000, /* add oD0, c0, c0 */
9498 0x00000002, 0xd00f0001, 0xa0e40000, 0xa0e40000, /* add oD1, c0, c0 */
9499 0x0000ffff
9501 static const DWORD ps1_code[] =
9503 0xffff0101, /* ps_1_1 */
9504 0x00000051, 0xa00f0000, 0x3e800000, 0x3e800000, 0x3e800000, 0x3e800000, /* def c0, 0.25, 0.25, 0.25, 0.25 */
9505 0x00000002, 0x800f0000, 0x90e40000, 0x90e40001, /* add r0, v0, v1 */
9506 0x00000005, 0x800f0000, 0x80e40000, 0xa0e40000, /* mul r0, r0, c0 */
9507 0x0000ffff
9509 static const struct
9511 DWORD vs_version;
9512 const DWORD *vs;
9513 DWORD ps_version;
9514 const DWORD *ps;
9515 D3DCOLOR expected, broken;
9517 tests[] =
9519 {0, NULL, 0, NULL, 0x00404040},
9520 {0, NULL, D3DPS_VERSION(1, 1), ps1_code, 0x00404040, 0x00808080},
9521 {D3DVS_VERSION(1, 1), vs1_code, 0, NULL, 0x00404040},
9522 {D3DVS_VERSION(1, 1), vs1_code, D3DPS_VERSION(1, 1), ps1_code, 0x007f7f7f},
9524 IDirect3DDevice8 *device;
9525 IDirect3D8 *d3d;
9526 unsigned int i;
9527 ULONG refcount;
9528 D3DCOLOR color;
9529 D3DCAPS8 caps;
9530 DWORD vs, ps;
9531 HWND window;
9532 HRESULT hr;
9534 window = create_window();
9535 d3d = Direct3DCreate8(D3D_SDK_VERSION);
9536 ok(!!d3d, "Failed to create a D3D object.\n");
9537 if (!(device = create_device(d3d, window, window, TRUE)))
9539 skip("Failed to create a D3D device, skipping tests.\n");
9540 IDirect3D8_Release(d3d);
9541 DestroyWindow(window);
9542 return;
9545 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
9546 ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
9548 hr = IDirect3DDevice8_SetTransform(device, D3DTS_WORLD, &mat);
9549 ok(SUCCEEDED(hr), "Failed to set world transform, hr %#x.\n", hr);
9550 hr = IDirect3DDevice8_SetTransform(device, D3DTS_VIEW, &mat);
9551 ok(SUCCEEDED(hr), "Failed to set view transform, hr %#x.\n", hr);
9552 hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, &mat);
9553 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
9554 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, FALSE);
9555 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#x.\n", hr);
9556 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, FALSE);
9557 ok(SUCCEEDED(hr), "Failed to disable Z test, hr %#x.\n", hr);
9558 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
9559 ok(SUCCEEDED(hr), "Failed to disable fog, hr %#x.\n", hr);
9560 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
9561 ok(SUCCEEDED(hr), "Failed to disable stencil test, hr %#x.\n", hr);
9562 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
9563 ok(SUCCEEDED(hr), "Failed to disable culling, hr %#x.\n", hr);
9564 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9565 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
9567 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xff404040);
9568 ok(SUCCEEDED(hr), "Failed to set texture factor, hr %#x.\n", hr);
9569 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
9570 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
9571 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9572 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
9573 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_SPECULAR);
9574 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
9575 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_MODULATE);
9576 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
9577 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TFACTOR);
9578 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
9579 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
9580 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
9582 for (i = 0; i < ARRAY_SIZE(tests); ++i)
9584 if (caps.VertexShaderVersion < tests[i].vs_version
9585 || caps.PixelShaderVersion < tests[i].ps_version)
9587 skip("Vertex / pixel shader version not supported, skipping test %u.\n", i);
9588 continue;
9590 if (tests[i].vs)
9592 hr = IDirect3DDevice8_CreateVertexShader(device, decl, tests[i].vs, &vs, 0);
9593 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x (case %u).\n", hr, i);
9595 else
9597 vs = D3DFVF_XYZ;
9599 if (tests[i].ps)
9601 hr = IDirect3DDevice8_CreatePixelShader(device, tests[i].ps, &ps);
9602 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x (case %u).\n", hr, i);
9604 else
9606 ps = 0;
9609 hr = IDirect3DDevice8_SetVertexShader(device, vs);
9610 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
9611 hr = IDirect3DDevice8_SetPixelShader(device, ps);
9612 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
9614 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0f, 0);
9615 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
9617 hr = IDirect3DDevice8_BeginScene(device);
9618 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9620 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
9621 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9623 hr = IDirect3DDevice8_EndScene(device);
9624 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9626 color = getPixelColor(device, 320, 240);
9627 ok(color_match(color, tests[i].expected, 1) || broken(color_match(color, tests[i].broken, 1)),
9628 "Got unexpected color 0x%08x, case %u.\n", color, i);
9630 if (vs != D3DFVF_XYZ)
9631 IDirect3DDevice8_DeleteVertexShader(device, vs);
9632 if (ps)
9633 IDirect3DDevice8_DeletePixelShader(device, ps);
9636 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
9637 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
9639 refcount = IDirect3DDevice8_Release(device);
9640 ok(!refcount, "Device has %u references left.\n", refcount);
9641 IDirect3D8_Release(d3d);
9642 DestroyWindow(window);
9645 static void test_edge_antialiasing_blending(void)
9647 IDirect3DDevice8 *device;
9648 IDirect3D8 *d3d8;
9649 ULONG refcount;
9650 D3DCOLOR color;
9651 D3DCAPS8 caps;
9652 HWND window;
9653 HRESULT hr;
9655 static const struct
9657 struct vec3 position;
9658 DWORD diffuse;
9660 green_quad[] =
9662 {{-1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0x7f, 0x00, 0xff, 0x00)},
9663 {{-1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0x7f, 0x00, 0xff, 0x00)},
9664 {{ 1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0x7f, 0x00, 0xff, 0x00)},
9665 {{ 1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0x7f, 0x00, 0xff, 0x00)},
9667 static const struct
9669 struct vec3 position;
9670 DWORD diffuse;
9672 red_quad[] =
9674 {{-1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0xcc, 0xff, 0x00, 0x00)},
9675 {{-1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0xcc, 0xff, 0x00, 0x00)},
9676 {{ 1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0xcc, 0xff, 0x00, 0x00)},
9677 {{ 1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0xcc, 0xff, 0x00, 0x00)},
9680 window = create_window();
9681 d3d8 = Direct3DCreate8(D3D_SDK_VERSION);
9682 ok(!!d3d8, "Failed to create a D3D object.\n");
9683 if (!(device = create_device(d3d8, window, window, TRUE)))
9685 skip("Failed to create a D3D device.\n");
9686 IDirect3D8_Release(d3d8);
9687 DestroyWindow(window);
9688 return;
9691 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
9692 ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
9693 trace("Edge antialiasing support: %#x.\n", caps.RasterCaps & D3DPRASTERCAPS_ANTIALIASEDGES);
9695 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, FALSE);
9696 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#x.\n", hr);
9697 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, FALSE);
9698 ok(SUCCEEDED(hr), "Failed to disable Z test, hr %#x.\n", hr);
9699 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9700 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
9702 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
9703 ok(SUCCEEDED(hr), "Failed to enable blending, hr %#x.\n", hr);
9704 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_BLENDOP, D3DBLENDOP_ADD);
9705 ok(SUCCEEDED(hr), "Failed to set blend op, hr %#x.\n", hr);
9706 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
9707 ok(SUCCEEDED(hr), "Failed to set src blend, hr %#x.\n", hr);
9708 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_DESTALPHA);
9709 ok(SUCCEEDED(hr), "Failed to set dest blend, hr %#x.\n", hr);
9711 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9712 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
9713 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9714 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
9715 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
9716 ok(SUCCEEDED(hr), "Failed to set alpha op, hr %#x.\n", hr);
9717 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
9718 ok(SUCCEEDED(hr), "Failed to set alpha arg, hr %#x.\n", hr);
9720 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9721 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
9723 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xccff0000, 0.0f, 0);
9724 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
9725 hr = IDirect3DDevice8_BeginScene(device);
9726 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9727 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, green_quad, sizeof(*green_quad));
9728 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9729 hr = IDirect3DDevice8_EndScene(device);
9730 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9731 color = getPixelColor(device, 320, 240);
9732 ok(color_match(color, 0x00cc7f00, 1), "Got unexpected color 0x%08x.\n", color);
9734 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x7f00ff00, 0.0f, 0);
9735 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
9736 hr = IDirect3DDevice8_BeginScene(device);
9737 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9738 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, red_quad, sizeof(*red_quad));
9739 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9740 hr = IDirect3DDevice8_EndScene(device);
9741 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9742 color = getPixelColor(device, 320, 240);
9743 ok(color_match(color, 0x00cc7f00, 1), "Got unexpected color 0x%08x.\n", color);
9745 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
9746 ok(SUCCEEDED(hr), "Failed to disable blending, hr %#x.\n", hr);
9748 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xccff0000, 0.0f, 0);
9749 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
9750 hr = IDirect3DDevice8_BeginScene(device);
9751 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9752 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, green_quad, sizeof(*green_quad));
9753 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9754 hr = IDirect3DDevice8_EndScene(device);
9755 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9756 color = getPixelColor(device, 320, 240);
9757 ok(color_match(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
9759 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x7f00ff00, 0.0f, 0);
9760 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
9761 hr = IDirect3DDevice8_BeginScene(device);
9762 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9763 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, red_quad, sizeof(*red_quad));
9764 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9765 hr = IDirect3DDevice8_EndScene(device);
9766 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9767 color = getPixelColor(device, 320, 240);
9768 ok(color_match(color, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color);
9770 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_EDGEANTIALIAS, TRUE);
9771 ok(SUCCEEDED(hr), "Failed to enable edge antialiasing, hr %#x.\n", hr);
9773 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xccff0000, 0.0f, 0);
9774 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
9775 hr = IDirect3DDevice8_BeginScene(device);
9776 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9777 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, green_quad, sizeof(*green_quad));
9778 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9779 hr = IDirect3DDevice8_EndScene(device);
9780 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9781 color = getPixelColor(device, 320, 240);
9782 ok(color_match(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
9784 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x7f00ff00, 0.0f, 0);
9785 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
9786 hr = IDirect3DDevice8_BeginScene(device);
9787 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9788 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, red_quad, sizeof(*red_quad));
9789 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9790 hr = IDirect3DDevice8_EndScene(device);
9791 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9792 color = getPixelColor(device, 320, 240);
9793 ok(color_match(color, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color);
9795 refcount = IDirect3DDevice8_Release(device);
9796 ok(!refcount, "Device has %u references left.\n", refcount);
9797 IDirect3D8_Release(d3d8);
9798 DestroyWindow(window);
9801 /* This test shows that 0xffff is valid index in D3D8. */
9802 static void test_max_index16(void)
9804 static const struct vertex
9806 struct vec3 position;
9807 DWORD diffuse;
9809 green_quad[] =
9811 {{-1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
9812 {{-1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
9813 {{ 1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
9814 {{ 1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
9816 static const unsigned short indices[] = {0, 1, 2, 0xffff};
9817 static const unsigned int vertex_count = 0xffff + 1;
9819 D3DADAPTER_IDENTIFIER8 identifier;
9820 IDirect3DVertexBuffer8 *vb;
9821 IDirect3DIndexBuffer8 *ib;
9822 IDirect3DDevice8 *device;
9823 struct vertex *vb_data;
9824 IDirect3D8 *d3d8;
9825 ULONG refcount;
9826 D3DCOLOR color;
9827 D3DCAPS8 caps;
9828 HWND window;
9829 BYTE *data;
9830 HRESULT hr;
9831 BOOL warp;
9833 window = create_window();
9834 d3d8 = Direct3DCreate8(D3D_SDK_VERSION);
9835 ok(!!d3d8, "Failed to create a D3D object.\n");
9837 hr = IDirect3D8_GetAdapterIdentifier(d3d8, D3DADAPTER_DEFAULT, 0, &identifier);
9838 ok(SUCCEEDED(hr), "Failed to get adapter identifier, hr %#x.\n", hr);
9839 warp = adapter_is_warp(&identifier);
9841 if (!(device = create_device(d3d8, window, window, TRUE)))
9843 skip("Failed to create a D3D device.\n");
9844 IDirect3D8_Release(d3d8);
9845 DestroyWindow(window);
9846 return;
9849 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
9850 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
9851 if (caps.MaxVertexIndex < 0xffff)
9853 skip("Max vertex index is lower than 0xffff (%#x).\n", caps.MaxVertexIndex);
9854 IDirect3DDevice8_Release(device);
9855 IDirect3D8_Release(d3d8);
9856 DestroyWindow(window);
9857 return;
9860 hr = IDirect3DDevice8_CreateVertexBuffer(device, vertex_count * sizeof(*green_quad), 0,
9861 D3DFVF_XYZ | D3DFVF_DIFFUSE, D3DPOOL_MANAGED, &vb);
9862 ok(SUCCEEDED(hr), "Failed to create vertex buffer, hr %#x.\n", hr);
9864 hr = IDirect3DDevice8_CreateIndexBuffer(device, sizeof(indices), 0,
9865 D3DFMT_INDEX16, D3DPOOL_MANAGED, &ib);
9866 ok(SUCCEEDED(hr), "Failed to create index buffer, hr %#x.\n", hr);
9868 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, FALSE);
9869 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#x.\n", hr);
9870 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, FALSE);
9871 ok(SUCCEEDED(hr), "Failed to disable Z test, hr %#x.\n", hr);
9872 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9873 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
9875 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9876 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
9878 hr = IDirect3DVertexBuffer8_Lock(vb, 0, sizeof(green_quad), (BYTE **)&vb_data, 0);
9879 ok(hr == D3D_OK, "Failed to lock vertex buffer, hr %#x.\n", hr);
9880 vb_data[0] = green_quad[0];
9881 vb_data[1] = green_quad[1];
9882 vb_data[2] = green_quad[2];
9883 vb_data[0xffff] = green_quad[3];
9884 hr = IDirect3DVertexBuffer8_Unlock(vb);
9885 ok(hr == D3D_OK, "Failed to unlock vertex buffer, hr %#x.\n", hr);
9887 hr = IDirect3DIndexBuffer8_Lock(ib, 0, sizeof(indices), &data, 0);
9888 ok(hr == D3D_OK, "Failed to lock index buffer, hr %#x.\n", hr);
9889 memcpy(data, indices, sizeof(indices));
9890 hr = IDirect3DIndexBuffer8_Unlock(ib);
9891 ok(hr == D3D_OK, "Failed to unlock index buffer, hr %#x.\n", hr);
9893 hr = IDirect3DDevice8_SetIndices(device, ib, 0);
9894 ok(hr == D3D_OK, "Failed to set index buffer, hr %#x.\n", hr);
9895 hr = IDirect3DDevice8_SetStreamSource(device, 0, vb, sizeof(struct vertex));
9896 ok(hr == D3D_OK, "Failed to set stream source, hr %#x.\n", hr);
9898 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
9899 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
9900 hr = IDirect3DDevice8_BeginScene(device);
9901 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9902 hr = IDirect3DDevice8_DrawIndexedPrimitive(device, D3DPT_TRIANGLESTRIP, 0, vertex_count, 0, 2);
9903 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9904 hr = IDirect3DDevice8_EndScene(device);
9905 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9906 color = getPixelColor(device, 20, 20);
9907 ok(color_match(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
9908 color = getPixelColor(device, 320, 240);
9909 ok(color_match(color, 0x0000ff00, 1) || broken(warp), "Got unexpected color 0x%08x.\n", color);
9910 color = getPixelColor(device, 620, 460);
9911 ok(color_match(color, 0x0000ff00, 1) || broken(warp), "Got unexpected color 0x%08x.\n", color);
9913 IDirect3DIndexBuffer8_Release(ib);
9914 IDirect3DVertexBuffer8_Release(vb);
9915 refcount = IDirect3DDevice8_Release(device);
9916 ok(!refcount, "Device has %u references left.\n", refcount);
9917 IDirect3D8_Release(d3d8);
9918 DestroyWindow(window);
9921 static void test_backbuffer_resize(void)
9923 D3DPRESENT_PARAMETERS present_parameters = {0};
9924 IDirect3DSurface8 *backbuffer;
9925 IDirect3DDevice8 *device;
9926 IDirect3D8 *d3d;
9927 D3DCOLOR color;
9928 ULONG refcount;
9929 HWND window;
9930 HRESULT hr;
9932 static const struct
9934 struct vec3 position;
9935 DWORD diffuse;
9937 quad[] =
9939 {{-1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
9940 {{-1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
9941 {{ 1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
9942 {{ 1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
9945 window = create_window();
9946 d3d = Direct3DCreate8(D3D_SDK_VERSION);
9947 ok(!!d3d, "Failed to create a D3D object.\n");
9948 if (!(device = create_device(d3d, window, window, TRUE)))
9950 skip("Failed to create a D3D device.\n");
9951 goto done;
9954 /* Wine d3d8 implementation had a bug which was triggered by a
9955 * SetRenderTarget() call with an unreferenced surface. */
9956 hr = IDirect3DDevice8_GetBackBuffer(device, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9957 ok(SUCCEEDED(hr), "Failed to get backbuffer, hr %#x.\n", hr);
9958 refcount = IDirect3DSurface8_Release(backbuffer);
9959 ok(!refcount, "Surface has %u references left.\n", refcount);
9960 hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, NULL);
9961 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
9962 hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, NULL);
9963 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
9965 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 1.0f, 0);
9966 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
9967 color = getPixelColor(device, 1, 1);
9968 ok(color == 0x00ff0000, "Got unexpected color 0x%08x.\n", color);
9970 present_parameters.BackBufferWidth = 800;
9971 present_parameters.BackBufferHeight = 600;
9972 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
9973 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
9974 present_parameters.hDeviceWindow = NULL;
9975 present_parameters.Windowed = TRUE;
9976 present_parameters.EnableAutoDepthStencil = TRUE;
9977 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
9978 hr = IDirect3DDevice8_Reset(device, &present_parameters);
9979 ok(SUCCEEDED(hr), "Failed to reset, hr %#x.\n", hr);
9981 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, FALSE);
9982 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#x.\n", hr);
9983 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, FALSE);
9984 ok(SUCCEEDED(hr), "Failed to disable Z test, hr %#x.\n", hr);
9985 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9986 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
9987 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9988 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
9990 hr = IDirect3DDevice8_GetBackBuffer(device, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9991 ok(SUCCEEDED(hr), "Failed to get backbuffer, hr %#x.\n", hr);
9992 hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, NULL);
9993 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
9994 IDirect3DSurface8_Release(backbuffer);
9996 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 1.0f, 0);
9997 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
9998 color = getPixelColor(device, 1, 1);
9999 ok(color == 0x00ffff00, "Got unexpected color 0x%08x.\n", color);
10000 color = getPixelColor(device, 700, 500);
10001 ok(color == 0x00ffff00, "Got unexpected color 0x%08x.\n", color);
10003 hr = IDirect3DDevice8_BeginScene(device);
10004 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
10005 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10006 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10007 hr = IDirect3DDevice8_EndScene(device);
10008 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
10009 color = getPixelColor(device, 1, 1);
10010 ok(color == 0x0000ff00, "Got unexpected color 0x%08x.\n", color);
10011 color = getPixelColor(device, 700, 500);
10012 ok(color == 0x0000ff00, "Got unexpected color 0x%08x.\n", color);
10014 refcount = IDirect3DDevice8_Release(device);
10015 ok(!refcount, "Device has %u references left.\n", refcount);
10016 done:
10017 IDirect3D8_Release(d3d);
10018 DestroyWindow(window);
10021 static void test_drawindexedprimitiveup(void)
10023 static const struct vertex
10025 struct vec3 position;
10026 DWORD diffuse;
10028 quad[] =
10030 {{-1.0f, -1.0f, 0.1f}, 0xff00ff00},
10031 {{-1.0f, 1.0f, 0.1f}, 0xff0000ff},
10032 {{ 1.0f, -1.0f, 0.1f}, 0xffff0000},
10033 {{ 1.0f, 1.0f, 0.1f}, 0xff0000ff},
10035 {{-1.0f, -1.0f, 0.1f}, 0xff0000ff},
10036 {{-1.0f, 1.0f, 0.1f}, 0xff00ff00},
10037 {{ 1.0f, -1.0f, 0.1f}, 0xffff0000},
10038 {{ 1.0f, 1.0f, 0.1f}, 0xff00ff00},
10040 static const unsigned short indices[] = {0, 1, 2, 3, 4, 5, 6, 7};
10041 IDirect3DDevice8 *device;
10042 IDirect3D8 *d3d;
10043 ULONG refcount;
10044 D3DCOLOR color;
10045 HWND window;
10046 HRESULT hr;
10048 window = create_window();
10049 d3d = Direct3DCreate8(D3D_SDK_VERSION);
10050 ok(!!d3d, "Failed to create a D3D object.\n");
10052 if (!(device = create_device(d3d, window, window, TRUE)))
10054 skip("Failed to create a D3D device.\n");
10055 IDirect3D8_Release(d3d);
10056 DestroyWindow(window);
10057 return;
10060 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, FALSE);
10061 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#x.\n", hr);
10062 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, FALSE);
10063 ok(SUCCEEDED(hr), "Failed to disable Z test, hr %#x.\n", hr);
10064 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10065 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
10067 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
10068 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
10069 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
10070 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
10071 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
10072 ok(SUCCEEDED(hr), "Failed to set alpha op, hr %#x.\n", hr);
10073 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
10074 ok(SUCCEEDED(hr), "Failed to set alpha arg, hr %#x.\n", hr);
10076 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10077 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
10079 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
10080 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
10082 hr = IDirect3DDevice8_BeginScene(device);
10083 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
10084 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 4, 4, 2, indices + 4, D3DFMT_INDEX16, quad, sizeof(*quad));
10085 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10086 hr = IDirect3DDevice8_EndScene(device);
10087 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
10089 color = getPixelColor(device, 160, 120);
10090 ok(color_match(color, 0x0040bf00, 1), "Got unexpected color 0x%08x.\n", color);
10091 color = getPixelColor(device, 480, 120);
10092 ok(color_match(color, 0x0040bf00, 1), "Got unexpected color 0x%08x.\n", color);
10093 color = getPixelColor(device, 160, 360);
10094 ok(color_match(color, 0x00404080, 1), "Got unexpected color 0x%08x.\n", color);
10095 color = getPixelColor(device, 480, 360);
10096 ok(color_match(color, 0x00bf4000, 1), "Got unexpected color 0x%08x.\n", color);
10098 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
10099 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
10101 hr = IDirect3DDevice8_BeginScene(device);
10102 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
10103 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 0, 4, 2, indices, D3DFMT_INDEX16, quad, sizeof(*quad));
10104 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10105 hr = IDirect3DDevice8_EndScene(device);
10106 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
10108 color = getPixelColor(device, 160, 120);
10109 ok(color_match(color, 0x004000bf, 1), "Got unexpected color 0x%08x.\n", color);
10110 color = getPixelColor(device, 480, 120);
10111 ok(color_match(color, 0x004000bf, 1), "Got unexpected color 0x%08x.\n", color);
10112 color = getPixelColor(device, 160, 360);
10113 ok(color_match(color, 0x00408040, 1), "Got unexpected color 0x%08x.\n", color);
10114 color = getPixelColor(device, 480, 360);
10115 ok(color_match(color, 0x00bf0040, 1), "Got unexpected color 0x%08x.\n", color);
10117 refcount = IDirect3DDevice8_Release(device);
10118 ok(!refcount, "Device has %u references left.\n", refcount);
10119 IDirect3D8_Release(d3d);
10120 DestroyWindow(window);
10123 static void test_map_synchronisation(void)
10125 LARGE_INTEGER frequency, diff, ts[3];
10126 unsigned int i, j, tri_count, size;
10127 D3DADAPTER_IDENTIFIER8 identifier;
10128 IDirect3DVertexBuffer8 *buffer;
10129 IDirect3DDevice8 *device;
10130 BOOL unsynchronised, ret;
10131 IDirect3D8 *d3d;
10132 D3DCOLOR colour;
10133 ULONG refcount;
10134 D3DCAPS8 caps;
10135 HWND window;
10136 HRESULT hr;
10138 static const struct
10140 unsigned int flags;
10141 BOOL unsynchronised;
10143 tests[] =
10145 {0, FALSE},
10146 {D3DLOCK_NOOVERWRITE, TRUE},
10147 {D3DLOCK_DISCARD, FALSE},
10148 {D3DLOCK_NOOVERWRITE | D3DLOCK_DISCARD, TRUE},
10151 static const struct quad
10153 struct
10155 struct vec3 position;
10156 DWORD diffuse;
10157 } strip[4];
10159 quad1 =
10162 {{-1.0f, -1.0f, 0.0f}, 0xffff0000},
10163 {{-1.0f, 1.0f, 0.0f}, 0xff00ff00},
10164 {{ 1.0f, -1.0f, 0.0f}, 0xff0000ff},
10165 {{ 1.0f, 1.0f, 0.0f}, 0xffffffff},
10168 quad2 =
10171 {{-1.0f, -1.0f, 0.0f}, 0xffffff00},
10172 {{-1.0f, 1.0f, 0.0f}, 0xffffff00},
10173 {{ 1.0f, -1.0f, 0.0f}, 0xffffff00},
10174 {{ 1.0f, 1.0f, 0.0f}, 0xffffff00},
10177 struct quad *quads;
10179 window = create_window();
10180 ok(!!window, "Failed to create a window.\n");
10182 d3d = Direct3DCreate8(D3D_SDK_VERSION);
10183 ok(!!d3d, "Failed to create a D3D object.\n");
10184 if (!(device = create_device(d3d, window, window, TRUE)))
10186 skip("Failed to create a D3D device, skipping tests.\n");
10187 IDirect3D8_Release(d3d);
10188 DestroyWindow(window);
10189 return;
10192 hr = IDirect3D8_GetAdapterIdentifier(d3d, D3DADAPTER_DEFAULT, 0, &identifier);
10193 ok(SUCCEEDED(hr), "Failed to get adapter identifier, hr %#x.\n", hr);
10194 /* Maps are always synchronised on WARP. */
10195 if (adapter_is_warp(&identifier))
10197 skip("Running on WARP, skipping test.\n");
10198 goto done;
10201 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
10202 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
10204 tri_count = 0x1000;
10205 if (tri_count > caps.MaxPrimitiveCount)
10207 skip("Device supports only %u primitives, skipping test.\n", caps.MaxPrimitiveCount);
10208 goto done;
10210 size = (tri_count + 2) * sizeof(*quad1.strip);
10212 ret = QueryPerformanceFrequency(&frequency);
10213 ok(ret, "Failed to get performance counter frequency.\n");
10215 hr = IDirect3DDevice8_CreateVertexBuffer(device, size,
10216 D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, 0, D3DPOOL_DEFAULT, &buffer);
10217 ok(SUCCEEDED(hr), "Failed to create vertex buffer, hr %#x.\n", hr);
10218 hr = IDirect3DVertexBuffer8_Lock(buffer, 0, size, (BYTE **)&quads, D3DLOCK_DISCARD);
10219 ok(SUCCEEDED(hr), "Failed to lock vertex buffer, hr %#x.\n", hr);
10220 for (j = 0; j < size / sizeof(*quads); ++j)
10222 quads[j] = quad1;
10224 hr = IDirect3DVertexBuffer8_Unlock(buffer);
10225 ok(SUCCEEDED(hr), "Failed to unlock vertex buffer, hr %#x.\n", hr);
10227 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10228 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10229 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10230 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
10231 hr = IDirect3DDevice8_SetStreamSource(device, 0, buffer, sizeof(*quads->strip));
10232 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
10234 /* Initial draw to initialise states, compile shaders, etc. */
10235 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0f, 0);
10236 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
10237 hr = IDirect3DDevice8_BeginScene(device);
10238 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
10239 hr = IDirect3DDevice8_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, tri_count);
10240 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10241 hr = IDirect3DDevice8_EndScene(device);
10242 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
10243 /* Read the result to ensure the GPU has finished drawing. */
10244 colour = getPixelColor(device, 320, 240);
10246 /* Time drawing tri_count triangles. */
10247 ret = QueryPerformanceCounter(&ts[0]);
10248 ok(ret, "Failed to read performance counter.\n");
10249 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0f, 0);
10250 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
10251 hr = IDirect3DDevice8_BeginScene(device);
10252 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
10253 hr = IDirect3DDevice8_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, tri_count);
10254 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10255 hr = IDirect3DDevice8_EndScene(device);
10256 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
10257 colour = getPixelColor(device, 320, 240);
10258 /* Time drawing a single triangle. */
10259 ret = QueryPerformanceCounter(&ts[1]);
10260 ok(ret, "Failed to read performance counter.\n");
10261 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0f, 0);
10262 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
10263 hr = IDirect3DDevice8_BeginScene(device);
10264 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
10265 hr = IDirect3DDevice8_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 1);
10266 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10267 hr = IDirect3DDevice8_EndScene(device);
10268 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
10269 colour = getPixelColor(device, 320, 240);
10270 ret = QueryPerformanceCounter(&ts[2]);
10271 ok(ret, "Failed to read performance counter.\n");
10273 IDirect3DVertexBuffer8_Release(buffer);
10275 /* Estimate the number of triangles we can draw in 100ms. */
10276 diff.QuadPart = ts[1].QuadPart - ts[0].QuadPart + ts[1].QuadPart - ts[2].QuadPart;
10277 tri_count = (tri_count * frequency.QuadPart) / (diff.QuadPart * 10);
10278 tri_count = ((tri_count + 2 + 3) & ~3) - 2;
10279 if (tri_count > caps.MaxPrimitiveCount)
10281 skip("Would need to draw %u triangles, but the device only supports %u primitives.\n",
10282 tri_count, caps.MaxPrimitiveCount);
10283 goto done;
10285 size = (tri_count + 2) * sizeof(*quad1.strip);
10287 for (i = 0; i < ARRAY_SIZE(tests); ++i)
10289 hr = IDirect3DDevice8_CreateVertexBuffer(device, size,
10290 D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, 0, D3DPOOL_DEFAULT, &buffer);
10291 ok(SUCCEEDED(hr), "Failed to create vertex buffer, hr %#x.\n", hr);
10292 hr = IDirect3DVertexBuffer8_Lock(buffer, 0, size, (BYTE **)&quads, D3DLOCK_DISCARD);
10293 ok(SUCCEEDED(hr), "Failed to lock vertex buffer, hr %#x.\n", hr);
10294 for (j = 0; j < size / sizeof(*quads); ++j)
10296 quads[j] = quad1;
10298 hr = IDirect3DVertexBuffer8_Unlock(buffer);
10299 ok(SUCCEEDED(hr), "Failed to unlock vertex buffer, hr %#x.\n", hr);
10301 hr = IDirect3DDevice8_SetStreamSource(device, 0, buffer, sizeof(*quads->strip));
10302 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
10304 /* Start a draw operation. */
10305 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0f, 0);
10306 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
10307 hr = IDirect3DDevice8_BeginScene(device);
10308 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
10309 hr = IDirect3DDevice8_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, tri_count);
10310 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10311 hr = IDirect3DDevice8_EndScene(device);
10312 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
10314 /* Map the last quad while the draw is in progress. */
10315 hr = IDirect3DVertexBuffer8_Lock(buffer, size - sizeof(quad2),
10316 sizeof(quad2), (BYTE **)&quads, tests[i].flags);
10317 ok(SUCCEEDED(hr), "Failed to lock vertex buffer, hr %#x.\n", hr);
10318 *quads = quad2;
10319 hr = IDirect3DVertexBuffer8_Unlock(buffer);
10320 ok(SUCCEEDED(hr), "Failed to unlock vertex buffer, hr %#x.\n", hr);
10322 colour = getPixelColor(device, 320, 240);
10323 unsynchronised = color_match(colour, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 1);
10324 ok(tests[i].unsynchronised == unsynchronised, "Expected %s map for flags %#x.\n",
10325 tests[i].unsynchronised ? "unsynchronised" : "synchronised", tests[i].flags);
10327 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
10328 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
10330 IDirect3DVertexBuffer8_Release(buffer);
10333 done:
10334 refcount = IDirect3DDevice8_Release(device);
10335 ok(!refcount, "Device has %u references left.\n", refcount);
10336 IDirect3D8_Release(d3d);
10337 DestroyWindow(window);
10340 static void test_viewport(void)
10342 static const struct
10344 D3DVIEWPORT8 vp;
10345 RECT expected_rect;
10346 const char *message;
10348 tests[] =
10350 {{ 0, 0, 640, 480}, { 0, 120, 479, 359}, "Viewport (0, 0) - (640, 480)"},
10351 {{ 0, 0, 320, 240}, { 0, 60, 239, 179}, "Viewport (0, 0) - (320, 240)"},
10352 {{ 0, 0, 1280, 960}, { 0, 240, 639, 479}, "Viewport (0, 0) - (1280, 960)"},
10353 {{ 0, 0, 2000, 1600}, {-10, -10, -10, -10}, "Viewport (0, 0) - (2000, 1600)"},
10354 {{100, 100, 640, 480}, {100, 220, 579, 459}, "Viewport (100, 100) - (640, 480)"},
10355 {{ 0, 0, 8192, 8192}, {-10, -10, -10, -10}, "Viewport (0, 0) - (8192, 8192)"},
10357 static const struct vec3 quad[] =
10359 {-1.5f, -0.5f, 0.1f},
10360 {-1.5f, 0.5f, 0.1f},
10361 { 0.5f, -0.5f, 0.1f},
10362 { 0.5f, 0.5f, 0.1f},
10364 static const struct vec2 rt_sizes[] =
10366 {640, 480}, {1280, 960}, {320, 240}, {800, 600},
10368 struct surface_readback rb;
10369 IDirect3DDevice8 *device;
10370 IDirect3DSurface8 *rt;
10371 unsigned int i, j;
10372 IDirect3D8 *d3d;
10373 ULONG refcount;
10374 HWND window;
10375 HRESULT hr;
10377 window = create_window();
10378 d3d = Direct3DCreate8(D3D_SDK_VERSION);
10379 ok(!!d3d, "Failed to create a D3D object.\n");
10380 if (!(device = create_device(d3d, window, window, TRUE)))
10382 skip("Failed to create a D3D device, skipping tests.\n");
10383 goto done;
10386 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
10387 ok(SUCCEEDED(hr), "Failed to disable depth test, hr %#x.\n", hr);
10388 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10389 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
10391 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ);
10392 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
10394 /* This crashes on Windows. */
10395 /* hr = IDirect3DDevice8_SetViewport(device, NULL); */
10397 for (i = 0; i < ARRAY_SIZE(rt_sizes); ++i)
10399 if (i)
10401 hr = IDirect3DDevice8_CreateRenderTarget(device, rt_sizes[i].x, rt_sizes[i].y,
10402 D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, TRUE, &rt);
10403 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x (i %u).\n", hr, i);
10404 hr = IDirect3DDevice8_SetRenderTarget(device, rt, NULL);
10405 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x (i %u).\n", hr, i);
10407 else
10409 hr = IDirect3DDevice8_GetBackBuffer(device, 0, D3DBACKBUFFER_TYPE_MONO, &rt);
10410 ok(SUCCEEDED(hr), "Failed to get backbuffer, hr %#x.\n", hr);
10413 for (j = 0; j < ARRAY_SIZE(tests); ++j)
10415 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 1.0f, 0);
10416 ok(SUCCEEDED(hr), "Failed to clear, hr %#x (i %u, j %u).\n", hr, i, j);
10418 hr = IDirect3DDevice8_SetViewport(device, &tests[j].vp);
10419 if (tests[j].vp.X + tests[j].vp.Width > rt_sizes[i].x
10420 || tests[j].vp.Y + tests[j].vp.Height > rt_sizes[i].y)
10422 ok(hr == D3DERR_INVALIDCALL,
10423 "Setting the viewport returned unexpected hr %#x (i %u, j %u).\n", hr, i, j);
10424 continue;
10426 else
10428 ok(SUCCEEDED(hr), "Failed to set the viewport, hr %#x (i %u, j %u).\n", hr, i, j);
10431 hr = IDirect3DDevice8_BeginScene(device);
10432 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x (i %u, j %u).\n", hr, i, j);
10433 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
10434 ok(SUCCEEDED(hr), "Got unexpected hr %#x (i %u, j %u).\n", hr, i, j);
10435 hr = IDirect3DDevice8_EndScene(device);
10436 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x (i %u, j %u).\n", hr, i, j);
10438 get_rt_readback(rt, &rb);
10439 check_rect(&rb, tests[j].expected_rect, tests[j].message);
10440 release_surface_readback(&rb);
10443 IDirect3DSurface8_Release(rt);
10446 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
10447 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
10449 refcount = IDirect3DDevice8_Release(device);
10450 ok(!refcount, "Device has %u references left.\n", refcount);
10451 done:
10452 IDirect3D8_Release(d3d);
10453 DestroyWindow(window);
10456 static void test_color_vertex(void)
10458 IDirect3DDevice8 *device;
10459 D3DMATERIAL8 material;
10460 IDirect3D8 *d3d;
10461 D3DCOLOR colour;
10462 unsigned int i;
10463 ULONG refcount;
10464 HWND window;
10465 HRESULT hr;
10467 /* The idea here is to set up ambient light parameters in a way that the
10468 * ambient colour from the material is just passed through. The emissive
10469 * colour is just passed through anyway. The sum of ambient + emissive
10470 * should allow deduction of where the material colour came from.
10472 * Note that in cases without a D3DFVF_DIFFUSE flag the first colour value
10473 * in the struct will be fed into the specular vertex colour slot. */
10474 static const struct
10476 DWORD fvf, color_vertex, ambient, emissive, result;
10478 tests[] =
10480 {D3DFVF_DIFFUSE | D3DFVF_SPECULAR, FALSE, D3DMCS_COLOR1, D3DMCS_COLOR2, 0x000000c0},
10482 {D3DFVF_DIFFUSE | D3DFVF_SPECULAR, TRUE, D3DMCS_COLOR1, D3DMCS_COLOR2, 0x00ffff00},
10483 {D3DFVF_DIFFUSE | D3DFVF_SPECULAR, TRUE, D3DMCS_MATERIAL, D3DMCS_COLOR2, 0x0000ff80},
10484 {D3DFVF_DIFFUSE | D3DFVF_SPECULAR, TRUE, D3DMCS_COLOR1, D3DMCS_MATERIAL, 0x00ff0040},
10485 {D3DFVF_DIFFUSE | D3DFVF_SPECULAR, TRUE, D3DMCS_COLOR1, D3DMCS_COLOR1, 0x00ff0000},
10486 {D3DFVF_DIFFUSE | D3DFVF_SPECULAR, TRUE, D3DMCS_COLOR2, D3DMCS_COLOR2, 0x0000ff00},
10488 {D3DFVF_SPECULAR, TRUE, D3DMCS_COLOR1, D3DMCS_COLOR2, 0x00ff0080},
10489 {D3DFVF_SPECULAR, TRUE, D3DMCS_COLOR1, D3DMCS_MATERIAL, 0x000000c0},
10490 {D3DFVF_SPECULAR, TRUE, D3DMCS_MATERIAL, D3DMCS_COLOR2, 0x00ff0080},
10491 {D3DFVF_DIFFUSE, TRUE, D3DMCS_COLOR1, D3DMCS_COLOR2, 0x00ff0040},
10492 {D3DFVF_DIFFUSE, TRUE, D3DMCS_COLOR1, D3DMCS_MATERIAL, 0x00ff0040},
10493 {D3DFVF_DIFFUSE, TRUE, D3DMCS_COLOR2, D3DMCS_MATERIAL, 0x000000c0},
10495 {0, TRUE, D3DMCS_COLOR1, D3DMCS_COLOR2, 0x000000c0},
10497 static const struct
10499 struct vec3 position;
10500 DWORD diffuse;
10501 DWORD specular;
10503 quad[] =
10505 {{-1.0f, -1.0f, 0.0f}, 0xffff0000, 0xff00ff00},
10506 {{-1.0f, 1.0f, 0.0f}, 0xffff0000, 0xff00ff00},
10507 {{ 1.0f, -1.0f, 0.0f}, 0xffff0000, 0xff00ff00},
10508 {{ 1.0f, 1.0f, 0.0f}, 0xffff0000, 0xff00ff00},
10511 window = create_window();
10512 ok(!!window, "Failed to create a window.\n");
10514 d3d = Direct3DCreate8(D3D_SDK_VERSION);
10515 ok(!!d3d, "Failed to create a D3D object.\n");
10516 if (!(device = create_device(d3d, window, window, TRUE)))
10518 skip("Failed to create a D3D device, skipping tests.\n");
10519 IDirect3D8_Release(d3d);
10520 DestroyWindow(window);
10521 return;
10524 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, TRUE);
10525 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10526 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_AMBIENT, 0xffffffff);
10527 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10529 memset(&material, 0, sizeof(material));
10530 material.Ambient.b = 0.5f;
10531 material.Emissive.b = 0.25f;
10532 hr = IDirect3DDevice8_SetMaterial(device, &material);
10533 ok(SUCCEEDED(hr), "Failed to set material, hr %#x\n", hr);
10535 for (i = 0; i < ARRAY_SIZE(tests); ++i)
10537 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_COLORVERTEX, tests[i].color_vertex);
10538 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10539 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_AMBIENTMATERIALSOURCE, tests[i].ambient);
10540 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10541 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_EMISSIVEMATERIALSOURCE, tests[i].emissive);
10542 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10543 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | tests[i].fvf);
10544 ok(SUCCEEDED(hr), "Failed to set vertex format, hr %#x.\n", hr);
10546 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x77777777, 0.0f, 0);
10547 ok(SUCCEEDED(hr), "Failed to clear depth/stencil, hr %#x.\n", hr);
10549 hr = IDirect3DDevice8_BeginScene(device);
10550 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
10551 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10552 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10553 hr = IDirect3DDevice8_EndScene(device);
10554 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
10556 colour = getPixelColor(device, 320, 240);
10557 ok(color_match(colour, tests[i].result, 1),
10558 "Expected colour 0x%08x for test %u, got 0x%08x.\n",
10559 tests[i].result, i, colour);
10562 refcount = IDirect3DDevice8_Release(device);
10563 ok(!refcount, "Device has %u references left.\n", refcount);
10564 IDirect3D8_Release(d3d);
10565 DestroyWindow(window);
10568 static void test_sysmem_draw(void)
10570 IDirect3DVertexBuffer8 *vb, *vb_s0, *vb_s1, *dst_vb, *get_vb;
10571 D3DPRESENT_PARAMETERS present_parameters = {0};
10572 IDirect3DTexture8 *texture;
10573 IDirect3DIndexBuffer8 *ib;
10574 IDirect3DDevice8 *device;
10575 unsigned int i, stride;
10576 struct vec4 *dst_data;
10577 D3DLOCKED_RECT lr;
10578 IDirect3D8 *d3d;
10579 D3DCOLOR colour;
10580 ULONG refcount;
10581 HWND window;
10582 HRESULT hr;
10583 BYTE *data;
10584 DWORD vs;
10586 static const DWORD texture_data[4] = {0xffff0000, 0xff00ff00, 0xff0000ff, 0xffffffff};
10587 static const DWORD decl[] =
10589 D3DVSD_STREAM(0),
10590 D3DVSD_REG(D3DVSDE_POSITION, D3DVSDT_FLOAT3),
10591 D3DVSD_STREAM(1),
10592 D3DVSD_REG(D3DVSDE_DIFFUSE, D3DVSDT_D3DCOLOR),
10593 D3DVSD_END()
10595 static const struct
10597 struct vec3 position;
10598 DWORD diffuse;
10600 quad[] =
10602 {{-0.5f, -0.5f, 0.0f}, 0xffff0000},
10603 {{-0.5f, 0.5f, 0.0f}, 0xff00ff00},
10604 {{ 0.5f, -0.5f, 0.0f}, 0xff0000ff},
10605 {{ 0.5f, 0.5f, 0.0f}, 0xffffffff},
10607 static const struct vec3 quad_s0[] =
10609 {-1.0f, -1.0f, 0.0f},
10610 {-1.0f, 1.0f, 0.0f},
10611 { 1.0f, -1.0f, 0.0f},
10612 { 1.0f, 1.0f, 0.0f},
10614 {-1.0f, -1.0f, 0.0f},
10615 {-1.0f, 1.0f, 0.0f},
10616 { 1.0f, -1.0f, 0.0f},
10617 { 1.0f, 1.0f, 0.0f},
10619 static const DWORD quad_s1[] =
10621 0xffff0000,
10622 0xff00ff00,
10623 0xff0000ff,
10624 0xffffffff,
10626 0xff443322,
10627 0xff443322,
10628 0xff443322,
10629 0xff443322,
10631 static const short indices[] = {0, 1, 2, 3};
10633 window = create_window();
10634 ok(!!window, "Failed to create a window.\n");
10636 d3d = Direct3DCreate8(D3D_SDK_VERSION);
10637 ok(!!d3d, "Failed to create a D3D object.\n");
10639 present_parameters.BackBufferWidth = 640;
10640 present_parameters.BackBufferHeight = 480;
10641 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
10642 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
10643 present_parameters.hDeviceWindow = window;
10644 present_parameters.Windowed = TRUE;
10645 present_parameters.EnableAutoDepthStencil = TRUE;
10646 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
10647 if (FAILED(hr = IDirect3D8_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
10648 window, D3DCREATE_MIXED_VERTEXPROCESSING, &present_parameters, &device)))
10650 skip("Failed to create a D3D device, skipping tests.\n");
10651 IDirect3D8_Release(d3d);
10652 DestroyWindow(window);
10653 return;
10656 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10657 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10659 hr = IDirect3DDevice8_CreateVertexBuffer(device, sizeof(quad), 0, 0, D3DPOOL_SYSTEMMEM, &vb);
10660 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10661 hr = IDirect3DVertexBuffer8_Lock(vb, 0, sizeof(quad), &data, 0);
10662 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10663 memcpy(data, quad, sizeof(quad));
10664 hr = IDirect3DVertexBuffer8_Unlock(vb);
10665 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10667 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x77777777, 0.0f, 0);
10668 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10670 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10671 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10672 hr = IDirect3DDevice8_SetStreamSource(device, 0, vb, sizeof(*quad));
10673 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10675 hr = IDirect3DDevice8_BeginScene(device);
10676 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10677 hr = IDirect3DDevice8_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
10678 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10679 hr = IDirect3DDevice8_EndScene(device);
10680 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10682 colour = getPixelColor(device, 320, 240);
10683 ok(color_match(colour, 0x00007f7f, 1), "Got unexpected colour 0x%08x.\n", colour);
10685 hr = IDirect3DDevice8_CreateVertexBuffer(device, ARRAY_SIZE(quad) * sizeof(*dst_data),
10686 0, D3DFVF_XYZRHW, D3DPOOL_SYSTEMMEM, &dst_vb);
10687 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10688 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SOFTWAREVERTEXPROCESSING, TRUE);
10689 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10690 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10691 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10692 hr = IDirect3DDevice8_SetStreamSource(device, 0, vb, sizeof(*quad));
10693 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10695 hr = IDirect3DDevice8_ProcessVertices(device, 0, 0, ARRAY_SIZE(quad), dst_vb, 0);
10696 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10697 hr = IDirect3DVertexBuffer8_Lock(dst_vb, 0, 0, (BYTE **)&dst_data, 0);
10698 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10699 for (i = 0; i < ARRAY_SIZE(quad); ++i)
10701 ok(compare_vec4(&dst_data[i], quad[i].position.x * 320.0f + 320.0f,
10702 -quad[i].position.y * 240.0f + 240.0f, 0.0f, 1.0f, 4),
10703 "Got unexpected vertex %u {%.8e, %.8e, %.8e, %.8e}.\n",
10704 i, dst_data[i].x, dst_data[i].y, dst_data[i].z, dst_data[i].w);
10706 hr = IDirect3DVertexBuffer8_Unlock(dst_vb);
10707 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10709 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SOFTWAREVERTEXPROCESSING, FALSE);
10710 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_CreateIndexBuffer(device, sizeof(indices), 0,
10717 D3DFMT_INDEX16, D3DPOOL_SYSTEMMEM, &ib);
10718 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10719 hr = IDirect3DIndexBuffer8_Lock(ib, 0, sizeof(indices), &data, 0);
10720 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10721 memcpy(data, indices, sizeof(indices));
10722 hr = IDirect3DIndexBuffer8_Unlock(ib);
10723 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10725 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x77777777, 0.0f, 0);
10726 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10728 hr = IDirect3DDevice8_SetIndices(device, ib, 0);
10729 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10731 hr = IDirect3DDevice8_BeginScene(device);
10732 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10733 hr = IDirect3DDevice8_DrawIndexedPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 4, 0, 2);
10734 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10735 hr = IDirect3DDevice8_EndScene(device);
10736 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10738 colour = getPixelColor(device, 320, 240);
10739 ok(color_match(colour, 0x00007f7f, 1), "Got unexpected colour 0x%08x.\n", colour);
10741 hr = IDirect3DDevice8_CreateVertexShader(device, decl, NULL, &vs, 0);
10742 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10743 hr = IDirect3DDevice8_SetVertexShader(device, vs);
10744 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10746 hr = IDirect3DDevice8_CreateVertexBuffer(device, sizeof(quad_s0), 0, 0, D3DPOOL_SYSTEMMEM, &vb_s0);
10747 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10748 hr = IDirect3DVertexBuffer8_Lock(vb_s0, 0, sizeof(quad_s0), &data, 0);
10749 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10750 memcpy(data, quad_s0, sizeof(quad_s0));
10751 hr = IDirect3DVertexBuffer8_Unlock(vb_s0);
10752 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10753 hr = IDirect3DDevice8_CreateVertexBuffer(device, sizeof(quad_s1), 0, 0, D3DPOOL_SYSTEMMEM, &vb_s1);
10754 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10755 hr = IDirect3DVertexBuffer8_Lock(vb_s1, 0, sizeof(quad_s1), &data, 0);
10756 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10757 memcpy(data, quad_s1, sizeof(quad_s1));
10758 hr = IDirect3DVertexBuffer8_Unlock(vb_s1);
10759 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10761 hr = IDirect3DDevice8_SetStreamSource(device, 0, vb_s0, sizeof(*quad_s0));
10762 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10763 hr = IDirect3DDevice8_SetStreamSource(device, 1, vb_s1, sizeof(*quad_s1));
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_BeginScene(device);
10770 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10771 hr = IDirect3DDevice8_DrawIndexedPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 4, 0, 2);
10772 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10773 hr = IDirect3DDevice8_EndScene(device);
10774 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10776 colour = getPixelColor(device, 320, 240);
10777 ok(color_match(colour, 0x00007f7f, 1), "Got unexpected colour 0x%08x.\n", colour);
10779 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x77777777, 0.0f, 0);
10780 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10782 hr = IDirect3DDevice8_SetIndices(device, ib, 4);
10783 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10785 hr = IDirect3DDevice8_BeginScene(device);
10786 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10787 hr = IDirect3DDevice8_DrawIndexedPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 5, 0, 2);
10788 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10789 hr = IDirect3DDevice8_EndScene(device);
10790 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10792 colour = getPixelColor(device, 320, 240);
10793 ok(color_match(colour, 0x00443322, 1), "Got unexpected colour 0x%08x.\n", colour);
10795 /* Test that releasing but not unbinding a vertex buffer doesn't break. */
10796 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10797 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10798 hr = IDirect3DDevice8_SetStreamSource(device, 0, vb, sizeof(*quad));
10799 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10800 hr = IDirect3DDevice8_SetIndices(device, ib, 0);
10801 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10803 refcount = IDirect3DVertexBuffer8_Release(vb_s1);
10804 ok(!refcount, "Unexpected refcount %u.\n", refcount);
10805 hr = IDirect3DDevice8_GetStreamSource(device, 1, &get_vb, &stride);
10806 ok(SUCCEEDED(hr), "Got unexpected hr %#x.\n", hr);
10807 ok(get_vb == vb_s1, "Got unexpected vertex buffer %p.\n", get_vb);
10808 refcount = IDirect3DVertexBuffer8_Release(get_vb);
10809 ok(!refcount, "Unexpected refcount %u.\n", refcount);
10811 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x77777777, 0.0f, 0);
10812 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10814 hr = IDirect3DDevice8_BeginScene(device);
10815 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10816 hr = IDirect3DDevice8_DrawIndexedPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 4, 0, 2);
10817 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10818 hr = IDirect3DDevice8_EndScene(device);
10819 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10821 colour = getPixelColor(device, 320, 240);
10822 ok(color_match(colour, 0x00007f7f, 1), "Got unexpected colour 0x%08x.\n", colour);
10824 hr = IDirect3DDevice8_SetVertexShader(device, vs);
10825 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10826 hr = IDirect3DDevice8_SetStreamSource(device, 0, vb_s0, sizeof(*quad_s0));
10827 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10829 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x77777777, 0.0f, 0);
10830 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10832 hr = IDirect3DDevice8_BeginScene(device);
10833 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10834 hr = IDirect3DDevice8_DrawIndexedPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 4, 0, 2);
10835 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10836 hr = IDirect3DDevice8_EndScene(device);
10837 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10839 colour = getPixelColor(device, 320, 240);
10840 ok(color_match(colour, 0x00007f7f, 1), "Got unexpected colour 0x%08x.\n", colour);
10842 hr = IDirect3DDevice8_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &texture);
10843 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10844 memset(&lr, 0, sizeof(lr));
10845 hr = IDirect3DTexture8_LockRect(texture, 0, &lr, NULL, 0);
10846 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10847 memcpy(lr.pBits, texture_data, sizeof(texture_data));
10848 hr = IDirect3DTexture8_UnlockRect(texture, 0);
10849 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10851 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
10852 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10854 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x77777777, 0.0f, 0);
10855 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10857 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ);
10858 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10860 hr = IDirect3DDevice8_BeginScene(device);
10861 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10862 hr = IDirect3DDevice8_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
10863 ok(hr == D3D_OK || hr == E_FAIL, "Got unexpected hr %#x.\n", hr);
10864 hr = IDirect3DDevice8_EndScene(device);
10865 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10867 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
10868 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
10870 IDirect3DTexture8_Release(texture);
10871 IDirect3DVertexBuffer8_Release(vb_s0);
10872 IDirect3DDevice8_DeleteVertexShader(device, vs);
10873 IDirect3DIndexBuffer8_Release(ib);
10874 IDirect3DVertexBuffer8_Release(dst_vb);
10875 IDirect3DVertexBuffer8_Release(vb);
10876 refcount = IDirect3DDevice8_Release(device);
10877 ok(!refcount, "Device has %u references left.\n", refcount);
10878 IDirect3D8_Release(d3d);
10879 DestroyWindow(window);
10882 static void test_alphatest(void)
10884 #define ALPHATEST_PASSED 0x0000ff00
10885 #define ALPHATEST_FAILED 0x00ff0000
10886 IDirect3DDevice8 *device;
10887 unsigned int i, j;
10888 IDirect3D8 *d3d;
10889 D3DCOLOR color;
10890 ULONG refcount;
10891 D3DCAPS8 caps;
10892 DWORD value;
10893 HWND window;
10894 HRESULT hr;
10895 DWORD ps;
10897 static const struct
10899 D3DCMPFUNC func;
10900 D3DCOLOR color_less;
10901 D3DCOLOR color_equal;
10902 D3DCOLOR color_greater;
10904 test_data[] =
10906 {D3DCMP_NEVER, ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_FAILED},
10907 {D3DCMP_LESS, ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_FAILED},
10908 {D3DCMP_EQUAL, ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_FAILED},
10909 {D3DCMP_LESSEQUAL, ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_FAILED},
10910 {D3DCMP_GREATER, ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_PASSED},
10911 {D3DCMP_NOTEQUAL, ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_PASSED},
10912 {D3DCMP_GREATEREQUAL, ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_PASSED},
10913 {D3DCMP_ALWAYS, ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_PASSED},
10915 static const struct
10917 struct vec3 position;
10918 DWORD diffuse;
10920 quad[] =
10922 {{-1.0f, -1.0f, 0.1f}, ALPHATEST_PASSED | 0x80000000},
10923 {{-1.0f, 1.0f, 0.1f}, ALPHATEST_PASSED | 0x80000000},
10924 {{ 1.0f, -1.0f, 0.1f}, ALPHATEST_PASSED | 0x80000000},
10925 {{ 1.0f, 1.0f, 0.1f}, ALPHATEST_PASSED | 0x80000000},
10928 window = create_window();
10929 ok(!!window, "Failed to create a window.\n");
10931 d3d = Direct3DCreate8(D3D_SDK_VERSION);
10932 ok(!!d3d, "Failed to create a D3D object.\n");
10934 if (!(device = create_device(d3d, window, window, TRUE)))
10936 skip("Failed to create a D3D device, skipping tests.\n");
10937 goto done;
10940 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
10941 ok(hr == D3D_OK, "Failed to clear, hr %#x.\n", hr);
10943 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10944 ok(hr == D3D_OK, "Failed to disable lighting, hr %#x.\n", hr);
10945 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ALPHATESTENABLE, TRUE);
10946 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState, hr %#x.\n", hr);
10947 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10948 ok(hr == D3D_OK, "IDirect3DDevice8_SetVertexShader failed, hr %#x.\n", hr);
10950 ps = 0;
10951 for (j = 0; j < 2; ++j)
10953 if (j == 1)
10955 /* Try a pixel shader instead of fixed function. The wined3d code
10956 * may emulate the alpha test either for performance reasons
10957 * (floating point RTs) or to work around driver bugs (GeForce
10958 * 7x00 cards on MacOS). There may be a different codepath for ffp
10959 * and shader in this case, and the test should cover both. */
10960 static const DWORD shader_code[] =
10962 0xffff0101, /* ps_1_1 */
10963 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
10964 0x0000ffff /* end */
10966 memset(&caps, 0, sizeof(caps));
10967 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
10968 ok(hr == D3D_OK, "IDirect3DDevice8_GetDeviceCaps failed, hr %#x.\n", hr);
10969 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 1))
10970 break;
10972 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code, &ps);
10973 ok(hr == D3D_OK, "IDirect3DDevice8_CreatePixelShader failed, hr %#x.\n", hr);
10974 hr = IDirect3DDevice8_SetPixelShader(device, ps);
10975 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShader failed, hr %#x.\n", hr);
10978 for (i = 0; i < ARRAY_SIZE(test_data); ++i)
10980 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ALPHAFUNC, test_data[i].func);
10981 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr %#x.\n", hr);
10983 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0f, 0);
10984 ok(hr == D3D_OK, "IDirect3DDevice8_Clear failed, hr %#x.\n", hr);
10985 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ALPHAREF, 0x70);
10986 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr %#x.\n", hr);
10987 hr = IDirect3DDevice8_BeginScene(device);
10988 ok(hr == D3D_OK, "IDirect3DDevice8_BeginScene failed, hr %#x.\n", hr);
10989 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
10990 ok(hr == D3D_OK, "IDirect3DDevice8_DrawPrimitiveUP failed, hr %#x.\n", hr);
10991 hr = IDirect3DDevice8_EndScene(device);
10992 ok(hr == D3D_OK, "IDirect3DDevice8_EndScene failed, hr %#x.\n", hr);
10993 color = getPixelColor(device, 320, 240);
10994 ok(color_match(color, test_data[i].color_greater, 0),
10995 "Alphatest failed, color 0x%08x, expected 0x%08x, alpha > ref, func %u.\n",
10996 color, test_data[i].color_greater, test_data[i].func);
10997 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
10998 ok(hr == D3D_OK, "IDirect3DDevice8_Present failed, hr %#x.\n", hr);
11000 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0f, 0);
11001 ok(hr == D3D_OK, "IDirect3DDevice8_Clear failed, hr %#x.\n", hr);
11002 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ALPHAREF, 0xff70);
11003 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr %#x.\n", hr);
11004 hr = IDirect3DDevice8_GetRenderState(device, D3DRS_ALPHAREF, &value);
11005 ok(hr == D3D_OK, "IDirect3DDevice8_GetRenderState failed, hr %#x.\n", hr);
11006 ok(value == 0xff70, "Unexpected D3DRS_ALPHAREF value %#x.\n", value);
11007 hr = IDirect3DDevice8_BeginScene(device);
11008 ok(hr == D3D_OK, "IDirect3DDevice8_BeginScene failed, hr %#x.\n", hr);
11009 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11010 ok(hr == D3D_OK, "IDirect3DDevice8_DrawPrimitiveUP failed, hr %#x.\n", hr);
11011 hr = IDirect3DDevice8_EndScene(device);
11012 ok(hr == D3D_OK, "IDirect3DDevice8_EndScene failed, hr %#x.\n", hr);
11013 color = getPixelColor(device, 320, 240);
11014 ok(color_match(color, test_data[i].color_greater, 0),
11015 "Alphatest failed, color 0x%08x, expected 0x%08x, alpha > ref, func %u.\n",
11016 color, test_data[i].color_greater, test_data[i].func);
11017 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
11018 ok(hr == D3D_OK, "IDirect3DDevice8_Present failed, hr %#x.\n", hr);
11021 if (ps)
11022 IDirect3DDevice8_DeletePixelShader(device, ps);
11024 refcount = IDirect3DDevice8_Release(device);
11025 ok(!refcount, "Device has %u references left.\n", refcount);
11026 done:
11027 IDirect3D8_Release(d3d);
11028 DestroyWindow(window);
11031 static void test_desktop_window(void)
11033 IDirect3DDevice8 *device;
11034 IDirect3D8 *d3d;
11035 D3DCOLOR color;
11036 ULONG refcount;
11037 HWND window;
11038 HRESULT hr;
11040 window = create_window();
11041 d3d = Direct3DCreate8(D3D_SDK_VERSION);
11042 ok(!!d3d, "Failed to create a D3D object.\n");
11043 if (!(device = create_device(d3d, window, window, TRUE)))
11045 skip("Failed to create a D3D device, skipping tests.\n");
11046 IDirect3D8_Release(d3d);
11047 DestroyWindow(window);
11048 return;
11050 IDirect3DDevice8_Release(device);
11051 DestroyWindow(window);
11053 device = create_device(d3d, GetDesktopWindow(), GetDesktopWindow(), TRUE);
11054 ok(!!device, "Failed to create a D3D device.\n");
11056 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 1.0f, 0);
11057 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
11058 color = getPixelColor(device, 1, 1);
11059 ok(color == 0x00ff0000, "Got unexpected color 0x%08x.\n", color);
11061 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
11062 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
11064 refcount = IDirect3DDevice8_Release(device);
11065 ok(!refcount, "Device has %u references left.\n", refcount);
11067 IDirect3D8_Release(d3d);
11070 START_TEST(visual)
11072 D3DADAPTER_IDENTIFIER8 identifier;
11073 IDirect3D8 *d3d;
11074 HRESULT hr;
11076 if (!(d3d = Direct3DCreate8(D3D_SDK_VERSION)))
11078 skip("Failed to create D3D8 object.\n");
11079 return;
11082 memset(&identifier, 0, sizeof(identifier));
11083 hr = IDirect3D8_GetAdapterIdentifier(d3d, D3DADAPTER_DEFAULT, 0, &identifier);
11084 ok(SUCCEEDED(hr), "Failed to get adapter identifier, hr %#x.\n", hr);
11085 trace("Driver string: \"%s\"\n", identifier.Driver);
11086 trace("Description string: \"%s\"\n", identifier.Description);
11087 /* Only Windows XP's default VGA driver should have an empty description */
11088 ok(identifier.Description[0] || broken(!strcmp(identifier.Driver, "vga.dll")), "Empty driver description.\n");
11089 trace("Driver version %d.%d.%d.%d\n",
11090 HIWORD(U(identifier.DriverVersion).HighPart), LOWORD(U(identifier.DriverVersion).HighPart),
11091 HIWORD(U(identifier.DriverVersion).LowPart), LOWORD(U(identifier.DriverVersion).LowPart));
11093 IDirect3D8_Release(d3d);
11095 test_sanity();
11096 depth_clamp_test();
11097 lighting_test();
11098 test_specular_lighting();
11099 clear_test();
11100 fog_test();
11101 z_range_test();
11102 offscreen_test();
11103 test_blend();
11104 test_scalar_instructions();
11105 fog_with_shader_test();
11106 cnd_test();
11107 p8_texture_test();
11108 texop_test();
11109 depth_buffer_test();
11110 depth_buffer2_test();
11111 intz_test();
11112 shadow_test();
11113 multisample_copy_rects_test();
11114 zenable_test();
11115 resz_test();
11116 fog_special_test();
11117 volume_dxtn_test();
11118 volume_v16u16_test();
11119 add_dirty_rect_test();
11120 test_3dc_formats();
11121 test_fog_interpolation();
11122 test_negative_fixedfunction_fog();
11123 test_table_fog_zw();
11124 test_signed_formats();
11125 test_updatetexture();
11126 test_pointsize();
11127 test_multisample_mismatch();
11128 test_texcoordindex();
11129 test_vshader_input();
11130 test_fixed_function_fvf();
11131 test_flip();
11132 test_uninitialized_varyings();
11133 test_shademode();
11134 test_multisample_init();
11135 test_texture_blending();
11136 test_color_clamping();
11137 test_edge_antialiasing_blending();
11138 test_max_index16();
11139 test_backbuffer_resize();
11140 test_drawindexedprimitiveup();
11141 test_map_synchronisation();
11142 test_viewport();
11143 test_color_vertex();
11144 test_sysmem_draw();
11145 test_alphatest();
11146 test_desktop_window();