d3d8/tests: Allow a higher slop for test_updatetexture.
[wine.git] / dlls / d3d8 / tests / visual.c
bloba7177d30eaec66f379b2f3af9015340921f44bba
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 <math.h>
24 #define COBJMACROS
25 #include <d3d8.h>
26 #include "wine/test.h"
28 struct vec2
30 float x, y;
33 struct vec3
35 float x, y, z;
38 struct vec4
40 float x, y, z, w;
43 static HWND create_window(void)
45 RECT rect;
47 SetRect(&rect, 0, 0, 640, 480);
48 AdjustWindowRect(&rect, WS_OVERLAPPEDWINDOW | WS_VISIBLE, FALSE);
49 return CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
50 0, 0, rect.right - rect.left, rect.bottom - rect.top, 0, 0, 0, 0);
53 static BOOL color_match(D3DCOLOR c1, D3DCOLOR c2, BYTE max_diff)
55 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
56 c1 >>= 8; c2 >>= 8;
57 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
58 c1 >>= 8; c2 >>= 8;
59 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
60 c1 >>= 8; c2 >>= 8;
61 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
62 return TRUE;
65 static BOOL adapter_is_warp(const D3DADAPTER_IDENTIFIER8 *identifier)
67 return !strcmp(identifier->Driver, "d3d10warp.dll");
70 struct surface_readback
72 IDirect3DSurface8 *surface;
73 D3DLOCKED_RECT locked_rect;
76 static void get_rt_readback(IDirect3DSurface8 *surface, struct surface_readback *rb)
78 IDirect3DTexture8 *tex = NULL;
79 IDirect3DDevice8 *device;
80 D3DSURFACE_DESC desc;
81 HRESULT hr;
83 memset(rb, 0, sizeof(*rb));
84 hr = IDirect3DSurface8_GetDevice(surface, &device);
85 ok(SUCCEEDED(hr), "Failed to get device, hr %#x.\n", hr);
86 hr = IDirect3DSurface8_GetDesc(surface, &desc);
87 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
88 hr = IDirect3DDevice8_CreateTexture(device, desc.Width, desc.Height, 1, 0, desc.Format, D3DPOOL_SYSTEMMEM, &tex);
89 if (FAILED(hr) || !tex)
91 trace("Can't create an offscreen plain surface to read the render target data, hr %#x.\n", hr);
92 goto error;
94 hr = IDirect3DTexture8_GetSurfaceLevel(tex, 0, &rb->surface);
95 if (FAILED(hr))
97 trace("Can't get surface from texture, hr %#x.\n", hr);
98 goto error;
100 hr = IDirect3DDevice8_CopyRects(device, surface, NULL, 0, rb->surface, NULL);
101 if (FAILED(hr))
103 trace("Can't read the render target, hr %#x.\n", hr);
104 goto error;
106 hr = IDirect3DSurface8_LockRect(rb->surface, &rb->locked_rect, NULL, D3DLOCK_READONLY);
107 if (FAILED(hr))
109 trace("Can't lock the offscreen surface, hr %#x.\n", hr);
110 goto error;
112 IDirect3DTexture8_Release(tex);
113 IDirect3DDevice8_Release(device);
114 return;
116 error:
117 if (rb->surface)
118 IDirect3DSurface8_Release(rb->surface);
119 rb->surface = NULL;
120 if (tex)
121 IDirect3DTexture8_Release(tex);
122 IDirect3DDevice8_Release(device);
125 static DWORD get_readback_color(struct surface_readback *rb, unsigned int x, unsigned int y)
127 return rb->locked_rect.pBits
128 ? ((DWORD *)rb->locked_rect.pBits)[y * rb->locked_rect.Pitch / sizeof(DWORD) + x] : 0xdeadbeef;
131 static void release_surface_readback(struct surface_readback *rb)
133 HRESULT hr;
135 if (!rb->surface)
136 return;
137 if (rb->locked_rect.pBits && FAILED(hr = IDirect3DSurface8_UnlockRect(rb->surface)))
138 trace("Can't unlock the offscreen surface, hr %#x.\n", hr);
139 IDirect3DSurface8_Release(rb->surface);
142 static DWORD getPixelColor(IDirect3DDevice8 *device, UINT x, UINT y)
144 DWORD ret;
145 IDirect3DSurface8 *rt;
146 struct surface_readback rb;
147 HRESULT hr;
149 hr = IDirect3DDevice8_GetRenderTarget(device, &rt);
150 if (FAILED(hr))
152 trace("Can't get the render target, hr %#x.\n", hr);
153 return 0xdeadbeef;
156 get_rt_readback(rt, &rb);
157 /* Remove the X channel for now. DirectX and OpenGL have different ideas how to treat it apparently, and it isn't
158 * really important for these tests
160 ret = get_readback_color(&rb, x, y) & 0x00ffffff;
161 release_surface_readback(&rb);
163 IDirect3DSurface8_Release(rt);
164 return ret;
167 static D3DCOLOR get_surface_color(IDirect3DSurface8 *surface, UINT x, UINT y)
169 DWORD color;
170 HRESULT hr;
171 D3DSURFACE_DESC desc;
172 RECT rectToLock = {x, y, x+1, y+1};
173 D3DLOCKED_RECT lockedRect;
175 hr = IDirect3DSurface8_GetDesc(surface, &desc);
176 ok(SUCCEEDED(hr), "Failed to get surface description, hr=%#x.\n", hr);
178 hr = IDirect3DSurface8_LockRect(surface, &lockedRect, &rectToLock, D3DLOCK_READONLY);
179 ok(SUCCEEDED(hr), "Failed to lock surface, hr=%#x.\n", hr);
181 switch(desc.Format)
183 case D3DFMT_A8R8G8B8:
184 color = ((D3DCOLOR *)lockedRect.pBits)[0];
185 break;
187 default:
188 trace("Error: unknown surface format: %u.\n", desc.Format);
189 color = 0xdeadbeef;
190 break;
193 hr = IDirect3DSurface8_UnlockRect(surface);
194 ok(SUCCEEDED(hr), "Failed to unlock surface, hr=%#x.\n", hr);
196 return color;
199 static IDirect3DDevice8 *create_device(IDirect3D8 *d3d, HWND device_window, HWND focus_window, BOOL windowed)
201 D3DPRESENT_PARAMETERS present_parameters = {0};
202 IDirect3DDevice8 *device;
204 present_parameters.Windowed = windowed;
205 present_parameters.hDeviceWindow = device_window;
206 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
207 present_parameters.BackBufferWidth = 640;
208 present_parameters.BackBufferHeight = 480;
209 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
210 present_parameters.EnableAutoDepthStencil = TRUE;
211 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
213 if (SUCCEEDED(IDirect3D8_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, focus_window,
214 D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device)))
215 return device;
217 return NULL;
220 static void test_sanity(void)
222 IDirect3DDevice8 *device;
223 IDirect3D8 *d3d;
224 D3DCOLOR color;
225 ULONG refcount;
226 HWND window;
227 HRESULT hr;
229 window = create_window();
230 d3d = Direct3DCreate8(D3D_SDK_VERSION);
231 ok(!!d3d, "Failed to create a D3D object.\n");
232 if (!(device = create_device(d3d, window, window, TRUE)))
234 skip("Failed to create a D3D device, skipping tests.\n");
235 goto done;
238 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 1.0f, 0);
239 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
240 color = getPixelColor(device, 1, 1);
241 ok(color == 0x00ff0000, "Got unexpected color 0x%08x.\n", color);
243 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
244 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
246 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ddee, 1.0f, 0);
247 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
248 color = getPixelColor(device, 639, 479);
249 ok(color == 0x0000ddee, "Got unexpected color 0x%08x.\n", color);
251 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
252 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
254 refcount = IDirect3DDevice8_Release(device);
255 ok(!refcount, "Device has %u references left.\n", refcount);
256 done:
257 IDirect3D8_Release(d3d);
258 DestroyWindow(window);
261 static void lighting_test(void)
263 DWORD nfvf = D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_NORMAL;
264 DWORD fvf = D3DFVF_XYZ | D3DFVF_DIFFUSE;
265 IDirect3DDevice8 *device;
266 IDirect3D8 *d3d;
267 D3DCOLOR color;
268 ULONG refcount;
269 HWND window;
270 HRESULT hr;
271 unsigned int i;
273 static const struct
275 struct vec3 position;
276 DWORD diffuse;
278 unlitquad[] =
280 {{-1.0f, -1.0f, 0.1f}, 0xffff0000},
281 {{-1.0f, 0.0f, 0.1f}, 0xffff0000},
282 {{ 0.0f, 0.0f, 0.1f}, 0xffff0000},
283 {{ 0.0f, -1.0f, 0.1f}, 0xffff0000},
285 litquad[] =
287 {{-1.0f, 0.0f, 0.1f}, 0xff00ff00},
288 {{-1.0f, 1.0f, 0.1f}, 0xff00ff00},
289 {{ 0.0f, 1.0f, 0.1f}, 0xff00ff00},
290 {{ 0.0f, 0.0f, 0.1f}, 0xff00ff00},
292 static const struct
294 struct vec3 position;
295 struct vec3 normal;
296 DWORD diffuse;
298 unlitnquad[] =
300 {{0.0f, -1.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xff0000ff},
301 {{0.0f, 0.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xff0000ff},
302 {{1.0f, 0.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xff0000ff},
303 {{1.0f, -1.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xff0000ff},
305 litnquad[] =
307 {{0.0f, 0.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xffffff00},
308 {{0.0f, 1.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xffffff00},
309 {{1.0f, 1.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xffffff00},
310 {{1.0f, 0.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xffffff00},
312 nquad[] =
314 {{-1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
315 {{-1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
316 {{ 1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
317 {{ 1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
319 rotatedquad[] =
321 {{-10.0f, -11.0f, 11.0f}, {-1.0f, 0.0f, 0.0f}, 0xff0000ff},
322 {{-10.0f, -9.0f, 11.0f}, {-1.0f, 0.0f, 0.0f}, 0xff0000ff},
323 {{-10.0f, -9.0f, 9.0f}, {-1.0f, 0.0f, 0.0f}, 0xff0000ff},
324 {{-10.0f, -11.0f, 9.0f}, {-1.0f, 0.0f, 0.0f}, 0xff0000ff},
326 translatedquad[] =
328 {{-11.0f, -11.0f, -10.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
329 {{-11.0f, -9.0f, -10.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
330 {{ -9.0f, -9.0f, -10.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
331 {{ -9.0f, -11.0f, -10.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
333 static const WORD indices[] = {0, 1, 2, 2, 3, 0};
334 static const D3DMATRIX mat =
336 1.0f, 0.0f, 0.0f, 0.0f,
337 0.0f, 1.0f, 0.0f, 0.0f,
338 0.0f, 0.0f, 1.0f, 0.0f,
339 0.0f, 0.0f, 0.0f, 1.0f,
340 }}},
341 mat_singular =
343 1.0f, 0.0f, 1.0f, 0.0f,
344 0.0f, 1.0f, 0.0f, 0.0f,
345 1.0f, 0.0f, 1.0f, 0.0f,
346 0.0f, 0.0f, 0.5f, 1.0f,
347 }}},
348 mat_transf =
350 0.0f, 0.0f, 1.0f, 0.0f,
351 0.0f, 1.0f, 0.0f, 0.0f,
352 -1.0f, 0.0f, 0.0f, 0.0f,
353 10.f, 10.0f, 10.0f, 1.0f,
354 }}},
355 mat_nonaffine =
357 1.0f, 0.0f, 0.0f, 0.0f,
358 0.0f, 1.0f, 0.0f, 0.0f,
359 0.0f, 0.0f, 1.0f, -1.0f,
360 10.f, 10.0f, 10.0f, 0.0f,
361 }}};
362 static const struct
364 const D3DMATRIX *world_matrix;
365 const void *quad;
366 unsigned int size;
367 DWORD expected;
368 const char *message;
370 tests[] =
372 {&mat, nquad, sizeof(nquad[0]), 0x000000ff, "Lit quad with light"},
373 {&mat_singular, nquad, sizeof(nquad[0]), 0x000000ff, "Lit quad with singular world matrix"},
374 {&mat_transf, rotatedquad, sizeof(rotatedquad[0]), 0x000000ff, "Lit quad with transformation matrix"},
375 {&mat_nonaffine, translatedquad, sizeof(translatedquad[0]), 0x00000000, "Lit quad with non-affine matrix"},
378 window = create_window();
379 d3d = Direct3DCreate8(D3D_SDK_VERSION);
380 ok(!!d3d, "Failed to create a D3D object.\n");
381 if (!(device = create_device(d3d, window, window, TRUE)))
383 skip("Failed to create a D3D device, skipping tests.\n");
384 goto done;
387 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
388 ok(hr == D3D_OK, "IDirect3DDevice8_Clear failed with %#08x\n", hr);
390 hr = IDirect3DDevice8_SetTransform(device, D3DTS_WORLDMATRIX(0), &mat);
391 ok(hr == D3D_OK, "IDirect3DDevice8_SetTransform returned %#08x\n", hr);
392 hr = IDirect3DDevice8_SetTransform(device, D3DTS_VIEW, &mat);
393 ok(hr == D3D_OK, "IDirect3DDevice8_SetTransform returned %#08x\n", hr);
394 hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, &mat);
395 ok(hr == D3D_OK, "IDirect3DDevice8_SetTransform returned %#08x\n", hr);
396 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, FALSE);
397 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %#08x\n", hr);
398 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, FALSE);
399 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %#08x\n", hr);
400 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
401 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %#08x\n", hr);
402 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
403 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %#08x\n", hr);
404 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
405 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed with %#08x\n", hr);
407 hr = IDirect3DDevice8_SetVertexShader(device, fvf);
408 ok(hr == D3D_OK, "IDirect3DDevice8_SetVertexShader returned %#08x\n", hr);
410 hr = IDirect3DDevice8_BeginScene(device);
411 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
413 /* No lights are defined... That means, lit vertices should be entirely black. */
414 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
415 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
416 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
417 2, indices, D3DFMT_INDEX16, unlitquad, sizeof(unlitquad[0]));
418 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
420 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, TRUE);
421 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
422 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
423 2, indices, D3DFMT_INDEX16, litquad, sizeof(litquad[0]));
424 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
426 hr = IDirect3DDevice8_SetVertexShader(device, nfvf);
427 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
429 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
430 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
431 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
432 2, indices, D3DFMT_INDEX16, unlitnquad, sizeof(unlitnquad[0]));
433 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
435 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, TRUE);
436 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
437 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
438 2, indices, D3DFMT_INDEX16, litnquad, sizeof(litnquad[0]));
439 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
441 hr = IDirect3DDevice8_EndScene(device);
442 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
444 color = getPixelColor(device, 160, 360); /* Lower left quad - unlit without normals */
445 ok(color == 0x00ff0000, "Unlit quad without normals has color 0x%08x, expected 0x00ff0000.\n", color);
446 color = getPixelColor(device, 160, 120); /* Upper left quad - lit without normals */
447 ok(color == 0x00000000, "Lit quad without normals has color 0x%08x, expected 0x00000000.\n", color);
448 color = getPixelColor(device, 480, 360); /* Lower right quad - unlit with normals */
449 ok(color == 0x000000ff, "Unlit quad with normals has color 0x%08x, expected 0x000000ff.\n", color);
450 color = getPixelColor(device, 480, 120); /* Upper right quad - lit with normals */
451 ok(color == 0x00000000, "Lit quad with normals has color 0x%08x, expected 0x00000000.\n", color);
453 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
455 hr = IDirect3DDevice8_LightEnable(device, 0, TRUE);
456 ok(SUCCEEDED(hr), "Failed to enable light 0, hr %#x.\n", hr);
458 for (i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i)
460 hr = IDirect3DDevice8_SetTransform(device, D3DTS_WORLD, tests[i].world_matrix);
461 ok(SUCCEEDED(hr), "Failed to set world transform, hr %#x.\n", hr);
463 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
464 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
466 hr = IDirect3DDevice8_BeginScene(device);
467 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
469 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
470 2, indices, D3DFMT_INDEX16, tests[i].quad, tests[i].size);
471 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
473 hr = IDirect3DDevice8_EndScene(device);
474 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
476 color = getPixelColor(device, 320, 240);
477 ok(color == tests[i].expected, "%s has color 0x%08x.\n", tests[i].message, color);
480 refcount = IDirect3DDevice8_Release(device);
481 ok(!refcount, "Device has %u references left.\n", refcount);
482 done:
483 IDirect3D8_Release(d3d);
484 DestroyWindow(window);
487 static void test_specular_lighting(void)
489 static const unsigned int vertices_side = 5;
490 const unsigned int indices_count = (vertices_side - 1) * (vertices_side - 1) * 2 * 3;
491 static const DWORD fvf = D3DFVF_XYZ | D3DFVF_NORMAL;
492 static const D3DMATRIX mat =
494 1.0f, 0.0f, 0.0f, 0.0f,
495 0.0f, 1.0f, 0.0f, 0.0f,
496 0.0f, 0.0f, 1.0f, 0.0f,
497 0.0f, 0.0f, 0.0f, 1.0f,
498 }}};
499 static const D3DLIGHT8 directional =
501 D3DLIGHT_DIRECTIONAL,
502 {0.0f, 0.0f, 0.0f, 0.0f},
503 {1.0f, 1.0f, 1.0f, 0.0f},
504 {0.0f, 0.0f, 0.0f, 0.0f},
505 {0.0f, 0.0f, 0.0f},
506 {0.0f, 0.0f, 1.0f},
508 point =
510 D3DLIGHT_POINT,
511 {0.0f, 0.0f, 0.0f, 0.0f},
512 {1.0f, 1.0f, 1.0f, 0.0f},
513 {0.0f, 0.0f, 0.0f, 0.0f},
514 {0.0f, 0.0f, 0.0f},
515 {0.0f, 0.0f, 0.0f},
516 100.0f,
517 0.0f,
518 0.0f, 0.0f, 1.0f,
520 spot =
522 D3DLIGHT_SPOT,
523 {0.0f, 0.0f, 0.0f, 0.0f},
524 {1.0f, 1.0f, 1.0f, 0.0f},
525 {0.0f, 0.0f, 0.0f, 0.0f},
526 {0.0f, 0.0f, 0.0f},
527 {0.0f, 0.0f, 1.0f},
528 100.0f,
529 1.0f,
530 0.0f, 0.0f, 1.0f,
531 M_PI / 12.0f, M_PI / 3.0f
533 /* The chosen range value makes the test fail when using a manhattan
534 * distance metric vs the correct euclidean distance. */
535 point_range =
537 D3DLIGHT_POINT,
538 {0.0f, 0.0f, 0.0f, 0.0f},
539 {1.0f, 1.0f, 1.0f, 0.0f},
540 {0.0f, 0.0f, 0.0f, 0.0f},
541 {0.0f, 0.0f, 0.0f},
542 {0.0f, 0.0f, 0.0f},
543 1.2f,
544 0.0f,
545 0.0f, 0.0f, 1.0f,
547 static const struct expected_color
549 unsigned int x, y;
550 D3DCOLOR color;
552 expected_directional[] =
554 {160, 120, 0x00ffffff},
555 {320, 120, 0x00ffffff},
556 {480, 120, 0x00ffffff},
557 {160, 240, 0x00ffffff},
558 {320, 240, 0x00ffffff},
559 {480, 240, 0x00ffffff},
560 {160, 360, 0x00ffffff},
561 {320, 360, 0x00ffffff},
562 {480, 360, 0x00ffffff},
564 expected_directional_local[] =
566 {160, 120, 0x003c3c3c},
567 {320, 120, 0x00717171},
568 {480, 120, 0x003c3c3c},
569 {160, 240, 0x00717171},
570 {320, 240, 0x00ffffff},
571 {480, 240, 0x00717171},
572 {160, 360, 0x003c3c3c},
573 {320, 360, 0x00717171},
574 {480, 360, 0x003c3c3c},
576 expected_point[] =
578 {160, 120, 0x00282828},
579 {320, 120, 0x005a5a5a},
580 {480, 120, 0x00282828},
581 {160, 240, 0x005a5a5a},
582 {320, 240, 0x00ffffff},
583 {480, 240, 0x005a5a5a},
584 {160, 360, 0x00282828},
585 {320, 360, 0x005a5a5a},
586 {480, 360, 0x00282828},
588 expected_point_local[] =
590 {160, 120, 0x00000000},
591 {320, 120, 0x00070707},
592 {480, 120, 0x00000000},
593 {160, 240, 0x00070707},
594 {320, 240, 0x00ffffff},
595 {480, 240, 0x00070707},
596 {160, 360, 0x00000000},
597 {320, 360, 0x00070707},
598 {480, 360, 0x00000000},
600 expected_spot[] =
602 {160, 120, 0x00000000},
603 {320, 120, 0x00141414},
604 {480, 120, 0x00000000},
605 {160, 240, 0x00141414},
606 {320, 240, 0x00ffffff},
607 {480, 240, 0x00141414},
608 {160, 360, 0x00000000},
609 {320, 360, 0x00141414},
610 {480, 360, 0x00000000},
612 expected_spot_local[] =
614 {160, 120, 0x00000000},
615 {320, 120, 0x00020202},
616 {480, 120, 0x00000000},
617 {160, 240, 0x00020202},
618 {320, 240, 0x00ffffff},
619 {480, 240, 0x00020202},
620 {160, 360, 0x00000000},
621 {320, 360, 0x00020202},
622 {480, 360, 0x00000000},
624 expected_point_range[] =
626 {160, 120, 0x00000000},
627 {320, 120, 0x005a5a5a},
628 {480, 120, 0x00000000},
629 {160, 240, 0x005a5a5a},
630 {320, 240, 0x00ffffff},
631 {480, 240, 0x005a5a5a},
632 {160, 360, 0x00000000},
633 {320, 360, 0x005a5a5a},
634 {480, 360, 0x00000000},
636 static const struct
638 const D3DLIGHT8 *light;
639 BOOL local_viewer;
640 const struct expected_color *expected;
641 unsigned int expected_count;
643 tests[] =
645 {&directional, FALSE, expected_directional,
646 sizeof(expected_directional) / sizeof(expected_directional[0])},
647 {&directional, TRUE, expected_directional_local,
648 sizeof(expected_directional_local) / sizeof(expected_directional_local[0])},
649 {&point, FALSE, expected_point,
650 sizeof(expected_point) / sizeof(expected_point[0])},
651 {&point, TRUE, expected_point_local,
652 sizeof(expected_point_local) / sizeof(expected_point_local[0])},
653 {&spot, FALSE, expected_spot,
654 sizeof(expected_spot) / sizeof(expected_spot[0])},
655 {&spot, TRUE, expected_spot_local,
656 sizeof(expected_spot_local) / sizeof(expected_spot_local[0])},
657 {&point_range, FALSE, expected_point_range,
658 sizeof(expected_point_range) / sizeof(expected_point_range[0])},
660 IDirect3DDevice8 *device;
661 D3DMATERIAL8 material;
662 IDirect3D8 *d3d;
663 D3DCOLOR color;
664 ULONG refcount;
665 HWND window;
666 HRESULT hr;
667 unsigned int i, j, x, y;
668 struct
670 struct vec3 position;
671 struct vec3 normal;
672 } *quad;
673 WORD *indices;
675 quad = HeapAlloc(GetProcessHeap(), 0, vertices_side * vertices_side * sizeof(*quad));
676 indices = HeapAlloc(GetProcessHeap(), 0, indices_count * sizeof(*indices));
677 for (i = 0, y = 0; y < vertices_side; ++y)
679 for (x = 0; x < vertices_side; ++x)
681 quad[i].position.x = x * 2.0f / (vertices_side - 1) - 1.0f;
682 quad[i].position.y = y * 2.0f / (vertices_side - 1) - 1.0f;
683 quad[i].position.z = 1.0f;
684 quad[i].normal.x = 0.0f;
685 quad[i].normal.y = 0.0f;
686 quad[i++].normal.z = -1.0f;
689 for (i = 0, y = 0; y < (vertices_side - 1); ++y)
691 for (x = 0; x < (vertices_side - 1); ++x)
693 indices[i++] = y * vertices_side + x + 1;
694 indices[i++] = y * vertices_side + x;
695 indices[i++] = (y + 1) * vertices_side + x;
696 indices[i++] = y * vertices_side + x + 1;
697 indices[i++] = (y + 1) * vertices_side + x;
698 indices[i++] = (y + 1) * vertices_side + x + 1;
702 window = create_window();
703 d3d = Direct3DCreate8(D3D_SDK_VERSION);
704 ok(!!d3d, "Failed to create a D3D object.\n");
705 if (!(device = create_device(d3d, window, window, TRUE)))
707 skip("Failed to create a D3D device, skipping tests.\n");
708 goto done;
711 hr = IDirect3DDevice8_SetTransform(device, D3DTS_WORLD, &mat);
712 ok(SUCCEEDED(hr), "Failed to set world transform, hr %#x.\n", hr);
713 hr = IDirect3DDevice8_SetTransform(device, D3DTS_VIEW, &mat);
714 ok(SUCCEEDED(hr), "Failed to set view transform, hr %#x.\n", hr);
715 hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, &mat);
716 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
717 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, FALSE);
718 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#x.\n", hr);
719 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, FALSE);
720 ok(SUCCEEDED(hr), "Failed to disable z test, hr %#x.\n", hr);
721 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
722 ok(SUCCEEDED(hr), "Failed to disable fog, hr %#x.\n", hr);
724 hr = IDirect3DDevice8_SetVertexShader(device, fvf);
725 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
727 memset(&material, 0, sizeof(material));
728 material.Specular.r = 1.0f;
729 material.Specular.g = 1.0f;
730 material.Specular.b = 1.0f;
731 material.Specular.a = 1.0f;
732 material.Power = 30.0f;
733 hr = IDirect3DDevice8_SetMaterial(device, &material);
734 ok(SUCCEEDED(hr), "Failed to set material, hr %#x.\n", hr);
736 hr = IDirect3DDevice8_LightEnable(device, 0, TRUE);
737 ok(SUCCEEDED(hr), "Failed to enable light 0, hr %#x.\n", hr);
738 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SPECULARENABLE, TRUE);
739 ok(SUCCEEDED(hr), "Failed to enable specular lighting, hr %#x.\n", hr);
741 for (i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i)
743 hr = IDirect3DDevice8_SetLight(device, 0, tests[i].light);
744 ok(SUCCEEDED(hr), "Failed to set light parameters, hr %#x.\n", hr);
746 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LOCALVIEWER, tests[i].local_viewer);
747 ok(SUCCEEDED(hr), "Failed to set local viewer state, hr %#x.\n", hr);
749 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
750 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
752 hr = IDirect3DDevice8_BeginScene(device);
753 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
755 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST,
756 0, vertices_side * vertices_side, indices_count / 3, indices,
757 D3DFMT_INDEX16, quad, sizeof(quad[0]));
758 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
760 hr = IDirect3DDevice8_EndScene(device);
761 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
763 for (j = 0; j < tests[i].expected_count; ++j)
765 color = getPixelColor(device, tests[i].expected[j].x, tests[i].expected[j].y);
766 ok(color_match(color, tests[i].expected[j].color, 1),
767 "Expected color 0x%08x at location (%u, %u), got 0x%08x, case %u.\n",
768 tests[i].expected[j].color, tests[i].expected[j].x,
769 tests[i].expected[j].y, color, i);
773 refcount = IDirect3DDevice8_Release(device);
774 ok(!refcount, "Device has %u references left.\n", refcount);
775 done:
776 IDirect3D8_Release(d3d);
777 DestroyWindow(window);
778 HeapFree(GetProcessHeap(), 0, indices);
779 HeapFree(GetProcessHeap(), 0, quad);
782 static void clear_test(void)
784 /* Tests the correctness of clearing parameters */
785 D3DRECT rect_negneg, rect[2];
786 IDirect3DDevice8 *device;
787 IDirect3D8 *d3d;
788 D3DCOLOR color;
789 ULONG refcount;
790 HWND window;
791 HRESULT hr;
793 window = create_window();
794 d3d = Direct3DCreate8(D3D_SDK_VERSION);
795 ok(!!d3d, "Failed to create a D3D object.\n");
796 if (!(device = create_device(d3d, window, window, TRUE)))
798 skip("Failed to create a D3D device, skipping tests.\n");
799 goto done;
802 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
803 ok(hr == D3D_OK, "IDirect3DDevice8_Clear failed with %#08x\n", hr);
805 /* Positive x, negative y */
806 rect[0].x1 = 0;
807 rect[0].y1 = 480;
808 rect[0].x2 = 320;
809 rect[0].y2 = 240;
811 /* Positive x, positive y */
812 rect[1].x1 = 0;
813 rect[1].y1 = 0;
814 rect[1].x2 = 320;
815 rect[1].y2 = 240;
816 /* Clear 2 rectangles with one call. Shows that a positive value is returned, but the negative rectangle
817 * is ignored, the positive is still cleared afterwards
819 hr = IDirect3DDevice8_Clear(device, 2, rect, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
820 ok(hr == D3D_OK, "IDirect3DDevice8_Clear failed with %#08x\n", hr);
822 /* negative x, negative y */
823 rect_negneg.x1 = 640;
824 rect_negneg.y1 = 240;
825 rect_negneg.x2 = 320;
826 rect_negneg.y2 = 0;
827 hr = IDirect3DDevice8_Clear(device, 1, &rect_negneg, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
828 ok(hr == D3D_OK, "IDirect3DDevice8_Clear failed with %#08x\n", hr);
830 color = getPixelColor(device, 160, 360); /* lower left quad */
831 ok(color == 0x00ffffff, "Clear rectangle 3(pos, neg) has color %08x\n", color);
832 color = getPixelColor(device, 160, 120); /* upper left quad */
833 ok(color == 0x00ff0000, "Clear rectangle 1(pos, pos) has color %08x\n", color);
834 color = getPixelColor(device, 480, 360); /* lower right quad */
835 ok(color == 0x00ffffff, "Clear rectangle 4(NULL) has color %08x\n", color);
836 color = getPixelColor(device, 480, 120); /* upper right quad */
837 ok(color == 0x00ffffff, "Clear rectangle 4(neg, neg) has color %08x\n", color);
839 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
841 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
842 ok(SUCCEEDED(hr), "IDirect3DDevice8_Clear failed with %#08x\n", hr);
844 rect[0].x1 = 0;
845 rect[0].y1 = 0;
846 rect[0].x2 = 640;
847 rect[0].y2 = 480;
848 hr = IDirect3DDevice8_Clear(device, 0, rect, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
849 ok(SUCCEEDED(hr), "IDirect3DDevice8_Clear failed with %#08x\n", hr);
851 color = getPixelColor(device, 320, 240);
852 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff), 1),
853 "Clear with count = 0, rect != NULL has color %#08x\n", color);
855 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
857 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
858 ok(SUCCEEDED(hr), "IDirect3DDevice8_Clear failed with %#08x\n", hr);
859 hr = IDirect3DDevice8_Clear(device, 1, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
860 ok(SUCCEEDED(hr), "IDirect3DDevice8_Clear failed with %#08x\n", hr);
862 color = getPixelColor(device, 320, 240);
863 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
864 "Clear with count = 1, rect = NULL has color %#08x\n", color);
866 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
868 refcount = IDirect3DDevice8_Release(device);
869 ok(!refcount, "Device has %u references left.\n", refcount);
870 done:
871 IDirect3D8_Release(d3d);
872 DestroyWindow(window);
875 static void fog_test(void)
877 float start = 0.0f, end = 1.0f;
878 IDirect3DDevice8 *device;
879 IDirect3D8 *d3d;
880 D3DCOLOR color;
881 ULONG refcount;
882 D3DCAPS8 caps;
883 HWND window;
884 HRESULT hr;
886 /* Gets full z based fog with linear fog, no fog with specular color. */
887 static const struct
889 float x, y, z;
890 D3DCOLOR diffuse;
891 D3DCOLOR specular;
893 untransformed_1[] =
895 {-1.0f, -1.0f, 0.1f, 0xffff0000, 0xff000000},
896 {-1.0f, 0.0f, 0.1f, 0xffff0000, 0xff000000},
897 { 0.0f, 0.0f, 0.1f, 0xffff0000, 0xff000000},
898 { 0.0f, -1.0f, 0.1f, 0xffff0000, 0xff000000},
900 /* Ok, I am too lazy to deal with transform matrices. */
901 untransformed_2[] =
903 {-1.0f, 0.0f, 1.0f, 0xffff0000, 0xff000000},
904 {-1.0f, 1.0f, 1.0f, 0xffff0000, 0xff000000},
905 { 0.0f, 1.0f, 1.0f, 0xffff0000, 0xff000000},
906 { 0.0f, 0.0f, 1.0f, 0xffff0000, 0xff000000},
908 far_quad1[] =
910 {-1.0f, -1.0f, 0.5f, 0xffff0000, 0xff000000},
911 {-1.0f, 0.0f, 0.5f, 0xffff0000, 0xff000000},
912 { 0.0f, 0.0f, 0.5f, 0xffff0000, 0xff000000},
913 { 0.0f, -1.0f, 0.5f, 0xffff0000, 0xff000000},
915 far_quad2[] =
917 {-1.0f, 0.0f, 1.5f, 0xffff0000, 0xff000000},
918 {-1.0f, 1.0f, 1.5f, 0xffff0000, 0xff000000},
919 { 0.0f, 1.0f, 1.5f, 0xffff0000, 0xff000000},
920 { 0.0f, 0.0f, 1.5f, 0xffff0000, 0xff000000},
923 /* Untransformed ones. Give them a different diffuse color to make the
924 * test look nicer. It also makes making sure that they are drawn
925 * correctly easier. */
926 static const struct
928 float x, y, z, rhw;
929 D3DCOLOR diffuse;
930 D3DCOLOR specular;
932 transformed_1[] =
934 {320.0f, 0.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
935 {640.0f, 0.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
936 {640.0f, 240.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
937 {320.0f, 240.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
939 transformed_2[] =
941 {320.0f, 240.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
942 {640.0f, 240.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
943 {640.0f, 480.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
944 {320.0f, 480.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
946 static const D3DMATRIX ident_mat =
948 1.0f, 0.0f, 0.0f, 0.0f,
949 0.0f, 1.0f, 0.0f, 0.0f,
950 0.0f, 0.0f, 1.0f, 0.0f,
951 0.0f, 0.0f, 0.0f, 1.0f,
952 }}};
953 static const D3DMATRIX world_mat1 =
955 1.0f, 0.0f, 0.0f, 0.0f,
956 0.0f, 1.0f, 0.0f, 0.0f,
957 0.0f, 0.0f, 1.0f, 0.0f,
958 0.0f, 0.0f, -0.5f, 1.0f,
959 }}};
960 static const D3DMATRIX world_mat2 =
962 1.0f, 0.0f, 0.0f, 0.0f,
963 0.0f, 1.0f, 0.0f, 0.0f,
964 0.0f, 0.0f, 1.0f, 0.0f,
965 0.0f, 0.0f, 1.0f, 1.0f,
966 }}};
967 static const D3DMATRIX proj_mat =
969 1.0f, 0.0f, 0.0f, 0.0f,
970 0.0f, 1.0f, 0.0f, 0.0f,
971 0.0f, 0.0f, 1.0f, 0.0f,
972 0.0f, 0.0f, -1.0f, 1.0f,
973 }}};
974 static const WORD Indices[] = {0, 1, 2, 2, 3, 0};
976 window = create_window();
977 d3d = Direct3DCreate8(D3D_SDK_VERSION);
978 ok(!!d3d, "Failed to create a D3D object.\n");
979 if (!(device = create_device(d3d, window, window, TRUE)))
981 skip("Failed to create a D3D device, skipping tests.\n");
982 goto done;
985 memset(&caps, 0, sizeof(caps));
986 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
987 ok(hr == D3D_OK, "IDirect3DDevice8_GetDeviceCaps returned %08x\n", hr);
988 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
989 ok(hr == D3D_OK, "IDirect3DDevice8_Clear returned %#08x\n", hr);
991 /* Setup initial states: No lighting, fog on, fog color */
992 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, FALSE);
993 ok(SUCCEEDED(hr), "Failed to disable D3DRS_ZENABLE, hr %#x.\n", hr);
994 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
995 ok(hr == D3D_OK, "Turning off lighting returned %#08x\n", hr);
996 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
997 ok(hr == D3D_OK, "Turning on fog calculations returned %#08x\n", hr);
998 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
999 ok(hr == D3D_OK, "Setting fog color returned %#08x\n", hr);
1000 /* Some of the tests seem to depend on the projection matrix explicitly
1001 * being set to an identity matrix, even though that's the default.
1002 * (AMD Radeon HD 6310, Windows 7) */
1003 hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, &ident_mat);
1004 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
1006 /* First test: Both table fog and vertex fog off */
1007 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1008 ok(hr == D3D_OK, "Turning off table fog returned %#08x\n", hr);
1009 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
1010 ok(hr == D3D_OK, "Turning off vertex fog returned %#08x\n", hr);
1012 /* Start = 0, end = 1. Should be default, but set them */
1013 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1014 ok(hr == D3D_OK, "Setting fog start returned %#08x\n", hr);
1015 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1016 ok(hr == D3D_OK, "Setting fog start returned %#08x\n", hr);
1018 hr = IDirect3DDevice8_BeginScene(device);
1019 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
1021 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1022 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
1023 /* Untransformed, vertex fog = NONE, table fog = NONE:
1024 * Read the fog weighting from the specular color. */
1025 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1026 2 /* PrimCount */, Indices, D3DFMT_INDEX16, untransformed_1, sizeof(untransformed_1[0]));
1027 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1029 /* This makes it use the Z value. */
1030 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1031 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
1032 /* Untransformed, vertex fog != none (or table fog != none):
1033 * Use the Z value as input into the equation. */
1034 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1035 2 /* PrimCount */, Indices, D3DFMT_INDEX16, untransformed_2, sizeof(untransformed_2[0]));
1036 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1038 /* Transformed vertices. */
1039 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1040 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
1041 /* Transformed, vertex fog != NONE, pixel fog == NONE:
1042 * Use specular color alpha component. */
1043 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1044 2 /* PrimCount */, Indices, D3DFMT_INDEX16, transformed_1, sizeof(transformed_1[0]));
1045 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1047 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
1048 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
1049 /* Transformed, table fog != none, vertex anything:
1050 * Use Z value as input to the fog equation. */
1051 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1052 2 /* PrimCount */, Indices, D3DFMT_INDEX16, transformed_2, sizeof(transformed_2[0]));
1053 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1055 hr = IDirect3DDevice8_EndScene(device);
1056 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
1058 color = getPixelColor(device, 160, 360);
1059 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xFF, 0x00, 0x00), 1),
1060 "Untransformed vertex with no table or vertex fog has color %08x\n", color);
1061 color = getPixelColor(device, 160, 120);
1062 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xFF, 0x00), 1),
1063 "Untransformed vertex with linear vertex fog has color %08x\n", color);
1064 color = getPixelColor(device, 480, 120);
1065 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xFF, 0xFF, 0x00), 1),
1066 "Transformed vertex with linear vertex fog has color %08x\n", color);
1067 color = getPixelColor(device, 480, 360);
1068 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xFF, 0x00), 1),
1069 "Transformed vertex with linear table fog has color %08x\n", color);
1071 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
1073 if (caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)
1075 /* A simple fog + non-identity world matrix test */
1076 hr = IDirect3DDevice8_SetTransform(device, D3DTS_WORLDMATRIX(0), &world_mat1);
1077 ok(hr == D3D_OK, "IDirect3DDevice8_SetTransform returned %#08x\n", hr);
1079 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
1080 ok(hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %#08x\n", hr);
1081 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
1082 ok(hr == D3D_OK, "Turning off vertex fog returned %#08x\n", hr);
1084 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1085 ok(hr == D3D_OK, "IDirect3DDevice8_Clear returned %#08x\n", hr);
1087 hr = IDirect3DDevice8_BeginScene(device);
1088 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
1089 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1090 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
1091 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
1092 2, Indices, D3DFMT_INDEX16, far_quad1, sizeof(far_quad1[0]));
1093 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1094 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
1095 2, Indices, D3DFMT_INDEX16, far_quad2, sizeof(far_quad2[0]));
1096 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1097 hr = IDirect3DDevice8_EndScene(device);
1098 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
1100 color = getPixelColor(device, 160, 360);
1101 ok(color_match(color, 0x00ff0000, 4), "Unfogged quad has color %08x\n", color);
1102 color = getPixelColor(device, 160, 120);
1103 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
1104 "Fogged out quad has color %08x\n", color);
1106 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
1108 /* Test fog behavior with an orthogonal (but not identity) projection matrix */
1109 hr = IDirect3DDevice8_SetTransform(device, D3DTS_WORLDMATRIX(0), &world_mat2);
1110 ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
1111 hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, &proj_mat);
1112 ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
1114 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1115 ok(hr == D3D_OK, "Clear returned %#08x\n", hr);
1117 hr = IDirect3DDevice8_BeginScene(device);
1118 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
1119 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1120 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
1121 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
1122 2, Indices, D3DFMT_INDEX16, untransformed_1, sizeof(untransformed_1[0]));
1123 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1124 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
1125 2, Indices, D3DFMT_INDEX16, untransformed_2, sizeof(untransformed_2[0]));
1126 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1127 hr = IDirect3DDevice8_EndScene(device);
1128 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
1130 color = getPixelColor(device, 160, 360);
1131 ok(color_match(color, 0x00e51900, 4), "Partially fogged quad has color %08x\n", color);
1132 color = getPixelColor(device, 160, 120);
1133 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
1134 "Fogged out quad has color %08x\n", color);
1136 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
1138 else
1140 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping some fog tests\n");
1143 refcount = IDirect3DDevice8_Release(device);
1144 ok(!refcount, "Device has %u references left.\n", refcount);
1145 done:
1146 IDirect3D8_Release(d3d);
1147 DestroyWindow(window);
1150 /* This tests fog in combination with shaders.
1151 * What's tested: linear fog (vertex and table) with pixel shader
1152 * linear table fog with non foggy vertex shader
1153 * vertex fog with foggy vertex shader, non-linear
1154 * fog with shader, non-linear fog with foggy shader,
1155 * linear table fog with foggy shader */
1156 static void fog_with_shader_test(void)
1158 /* Fill the null-shader entry with the FVF (SetVertexShader is "overloaded" on d3d8...) */
1159 DWORD vertex_shader[3] = {D3DFVF_XYZ | D3DFVF_DIFFUSE, 0, 0};
1160 DWORD pixel_shader[2] = {0, 0};
1161 IDirect3DDevice8 *device;
1162 unsigned int i, j;
1163 IDirect3D8 *d3d;
1164 D3DCOLOR color;
1165 ULONG refcount;
1166 D3DCAPS8 caps;
1167 HWND window;
1168 HRESULT hr;
1169 union
1171 float f;
1172 DWORD i;
1173 } start, end;
1175 /* Basic vertex shader without fog computation ("non foggy") */
1176 static const DWORD vertex_shader_code1[] =
1178 0xfffe0100, /* vs.1.0 */
1179 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1180 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
1181 0x0000ffff
1183 /* Basic vertex shader with reversed fog computation ("foggy") */
1184 static const DWORD vertex_shader_code2[] =
1186 0xfffe0100, /* vs.1.0 */
1187 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1188 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
1189 0x00000002, 0x800f0000, 0x90aa0000, 0xa0aa0000, /* add r0, v0.z, c0.z */
1190 0x00000005, 0xc00f0001, 0x80000000, 0xa0000000, /* mul oFog, r0.x, c0.x */
1191 0x0000ffff
1193 /* Basic pixel shader */
1194 static const DWORD pixel_shader_code[] =
1196 0xffff0101, /* ps_1_1 */
1197 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
1198 0x0000ffff
1200 static struct
1202 struct vec3 position;
1203 DWORD diffuse;
1205 quad[] =
1207 {{-1.0f, -1.0f, 0.0f}, 0xffff0000},
1208 {{-1.0f, 1.0f, 0.0f}, 0xffff0000},
1209 {{ 1.0f, -1.0f, 0.0f}, 0xffff0000},
1210 {{ 1.0f, 1.0f, 0.0f}, 0xffff0000},
1212 static const DWORD decl[] =
1214 D3DVSD_STREAM(0),
1215 D3DVSD_REG(0, D3DVSDT_FLOAT3), /* position, v0 */
1216 D3DVSD_REG(1, D3DVSDT_D3DCOLOR), /* diffuse color, v1 */
1217 D3DVSD_END()
1219 static const float vs_constant[4] = {-1.25f, 0.0f, -0.9f, 0.0f};
1220 /* This reference data was collected on a nVidia GeForce 7600GS
1221 * driver version 84.19 DirectX version 9.0c on Windows XP */
1222 static const struct test_data_t
1224 int vshader;
1225 int pshader;
1226 D3DFOGMODE vfog;
1227 D3DFOGMODE tfog;
1228 BOOL uninitialized_reg;
1229 unsigned int color[11];
1231 test_data[] =
1233 /* Only pixel shader */
1234 {0, 1, D3DFOG_NONE, D3DFOG_LINEAR, FALSE,
1235 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1236 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1237 {0, 1, D3DFOG_EXP, D3DFOG_LINEAR, FALSE,
1238 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1239 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1240 {0, 1, D3DFOG_EXP2, D3DFOG_LINEAR, FALSE,
1241 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1242 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1243 {0, 1, D3DFOG_LINEAR, D3DFOG_NONE, FALSE,
1244 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1245 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1246 {0, 1, D3DFOG_LINEAR, D3DFOG_LINEAR, FALSE,
1247 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1248 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1250 /* Vertex shader */
1251 {1, 0, D3DFOG_NONE, D3DFOG_NONE, TRUE,
1252 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1253 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1254 {1, 0, D3DFOG_NONE, D3DFOG_LINEAR, FALSE,
1255 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1256 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1257 {1, 0, D3DFOG_EXP, D3DFOG_LINEAR, FALSE,
1258 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1259 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1261 {1, 0, D3DFOG_EXP2, D3DFOG_LINEAR, FALSE,
1262 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1263 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1264 {1, 0, D3DFOG_LINEAR, D3DFOG_LINEAR, FALSE,
1265 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1266 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1268 /* Vertex shader and pixel shader */
1269 /* The next 4 tests would read the fog coord output, but it isn't available.
1270 * The result is a fully fogged quad, no matter what the Z coord is. */
1271 {1, 1, D3DFOG_NONE, D3DFOG_NONE, TRUE,
1272 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1273 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1274 {1, 1, D3DFOG_LINEAR, D3DFOG_NONE, TRUE,
1275 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1276 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1277 {1, 1, D3DFOG_EXP, D3DFOG_NONE, TRUE,
1278 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1279 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1280 {1, 1, D3DFOG_EXP2, D3DFOG_NONE, TRUE,
1281 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1282 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1284 /* These use the Z coordinate with linear table fog */
1285 {1, 1, D3DFOG_NONE, D3DFOG_LINEAR, FALSE,
1286 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1287 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1288 {1, 1, D3DFOG_EXP, D3DFOG_LINEAR, FALSE,
1289 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1290 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1291 {1, 1, D3DFOG_EXP2, D3DFOG_LINEAR, FALSE,
1292 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1293 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1294 {1, 1, D3DFOG_LINEAR, D3DFOG_LINEAR, FALSE,
1295 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1296 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1298 /* Non-linear table fog without fog coord */
1299 {1, 1, D3DFOG_NONE, D3DFOG_EXP, FALSE,
1300 {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
1301 0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
1302 {1, 1, D3DFOG_NONE, D3DFOG_EXP2, FALSE,
1303 {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
1304 0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
1306 /* These tests fail on older Nvidia drivers */
1307 /* Foggy vertex shader */
1308 {2, 0, D3DFOG_NONE, D3DFOG_NONE, FALSE,
1309 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1310 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1311 {2, 0, D3DFOG_EXP, D3DFOG_NONE, FALSE,
1312 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1313 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1314 {2, 0, D3DFOG_EXP2, D3DFOG_NONE, FALSE,
1315 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1316 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1317 {2, 0, D3DFOG_LINEAR, D3DFOG_NONE, FALSE,
1318 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1319 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1321 /* Foggy vertex shader and pixel shader. First 4 tests with vertex fog,
1322 * all using the fixed fog-coord linear fog */
1323 {2, 1, D3DFOG_NONE, D3DFOG_NONE, FALSE,
1324 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1325 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1326 {2, 1, D3DFOG_EXP, D3DFOG_NONE, FALSE,
1327 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1328 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1329 {2, 1, D3DFOG_EXP2, D3DFOG_NONE, FALSE,
1330 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1331 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1332 {2, 1, D3DFOG_LINEAR, D3DFOG_NONE, FALSE,
1333 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1334 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1336 /* These use table fog. Here the shader-provided fog coordinate is
1337 * ignored and the z coordinate used instead */
1338 {2, 1, D3DFOG_NONE, D3DFOG_EXP, FALSE,
1339 {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
1340 0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
1341 {2, 1, D3DFOG_NONE, D3DFOG_EXP2, FALSE,
1342 {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
1343 0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
1344 {2, 1, D3DFOG_NONE, D3DFOG_LINEAR, FALSE,
1345 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1346 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1348 static const D3DMATRIX identity =
1350 1.0f, 0.0f, 0.0f, 0.0f,
1351 0.0f, 1.0f, 0.0f, 0.0f,
1352 0.0f, 0.0f, 1.0f, 0.0f,
1353 0.0f, 0.0f, 0.0f, 1.0f,
1354 }}};
1356 window = create_window();
1357 d3d = Direct3DCreate8(D3D_SDK_VERSION);
1358 ok(!!d3d, "Failed to create a D3D object.\n");
1359 if (!(device = create_device(d3d, window, window, TRUE)))
1361 skip("Failed to create a D3D device, skipping tests.\n");
1362 goto done;
1365 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
1366 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
1367 if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1) || caps.PixelShaderVersion < D3DPS_VERSION(1, 1))
1369 skip("No vs_1_1 / ps_1_1 support, skipping tests.\n");
1370 IDirect3DDevice8_Release(device);
1371 goto done;
1374 /* NOTE: changing these values will not affect the tests with foggy vertex
1375 * shader, as the values are hardcoded in the shader constant. */
1376 start.f = 0.1f;
1377 end.f = 0.9f;
1379 /* Some of the tests seem to depend on the projection matrix explicitly
1380 * being set to an identity matrix, even though that's the default.
1381 * (AMD Radeon HD 6310, Windows 7) */
1382 hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, &identity);
1383 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
1385 hr = IDirect3DDevice8_CreateVertexShader(device, decl, vertex_shader_code1, &vertex_shader[1], 0);
1386 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1387 hr = IDirect3DDevice8_CreateVertexShader(device, decl, vertex_shader_code2, &vertex_shader[2], 0);
1388 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1389 hr = IDirect3DDevice8_CreatePixelShader(device, pixel_shader_code, &pixel_shader[1]);
1390 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1392 /* Set shader constant value */
1393 hr = IDirect3DDevice8_SetVertexShader(device, vertex_shader[2]);
1394 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1395 hr = IDirect3DDevice8_SetVertexShaderConstant(device, 0, vs_constant, 1);
1396 ok(hr == D3D_OK, "Setting vertex shader constant failed (%08x)\n", hr);
1398 /* Setup initial states: No lighting, fog on, fog color */
1399 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1400 ok(hr == D3D_OK, "Turning off lighting failed (%08x)\n", hr);
1401 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
1402 ok(hr == D3D_OK, "Turning on fog calculations failed (%08x)\n", hr);
1403 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
1404 ok(hr == D3D_OK, "Setting fog color failed (%08x)\n", hr);
1406 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1407 ok(hr == D3D_OK, "Turning off table fog failed (%08x)\n", hr);
1408 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
1409 ok(hr == D3D_OK, "Turning off vertex fog failed (%08x)\n", hr);
1411 /* Use fogtart = 0.1 and end = 0.9 to test behavior outside the fog transition phase, too */
1412 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGSTART, start.i);
1413 ok(hr == D3D_OK, "Setting fog start failed (%08x)\n", hr);
1414 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGEND, end.i);
1415 ok(hr == D3D_OK, "Setting fog end failed (%08x)\n", hr);
1417 for (i = 0; i < sizeof(test_data)/sizeof(test_data[0]); ++i)
1419 hr = IDirect3DDevice8_SetVertexShader(device, vertex_shader[test_data[i].vshader]);
1420 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1421 hr = IDirect3DDevice8_SetPixelShader(device, pixel_shader[test_data[i].pshader]);
1422 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1423 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGVERTEXMODE, test_data[i].vfog);
1424 ok( hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1425 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGTABLEMODE, test_data[i].tfog);
1426 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1428 for(j = 0; j < 11; ++j)
1430 /* Don't use the whole zrange to prevent rounding errors */
1431 quad[0].position.z = 0.001f + j / 10.02f;
1432 quad[1].position.z = 0.001f + j / 10.02f;
1433 quad[2].position.z = 0.001f + j / 10.02f;
1434 quad[3].position.z = 0.001f + j / 10.02f;
1436 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff00ff, 1.0f, 0);
1437 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
1439 hr = IDirect3DDevice8_BeginScene(device);
1440 ok( hr == D3D_OK, "BeginScene returned failed (%08x)\n", hr);
1442 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1443 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
1445 hr = IDirect3DDevice8_EndScene(device);
1446 ok(hr == D3D_OK, "EndScene failed (%08x)\n", hr);
1448 /* As the red and green component are the result of blending use 5% tolerance on the expected value */
1449 color = getPixelColor(device, 128, 240);
1450 ok(color_match(color, test_data[i].color[j], 13) || broken(test_data[i].uninitialized_reg),
1451 "fog vs%i ps%i fvm%i ftm%i %d: got color %08x, expected %08x +-5%%\n",
1452 test_data[i].vshader, test_data[i].pshader,
1453 test_data[i].vfog, test_data[i].tfog, j, color, test_data[i].color[j]);
1456 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
1458 IDirect3DDevice8_DeleteVertexShader(device, vertex_shader[1]);
1459 IDirect3DDevice8_DeleteVertexShader(device, vertex_shader[2]);
1460 IDirect3DDevice8_DeleteVertexShader(device, pixel_shader[1]);
1461 refcount = IDirect3DDevice8_Release(device);
1462 ok(!refcount, "Device has %u references left.\n", refcount);
1463 done:
1464 IDirect3D8_Release(d3d);
1465 DestroyWindow(window);
1468 static void cnd_test(void)
1470 DWORD shader_11_coissue_2, shader_12_coissue_2, shader_13_coissue_2, shader_14_coissue_2;
1471 DWORD shader_11_coissue, shader_12_coissue, shader_13_coissue, shader_14_coissue;
1472 DWORD shader_11, shader_12, shader_13, shader_14;
1473 IDirect3DDevice8 *device;
1474 IDirect3D8 *d3d;
1475 ULONG refcount;
1476 D3DCAPS8 caps;
1477 DWORD color;
1478 HWND window;
1479 HRESULT hr;
1481 /* ps 1.x shaders are rather picky with writemasks and source swizzles.
1482 * The dp3 is used to copy r0.r to all components of r1, then copy r1.a to
1483 * r0.a. Essentially it does a mov r0.a, r0.r, which isn't allowed as-is
1484 * in 1.x pixel shaders. */
1485 static const DWORD shader_code_11[] =
1487 0xffff0101, /* ps_1_1 */
1488 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
1489 0x00000040, 0xb00f0000, /* texcoord t0 */
1490 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
1491 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3 r1, r0, c0 */
1492 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
1493 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
1494 0x0000ffff /* end */
1496 static const DWORD shader_code_12[] =
1498 0xffff0102, /* ps_1_2 */
1499 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
1500 0x00000040, 0xb00f0000, /* texcoord t0 */
1501 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
1502 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3 r1, r0, c0 */
1503 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
1504 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
1505 0x0000ffff /* end */
1507 static const DWORD shader_code_13[] =
1509 0xffff0103, /* ps_1_3 */
1510 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
1511 0x00000040, 0xb00f0000, /* texcoord t0 */
1512 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
1513 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3, r1, r0, c0 */
1514 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
1515 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
1516 0x0000ffff /* end */
1518 static const DWORD shader_code_14[] =
1520 0xffff0104, /* ps_1_3 */
1521 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
1522 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0, t0 */
1523 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
1524 0x00000050, 0x800f0000, 0x80e40000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0, c1, c2 */
1525 0x0000ffff /* end */
1528 /* Special fun: The coissue flag on cnd: Apparently cnd always selects the 2nd source,
1529 * as if the src0 comparison against 0.5 always evaluates to true. The coissue flag isn't
1530 * set by the compiler, it was added manually after compilation. Note that the COISSUE
1531 * flag on a color(.xyz) operation is only allowed after an alpha operation. DirectX doesn't
1532 * have proper docs, but GL_ATI_fragment_shader explains the pairing of color and alpha ops
1533 * well enough.
1535 * The shader attempts to test the range [-1;1] against coissued cnd, which is a bit tricky.
1536 * The input from t0 is [0;1]. 0.5 is subtracted, then we have to multiply with 2. Since
1537 * constants are clamped to [-1;1], a 2.0 is constructed by adding c0.r(=1.0) to c0.r into r1.r,
1538 * then r1(2.0, 0.0, 0.0, 0.0) is passed to dp3(explained above).
1540 static const DWORD shader_code_11_coissue[] =
1542 0xffff0101, /* ps_1_1 */
1543 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
1544 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
1545 0x00000040, 0xb00f0000, /* texcoord t0 */
1546 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
1547 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
1548 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
1549 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
1550 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
1551 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.xyz, r0.a, c1, c2*/
1552 0x0000ffff /* end */
1554 static const DWORD shader_code_11_coissue_2[] =
1556 0xffff0101, /* ps_1_1 */
1557 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
1558 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
1559 0x00000040, 0xb00f0000, /* texcoord t0 */
1560 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
1561 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
1562 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
1563 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
1564 0x00000001, 0x800f0000, 0x80e40001, /* mov r0, r1 */
1565 0x00000001, 0x80070000, 0x80ff0001, /* mov r0.xyz, r1.a */
1566 0x40000050, 0x80080000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.a, r0.a, c1, c2 */
1567 0x00000001, 0x80070000, 0x80ff0000, /* mov r0.xyz, r0.a */
1568 0x0000ffff /* end */
1570 static const DWORD shader_code_12_coissue[] =
1572 0xffff0102, /* ps_1_2 */
1573 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
1574 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
1575 0x00000040, 0xb00f0000, /* texcoord t0 */
1576 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
1577 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
1578 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
1579 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
1580 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
1581 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.xyz, r0.a, c1, c2*/
1582 0x0000ffff /* end */
1584 static const DWORD shader_code_12_coissue_2[] =
1586 0xffff0102, /* ps_1_2 */
1587 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
1588 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
1589 0x00000040, 0xb00f0000, /* texcoord t0 */
1590 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
1591 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
1592 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
1593 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
1594 0x00000001, 0x800f0000, 0x80e40001, /* mov r0, r1 */
1595 0x00000001, 0x80070000, 0x80ff0001, /* mov r0.xyz, r1.a */
1596 0x40000050, 0x80080000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.a, r0.a, c1, c2 */
1597 0x00000001, 0x80070000, 0x80ff0000, /* mov r0.xyz, r0.a */
1598 0x0000ffff /* end */
1600 static const DWORD shader_code_13_coissue[] =
1602 0xffff0103, /* ps_1_3 */
1603 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
1604 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
1605 0x00000040, 0xb00f0000, /* texcoord t0 */
1606 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
1607 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
1608 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
1609 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
1610 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
1611 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.xyz, r0.a, c1, c2*/
1612 0x0000ffff /* end */
1614 static const DWORD shader_code_13_coissue_2[] =
1616 0xffff0103, /* ps_1_3 */
1617 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
1618 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
1619 0x00000040, 0xb00f0000, /* texcoord t0 */
1620 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
1621 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
1622 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
1623 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
1624 0x00000001, 0x800f0000, 0x80e40001, /* mov r0, r1 */
1625 0x00000001, 0x80070000, 0x80ff0001, /* mov r0.xyz, r1.a */
1626 0x40000050, 0x80080000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.a, r0.a, c1, c2 */
1627 0x00000001, 0x80070000, 0x80ff0000, /* mov r0.xyz, r0.a */
1628 0x0000ffff /* end */
1630 /* ps_1_4 does not have a different cnd behavior, just pass the [0;1]
1631 * texcrd result to cnd, it will compare against 0.5. */
1632 static const DWORD shader_code_14_coissue[] =
1634 0xffff0104, /* ps_1_4 */
1635 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
1636 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0.xyz, t0 */
1637 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
1638 0x40000050, 0x80070000, 0x80e40000, 0xa0e40001, 0xa0e40002, /* +cnd r0.xyz, r0, c1, c2 */
1639 0x0000ffff /* end */
1641 static const DWORD shader_code_14_coissue_2[] =
1643 0xffff0104, /* ps_1_4 */
1644 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
1645 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0.xyz, t0 */
1646 0x00000001, 0x80080000, 0x80000000, /* mov r0.a, r0.x */
1647 0x00000001, 0x80070001, 0xa0ff0000, /* mov r1.xyz, c0.a */
1648 0x40000050, 0x80080001, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r1.a, r0.a, c1, c2 */
1649 0x00000001, 0x80070000, 0x80ff0001, /* mov r0.xyz, r1.a */
1650 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
1651 0x0000ffff /* end */
1653 static const float quad1[] =
1655 -1.0f, -1.0f, 0.1f, 0.0f, 0.0f, 1.0f,
1656 -1.0f, 0.0f, 0.1f, 0.0f, 1.0f, 0.0f,
1657 0.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f,
1658 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 0.0f
1660 static const float quad2[] =
1662 0.0f, -1.0f, 0.1f, 0.0f, 0.0f, 1.0f,
1663 0.0f, 0.0f, 0.1f, 0.0f, 1.0f, 0.0f,
1664 1.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f,
1665 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 0.0f
1667 static const float quad3[] =
1669 0.0f, 0.0f, 0.1f, 0.0f, 0.0f, 1.0f,
1670 0.0f, 1.0f, 0.1f, 0.0f, 1.0f, 0.0f,
1671 1.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f,
1672 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 0.0f
1674 static const float quad4[] =
1676 -1.0f, 0.0f, 0.1f, 0.0f, 0.0f, 1.0f,
1677 -1.0f, 1.0f, 0.1f, 0.0f, 1.0f, 0.0f,
1678 0.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f,
1679 0.0f, 1.0f, 0.1f, 1.0f, 1.0f, 0.0f
1681 static const float test_data_c1[4] = {0.0f, 0.0f, 0.0f, 0.0f};
1682 static const float test_data_c2[4] = {1.0f, 1.0f, 1.0f, 1.0f};
1683 static const float test_data_c1_coi[4] = {0.0f, 1.0f, 0.0f, 0.0f};
1684 static const float test_data_c2_coi[4] = {1.0f, 0.0f, 1.0f, 1.0f};
1686 window = create_window();
1687 d3d = Direct3DCreate8(D3D_SDK_VERSION);
1688 ok(!!d3d, "Failed to create a D3D object.\n");
1689 if (!(device = create_device(d3d, window, window, TRUE)))
1691 skip("Failed to create a D3D device, skipping tests.\n");
1692 goto done;
1695 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
1696 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
1697 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 4))
1699 skip("No ps_1_4 support, skipping tests.\n");
1700 IDirect3DDevice8_Release(device);
1701 goto done;
1704 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
1705 ok(hr == D3D_OK, "IDirect3DDevice8_Clear returned %08x\n", hr);
1707 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code_11, &shader_11);
1708 ok(hr == D3D_OK, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr);
1709 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code_12, &shader_12);
1710 ok(hr == D3D_OK, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr);
1711 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code_13, &shader_13);
1712 ok(hr == D3D_OK, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr);
1713 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code_14, &shader_14);
1714 ok(hr == D3D_OK, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr);
1715 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code_11_coissue, &shader_11_coissue);
1716 ok(hr == D3D_OK, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr);
1717 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code_12_coissue, &shader_12_coissue);
1718 ok(hr == D3D_OK, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr);
1719 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code_13_coissue, &shader_13_coissue);
1720 ok(hr == D3D_OK, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr);
1721 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code_14_coissue, &shader_14_coissue);
1722 ok(hr == D3D_OK, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr);
1723 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code_11_coissue_2, &shader_11_coissue_2);
1724 ok(hr == D3D_OK, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr);
1725 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code_12_coissue_2, &shader_12_coissue_2);
1726 ok(hr == D3D_OK, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr);
1727 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code_13_coissue_2, &shader_13_coissue_2);
1728 ok(hr == D3D_OK, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr);
1729 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code_14_coissue_2, &shader_14_coissue_2);
1730 ok(hr == D3D_OK, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr);
1732 hr = IDirect3DDevice8_SetPixelShaderConstant(device, 1, test_data_c1, 1);
1733 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShaderConstant returned %08x\n", hr);
1734 hr = IDirect3DDevice8_SetPixelShaderConstant(device, 2, test_data_c2, 1);
1735 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShaderConstant returned %08x\n", hr);
1736 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX1);
1737 ok(hr == D3D_OK, "IDirect3DDevice8_SetVertexShader returned %#08x\n", hr);
1739 hr = IDirect3DDevice8_BeginScene(device);
1740 ok(hr == D3D_OK, "IDirect3DDevice8_BeginScene returned %08x\n", hr);
1742 hr = IDirect3DDevice8_SetPixelShader(device, shader_11);
1743 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr);
1744 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
1745 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
1747 hr = IDirect3DDevice8_SetPixelShader(device, shader_12);
1748 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr);
1749 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
1750 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
1752 hr = IDirect3DDevice8_SetPixelShader(device, shader_13);
1753 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr);
1754 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
1755 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
1757 hr = IDirect3DDevice8_SetPixelShader(device, shader_14);
1758 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr);
1759 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
1760 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
1762 hr = IDirect3DDevice8_EndScene(device);
1763 ok(hr == D3D_OK, "IDirect3DDevice8_EndScene returned %08x\n", hr);
1765 hr = IDirect3DDevice8_SetPixelShader(device, 0);
1766 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr);
1768 /* This is the 1.4 test. Each component(r, g, b) is tested separately against 0.5 */
1769 color = getPixelColor(device, 158, 118);
1770 ok(color == 0x00ff00ff, "pixel 158, 118 has color %08x, expected 0x00ff00ff\n", color);
1771 color = getPixelColor(device, 162, 118);
1772 ok(color == 0x000000ff, "pixel 162, 118 has color %08x, expected 0x000000ff\n", color);
1773 color = getPixelColor(device, 158, 122);
1774 ok(color == 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color);
1775 color = getPixelColor(device, 162, 122);
1776 ok(color == 0x0000ffff, "pixel 162, 122 has color %08x, expected 0x0000ffff\n", color);
1778 /* 1.1 shader. All 3 components get set, based on the .w comparison */
1779 color = getPixelColor(device, 158, 358);
1780 ok(color == 0x00ffffff, "pixel 158, 358 has color %08x, expected 0x00ffffff\n", color);
1781 color = getPixelColor(device, 162, 358);
1782 ok(color_match(color, 0x00000000, 1),
1783 "pixel 162, 358 has color %08x, expected 0x00000000\n", color);
1784 color = getPixelColor(device, 158, 362);
1785 ok(color == 0x00ffffff, "pixel 158, 362 has color %08x, expected 0x00ffffff\n", color);
1786 color = getPixelColor(device, 162, 362);
1787 ok(color_match(color, 0x00000000, 1),
1788 "pixel 162, 362 has color %08x, expected 0x00000000\n", color);
1790 /* 1.2 shader */
1791 color = getPixelColor(device, 478, 358);
1792 ok(color == 0x00ffffff, "pixel 478, 358 has color %08x, expected 0x00ffffff\n", color);
1793 color = getPixelColor(device, 482, 358);
1794 ok(color_match(color, 0x00000000, 1),
1795 "pixel 482, 358 has color %08x, expected 0x00000000\n", color);
1796 color = getPixelColor(device, 478, 362);
1797 ok(color == 0x00ffffff, "pixel 478, 362 has color %08x, expected 0x00ffffff\n", color);
1798 color = getPixelColor(device, 482, 362);
1799 ok(color_match(color, 0x00000000, 1),
1800 "pixel 482, 362 has color %08x, expected 0x00000000\n", color);
1802 /* 1.3 shader */
1803 color = getPixelColor(device, 478, 118);
1804 ok(color == 0x00ffffff, "pixel 478, 118 has color %08x, expected 0x00ffffff\n", color);
1805 color = getPixelColor(device, 482, 118);
1806 ok(color_match(color, 0x00000000, 1),
1807 "pixel 482, 118 has color %08x, expected 0x00000000\n", color);
1808 color = getPixelColor(device, 478, 122);
1809 ok(color == 0x00ffffff, "pixel 478, 122 has color %08x, expected 0x00ffffff\n", color);
1810 color = getPixelColor(device, 482, 122);
1811 ok(color_match(color, 0x00000000, 1),
1812 "pixel 482, 122 has color %08x, expected 0x00000000\n", color);
1814 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
1815 ok(hr == D3D_OK, "IDirect3DDevice8_Present failed with %08x\n", hr);
1817 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0f, 0);
1818 ok(hr == D3D_OK, "IDirect3DDevice8_Clear returned %08x\n", hr);
1819 hr = IDirect3DDevice8_SetPixelShaderConstant(device, 1, test_data_c1_coi, 1);
1820 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShaderConstant returned %08x\n", hr);
1821 hr = IDirect3DDevice8_SetPixelShaderConstant(device, 2, test_data_c2_coi, 1);
1822 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShaderConstant returned %08x\n", hr);
1824 hr = IDirect3DDevice8_BeginScene(device);
1825 ok(hr == D3D_OK, "IDirect3DDevice8_BeginScene returned %08x\n", hr);
1827 hr = IDirect3DDevice8_SetPixelShader(device, shader_11_coissue);
1828 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr);
1829 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
1830 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
1832 hr = IDirect3DDevice8_SetPixelShader(device, shader_12_coissue);
1833 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr);
1834 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
1835 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
1837 hr = IDirect3DDevice8_SetPixelShader(device, shader_13_coissue);
1838 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr);
1839 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
1840 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
1842 hr = IDirect3DDevice8_SetPixelShader(device, shader_14_coissue);
1843 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr);
1844 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
1845 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
1847 hr = IDirect3DDevice8_EndScene(device);
1848 ok(hr == D3D_OK, "IDirect3DDevice8_EndScene returned %08x\n", hr);
1850 hr = IDirect3DDevice8_SetPixelShader(device, 0);
1851 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr);
1853 /* This is the 1.4 test. The coissue doesn't change the behavior here, but keep in mind
1854 * that we swapped the values in c1 and c2 to make the other tests return some color
1856 color = getPixelColor(device, 158, 118);
1857 ok(color == 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color);
1858 color = getPixelColor(device, 162, 118);
1859 ok(color == 0x0000ffff, "pixel 162, 118 has color %08x, expected 0x0000ffff\n", color);
1860 color = getPixelColor(device, 158, 122);
1861 ok(color == 0x00ff00ff, "pixel 162, 122 has color %08x, expected 0x00ff00ff\n", color);
1862 color = getPixelColor(device, 162, 122);
1863 ok(color == 0x000000ff, "pixel 162, 122 has color %08x, expected 0x000000ff\n", color);
1865 /* 1.1 shader. coissue flag changed the semantic of cnd, c1 is always selected
1866 * (The Win7 nvidia driver always selects c2)
1868 color = getPixelColor(device, 158, 358);
1869 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
1870 "pixel 158, 358 has color %08x, expected 0x0000ff00\n", color);
1871 color = getPixelColor(device, 162, 358);
1872 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
1873 "pixel 162, 358 has color %08x, expected 0x0000ff00\n", color);
1874 color = getPixelColor(device, 158, 362);
1875 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
1876 "pixel 158, 362 has color %08x, expected 0x0000ff00\n", color);
1877 color = getPixelColor(device, 162, 362);
1878 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
1879 "pixel 162, 362 has color %08x, expected 0x0000ff00\n", color);
1881 /* 1.2 shader */
1882 color = getPixelColor(device, 478, 358);
1883 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
1884 "pixel 478, 358 has color %08x, expected 0x0000ff00\n", color);
1885 color = getPixelColor(device, 482, 358);
1886 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
1887 "pixel 482, 358 has color %08x, expected 0x0000ff00\n", color);
1888 color = getPixelColor(device, 478, 362);
1889 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
1890 "pixel 478, 362 has color %08x, expected 0x0000ff00\n", color);
1891 color = getPixelColor(device, 482, 362);
1892 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
1893 "pixel 482, 362 has color %08x, expected 0x0000ff00\n", color);
1895 /* 1.3 shader */
1896 color = getPixelColor(device, 478, 118);
1897 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
1898 "pixel 478, 118 has color %08x, expected 0x0000ff00\n", color);
1899 color = getPixelColor(device, 482, 118);
1900 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
1901 "pixel 482, 118 has color %08x, expected 0x0000ff00\n", color);
1902 color = getPixelColor(device, 478, 122);
1903 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
1904 "pixel 478, 122 has color %08x, expected 0x0000ff00\n", color);
1905 color = getPixelColor(device, 482, 122);
1906 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
1907 "pixel 482, 122 has color %08x, expected 0x0000ff00\n", color);
1909 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
1910 ok(hr == D3D_OK, "IDirect3DDevice8_Present failed with %08x\n", hr);
1912 /* Retest with the coissue flag on the alpha instruction instead. This
1913 * works "as expected". The Windows 8 testbot (WARP) seems to handle this
1914 * the same as coissue on .rgb. */
1915 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0f, 0);
1916 ok(hr == D3D_OK, "IDirect3DDevice8_Clear returned %08x\n", hr);
1918 hr = IDirect3DDevice8_BeginScene(device);
1919 ok(hr == D3D_OK, "IDirect3DDevice8_BeginScene returned %08x\n", hr);
1921 hr = IDirect3DDevice8_SetPixelShader(device, shader_11_coissue_2);
1922 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr);
1923 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
1924 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
1926 hr = IDirect3DDevice8_SetPixelShader(device, shader_12_coissue_2);
1927 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr);
1928 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
1929 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
1931 hr = IDirect3DDevice8_SetPixelShader(device, shader_13_coissue_2);
1932 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr);
1933 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
1934 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
1936 hr = IDirect3DDevice8_SetPixelShader(device, shader_14_coissue_2);
1937 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr);
1938 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
1939 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
1941 hr = IDirect3DDevice8_EndScene(device);
1942 ok(hr == D3D_OK, "IDirect3DDevice8_EndScene returned %08x\n", hr);
1944 /* 1.4 shader */
1945 color = getPixelColor(device, 158, 118);
1946 ok(color == 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color);
1947 color = getPixelColor(device, 162, 118);
1948 ok(color == 0x00000000, "pixel 162, 118 has color %08x, expected 0x00000000\n", color);
1949 color = getPixelColor(device, 158, 122);
1950 ok(color == 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color);
1951 color = getPixelColor(device, 162, 122);
1952 ok(color == 0x00000000, "pixel 162, 122 has color %08x, expected 0x00000000\n", color);
1954 /* 1.1 shader */
1955 color = getPixelColor(device, 238, 358);
1956 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
1957 "pixel 238, 358 has color %08x, expected 0x00ffffff\n", color);
1958 color = getPixelColor(device, 242, 358);
1959 ok(color_match(color, 0x00000000, 1),
1960 "pixel 242, 358 has color %08x, expected 0x00000000\n", color);
1961 color = getPixelColor(device, 238, 362);
1962 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
1963 "pixel 238, 362 has color %08x, expected 0x00ffffff\n", color);
1964 color = getPixelColor(device, 242, 362);
1965 ok(color_match(color, 0x00000000, 1),
1966 "pixel 242, 362 has color %08x, expected 0x00000000\n", color);
1968 /* 1.2 shader */
1969 color = getPixelColor(device, 558, 358);
1970 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
1971 "pixel 558, 358 has color %08x, expected 0x00ffffff\n", color);
1972 color = getPixelColor(device, 562, 358);
1973 ok(color_match(color, 0x00000000, 1),
1974 "pixel 562, 358 has color %08x, expected 0x00000000\n", color);
1975 color = getPixelColor(device, 558, 362);
1976 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
1977 "pixel 558, 362 has color %08x, expected 0x00ffffff\n", color);
1978 color = getPixelColor(device, 562, 362);
1979 ok(color_match(color, 0x00000000, 1),
1980 "pixel 562, 362 has color %08x, expected 0x00000000\n", color);
1982 /* 1.3 shader */
1983 color = getPixelColor(device, 558, 118);
1984 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
1985 "pixel 558, 118 has color %08x, expected 0x00ffffff\n", color);
1986 color = getPixelColor(device, 562, 118);
1987 ok(color_match(color, 0x00000000, 1),
1988 "pixel 562, 118 has color %08x, expected 0x00000000\n", color);
1989 color = getPixelColor(device, 558, 122);
1990 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
1991 "pixel 558, 122 has color %08x, expected 0x00ffffff\n", color);
1992 color = getPixelColor(device, 562, 122);
1993 ok(color_match(color, 0x00000000, 1),
1994 "pixel 562, 122 has color %08x, expected 0x00000000\n", color);
1996 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
1997 ok(hr == D3D_OK, "IDirect3DDevice8_Present failed with %08x\n", hr);
1999 IDirect3DDevice8_DeletePixelShader(device, shader_14_coissue_2);
2000 IDirect3DDevice8_DeletePixelShader(device, shader_13_coissue_2);
2001 IDirect3DDevice8_DeletePixelShader(device, shader_12_coissue_2);
2002 IDirect3DDevice8_DeletePixelShader(device, shader_11_coissue_2);
2003 IDirect3DDevice8_DeletePixelShader(device, shader_14_coissue);
2004 IDirect3DDevice8_DeletePixelShader(device, shader_13_coissue);
2005 IDirect3DDevice8_DeletePixelShader(device, shader_12_coissue);
2006 IDirect3DDevice8_DeletePixelShader(device, shader_11_coissue);
2007 IDirect3DDevice8_DeletePixelShader(device, shader_14);
2008 IDirect3DDevice8_DeletePixelShader(device, shader_13);
2009 IDirect3DDevice8_DeletePixelShader(device, shader_12);
2010 IDirect3DDevice8_DeletePixelShader(device, shader_11);
2011 refcount = IDirect3DDevice8_Release(device);
2012 ok(!refcount, "Device has %u references left.\n", refcount);
2013 done:
2014 IDirect3D8_Release(d3d);
2015 DestroyWindow(window);
2018 static void z_range_test(void)
2020 IDirect3DDevice8 *device;
2021 IDirect3D8 *d3d;
2022 D3DCOLOR color;
2023 ULONG refcount;
2024 D3DCAPS8 caps;
2025 DWORD shader;
2026 HWND window;
2027 HRESULT hr;
2029 static const struct
2031 struct vec3 position;
2032 DWORD diffuse;
2034 quad[] =
2036 {{-1.0f, 0.0f, 1.1f}, 0xffff0000},
2037 {{-1.0f, 1.0f, 1.1f}, 0xffff0000},
2038 {{ 1.0f, 0.0f, -1.1f}, 0xffff0000},
2039 {{ 1.0f, 1.0f, -1.1f}, 0xffff0000},
2041 quad2[] =
2043 {{-1.0f, 0.0f, 1.1f}, 0xff0000ff},
2044 {{-1.0f, 1.0f, 1.1f}, 0xff0000ff},
2045 {{ 1.0f, 0.0f, -1.1f}, 0xff0000ff},
2046 {{ 1.0f, 1.0f, -1.1f}, 0xff0000ff},
2048 static const struct
2050 struct vec4 position;
2051 DWORD diffuse;
2053 quad3[] =
2055 {{640.0f, 240.0f, -1.1f, 1.0f}, 0xffffff00},
2056 {{640.0f, 480.0f, -1.1f, 1.0f}, 0xffffff00},
2057 {{ 0.0f, 240.0f, 1.1f, 1.0f}, 0xffffff00},
2058 {{ 0.0f, 480.0f, 1.1f, 1.0f}, 0xffffff00},
2060 quad4[] =
2062 {{640.0f, 240.0f, -1.1f, 1.0f}, 0xff00ff00},
2063 {{640.0f, 480.0f, -1.1f, 1.0f}, 0xff00ff00},
2064 {{ 0.0f, 240.0f, 1.1f, 1.0f}, 0xff00ff00},
2065 {{ 0.0f, 480.0f, 1.1f, 1.0f}, 0xff00ff00},
2067 static const DWORD shader_code[] =
2069 0xfffe0101, /* vs_1_1 */
2070 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
2071 0x00000001, 0xd00f0000, 0xa0e40000, /* mov oD0, c0 */
2072 0x0000ffff /* end */
2074 static const float color_const_1[] = {1.0f, 0.0f, 0.0f, 1.0f};
2075 static const float color_const_2[] = {0.0f, 0.0f, 1.0f, 1.0f};
2076 static const DWORD vertex_declaration[] =
2078 D3DVSD_STREAM(0),
2079 D3DVSD_REG(D3DVSDE_POSITION, D3DVSDT_FLOAT3),
2080 D3DVSD_END()
2083 window = create_window();
2084 d3d = Direct3DCreate8(D3D_SDK_VERSION);
2085 ok(!!d3d, "Failed to create a D3D object.\n");
2086 if (!(device = create_device(d3d, window, window, TRUE)))
2088 skip("Failed to create a D3D device, skipping tests.\n");
2089 goto done;
2092 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
2093 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
2095 /* Does the Present clear the depth stencil? Clear the depth buffer with some value != 0,
2096 * then call Present. Then clear the color buffer to make sure it has some defined content
2097 * after the Present with D3DSWAPEFFECT_DISCARD. After that draw a plane that is somewhere cut
2098 * by the depth value. */
2099 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.75f, 0);
2100 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
2101 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
2102 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
2103 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
2104 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
2106 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
2107 ok(SUCCEEDED(hr), "Failed to disabled lighting, hr %#x.\n", hr);
2108 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, TRUE);
2109 ok(SUCCEEDED(hr), "Failed to enable clipping, hr %#x.\n", hr);
2110 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
2111 ok(SUCCEEDED(hr), "Failed to enable z test, hr %#x.\n", hr);
2112 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
2113 ok(SUCCEEDED(hr), "Failed to disable z writes, hr %#x.\n", hr);
2114 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
2115 ok(SUCCEEDED(hr), "Failed to set z function, hr %#x.\n", hr);
2116 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
2117 ok(SUCCEEDED(hr), "Failed set FVF, hr %#x.\n", hr);
2119 hr = IDirect3DDevice8_BeginScene(device);
2120 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
2122 /* Test the untransformed vertex path */
2123 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
2124 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2125 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
2126 ok(SUCCEEDED(hr), "Failed to set z function, hr %#x.\n", hr);
2127 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
2128 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2130 /* Test the transformed vertex path */
2131 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
2132 ok(SUCCEEDED(hr), "Failed set FVF, hr %#x.\n", hr);
2134 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(quad4[0]));
2135 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2136 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
2137 ok(SUCCEEDED(hr), "Failed to set z function, hr %#x.\n", hr);
2138 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(quad3[0]));
2139 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2141 hr = IDirect3DDevice8_EndScene(device);
2142 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
2144 /* Do not test the exact corner pixels, but go pretty close to them */
2146 /* Clipped because z > 1.0 */
2147 color = getPixelColor(device, 28, 238);
2148 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2149 color = getPixelColor(device, 28, 241);
2150 if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
2151 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2152 else
2153 ok(color_match(color, 0x00ffff00, 0), "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2155 /* Not clipped, > z buffer clear value(0.75).
2157 * On the r500 driver on Windows D3DCMP_GREATER and D3DCMP_GREATEREQUAL are broken for depth
2158 * values > 0.5. The range appears to be distorted, apparently an incoming value of ~0.875 is
2159 * equal to a stored depth buffer value of 0.5. */
2160 color = getPixelColor(device, 31, 238);
2161 ok(color_match(color, 0x00ff0000, 0), "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2162 color = getPixelColor(device, 31, 241);
2163 ok(color_match(color, 0x00ffff00, 0), "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2164 color = getPixelColor(device, 100, 238);
2165 ok(color_match(color, 0x00ff0000, 0) || broken(color_match(color, 0x00ffffff, 0)),
2166 "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2167 color = getPixelColor(device, 100, 241);
2168 ok(color_match(color, 0x00ffff00, 0) || broken(color_match(color, 0x00ffffff, 0)),
2169 "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2171 /* Not clipped, < z buffer clear value */
2172 color = getPixelColor(device, 104, 238);
2173 ok(color_match(color, 0x000000ff, 0), "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2174 color = getPixelColor(device, 104, 241);
2175 ok(color_match(color, 0x0000ff00, 0), "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
2176 color = getPixelColor(device, 318, 238);
2177 ok(color_match(color, 0x000000ff, 0), "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2178 color = getPixelColor(device, 318, 241);
2179 ok(color_match(color, 0x0000ff00, 0), "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
2181 /* Clipped because z < 0.0 */
2182 color = getPixelColor(device, 321, 238);
2183 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2184 color = getPixelColor(device, 321, 241);
2185 if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
2186 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2187 else
2188 ok(color_match(color, 0x0000ff00, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2190 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
2191 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
2193 /* Test the shader path */
2194 if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1))
2196 skip("Vertex shaders not supported\n");
2197 IDirect3DDevice8_Release(device);
2198 goto done;
2200 hr = IDirect3DDevice8_CreateVertexShader(device, vertex_declaration, shader_code, &shader, 0);
2201 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
2203 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
2204 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
2206 hr = IDirect3DDevice8_SetVertexShader(device, shader);
2207 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
2209 hr = IDirect3DDevice8_BeginScene(device);
2210 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
2212 hr = IDirect3DDevice8_SetVertexShaderConstant(device, 0, color_const_1, 1);
2213 ok(SUCCEEDED(hr), "Failed to set vs constant 0, hr %#x.\n", hr);
2214 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
2215 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2217 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
2218 ok(SUCCEEDED(hr), "Failed to set z function, hr %#x.\n", hr);
2219 hr = IDirect3DDevice8_SetVertexShaderConstant(device, 0, color_const_2, 1);
2220 ok(SUCCEEDED(hr), "Failed to set vs constant 0, hr %#x.\n", hr);
2221 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
2222 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2224 hr = IDirect3DDevice8_EndScene(device);
2225 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
2227 hr = IDirect3DDevice8_SetVertexShader(device, 0);
2228 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
2230 hr = IDirect3DDevice8_DeleteVertexShader(device, shader);
2231 ok(SUCCEEDED(hr), "Failed to delete vertex shader, hr %#x.\n", hr);
2233 /* Z < 1.0 */
2234 color = getPixelColor(device, 28, 238);
2235 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2237 /* 1.0 < z < 0.75 */
2238 color = getPixelColor(device, 31, 238);
2239 ok(color_match(color, 0x00ff0000, 0), "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2240 color = getPixelColor(device, 100, 238);
2241 ok(color_match(color, 0x00ff0000, 0) || broken(color_match(color, 0x00ffffff, 0)),
2242 "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2244 /* 0.75 < z < 0.0 */
2245 color = getPixelColor(device, 104, 238);
2246 ok(color_match(color, 0x000000ff, 0), "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2247 color = getPixelColor(device, 318, 238);
2248 ok(color_match(color, 0x000000ff, 0), "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2250 /* 0.0 < z */
2251 color = getPixelColor(device, 321, 238);
2252 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2254 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
2255 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
2257 refcount = IDirect3DDevice8_Release(device);
2258 ok(!refcount, "Device has %u references left.\n", refcount);
2259 done:
2260 IDirect3D8_Release(d3d);
2261 DestroyWindow(window);
2264 static void test_scalar_instructions(void)
2266 IDirect3DDevice8 *device;
2267 IDirect3D8 *d3d;
2268 unsigned int i;
2269 D3DCOLOR color;
2270 ULONG refcount;
2271 D3DCAPS8 caps;
2272 DWORD shader;
2273 HWND window;
2274 HRESULT hr;
2276 static const struct vec3 quad[] =
2278 {-1.0f, -1.0f, 0.0f},
2279 {-1.0f, 1.0f, 0.0f},
2280 { 1.0f, -1.0f, 0.0f},
2281 { 1.0f, 1.0f, 0.0f},
2283 static const DWORD decl[] =
2285 D3DVSD_STREAM(0),
2286 D3DVSD_REG(D3DVSDE_POSITION, D3DVSDT_FLOAT3), /* dcl_position v0 */
2287 D3DVSD_CONST(0, 1), 0x3e800000, 0x3f000000, 0x3f800000, 0x40000000, /* def c0, 0.25, 0.5, 1.0, 2.0 */
2288 D3DVSD_END()
2290 static const DWORD rcp_test[] =
2292 0xfffe0101, /* vs_1_1 */
2293 0x0009fffe, 0x30303030, 0x30303030, /* Shaders have to have a minimal size. */
2294 0x30303030, 0x30303030, 0x30303030, /* Add a filler comment. Usually d3dx8's */
2295 0x30303030, 0x30303030, 0x30303030, /* version comment makes the shader big */
2296 0x00303030, /* enough to make Windows happy. */
2297 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
2298 0x00000006, 0xd00f0000, 0xa0e40000, /* rcp oD0, c0 */
2299 0x0000ffff /* END */
2301 static const DWORD rsq_test[] =
2303 0xfffe0101, /* vs_1_1 */
2304 0x0009fffe, 0x30303030, 0x30303030, /* Shaders have to have a minimal size. */
2305 0x30303030, 0x30303030, 0x30303030, /* Add a filler comment. Usually d3dx8's */
2306 0x30303030, 0x30303030, 0x30303030, /* version comment makes the shader big */
2307 0x00303030, /* enough to make Windows happy. */
2308 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
2309 0x00000007, 0xd00f0000, 0xa0e40000, /* rsq oD0, c0 */
2310 0x0000ffff /* END */
2312 static const DWORD exp_test[] =
2314 0xfffe0101, /* vs_1_1 */
2315 0x0009fffe, 0x30303030, 0x30303030, /* Shaders have to have a minimal size. */
2316 0x30303030, 0x30303030, 0x30303030, /* Add a filler comment. Usually d3dx8's */
2317 0x30303030, 0x30303030, 0x30303030, /* version comment makes the shader big */
2318 0x00303030, /* enough to make Windows happy. */
2319 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
2320 0x0000000e, 0x800f0000, 0xa0e40000, /* exp r0, c0 */
2321 0x00000006, 0xd00f0000, 0x80000000, /* rcp oD0, r0.x */
2322 0x0000ffff, /* END */
2324 static const DWORD expp_test[] =
2326 0xfffe0101, /* vs_1_1 */
2327 0x0009fffe, 0x30303030, 0x30303030, /* Shaders have to have a minimal size. */
2328 0x30303030, 0x30303030, 0x30303030, /* Add a filler comment. Usually d3dx8's */
2329 0x30303030, 0x30303030, 0x30303030, /* version comment makes the shader big */
2330 0x00303030, /* enough to make Windows happy. */
2331 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
2332 0x0000004e, 0x800f0000, 0xa0e40000, /* expp r0, c0 */
2333 0x00000006, 0xd00f0000, 0x80000000, /* rcp oD0, r0.x */
2334 0x0000ffff, /* END */
2336 static const DWORD log_test[] =
2338 0xfffe0101, /* vs_1_1 */
2339 0x0009fffe, 0x30303030, 0x30303030, /* Shaders have to have a minimal size. */
2340 0x30303030, 0x30303030, 0x30303030, /* Add a filler comment. Usually d3dx8's */
2341 0x30303030, 0x30303030, 0x30303030, /* version comment makes the shader big */
2342 0x00303030, /* enough to make Windows happy. */
2343 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
2344 0x0000000f, 0xd00f0000, 0xa0e40000, /* log oD0, c0 */
2345 0x0000ffff, /* END */
2347 static const DWORD logp_test[] =
2349 0xfffe0101, /* vs_1_1 */
2350 0x0009fffe, 0x30303030, 0x30303030, /* Shaders have to have a minimal size. */
2351 0x30303030, 0x30303030, 0x30303030, /* Add a filler comment. Usually d3dx8's */
2352 0x30303030, 0x30303030, 0x30303030, /* version comment makes the shader big */
2353 0x00303030, /* enough to make Windows happy. */
2354 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
2355 0x0000004f, 0xd00f0000, 0xa0e40000, /* logp oD0, c0 */
2356 0x0000ffff, /* END */
2358 static const struct
2360 const char *name;
2361 const DWORD *byte_code;
2362 D3DCOLOR color;
2363 /* Some drivers, including Intel HD4000 10.18.10.3345 and VMware SVGA
2364 * 3D 7.14.1.5025, use the .x component instead of the .w one. */
2365 D3DCOLOR broken_color;
2367 test_data[] =
2369 {"rcp_test", rcp_test, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x80), D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff)},
2370 {"rsq_test", rsq_test, D3DCOLOR_ARGB(0x00, 0xb4, 0xb4, 0xb4), D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff)},
2371 {"exp_test", exp_test, D3DCOLOR_ARGB(0x00, 0x40, 0x40, 0x40), D3DCOLOR_ARGB(0x00, 0xd6, 0xd6, 0xd6)},
2372 {"expp_test", expp_test, D3DCOLOR_ARGB(0x00, 0x40, 0x40, 0x40), D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff)},
2373 {"log_test", log_test, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff), D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
2374 {"logp_test", logp_test, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff), D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
2377 window = create_window();
2378 d3d = Direct3DCreate8(D3D_SDK_VERSION);
2379 ok(!!d3d, "Failed to create a D3D object.\n");
2380 if (!(device = create_device(d3d, window, window, TRUE)))
2382 skip("Failed to create a D3D device, skipping tests.\n");
2383 goto done;
2386 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
2387 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
2388 if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1))
2390 skip("No vs_1_1 support, skipping tests.\n");
2391 IDirect3DDevice8_Release(device);
2392 goto done;
2395 for (i = 0; i < sizeof(test_data) / sizeof(*test_data); ++i)
2397 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff336699, 0.0f, 0);
2398 ok(SUCCEEDED(hr), "%s: Failed to clear, hr %#x.\n", test_data[i].name, hr);
2400 hr = IDirect3DDevice8_CreateVertexShader(device, decl, test_data[i].byte_code, &shader, 0);
2401 ok(SUCCEEDED(hr), "%s: Failed to create vertex shader, hr %#x.\n", test_data[i].name, hr);
2402 hr = IDirect3DDevice8_SetVertexShader(device, shader);
2403 ok(SUCCEEDED(hr), "%s: Failed to set vertex shader, hr %#x.\n", test_data[i].name, hr);
2405 hr = IDirect3DDevice8_BeginScene(device);
2406 ok(SUCCEEDED(hr), "%s: Failed to begin scene, hr %#x.\n", test_data[i].name, hr);
2407 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], 3 * sizeof(float));
2408 ok(SUCCEEDED(hr), "%s: Failed to draw primitive, hr %#x.\n", test_data[i].name, hr);
2409 hr = IDirect3DDevice8_EndScene(device);
2410 ok(SUCCEEDED(hr), "%s: Failed to end scene, hr %#x.\n", test_data[i].name, hr);
2412 color = getPixelColor(device, 320, 240);
2413 ok(color_match(color, test_data[i].color, 4) || broken(color_match(color, test_data[i].broken_color, 4)),
2414 "%s: Got unexpected color 0x%08x, expected 0x%08x.\n",
2415 test_data[i].name, color, test_data[i].color);
2417 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
2418 ok(SUCCEEDED(hr), "%s: Failed to present, hr %#x.\n", test_data[i].name, hr);
2420 hr = IDirect3DDevice8_SetVertexShader(device, 0);
2421 ok(SUCCEEDED(hr), "%s: Failed to set vertex shader, hr %#x.\n", test_data[i].name, hr);
2422 hr = IDirect3DDevice8_DeleteVertexShader(device, shader);
2423 ok(SUCCEEDED(hr), "%s: Failed to delete vertex shader, hr %#x.\n", test_data[i].name, hr);
2426 refcount = IDirect3DDevice8_Release(device);
2427 ok(!refcount, "Device has %u references left.\n", refcount);
2428 done:
2429 IDirect3D8_Release(d3d);
2430 DestroyWindow(window);
2433 static void offscreen_test(void)
2435 IDirect3DSurface8 *backbuffer, *offscreen, *depthstencil;
2436 IDirect3DTexture8 *offscreenTexture;
2437 IDirect3DDevice8 *device;
2438 IDirect3D8 *d3d;
2439 D3DCOLOR color;
2440 ULONG refcount;
2441 HWND window;
2442 HRESULT hr;
2444 static const float quad[][5] =
2446 {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
2447 {-0.5f, 0.5f, 0.1f, 0.0f, 1.0f},
2448 { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
2449 { 0.5f, 0.5f, 0.1f, 1.0f, 1.0f},
2452 window = create_window();
2453 d3d = Direct3DCreate8(D3D_SDK_VERSION);
2454 ok(!!d3d, "Failed to create a D3D object.\n");
2455 if (!(device = create_device(d3d, window, window, TRUE)))
2457 skip("Failed to create a D3D device, skipping tests.\n");
2458 goto done;
2461 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 1.0f, 0);
2462 ok(hr == D3D_OK, "Clear failed, hr = %#08x\n", hr);
2464 hr = IDirect3DDevice8_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET,
2465 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture);
2466 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %#08x\n", hr);
2467 if (!offscreenTexture)
2469 trace("Failed to create an X8R8G8B8 offscreen texture, trying R5G6B5\n");
2470 hr = IDirect3DDevice8_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET,
2471 D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &offscreenTexture);
2472 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %#08x\n", hr);
2473 if (!offscreenTexture)
2475 skip("Cannot create an offscreen render target.\n");
2476 IDirect3DDevice8_Release(device);
2477 goto done;
2481 hr = IDirect3DDevice8_GetDepthStencilSurface(device, &depthstencil);
2482 ok(hr == D3D_OK, "IDirect3DDevice8_GetDepthStencilSurface failed, hr = %#08x\n", hr);
2484 hr = IDirect3DDevice8_GetBackBuffer(device, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
2485 ok(hr == D3D_OK, "Can't get back buffer, hr = %#08x\n", hr);
2487 hr = IDirect3DTexture8_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
2488 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %#08x\n", hr);
2490 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX1);
2491 ok(hr == D3D_OK, "SetVertexShader failed, hr = %#08x\n", hr);
2493 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
2494 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %#08x\n", hr);
2495 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
2496 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %#08x\n", hr);
2497 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MINFILTER, D3DTEXF_NONE);
2498 ok(SUCCEEDED(hr), "SetTextureStageState D3DSAMP_MINFILTER failed (%#08x)\n", hr);
2499 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MAGFILTER, D3DTEXF_NONE);
2500 ok(SUCCEEDED(hr), "SetTextureStageState D3DSAMP_MAGFILTER failed (%#08x)\n", hr);
2501 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
2502 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %08x\n", hr);
2504 hr = IDirect3DDevice8_BeginScene(device);
2505 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
2507 hr = IDirect3DDevice8_SetRenderTarget(device, offscreen, depthstencil);
2508 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
2509 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 1.0f, 0);
2510 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
2512 /* Draw without textures - Should result in a white quad. */
2513 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
2514 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2516 hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, depthstencil);
2517 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
2518 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)offscreenTexture);
2519 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
2521 /* This time with the texture .*/
2522 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
2523 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2525 hr = IDirect3DDevice8_EndScene(device);
2526 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
2528 /* Center quad - should be white */
2529 color = getPixelColor(device, 320, 240);
2530 ok(color == 0x00ffffff, "Offscreen failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2531 /* Some quad in the cleared part of the texture */
2532 color = getPixelColor(device, 170, 240);
2533 ok(color == 0x00ff00ff, "Offscreen failed: Got color 0x%08x, expected 0x00ff00ff.\n", color);
2534 /* Part of the originally cleared back buffer */
2535 color = getPixelColor(device, 10, 10);
2536 ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2537 color = getPixelColor(device, 10, 470);
2538 ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2540 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
2542 IDirect3DSurface8_Release(backbuffer);
2543 IDirect3DTexture8_Release(offscreenTexture);
2544 IDirect3DSurface8_Release(offscreen);
2545 IDirect3DSurface8_Release(depthstencil);
2546 refcount = IDirect3DDevice8_Release(device);
2547 ok(!refcount, "Device has %u references left.\n", refcount);
2548 done:
2549 IDirect3D8_Release(d3d);
2550 DestroyWindow(window);
2553 static void test_blend(void)
2555 IDirect3DSurface8 *backbuffer, *offscreen, *depthstencil;
2556 IDirect3DTexture8 *offscreenTexture;
2557 IDirect3DDevice8 *device;
2558 IDirect3D8 *d3d;
2559 D3DCOLOR color;
2560 ULONG refcount;
2561 HWND window;
2562 HRESULT hr;
2564 static const struct
2566 struct vec3 position;
2567 DWORD diffuse;
2569 quad1[] =
2571 {{-1.0f, -1.0f, 0.1f}, 0x4000ff00},
2572 {{-1.0f, 0.0f, 0.1f}, 0x4000ff00},
2573 {{ 1.0f, -1.0f, 0.1f}, 0x4000ff00},
2574 {{ 1.0f, 0.0f, 0.1f}, 0x4000ff00},
2576 quad2[] =
2578 {{-1.0f, 0.0f, 0.1f}, 0xc00000ff},
2579 {{-1.0f, 1.0f, 0.1f}, 0xc00000ff},
2580 {{ 1.0f, 0.0f, 0.1f}, 0xc00000ff},
2581 {{ 1.0f, 1.0f, 0.1f}, 0xc00000ff},
2583 static const float composite_quad[][5] =
2585 { 0.0f, -1.0f, 0.1f, 0.0f, 1.0f},
2586 { 0.0f, 1.0f, 0.1f, 0.0f, 0.0f},
2587 { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f},
2588 { 1.0f, 1.0f, 0.1f, 1.0f, 0.0f},
2591 window = create_window();
2592 d3d = Direct3DCreate8(D3D_SDK_VERSION);
2593 ok(!!d3d, "Failed to create a D3D object.\n");
2594 if (!(device = create_device(d3d, window, window, TRUE)))
2596 skip("Failed to create a D3D device, skipping tests.\n");
2597 goto done;
2600 /* Clear the render target with alpha = 0.5 */
2601 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x80ff0000, 1.0f, 0);
2602 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
2604 hr = IDirect3DDevice8_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET,
2605 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture);
2606 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
2608 hr = IDirect3DDevice8_GetDepthStencilSurface(device, &depthstencil);
2609 ok(SUCCEEDED(hr), "Failed to get depth/stencil buffer, hr %#x.\n", hr);
2610 hr = IDirect3DDevice8_GetBackBuffer(device, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
2611 ok(SUCCEEDED(hr), "Failed to get back buffer, hr %#x.\n", hr);
2613 hr = IDirect3DTexture8_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
2614 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %#08x\n", hr);
2616 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
2617 ok(hr == D3D_OK, "SetVertexShader failed, hr = %#08x\n", hr);
2619 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
2620 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %#08x\n", hr);
2621 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
2622 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %#08x\n", hr);
2623 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MINFILTER, D3DTEXF_NONE);
2624 ok(SUCCEEDED(hr), "SetTextureStageState D3DSAMP_MINFILTER failed (%#08x)\n", hr);
2625 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MAGFILTER, D3DTEXF_NONE);
2626 ok(SUCCEEDED(hr), "SetTextureStageState D3DSAMP_MAGFILTER failed (%#08x)\n", hr);
2627 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
2628 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %08x\n", hr);
2630 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
2631 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
2632 hr = IDirect3DDevice8_BeginScene(device);
2633 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
2635 /* Draw two quads, one with src alpha blending, one with dest alpha blending. */
2636 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
2637 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
2638 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
2639 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
2640 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
2641 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2643 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
2644 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
2645 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
2646 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
2647 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
2648 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2650 /* Switch to the offscreen buffer, and redo the testing. The offscreen
2651 * render target doesn't have an alpha channel. DESTALPHA and INVDESTALPHA
2652 * "don't work" on render targets without alpha channel, they give
2653 * essentially ZERO and ONE blend factors. */
2654 hr = IDirect3DDevice8_SetRenderTarget(device, offscreen, 0);
2655 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
2656 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
2657 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
2659 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
2660 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
2661 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
2662 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
2663 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
2664 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2666 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
2667 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
2668 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
2669 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
2670 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
2671 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2673 hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, depthstencil);
2674 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
2676 /* Render the offscreen texture onto the frame buffer to be able to
2677 * compare it regularly. Disable alpha blending for the final
2678 * composition. */
2679 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
2680 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
2681 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX1);
2682 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
2684 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *) offscreenTexture);
2685 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
2686 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, composite_quad, sizeof(float) * 5);
2687 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2689 hr = IDirect3DDevice8_EndScene(device);
2690 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
2692 color = getPixelColor(device, 160, 360);
2693 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
2694 "SRCALPHA on frame buffer returned color %08x, expected 0x00bf4000\n", color);
2696 color = getPixelColor(device, 160, 120);
2697 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x00, 0x80), 2),
2698 "DSTALPHA on frame buffer returned color %08x, expected 0x007f0080\n", color);
2700 color = getPixelColor(device, 480, 360);
2701 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
2702 "SRCALPHA on texture returned color %08x, expected 0x00bf4000\n", color);
2704 color = getPixelColor(device, 480, 120);
2705 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
2706 "DSTALPHA on texture returned color %08x, expected 0x000000ff\n", color);
2708 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
2710 IDirect3DSurface8_Release(backbuffer);
2711 IDirect3DTexture8_Release(offscreenTexture);
2712 IDirect3DSurface8_Release(offscreen);
2713 IDirect3DSurface8_Release(depthstencil);
2714 refcount = IDirect3DDevice8_Release(device);
2715 ok(!refcount, "Device has %u references left.\n", refcount);
2716 done:
2717 IDirect3D8_Release(d3d);
2718 DestroyWindow(window);
2721 static void p8_texture_test(void)
2723 IDirect3DTexture8 *texture, *texture2;
2724 IDirect3DDevice8 *device;
2725 PALETTEENTRY table[256];
2726 unsigned char *data;
2727 D3DLOCKED_RECT lr;
2728 IDirect3D8 *d3d;
2729 D3DCOLOR color;
2730 ULONG refcount;
2731 D3DCAPS8 caps;
2732 HWND window;
2733 HRESULT hr;
2734 UINT i;
2736 static const float quad[] =
2738 -1.0f, 0.0f, 0.1f, 0.0f, 0.0f,
2739 -1.0f, 1.0f, 0.1f, 0.0f, 1.0f,
2740 1.0f, 0.0f, 0.1f, 1.0f, 0.0f,
2741 1.0f, 1.0f, 0.1f, 1.0f, 1.0f,
2743 static const float quad2[] =
2745 -1.0f, -1.0f, 0.1f, 0.0f, 0.0f,
2746 -1.0f, 0.0f, 0.1f, 0.0f, 1.0f,
2747 1.0f, -1.0f, 0.1f, 1.0f, 0.0f,
2748 1.0f, 0.0f, 0.1f, 1.0f, 1.0f,
2751 window = create_window();
2752 d3d = Direct3DCreate8(D3D_SDK_VERSION);
2753 ok(!!d3d, "Failed to create a D3D object.\n");
2754 if (!(device = create_device(d3d, window, window, TRUE)))
2756 skip("Failed to create a D3D device, skipping tests.\n");
2757 goto done;
2760 if (IDirect3D8_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
2761 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_P8) != D3D_OK)
2763 skip("D3DFMT_P8 textures not supported.\n");
2764 IDirect3DDevice8_Release(device);
2765 goto done;
2768 hr = IDirect3DDevice8_CreateTexture(device, 1, 1, 1, 0, D3DFMT_P8, D3DPOOL_MANAGED, &texture2);
2769 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
2770 memset(&lr, 0, sizeof(lr));
2771 hr = IDirect3DTexture8_LockRect(texture2, 0, &lr, NULL, 0);
2772 ok(hr == D3D_OK, "IDirect3DTexture8_LockRect failed, hr = %08x\n", hr);
2773 data = lr.pBits;
2774 *data = 1;
2775 hr = IDirect3DTexture8_UnlockRect(texture2, 0);
2776 ok(hr == D3D_OK, "IDirect3DTexture8_UnlockRect failed, hr = %08x\n", hr);
2778 hr = IDirect3DDevice8_CreateTexture(device, 1, 1, 1, 0, D3DFMT_P8, D3DPOOL_MANAGED, &texture);
2779 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
2780 memset(&lr, 0, sizeof(lr));
2781 hr = IDirect3DTexture8_LockRect(texture, 0, &lr, NULL, 0);
2782 ok(hr == D3D_OK, "IDirect3DTexture8_LockRect failed, hr = %08x\n", hr);
2783 data = lr.pBits;
2784 *data = 1;
2785 hr = IDirect3DTexture8_UnlockRect(texture, 0);
2786 ok(hr == D3D_OK, "IDirect3DTexture8_UnlockRect failed, hr = %08x\n", hr);
2788 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff000000, 1.0f, 0);
2789 ok(hr == D3D_OK, "IDirect3DDevice8_Clear failed, hr = %08x\n", hr);
2791 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
2792 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
2793 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
2794 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
2796 /* The first part of the test should work both with and without D3DPTEXTURECAPS_ALPHAPALETTE;
2797 alpha of every entry is set to 1.0, which MS says is required when there's no
2798 D3DPTEXTURECAPS_ALPHAPALETTE capability */
2799 for (i = 0; i < 256; i++) {
2800 table[i].peRed = table[i].peGreen = table[i].peBlue = 0;
2801 table[i].peFlags = 0xff;
2803 table[1].peRed = 0xff;
2804 hr = IDirect3DDevice8_SetPaletteEntries(device, 0, table);
2805 ok(hr == D3D_OK, "IDirect3DDevice8_SetPaletteEntries failed, hr = %08x\n", hr);
2807 table[1].peRed = 0;
2808 table[1].peBlue = 0xff;
2809 hr = IDirect3DDevice8_SetPaletteEntries(device, 1, table);
2810 ok(hr == D3D_OK, "IDirect3DDevice8_SetPaletteEntries failed, hr = %08x\n", hr);
2812 hr = IDirect3DDevice8_BeginScene(device);
2813 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
2815 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
2816 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
2817 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
2818 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
2819 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX1);
2820 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
2821 hr = IDirect3DDevice8_SetCurrentTexturePalette(device, 0);
2822 ok(SUCCEEDED(hr), "Failed to set texture palette, hr %#x.\n", hr);
2823 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture2);
2824 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
2825 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
2826 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2828 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
2829 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
2830 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
2831 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2833 hr = IDirect3DDevice8_SetCurrentTexturePalette(device, 1);
2834 ok(SUCCEEDED(hr), "Failed to set texture palette, hr %#x.\n", hr);
2835 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
2836 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2838 hr = IDirect3DDevice8_EndScene(device);
2839 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
2841 color = getPixelColor(device, 32, 32);
2842 ok(color_match(color, 0x00ff0000, 0), "Got unexpected color 0x%08x.\n", color);
2843 color = getPixelColor(device, 32, 320);
2844 ok(color_match(color, 0x000000ff, 0), "Got unexpected color 0x%08x.\n", color);
2846 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
2847 ok(hr == D3D_OK, "IDirect3DDevice8_Present failed, hr = %08x\n", hr);
2849 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
2850 ok(hr == D3D_OK, "IDirect3DDevice8_Clear failed, hr = %08x\n", hr);
2852 hr = IDirect3DDevice8_BeginScene(device);
2853 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
2854 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture2);
2855 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
2856 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
2857 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2858 hr = IDirect3DDevice8_EndScene(device);
2859 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
2861 color = getPixelColor(device, 32, 32);
2862 ok(color_match(color, 0x000000ff, 0), "Got unexpected color 0x%08x.\n", color);
2864 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
2865 ok(hr == D3D_OK, "IDirect3DDevice8_Present failed, hr = %08x\n", hr);
2867 /* Test palettes with alpha */
2868 IDirect3DDevice8_GetDeviceCaps(device, &caps);
2869 if (!(caps.TextureCaps & D3DPTEXTURECAPS_ALPHAPALETTE)) {
2870 skip("no D3DPTEXTURECAPS_ALPHAPALETTE capability, tests with alpha in palette will be skipped\n");
2871 } else {
2872 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
2873 ok(hr == D3D_OK, "IDirect3DDevice8_Clear failed, hr = %08x\n", hr);
2875 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
2876 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
2878 for (i = 0; i < 256; i++) {
2879 table[i].peRed = table[i].peGreen = table[i].peBlue = 0;
2880 table[i].peFlags = 0xff;
2882 table[1].peRed = 0xff;
2883 table[1].peFlags = 0x80;
2884 hr = IDirect3DDevice8_SetPaletteEntries(device, 0, table);
2885 ok(hr == D3D_OK, "IDirect3DDevice8_SetPaletteEntries failed, hr = %08x\n", hr);
2887 table[1].peRed = 0;
2888 table[1].peBlue = 0xff;
2889 table[1].peFlags = 0x80;
2890 hr = IDirect3DDevice8_SetPaletteEntries(device, 1, table);
2891 ok(hr == D3D_OK, "IDirect3DDevice8_SetPaletteEntries failed, hr = %08x\n", hr);
2893 hr = IDirect3DDevice8_BeginScene(device);
2894 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
2896 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
2897 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
2898 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
2899 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
2900 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX1);
2901 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
2903 hr = IDirect3DDevice8_SetCurrentTexturePalette(device, 0);
2904 ok(SUCCEEDED(hr), "Failed to set texture palette, hr %#x.\n", hr);
2905 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
2906 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2908 hr = IDirect3DDevice8_SetCurrentTexturePalette(device, 1);
2909 ok(SUCCEEDED(hr), "Failed to set texture palette, hr %#x.\n", hr);
2910 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
2911 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2913 hr = IDirect3DDevice8_EndScene(device);
2914 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
2916 color = getPixelColor(device, 32, 32);
2917 ok(color_match(color, 0x00800000, 1), "Got unexpected color 0x%08x.\n", color);
2918 color = getPixelColor(device, 32, 320);
2919 ok(color_match(color, 0x00000080, 1), "Got unexpected color 0x%08x.\n", color);
2921 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
2922 ok(hr == D3D_OK, "IDirect3DDevice8_Present failed, hr = %08x\n", hr);
2925 IDirect3DTexture8_Release(texture);
2926 IDirect3DTexture8_Release(texture2);
2927 refcount = IDirect3DDevice8_Release(device);
2928 ok(!refcount, "Device has %u references left.\n", refcount);
2929 done:
2930 IDirect3D8_Release(d3d);
2931 DestroyWindow(window);
2934 static void texop_test(void)
2936 IDirect3DTexture8 *texture;
2937 D3DLOCKED_RECT locked_rect;
2938 IDirect3DDevice8 *device;
2939 IDirect3D8 *d3d;
2940 unsigned int i;
2941 D3DCOLOR color;
2942 ULONG refcount;
2943 D3DCAPS8 caps;
2944 HWND window;
2945 HRESULT hr;
2947 static const struct {
2948 float x, y, z;
2949 D3DCOLOR diffuse;
2950 float s, t;
2951 } quad[] = {
2952 {-1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00), -1.0f, -1.0f},
2953 {-1.0f, 1.0f, 0.1f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00), -1.0f, 1.0f},
2954 { 1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00), 1.0f, -1.0f},
2955 { 1.0f, 1.0f, 0.1f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00), 1.0f, 1.0f}
2958 static const struct {
2959 D3DTEXTUREOP op;
2960 const char *name;
2961 DWORD caps_flag;
2962 D3DCOLOR result;
2963 } test_data[] = {
2964 {D3DTOP_SELECTARG1, "SELECTARG1", D3DTEXOPCAPS_SELECTARG1, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
2965 {D3DTOP_SELECTARG2, "SELECTARG2", D3DTEXOPCAPS_SELECTARG2, D3DCOLOR_ARGB(0x00, 0x33, 0x33, 0x33)},
2966 {D3DTOP_MODULATE, "MODULATE", D3DTEXOPCAPS_MODULATE, D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x00)},
2967 {D3DTOP_MODULATE2X, "MODULATE2X", D3DTEXOPCAPS_MODULATE2X, D3DCOLOR_ARGB(0x00, 0x00, 0x66, 0x00)},
2968 {D3DTOP_MODULATE4X, "MODULATE4X", D3DTEXOPCAPS_MODULATE4X, D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
2969 {D3DTOP_ADD, "ADD", D3DTEXOPCAPS_ADD, D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
2971 {D3DTOP_ADDSIGNED, "ADDSIGNED", D3DTEXOPCAPS_ADDSIGNED, D3DCOLOR_ARGB(0x00, 0x00, 0xb2, 0x00)},
2972 {D3DTOP_ADDSIGNED2X, "ADDSIGNED2X", D3DTEXOPCAPS_ADDSIGNED2X, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
2974 {D3DTOP_SUBTRACT, "SUBTRACT", D3DTEXOPCAPS_SUBTRACT, D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
2975 {D3DTOP_ADDSMOOTH, "ADDSMOOTH", D3DTEXOPCAPS_ADDSMOOTH, D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
2976 {D3DTOP_BLENDDIFFUSEALPHA, "BLENDDIFFUSEALPHA", D3DTEXOPCAPS_BLENDDIFFUSEALPHA, D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
2977 {D3DTOP_BLENDTEXTUREALPHA, "BLENDTEXTUREALPHA", D3DTEXOPCAPS_BLENDTEXTUREALPHA, D3DCOLOR_ARGB(0x00, 0x14, 0xad, 0x14)},
2978 {D3DTOP_BLENDFACTORALPHA, "BLENDFACTORALPHA", D3DTEXOPCAPS_BLENDFACTORALPHA, D3DCOLOR_ARGB(0x00, 0x07, 0xe4, 0x07)},
2979 {D3DTOP_BLENDTEXTUREALPHAPM, "BLENDTEXTUREALPHAPM", D3DTEXOPCAPS_BLENDTEXTUREALPHAPM, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
2980 {D3DTOP_BLENDCURRENTALPHA, "BLENDCURRENTALPHA", D3DTEXOPCAPS_BLENDCURRENTALPHA, D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
2981 {D3DTOP_MODULATEALPHA_ADDCOLOR, "MODULATEALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x1f, 0xff, 0x1f)},
2982 {D3DTOP_MODULATECOLOR_ADDALPHA, "MODULATECOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0x99, 0xcc, 0x99)},
2983 {D3DTOP_MODULATEINVALPHA_ADDCOLOR, "MODULATEINVALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
2984 {D3DTOP_MODULATEINVCOLOR_ADDALPHA, "MODULATEINVCOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0xcc, 0x99, 0xcc)},
2985 /* BUMPENVMAP & BUMPENVMAPLUMINANCE have their own tests */
2986 {D3DTOP_DOTPRODUCT3, "DOTPRODUCT2", D3DTEXOPCAPS_DOTPRODUCT3, D3DCOLOR_ARGB(0x00, 0x99, 0x99, 0x99)},
2987 {D3DTOP_MULTIPLYADD, "MULTIPLYADD", D3DTEXOPCAPS_MULTIPLYADD, D3DCOLOR_ARGB(0x00, 0xff, 0x33, 0x00)},
2988 {D3DTOP_LERP, "LERP", D3DTEXOPCAPS_LERP, D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x33)},
2991 window = create_window();
2992 d3d = Direct3DCreate8(D3D_SDK_VERSION);
2993 ok(!!d3d, "Failed to create a D3D object.\n");
2994 if (!(device = create_device(d3d, window, window, TRUE)))
2996 skip("Failed to create a D3D device, skipping tests.\n");
2997 goto done;
3000 memset(&caps, 0, sizeof(caps));
3001 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
3002 ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
3004 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX0);
3005 ok(SUCCEEDED(hr), "SetVertexShader failed with 0x%08x\n", hr);
3007 hr = IDirect3DDevice8_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture);
3008 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
3009 hr = IDirect3DTexture8_LockRect(texture, 0, &locked_rect, NULL, 0);
3010 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
3011 *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x99, 0x00, 0xff, 0x00);
3012 hr = IDirect3DTexture8_UnlockRect(texture, 0);
3013 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
3014 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
3015 ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
3017 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG0, D3DTA_DIFFUSE);
3018 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
3019 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
3020 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
3021 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
3022 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
3024 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
3025 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
3027 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3028 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
3029 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xdd333333);
3030 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
3031 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_ALPHA);
3032 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
3034 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
3035 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
3037 for (i = 0; i < sizeof(test_data) / sizeof(*test_data); ++i)
3039 if (!(caps.TextureOpCaps & test_data[i].caps_flag))
3041 skip("tex operation %s not supported\n", test_data[i].name);
3042 continue;
3045 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLOROP, test_data[i].op);
3046 ok(SUCCEEDED(hr), "SetTextureStageState (%s) failed with 0x%08x\n", test_data[i].name, hr);
3048 hr = IDirect3DDevice8_BeginScene(device);
3049 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
3051 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
3052 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
3054 hr = IDirect3DDevice8_EndScene(device);
3055 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
3057 color = getPixelColor(device, 320, 240);
3058 ok(color_match(color, test_data[i].result, 3), "Operation %s returned color 0x%08x, expected 0x%08x\n",
3059 test_data[i].name, color, test_data[i].result);
3061 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
3062 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
3064 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
3065 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
3068 IDirect3DTexture8_Release(texture);
3069 refcount = IDirect3DDevice8_Release(device);
3070 ok(!refcount, "Device has %u references left.\n", refcount);
3071 done:
3072 IDirect3D8_Release(d3d);
3073 DestroyWindow(window);
3076 /* This test tests depth clamping / clipping behaviour:
3077 * - With software vertex processing, depth values are clamped to the
3078 * minimum / maximum z value when D3DRS_CLIPPING is disabled, and clipped
3079 * when D3DRS_CLIPPING is enabled. Pretransformed vertices behave the
3080 * same as regular vertices here.
3081 * - With hardware vertex processing, D3DRS_CLIPPING seems to be ignored.
3082 * Normal vertices are always clipped. Pretransformed vertices are
3083 * clipped when D3DPMISCCAPS_CLIPTLVERTS is set, clamped when it isn't.
3084 * - The viewport's MinZ/MaxZ is irrelevant for this.
3086 static void depth_clamp_test(void)
3088 IDirect3DDevice8 *device;
3089 D3DVIEWPORT8 vp;
3090 IDirect3D8 *d3d;
3091 D3DCOLOR color;
3092 ULONG refcount;
3093 D3DCAPS8 caps;
3094 HWND window;
3095 HRESULT hr;
3097 static const struct
3099 struct vec4 position;
3100 DWORD diffuse;
3102 quad1[] =
3104 {{ 0.0f, 0.0f, 5.0f, 1.0f}, 0xff002b7f},
3105 {{640.0f, 0.0f, 5.0f, 1.0f}, 0xff002b7f},
3106 {{ 0.0f, 480.0f, 5.0f, 1.0f}, 0xff002b7f},
3107 {{640.0f, 480.0f, 5.0f, 1.0f}, 0xff002b7f},
3109 quad2[] =
3111 {{ 0.0f, 300.0f, 10.0f, 1.0f}, 0xfff9e814},
3112 {{640.0f, 300.0f, 10.0f, 1.0f}, 0xfff9e814},
3113 {{ 0.0f, 360.0f, 10.0f, 1.0f}, 0xfff9e814},
3114 {{640.0f, 360.0f, 10.0f, 1.0f}, 0xfff9e814},
3116 quad3[] =
3118 {{112.0f, 108.0f, 5.0f, 1.0f}, 0xffffffff},
3119 {{208.0f, 108.0f, 5.0f, 1.0f}, 0xffffffff},
3120 {{112.0f, 204.0f, 5.0f, 1.0f}, 0xffffffff},
3121 {{208.0f, 204.0f, 5.0f, 1.0f}, 0xffffffff},
3123 quad4[] =
3125 {{ 42.0f, 41.0f, 10.0f, 1.0f}, 0xffffffff},
3126 {{112.0f, 41.0f, 10.0f, 1.0f}, 0xffffffff},
3127 {{ 42.0f, 108.0f, 10.0f, 1.0f}, 0xffffffff},
3128 {{112.0f, 108.0f, 10.0f, 1.0f}, 0xffffffff},
3130 static const struct
3132 struct vec3 position;
3133 DWORD diffuse;
3135 quad5[] =
3137 {{-0.5f, 0.5f, 10.0f}, 0xff14f914},
3138 {{ 0.5f, 0.5f, 10.0f}, 0xff14f914},
3139 {{-0.5f, -0.5f, 10.0f}, 0xff14f914},
3140 {{ 0.5f, -0.5f, 10.0f}, 0xff14f914},
3142 quad6[] =
3144 {{-1.0f, 0.5f, 10.0f}, 0xfff91414},
3145 {{ 1.0f, 0.5f, 10.0f}, 0xfff91414},
3146 {{-1.0f, 0.25f, 10.0f}, 0xfff91414},
3147 {{ 1.0f, 0.25f, 10.0f}, 0xfff91414},
3150 window = create_window();
3151 d3d = Direct3DCreate8(D3D_SDK_VERSION);
3152 ok(!!d3d, "Failed to create a D3D object.\n");
3153 if (!(device = create_device(d3d, window, window, TRUE)))
3155 skip("Failed to create a D3D device, skipping tests.\n");
3156 goto done;
3159 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
3160 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
3162 vp.X = 0;
3163 vp.Y = 0;
3164 vp.Width = 640;
3165 vp.Height = 480;
3166 vp.MinZ = 0.0;
3167 vp.MaxZ = 7.5;
3169 hr = IDirect3DDevice8_SetViewport(device, &vp);
3170 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
3172 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0, 0);
3173 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
3175 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, FALSE);
3176 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3177 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3178 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3179 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
3180 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3181 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
3182 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3184 hr = IDirect3DDevice8_BeginScene(device);
3185 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
3187 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
3188 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
3190 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
3191 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3192 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
3193 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3195 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, TRUE);
3196 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3198 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
3199 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3200 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(*quad4));
3201 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3203 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, FALSE);
3204 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3205 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
3206 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
3208 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad5, sizeof(*quad5));
3209 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3211 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, TRUE);
3212 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3214 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad6, sizeof(*quad6));
3215 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3217 hr = IDirect3DDevice8_EndScene(device);
3218 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
3220 if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
3222 color = getPixelColor(device, 75, 75);
3223 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
3224 color = getPixelColor(device, 150, 150);
3225 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
3226 color = getPixelColor(device, 320, 240);
3227 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
3228 color = getPixelColor(device, 320, 330);
3229 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
3230 color = getPixelColor(device, 320, 330);
3231 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
3233 else
3235 color = getPixelColor(device, 75, 75);
3236 ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
3237 color = getPixelColor(device, 150, 150);
3238 ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
3239 color = getPixelColor(device, 320, 240);
3240 ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);
3241 color = getPixelColor(device, 320, 330);
3242 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
3243 color = getPixelColor(device, 320, 330);
3244 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
3247 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
3248 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3250 refcount = IDirect3DDevice8_Release(device);
3251 ok(!refcount, "Device has %u references left.\n", refcount);
3252 done:
3253 IDirect3D8_Release(d3d);
3254 DestroyWindow(window);
3257 static void depth_buffer_test(void)
3259 IDirect3DSurface8 *backbuffer, *rt1, *rt2, *rt3;
3260 IDirect3DSurface8 *depth_stencil;
3261 IDirect3DDevice8 *device;
3262 unsigned int i, j;
3263 D3DVIEWPORT8 vp;
3264 IDirect3D8 *d3d;
3265 D3DCOLOR color;
3266 ULONG refcount;
3267 HWND window;
3268 HRESULT hr;
3270 static const struct
3272 struct vec3 position;
3273 DWORD diffuse;
3275 quad1[] =
3277 {{-1.0f, 1.0f, 0.33f}, 0xff00ff00},
3278 {{ 1.0f, 1.0f, 0.33f}, 0xff00ff00},
3279 {{-1.0f, -1.0f, 0.33f}, 0xff00ff00},
3280 {{ 1.0f, -1.0f, 0.33f}, 0xff00ff00},
3282 quad2[] =
3284 {{-1.0f, 1.0f, 0.50f}, 0xffff00ff},
3285 {{ 1.0f, 1.0f, 0.50f}, 0xffff00ff},
3286 {{-1.0f, -1.0f, 0.50f}, 0xffff00ff},
3287 {{ 1.0f, -1.0f, 0.50f}, 0xffff00ff},
3289 quad3[] =
3291 {{-1.0f, 1.0f, 0.66f}, 0xffff0000},
3292 {{ 1.0f, 1.0f, 0.66f}, 0xffff0000},
3293 {{-1.0f, -1.0f, 0.66f}, 0xffff0000},
3294 {{ 1.0f, -1.0f, 0.66f}, 0xffff0000},
3296 static const DWORD expected_colors[4][4] =
3298 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
3299 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
3300 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x00ff0000},
3301 {0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
3304 window = create_window();
3305 d3d = Direct3DCreate8(D3D_SDK_VERSION);
3306 ok(!!d3d, "Failed to create a D3D object.\n");
3307 if (!(device = create_device(d3d, window, window, TRUE)))
3309 skip("Failed to create a D3D device, skipping tests.\n");
3310 goto done;
3313 vp.X = 0;
3314 vp.Y = 0;
3315 vp.Width = 640;
3316 vp.Height = 480;
3317 vp.MinZ = 0.0;
3318 vp.MaxZ = 1.0;
3320 hr = IDirect3DDevice8_SetViewport(device, &vp);
3321 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
3323 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3324 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3325 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
3326 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3327 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
3328 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3329 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
3330 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3331 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
3332 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
3334 hr = IDirect3DDevice8_GetDepthStencilSurface(device, &depth_stencil);
3335 ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
3336 hr = IDirect3DDevice8_GetRenderTarget(device, &backbuffer);
3337 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
3338 hr = IDirect3DDevice8_CreateRenderTarget(device, 320, 240, D3DFMT_A8R8G8B8,
3339 D3DMULTISAMPLE_NONE, FALSE, &rt1);
3340 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
3341 hr = IDirect3DDevice8_CreateRenderTarget(device, 480, 360, D3DFMT_A8R8G8B8,
3342 D3DMULTISAMPLE_NONE, FALSE, &rt2);
3343 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
3344 hr = IDirect3DDevice8_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
3345 D3DMULTISAMPLE_NONE, FALSE, &rt3);
3346 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
3348 hr = IDirect3DDevice8_SetRenderTarget(device, rt3, depth_stencil);
3349 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
3350 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0f, 0);
3351 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
3353 hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, depth_stencil);
3354 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
3355 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
3356 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
3358 hr = IDirect3DDevice8_SetRenderTarget(device, rt1, depth_stencil);
3359 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
3360 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0f, 0);
3361 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
3363 hr = IDirect3DDevice8_SetRenderTarget(device, rt2, depth_stencil);
3364 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
3365 hr = IDirect3DDevice8_BeginScene(device);
3366 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
3367 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
3368 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3369 hr = IDirect3DDevice8_EndScene(device);
3370 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
3372 hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, depth_stencil);
3373 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
3375 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
3376 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3378 hr = IDirect3DDevice8_BeginScene(device);
3379 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
3380 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
3381 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3382 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
3383 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3384 hr = IDirect3DDevice8_EndScene(device);
3385 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
3387 for (i = 0; i < 4; ++i)
3389 for (j = 0; j < 4; ++j)
3391 unsigned int x = 80 * ((2 * j) + 1);
3392 unsigned int y = 60 * ((2 * i) + 1);
3393 color = getPixelColor(device, x, y);
3394 ok(color_match(color, expected_colors[i][j], 0),
3395 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors[i][j], x, y, color);
3399 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
3400 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3402 IDirect3DSurface8_Release(depth_stencil);
3403 IDirect3DSurface8_Release(backbuffer);
3404 IDirect3DSurface8_Release(rt3);
3405 IDirect3DSurface8_Release(rt2);
3406 IDirect3DSurface8_Release(rt1);
3407 refcount = IDirect3DDevice8_Release(device);
3408 ok(!refcount, "Device has %u references left.\n", refcount);
3409 done:
3410 IDirect3D8_Release(d3d);
3411 DestroyWindow(window);
3414 /* Test that partial depth copies work the way they're supposed to. The clear
3415 * on rt2 only needs a partial copy of the onscreen depth/stencil buffer, and
3416 * the following draw should only copy back the part that was modified. */
3417 static void depth_buffer2_test(void)
3419 IDirect3DSurface8 *backbuffer, *rt1, *rt2;
3420 IDirect3DSurface8 *depth_stencil;
3421 IDirect3DDevice8 *device;
3422 unsigned int i, j;
3423 D3DVIEWPORT8 vp;
3424 IDirect3D8 *d3d;
3425 D3DCOLOR color;
3426 ULONG refcount;
3427 HWND window;
3428 HRESULT hr;
3430 static const struct
3432 struct vec3 position;
3433 DWORD diffuse;
3435 quad[] =
3437 {{-1.0f, 1.0f, 0.66f}, 0xffff0000},
3438 {{ 1.0f, 1.0f, 0.66f}, 0xffff0000},
3439 {{-1.0f, -1.0f, 0.66f}, 0xffff0000},
3440 {{ 1.0f, -1.0f, 0.66f}, 0xffff0000},
3443 window = create_window();
3444 d3d = Direct3DCreate8(D3D_SDK_VERSION);
3445 ok(!!d3d, "Failed to create a D3D object.\n");
3446 if (!(device = create_device(d3d, window, window, TRUE)))
3448 skip("Failed to create a D3D device, skipping tests.\n");
3449 goto done;
3452 vp.X = 0;
3453 vp.Y = 0;
3454 vp.Width = 640;
3455 vp.Height = 480;
3456 vp.MinZ = 0.0;
3457 vp.MaxZ = 1.0;
3459 hr = IDirect3DDevice8_SetViewport(device, &vp);
3460 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
3462 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3463 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3464 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
3465 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3466 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
3467 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3468 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
3469 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3470 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
3471 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
3473 hr = IDirect3DDevice8_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
3474 D3DMULTISAMPLE_NONE, FALSE, &rt1);
3475 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
3476 hr = IDirect3DDevice8_CreateRenderTarget(device, 480, 360, D3DFMT_A8R8G8B8,
3477 D3DMULTISAMPLE_NONE, FALSE, &rt2);
3478 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
3479 hr = IDirect3DDevice8_GetDepthStencilSurface(device, &depth_stencil);
3480 ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
3481 hr = IDirect3DDevice8_GetRenderTarget(device, &backbuffer);
3482 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
3484 hr = IDirect3DDevice8_SetRenderTarget(device, rt1, depth_stencil);
3485 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
3486 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
3487 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
3489 hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, depth_stencil);
3490 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
3491 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 0.5f, 0);
3492 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
3494 hr = IDirect3DDevice8_SetRenderTarget(device, rt2, depth_stencil);
3495 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
3496 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0f, 0);
3497 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
3499 hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, depth_stencil);
3500 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
3502 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
3503 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3505 hr = IDirect3DDevice8_BeginScene(device);
3506 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
3507 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
3508 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3509 hr = IDirect3DDevice8_EndScene(device);
3510 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
3512 for (i = 0; i < 4; ++i)
3514 for (j = 0; j < 4; ++j)
3516 unsigned int x = 80 * ((2 * j) + 1);
3517 unsigned int y = 60 * ((2 * i) + 1);
3518 color = getPixelColor(device, x, y);
3519 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
3520 "Expected color 0x0000ff00 %u,%u, got 0x%08x.\n", x, y, color);
3524 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
3525 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3527 IDirect3DSurface8_Release(depth_stencil);
3528 IDirect3DSurface8_Release(backbuffer);
3529 IDirect3DSurface8_Release(rt2);
3530 IDirect3DSurface8_Release(rt1);
3531 refcount = IDirect3DDevice8_Release(device);
3532 ok(!refcount, "Device has %u references left.\n", refcount);
3533 done:
3534 IDirect3D8_Release(d3d);
3535 DestroyWindow(window);
3538 static void intz_test(void)
3540 IDirect3DSurface8 *original_rt, *rt;
3541 struct surface_readback rb;
3542 IDirect3DTexture8 *texture;
3543 IDirect3DDevice8 *device;
3544 IDirect3DSurface8 *ds;
3545 IDirect3D8 *d3d;
3546 ULONG refcount;
3547 D3DCAPS8 caps;
3548 HWND window;
3549 HRESULT hr;
3550 DWORD ps;
3551 UINT i;
3553 static const DWORD ps_code[] =
3555 0xffff0101, /* ps_1_1 */
3556 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c0, 1.0, 0.0, 1.0, 1.0 */
3557 0x00000051, 0xa00f0001, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c1, 0.0, 1.0, 0.0, 0.0 */
3558 0x00000042, 0xb00f0000, /* tex t0 */
3559 0x00000042, 0xb00f0001, /* tex t1 */
3560 0x00000005, 0xb00f0000, 0xa0e40000, 0xb0e40000, /* mul t0, c0, t0 */
3561 0x00000004, 0x800f0000, 0xa0e40001, 0xb0e40001, 0xb0e40000, /* mad r0, c1, t1, t0 */
3562 0x0000ffff, /* end */
3564 static const struct
3566 float x, y, z;
3567 float s0, t0, p0;
3568 float s1, t1, p1, q1;
3570 quad[] =
3572 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.5f},
3573 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
3574 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
3575 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.5f},
3577 half_quad_1[] =
3579 { -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.5f},
3580 { 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
3581 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
3582 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.5f},
3584 half_quad_2[] =
3586 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.5f},
3587 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
3588 { -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
3589 { 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.5f},
3591 static const struct
3593 UINT x, y;
3594 D3DCOLOR color;
3596 expected_colors[] =
3598 { 80, 100, 0x20204020},
3599 {240, 100, 0x6060bf60},
3600 {400, 100, 0x9f9f409f},
3601 {560, 100, 0xdfdfbfdf},
3602 { 80, 450, 0x20204020},
3603 {240, 450, 0x6060bf60},
3604 {400, 450, 0x9f9f409f},
3605 {560, 450, 0xdfdfbfdf},
3608 window = create_window();
3609 d3d = Direct3DCreate8(D3D_SDK_VERSION);
3610 ok(!!d3d, "Failed to create a D3D object.\n");
3611 if (!(device = create_device(d3d, window, window, TRUE)))
3613 skip("Failed to create a D3D device, skipping tests.\n");
3614 goto done;
3617 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
3618 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
3619 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 1))
3621 skip("No pixel shader 1.1 support, skipping INTZ test.\n");
3622 IDirect3DDevice8_Release(device);
3623 goto done;
3625 if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
3627 skip("No unconditional NP2 texture support, skipping INTZ test.\n");
3628 IDirect3DDevice8_Release(device);
3629 goto done;
3632 if (FAILED(hr = IDirect3D8_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
3633 D3DFMT_X8R8G8B8, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, MAKEFOURCC('I','N','T','Z'))))
3635 skip("No INTZ support, skipping INTZ test.\n");
3636 IDirect3DDevice8_Release(device);
3637 goto done;
3640 hr = IDirect3DDevice8_GetRenderTarget(device, &original_rt);
3641 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
3643 hr = IDirect3DDevice8_CreateTexture(device, 640, 480, 1,
3644 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture);
3645 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
3646 hr = IDirect3DDevice8_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
3647 D3DMULTISAMPLE_NONE, FALSE, &rt);
3648 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
3649 hr = IDirect3DDevice8_CreatePixelShader(device, ps_code, &ps);
3650 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
3652 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX2
3653 | D3DFVF_TEXCOORDSIZE3(0) | D3DFVF_TEXCOORDSIZE4(1));
3654 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
3655 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
3656 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3657 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
3658 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3659 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
3660 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3661 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3662 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3664 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MINFILTER, D3DTEXF_POINT);
3665 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3666 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MIPFILTER, D3DTEXF_POINT);
3667 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3668 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MAGFILTER, D3DTEXF_POINT);
3669 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3670 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
3671 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3673 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP);
3674 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3675 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP);
3676 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3677 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MAGFILTER, D3DTEXF_POINT);
3678 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3679 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MINFILTER, D3DTEXF_POINT);
3680 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3681 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MIPFILTER, D3DTEXF_POINT);
3682 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3683 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS,
3684 D3DTTFF_COUNT4 | D3DTTFF_PROJECTED);
3685 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3687 hr = IDirect3DTexture8_GetSurfaceLevel(texture, 0, &ds);
3688 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
3690 /* Render offscreen, using the INTZ texture as depth buffer */
3691 hr = IDirect3DDevice8_SetRenderTarget(device, rt, ds);
3692 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
3693 hr = IDirect3DDevice8_SetPixelShader(device, 0);
3694 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
3696 /* Setup the depth/stencil surface. */
3697 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
3698 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
3700 hr = IDirect3DDevice8_BeginScene(device);
3701 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
3702 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
3703 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3704 hr = IDirect3DDevice8_EndScene(device);
3705 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
3707 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, NULL);
3708 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
3709 IDirect3DSurface8_Release(ds);
3710 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
3711 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
3712 hr = IDirect3DDevice8_SetTexture(device, 1, (IDirect3DBaseTexture8 *)texture);
3713 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
3714 hr = IDirect3DDevice8_SetPixelShader(device, ps);
3715 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
3717 /* Read the depth values back. */
3718 hr = IDirect3DDevice8_BeginScene(device);
3719 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
3720 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
3721 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3722 hr = IDirect3DDevice8_EndScene(device);
3723 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
3725 get_rt_readback(original_rt, &rb);
3726 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
3728 D3DCOLOR color = get_readback_color(&rb, expected_colors[i].x, expected_colors[i].y);
3729 ok(color_match(color, expected_colors[i].color, 1),
3730 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
3731 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
3733 release_surface_readback(&rb);
3735 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
3736 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
3738 hr = IDirect3DDevice8_SetTexture(device, 0, NULL);
3739 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
3740 hr = IDirect3DDevice8_SetTexture(device, 1, NULL);
3741 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
3742 IDirect3DTexture8_Release(texture);
3744 /* Render onscreen while using the INTZ texture as depth buffer */
3745 hr = IDirect3DDevice8_CreateTexture(device, 640, 480, 1,
3746 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture);
3747 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
3748 hr = IDirect3DTexture8_GetSurfaceLevel(texture, 0, &ds);
3749 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
3750 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, ds);
3751 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
3752 hr = IDirect3DDevice8_SetPixelShader(device, 0);
3753 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
3755 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
3756 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
3758 hr = IDirect3DDevice8_BeginScene(device);
3759 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
3760 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
3761 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3762 hr = IDirect3DDevice8_EndScene(device);
3763 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
3765 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, NULL);
3766 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
3767 IDirect3DSurface8_Release(ds);
3768 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
3769 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
3770 hr = IDirect3DDevice8_SetTexture(device, 1, (IDirect3DBaseTexture8 *)texture);
3771 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
3772 hr = IDirect3DDevice8_SetPixelShader(device, ps);
3773 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
3775 /* Read the depth values back. */
3776 hr = IDirect3DDevice8_BeginScene(device);
3777 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
3778 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
3779 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3780 hr = IDirect3DDevice8_EndScene(device);
3781 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
3783 get_rt_readback(original_rt, &rb);
3784 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
3786 D3DCOLOR color = get_readback_color(&rb, expected_colors[i].x, expected_colors[i].y);
3787 ok(color_match(color, expected_colors[i].color, 1),
3788 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
3789 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
3791 release_surface_readback(&rb);
3793 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
3794 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
3796 hr = IDirect3DDevice8_SetTexture(device, 0, NULL);
3797 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
3798 hr = IDirect3DDevice8_SetTexture(device, 1, NULL);
3799 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
3800 IDirect3DTexture8_Release(texture);
3802 /* Render offscreen, then onscreen, and finally check the INTZ texture in both areas */
3803 hr = IDirect3DDevice8_CreateTexture(device, 640, 480, 1,
3804 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture);
3805 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
3806 hr = IDirect3DTexture8_GetSurfaceLevel(texture, 0, &ds);
3807 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
3808 hr = IDirect3DDevice8_SetRenderTarget(device, rt, ds);
3809 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
3810 hr = IDirect3DDevice8_SetPixelShader(device, 0);
3811 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
3813 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
3814 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
3816 hr = IDirect3DDevice8_BeginScene(device);
3817 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
3818 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, half_quad_1, sizeof(*half_quad_1));
3819 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3820 hr = IDirect3DDevice8_EndScene(device);
3821 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
3823 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, ds);
3824 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
3826 hr = IDirect3DDevice8_BeginScene(device);
3827 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
3828 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, half_quad_2, sizeof(*half_quad_2));
3829 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3830 hr = IDirect3DDevice8_EndScene(device);
3831 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
3833 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, NULL);
3834 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
3835 IDirect3DSurface8_Release(ds);
3836 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
3837 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
3838 hr = IDirect3DDevice8_SetTexture(device, 1, (IDirect3DBaseTexture8 *)texture);
3839 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
3840 hr = IDirect3DDevice8_SetPixelShader(device, ps);
3841 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
3843 /* Read the depth values back. */
3844 hr = IDirect3DDevice8_BeginScene(device);
3845 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
3846 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
3847 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3848 hr = IDirect3DDevice8_EndScene(device);
3849 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
3851 get_rt_readback(original_rt, &rb);
3852 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
3854 D3DCOLOR color = get_readback_color(&rb, expected_colors[i].x, expected_colors[i].y);
3855 ok(color_match(color, expected_colors[i].color, 1),
3856 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
3857 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
3859 release_surface_readback(&rb);
3861 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
3862 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
3864 IDirect3DTexture8_Release(texture);
3865 hr = IDirect3DDevice8_DeletePixelShader(device, ps);
3866 ok(SUCCEEDED(hr), "DeletePixelShader failed, hr %#x.\n", hr);
3867 IDirect3DSurface8_Release(original_rt);
3868 IDirect3DSurface8_Release(rt);
3869 refcount = IDirect3DDevice8_Release(device);
3870 ok(!refcount, "Device has %u references left.\n", refcount);
3871 done:
3872 IDirect3D8_Release(d3d);
3873 DestroyWindow(window);
3876 static void shadow_test(void)
3878 IDirect3DSurface8 *original_rt, *rt;
3879 struct surface_readback rb;
3880 IDirect3DDevice8 *device;
3881 IDirect3D8 *d3d;
3882 ULONG refcount;
3883 D3DCAPS8 caps;
3884 HWND window;
3885 HRESULT hr;
3886 DWORD ps;
3887 UINT i;
3889 static const DWORD ps_code[] =
3891 0xffff0101, /* ps_1_1 */
3892 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c0, 1.0, 0.0, 1.0, 1.0 */
3893 0x00000051, 0xa00f0001, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c1, 0.0, 1.0, 0.0, 0.0 */
3894 0x00000042, 0xb00f0000, /* tex t0 */
3895 0x00000042, 0xb00f0001, /* tex t1 */
3896 0x00000005, 0xb00f0000, 0xa0e40000, 0xb0e40000, /* mul t0, c0, t0 */
3897 0x00000004, 0x800f0000, 0xa0e40001, 0xb0e40001, 0xb0e40000, /* mad r0, c1, t1, t0 */
3898 0x0000ffff, /* end */
3900 static const struct
3902 D3DFORMAT format;
3903 const char *name;
3905 formats[] =
3907 {D3DFMT_D16_LOCKABLE, "D3DFMT_D16_LOCKABLE"},
3908 {D3DFMT_D32, "D3DFMT_D32"},
3909 {D3DFMT_D15S1, "D3DFMT_D15S1"},
3910 {D3DFMT_D24S8, "D3DFMT_D24S8"},
3911 {D3DFMT_D24X8, "D3DFMT_D24X8"},
3912 {D3DFMT_D24X4S4, "D3DFMT_D24X4S4"},
3913 {D3DFMT_D16, "D3DFMT_D16"},
3915 static const struct
3917 float x, y, z;
3918 float s0, t0, p0;
3919 float s1, t1, p1, q1;
3921 quad[] =
3923 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f},
3924 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f},
3925 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
3926 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f},
3928 static const struct
3930 UINT x, y;
3931 D3DCOLOR color;
3933 expected_colors[] =
3935 {400, 60, 0x00000000},
3936 {560, 180, 0xffff00ff},
3937 {560, 300, 0xffff00ff},
3938 {400, 420, 0xffffffff},
3939 {240, 420, 0xffffffff},
3940 { 80, 300, 0x00000000},
3941 { 80, 180, 0x00000000},
3942 {240, 60, 0x00000000},
3945 window = create_window();
3946 d3d = Direct3DCreate8(D3D_SDK_VERSION);
3947 ok(!!d3d, "Failed to create a D3D object.\n");
3948 if (!(device = create_device(d3d, window, window, TRUE)))
3950 skip("Failed to create a D3D device, skipping tests.\n");
3951 goto done;
3954 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
3955 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
3956 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 1))
3958 skip("No pixel shader 1.1 support, skipping shadow test.\n");
3959 IDirect3DDevice8_Release(device);
3960 goto done;
3963 hr = IDirect3DDevice8_GetRenderTarget(device, &original_rt);
3964 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
3966 hr = IDirect3DDevice8_CreateRenderTarget(device, 1024, 1024, D3DFMT_A8R8G8B8,
3967 D3DMULTISAMPLE_NONE, FALSE, &rt);
3968 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
3969 hr = IDirect3DDevice8_CreatePixelShader(device, ps_code, &ps);
3970 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
3972 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX2
3973 | D3DFVF_TEXCOORDSIZE3(0) | D3DFVF_TEXCOORDSIZE4(1));
3974 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
3975 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
3976 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3977 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
3978 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3979 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
3980 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3981 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3982 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3984 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MINFILTER, D3DTEXF_POINT);
3985 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3986 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MIPFILTER, D3DTEXF_POINT);
3987 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3988 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MAGFILTER, D3DTEXF_POINT);
3989 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3990 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
3991 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3993 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP);
3994 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3995 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP);
3996 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3997 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MAGFILTER, D3DTEXF_POINT);
3998 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3999 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MINFILTER, D3DTEXF_POINT);
4000 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
4001 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MIPFILTER, D3DTEXF_POINT);
4002 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
4003 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS,
4004 D3DTTFF_COUNT4 | D3DTTFF_PROJECTED);
4005 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
4007 for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
4009 D3DFORMAT format = formats[i].format;
4010 IDirect3DTexture8 *texture;
4011 IDirect3DSurface8 *ds;
4012 unsigned int j;
4014 if (FAILED(IDirect3D8_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
4015 D3DFMT_X8R8G8B8, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, format)))
4016 continue;
4018 hr = IDirect3DDevice8_CreateTexture(device, 1024, 1024, 1,
4019 D3DUSAGE_DEPTHSTENCIL, format, D3DPOOL_DEFAULT, &texture);
4020 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
4022 hr = IDirect3DTexture8_GetSurfaceLevel(texture, 0, &ds);
4023 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
4025 hr = IDirect3DDevice8_SetRenderTarget(device, rt, ds);
4026 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
4028 hr = IDirect3DDevice8_SetPixelShader(device, 0);
4029 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
4031 /* Setup the depth/stencil surface. */
4032 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
4033 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
4035 hr = IDirect3DDevice8_BeginScene(device);
4036 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
4037 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
4038 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
4039 hr = IDirect3DDevice8_EndScene(device);
4040 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
4042 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, NULL);
4043 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
4044 IDirect3DSurface8_Release(ds);
4046 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
4047 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
4048 hr = IDirect3DDevice8_SetTexture(device, 1, (IDirect3DBaseTexture8 *)texture);
4049 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
4051 hr = IDirect3DDevice8_SetPixelShader(device, ps);
4052 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
4054 /* Do the actual shadow mapping. */
4055 hr = IDirect3DDevice8_BeginScene(device);
4056 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
4057 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
4058 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
4059 hr = IDirect3DDevice8_EndScene(device);
4060 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
4062 hr = IDirect3DDevice8_SetTexture(device, 0, NULL);
4063 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
4064 hr = IDirect3DDevice8_SetTexture(device, 1, NULL);
4065 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
4066 IDirect3DTexture8_Release(texture);
4068 get_rt_readback(original_rt, &rb);
4069 for (j = 0; j < sizeof(expected_colors) / sizeof(*expected_colors); ++j)
4071 D3DCOLOR color = get_readback_color(&rb, expected_colors[j].x, expected_colors[j].y);
4072 ok(color_match(color, expected_colors[j].color, 0),
4073 "Expected color 0x%08x at (%u, %u) for format %s, got 0x%08x.\n",
4074 expected_colors[j].color, expected_colors[j].x, expected_colors[j].y,
4075 formats[i].name, color);
4077 release_surface_readback(&rb);
4079 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
4080 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
4083 hr = IDirect3DDevice8_DeletePixelShader(device, ps);
4084 ok(SUCCEEDED(hr), "DeletePixelShader failed, hr %#x.\n", hr);
4085 IDirect3DSurface8_Release(original_rt);
4086 IDirect3DSurface8_Release(rt);
4087 refcount = IDirect3DDevice8_Release(device);
4088 ok(!refcount, "Device has %u references left.\n", refcount);
4089 done:
4090 IDirect3D8_Release(d3d);
4091 DestroyWindow(window);
4094 static void multisample_copy_rects_test(void)
4096 IDirect3DSurface8 *ds, *ds_plain, *rt, *readback;
4097 RECT src_rect = {64, 64, 128, 128};
4098 POINT dst_point = {96, 96};
4099 D3DLOCKED_RECT locked_rect;
4100 IDirect3DDevice8 *device;
4101 IDirect3D8 *d3d;
4102 D3DCOLOR color;
4103 ULONG refcount;
4104 HWND window;
4105 HRESULT hr;
4107 window = create_window();
4108 d3d = Direct3DCreate8(D3D_SDK_VERSION);
4109 ok(!!d3d, "Failed to create a D3D object.\n");
4110 if (!(device = create_device(d3d, window, window, TRUE)))
4112 skip("Failed to create a D3D device, skipping tests.\n");
4113 goto done;
4116 if (FAILED(IDirect3D8_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT,
4117 D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES)))
4119 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping multisampled CopyRects test.\n");
4120 IDirect3DDevice8_Release(device);
4121 goto done;
4124 hr = IDirect3DDevice8_CreateRenderTarget(device, 256, 256, D3DFMT_A8R8G8B8,
4125 D3DMULTISAMPLE_2_SAMPLES, FALSE, &rt);
4126 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
4127 hr = IDirect3DDevice8_CreateDepthStencilSurface(device, 256, 256, D3DFMT_D24S8,
4128 D3DMULTISAMPLE_2_SAMPLES, &ds);
4129 ok(SUCCEEDED(hr), "Failed to create depth stencil surface, hr %#x.\n", hr);
4130 hr = IDirect3DDevice8_CreateDepthStencilSurface(device, 256, 256, D3DFMT_D24S8,
4131 D3DMULTISAMPLE_NONE, &ds_plain);
4132 ok(SUCCEEDED(hr), "Failed to create depth stencil surface, hr %#x.\n", hr);
4133 hr = IDirect3DDevice8_CreateImageSurface(device, 256, 256, D3DFMT_A8R8G8B8, &readback);
4134 ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
4136 hr = IDirect3DDevice8_SetRenderTarget(device, rt, ds);
4137 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
4139 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
4140 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
4142 hr = IDirect3DDevice8_CopyRects(device, rt, NULL, 0, readback, NULL);
4143 ok(SUCCEEDED(hr), "Failed to read render target back, hr %#x.\n", hr);
4145 hr = IDirect3DDevice8_CopyRects(device, ds, NULL, 0, ds_plain, NULL);
4146 ok(hr == D3DERR_INVALIDCALL, "Depth buffer copy, hr %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
4148 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4149 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
4151 hr = IDirect3DDevice8_CopyRects(device, rt, &src_rect, 1, readback, &dst_point);
4152 ok(SUCCEEDED(hr), "Failed to read render target back, hr %#x.\n", hr);
4154 hr = IDirect3DSurface8_LockRect(readback, &locked_rect, NULL, D3DLOCK_READONLY);
4155 ok(SUCCEEDED(hr), "Failed to lock readback surface, hr %#x.\n", hr);
4157 color = *(DWORD *)((BYTE *)locked_rect.pBits + 31 * locked_rect.Pitch + 31 * 4);
4158 ok(color == 0xff00ff00, "Got unexpected color 0x%08x.\n", color);
4160 color = *(DWORD *)((BYTE *)locked_rect.pBits + 127 * locked_rect.Pitch + 127 * 4);
4161 ok(color == 0xffff0000, "Got unexpected color 0x%08x.\n", color);
4163 hr = IDirect3DSurface8_UnlockRect(readback);
4164 ok(SUCCEEDED(hr), "Failed to unlock readback surface, hr %#x.\n", hr);
4166 IDirect3DSurface8_Release(readback);
4167 IDirect3DSurface8_Release(ds_plain);
4168 IDirect3DSurface8_Release(ds);
4169 IDirect3DSurface8_Release(rt);
4170 refcount = IDirect3DDevice8_Release(device);
4171 ok(!refcount, "Device has %u references left.\n", refcount);
4172 done:
4173 IDirect3D8_Release(d3d);
4174 DestroyWindow(window);
4177 static void resz_test(void)
4179 IDirect3DSurface8 *rt, *original_rt, *ds, *original_ds, *intz_ds;
4180 IDirect3DTexture8 *texture;
4181 IDirect3DDevice8 *device;
4182 IDirect3D8 *d3d;
4183 DWORD ps, value;
4184 unsigned int i;
4185 ULONG refcount;
4186 D3DCAPS8 caps;
4187 HWND window;
4188 HRESULT hr;
4190 static const DWORD ps_code[] =
4192 0xffff0101, /* ps_1_1 */
4193 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1.0, 0.0, 0.0, 0.0 */
4194 0x00000051, 0xa00f0001, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c1, 0.0, 1.0, 0.0, 0.0 */
4195 0x00000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c2, 0.0, 0.0, 1.0, 0.0 */
4196 0x00000042, 0xb00f0000, /* tex t0 */
4197 0x00000042, 0xb00f0001, /* tex t1 */
4198 0x00000008, 0xb0070001, 0xa0e40000, 0xb0e40001, /* dp3 t1.xyz, c0, t1 */
4199 0x00000005, 0x80070000, 0xa0e40001, 0xb0e40001, /* mul r0.xyz, c1, t1 */
4200 0x00000004, 0x80070000, 0xa0e40000, 0xb0e40000, 0x80e40000, /* mad r0.xyz, c0, t0, r0 */
4201 0x40000001, 0x80080000, 0xa0aa0002, /* +mov r0.w, c2.z */
4202 0x0000ffff, /* end */
4204 static const struct
4206 float x, y, z;
4207 float s0, t0, p0;
4208 float s1, t1, p1, q1;
4210 quad[] =
4212 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.5f},
4213 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
4214 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
4215 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.5f},
4217 static const struct
4219 UINT x, y;
4220 D3DCOLOR color;
4222 expected_colors[] =
4224 { 80, 100, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
4225 {240, 100, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
4226 {400, 100, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
4227 {560, 100, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
4228 { 80, 450, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
4229 {240, 450, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
4230 {400, 450, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
4231 {560, 450, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
4234 window = create_window();
4235 d3d = Direct3DCreate8(D3D_SDK_VERSION);
4236 ok(!!d3d, "Failed to create a D3D object.\n");
4237 if (!(device = create_device(d3d, window, window, TRUE)))
4239 skip("Failed to create a D3D device, skipping tests.\n");
4240 goto done;
4243 if (FAILED(IDirect3D8_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT,
4244 D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES)))
4246 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping RESZ test.\n");
4247 IDirect3DDevice8_Release(device);
4248 goto done;
4250 if (FAILED(IDirect3D8_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT,
4251 D3DDEVTYPE_HAL, D3DFMT_D24S8, TRUE, D3DMULTISAMPLE_2_SAMPLES)))
4253 skip("Multisampling not supported for D3DFMT_D24S8, skipping RESZ test.\n");
4254 IDirect3DDevice8_Release(device);
4255 goto done;
4257 if (FAILED(IDirect3D8_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
4258 D3DFMT_X8R8G8B8, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, MAKEFOURCC('I','N','T','Z'))))
4260 skip("No INTZ support, skipping RESZ test.\n");
4261 IDirect3DDevice8_Release(device);
4262 goto done;
4264 if (FAILED(IDirect3D8_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
4265 D3DFMT_X8R8G8B8, D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE, MAKEFOURCC('R','E','S','Z'))))
4267 skip("No RESZ support, skipping RESZ test.\n");
4268 IDirect3DDevice8_Release(device);
4269 goto done;
4272 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
4273 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
4274 if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
4276 skip("No unconditional NP2 texture support, skipping INTZ test.\n");
4277 IDirect3DDevice8_Release(device);
4278 goto done;
4281 hr = IDirect3DDevice8_GetRenderTarget(device, &original_rt);
4282 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
4283 hr = IDirect3DDevice8_GetDepthStencilSurface(device, &original_ds);
4284 ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#x.\n", hr);
4286 hr = IDirect3DDevice8_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
4287 D3DMULTISAMPLE_2_SAMPLES, FALSE, &rt);
4288 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
4289 hr = IDirect3DDevice8_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
4290 D3DMULTISAMPLE_2_SAMPLES, &ds);
4292 hr = IDirect3DDevice8_CreateTexture(device, 640, 480, 1,
4293 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture);
4294 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
4295 hr = IDirect3DTexture8_GetSurfaceLevel(texture, 0, &intz_ds);
4296 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
4298 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, intz_ds);
4299 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
4300 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
4301 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
4303 hr = IDirect3DDevice8_SetRenderTarget(device, rt, ds);
4304 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
4305 IDirect3DSurface8_Release(intz_ds);
4306 hr = IDirect3DDevice8_CreatePixelShader(device, ps_code, &ps);
4307 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
4309 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX2
4310 | D3DFVF_TEXCOORDSIZE3(0) | D3DFVF_TEXCOORDSIZE4(1));
4311 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
4312 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
4313 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
4314 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
4315 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
4316 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
4317 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
4318 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
4319 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
4321 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MINFILTER, D3DTEXF_POINT);
4322 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
4323 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MIPFILTER, D3DTEXF_POINT);
4324 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
4325 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MAGFILTER, D3DTEXF_POINT);
4326 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
4327 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
4328 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
4330 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP);
4331 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
4332 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP);
4333 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
4334 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MAGFILTER, D3DTEXF_POINT);
4335 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
4336 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MINFILTER, D3DTEXF_POINT);
4337 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
4338 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MIPFILTER, D3DTEXF_POINT);
4339 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
4340 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS,
4341 D3DTTFF_COUNT4 | D3DTTFF_PROJECTED);
4342 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
4344 /* Render offscreen (multisampled), blit the depth buffer into the INTZ texture and then check its contents. */
4345 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
4346 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
4348 hr = IDirect3DDevice8_BeginScene(device);
4349 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
4350 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
4351 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
4353 /* The destination depth texture has to be bound to sampler 0 */
4354 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
4355 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
4357 /* the ATI "spec" says you have to do a dummy draw to ensure correct commands ordering */
4358 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, FALSE);
4359 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
4360 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
4361 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
4362 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0);
4363 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
4364 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
4365 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
4366 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, TRUE);
4367 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
4368 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
4369 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
4370 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0xf);
4371 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
4373 /* The actual multisampled depth buffer resolve happens here */
4374 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
4375 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
4376 hr = IDirect3DDevice8_GetRenderState(device, D3DRS_POINTSIZE, &value);
4377 ok(SUCCEEDED(hr) && value == 0x7fa05000, "GetRenderState failed, hr %#x, value %#x.\n", hr, value);
4379 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, NULL);
4380 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
4381 hr = IDirect3DDevice8_SetTexture(device, 1, (IDirect3DBaseTexture8 *)texture);
4382 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
4383 hr = IDirect3DDevice8_SetPixelShader(device, ps);
4384 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
4386 /* Read the depth values back. */
4387 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
4388 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
4389 hr = IDirect3DDevice8_EndScene(device);
4390 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
4392 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
4394 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
4395 ok(color_match(color, expected_colors[i].color, 1),
4396 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
4397 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
4400 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
4401 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
4403 /* Test edge cases - try with no texture at all */
4404 hr = IDirect3DDevice8_SetTexture(device, 0, NULL);
4405 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
4406 hr = IDirect3DDevice8_SetTexture(device, 1, NULL);
4407 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
4408 hr = IDirect3DDevice8_SetRenderTarget(device, rt, ds);
4409 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
4411 hr = IDirect3DDevice8_BeginScene(device);
4412 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
4413 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
4414 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
4415 hr = IDirect3DDevice8_EndScene(device);
4416 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
4418 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
4419 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
4421 /* With a non-multisampled depth buffer */
4422 IDirect3DSurface8_Release(ds);
4423 IDirect3DSurface8_Release(rt);
4424 hr = IDirect3DDevice8_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
4425 D3DMULTISAMPLE_NONE, &ds);
4427 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, ds);
4428 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
4429 hr = IDirect3DDevice8_SetPixelShader(device, 0);
4430 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
4432 hr = IDirect3DDevice8_BeginScene(device);
4433 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
4434 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
4435 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
4436 hr = IDirect3DDevice8_EndScene(device);
4437 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
4439 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
4440 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
4442 hr = IDirect3DDevice8_BeginScene(device);
4443 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
4444 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, FALSE);
4445 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
4446 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
4447 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
4448 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0);
4449 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
4450 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
4451 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
4452 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, TRUE);
4453 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
4454 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
4455 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
4456 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0xf);
4457 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
4458 hr = IDirect3DDevice8_EndScene(device);
4459 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
4461 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
4462 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
4464 hr = IDirect3DDevice8_SetTexture(device, 1, (IDirect3DBaseTexture8 *)texture);
4465 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
4466 hr = IDirect3DDevice8_SetPixelShader(device, ps);
4467 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
4469 /* Read the depth values back. */
4470 hr = IDirect3DDevice8_BeginScene(device);
4471 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
4472 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
4473 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
4474 hr = IDirect3DDevice8_EndScene(device);
4475 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
4477 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
4479 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
4480 ok(color_match(color, expected_colors[i].color, 1),
4481 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
4482 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
4485 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
4486 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
4488 IDirect3DSurface8_Release(ds);
4489 IDirect3DTexture8_Release(texture);
4490 hr = IDirect3DDevice8_DeletePixelShader(device, ps);
4491 ok(SUCCEEDED(hr), "DeletePixelShader failed, hr %#x.\n", hr);
4492 IDirect3DSurface8_Release(original_ds);
4493 IDirect3DSurface8_Release(original_rt);
4495 refcount = IDirect3DDevice8_Release(device);
4496 ok(!refcount, "Device has %u references left.\n", refcount);
4497 done:
4498 IDirect3D8_Release(d3d);
4499 DestroyWindow(window);
4502 static void zenable_test(void)
4504 IDirect3DDevice8 *device;
4505 IDirect3D8 *d3d;
4506 D3DCOLOR color;
4507 ULONG refcount;
4508 D3DCAPS8 caps;
4509 HWND window;
4510 HRESULT hr;
4511 UINT x, y;
4512 UINT i, j;
4513 UINT test;
4514 IDirect3DSurface8 *ds, *rt;
4516 static const struct
4518 struct vec4 position;
4519 D3DCOLOR diffuse;
4521 tquad[] =
4523 {{ 0.0f, 480.0f, -0.5f, 1.0f}, 0xff00ff00},
4524 {{ 0.0f, 0.0f, -0.5f, 1.0f}, 0xff00ff00},
4525 {{640.0f, 480.0f, 1.5f, 1.0f}, 0xff00ff00},
4526 {{640.0f, 0.0f, 1.5f, 1.0f}, 0xff00ff00},
4529 window = create_window();
4530 d3d = Direct3DCreate8(D3D_SDK_VERSION);
4531 ok(!!d3d, "Failed to create a D3D object.\n");
4532 if (!(device = create_device(d3d, window, window, TRUE)))
4534 skip("Failed to create a D3D device, skipping tests.\n");
4535 goto done;
4538 hr = IDirect3DDevice8_GetDepthStencilSurface(device, &ds);
4539 ok(SUCCEEDED(hr), "Failed to get depth stencil surface, hr %#x.\n", hr);
4540 hr = IDirect3DDevice8_GetRenderTarget(device, &rt);
4541 ok(SUCCEEDED(hr), "Failed to get render target surface, hr %#x.\n", hr);
4543 for (test = 0; test < 2; ++test)
4545 /* The Windows 8 testbot (WARP) appears to clip with
4546 * ZENABLE = D3DZB_TRUE and no depth buffer set. */
4547 static const D3DCOLOR expected_broken[] =
4549 0x00ff0000, 0x0000ff00, 0x0000ff00, 0x00ff0000,
4550 0x00ff0000, 0x0000ff00, 0x0000ff00, 0x00ff0000,
4551 0x00ff0000, 0x0000ff00, 0x0000ff00, 0x00ff0000,
4552 0x00ff0000, 0x0000ff00, 0x0000ff00, 0x00ff0000,
4555 if (!test)
4557 hr = IDirect3DDevice8_SetRenderTarget(device, rt, NULL);
4558 ok(SUCCEEDED(hr), "Failed to set depth stencil surface, hr %#x.\n", hr);
4560 else
4562 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
4563 ok(SUCCEEDED(hr), "Failed to disable z-buffering, hr %#x.\n", hr);
4564 hr = IDirect3DDevice8_SetRenderTarget(device, rt, ds);
4565 ok(SUCCEEDED(hr), "Failed to set depth stencil surface, hr %#x.\n", hr);
4566 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 0.0f, 0);
4567 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
4569 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
4570 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
4572 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0f, 0);
4573 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
4574 hr = IDirect3DDevice8_BeginScene(device);
4575 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
4576 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, tquad, sizeof(*tquad));
4577 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4578 hr = IDirect3DDevice8_EndScene(device);
4579 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
4581 for (i = 0; i < 4; ++i)
4583 for (j = 0; j < 4; ++j)
4585 x = 80 * ((2 * j) + 1);
4586 y = 60 * ((2 * i) + 1);
4587 color = getPixelColor(device, x, y);
4588 ok(color_match(color, 0x0000ff00, 1)
4589 || broken(color_match(color, expected_broken[i * 4 + j], 1) && !test),
4590 "Expected color 0x0000ff00 at %u, %u, got 0x%08x.\n", x, y, color);
4594 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
4595 ok(SUCCEEDED(hr), "Failed to present backbuffer, hr %#x.\n", hr);
4598 IDirect3DSurface8_Release(ds);
4599 IDirect3DSurface8_Release(rt);
4601 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
4602 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
4604 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1)
4605 && caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
4607 static const DWORD vs_code[] =
4609 0xfffe0101, /* vs_1_1 */
4610 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4611 0x00000001, 0xd00f0000, 0x90e40000, /* mov oD0, v0 */
4612 0x0000ffff
4614 static const DWORD ps_code[] =
4616 0xffff0101, /* ps_1_1 */
4617 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
4618 0x0000ffff /* end */
4620 static const struct vec3 quad[] =
4622 {-1.0f, -1.0f, -0.5f},
4623 {-1.0f, 1.0f, -0.5f},
4624 { 1.0f, -1.0f, 1.5f},
4625 { 1.0f, 1.0f, 1.5f},
4627 static const D3DCOLOR expected[] =
4629 0x00ff0000, 0x0060df60, 0x009fdf9f, 0x00ff0000,
4630 0x00ff0000, 0x00609f60, 0x009f9f9f, 0x00ff0000,
4631 0x00ff0000, 0x00606060, 0x009f609f, 0x00ff0000,
4632 0x00ff0000, 0x00602060, 0x009f209f, 0x00ff0000,
4634 /* The Windows 8 testbot (WARP) appears to not clip z for regular
4635 * vertices either. */
4636 static const D3DCOLOR expected_broken[] =
4638 0x0020df20, 0x0060df60, 0x009fdf9f, 0x00dfdfdf,
4639 0x00209f20, 0x00609f60, 0x009f9f9f, 0x00df9fdf,
4640 0x00206020, 0x00606060, 0x009f609f, 0x00df60df,
4641 0x00202020, 0x00602060, 0x009f209f, 0x00df20df,
4643 static const DWORD decl[] =
4645 D3DVSD_STREAM(0),
4646 D3DVSD_REG(D3DVSDE_POSITION, D3DVSDT_FLOAT3),
4647 D3DVSD_END()
4649 DWORD vs, ps;
4651 hr = IDirect3DDevice8_CreateVertexShader(device, decl, vs_code, &vs, 0);
4652 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
4653 hr = IDirect3DDevice8_CreatePixelShader(device, ps_code, &ps);
4654 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
4655 hr = IDirect3DDevice8_SetVertexShader(device, vs);
4656 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
4657 hr = IDirect3DDevice8_SetPixelShader(device, ps);
4658 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
4660 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0f, 0);
4661 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
4662 hr = IDirect3DDevice8_BeginScene(device);
4663 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
4664 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
4665 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4666 hr = IDirect3DDevice8_EndScene(device);
4667 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
4669 for (i = 0; i < 4; ++i)
4671 for (j = 0; j < 4; ++j)
4673 x = 80 * ((2 * j) + 1);
4674 y = 60 * ((2 * i) + 1);
4675 color = getPixelColor(device, x, y);
4676 ok(color_match(color, expected[i * 4 + j], 1)
4677 || broken(color_match(color, expected_broken[i * 4 + j], 1)),
4678 "Expected color 0x%08x at %u, %u, got 0x%08x.\n", expected[i * 4 + j], x, y, color);
4682 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
4683 ok(SUCCEEDED(hr), "Failed to present backbuffer, hr %#x.\n", hr);
4685 hr = IDirect3DDevice8_DeletePixelShader(device, ps);
4686 ok(SUCCEEDED(hr), "Failed to delete pixel shader, hr %#x.\n", hr);
4687 hr = IDirect3DDevice8_DeleteVertexShader(device, vs);
4688 ok(SUCCEEDED(hr), "Failed to delete vertex shader, hr %#x.\n", hr);
4691 refcount = IDirect3DDevice8_Release(device);
4692 ok(!refcount, "Device has %u references left.\n", refcount);
4693 done:
4694 IDirect3D8_Release(d3d);
4695 DestroyWindow(window);
4698 static void fog_special_test(void)
4700 IDirect3DDevice8 *device;
4701 IDirect3D8 *d3d;
4702 unsigned int i;
4703 D3DCOLOR color;
4704 ULONG refcount;
4705 D3DCAPS8 caps;
4706 DWORD ps, vs;
4707 HWND window;
4708 HRESULT hr;
4709 union
4711 float f;
4712 DWORD d;
4713 } conv;
4715 static const struct
4717 struct vec3 position;
4718 D3DCOLOR diffuse;
4720 quad[] =
4722 {{ -1.0f, -1.0f, 0.0f}, 0xff00ff00},
4723 {{ -1.0f, 1.0f, 0.0f}, 0xff00ff00},
4724 {{ 1.0f, -1.0f, 1.0f}, 0xff00ff00},
4725 {{ 1.0f, 1.0f, 1.0f}, 0xff00ff00}
4727 static const struct
4729 DWORD vertexmode, tablemode;
4730 BOOL vs, ps;
4731 D3DCOLOR color_left, color_right;
4733 tests[] =
4735 {D3DFOG_LINEAR, D3DFOG_NONE, FALSE, FALSE, 0x00ff0000, 0x00ff0000},
4736 {D3DFOG_LINEAR, D3DFOG_NONE, FALSE, TRUE, 0x00ff0000, 0x00ff0000},
4737 {D3DFOG_LINEAR, D3DFOG_NONE, TRUE, FALSE, 0x00ff0000, 0x00ff0000},
4738 {D3DFOG_LINEAR, D3DFOG_NONE, TRUE, TRUE, 0x00ff0000, 0x00ff0000},
4740 {D3DFOG_NONE, D3DFOG_LINEAR, FALSE, FALSE, 0x0000ff00, 0x00ff0000},
4741 {D3DFOG_NONE, D3DFOG_LINEAR, FALSE, TRUE, 0x0000ff00, 0x00ff0000},
4742 {D3DFOG_NONE, D3DFOG_LINEAR, TRUE, FALSE, 0x0000ff00, 0x00ff0000},
4743 {D3DFOG_NONE, D3DFOG_LINEAR, TRUE, TRUE, 0x0000ff00, 0x00ff0000},
4745 static const DWORD pixel_shader_code[] =
4747 0xffff0101, /* ps.1.1 */
4748 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
4749 0x0000ffff
4751 static const DWORD vertex_decl[] =
4753 D3DVSD_STREAM(0),
4754 D3DVSD_REG(0, D3DVSDT_FLOAT3), /* position, v0 */
4755 D3DVSD_REG(1, D3DVSDT_D3DCOLOR), /* diffuse color, v1 */
4756 D3DVSD_END()
4758 static const DWORD vertex_shader_code[] =
4760 0xfffe0101, /* vs.1.1 */
4761 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4762 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
4763 0x0000ffff
4765 static const D3DMATRIX identity =
4767 1.0f, 0.0f, 0.0f, 0.0f,
4768 0.0f, 1.0f, 0.0f, 0.0f,
4769 0.0f, 0.0f, 1.0f, 0.0f,
4770 0.0f, 0.0f, 0.0f, 1.0f,
4771 }}};
4773 window = create_window();
4774 d3d = Direct3DCreate8(D3D_SDK_VERSION);
4775 ok(!!d3d, "Failed to create a D3D object.\n");
4776 if (!(device = create_device(d3d, window, window, TRUE)))
4778 skip("Failed to create a D3D device, skipping tests.\n");
4779 goto done;
4782 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
4783 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
4784 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
4786 hr = IDirect3DDevice8_CreateVertexShader(device, vertex_decl, vertex_shader_code, &vs, 0);
4787 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
4789 else
4791 skip("Vertex Shaders not supported, skipping some fog tests.\n");
4792 vs = 0;
4794 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
4796 hr = IDirect3DDevice8_CreatePixelShader(device, pixel_shader_code, &ps);
4797 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
4799 else
4801 skip("Pixel Shaders not supported, skipping some fog tests.\n");
4802 ps = 0;
4805 /* The table fog tests seem to depend on the projection matrix explicitly
4806 * being set to an identity matrix, even though that's the default.
4807 * (AMD Radeon HD 6310, Windows 7) */
4808 hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, &identity);
4809 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
4811 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
4812 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
4813 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
4814 ok(SUCCEEDED(hr), "Failed to enable fog, hr %#x.\n", hr);
4815 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGCOLOR, 0xffff0000);
4816 ok(SUCCEEDED(hr), "Failed to set fog color, hr %#x.\n", hr);
4818 conv.f = 0.5f;
4819 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGSTART, conv.d);
4820 ok(SUCCEEDED(hr), "Failed to set fog start, hr %#x.\n", hr);
4821 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGEND, conv.d);
4822 ok(SUCCEEDED(hr), "Failed to set fog end, hr %#x.\n", hr);
4824 for (i = 0; i < sizeof(tests) / sizeof(*tests); i++)
4826 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
4827 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
4829 if (!tests[i].vs)
4831 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
4832 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr);
4834 else if (vs)
4836 hr = IDirect3DDevice8_SetVertexShader(device, vs);
4837 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
4839 else
4841 continue;
4844 if (!tests[i].ps)
4846 hr = IDirect3DDevice8_SetPixelShader(device, 0);
4847 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
4849 else if (ps)
4851 hr = IDirect3DDevice8_SetPixelShader(device, ps);
4852 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
4854 else
4856 continue;
4859 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGVERTEXMODE, tests[i].vertexmode);
4860 ok(SUCCEEDED(hr), "Failed to set fogvertexmode, hr %#x.\n", hr);
4861 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGTABLEMODE, tests[i].tablemode);
4862 ok(SUCCEEDED(hr), "Failed to set fogtablemode, hr %#x.\n", hr);
4864 hr = IDirect3DDevice8_BeginScene(device);
4865 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
4866 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
4867 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4868 hr = IDirect3DDevice8_EndScene(device);
4869 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
4871 color = getPixelColor(device, 310, 240);
4872 ok(color_match(color, tests[i].color_left, 1),
4873 "Expected left color 0x%08x, got 0x%08x, case %u.\n", tests[i].color_left, color, i);
4874 color = getPixelColor(device, 330, 240);
4875 ok(color_match(color, tests[i].color_right, 1),
4876 "Expected right color 0x%08x, got 0x%08x, case %u.\n", tests[i].color_right, color, i);
4878 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
4879 ok(SUCCEEDED(hr), "Failed to present backbuffer, hr %#x.\n", hr);
4882 if (vs)
4883 IDirect3DDevice8_DeleteVertexShader(device, vs);
4884 if (ps)
4885 IDirect3DDevice8_DeletePixelShader(device, ps);
4886 refcount = IDirect3DDevice8_Release(device);
4887 ok(!refcount, "Device has %u references left.\n", refcount);
4888 done:
4889 IDirect3D8_Release(d3d);
4890 DestroyWindow(window);
4893 static void volume_dxt5_test(void)
4895 IDirect3DVolumeTexture8 *texture;
4896 IDirect3DDevice8 *device;
4897 D3DLOCKED_BOX box;
4898 IDirect3D8 *d3d;
4899 unsigned int i;
4900 D3DCOLOR color;
4901 ULONG refcount;
4902 HWND window;
4903 HRESULT hr;
4905 static const char texture_data[] =
4907 /* A 8x4x2 texture consisting of 4 4x4 blocks. The colors of the blocks are red, green, blue and white. */
4908 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00,
4909 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00,
4910 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00,
4911 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00
4913 static const struct
4915 struct vec3 position;
4916 struct vec3 texcrd;
4918 quads[] =
4920 {{ -1.0f, -1.0f, 0.0f}, { 0.0f, 0.0f, 0.25f}},
4921 {{ -1.0f, 1.0f, 0.0f}, { 0.0f, 1.0f, 0.25f}},
4922 {{ 0.0f, -1.0f, 1.0f}, { 1.0f, 0.0f, 0.25f}},
4923 {{ 0.0f, 1.0f, 1.0f}, { 1.0f, 1.0f, 0.25f}},
4925 {{ 0.0f, -1.0f, 0.0f}, { 0.0f, 0.0f, 0.75f}},
4926 {{ 0.0f, 1.0f, 0.0f}, { 0.0f, 1.0f, 0.75f}},
4927 {{ 1.0f, -1.0f, 1.0f}, { 1.0f, 0.0f, 0.75f}},
4928 {{ 1.0f, 1.0f, 1.0f}, { 1.0f, 1.0f, 0.75f}},
4930 static const DWORD expected_colors[] = {0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff};
4932 window = create_window();
4933 d3d = Direct3DCreate8(D3D_SDK_VERSION);
4934 ok(!!d3d, "Failed to create a D3D object.\n");
4935 if (!(device = create_device(d3d, window, window, TRUE)))
4937 skip("Failed to create a D3D device, skipping tests.\n");
4938 goto done;
4941 if (FAILED(IDirect3D8_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
4942 D3DFMT_X8R8G8B8, 0, D3DRTYPE_VOLUMETEXTURE, D3DFMT_DXT5)))
4944 skip("Volume DXT5 textures are not supported, skipping test.\n");
4945 IDirect3DDevice8_Release(device);
4946 goto done;
4949 hr = IDirect3DDevice8_CreateVolumeTexture(device, 8, 4, 2, 1, 0, D3DFMT_DXT5,
4950 D3DPOOL_MANAGED, &texture);
4951 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
4953 hr = IDirect3DVolumeTexture8_LockBox(texture, 0, &box, NULL, 0);
4954 ok(SUCCEEDED(hr), "Failed to lock volume texture, hr %#x.\n", hr);
4955 memcpy(box.pBits, texture_data, sizeof(texture_data));
4956 hr = IDirect3DVolumeTexture8_UnlockBox(texture, 0);
4957 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#x.\n", hr);
4959 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE3(0));
4960 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
4961 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
4962 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
4963 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
4964 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
4965 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
4966 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
4967 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
4968 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
4969 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MAGFILTER, D3DTEXF_POINT);
4970 ok(SUCCEEDED(hr), "Failed to set mag filter, hr %#x.\n", hr);
4972 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff00ff, 1.0f, 0);
4973 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
4974 hr = IDirect3DDevice8_BeginScene(device);
4975 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
4976 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads));
4977 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4978 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[4], sizeof(*quads));
4979 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4980 hr = IDirect3DDevice8_EndScene(device);
4981 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
4983 for (i = 0; i < 4; i++)
4985 color = getPixelColor(device, 80 + 160 * i, 240);
4986 ok (color_match(color, expected_colors[i], 1),
4987 "Expected color 0x%08x, got 0x%08x, case %u.\n", expected_colors[i], color, i);
4990 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
4991 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
4992 IDirect3DVolumeTexture8_Release(texture);
4993 refcount = IDirect3DDevice8_Release(device);
4994 ok(!refcount, "Device has %u references left.\n", refcount);
4995 done:
4996 IDirect3D8_Release(d3d);
4997 DestroyWindow(window);
5000 static void volume_v16u16_test(void)
5002 IDirect3DVolumeTexture8 *texture;
5003 IDirect3DDevice8 *device;
5004 D3DLOCKED_BOX box;
5005 IDirect3D8 *d3d;
5006 unsigned int i;
5007 D3DCOLOR color;
5008 ULONG refcount;
5009 D3DCAPS8 caps;
5010 DWORD shader;
5011 SHORT *texel;
5012 HWND window;
5013 HRESULT hr;
5015 static const struct
5017 struct vec3 position;
5018 struct vec3 texcrd;
5020 quads[] =
5022 {{ -1.0f, -1.0f, 0.0f}, { 0.0f, 0.0f, 0.25f}},
5023 {{ -1.0f, 1.0f, 0.0f}, { 0.0f, 1.0f, 0.25f}},
5024 {{ 0.0f, -1.0f, 1.0f}, { 1.0f, 0.0f, 0.25f}},
5025 {{ 0.0f, 1.0f, 1.0f}, { 1.0f, 1.0f, 0.25f}},
5027 {{ 0.0f, -1.0f, 0.0f}, { 0.0f, 0.0f, 0.75f}},
5028 {{ 0.0f, 1.0f, 0.0f}, { 0.0f, 1.0f, 0.75f}},
5029 {{ 1.0f, -1.0f, 1.0f}, { 1.0f, 0.0f, 0.75f}},
5030 {{ 1.0f, 1.0f, 1.0f}, { 1.0f, 1.0f, 0.75f}},
5032 static const DWORD shader_code[] =
5034 0xffff0101, /* ps_1_1 */
5035 0x00000051, 0xa00f0000, 0x3f000000, 0x3f000000, /* def c0, 0.5, 0.5, */
5036 0x3f000000, 0x3f000000, /* 0.5, 0.5 */
5037 0x00000042, 0xb00f0000, /* tex t0 */
5038 0x00000004, 0x800f0000, 0xb0e40000, 0xa0e40000, 0xa0e40000, /* mad r0, t0, c0, c0 */
5039 0x0000ffff /* end */
5042 window = create_window();
5043 d3d = Direct3DCreate8(D3D_SDK_VERSION);
5044 ok(!!d3d, "Failed to create a D3D object.\n");
5045 if (!(device = create_device(d3d, window, window, TRUE)))
5047 skip("Failed to create a D3D device, skipping tests.\n");
5048 goto done;
5051 if (FAILED(IDirect3D8_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
5052 D3DFMT_X8R8G8B8, 0, D3DRTYPE_VOLUMETEXTURE, D3DFMT_V16U16)))
5054 skip("Volume V16U16 textures are not supported, skipping test.\n");
5055 IDirect3DDevice8_Release(device);
5056 goto done;
5058 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
5059 ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
5060 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 1))
5062 skip("No pixel shader 1.1 support, skipping test.\n");
5063 IDirect3DDevice8_Release(device);
5064 goto done;
5067 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE3(0));
5068 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
5069 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code, &shader);
5070 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
5071 hr = IDirect3DDevice8_SetPixelShader(device, shader);
5072 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
5073 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MAGFILTER, D3DTEXF_POINT);
5074 ok(SUCCEEDED(hr), "Failed to set filter, hr %#x.\n", hr);
5076 for (i = 0; i < 2; i++)
5078 D3DPOOL pool;
5080 if (i)
5081 pool = D3DPOOL_SYSTEMMEM;
5082 else
5083 pool = D3DPOOL_MANAGED;
5085 hr = IDirect3DDevice8_CreateVolumeTexture(device, 1, 2, 2, 1, 0, D3DFMT_V16U16,
5086 pool, &texture);
5087 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
5089 hr = IDirect3DVolumeTexture8_LockBox(texture, 0, &box, NULL, 0);
5090 ok(SUCCEEDED(hr), "Failed to lock volume texture, hr %#x.\n", hr);
5092 texel = (SHORT *)((BYTE *)box.pBits + 0 * box.RowPitch + 0 * box.SlicePitch);
5093 texel[0] = 32767;
5094 texel[1] = 32767;
5095 texel = (SHORT *)((BYTE *)box.pBits + 1 * box.RowPitch + 0 * box.SlicePitch);
5096 texel[0] = -32768;
5097 texel[1] = 0;
5098 texel = (SHORT *)((BYTE *)box.pBits + 0 * box.RowPitch + 1 * box.SlicePitch);
5099 texel[0] = -16384;
5100 texel[1] = 16384;
5101 texel = (SHORT *)((BYTE *)box.pBits + 1 * box.RowPitch + 1 * box.SlicePitch);
5102 texel[0] = 0;
5103 texel[1] = 0;
5105 hr = IDirect3DVolumeTexture8_UnlockBox(texture, 0);
5106 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#x.\n", hr);
5108 if (i)
5110 IDirect3DVolumeTexture8 *texture2;
5112 hr = IDirect3DDevice8_CreateVolumeTexture(device, 1, 2, 2, 1, 0, D3DFMT_V16U16,
5113 D3DPOOL_DEFAULT, &texture2);
5114 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
5116 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)texture,
5117 (IDirect3DBaseTexture8 *)texture2);
5118 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
5120 IDirect3DVolumeTexture8_Release(texture);
5121 texture = texture2;
5124 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *) texture);
5125 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
5127 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff00ff, 1.0f, 0);
5128 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
5129 hr = IDirect3DDevice8_BeginScene(device);
5130 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5131 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads));
5132 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5133 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[4], sizeof(*quads));
5134 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5135 hr = IDirect3DDevice8_EndScene(device);
5136 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5138 color = getPixelColor(device, 120, 160);
5139 ok (color_match(color, 0x000080ff, 2),
5140 "Expected color 0x000080ff, got 0x%08x, V16U16 input -32768, 0.\n", color);
5141 color = getPixelColor(device, 120, 400);
5142 ok (color_match(color, 0x00ffffff, 2),
5143 "Expected color 0x00ffffff, got 0x%08x, V16U16 input 32767, 32767.\n", color);
5144 color = getPixelColor(device, 360, 160);
5145 ok (color_match(color, 0x007f7fff, 2),
5146 "Expected color 0x007f7fff, got 0x%08x, V16U16 input 0, 0.\n", color);
5147 color = getPixelColor(device, 360, 400);
5148 ok (color_match(color, 0x0040c0ff, 2),
5149 "Expected color 0x0040c0ff, got 0x%08x, V16U16 input -16384, 16384.\n", color);
5151 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5152 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5154 IDirect3DVolumeTexture8_Release(texture);
5157 hr = IDirect3DDevice8_DeletePixelShader(device, shader);
5158 ok(SUCCEEDED(hr), "Failed delete pixel shader, hr %#x.\n", hr);
5159 refcount = IDirect3DDevice8_Release(device);
5160 ok(!refcount, "Device has %u references left.\n", refcount);
5161 done:
5162 IDirect3D8_Release(d3d);
5163 DestroyWindow(window);
5166 static void fill_surface(IDirect3DSurface8 *surface, DWORD color, DWORD flags)
5168 D3DSURFACE_DESC desc;
5169 D3DLOCKED_RECT l;
5170 HRESULT hr;
5171 unsigned int x, y;
5172 DWORD *mem;
5174 hr = IDirect3DSurface8_GetDesc(surface, &desc);
5175 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
5176 hr = IDirect3DSurface8_LockRect(surface, &l, NULL, flags);
5177 ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
5178 if (FAILED(hr))
5179 return;
5181 for (y = 0; y < desc.Height; y++)
5183 mem = (DWORD *)((BYTE *)l.pBits + y * l.Pitch);
5184 for (x = 0; x < l.Pitch / sizeof(DWORD); x++)
5186 mem[x] = color;
5189 hr = IDirect3DSurface8_UnlockRect(surface);
5190 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
5193 static void add_dirty_rect_test_draw(IDirect3DDevice8 *device)
5195 HRESULT hr;
5196 static const struct
5198 struct vec3 position;
5199 struct vec2 texcoord;
5201 quad[] =
5203 {{-1.0f, -1.0f, 0.0f}, {0.0f, 0.0f}},
5204 {{-1.0f, 1.0f, 0.0f}, {0.0f, 1.0f}},
5205 {{ 1.0f, -1.0f, 0.0f}, {1.0f, 0.0f}},
5206 {{ 1.0f, 1.0f, 0.0f}, {1.0f, 1.0f}},
5209 hr = IDirect3DDevice8_BeginScene(device);
5210 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5211 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad, sizeof(*quad));
5212 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5213 hr = IDirect3DDevice8_EndScene(device);
5214 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5217 static void add_dirty_rect_test(void)
5219 IDirect3DTexture8 *tex_dst1, *tex_dst2, *tex_src_red, *tex_src_green,
5220 *tex_managed, *tex_dynamic;
5221 IDirect3DSurface8 *surface_dst2, *surface_src_green, *surface_src_red,
5222 *surface_managed, *surface_dynamic;
5223 D3DLOCKED_RECT locked_rect;
5224 IDirect3DDevice8 *device;
5225 IDirect3D8 *d3d;
5226 unsigned int i;
5227 D3DCOLOR color;
5228 ULONG refcount;
5229 DWORD *texel;
5230 HWND window;
5231 HRESULT hr;
5233 static const RECT part_rect = {96, 96, 160, 160};
5235 window = create_window();
5236 d3d = Direct3DCreate8(D3D_SDK_VERSION);
5237 ok(!!d3d, "Failed to create a D3D object.\n");
5238 if (!(device = create_device(d3d, window, window, TRUE)))
5240 skip("Failed to create a D3D device, skipping tests.\n");
5241 goto done;
5244 hr = IDirect3DDevice8_CreateTexture(device, 256, 256, 1, 0, D3DFMT_X8R8G8B8,
5245 D3DPOOL_DEFAULT, &tex_dst1);
5246 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
5247 hr = IDirect3DDevice8_CreateTexture(device, 256, 256, 1, 0, D3DFMT_X8R8G8B8,
5248 D3DPOOL_DEFAULT, &tex_dst2);
5249 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
5250 hr = IDirect3DDevice8_CreateTexture(device, 256, 256, 1, 0, D3DFMT_X8R8G8B8,
5251 D3DPOOL_SYSTEMMEM, &tex_src_red);
5252 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
5253 hr = IDirect3DDevice8_CreateTexture(device, 256, 256, 1, 0, D3DFMT_X8R8G8B8,
5254 D3DPOOL_SYSTEMMEM, &tex_src_green);
5255 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
5256 hr = IDirect3DDevice8_CreateTexture(device, 256, 256, 1, 0, D3DFMT_X8R8G8B8,
5257 D3DPOOL_MANAGED, &tex_managed);
5258 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
5259 hr = IDirect3DDevice8_CreateTexture(device, 256, 256, 1, D3DUSAGE_DYNAMIC,
5260 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &tex_dynamic);
5261 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
5263 hr = IDirect3DTexture8_GetSurfaceLevel(tex_dst2, 0, &surface_dst2);
5264 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
5265 hr = IDirect3DTexture8_GetSurfaceLevel(tex_src_green, 0, &surface_src_green);
5266 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
5267 hr = IDirect3DTexture8_GetSurfaceLevel(tex_src_red, 0, &surface_src_red);
5268 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
5269 hr = IDirect3DTexture8_GetSurfaceLevel(tex_managed, 0, &surface_managed);
5270 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
5271 hr = IDirect3DTexture8_GetSurfaceLevel(tex_dynamic, 0, &surface_dynamic);
5272 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
5274 fill_surface(surface_src_red, 0x00ff0000, 0);
5275 fill_surface(surface_src_green, 0x0000ff00, 0);
5277 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX1);
5278 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr);
5279 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
5280 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
5281 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
5282 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
5284 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_green,
5285 (IDirect3DBaseTexture8 *)tex_dst1);
5286 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
5288 /* The second UpdateTexture call writing to tex_dst2 is ignored because tex_src_green is not dirty. */
5289 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_red,
5290 (IDirect3DBaseTexture8 *)tex_dst2);
5291 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
5292 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_green,
5293 (IDirect3DBaseTexture8 *)tex_dst2);
5294 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
5296 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)tex_dst1);
5297 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
5298 add_dirty_rect_test_draw(device);
5299 color = getPixelColor(device, 320, 240);
5300 ok(color_match(color, 0x0000ff00, 1),
5301 "Expected color 0x0000ff00, got 0x%08x.\n", color);
5302 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5303 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5305 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)tex_dst2);
5306 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
5307 add_dirty_rect_test_draw(device);
5308 color = getPixelColor(device, 320, 240);
5309 todo_wine ok(color_match(color, 0x00ff0000, 1),
5310 "Expected color 0x00ff0000, got 0x%08x.\n", color);
5311 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5312 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5314 /* AddDirtyRect on the destination is ignored. */
5315 hr = IDirect3DTexture8_AddDirtyRect(tex_dst2, &part_rect);
5316 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
5317 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_green,
5318 (IDirect3DBaseTexture8 *)tex_dst2);
5319 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
5320 add_dirty_rect_test_draw(device);
5321 color = getPixelColor(device, 320, 240);
5322 todo_wine ok(color_match(color, 0x00ff0000, 1),
5323 "Expected color 0x00ff0000, got 0x%08x.\n", color);
5324 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5325 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5327 hr = IDirect3DTexture8_AddDirtyRect(tex_dst2, NULL);
5328 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
5329 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_green,
5330 (IDirect3DBaseTexture8 *)tex_dst2);
5331 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
5332 add_dirty_rect_test_draw(device);
5333 color = getPixelColor(device, 320, 240);
5334 todo_wine ok(color_match(color, 0x00ff0000, 1),
5335 "Expected color 0x00ff0000, got 0x%08x.\n", color);
5336 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5337 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5339 /* AddDirtyRect on the source makes UpdateTexture work. Partial rectangle
5340 * tracking is supported. */
5341 hr = IDirect3DTexture8_AddDirtyRect(tex_src_green, &part_rect);
5342 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
5343 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_green,
5344 (IDirect3DBaseTexture8 *)tex_dst2);
5345 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
5346 add_dirty_rect_test_draw(device);
5347 color = getPixelColor(device, 320, 240);
5348 ok(color_match(color, 0x0000ff00, 1),
5349 "Expected color 0x0000ff00, got 0x%08x.\n", color);
5350 color = getPixelColor(device, 1, 1);
5351 todo_wine ok(color_match(color, 0x00ff0000, 1),
5352 "Expected color 0x00ff0000, got 0x%08x.\n", color);
5353 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5354 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5356 hr = IDirect3DTexture8_AddDirtyRect(tex_src_green, NULL);
5357 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
5358 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_green,
5359 (IDirect3DBaseTexture8 *)tex_dst2);
5360 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
5361 add_dirty_rect_test_draw(device);
5362 color = getPixelColor(device, 1, 1);
5363 ok(color_match(color, 0x0000ff00, 1),
5364 "Expected color 0x0000ff00, got 0x%08x.\n", color);
5366 /* Locks with NO_DIRTY_UPDATE are ignored. */
5367 fill_surface(surface_src_green, 0x00000080, D3DLOCK_NO_DIRTY_UPDATE);
5368 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_green,
5369 (IDirect3DBaseTexture8 *)tex_dst2);
5370 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
5371 add_dirty_rect_test_draw(device);
5372 color = getPixelColor(device, 320, 240);
5373 todo_wine ok(color_match(color, 0x0000ff00, 1),
5374 "Expected color 0x0000ff00, got 0x%08x.\n", color);
5375 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5376 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5378 /* Readonly maps write to D3DPOOL_SYSTEMMEM, but don't record a dirty rectangle. */
5379 fill_surface(surface_src_green, 0x000000ff, D3DLOCK_READONLY);
5380 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_green,
5381 (IDirect3DBaseTexture8 *)tex_dst2);
5382 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
5383 add_dirty_rect_test_draw(device);
5384 color = getPixelColor(device, 320, 240);
5385 todo_wine ok(color_match(color, 0x0000ff00, 1),
5386 "Expected color 0x0000ff00, got 0x%08x.\n", color);
5387 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5388 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5390 hr = IDirect3DTexture8_AddDirtyRect(tex_src_green, NULL);
5391 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_green,
5392 (IDirect3DBaseTexture8 *)tex_dst2);
5393 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
5394 add_dirty_rect_test_draw(device);
5395 color = getPixelColor(device, 320, 240);
5396 ok(color_match(color, 0x000000ff, 1),
5397 "Expected color 0x000000ff, got 0x%08x.\n", color);
5398 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5399 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5401 /* Maps without either of these flags record a dirty rectangle. */
5402 fill_surface(surface_src_green, 0x00ffffff, 0);
5403 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_green,
5404 (IDirect3DBaseTexture8 *)tex_dst2);
5405 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
5406 add_dirty_rect_test_draw(device);
5407 color = getPixelColor(device, 320, 240);
5408 ok(color_match(color, 0x00ffffff, 1),
5409 "Expected color 0x00ffffff, got 0x%08x.\n", color);
5410 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5411 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5413 /* Partial LockRect works just like a partial AddDirtyRect call. */
5414 hr = IDirect3DTexture8_LockRect(tex_src_green, 0, &locked_rect, &part_rect, 0);
5415 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
5416 texel = locked_rect.pBits;
5417 for (i = 0; i < 64; i++)
5418 texel[i] = 0x00ff00ff;
5419 for (i = 1; i < 64; i++)
5420 memcpy((BYTE *)locked_rect.pBits + i * locked_rect.Pitch, locked_rect.pBits, locked_rect.Pitch);
5421 hr = IDirect3DTexture8_UnlockRect(tex_src_green, 0);
5422 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
5423 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_green,
5424 (IDirect3DBaseTexture8 *)tex_dst2);
5425 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
5426 add_dirty_rect_test_draw(device);
5427 color = getPixelColor(device, 320, 240);
5428 ok(color_match(color, 0x00ff00ff, 1),
5429 "Expected color 0x00ff00ff, got 0x%08x.\n", color);
5430 color = getPixelColor(device, 1, 1);
5431 ok(color_match(color, 0x00ffffff, 1),
5432 "Expected color 0x00ffffff, got 0x%08x.\n", color);
5433 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5434 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5436 fill_surface(surface_src_red, 0x00ff0000, 0);
5437 fill_surface(surface_src_green, 0x0000ff00, 0);
5439 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_green,
5440 (IDirect3DBaseTexture8 *)tex_dst1);
5441 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
5442 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)tex_dst1);
5443 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
5444 add_dirty_rect_test_draw(device);
5445 color = getPixelColor(device, 320, 240);
5446 ok(color_match(color, 0x0000ff00, 1),
5447 "Expected color 0x0000ff00, got 0x%08x.\n", color);
5448 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5449 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5451 /* UpdateSurface ignores the missing dirty marker. */
5452 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_red,
5453 (IDirect3DBaseTexture8 *)tex_dst2);
5454 hr = IDirect3DDevice8_CopyRects(device, surface_src_green, NULL, 0, surface_dst2, NULL);
5455 ok(SUCCEEDED(hr), "Failed to update surface, hr %#x.\n", hr);
5456 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)tex_dst2);
5457 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
5458 add_dirty_rect_test_draw(device);
5459 color = getPixelColor(device, 320, 240);
5460 ok(color_match(color, 0x0000ff00, 1),
5461 "Expected color 0x0000ff00, got 0x%08x.\n", color);
5462 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5463 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5465 /* Tests with managed textures. */
5466 fill_surface(surface_managed, 0x00ff0000, 0);
5467 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)tex_managed);
5468 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
5469 add_dirty_rect_test_draw(device);
5470 color = getPixelColor(device, 320, 240);
5471 ok(color_match(color, 0x00ff0000, 1),
5472 "Expected color 0x00ff0000, got 0x%08x.\n", color);
5473 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5474 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5476 /* Managed textures also honor D3DLOCK_NO_DIRTY_UPDATE. */
5477 fill_surface(surface_managed, 0x0000ff00, D3DLOCK_NO_DIRTY_UPDATE);
5478 add_dirty_rect_test_draw(device);
5479 color = getPixelColor(device, 320, 240);
5480 ok(color_match(color, 0x00ff0000, 1),
5481 "Expected color 0x00ff0000, got 0x%08x.\n", color);
5482 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5483 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5485 /* AddDirtyRect uploads the new contents.
5486 * Side note, not tested in the test: Partial surface updates work, and two separate
5487 * dirty rectangles are tracked individually. Tested on Nvidia Kepler, other drivers
5488 * untested. */
5489 hr = IDirect3DTexture8_AddDirtyRect(tex_managed, NULL);
5490 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
5491 add_dirty_rect_test_draw(device);
5492 color = getPixelColor(device, 320, 240);
5493 ok(color_match(color, 0x0000ff00, 1),
5494 "Expected color 0x0000ff00, got 0x%08x.\n", color);
5495 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5496 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5498 /* So does ResourceManagerDiscardBytes. */
5499 fill_surface(surface_managed, 0x000000ff, D3DLOCK_NO_DIRTY_UPDATE);
5500 hr = IDirect3DDevice8_ResourceManagerDiscardBytes(device, 0);
5501 ok(SUCCEEDED(hr), "Failed to evict managed resources, hr %#x.\n", hr);
5502 add_dirty_rect_test_draw(device);
5503 color = getPixelColor(device, 320, 240);
5504 ok(color_match(color, 0x000000ff, 1),
5505 "Expected color 0x000000ff, got 0x%08x.\n", color);
5506 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5507 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5509 /* Tests with dynamic textures */
5510 fill_surface(surface_dynamic, 0x0000ffff, 0);
5511 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)tex_dynamic);
5512 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
5513 add_dirty_rect_test_draw(device);
5514 color = getPixelColor(device, 320, 240);
5515 ok(color_match(color, 0x0000ffff, 1),
5516 "Expected color 0x0000ffff, got 0x%08x.\n", color);
5517 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5518 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5520 /* Dynamic textures don't honor D3DLOCK_NO_DIRTY_UPDATE. */
5521 fill_surface(surface_dynamic, 0x00ffff00, D3DLOCK_NO_DIRTY_UPDATE);
5522 add_dirty_rect_test_draw(device);
5523 color = getPixelColor(device, 320, 240);
5524 ok(color_match(color, 0x00ffff00, 1),
5525 "Expected color 0x00ffff00, got 0x%08x.\n", color);
5526 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5527 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5529 /* AddDirtyRect on a locked texture is allowed. */
5530 hr = IDirect3DTexture8_LockRect(tex_src_red, 0, &locked_rect, NULL, 0);
5531 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
5532 hr = IDirect3DTexture8_AddDirtyRect(tex_src_red, NULL);
5533 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
5534 hr = IDirect3DTexture8_UnlockRect(tex_src_red, 0);
5535 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
5537 /* Redundant AddDirtyRect calls are ok. */
5538 hr = IDirect3DTexture8_AddDirtyRect(tex_managed, NULL);
5539 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
5540 hr = IDirect3DTexture8_AddDirtyRect(tex_managed, NULL);
5541 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
5543 IDirect3DSurface8_Release(surface_dst2);
5544 IDirect3DSurface8_Release(surface_managed);
5545 IDirect3DSurface8_Release(surface_src_red);
5546 IDirect3DSurface8_Release(surface_src_green);
5547 IDirect3DSurface8_Release(surface_dynamic);
5548 IDirect3DTexture8_Release(tex_src_red);
5549 IDirect3DTexture8_Release(tex_src_green);
5550 IDirect3DTexture8_Release(tex_dst1);
5551 IDirect3DTexture8_Release(tex_dst2);
5552 IDirect3DTexture8_Release(tex_managed);
5553 IDirect3DTexture8_Release(tex_dynamic);
5554 refcount = IDirect3DDevice8_Release(device);
5555 ok(!refcount, "Device has %u references left.\n", refcount);
5556 done:
5557 IDirect3D8_Release(d3d);
5558 DestroyWindow(window);
5561 static void test_3dc_formats(void)
5563 static const char ati1n_data[] =
5565 /* A 4x4 texture with the color component at 50%. */
5566 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5568 static const char ati2n_data[] =
5570 /* A 8x4 texture consisting of 2 4x4 blocks. The first block has 50% first color component,
5571 * 0% second component. Second block is the opposite. */
5572 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5573 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5575 static const struct
5577 struct vec3 position;
5578 struct vec2 texcoord;
5580 quads[] =
5582 {{-1.0f, -1.0f, 0.0f}, {0.0f, 0.0f}},
5583 {{-1.0f, 1.0f, 0.0f}, {0.0f, 1.0f}},
5584 {{ 0.0f, -1.0f, 1.0f}, {1.0f, 0.0f}},
5585 {{ 0.0f, 1.0f, 1.0f}, {1.0f, 1.0f}},
5587 {{ 0.0f, -1.0f, 0.0f}, {0.0f, 0.0f}},
5588 {{ 0.0f, 1.0f, 0.0f}, {0.0f, 1.0f}},
5589 {{ 1.0f, -1.0f, 1.0f}, {1.0f, 0.0f}},
5590 {{ 1.0f, 1.0f, 1.0f}, {1.0f, 1.0f}},
5592 static const DWORD ati1n_fourcc = MAKEFOURCC('A','T','I','1');
5593 static const DWORD ati2n_fourcc = MAKEFOURCC('A','T','I','2');
5594 static const struct
5596 struct vec2 position;
5597 D3DCOLOR amd_r500;
5598 D3DCOLOR amd_r600;
5599 D3DCOLOR nvidia_old;
5600 D3DCOLOR nvidia_new;
5602 expected_colors[] =
5604 {{ 80, 240}, 0x007fffff, 0x003f3f3f, 0x007f7f7f, 0x007f0000},
5605 {{240, 240}, 0x007fffff, 0x003f3f3f, 0x007f7f7f, 0x007f0000},
5606 {{400, 240}, 0x00007fff, 0x00007fff, 0x00007fff, 0x00007fff},
5607 {{560, 240}, 0x007f00ff, 0x007f00ff, 0x007f00ff, 0x007f00ff},
5609 IDirect3D8 *d3d;
5610 IDirect3DDevice8 *device;
5611 IDirect3DTexture8 *ati1n_texture, *ati2n_texture;
5612 D3DCAPS8 caps;
5613 D3DLOCKED_RECT rect;
5614 D3DCOLOR color;
5615 ULONG refcount;
5616 HWND window;
5617 HRESULT hr;
5618 unsigned int i;
5620 window = create_window();
5621 d3d = Direct3DCreate8(D3D_SDK_VERSION);
5622 ok(!!d3d, "Failed to create a D3D object.\n");
5623 if (FAILED(IDirect3D8_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
5624 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, ati1n_fourcc)))
5626 skip("ATI1N textures are not supported, skipping test.\n");
5627 goto done;
5629 if (FAILED(IDirect3D8_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
5630 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, ati2n_fourcc)))
5632 skip("ATI2N textures are not supported, skipping test.\n");
5633 goto done;
5635 if (!(device = create_device(d3d, window, window, TRUE)))
5637 skip("Failed to create a D3D device, skipping tests.\n");
5638 goto done;
5640 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
5641 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
5642 if (!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP))
5644 skip("D3DTA_TEMP not supported, skipping tests.\n");
5645 IDirect3DDevice8_Release(device);
5646 goto done;
5649 hr = IDirect3DDevice8_CreateTexture(device, 4, 4, 1, 0, ati1n_fourcc,
5650 D3DPOOL_MANAGED, &ati1n_texture);
5651 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
5653 hr = IDirect3DTexture8_LockRect(ati1n_texture, 0, &rect, NULL, 0);
5654 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
5655 memcpy(rect.pBits, ati1n_data, sizeof(ati1n_data));
5656 hr = IDirect3DTexture8_UnlockRect(ati1n_texture, 0);
5657 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
5659 hr = IDirect3DDevice8_CreateTexture(device, 8, 4, 1, 0, ati2n_fourcc,
5660 D3DPOOL_MANAGED, &ati2n_texture);
5661 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
5663 hr = IDirect3DTexture8_LockRect(ati2n_texture, 0, &rect, NULL, 0);
5664 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
5665 memcpy(rect.pBits, ati2n_data, sizeof(ati2n_data));
5666 hr = IDirect3DTexture8_UnlockRect(ati2n_texture, 0);
5667 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
5669 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE2(0));
5670 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
5671 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BLENDTEXTUREALPHA);
5672 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
5673 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
5674 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
5675 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TEMP);
5676 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
5677 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
5678 ok(SUCCEEDED(hr), "Failed to set alpha op, hr %#x.\n", hr);
5679 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
5680 ok(SUCCEEDED(hr), "Failed to set alpha arg, hr %#x.\n", hr);
5681 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
5682 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
5683 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MAGFILTER, D3DTEXF_POINT);
5684 ok(SUCCEEDED(hr), "Failed to set mag filter, hr %#x.\n", hr);
5686 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff00ff, 1.0f, 0);
5687 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
5688 hr = IDirect3DDevice8_BeginScene(device);
5689 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5690 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)ati1n_texture);
5691 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
5692 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads));
5693 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5694 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)ati2n_texture);
5695 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
5696 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[4], sizeof(*quads));
5697 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5698 hr = IDirect3DDevice8_EndScene(device);
5699 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5701 for (i = 0; i < 4; ++i)
5703 color = getPixelColor(device, expected_colors[i].position.x, expected_colors[i].position.y);
5704 ok (color_match(color, expected_colors[i].amd_r500, 1)
5705 || color_match(color, expected_colors[i].amd_r600, 1)
5706 || color_match(color, expected_colors[i].nvidia_old, 1)
5707 || color_match(color, expected_colors[i].nvidia_new, 1),
5708 "Got unexpected color 0x%08x, case %u.\n", color, i);
5711 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5712 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5713 IDirect3DTexture8_Release(ati2n_texture);
5714 IDirect3DTexture8_Release(ati1n_texture);
5715 refcount = IDirect3DDevice8_Release(device);
5716 ok(!refcount, "Device has %u references left.\n", refcount);
5718 done:
5719 IDirect3D8_Release(d3d);
5720 DestroyWindow(window);
5723 static void test_fog_interpolation(void)
5725 HRESULT hr;
5726 IDirect3DDevice8 *device;
5727 IDirect3D8 *d3d;
5728 ULONG refcount;
5729 HWND window;
5730 D3DCOLOR color;
5731 static const struct
5733 struct vec3 position;
5734 D3DCOLOR diffuse;
5735 D3DCOLOR specular;
5737 quad[] =
5739 {{-1.0f, -1.0f, 0.0f}, 0xffff0000, 0xff000000},
5740 {{-1.0f, 1.0f, 0.0f}, 0xffff0000, 0xff000000},
5741 {{ 1.0f, -1.0f, 1.0f}, 0xffff0000, 0x00000000},
5742 {{ 1.0f, 1.0f, 1.0f}, 0xffff0000, 0x00000000},
5744 union
5746 DWORD d;
5747 float f;
5748 } conv;
5749 unsigned int i;
5750 static const struct
5752 D3DFOGMODE vfog, tfog;
5753 D3DSHADEMODE shade;
5754 D3DCOLOR middle_color;
5755 BOOL todo;
5757 tests[] =
5759 {D3DFOG_NONE, D3DFOG_NONE, D3DSHADE_FLAT, 0x00007f80, FALSE},
5760 {D3DFOG_NONE, D3DFOG_NONE, D3DSHADE_GOURAUD, 0x00007f80, FALSE},
5761 {D3DFOG_EXP, D3DFOG_NONE, D3DSHADE_FLAT, 0x00007f80, TRUE},
5762 {D3DFOG_EXP, D3DFOG_NONE, D3DSHADE_GOURAUD, 0x00007f80, TRUE},
5763 {D3DFOG_NONE, D3DFOG_EXP, D3DSHADE_FLAT, 0x0000ea15, FALSE},
5764 {D3DFOG_NONE, D3DFOG_EXP, D3DSHADE_GOURAUD, 0x0000ea15, FALSE},
5765 {D3DFOG_EXP, D3DFOG_EXP, D3DSHADE_FLAT, 0x0000ea15, FALSE},
5766 {D3DFOG_EXP, D3DFOG_EXP, D3DSHADE_GOURAUD, 0x0000ea15, FALSE},
5768 static const D3DMATRIX ident_mat =
5770 1.0f, 0.0f, 0.0f, 0.0f,
5771 0.0f, 1.0f, 0.0f, 0.0f,
5772 0.0f, 0.0f, 1.0f, 0.0f,
5773 0.0f, 0.0f, 0.0f, 1.0f
5774 }}};
5775 D3DCAPS8 caps;
5777 window = create_window();
5778 d3d = Direct3DCreate8(D3D_SDK_VERSION);
5779 ok(!!d3d, "Failed to create a D3D object.\n");
5781 if (!(device = create_device(d3d, window, window, TRUE)))
5783 skip("Failed to create a D3D device, skipping tests.\n");
5784 IDirect3D8_Release(d3d);
5785 DestroyWindow(window);
5786 return;
5789 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
5790 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
5791 if (!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE))
5792 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping some fog tests\n");
5794 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
5795 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr);
5796 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
5797 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
5798 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, FALSE);
5799 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
5800 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
5801 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
5802 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGCOLOR, 0x0000ff00);
5803 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
5804 conv.f = 5.0;
5805 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGDENSITY, conv.d);
5806 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
5808 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
5809 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
5810 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TFACTOR);
5811 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
5812 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x000000ff);
5813 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
5815 /* Some of the tests seem to depend on the projection matrix explicitly
5816 * being set to an identity matrix, even though that's the default.
5817 * (AMD Radeon X1600, AMD Radeon HD 6310, Windows 7). Without this,
5818 * the drivers seem to use a static z = 1.0 input for the fog equation.
5819 * The input value is independent of the actual z and w component of
5820 * the vertex position. */
5821 hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, &ident_mat);
5822 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
5824 for (i = 0; i < sizeof(tests) / sizeof(*tests); i++)
5826 if(!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE) && tests[i].tfog)
5827 continue;
5829 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00808080, 0.0f, 0);
5830 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
5832 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SHADEMODE, tests[i].shade);
5833 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
5834 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGVERTEXMODE, tests[i].vfog);
5835 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
5836 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGTABLEMODE, tests[i].tfog);
5837 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
5838 hr = IDirect3DDevice8_BeginScene(device);
5839 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5840 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
5841 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5842 hr = IDirect3DDevice8_EndScene(device);
5843 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5845 color = getPixelColor(device, 0, 240);
5846 ok(color_match(color, 0x000000ff, 2), "Got unexpected color 0x%08x, case %u.\n", color, i);
5847 color = getPixelColor(device, 320, 240);
5848 todo_wine_if (tests[i].todo)
5849 ok(color_match(color, tests[i].middle_color, 2),
5850 "Got unexpected color 0x%08x, case %u.\n", color, i);
5851 color = getPixelColor(device, 639, 240);
5852 ok(color_match(color, 0x0000fd02, 2), "Got unexpected color 0x%08x, case %u.\n", color, i);
5853 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5854 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5857 refcount = IDirect3DDevice8_Release(device);
5858 ok(!refcount, "Device has %u references left.\n", refcount);
5859 IDirect3D8_Release(d3d);
5860 DestroyWindow(window);
5863 static void test_negative_fixedfunction_fog(void)
5865 HRESULT hr;
5866 IDirect3DDevice8 *device;
5867 IDirect3D8 *d3d;
5868 ULONG refcount;
5869 HWND window;
5870 D3DCOLOR color;
5871 static const struct
5873 struct vec3 position;
5874 D3DCOLOR diffuse;
5876 quad[] =
5878 {{-1.0f, -1.0f, -0.5f}, 0xffff0000},
5879 {{-1.0f, 1.0f, -0.5f}, 0xffff0000},
5880 {{ 1.0f, -1.0f, -0.5f}, 0xffff0000},
5881 {{ 1.0f, 1.0f, -0.5f}, 0xffff0000},
5883 static const struct
5885 struct vec4 position;
5886 D3DCOLOR diffuse;
5888 tquad[] =
5890 {{ 0.0f, 0.0f, -0.5f, 1.0f}, 0xffff0000},
5891 {{640.0f, 0.0f, -0.5f, 1.0f}, 0xffff0000},
5892 {{ 0.0f, 480.0f, -0.5f, 1.0f}, 0xffff0000},
5893 {{640.0f, 480.0f, -0.5f, 1.0f}, 0xffff0000},
5895 unsigned int i;
5896 static const D3DMATRIX zero =
5898 1.0f, 0.0f, 0.0f, 0.0f,
5899 0.0f, 1.0f, 0.0f, 0.0f,
5900 0.0f, 0.0f, 0.0f, 0.0f,
5901 0.0f, 0.0f, 0.0f, 1.0f
5902 }}};
5903 /* Needed to make AMD drivers happy. Yeah, it is not supposed to
5904 * have an effect on RHW draws. */
5905 static const D3DMATRIX identity =
5907 1.0f, 0.0f, 0.0f, 0.0f,
5908 0.0f, 1.0f, 0.0f, 0.0f,
5909 0.0f, 0.0f, 1.0f, 0.0f,
5910 0.0f, 0.0f, 0.0f, 1.0f
5911 }}};
5912 static const struct
5914 DWORD pos_type;
5915 const void *quad;
5916 size_t stride;
5917 const D3DMATRIX *matrix;
5918 union
5920 float f;
5921 DWORD d;
5922 } start, end;
5923 D3DFOGMODE vfog, tfog;
5924 DWORD color, color_broken, color_broken2;
5926 tests[] =
5928 /* Run the XYZRHW tests first. Depth clamping is broken after RHW draws on the testbot.
5930 * Geforce8+ GPUs on Windows abs() table fog, everything else does not. */
5931 {D3DFVF_XYZRHW, tquad, sizeof(*tquad), &identity, { 0.0f}, {1.0f},
5932 D3DFOG_NONE, D3DFOG_LINEAR, 0x00ff0000, 0x00808000, 0x00808000},
5933 /* r200 GPUs and presumably all d3d8 and older HW clamp the fog
5934 * parameters to 0.0 and 1.0 in the table fog case. */
5935 {D3DFVF_XYZRHW, tquad, sizeof(*tquad), &identity, {-1.0f}, {0.0f},
5936 D3DFOG_NONE, D3DFOG_LINEAR, 0x00808000, 0x00ff0000, 0x0000ff00},
5937 /* test_fog_interpolation shows that vertex fog evaluates the fog
5938 * equation in the vertex pipeline. Start = -1.0 && end = 0.0 shows
5939 * that the abs happens before the fog equation is evaluated.
5941 * Vertex fog abs() behavior is the same on all GPUs. */
5942 {D3DFVF_XYZ, quad, sizeof(*quad), &zero, { 0.0f}, {1.0f},
5943 D3DFOG_LINEAR, D3DFOG_NONE, 0x00808000, 0x00808000, 0x00808000},
5944 {D3DFVF_XYZ, quad, sizeof(*quad), &zero, {-1.0f}, {0.0f},
5945 D3DFOG_LINEAR, D3DFOG_NONE, 0x0000ff00, 0x0000ff00, 0x0000ff00},
5946 {D3DFVF_XYZ, quad, sizeof(*quad), &zero, { 0.0f}, {1.0f},
5947 D3DFOG_EXP, D3DFOG_NONE, 0x009b6400, 0x009b6400, 0x009b6400},
5949 D3DCAPS8 caps;
5951 window = create_window();
5952 d3d = Direct3DCreate8(D3D_SDK_VERSION);
5953 ok(!!d3d, "Failed to create a D3D object.\n");
5955 if (!(device = create_device(d3d, window, window, TRUE)))
5957 skip("Failed to create a D3D device, skipping tests.\n");
5958 IDirect3D8_Release(d3d);
5959 DestroyWindow(window);
5960 return;
5963 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
5964 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
5965 if (!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE))
5966 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping some fog tests.\n");
5968 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
5969 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
5970 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
5971 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
5972 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
5973 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
5974 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGCOLOR, 0x0000ff00);
5975 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
5976 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, FALSE);
5977 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
5979 for (i = 0; i < sizeof(tests) / sizeof(*tests); i++)
5981 if (!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE) && tests[i].tfog)
5982 continue;
5984 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x000000ff, 0.0f, 0);
5985 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
5987 hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, tests[i].matrix);
5988 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
5989 hr = IDirect3DDevice8_SetVertexShader(device, tests[i].pos_type | D3DFVF_DIFFUSE);
5990 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr);
5991 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGSTART, tests[i].start.d);
5992 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
5993 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGEND, tests[i].end.d);
5994 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
5995 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGVERTEXMODE, tests[i].vfog);
5996 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
5997 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGTABLEMODE, tests[i].tfog);
5998 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6000 hr = IDirect3DDevice8_BeginScene(device);
6001 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6002 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, tests[i].quad, tests[i].stride);
6003 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6004 hr = IDirect3DDevice8_EndScene(device);
6005 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6007 color = getPixelColor(device, 320, 240);
6008 ok(color_match(color, tests[i].color, 2) || broken(color_match(color, tests[i].color_broken, 2))
6009 || broken(color_match(color, tests[i].color_broken2, 2)),
6010 "Got unexpected color 0x%08x, case %u.\n", color, i);
6011 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
6012 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
6015 refcount = IDirect3DDevice8_Release(device);
6016 ok(!refcount, "Device has %u references left.\n", refcount);
6017 IDirect3D8_Release(d3d);
6018 DestroyWindow(window);
6021 static void test_table_fog_zw(void)
6023 HRESULT hr;
6024 IDirect3DDevice8 *device;
6025 IDirect3D8 *d3d;
6026 ULONG refcount;
6027 HWND window;
6028 D3DCOLOR color;
6029 D3DCAPS8 caps;
6030 static struct
6032 struct vec4 position;
6033 D3DCOLOR diffuse;
6035 quad[] =
6037 {{ 0.0f, 0.0f, 0.0f, 0.0f}, 0xffff0000},
6038 {{640.0f, 0.0f, 0.0f, 0.0f}, 0xffff0000},
6039 {{ 0.0f, 480.0f, 0.0f, 0.0f}, 0xffff0000},
6040 {{640.0f, 480.0f, 0.0f, 0.0f}, 0xffff0000},
6042 static const D3DMATRIX identity =
6044 1.0f, 0.0f, 0.0f, 0.0f,
6045 0.0f, 1.0f, 0.0f, 0.0f,
6046 0.0f, 0.0f, 1.0f, 0.0f,
6047 0.0f, 0.0f, 0.0f, 1.0f
6048 }}};
6049 static const struct
6051 float z, w;
6052 D3DZBUFFERTYPE z_test;
6053 D3DCOLOR color;
6055 tests[] =
6057 {0.7f, 0.0f, D3DZB_TRUE, 0x004cb200},
6058 {0.7f, 0.0f, D3DZB_FALSE, 0x004cb200},
6059 {0.7f, 0.3f, D3DZB_TRUE, 0x004cb200},
6060 {0.7f, 0.3f, D3DZB_FALSE, 0x004cb200},
6061 {0.7f, 3.0f, D3DZB_TRUE, 0x004cb200},
6062 {0.7f, 3.0f, D3DZB_FALSE, 0x004cb200},
6063 {0.3f, 0.0f, D3DZB_TRUE, 0x00b24c00},
6064 {0.3f, 0.0f, D3DZB_FALSE, 0x00b24c00},
6066 unsigned int i;
6068 window = create_window();
6069 d3d = Direct3DCreate8(D3D_SDK_VERSION);
6070 ok(!!d3d, "Failed to create a D3D object.\n");
6072 if (!(device = create_device(d3d, window, window, TRUE)))
6074 skip("Failed to create a D3D device, skipping tests.\n");
6075 IDirect3D8_Release(d3d);
6076 DestroyWindow(window);
6077 return;
6080 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
6081 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
6082 if (!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE))
6084 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping POSITIONT table fog test.\n");
6085 goto done;
6088 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6089 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6090 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
6091 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6092 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGCOLOR, 0x0000ff00);
6093 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6094 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, FALSE);
6095 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
6096 /* Work around an AMD Windows driver bug. Needs a proj matrix applied redundantly. */
6097 hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, &identity);
6098 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
6099 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
6100 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6101 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
6102 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr);
6104 for (i = 0; i < sizeof(tests) / sizeof(*tests); ++i)
6106 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
6107 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
6109 quad[0].position.z = tests[i].z;
6110 quad[1].position.z = tests[i].z;
6111 quad[2].position.z = tests[i].z;
6112 quad[3].position.z = tests[i].z;
6113 quad[0].position.w = tests[i].w;
6114 quad[1].position.w = tests[i].w;
6115 quad[2].position.w = tests[i].w;
6116 quad[3].position.w = tests[i].w;
6117 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, tests[i].z_test);
6118 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6120 hr = IDirect3DDevice8_BeginScene(device);
6121 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6122 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
6123 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6124 hr = IDirect3DDevice8_EndScene(device);
6125 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6127 color = getPixelColor(device, 320, 240);
6128 ok(color_match(color, tests[i].color, 2),
6129 "Got unexpected color 0x%08x, expected 0x%08x, case %u.\n", color, tests[i].color, i);
6130 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
6131 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
6134 done:
6135 refcount = IDirect3DDevice8_Release(device);
6136 ok(!refcount, "Device has %u references left.\n", refcount);
6137 IDirect3D8_Release(d3d);
6138 DestroyWindow(window);
6141 static void test_signed_formats(void)
6143 IDirect3DDevice8 *device;
6144 HWND window;
6145 HRESULT hr;
6146 unsigned int i, j, x, y;
6147 IDirect3DTexture8 *texture, *texture_sysmem;
6148 D3DLOCKED_RECT locked_rect;
6149 DWORD shader, shader_alpha;
6150 IDirect3D8 *d3d;
6151 D3DCOLOR color;
6152 D3DCAPS8 caps;
6153 ULONG refcount;
6155 /* See comments in the d3d9 version of this test for an
6156 * explanation of these values. */
6157 static const USHORT content_v8u8[4][4] =
6159 {0x0000, 0x7f7f, 0x8880, 0x0000},
6160 {0x0080, 0x8000, 0x7f00, 0x007f},
6161 {0x193b, 0xe8c8, 0x0808, 0xf8f8},
6162 {0x4444, 0xc0c0, 0xa066, 0x22e0},
6164 static const DWORD content_v16u16[4][4] =
6166 {0x00000000, 0x7fff7fff, 0x88008000, 0x00000000},
6167 {0x00008000, 0x80000000, 0x7fff0000, 0x00007fff},
6168 {0x19993bbb, 0xe800c800, 0x08880888, 0xf800f800},
6169 {0x44444444, 0xc000c000, 0xa0006666, 0x2222e000},
6171 static const DWORD content_q8w8v8u8[4][4] =
6173 {0x00000000, 0xff7f7f7f, 0x7f008880, 0x817f0000},
6174 {0x10000080, 0x20008000, 0x30007f00, 0x4000007f},
6175 {0x5020193b, 0x6028e8c8, 0x70020808, 0x807ff8f8},
6176 {0x90414444, 0xa000c0c0, 0x8261a066, 0x834922e0},
6178 static const DWORD content_x8l8v8u8[4][4] =
6180 {0x00000000, 0x00ff7f7f, 0x00008880, 0x00ff0000},
6181 {0x00000080, 0x00008000, 0x00007f00, 0x0000007f},
6182 {0x0041193b, 0x0051e8c8, 0x00040808, 0x00fff8f8},
6183 {0x00824444, 0x0000c0c0, 0x00c2a066, 0x009222e0},
6185 static const USHORT content_l6v5u5[4][4] =
6187 {0x0000, 0xfdef, 0x0230, 0xfc00},
6188 {0x0010, 0x0200, 0x01e0, 0x000f},
6189 {0x4067, 0x53b9, 0x0421, 0xffff},
6190 {0x8108, 0x0318, 0xc28c, 0x909c},
6192 static const struct
6194 D3DFORMAT format;
6195 const char *name;
6196 const void *content;
6197 SIZE_T pixel_size;
6198 BOOL blue, alpha;
6199 unsigned int slop, slop_broken, alpha_broken;
6201 formats[] =
6203 {D3DFMT_V8U8, "D3DFMT_V8U8", content_v8u8, sizeof(WORD), FALSE, FALSE, 1, 0, FALSE},
6204 {D3DFMT_V16U16, "D3DFMT_V16U16", content_v16u16, sizeof(DWORD), FALSE, FALSE, 1, 0, FALSE},
6205 {D3DFMT_Q8W8V8U8, "D3DFMT_Q8W8V8U8", content_q8w8v8u8, sizeof(DWORD), TRUE, TRUE, 1, 0, TRUE },
6206 {D3DFMT_X8L8V8U8, "D3DFMT_X8L8V8U8", content_x8l8v8u8, sizeof(DWORD), TRUE, FALSE, 1, 0, FALSE},
6207 {D3DFMT_L6V5U5, "D3DFMT_L6V5U5", content_l6v5u5, sizeof(WORD), TRUE, FALSE, 4, 7, FALSE},
6209 static const struct
6211 D3DPOOL pool;
6212 UINT width;
6214 tests[] =
6216 {D3DPOOL_SYSTEMMEM, 4},
6217 {D3DPOOL_SYSTEMMEM, 1},
6218 {D3DPOOL_MANAGED, 4},
6219 {D3DPOOL_MANAGED, 1},
6221 static const DWORD shader_code[] =
6223 0xffff0101, /* ps_1_1 */
6224 0x00000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, /* def c0, 0.5, 0.5, 0,5, 0,5 */
6225 0x00000042, 0xb00f0000, /* tex t0 */
6226 0x00000004, 0x800f0000, 0xb0e40000, 0xa0e40000, 0xa0e40000, /* mad r0, t0, c0, c0 */
6227 0x0000ffff /* end */
6229 static const DWORD shader_code_alpha[] =
6231 /* The idea of this shader is to replicate the alpha value in .rg, and set
6232 * blue to 1.0 iff the alpha value is < -1.0 and 0.0 otherwise. */
6233 0xffff0101, /* ps_1_1 */
6234 0x00000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, /* def c0, 0.5, 0.5, 0.5, 0.5 */
6235 0x00000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0 */
6236 0x00000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c2, 0.0, 0.0, 1.0, 0.0 */
6237 0x00000042, 0xb00f0000, /* tex t0 */
6238 0x00000004, 0x80070000, 0xb0ff0000, 0xa0e40000, 0xa0e40000, /* mad r0.rgb, t0.a, c0, c0 */
6239 0x00000003, 0x80080000, 0xb1ff0000, 0xa0e40000, /* sub r0.a, -t0.a, c0 */
6240 0x00000050, 0x80080000, 0x80ff0000, 0xa0ff0001, 0xa0ff0002, /* cnd r0.a, r0.a, c1.a, c2.a */
6241 0x00000005, 0x80070001, 0xa0e40001, 0x80e40000, /* mul r1.rgb, c1, r0 */
6242 0x00000004, 0x80070000, 0x80ff0000, 0xa0e40002, 0x80e40001, /* mad r0.rgb, r0.a, c2, r1 */
6243 0x0000ffff /* end */
6245 static const struct
6247 struct vec3 position;
6248 struct vec2 texcrd;
6250 quad[] =
6252 /* Flip the y coordinate to make the input and
6253 * output arrays easier to compare. */
6254 {{ -1.0f, -1.0f, 0.0f}, { 0.0f, 1.0f}},
6255 {{ -1.0f, 1.0f, 0.0f}, { 0.0f, 0.0f}},
6256 {{ 1.0f, -1.0f, 0.0f}, { 1.0f, 1.0f}},
6257 {{ 1.0f, 1.0f, 0.0f}, { 1.0f, 0.0f}},
6259 static const D3DCOLOR expected_alpha[4][4] =
6261 {0x00808000, 0x007f7f00, 0x00ffff00, 0x00000000},
6262 {0x00909000, 0x00a0a000, 0x00b0b000, 0x00c0c000},
6263 {0x00d0d000, 0x00e0e000, 0x00f0f000, 0x00000000},
6264 {0x00101000, 0x00202000, 0x00010100, 0x00020200},
6266 static const BOOL alpha_broken[4][4] =
6268 {FALSE, FALSE, FALSE, FALSE},
6269 {FALSE, FALSE, FALSE, FALSE},
6270 {FALSE, FALSE, FALSE, TRUE },
6271 {FALSE, FALSE, FALSE, FALSE},
6273 static const D3DCOLOR expected_colors[4][4] =
6275 {0x00808080, 0x00fefeff, 0x00010780, 0x008080ff},
6276 {0x00018080, 0x00800180, 0x0080fe80, 0x00fe8080},
6277 {0x00ba98a0, 0x004767a8, 0x00888881, 0x007878ff},
6278 {0x00c3c3c0, 0x003f3f80, 0x00e51fe1, 0x005fa2c8},
6280 D3DCOLOR expected_color;
6282 window = create_window();
6283 d3d = Direct3DCreate8(D3D_SDK_VERSION);
6284 ok(!!d3d, "Failed to create a D3D object.\n");
6286 if (!(device = create_device(d3d, window, window, TRUE)))
6288 skip("Failed to create a D3D device, skipping tests.\n");
6289 IDirect3D8_Release(d3d);
6290 DestroyWindow(window);
6291 return;
6294 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
6295 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
6297 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 1))
6299 skip("Pixel shaders not supported, skipping converted format test.\n");
6300 goto done;
6303 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
6304 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6305 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX1);
6306 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
6307 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code, &shader);
6308 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
6309 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code_alpha, &shader_alpha);
6310 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
6312 for (i = 0; i < sizeof(formats) / sizeof(*formats); i++)
6314 hr = IDirect3D8_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
6315 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, formats[i].format);
6316 if (FAILED(hr))
6318 skip("Format %s not supported, skipping.\n", formats[i].name);
6319 continue;
6322 for (j = 0; j < sizeof(tests) / sizeof(*tests); j++)
6324 texture_sysmem = NULL;
6325 hr = IDirect3DDevice8_CreateTexture(device, tests[j].width, 4, 1, 0,
6326 formats[i].format, tests[j].pool, &texture);
6327 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
6329 hr = IDirect3DTexture8_LockRect(texture, 0, &locked_rect, NULL, 0);
6330 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
6331 for (y = 0; y < 4; y++)
6333 memcpy((char *)locked_rect.pBits + y * locked_rect.Pitch,
6334 (char *)formats[i].content + y * 4 * formats[i].pixel_size,
6335 tests[j].width * formats[i].pixel_size);
6337 hr = IDirect3DTexture8_UnlockRect(texture, 0);
6338 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
6340 if (tests[j].pool == D3DPOOL_SYSTEMMEM)
6342 texture_sysmem = texture;
6343 hr = IDirect3DDevice8_CreateTexture(device, tests[j].width, 4, 1, 0,
6344 formats[i].format, D3DPOOL_DEFAULT, &texture);
6345 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
6347 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)texture_sysmem,
6348 (IDirect3DBaseTexture8 *)texture);
6349 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
6350 IDirect3DTexture8_Release(texture_sysmem);
6353 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
6354 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
6355 hr = IDirect3DDevice8_SetPixelShader(device, shader_alpha);
6356 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6358 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00330033, 0.0f, 0);
6359 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
6360 hr = IDirect3DDevice8_BeginScene(device);
6361 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6362 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(*quad));
6363 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6364 hr = IDirect3DDevice8_EndScene(device);
6365 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6367 for (y = 0; y < 4; y++)
6369 for (x = 0; x < tests[j].width; x++)
6371 BOOL r200_broken = formats[i].alpha_broken && alpha_broken[y][x];
6372 if (formats[i].alpha)
6373 expected_color = expected_alpha[y][x];
6374 else
6375 expected_color = 0x00ffff00;
6377 color = getPixelColor(device, 80 + 160 * x, 60 + 120 * y);
6378 ok(color_match(color, expected_color, 1) || broken(r200_broken),
6379 "Expected color 0x%08x, got 0x%08x, format %s, location %ux%u.\n",
6380 expected_color, color, formats[i].name, x, y);
6383 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
6384 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
6386 hr = IDirect3DDevice8_SetPixelShader(device, shader);
6387 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6389 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00330033, 0.0f, 0);
6390 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
6391 hr = IDirect3DDevice8_BeginScene(device);
6392 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6393 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(*quad));
6394 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6395 hr = IDirect3DDevice8_EndScene(device);
6396 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6398 for (y = 0; y < 4; y++)
6400 for (x = 0; x < tests[j].width; x++)
6402 expected_color = expected_colors[y][x];
6403 if (!formats[i].blue)
6404 expected_color |= 0x000000ff;
6406 color = getPixelColor(device, 80 + 160 * x, 60 + 120 * y);
6407 ok(color_match(color, expected_color, formats[i].slop)
6408 || broken(color_match(color, expected_color, formats[i].slop_broken)),
6409 "Expected color 0x%08x, got 0x%08x, format %s, location %ux%u.\n",
6410 expected_color, color, formats[i].name, x, y);
6413 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
6414 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
6416 IDirect3DTexture8_Release(texture);
6420 IDirect3DDevice8_DeletePixelShader(device, shader);
6421 IDirect3DDevice8_DeletePixelShader(device, shader_alpha);
6423 done:
6424 refcount = IDirect3DDevice8_Release(device);
6425 ok(!refcount, "Device has %u references left.\n", refcount);
6426 IDirect3D8_Release(d3d);
6427 DestroyWindow(window);
6430 static void test_updatetexture(void)
6432 IDirect3DDevice8 *device;
6433 IDirect3D8 *d3d;
6434 HWND window;
6435 HRESULT hr;
6436 IDirect3DBaseTexture8 *src, *dst;
6437 unsigned int t, i, f, l, x, y, z;
6438 D3DLOCKED_RECT locked_rect;
6439 D3DLOCKED_BOX locked_box;
6440 ULONG refcount;
6441 D3DCAPS8 caps;
6442 D3DCOLOR color;
6443 BOOL ati2n_supported, do_visual_test;
6444 static const struct
6446 struct vec3 pos;
6447 struct vec2 texcoord;
6449 quad[] =
6451 {{-1.0f, -1.0f, 0.0f}, {0.0f, 1.0f}},
6452 {{-1.0f, 1.0f, 0.0f}, {0.0f, 0.0f}},
6453 {{ 1.0f, -1.0f, 0.0f}, {1.0f, 1.0f}},
6454 {{ 1.0f, 1.0f, 0.0f}, {1.0f, 0.0f}},
6456 static const struct
6458 struct vec3 pos;
6459 struct vec3 texcoord;
6461 quad_cube_tex[] =
6463 {{-1.0f, -1.0f, 0.0f}, {1.0f, -0.5f, 0.5f}},
6464 {{-1.0f, 1.0f, 0.0f}, {1.0f, 0.5f, 0.5f}},
6465 {{ 1.0f, -1.0f, 0.0f}, {1.0f, -0.5f, -0.5f}},
6466 {{ 1.0f, 1.0f, 0.0f}, {1.0f, 0.5f, -0.5f}},
6468 static const struct
6470 UINT src_width, src_height;
6471 UINT dst_width, dst_height;
6472 UINT src_levels, dst_levels;
6473 D3DFORMAT src_format, dst_format;
6474 BOOL broken;
6476 tests[] =
6478 {8, 8, 8, 8, 0, 0, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 0 */
6479 {8, 8, 8, 8, 4, 4, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 1 */
6480 {8, 8, 8, 8, 2, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 2 */
6481 {8, 8, 8, 8, 1, 1, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 3 */
6482 {8, 8, 8, 8, 4, 0, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 4 */
6483 {8, 8, 2, 2, 4, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 5 */
6484 /* The WARP renderer doesn't handle these cases correctly. */
6485 {8, 8, 8, 8, 4, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, TRUE}, /* 6 */
6486 {8, 8, 4, 4, 4, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, TRUE}, /* 7 */
6487 /* Not clear what happens here on Windows, it doesn't make much sense
6488 * though (on Nvidia it seems to upload the 4x4 surface into the 7x7
6489 * one or something like that). */
6490 /* {8, 8, 7, 7, 4, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, */
6491 {8, 8, 8, 8, 1, 4, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 8 */
6492 {4, 4, 8, 8, 1, 1, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 9 */
6493 /* This one causes weird behavior on Windows (it probably writes out
6494 * of the texture memory). */
6495 /* {8, 8, 4, 4, 1, 1, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, */
6496 {8, 4, 4, 2, 4, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 10 */
6497 {8, 4, 2, 4, 4, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 11 */
6498 {8, 8, 8, 8, 4, 4, D3DFMT_A8R8G8B8, D3DFMT_X8R8G8B8, FALSE}, /* 12 */
6499 {8, 8, 8, 8, 4, 4, D3DFMT_X8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 13 */
6500 /* The data is converted correctly on AMD, on Nvidia nothing happens
6501 * (it draws a black quad). */
6502 {8, 8, 8, 8, 4, 4, D3DFMT_A8R8G8B8, D3DFMT_R5G6B5, TRUE}, /* 14 */
6503 /* This one doesn't seem to give the expected results on AMD. */
6504 /* {8, 8, 8, 8, 4, 4, D3DFMT_A8R8G8B8, D3DFMT_Q8W8V8U8, FALSE}, */
6505 {8, 8, 8, 8, 4, 4, MAKEFOURCC('A','T','I','2'), MAKEFOURCC('A','T','I','2'), FALSE}, /* 15 */
6506 {8, 8, 8, 8, 4, 2, MAKEFOURCC('A','T','I','2'), MAKEFOURCC('A','T','I','2'), FALSE}, /* 16 */
6507 {8, 8, 2, 2, 4, 2, MAKEFOURCC('A','T','I','2'), MAKEFOURCC('A','T','I','2'), FALSE}, /* 17 */
6509 static const struct
6511 D3DRESOURCETYPE type;
6512 DWORD fvf;
6513 const void *quad;
6514 unsigned int vertex_size;
6515 DWORD cap;
6516 const char *name;
6518 texture_types[] =
6520 {D3DRTYPE_TEXTURE, D3DFVF_XYZ | D3DFVF_TEX1,
6521 quad, sizeof(*quad), D3DPTEXTURECAPS_MIPMAP, "2D mipmapped"},
6523 {D3DRTYPE_CUBETEXTURE, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE3(0),
6524 quad_cube_tex, sizeof(*quad_cube_tex), D3DPTEXTURECAPS_CUBEMAP, "Cube"},
6526 {D3DRTYPE_VOLUMETEXTURE, D3DFVF_XYZ | D3DFVF_TEX1,
6527 quad, sizeof(*quad), D3DPTEXTURECAPS_VOLUMEMAP, "Volume"}
6530 window = create_window();
6531 d3d = Direct3DCreate8(D3D_SDK_VERSION);
6532 ok(!!d3d, "Failed to create a D3D object.\n");
6533 if (!(device = create_device(d3d, window, window, TRUE)))
6535 skip("Failed to create a D3D device, skipping tests.\n");
6536 IDirect3D8_Release(d3d);
6537 DestroyWindow(window);
6538 return;
6541 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
6542 ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
6544 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR);
6545 ok(SUCCEEDED(hr), "Failed to set texture filtering state, hr %#x.\n", hr);
6546 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP);
6547 ok(SUCCEEDED(hr), "Failed to set texture filtering state, hr %#x.\n", hr);
6548 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP);
6549 ok(SUCCEEDED(hr), "Failed to set texture filtering state, hr %#x.\n", hr);
6550 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_ADDRESSW, D3DTADDRESS_CLAMP);
6551 ok(SUCCEEDED(hr), "Failed to set texture filtering state, hr %#x.\n", hr);
6552 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6553 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6554 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
6555 ok(hr == D3D_OK, "Failed to set texture stage state, hr %#x.\n", hr);
6556 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
6557 ok(hr == D3D_OK, "Failed to set texture stage state, hr %#x.\n", hr);
6559 for (t = 0; t < sizeof(texture_types) / sizeof(*texture_types); ++t)
6561 if (!(caps.TextureCaps & texture_types[t].cap))
6563 skip("%s textures not supported, skipping some tests.\n", texture_types[t].name);
6564 continue;
6567 if (FAILED(IDirect3D8_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
6568 D3DFMT_X8R8G8B8, 0, texture_types[t].type, MAKEFOURCC('A','T','I','2'))))
6570 skip("%s ATI2N textures are not supported, skipping some tests.\n", texture_types[t].name);
6571 ati2n_supported = FALSE;
6573 else
6575 ati2n_supported = TRUE;
6578 hr = IDirect3DDevice8_SetVertexShader(device, texture_types[t].fvf);
6579 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
6581 for (i = 0; i < sizeof(tests) / sizeof(*tests); ++i)
6583 if (tests[i].src_format == MAKEFOURCC('A','T','I','2') && !ati2n_supported)
6584 continue;
6586 switch (texture_types[t].type)
6588 case D3DRTYPE_TEXTURE:
6589 hr = IDirect3DDevice8_CreateTexture(device,
6590 tests[i].src_width, tests[i].src_height,
6591 tests[i].src_levels, 0, tests[i].src_format, D3DPOOL_SYSTEMMEM,
6592 (IDirect3DTexture8 **)&src);
6593 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x, case %u, %u.\n", hr, t, i);
6594 hr = IDirect3DDevice8_CreateTexture(device,
6595 tests[i].dst_width, tests[i].dst_height,
6596 tests[i].dst_levels, 0, tests[i].dst_format, D3DPOOL_DEFAULT,
6597 (IDirect3DTexture8 **)&dst);
6598 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x, case %u, %u.\n", hr, t, i);
6599 break;
6600 case D3DRTYPE_CUBETEXTURE:
6601 hr = IDirect3DDevice8_CreateCubeTexture(device,
6602 tests[i].src_width,
6603 tests[i].src_levels, 0, tests[i].src_format, D3DPOOL_SYSTEMMEM,
6604 (IDirect3DCubeTexture8 **)&src);
6605 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x, case %u, %u.\n", hr, t, i);
6606 hr = IDirect3DDevice8_CreateCubeTexture(device,
6607 tests[i].dst_width,
6608 tests[i].dst_levels, 0, tests[i].dst_format, D3DPOOL_DEFAULT,
6609 (IDirect3DCubeTexture8 **)&dst);
6610 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x, case %u, %u.\n", hr, t, i);
6611 break;
6612 case D3DRTYPE_VOLUMETEXTURE:
6613 hr = IDirect3DDevice8_CreateVolumeTexture(device,
6614 tests[i].src_width, tests[i].src_height, tests[i].src_width,
6615 tests[i].src_levels, 0, tests[i].src_format, D3DPOOL_SYSTEMMEM,
6616 (IDirect3DVolumeTexture8 **)&src);
6617 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x, case %u, %u.\n", hr, t, i);
6618 hr = IDirect3DDevice8_CreateVolumeTexture(device,
6619 tests[i].dst_width, tests[i].dst_height, tests[i].dst_width,
6620 tests[i].dst_levels, 0, tests[i].dst_format, D3DPOOL_DEFAULT,
6621 (IDirect3DVolumeTexture8 **)&dst);
6622 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x, case %u, %u.\n", hr, t, i);
6623 break;
6624 default:
6625 trace("Unexpected resource type.\n");
6628 /* Skip the visual part of the test for ATI2N (laziness) and cases that
6629 * give a different (and unlikely to be useful) result. */
6630 do_visual_test = (tests[i].src_format == D3DFMT_A8R8G8B8 || tests[i].src_format == D3DFMT_X8R8G8B8)
6631 && tests[i].src_levels != 0
6632 && tests[i].src_width >= tests[i].dst_width && tests[i].src_height >= tests[i].dst_height
6633 && !(tests[i].src_width > tests[i].src_height && tests[i].dst_width < tests[i].dst_height);
6635 if (do_visual_test)
6637 DWORD *ptr = NULL;
6638 unsigned int width, height, depth, row_pitch = 0, slice_pitch = 0;
6640 for (f = 0; f < (texture_types[t].type == D3DRTYPE_CUBETEXTURE ? 6 : 1); ++f)
6642 width = tests[i].src_width;
6643 height = texture_types[t].type != D3DRTYPE_CUBETEXTURE ? tests[i].src_height : tests[i].src_width;
6644 depth = texture_types[t].type == D3DRTYPE_VOLUMETEXTURE ? width : 1;
6646 for (l = 0; l < tests[i].src_levels; ++l)
6648 switch (texture_types[t].type)
6650 case D3DRTYPE_TEXTURE:
6651 hr = IDirect3DTexture8_LockRect((IDirect3DTexture8 *)src,
6652 l, &locked_rect, NULL, 0);
6653 ptr = locked_rect.pBits;
6654 row_pitch = locked_rect.Pitch / sizeof(*ptr);
6655 break;
6656 case D3DRTYPE_CUBETEXTURE:
6657 hr = IDirect3DCubeTexture8_LockRect((IDirect3DCubeTexture8 *)src,
6658 f, l, &locked_rect, NULL, 0);
6659 ptr = locked_rect.pBits;
6660 row_pitch = locked_rect.Pitch / sizeof(*ptr);
6661 break;
6662 case D3DRTYPE_VOLUMETEXTURE:
6663 hr = IDirect3DVolumeTexture8_LockBox((IDirect3DVolumeTexture8 *)src,
6664 l, &locked_box, NULL, 0);
6665 ptr = locked_box.pBits;
6666 row_pitch = locked_box.RowPitch / sizeof(*ptr);
6667 slice_pitch = locked_box.SlicePitch / sizeof(*ptr);
6668 break;
6669 default:
6670 trace("Unexpected resource type.\n");
6672 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
6674 for (z = 0; z < depth; ++z)
6676 for (y = 0; y < height; ++y)
6678 for (x = 0; x < width; ++x)
6680 ptr[z * slice_pitch + y * row_pitch + x] = 0xff000000
6681 | (DWORD)(x / (width - 1.0f) * 255.0f) << 16
6682 | (DWORD)(y / (height - 1.0f) * 255.0f) << 8;
6687 switch (texture_types[t].type)
6689 case D3DRTYPE_TEXTURE:
6690 hr = IDirect3DTexture8_UnlockRect((IDirect3DTexture8 *)src, l);
6691 break;
6692 case D3DRTYPE_CUBETEXTURE:
6693 hr = IDirect3DCubeTexture8_UnlockRect((IDirect3DCubeTexture8 *)src, f, l);
6694 break;
6695 case D3DRTYPE_VOLUMETEXTURE:
6696 hr = IDirect3DVolumeTexture8_UnlockBox((IDirect3DVolumeTexture8 *)src, l);
6697 break;
6698 default:
6699 trace("Unexpected resource type.\n");
6701 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
6703 width >>= 1;
6704 if (!width)
6705 width = 1;
6706 height >>= 1;
6707 if (!height)
6708 height = 1;
6709 depth >>= 1;
6710 if (!depth)
6711 depth = 1;
6716 hr = IDirect3DDevice8_UpdateTexture(device, src, dst);
6717 if (FAILED(hr))
6719 todo_wine ok(SUCCEEDED(hr), "Failed to update texture, hr %#x, case %u, %u.\n", hr, t, i);
6720 IDirect3DBaseTexture8_Release(src);
6721 IDirect3DBaseTexture8_Release(dst);
6722 continue;
6724 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x, case %u, %u.\n", hr, t, i);
6726 if (do_visual_test)
6728 hr = IDirect3DDevice8_SetTexture(device, 0, dst);
6729 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
6731 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 1.0f, 0);
6732 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
6734 hr = IDirect3DDevice8_BeginScene(device);
6735 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6736 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,
6737 texture_types[t].quad, texture_types[t].vertex_size);
6738 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6739 hr = IDirect3DDevice8_EndScene(device);
6740 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6742 color = getPixelColor(device, 320, 240);
6743 ok (color_match(color, 0x007f7f00, 3) || broken(tests[i].broken)
6744 || broken(color == 0x00adbeef), /* WARP device often just breaks down. */
6745 "Got unexpected color 0x%08x, case %u, %u.\n", color, t, i);
6748 IDirect3DBaseTexture8_Release(src);
6749 IDirect3DBaseTexture8_Release(dst);
6753 refcount = IDirect3DDevice8_Release(device);
6754 ok(!refcount, "Device has %u references left.\n", refcount);
6755 IDirect3D8_Release(d3d);
6756 DestroyWindow(window);
6759 static BOOL point_match(IDirect3DDevice8 *device, UINT x, UINT y, UINT r)
6761 D3DCOLOR color;
6763 color = D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff);
6764 if (!color_match(getPixelColor(device, x + r, y), color, 1))
6765 return FALSE;
6766 if (!color_match(getPixelColor(device, x - r, y), color, 1))
6767 return FALSE;
6768 if (!color_match(getPixelColor(device, x, y + r), color, 1))
6769 return FALSE;
6770 if (!color_match(getPixelColor(device, x, y - r), color, 1))
6771 return FALSE;
6773 ++r;
6774 color = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff);
6775 if (!color_match(getPixelColor(device, x + r, y), color, 1))
6776 return FALSE;
6777 if (!color_match(getPixelColor(device, x - r, y), color, 1))
6778 return FALSE;
6779 if (!color_match(getPixelColor(device, x, y + r), color, 1))
6780 return FALSE;
6781 if (!color_match(getPixelColor(device, x, y - r), color, 1))
6782 return FALSE;
6784 return TRUE;
6787 static void test_pointsize(void)
6789 static const float a = 0.5f, b = 0.5f, c = 0.5f;
6790 float ptsize, ptsizemax_orig, ptsizemin_orig;
6791 IDirect3DSurface8 *rt, *backbuffer, *depthstencil;
6792 IDirect3DTexture8 *tex1, *tex2;
6793 IDirect3DDevice8 *device;
6794 DWORD vs, ps;
6795 D3DLOCKED_RECT lr;
6796 IDirect3D8 *d3d;
6797 D3DCOLOR color;
6798 ULONG refcount;
6799 D3DCAPS8 caps;
6800 HWND window;
6801 HRESULT hr;
6802 unsigned int i, j;
6804 static const DWORD tex1_data[4] = {0x00ff0000, 0x00ff0000, 0x00000000, 0x00000000};
6805 static const DWORD tex2_data[4] = {0x00000000, 0x0000ff00, 0x00000000, 0x0000ff00};
6806 static const float vertices[] =
6808 64.0f, 64.0f, 0.1f,
6809 128.0f, 64.0f, 0.1f,
6810 192.0f, 64.0f, 0.1f,
6811 256.0f, 64.0f, 0.1f,
6812 320.0f, 64.0f, 0.1f,
6813 384.0f, 64.0f, 0.1f,
6814 448.0f, 64.0f, 0.1f,
6815 512.0f, 64.0f, 0.1f,
6817 static const struct
6819 float x, y, z;
6820 float point_size;
6822 vertex_pointsize = {64.0f, 64.0f, 0.1f, 48.0f},
6823 vertex_pointsize_scaled = {64.0f, 64.0f, 0.1f, 24.0f},
6824 vertex_pointsize_zero = {64.0f, 64.0f, 0.1f, 0.0f};
6825 static const DWORD decl[] =
6827 D3DVSD_STREAM(0),
6828 D3DVSD_REG(0, D3DVSDT_FLOAT3), /* position */
6829 D3DVSD_END()
6831 decl_psize[] =
6833 D3DVSD_STREAM(0),
6834 D3DVSD_REG(0, D3DVSDT_FLOAT3), /* position, v0 */
6835 D3DVSD_REG(1, D3DVSDT_FLOAT1), /* point size, v1 */
6836 D3DVSD_END()
6838 static const DWORD vshader_code[] =
6840 0xfffe0101, /* vs_1_1 */
6841 0x00000005, 0x800f0000, 0x90000000, 0xa0e40000, /* mul r0, v0.x, c0 */
6842 0x00000004, 0x800f0000, 0x90550000, 0xa0e40001, 0x80e40000, /* mad r0, v0.y, c1, r0 */
6843 0x00000004, 0x800f0000, 0x90aa0000, 0xa0e40002, 0x80e40000, /* mad r0, v0.z, c2, r0 */
6844 0x00000004, 0xc00f0000, 0x90ff0000, 0xa0e40003, 0x80e40000, /* mad oPos, v0.w, c3, r0 */
6845 0x0000ffff
6847 static const DWORD vshader_psize_code[] =
6849 0xfffe0101, /* vs_1_1 */
6850 0x00000005, 0x800f0000, 0x90000000, 0xa0e40000, /* mul r0, v0.x, c0 */
6851 0x00000004, 0x800f0000, 0x90550000, 0xa0e40001, 0x80e40000, /* mad r0, v0.y, c1, r0 */
6852 0x00000004, 0x800f0000, 0x90aa0000, 0xa0e40002, 0x80e40000, /* mad r0, v0.z, c2, r0 */
6853 0x00000004, 0xc00f0000, 0x90ff0000, 0xa0e40003, 0x80e40000, /* mad oPos, v0.w, c3, r0 */
6854 0x00000001, 0xc00f0002, 0x90000001, /* mov oPts, v1.x */
6855 0x0000ffff
6857 static const DWORD pshader_code[] =
6859 0xffff0101, /* ps_1_1 */
6860 0x00000042, 0xb00f0000, /* tex t0 */
6861 0x00000042, 0xb00f0001, /* tex t1 */
6862 0x00000002, 0x800f0000, 0xb0e40000, 0xb0e40001, /* add r0, t0, t1 */
6863 0x0000ffff
6865 static const struct test_shader
6867 DWORD version;
6868 const DWORD *code;
6870 novs = {0, NULL},
6871 vs1 = {D3DVS_VERSION(1, 1), vshader_code},
6872 vs1_psize = {D3DVS_VERSION(1, 1), vshader_psize_code},
6873 nops = {0, NULL},
6874 ps1 = {D3DPS_VERSION(1, 1), pshader_code};
6875 static const struct
6877 const DWORD *decl;
6878 const struct test_shader *vs;
6879 const struct test_shader *ps;
6880 DWORD accepted_fvf;
6881 unsigned int nonscaled_size, scaled_size;
6883 test_setups[] =
6885 {NULL, &novs, &nops, D3DFVF_XYZ, 32, 62},
6886 {decl, &vs1, &ps1, D3DFVF_XYZ, 32, 32},
6887 {NULL, &novs, &ps1, D3DFVF_XYZ, 32, 62},
6888 {decl, &vs1, &nops, D3DFVF_XYZ, 32, 32},
6889 {NULL, &novs, &nops, D3DFVF_XYZ | D3DFVF_PSIZE, 48, 48},
6890 {decl_psize, &vs1_psize, &ps1, D3DFVF_XYZ | D3DFVF_PSIZE, 48, 24},
6892 static const struct
6894 BOOL zero_size;
6895 BOOL scale;
6896 BOOL override_min;
6897 DWORD fvf;
6898 const void *vertex_data;
6899 unsigned int vertex_size;
6901 tests[] =
6903 {FALSE, FALSE, FALSE, D3DFVF_XYZ, vertices, sizeof(float) * 3},
6904 {FALSE, TRUE, FALSE, D3DFVF_XYZ, vertices, sizeof(float) * 3},
6905 {FALSE, FALSE, TRUE, D3DFVF_XYZ, vertices, sizeof(float) * 3},
6906 {TRUE, FALSE, FALSE, D3DFVF_XYZ, vertices, sizeof(float) * 3},
6907 {FALSE, FALSE, FALSE, D3DFVF_XYZ | D3DFVF_PSIZE, &vertex_pointsize, sizeof(vertex_pointsize)},
6908 {FALSE, TRUE, FALSE, D3DFVF_XYZ | D3DFVF_PSIZE, &vertex_pointsize_scaled, sizeof(vertex_pointsize_scaled)},
6909 {FALSE, FALSE, TRUE, D3DFVF_XYZ | D3DFVF_PSIZE, &vertex_pointsize, sizeof(vertex_pointsize)},
6910 {TRUE, FALSE, FALSE, D3DFVF_XYZ | D3DFVF_PSIZE, &vertex_pointsize_zero, sizeof(vertex_pointsize_zero)},
6912 /* Transforms the coordinate system [-1.0;1.0]x[1.0;-1.0] to
6913 * [0.0;0.0]x[640.0;480.0]. Z is untouched. */
6914 D3DMATRIX matrix =
6916 2.0f / 640.0f, 0.0f, 0.0f, 0.0f,
6917 0.0f, -2.0f / 480.0f, 0.0f, 0.0f,
6918 0.0f, 0.0f, 1.0f, 0.0f,
6919 -1.0f, 1.0f, 0.0f, 1.0f,
6920 }}};
6922 window = create_window();
6923 d3d = Direct3DCreate8(D3D_SDK_VERSION);
6924 ok(!!d3d, "Failed to create a D3D object.\n");
6925 if (!(device = create_device(d3d, window, window, TRUE)))
6927 skip("Failed to create a D3D device, skipping tests.\n");
6928 goto done;
6931 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
6932 ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
6933 if (caps.MaxPointSize < 32.0f)
6935 skip("MaxPointSize %f < 32.0, skipping.\n", caps.MaxPointSize);
6936 IDirect3DDevice8_Release(device);
6937 goto done;
6940 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
6941 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
6942 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6943 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
6944 hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, &matrix);
6945 ok(SUCCEEDED(hr), "Failed to set projection matrix, hr %#x.\n", hr);
6946 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ);
6947 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
6949 hr = IDirect3DDevice8_BeginScene(device);
6950 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6952 ptsize = 15.0f;
6953 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
6954 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6955 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
6956 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6958 ptsize = 31.0f;
6959 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
6960 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6961 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[3], sizeof(float) * 3);
6962 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6964 ptsize = 30.75f;
6965 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
6966 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6967 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[6], sizeof(float) * 3);
6968 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6970 if (caps.MaxPointSize >= 63.0f)
6972 ptsize = 63.0f;
6973 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
6974 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6975 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[9], sizeof(float) * 3);
6976 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6978 ptsize = 62.75f;
6979 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
6980 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6981 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[15], sizeof(float) * 3);
6982 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6985 ptsize = 1.0f;
6986 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
6987 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6988 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[12], sizeof(float) * 3);
6989 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6991 hr = IDirect3DDevice8_GetRenderState(device, D3DRS_POINTSIZE_MAX, (DWORD *)&ptsizemax_orig);
6992 ok(SUCCEEDED(hr), "Failed to get render state, hr %#x.\n", hr);
6993 hr = IDirect3DDevice8_GetRenderState(device, D3DRS_POINTSIZE_MIN, (DWORD *)&ptsizemin_orig);
6994 ok(SUCCEEDED(hr), "Failed to get render state, hr %#x.\n", hr);
6996 /* What happens if point scaling is disabled, and POINTSIZE_MAX < POINTSIZE? */
6997 ptsize = 15.0f;
6998 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
6999 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
7000 ptsize = 1.0f;
7001 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE_MAX, *(DWORD *)&ptsize);
7002 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
7003 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[18], sizeof(float) * 3);
7004 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7006 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE_MAX, *(DWORD *)&ptsizemax_orig);
7007 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
7009 /* pointsize < pointsize_min < pointsize_max?
7010 * pointsize = 1.0, pointsize_min = 15.0, pointsize_max = default(usually 64.0) */
7011 ptsize = 1.0f;
7012 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
7013 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
7014 ptsize = 15.0f;
7015 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE_MIN, *(DWORD *)&ptsize);
7016 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
7017 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[21], sizeof(float) * 3);
7018 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7020 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE_MIN, *(DWORD *)&ptsizemin_orig);
7021 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
7023 hr = IDirect3DDevice8_EndScene(device);
7024 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7026 ok(point_match(device, 64, 64, 7), "point_match(64, 64, 7) failed, expected point size 15.\n");
7027 ok(point_match(device, 128, 64, 15), "point_match(128, 64, 15) failed, expected point size 31.\n");
7028 ok(point_match(device, 192, 64, 15), "point_match(192, 64, 15) failed, expected point size 31.\n");
7030 if (caps.MaxPointSize >= 63.0f)
7032 ok(point_match(device, 256, 64, 31), "point_match(256, 64, 31) failed, expected point size 63.\n");
7033 ok(point_match(device, 384, 64, 31), "point_match(384, 64, 31) failed, expected point size 63.\n");
7036 ok(point_match(device, 320, 64, 0), "point_match(320, 64, 0) failed, expected point size 1.\n");
7037 /* ptsize = 15, ptsize_max = 1 --> point has size 1 */
7038 ok(point_match(device, 448, 64, 0), "point_match(448, 64, 0) failed, expected point size 1.\n");
7039 /* ptsize = 1, ptsize_max = default(64), ptsize_min = 15 --> point has size 15 */
7040 ok(point_match(device, 512, 64, 7), "point_match(512, 64, 7) failed, expected point size 15.\n");
7042 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
7044 /* The following code tests point sprites with two textures, to see if each texture coordinate unit
7045 * generates texture coordinates for the point(result: Yes, it does)
7047 * However, not all GL implementations support point sprites(they need GL_ARB_point_sprite), but there
7048 * is no point sprite cap bit in d3d because native d3d software emulates point sprites. Until the
7049 * SW emulation is implemented in wined3d, this test will fail on GL drivers that does not support them.
7051 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
7052 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
7054 hr = IDirect3DDevice8_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex1);
7055 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
7056 hr = IDirect3DDevice8_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex2);
7057 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
7058 memset(&lr, 0, sizeof(lr));
7059 hr = IDirect3DTexture8_LockRect(tex1, 0, &lr, NULL, 0);
7060 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
7061 memcpy(lr.pBits, tex1_data, sizeof(tex1_data));
7062 hr = IDirect3DTexture8_UnlockRect(tex1, 0);
7063 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
7064 memset(&lr, 0, sizeof(lr));
7065 hr = IDirect3DTexture8_LockRect(tex2, 0, &lr, NULL, 0);
7066 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
7067 memcpy(lr.pBits, tex2_data, sizeof(tex2_data));
7068 hr = IDirect3DTexture8_UnlockRect(tex2, 0);
7069 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
7070 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)tex1);
7071 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
7072 hr = IDirect3DDevice8_SetTexture(device, 1, (IDirect3DBaseTexture8 *)tex2);
7073 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
7074 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7075 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
7076 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7077 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
7078 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
7079 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
7080 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7081 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
7082 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
7083 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
7085 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSPRITEENABLE, TRUE);
7086 ok(SUCCEEDED(hr), "Failed to enable point sprites, hr %#x.\n", hr);
7087 ptsize = 32.0f;
7088 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
7089 ok(SUCCEEDED(hr), "Failed to set point size, hr %#x.\n", hr);
7091 hr = IDirect3DDevice8_BeginScene(device);
7092 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7093 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
7094 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7095 hr = IDirect3DDevice8_EndScene(device);
7096 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7098 color = getPixelColor(device, 64 - 4, 64 - 4);
7099 ok(color == 0x00ff0000, "pSprite: Pixel (64 - 4),(64 - 4) has color 0x%08x, expected 0x00ff0000\n", color);
7100 color = getPixelColor(device, 64 - 4, 64 + 4);
7101 ok(color == 0x00000000, "pSprite: Pixel (64 - 4),(64 + 4) has color 0x%08x, expected 0x00000000\n", color);
7102 color = getPixelColor(device, 64 + 4, 64 + 4);
7103 ok(color == 0x0000ff00, "pSprite: Pixel (64 + 4),(64 + 4) has color 0x%08x, expected 0x0000ff00\n", color);
7104 color = getPixelColor(device, 64 + 4, 64 - 4);
7105 ok(color == 0x00ffff00, "pSprite: Pixel (64 + 4),(64 - 4) has color 0x%08x, expected 0x00ffff00\n", color);
7106 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
7108 U(matrix).m[0][0] = 1.0f / 64.0f;
7109 U(matrix).m[1][1] = -1.0f / 64.0f;
7110 hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, &matrix);
7111 ok(SUCCEEDED(hr), "Failed to set projection matrix, hr %#x.\n", hr);
7113 hr = IDirect3DDevice8_GetRenderTarget(device, &backbuffer);
7114 ok(SUCCEEDED(hr), "Failed to get backbuffer, hr %#x.\n", hr);
7115 hr = IDirect3DDevice8_GetDepthStencilSurface(device, &depthstencil);
7116 ok(SUCCEEDED(hr), "Failed to get depth / stencil buffer, hr %#x.\n", hr);
7118 hr = IDirect3DDevice8_CreateRenderTarget(device, 128, 128, D3DFMT_A8R8G8B8,
7119 D3DMULTISAMPLE_NONE, TRUE, &rt);
7120 ok(SUCCEEDED(hr), "Failed to create a render target, hr %#x.\n", hr);
7122 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSCALE_A, *(DWORD *)&a);
7123 ok(SUCCEEDED(hr), "Failed setting point scale attenuation coefficient, hr %#x.\n", hr);
7124 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSCALE_B, *(DWORD *)&b);
7125 ok(SUCCEEDED(hr), "Failed setting point scale attenuation coefficient, hr %#x.\n", hr);
7126 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSCALE_C, *(DWORD *)&c);
7127 ok(SUCCEEDED(hr), "Failed setting point scale attenuation coefficient, hr %#x.\n", hr);
7128 hr = IDirect3DDevice8_SetVertexShaderConstant(device, 0, &S(U(matrix))._11, 4);
7129 ok(SUCCEEDED(hr), "Failed to set vertex shader constants, hr %#x.\n", hr);
7131 if (caps.MaxPointSize < 63.0f)
7133 skip("MaxPointSize %f < 63.0, skipping some tests.\n", caps.MaxPointSize);
7134 goto cleanup;
7137 hr = IDirect3DDevice8_SetRenderTarget(device, rt, depthstencil);
7138 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
7140 for (i = 0; i < sizeof(test_setups) / sizeof(test_setups[0]); ++i)
7142 if (caps.VertexShaderVersion < test_setups[i].vs->version
7143 || caps.PixelShaderVersion < test_setups[i].ps->version)
7145 skip("Vertex / pixel shader version not supported, skipping test.\n");
7146 continue;
7148 if (test_setups[i].vs->code)
7150 hr = IDirect3DDevice8_CreateVertexShader(device, test_setups[i].decl, test_setups[i].vs->code, &vs, 0);
7151 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x (case %u).\n", hr, i);
7153 else
7155 vs = 0;
7157 if (test_setups[i].ps->code)
7159 hr = IDirect3DDevice8_CreatePixelShader(device, test_setups[i].ps->code, &ps);
7160 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x (case %u).\n", hr, i);
7162 else
7164 ps = 0;
7167 hr = IDirect3DDevice8_SetVertexShader(device, vs ? vs : test_setups[i].accepted_fvf);
7168 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
7169 hr = IDirect3DDevice8_SetPixelShader(device, ps);
7170 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
7172 for (j = 0; j < sizeof(tests) / sizeof(tests[0]); ++j)
7174 unsigned int size = tests[j].override_min ? 63 : tests[j].zero_size ? 0 : tests[j].scale
7175 ? test_setups[i].scaled_size : test_setups[i].nonscaled_size;
7177 if (test_setups[i].accepted_fvf != tests[j].fvf)
7178 continue;
7180 ptsize = tests[j].zero_size ? 0.0f : 32.0f;
7181 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
7182 ok(SUCCEEDED(hr), "Failed to set pointsize, hr %#x.\n", hr);
7184 ptsize = tests[j].override_min ? 63.0f : tests[j].zero_size ? 0.0f : ptsizemin_orig;
7185 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE_MIN, *(DWORD *)&ptsize);
7186 ok(SUCCEEDED(hr), "Failed to set minimum pointsize, hr %#x.\n", hr);
7188 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSCALEENABLE, tests[j].scale);
7189 ok(SUCCEEDED(hr), "Failed setting point scale state, hr %#x.\n", hr);
7191 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
7192 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
7194 hr = IDirect3DDevice8_BeginScene(device);
7195 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7196 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1,
7197 tests[j].vertex_data, tests[j].vertex_size);
7198 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7199 hr = IDirect3DDevice8_EndScene(device);
7200 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7202 if (tests[j].zero_size)
7204 /* Technically 0 pointsize is undefined in OpenGL but in practice it seems like
7205 * it does the "useful" thing on all the drivers I tried. */
7206 /* On WARP it does draw some pixels, most of the time. */
7207 color = getPixelColor(device, 64, 64);
7208 ok(color_match(color, 0x0000ffff, 0)
7209 || broken(color_match(color, 0x00ff0000, 0))
7210 || broken(color_match(color, 0x00ffff00, 0))
7211 || broken(color_match(color, 0x00000000, 0))
7212 || broken(color_match(color, 0x0000ff00, 0)),
7213 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
7215 else
7217 struct surface_readback rb;
7219 get_rt_readback(rt, &rb);
7220 color = get_readback_color(&rb, 64 - size / 2 + 1, 64 - size / 2 + 1);
7221 ok(color_match(color, 0x00ff0000, 0),
7222 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
7223 color = get_readback_color(&rb, 64 + size / 2 - 1, 64 - size / 2 + 1);
7224 ok(color_match(color, 0x00ffff00, 0),
7225 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
7226 color = get_readback_color(&rb, 64 - size / 2 + 1, 64 + size / 2 - 1);
7227 ok(color_match(color, 0x00000000, 0),
7228 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
7229 color = get_readback_color(&rb, 64 + size / 2 - 1, 64 + size / 2 - 1);
7230 ok(color_match(color, 0x0000ff00, 0),
7231 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
7233 color = get_readback_color(&rb, 64 - size / 2 - 1, 64 - size / 2 - 1);
7234 ok(color_match(color, 0xff00ffff, 0),
7235 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
7236 color = get_readback_color(&rb, 64 + size / 2 + 1, 64 - size / 2 - 1);
7237 ok(color_match(color, 0xff00ffff, 0),
7238 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
7239 color = get_readback_color(&rb, 64 - size / 2 - 1, 64 + size / 2 + 1);
7240 ok(color_match(color, 0xff00ffff, 0),
7241 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
7242 color = get_readback_color(&rb, 64 + size / 2 + 1, 64 + size / 2 + 1);
7243 ok(color_match(color, 0xff00ffff, 0),
7244 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
7246 release_surface_readback(&rb);
7249 IDirect3DDevice8_SetVertexShader(device, 0);
7250 IDirect3DDevice8_SetPixelShader(device, 0);
7251 if (vs)
7252 IDirect3DDevice8_DeleteVertexShader(device, vs);
7253 if (ps)
7254 IDirect3DDevice8_DeletePixelShader(device, ps);
7256 hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, depthstencil);
7257 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
7259 cleanup:
7260 IDirect3DSurface8_Release(backbuffer);
7261 IDirect3DSurface8_Release(depthstencil);
7262 IDirect3DSurface8_Release(rt);
7264 IDirect3DTexture8_Release(tex1);
7265 IDirect3DTexture8_Release(tex2);
7266 refcount = IDirect3DDevice8_Release(device);
7267 ok(!refcount, "Device has %u references left.\n", refcount);
7268 done:
7269 IDirect3D8_Release(d3d);
7270 DestroyWindow(window);
7273 static void test_multisample_mismatch(void)
7275 IDirect3DDevice8 *device;
7276 IDirect3D8 *d3d;
7277 HWND window;
7278 HRESULT hr;
7279 ULONG refcount;
7280 IDirect3DSurface8 *rt_multi, *ds;
7282 window = create_window();
7283 d3d = Direct3DCreate8(D3D_SDK_VERSION);
7284 ok(!!d3d, "Failed to create a D3D object.\n");
7285 if (FAILED(IDirect3D8_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
7286 D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES)))
7288 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping multisample mismatch test.\n");
7289 IDirect3D8_Release(d3d);
7290 return;
7293 if (!(device = create_device(d3d, window, window, TRUE)))
7295 skip("Failed to create a D3D device, skipping tests.\n");
7296 goto done;
7299 hr = IDirect3DDevice8_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
7300 D3DMULTISAMPLE_2_SAMPLES, FALSE, &rt_multi);
7301 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
7302 hr = IDirect3DDevice8_GetDepthStencilSurface(device, &ds);
7303 ok(SUCCEEDED(hr), "Failed to get original depth/stencil, hr %#x.\n", hr);
7305 hr = IDirect3DDevice8_SetRenderTarget(device, rt_multi, ds);
7306 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
7308 IDirect3DSurface8_Release(ds);
7309 IDirect3DSurface8_Release(rt_multi);
7311 refcount = IDirect3DDevice8_Release(device);
7312 ok(!refcount, "Device has %u references left.\n", refcount);
7313 done:
7314 IDirect3D8_Release(d3d);
7315 DestroyWindow(window);
7318 static void test_texcoordindex(void)
7320 static const D3DMATRIX mat =
7322 1.0f, 0.0f, 0.0f, 0.0f,
7323 0.0f, 0.0f, 0.0f, 0.0f,
7324 0.0f, 0.0f, 0.0f, 0.0f,
7325 0.0f, 0.0f, 0.0f, 0.0f,
7326 }}};
7327 static const struct
7329 struct vec3 pos;
7330 struct vec2 texcoord1;
7331 struct vec2 texcoord2;
7332 struct vec2 texcoord3;
7334 quad[] =
7336 {{-1.0f, -1.0f, 0.0f}, {0.0f, 1.0f}, {0.0f, 0.0f}, {1.0f, 1.0f}},
7337 {{-1.0f, 1.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 1.0f}, {1.0f, 0.0f}},
7338 {{ 1.0f, -1.0f, 0.0f}, {1.0f, 1.0f}, {1.0f, 0.0f}, {0.0f, 1.0f}},
7339 {{ 1.0f, 1.0f, 0.0f}, {1.0f, 0.0f}, {1.0f, 1.0f}, {0.0f, 0.0f}},
7341 IDirect3DDevice8 *device;
7342 IDirect3D8 *d3d;
7343 HWND window;
7344 HRESULT hr;
7345 IDirect3DTexture8 *texture1, *texture2;
7346 D3DLOCKED_RECT locked_rect;
7347 ULONG refcount;
7348 D3DCOLOR color;
7349 DWORD *ptr;
7351 window = create_window();
7352 d3d = Direct3DCreate8(D3D_SDK_VERSION);
7353 ok(!!d3d, "Failed to create a D3D object.\n");
7354 if (!(device = create_device(d3d, window, window, TRUE)))
7356 skip("Failed to create a D3D device, skipping tests.\n");
7357 IDirect3D8_Release(d3d);
7358 DestroyWindow(window);
7359 return;
7362 hr = IDirect3DDevice8_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture1);
7363 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
7364 hr = IDirect3DDevice8_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture2);
7365 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
7367 hr = IDirect3DTexture8_LockRect(texture1, 0, &locked_rect, NULL, D3DLOCK_DISCARD);
7368 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
7369 ptr = locked_rect.pBits;
7370 ptr[0] = 0xff000000;
7371 ptr[1] = 0xff00ff00;
7372 ptr[2] = 0xff0000ff;
7373 ptr[3] = 0xff00ffff;
7374 hr = IDirect3DTexture8_UnlockRect(texture1, 0);
7375 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
7377 hr = IDirect3DTexture8_LockRect(texture2, 0, &locked_rect, NULL, D3DLOCK_DISCARD);
7378 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
7379 ptr = locked_rect.pBits;
7380 ptr[0] = 0xff000000;
7381 ptr[1] = 0xff0000ff;
7382 ptr[2] = 0xffff0000;
7383 ptr[3] = 0xffff00ff;
7384 hr = IDirect3DTexture8_UnlockRect(texture2, 0);
7385 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
7387 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture1);
7388 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
7389 hr = IDirect3DDevice8_SetTexture(device, 1, (IDirect3DBaseTexture8 *)texture2);
7390 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
7391 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX3);
7392 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
7393 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
7394 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
7395 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7396 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
7397 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7398 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
7399 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
7400 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
7401 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7402 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
7403 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
7404 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
7405 hr = IDirect3DDevice8_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
7406 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
7408 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_TEXCOORDINDEX, 1);
7409 ok(SUCCEEDED(hr), "Failed to set texcoord index, hr %#x.\n", hr);
7410 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_TEXCOORDINDEX, 0);
7411 ok(SUCCEEDED(hr), "Failed to set texcoord index, hr %#x.\n", hr);
7413 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 1.0f, 0);
7414 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
7416 hr = IDirect3DDevice8_BeginScene(device);
7417 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7418 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
7419 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7420 hr = IDirect3DDevice8_EndScene(device);
7421 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7423 color = getPixelColor(device, 160, 120);
7424 ok(color_match(color, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color);
7425 color = getPixelColor(device, 480, 120);
7426 ok(color_match(color, 0x0000ffff, 2), "Got unexpected color 0x%08x.\n", color);
7427 color = getPixelColor(device, 160, 360);
7428 ok(color_match(color, 0x00ff0000, 2), "Got unexpected color 0x%08x.\n", color);
7429 color = getPixelColor(device, 480, 360);
7430 ok(color_match(color, 0x00ffffff, 2), "Got unexpected color 0x%08x.\n", color);
7432 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
7433 ok(SUCCEEDED(hr), "Failed to set texture transform flags, hr %#x.\n", hr);
7434 hr = IDirect3DDevice8_SetTransform(device, D3DTS_TEXTURE1, &mat);
7435 ok(SUCCEEDED(hr), "Failed to set transformation matrix, hr %#x.\n", hr);
7437 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 1.0f, 0);
7438 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
7440 hr = IDirect3DDevice8_BeginScene(device);
7441 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7442 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
7443 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7444 hr = IDirect3DDevice8_EndScene(device);
7445 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7447 color = getPixelColor(device, 160, 120);
7448 ok(color_match(color, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color);
7449 color = getPixelColor(device, 480, 120);
7450 ok(color_match(color, 0x0000ffff, 2), "Got unexpected color 0x%08x.\n", color);
7451 color = getPixelColor(device, 160, 360);
7452 ok(color_match(color, 0x00000000, 2), "Got unexpected color 0x%08x.\n", color);
7453 color = getPixelColor(device, 480, 360);
7454 ok(color_match(color, 0x0000ffff, 2), "Got unexpected color 0x%08x.\n", color);
7456 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
7457 ok(SUCCEEDED(hr), "Failed to set texture transform flags, hr %#x.\n", hr);
7458 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_TEXCOORDINDEX, 2);
7459 ok(SUCCEEDED(hr), "Failed to set texcoord index, hr %#x.\n", hr);
7461 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 1.0f, 0);
7462 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
7464 hr = IDirect3DDevice8_BeginScene(device);
7465 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7466 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
7467 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7468 hr = IDirect3DDevice8_EndScene(device);
7469 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7471 color = getPixelColor(device, 160, 120);
7472 ok(color_match(color, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color);
7473 color = getPixelColor(device, 480, 120);
7474 ok(color_match(color, 0x0000ffff, 2), "Got unexpected color 0x%08x.\n", color);
7475 color = getPixelColor(device, 160, 360);
7476 ok(color_match(color, 0x00ff00ff, 2), "Got unexpected color 0x%08x.\n", color);
7477 color = getPixelColor(device, 480, 360);
7478 ok(color_match(color, 0x00ffff00, 2), "Got unexpected color 0x%08x.\n", color);
7480 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
7481 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
7483 IDirect3DTexture8_Release(texture1);
7484 IDirect3DTexture8_Release(texture2);
7486 refcount = IDirect3DDevice8_Release(device);
7487 ok(!refcount, "Device has %u references left.\n", refcount);
7488 IDirect3D8_Release(d3d);
7489 DestroyWindow(window);
7492 static void test_vshader_input(void)
7494 DWORD swapped_twotexcrd_shader, swapped_onetexcrd_shader = 0;
7495 DWORD swapped_twotex_wrongidx_shader = 0, swapped_twotexcrd_rightorder_shader;
7496 DWORD texcoord_color_shader, color_ubyte_shader, color_color_shader, color_float_shader;
7497 DWORD color_nocolor_shader = 0;
7498 IDirect3DDevice8 *device;
7499 IDirect3D8 *d3d;
7500 ULONG refcount;
7501 D3DCAPS8 caps;
7502 DWORD color;
7503 HWND window;
7504 HRESULT hr;
7506 static const DWORD swapped_shader_code[] =
7508 0xfffe0101, /* vs_1_1 */
7509 0x00000001, 0xc00f0000, 0x90e40000, /* mov o0, v0 */
7510 0x00000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
7511 0x00000002, 0xd00f0000, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
7512 0x0000ffff /* end */
7514 static const DWORD texcoord_color_shader_code[] =
7516 0xfffe0101, /* vs_1_1 */
7517 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
7518 0x00000001, 0xd00f0000, 0x90e40007, /* mov oD0, v7 */
7519 0x0000ffff /* end */
7521 static const DWORD color_color_shader_code[] =
7523 0xfffe0101, /* vs_1_1 */
7524 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
7525 0x00000005, 0xd00f0000, 0xa0e40000, 0x90e40005, /* mul oD0, c0, v5 */
7526 0x0000ffff /* end */
7528 static const float quad1[] =
7530 -1.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7531 -1.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7532 0.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7533 0.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7535 static const float quad4[] =
7537 0.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7538 0.0f, 1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7539 1.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7540 1.0f, 1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7542 static const struct
7544 struct vec3 position;
7545 DWORD diffuse;
7547 quad1_color[] =
7549 {{-1.0f, -1.0f, 0.1f}, 0x00ff8040},
7550 {{-1.0f, 0.0f, 0.1f}, 0x00ff8040},
7551 {{ 0.0f, -1.0f, 0.1f}, 0x00ff8040},
7552 {{ 0.0f, 0.0f, 0.1f}, 0x00ff8040},
7554 quad2_color[] =
7556 {{ 0.0f, -1.0f, 0.1f}, 0x00ff8040},
7557 {{ 0.0f, 0.0f, 0.1f}, 0x00ff8040},
7558 {{ 1.0f, -1.0f, 0.1f}, 0x00ff8040},
7559 {{ 1.0f, 0.0f, 0.1f}, 0x00ff8040},
7561 quad3_color[] =
7563 {{-1.0f, 0.0f, 0.1f}, 0x00ff8040},
7564 {{-1.0f, 1.0f, 0.1f}, 0x00ff8040},
7565 {{ 0.0f, 0.0f, 0.1f}, 0x00ff8040},
7566 {{ 0.0f, 1.0f, 0.1f}, 0x00ff8040},
7568 static const float quad4_color[] =
7570 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 0.0f, 0.0f,
7571 0.0f, 1.0f, 0.1f, 1.0f, 1.0f, 0.0f, 0.0f,
7572 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 0.0f, 1.0f,
7573 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 0.0f, 1.0f,
7575 static const DWORD decl_twotexcrd[] =
7577 D3DVSD_STREAM(0),
7578 D3DVSD_REG(0, D3DVSDT_FLOAT3), /* position */
7579 D3DVSD_REG(1, D3DVSDT_FLOAT4), /* texcoord0 */
7580 D3DVSD_REG(2, D3DVSDT_FLOAT4), /* texcoord1 */
7581 D3DVSD_END()
7583 static const DWORD decl_twotexcrd_rightorder[] =
7585 D3DVSD_STREAM(0),
7586 D3DVSD_REG(0, D3DVSDT_FLOAT3), /* position */
7587 D3DVSD_REG(2, D3DVSDT_FLOAT4), /* texcoord0 */
7588 D3DVSD_REG(1, D3DVSDT_FLOAT4), /* texcoord1 */
7589 D3DVSD_END()
7591 static const DWORD decl_onetexcrd[] =
7593 D3DVSD_STREAM(0),
7594 D3DVSD_REG(0, D3DVSDT_FLOAT3), /* position */
7595 D3DVSD_REG(1, D3DVSDT_FLOAT4), /* texcoord0 */
7596 D3DVSD_END()
7598 static const DWORD decl_twotexcrd_wrongidx[] =
7600 D3DVSD_STREAM(0),
7601 D3DVSD_REG(0, D3DVSDT_FLOAT3), /* position */
7602 D3DVSD_REG(2, D3DVSDT_FLOAT4), /* texcoord1 */
7603 D3DVSD_REG(3, D3DVSDT_FLOAT4), /* texcoord2 */
7604 D3DVSD_END()
7606 static const DWORD decl_texcoord_color[] =
7608 D3DVSD_STREAM(0),
7609 D3DVSD_REG(0, D3DVSDT_FLOAT3), /* position */
7610 D3DVSD_REG(7, D3DVSDT_D3DCOLOR), /* texcoord0 */
7611 D3DVSD_END()
7613 static const DWORD decl_color_color[] =
7615 D3DVSD_STREAM(0),
7616 D3DVSD_REG(0, D3DVSDT_FLOAT3), /* position */
7617 D3DVSD_REG(5, D3DVSDT_D3DCOLOR), /* diffuse */
7618 D3DVSD_END()
7620 static const DWORD decl_color_ubyte[] =
7622 D3DVSD_STREAM(0),
7623 D3DVSD_REG(0, D3DVSDT_FLOAT3),
7624 D3DVSD_REG(5, D3DVSDT_UBYTE4),
7625 D3DVSD_END()
7627 static const DWORD decl_color_float[] =
7629 D3DVSD_STREAM(0),
7630 D3DVSD_REG(0, D3DVSDT_FLOAT3),
7631 D3DVSD_REG(5, D3DVSDT_FLOAT4),
7632 D3DVSD_END()
7634 static const DWORD decl_nocolor[] =
7636 D3DVSD_STREAM(0),
7637 D3DVSD_REG(0, D3DVSDT_FLOAT3),
7638 D3DVSD_END()
7640 static const float normalize[4] = {1.0f / 256.0f, 1.0f / 256.0f, 1.0f / 256.0f, 1.0f / 256.0f};
7641 static const float no_normalize[4] = {1.0f, 1.0f, 1.0f, 1.0f};
7643 window = create_window();
7644 d3d = Direct3DCreate8(D3D_SDK_VERSION);
7645 ok(!!d3d, "Failed to create a D3D object.\n");
7646 if (!(device = create_device(d3d, window, window, TRUE)))
7648 skip("Failed to create a D3D device, skipping tests.\n");
7649 goto done;
7652 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
7653 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
7654 if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1))
7656 skip("No vs_1_1 support, skipping tests.\n");
7657 IDirect3DDevice8_Release(device);
7658 goto done;
7661 hr = IDirect3DDevice8_CreateVertexShader(device, decl_twotexcrd, swapped_shader_code, &swapped_twotexcrd_shader, 0);
7662 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
7663 hr = IDirect3DDevice8_CreateVertexShader(device, decl_onetexcrd, swapped_shader_code, &swapped_onetexcrd_shader, 0);
7664 todo_wine ok(hr == D3DERR_INVALIDCALL, "Unexpected error while creating vertex shader, hr %#x.\n", hr);
7665 hr = IDirect3DDevice8_CreateVertexShader(device, decl_twotexcrd_wrongidx, swapped_shader_code, &swapped_twotex_wrongidx_shader, 0);
7666 todo_wine ok(hr == D3DERR_INVALIDCALL, "Unexpected error while creating vertex shader, hr %#x.\n", hr);
7667 hr = IDirect3DDevice8_CreateVertexShader(device, decl_twotexcrd_rightorder, swapped_shader_code, &swapped_twotexcrd_rightorder_shader, 0);
7668 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
7670 hr = IDirect3DDevice8_CreateVertexShader(device, decl_texcoord_color, texcoord_color_shader_code, &texcoord_color_shader, 0);
7671 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
7672 hr = IDirect3DDevice8_CreateVertexShader(device, decl_color_ubyte, color_color_shader_code, &color_ubyte_shader, 0);
7673 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
7674 hr = IDirect3DDevice8_CreateVertexShader(device, decl_color_color, color_color_shader_code, &color_color_shader, 0);
7675 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
7676 hr = IDirect3DDevice8_CreateVertexShader(device, decl_color_float, color_color_shader_code, &color_float_shader, 0);
7677 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
7678 hr = IDirect3DDevice8_CreateVertexShader(device, decl_nocolor, color_color_shader_code, &color_nocolor_shader, 0);
7679 todo_wine ok(hr == D3DERR_INVALIDCALL, "Unexpected error while creating vertex shader, hr %#x.\n", hr);
7681 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 1.0f, 0);
7682 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
7684 hr = IDirect3DDevice8_BeginScene(device);
7685 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7687 hr = IDirect3DDevice8_SetVertexShader(device, swapped_twotexcrd_shader);
7688 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
7690 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 11);
7691 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7693 hr = IDirect3DDevice8_SetVertexShader(device, swapped_twotexcrd_rightorder_shader);
7694 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
7695 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 11);
7696 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7698 hr = IDirect3DDevice8_EndScene(device);
7699 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7701 color = getPixelColor(device, 160, 360);
7702 ok(color_match(color, 0x00ffff80, 1), "Got unexpected color 0x%08x for quad 1 (2crd).\n", color);
7703 color = getPixelColor(device, 480, 160);
7704 ok(color == 0x00000000, "Got unexpected color 0x%08x for quad 4 (2crd-rightorder).\n", color);
7706 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
7707 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
7709 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
7710 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
7712 hr = IDirect3DDevice8_BeginScene(device);
7713 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7715 hr = IDirect3DDevice8_SetVertexShader(device, texcoord_color_shader);
7716 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
7717 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1_color, sizeof(quad1_color[0]));
7718 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7720 hr = IDirect3DDevice8_SetVertexShader(device, color_ubyte_shader);
7721 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
7723 hr = IDirect3DDevice8_SetVertexShaderConstant(device, 0, normalize, 1);
7724 ok(SUCCEEDED(hr), "Failed to set vertex shader constant, hr %#x.\n", hr);
7725 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_color, sizeof(quad2_color[0]));
7726 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7728 hr = IDirect3DDevice8_SetVertexShaderConstant(device, 0, no_normalize, 1);
7729 ok(SUCCEEDED(hr), "Failed to set vertex shader constant, hr %#x.\n", hr);
7730 hr = IDirect3DDevice8_SetVertexShader(device, color_color_shader);
7731 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
7732 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3_color, sizeof(quad3_color[0]));
7733 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7735 hr = IDirect3DDevice8_SetVertexShader(device, color_float_shader);
7736 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
7737 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4_color, sizeof(float) * 7);
7738 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7740 hr = IDirect3DDevice8_EndScene(device);
7741 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7743 IDirect3DDevice8_SetVertexShader(device, 0);
7745 color = getPixelColor(device, 160, 360);
7746 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
7747 "Input test: Quad 1(color-texcoord) returned color 0x%08x, expected 0x00ff8040\n", color);
7748 color = getPixelColor(device, 480, 360);
7749 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x40, 0x80, 0xff), 1),
7750 "Input test: Quad 2(color-ubyte) returned color 0x%08x, expected 0x004080ff\n", color);
7751 color = getPixelColor(device, 160, 120);
7752 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
7753 "Input test: Quad 3(color-color) returned color 0x%08x, expected 0x00ff8040\n", color);
7754 color = getPixelColor(device, 480, 160);
7755 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 1),
7756 "Input test: Quad 4(color-float) returned color 0x%08x, expected 0x00ffff00\n", color);
7758 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
7759 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
7761 IDirect3DDevice8_DeleteVertexShader(device, swapped_twotexcrd_shader);
7762 IDirect3DDevice8_DeleteVertexShader(device, swapped_onetexcrd_shader);
7763 IDirect3DDevice8_DeleteVertexShader(device, swapped_twotex_wrongidx_shader);
7764 IDirect3DDevice8_DeleteVertexShader(device, swapped_twotexcrd_rightorder_shader);
7765 IDirect3DDevice8_DeleteVertexShader(device, texcoord_color_shader);
7766 IDirect3DDevice8_DeleteVertexShader(device, color_ubyte_shader);
7767 IDirect3DDevice8_DeleteVertexShader(device, color_color_shader);
7768 IDirect3DDevice8_DeleteVertexShader(device, color_float_shader);
7769 IDirect3DDevice8_DeleteVertexShader(device, color_nocolor_shader);
7771 refcount = IDirect3DDevice8_Release(device);
7772 ok(!refcount, "Device has %u references left.\n", refcount);
7773 done:
7774 IDirect3D8_Release(d3d);
7775 DestroyWindow(window);
7778 static void test_fixed_function_fvf(void)
7780 IDirect3DDevice8 *device;
7781 DWORD color;
7782 IDirect3D8 *d3d;
7783 ULONG refcount;
7784 D3DCAPS8 caps;
7785 HWND window;
7786 HRESULT hr;
7788 static const struct
7790 struct vec3 position;
7791 DWORD diffuse;
7793 quad1[] =
7795 {{-1.0f, -1.0f, 0.1f}, 0x00ffff00},
7796 {{-1.0f, 0.0f, 0.1f}, 0x00ffff00},
7797 {{ 0.0f, -1.0f, 0.1f}, 0x00ffff00},
7798 {{ 0.0f, 0.0f, 0.1f}, 0x00ffff00},
7800 static const struct vec3 quad2[] =
7802 {-1.0f, -1.0f, 0.1f},
7803 {-1.0f, 0.0f, 0.1f},
7804 { 0.0f, -1.0f, 0.1f},
7805 { 0.0f, 0.0f, 0.1f},
7807 static const struct
7809 struct vec4 position;
7810 DWORD diffuse;
7812 quad_transformed[] =
7814 {{ 90.0f, 110.0f, 0.1f, 2.0f}, 0x00ffff00},
7815 {{570.0f, 110.0f, 0.1f, 2.0f}, 0x00ffff00},
7816 {{ 90.0f, 300.0f, 0.1f, 2.0f}, 0x00ffff00},
7817 {{570.0f, 300.0f, 0.1f, 2.0f}, 0x00ffff00},
7820 window = create_window();
7821 d3d = Direct3DCreate8(D3D_SDK_VERSION);
7822 ok(!!d3d, "Failed to create a D3D object.\n");
7823 if (!(device = create_device(d3d, window, window, TRUE)))
7825 skip("Failed to create a D3D device, skipping tests.\n");
7826 goto done;
7829 memset(&caps, 0, sizeof(caps));
7830 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
7831 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
7833 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
7834 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
7836 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
7837 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
7839 hr = IDirect3DDevice8_BeginScene(device);
7840 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7842 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
7843 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
7844 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
7845 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7847 hr = IDirect3DDevice8_EndScene(device);
7848 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7850 color = getPixelColor(device, 160, 360);
7851 ok(color == 0x00ffff00,
7852 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7853 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
7855 /* Test with no diffuse color attribute. */
7856 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7857 ok(SUCCEEDED(hr), "IDirect3DDevice8_Clear failed with %08x\n", hr);
7859 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ);
7860 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
7861 hr = IDirect3DDevice8_BeginScene(device);
7862 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7863 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad2, sizeof(quad2[0]));
7864 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7865 hr = IDirect3DDevice8_EndScene(device);
7866 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7868 color = getPixelColor(device, 160, 360);
7869 ok(color == 0x00ffffff, "Got unexpected color 0x%08x in the no diffuse attribute test.\n", color);
7870 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
7872 /* Test what happens with specular lighting enabled and no specular color attribute. */
7873 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
7874 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
7875 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SPECULARENABLE, TRUE);
7876 ok(SUCCEEDED(hr), "Failed to enable specular lighting, hr %#x.\n", hr);
7877 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
7878 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
7879 hr = IDirect3DDevice8_BeginScene(device);
7880 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7882 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad1, sizeof(quad1[0]));
7883 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7885 hr = IDirect3DDevice8_EndScene(device);
7886 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7887 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SPECULARENABLE, FALSE);
7888 ok(SUCCEEDED(hr), "Failed to disable specular lighting, hr %#x.\n", hr);
7890 color = getPixelColor(device, 160, 360);
7891 ok(color == 0x00ffff00, "Got unexpected color 0x%08x in the no specular attribute test.\n", color);
7893 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
7895 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
7896 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
7898 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7899 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
7901 hr = IDirect3DDevice8_BeginScene(device);
7902 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7903 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad_transformed, sizeof(quad_transformed[0]));
7904 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7905 hr = IDirect3DDevice8_EndScene(device);
7906 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7908 color = getPixelColor(device, 88, 108);
7909 ok(color == 0x000000ff,
7910 "pixel 88/108 has color %08x, expected 0x000000ff\n", color);
7911 color = getPixelColor(device, 92, 108);
7912 ok(color == 0x000000ff,
7913 "pixel 92/108 has color %08x, expected 0x000000ff\n", color);
7914 color = getPixelColor(device, 88, 112);
7915 ok(color == 0x000000ff,
7916 "pixel 88/112 has color %08x, expected 0x000000ff\n", color);
7917 color = getPixelColor(device, 92, 112);
7918 ok(color == 0x00ffff00,
7919 "pixel 92/112 has color %08x, expected 0x00ffff00\n", color);
7921 color = getPixelColor(device, 568, 108);
7922 ok(color == 0x000000ff,
7923 "pixel 568/108 has color %08x, expected 0x000000ff\n", color);
7924 color = getPixelColor(device, 572, 108);
7925 ok(color == 0x000000ff,
7926 "pixel 572/108 has color %08x, expected 0x000000ff\n", color);
7927 color = getPixelColor(device, 568, 112);
7928 ok(color == 0x00ffff00,
7929 "pixel 568/112 has color %08x, expected 0x00ffff00\n", color);
7930 color = getPixelColor(device, 572, 112);
7931 ok(color == 0x000000ff,
7932 "pixel 572/112 has color %08x, expected 0x000000ff\n", color);
7934 color = getPixelColor(device, 88, 298);
7935 ok(color == 0x000000ff,
7936 "pixel 88/298 has color %08x, expected 0x000000ff\n", color);
7937 color = getPixelColor(device, 92, 298);
7938 ok(color == 0x00ffff00,
7939 "pixel 92/298 has color %08x, expected 0x00ffff00\n", color);
7940 color = getPixelColor(device, 88, 302);
7941 ok(color == 0x000000ff,
7942 "pixel 88/302 has color %08x, expected 0x000000ff\n", color);
7943 color = getPixelColor(device, 92, 302);
7944 ok(color == 0x000000ff,
7945 "pixel 92/302 has color %08x, expected 0x000000ff\n", color);
7947 color = getPixelColor(device, 568, 298);
7948 ok(color == 0x00ffff00,
7949 "pixel 568/298 has color %08x, expected 0x00ffff00\n", color);
7950 color = getPixelColor(device, 572, 298);
7951 ok(color == 0x000000ff,
7952 "pixel 572/298 has color %08x, expected 0x000000ff\n", color);
7953 color = getPixelColor(device, 568, 302);
7954 ok(color == 0x000000ff,
7955 "pixel 568/302 has color %08x, expected 0x000000ff\n", color);
7956 color = getPixelColor(device, 572, 302);
7957 ok(color == 0x000000ff,
7958 "pixel 572/302 has color %08x, expected 0x000000ff\n", color);
7960 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
7962 refcount = IDirect3DDevice8_Release(device);
7963 ok(!refcount, "Device has %u references left.\n", refcount);
7964 done:
7965 IDirect3D8_Release(d3d);
7966 DestroyWindow(window);
7969 static void test_flip(void)
7971 IDirect3DDevice8 *device;
7972 IDirect3D8 *d3d;
7973 ULONG refcount;
7974 HWND window;
7975 HRESULT hr;
7976 IDirect3DSurface8 *back_buffers[3], *test_surface;
7977 unsigned int i;
7978 D3DCOLOR color;
7979 D3DPRESENT_PARAMETERS present_parameters = {0};
7981 window = create_window();
7982 d3d = Direct3DCreate8(D3D_SDK_VERSION);
7983 ok(!!d3d, "Failed to create a D3D object.\n");
7985 present_parameters.BackBufferWidth = 640;
7986 present_parameters.BackBufferHeight = 480;
7987 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
7988 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
7989 present_parameters.hDeviceWindow = window;
7990 present_parameters.Windowed = TRUE;
7991 present_parameters.BackBufferCount = 3;
7992 present_parameters.Flags = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER;
7993 hr = IDirect3D8_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
7994 window, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device);
7995 if (!device)
7997 skip("Failed to create a D3D device, skipping tests.\n");
7998 IDirect3D8_Release(d3d);
7999 DestroyWindow(window);
8000 return;
8003 for (i = 0; i < sizeof(back_buffers) / sizeof(*back_buffers); ++i)
8005 hr = IDirect3DDevice8_GetBackBuffer(device, i, D3DBACKBUFFER_TYPE_MONO, &back_buffers[i]);
8006 ok(SUCCEEDED(hr), "Failed to get back buffer, hr %#x.\n", hr);
8008 hr = IDirect3DDevice8_GetRenderTarget(device, &test_surface);
8009 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
8010 ok(test_surface == back_buffers[0], "Expected render target %p, got %p.\n", back_buffers[0], test_surface);
8011 IDirect3DSurface8_Release(test_surface);
8014 hr = IDirect3DDevice8_SetRenderTarget(device, back_buffers[0], NULL);
8015 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
8016 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0f, 0);
8017 ok(SUCCEEDED(hr), "Failed to clear, hr %#x\n", hr);
8019 hr = IDirect3DDevice8_SetRenderTarget(device, back_buffers[1], NULL);
8020 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
8021 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0f, 0);
8022 ok(SUCCEEDED(hr), "Failed to clear, hr %#x\n", hr);
8024 hr = IDirect3DDevice8_SetRenderTarget(device, back_buffers[2], NULL);
8025 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
8026 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0f, 0);
8027 ok(SUCCEEDED(hr), "Failed to clear, hr %#x\n", hr);
8029 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
8030 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
8032 /* Render target is unmodified. */
8033 hr = IDirect3DDevice8_GetRenderTarget(device, &test_surface);
8034 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
8035 ok(test_surface == back_buffers[2], "Expected render target %p, got %p.\n", back_buffers[2], test_surface);
8036 IDirect3DSurface8_Release(test_surface);
8038 /* Backbuffer surface pointers are unmodified */
8039 for (i = 0; i < sizeof(back_buffers) / sizeof(*back_buffers); ++i)
8041 hr = IDirect3DDevice8_GetBackBuffer(device, i, D3DBACKBUFFER_TYPE_MONO, &test_surface);
8042 ok(SUCCEEDED(hr), "Failed to get back buffer, hr %#x.\n", hr);
8043 ok(test_surface == back_buffers[i], "Expected back buffer %u = %p, got %p.\n",
8044 i, back_buffers[i], test_surface);
8045 IDirect3DSurface8_Release(test_surface);
8048 /* Contents were changed. */
8049 color = get_surface_color(back_buffers[0], 1, 1);
8050 ok(color == 0xff00ff00, "Got unexpected color 0x%08x.\n", color);
8051 color = get_surface_color(back_buffers[1], 1, 1);
8052 ok(color == 0xff0000ff, "Got unexpected color 0x%08x.\n", color);
8054 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff808080, 0.0f, 0);
8055 ok(SUCCEEDED(hr), "Failed to clear, hr %#x\n", hr);
8057 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
8058 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
8060 color = get_surface_color(back_buffers[0], 1, 1);
8061 ok(color == 0xff0000ff, "Got unexpected color 0x%08x.\n", color);
8062 color = get_surface_color(back_buffers[1], 1, 1);
8063 ok(color == 0xff808080, "Got unexpected color 0x%08x.\n", color);
8065 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
8066 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
8068 color = get_surface_color(back_buffers[0], 1, 1);
8069 ok(color == 0xff808080, "Got unexpected color 0x%08x.\n", color);
8071 for (i = 0; i < sizeof(back_buffers) / sizeof(*back_buffers); ++i)
8072 IDirect3DSurface8_Release(back_buffers[i]);
8074 refcount = IDirect3DDevice8_Release(device);
8075 ok(!refcount, "Device has %u references left.\n", refcount);
8077 if (FAILED(IDirect3D8_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
8078 D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES)))
8080 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping multisample flip test.\n");
8081 goto done;
8084 present_parameters.BackBufferCount = 2;
8085 present_parameters.MultiSampleType = D3DMULTISAMPLE_2_SAMPLES;
8086 present_parameters.Flags = 0;
8087 hr = IDirect3D8_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
8088 window, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device);
8090 for (i = 0; i < present_parameters.BackBufferCount; ++i)
8092 hr = IDirect3DDevice8_GetBackBuffer(device, i, D3DBACKBUFFER_TYPE_MONO, &back_buffers[i]);
8093 ok(SUCCEEDED(hr), "Failed to get back buffer, hr %#x.\n", hr);
8096 hr = IDirect3DDevice8_SetRenderTarget(device, back_buffers[1], NULL);
8097 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
8098 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff808080, 0.0f, 0);
8099 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
8101 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
8102 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
8104 hr = IDirect3DDevice8_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
8105 D3DMULTISAMPLE_NONE, TRUE, &test_surface);
8106 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
8107 hr = IDirect3DDevice8_CopyRects(device, back_buffers[0], NULL, 0, test_surface, NULL);
8108 ok(SUCCEEDED(hr), "CopyRects failed, hr %#x.\n", hr);
8110 color = get_surface_color(test_surface, 1, 1);
8111 ok(color == 0xff808080, "Got unexpected color 0x%08x.\n", color);
8113 IDirect3DSurface8_Release(test_surface);
8114 for (i = 0; i < present_parameters.BackBufferCount; ++i)
8115 IDirect3DSurface8_Release(back_buffers[i]);
8117 refcount = IDirect3DDevice8_Release(device);
8118 ok(!refcount, "Device has %u references left.\n", refcount);
8120 done:
8121 IDirect3D8_Release(d3d);
8122 DestroyWindow(window);
8125 static void test_uninitialized_varyings(void)
8127 static const D3DMATRIX mat =
8129 1.0f, 0.0f, 0.0f, 0.0f,
8130 0.0f, 1.0f, 0.0f, 0.0f,
8131 0.0f, 0.0f, 1.0f, 0.0f,
8132 0.0f, 0.0f, 0.0f, 1.0f,
8133 }}};
8134 static const struct vec3 quad[] =
8136 {-1.0f, -1.0f, 0.1f},
8137 {-1.0f, 1.0f, 0.1f},
8138 { 1.0f, -1.0f, 0.1f},
8139 { 1.0f, 1.0f, 0.1f},
8141 static const DWORD decl[] =
8143 D3DVSD_STREAM(0),
8144 D3DVSD_REG(0, D3DVSDT_FLOAT3),
8145 D3DVSD_CONST(0, 1), 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, /* def c0, 0.5, 0.5, 0.5, 0.5 */
8146 D3DVSD_END()
8148 static const DWORD vs1_code[] =
8150 0xfffe0101, /* vs_1_1 */
8151 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
8152 0x0000ffff
8154 static const DWORD vs1_partial_code[] =
8156 0xfffe0101, /* vs_1_1 */
8157 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
8158 0x00000001, 0xd0010000, 0xa0e40000, /* mov oD0.x, c0 */
8159 0x00000001, 0xd0010001, 0xa0e40000, /* mov oD1.x, c0 */
8160 0x00000001, 0xe0010000, 0xa0e40000, /* mov oT0.x, c0 */
8161 0x0000ffff
8163 static const DWORD ps1_diffuse_code[] =
8165 0xffff0101, /* ps_1_1 */
8166 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
8167 0x0000ffff
8169 static const DWORD ps1_specular_code[] =
8171 0xffff0101, /* ps_1_1 */
8172 0x00000001, 0x800f0000, 0x90e40001, /* mov r0, v1 */
8173 0x0000ffff
8175 static const DWORD ps1_texcoord_code[] =
8177 0xffff0101, /* ps_1_1 */
8178 0x00000040, 0xb00f0000, /* texcoord t0 */
8179 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
8180 0x0000ffff
8182 static const struct
8184 DWORD vs_version;
8185 const DWORD *vs;
8186 DWORD ps_version;
8187 const DWORD *ps;
8188 D3DCOLOR expected;
8189 BOOL allow_zero_alpha;
8190 BOOL broken_warp;
8192 /* On AMD specular color is generally initialized to 0x00000000 and texcoords to 0xff000000
8193 * while on Nvidia it's the opposite. Just allow both. */
8194 tests[] =
8196 {D3DVS_VERSION(1, 1), vs1_code, 0, NULL, 0xffffffff},
8197 { 0, NULL, D3DPS_VERSION(1, 1), ps1_texcoord_code, 0xff000000, TRUE},
8198 {D3DVS_VERSION(1, 1), vs1_code, D3DPS_VERSION(1, 1), ps1_diffuse_code, 0xffffffff},
8199 {D3DVS_VERSION(1, 1), vs1_code, D3DPS_VERSION(1, 1), ps1_specular_code, 0xff000000, TRUE, TRUE},
8200 {D3DVS_VERSION(1, 1), vs1_code, D3DPS_VERSION(1, 1), ps1_texcoord_code, 0xff000000, TRUE},
8201 {D3DVS_VERSION(1, 1), vs1_partial_code, 0, NULL, 0xff7fffff, FALSE, TRUE},
8202 {D3DVS_VERSION(1, 1), vs1_partial_code, D3DPS_VERSION(1, 1), ps1_diffuse_code, 0xff7fffff, FALSE, TRUE},
8203 {D3DVS_VERSION(1, 1), vs1_partial_code, D3DPS_VERSION(1, 1), ps1_specular_code, 0xff7f0000, TRUE},
8204 {D3DVS_VERSION(1, 1), vs1_partial_code, D3DPS_VERSION(1, 1), ps1_texcoord_code, 0xff7f0000, TRUE},
8206 IDirect3DDevice8 *device;
8207 IDirect3D8 *d3d;
8208 HWND window;
8209 HRESULT hr;
8210 DWORD vs, ps;
8211 unsigned int i;
8212 ULONG refcount;
8213 D3DCAPS8 caps;
8214 IDirect3DSurface8 *backbuffer;
8215 D3DADAPTER_IDENTIFIER8 identifier;
8216 struct surface_readback rb;
8217 D3DCOLOR color;
8218 BOOL warp;
8220 window = create_window();
8221 d3d = Direct3DCreate8(D3D_SDK_VERSION);
8222 ok(!!d3d, "Failed to create a D3D object.\n");
8223 if (!(device = create_device(d3d, window, window, TRUE)))
8225 skip("Failed to create a D3D device, skipping tests.\n");
8226 IDirect3D8_Release(d3d);
8227 DestroyWindow(window);
8228 return;
8231 hr = IDirect3D8_GetAdapterIdentifier(d3d, D3DADAPTER_DEFAULT, 0, &identifier);
8232 ok(SUCCEEDED(hr), "Failed to get adapter identifier, hr %#x.\n", hr);
8233 warp = adapter_is_warp(&identifier);
8235 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
8236 ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
8238 hr = IDirect3DDevice8_GetBackBuffer(device, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8239 ok(SUCCEEDED(hr), "Failed to get back buffer, hr %#x.\n", hr);
8241 hr = IDirect3DDevice8_SetTransform(device, D3DTS_WORLD, &mat);
8242 ok(SUCCEEDED(hr), "Failed to set world transform, hr %#x.\n", hr);
8243 hr = IDirect3DDevice8_SetTransform(device, D3DTS_VIEW, &mat);
8244 ok(SUCCEEDED(hr), "Failed to set view transform, hr %#x.\n", hr);
8245 hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, &mat);
8246 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
8247 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, FALSE);
8248 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#x.\n", hr);
8249 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, FALSE);
8250 ok(SUCCEEDED(hr), "Failed to disable Z test, hr %#x.\n", hr);
8251 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
8252 ok(SUCCEEDED(hr), "Failed to disable fog, hr %#x.\n", hr);
8253 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
8254 ok(SUCCEEDED(hr), "Failed to disable stencil test, hr %#x.\n", hr);
8255 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8256 ok(SUCCEEDED(hr), "Failed to disable culling, hr %#x.\n", hr);
8258 for (i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i)
8260 if (caps.VertexShaderVersion < tests[i].vs_version
8261 || caps.PixelShaderVersion < tests[i].ps_version)
8263 skip("Vertex / pixel shader version not supported, skipping test %u.\n", i);
8264 continue;
8266 if (tests[i].vs)
8268 hr = IDirect3DDevice8_CreateVertexShader(device, decl, tests[i].vs, &vs, 0);
8269 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x (case %u).\n", hr, i);
8270 hr = IDirect3DDevice8_SetVertexShader(device, vs);
8271 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
8273 else
8275 vs = 0;
8276 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ);
8277 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
8279 if (tests[i].ps)
8281 hr = IDirect3DDevice8_CreatePixelShader(device, tests[i].ps, &ps);
8282 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x (case %u).\n", hr, i);
8284 else
8286 ps = 0;
8289 hr = IDirect3DDevice8_SetPixelShader(device, ps);
8290 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
8292 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0f, 0);
8293 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
8295 hr = IDirect3DDevice8_BeginScene(device);
8296 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
8298 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
8299 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8301 hr = IDirect3DDevice8_EndScene(device);
8302 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
8304 get_rt_readback(backbuffer, &rb);
8305 color = get_readback_color(&rb, 320, 240);
8306 ok(color_match(color, tests[i].expected, 1)
8307 || (tests[i].allow_zero_alpha && color_match(color, tests[i].expected & 0x00ffffff, 1))
8308 || (broken(warp && tests[i].broken_warp)),
8309 "Got unexpected color 0x%08x, case %u.\n", color, i);
8310 release_surface_readback(&rb);
8312 if (vs)
8313 IDirect3DDevice8_DeleteVertexShader(device, vs);
8314 if (ps)
8315 IDirect3DDevice8_DeletePixelShader(device, ps);
8318 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
8319 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
8321 IDirect3DSurface8_Release(backbuffer);
8322 refcount = IDirect3DDevice8_Release(device);
8323 ok(!refcount, "Device has %u references left.\n", refcount);
8324 IDirect3D8_Release(d3d);
8325 DestroyWindow(window);
8328 static void test_shademode(void)
8330 IDirect3DVertexBuffer8 *vb_strip;
8331 IDirect3DVertexBuffer8 *vb_list;
8332 IDirect3DDevice8 *device;
8333 DWORD color0, color1;
8334 BYTE *data = NULL;
8335 IDirect3D8 *d3d;
8336 ULONG refcount;
8337 D3DCAPS8 caps;
8338 DWORD vs, ps;
8339 HWND window;
8340 HRESULT hr;
8341 UINT i;
8342 static const DWORD decl[] =
8344 D3DVSD_STREAM(0),
8345 D3DVSD_REG(D3DVSDE_POSITION, D3DVSDT_FLOAT3),
8346 D3DVSD_REG(D3DVSDE_DIFFUSE, D3DVSDT_D3DCOLOR),
8347 D3DVSD_END()
8349 static const DWORD vs1_code[] =
8351 0xfffe0101, /* vs_1_1 */
8352 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
8353 0x00000001, 0xd00f0000, 0x90e40005, /* mov oD0, v5 */
8354 0x0000ffff
8356 static const DWORD ps1_code[] =
8358 0xffff0101, /* ps_1_1 */
8359 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
8360 0x0000ffff
8362 static const struct
8364 struct vec3 position;
8365 DWORD diffuse;
8367 quad_strip[] =
8369 {{-1.0f, -1.0f, 0.0f}, 0xffff0000},
8370 {{-1.0f, 1.0f, 0.0f}, 0xff00ff00},
8371 {{ 1.0f, -1.0f, 0.0f}, 0xff0000ff},
8372 {{ 1.0f, 1.0f, 0.0f}, 0xffffffff},
8374 quad_list[] =
8376 {{-1.0f, -1.0f, 0.0f}, 0xffff0000},
8377 {{-1.0f, 1.0f, 0.0f}, 0xff00ff00},
8378 {{ 1.0f, -1.0f, 0.0f}, 0xff0000ff},
8380 {{ 1.0f, -1.0f, 0.0f}, 0xff0000ff},
8381 {{-1.0f, 1.0f, 0.0f}, 0xff00ff00},
8382 {{ 1.0f, 1.0f, 0.0f}, 0xffffffff},
8384 static const struct test_shader
8386 DWORD version;
8387 const DWORD *code;
8389 novs = {0, NULL},
8390 vs_1 = {D3DVS_VERSION(1, 1), vs1_code},
8391 nops = {0, NULL},
8392 ps_1 = {D3DPS_VERSION(1, 1), ps1_code};
8393 static const struct
8395 const struct test_shader *vs, *ps;
8396 DWORD primtype;
8397 DWORD shademode;
8398 DWORD color0, color1;
8400 tests[] =
8402 {&novs, &nops, D3DPT_TRIANGLESTRIP, D3DSHADE_FLAT, 0x00ff0000, 0x0000ff00},
8403 {&novs, &nops, D3DPT_TRIANGLESTRIP, D3DSHADE_PHONG, 0x000dca28, 0x000d45c7},
8404 {&novs, &nops, D3DPT_TRIANGLESTRIP, D3DSHADE_GOURAUD, 0x000dca28, 0x000d45c7},
8405 {&novs, &nops, D3DPT_TRIANGLESTRIP, D3DSHADE_PHONG, 0x000dca28, 0x000d45c7},
8406 {&novs, &nops, D3DPT_TRIANGLELIST, D3DSHADE_FLAT, 0x00ff0000, 0x000000ff},
8407 {&novs, &nops, D3DPT_TRIANGLELIST, D3DSHADE_GOURAUD, 0x000dca28, 0x000d45c7},
8408 {&vs_1, &ps_1, D3DPT_TRIANGLESTRIP, D3DSHADE_FLAT, 0x00ff0000, 0x0000ff00},
8409 {&vs_1, &ps_1, D3DPT_TRIANGLESTRIP, D3DSHADE_GOURAUD, 0x000dca28, 0x000d45c7},
8410 {&vs_1, &ps_1, D3DPT_TRIANGLELIST, D3DSHADE_FLAT, 0x00ff0000, 0x000000ff},
8411 {&vs_1, &ps_1, D3DPT_TRIANGLELIST, D3DSHADE_GOURAUD, 0x000dca28, 0x000d45c7},
8412 {&novs, &ps_1, D3DPT_TRIANGLESTRIP, D3DSHADE_FLAT, 0x00ff0000, 0x0000ff00},
8413 {&vs_1, &nops, D3DPT_TRIANGLESTRIP, D3DSHADE_FLAT, 0x00ff0000, 0x0000ff00},
8416 window = create_window();
8417 d3d = Direct3DCreate8(D3D_SDK_VERSION);
8418 ok(!!d3d, "Failed to create a D3D object.\n");
8419 if (!(device = create_device(d3d, window, window, TRUE)))
8421 skip("Failed to create a D3D device, skipping tests.\n");
8422 IDirect3D8_Release(d3d);
8423 DestroyWindow(window);
8424 return;
8427 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
8428 ok(hr == D3D_OK, "Failed to disable lighting, hr %#x.\n", hr);
8429 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
8430 ok(SUCCEEDED(hr), "Failed to disable fog, hr %#x.\n", hr);
8432 hr = IDirect3DDevice8_CreateVertexBuffer(device, sizeof(quad_strip), 0, 0, D3DPOOL_MANAGED, &vb_strip);
8433 ok(hr == D3D_OK, "Failed to create vertex buffer, hr %#x.\n", hr);
8434 hr = IDirect3DVertexBuffer8_Lock(vb_strip, 0, sizeof(quad_strip), &data, 0);
8435 ok(hr == D3D_OK, "Failed to lock vertex buffer, hr %#x.\n", hr);
8436 memcpy(data, quad_strip, sizeof(quad_strip));
8437 hr = IDirect3DVertexBuffer8_Unlock(vb_strip);
8438 ok(hr == D3D_OK, "Failed to unlock vertex buffer, hr %#x.\n", hr);
8440 hr = IDirect3DDevice8_CreateVertexBuffer(device, sizeof(quad_list), 0, 0, D3DPOOL_MANAGED, &vb_list);
8441 ok(hr == D3D_OK, "Failed to create vertex buffer, hr %#x.\n", hr);
8442 hr = IDirect3DVertexBuffer8_Lock(vb_list, 0, sizeof(quad_list), &data, 0);
8443 ok(hr == D3D_OK, "Failed to lock vertex buffer, hr %#x.\n", hr);
8444 memcpy(data, quad_list, sizeof(quad_list));
8445 hr = IDirect3DVertexBuffer8_Unlock(vb_list);
8446 ok(hr == D3D_OK, "Failed to unlock vertex buffer, hr %#x.\n", hr);
8448 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
8449 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
8451 /* Try it first with a TRIANGLESTRIP. Do it with different geometry because
8452 * the color fixups we have to do for FLAT shading will be dependent on that. */
8454 for (i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i)
8456 if (tests[i].vs->version)
8458 if (caps.VertexShaderVersion >= tests[i].vs->version)
8460 hr = IDirect3DDevice8_CreateVertexShader(device, decl, tests[i].vs->code, &vs, 0);
8461 ok(hr == D3D_OK, "Failed to create vertex shader, hr %#x.\n", hr);
8462 hr = IDirect3DDevice8_SetVertexShader(device, vs);
8463 ok(hr == D3D_OK, "Failed to set vertex shader, hr %#x.\n", hr);
8465 else
8467 skip("Shader version unsupported, skipping some tests.\n");
8468 continue;
8471 else
8473 vs = 0;
8474 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8475 ok(hr == D3D_OK, "Failed to set FVF, hr %#x.\n", hr);
8477 if (tests[i].ps->version)
8479 if (caps.PixelShaderVersion >= tests[i].ps->version)
8481 hr = IDirect3DDevice8_CreatePixelShader(device, tests[i].ps->code, &ps);
8482 ok(hr == D3D_OK, "Failed to create pixel shader, hr %#x.\n", hr);
8483 hr = IDirect3DDevice8_SetPixelShader(device, ps);
8484 ok(hr == D3D_OK, "Failed to set pixel shader, hr %#x.\n", hr);
8486 else
8488 skip("Shader version unsupported, skipping some tests.\n");
8489 if (vs)
8491 IDirect3DDevice8_SetVertexShader(device, 0);
8492 IDirect3DDevice8_DeleteVertexShader(device, vs);
8494 continue;
8497 else
8499 ps = 0;
8502 hr = IDirect3DDevice8_SetStreamSource(device, 0,
8503 tests[i].primtype == D3DPT_TRIANGLESTRIP ? vb_strip : vb_list, sizeof(quad_strip[0]));
8504 ok(hr == D3D_OK, "Failed to set stream source, hr %#x.\n", hr);
8506 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
8507 ok(hr == D3D_OK, "Failed to clear, hr %#x.\n", hr);
8509 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SHADEMODE, tests[i].shademode);
8510 ok(hr == D3D_OK, "Failed to set shade mode, hr %#x.\n", hr);
8512 hr = IDirect3DDevice8_BeginScene(device);
8513 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
8514 hr = IDirect3DDevice8_DrawPrimitive(device, tests[i].primtype, 0, 2);
8515 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8516 hr = IDirect3DDevice8_EndScene(device);
8517 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
8519 color0 = getPixelColor(device, 100, 100); /* Inside first triangle */
8520 color1 = getPixelColor(device, 500, 350); /* Inside second triangle */
8522 /* For D3DSHADE_FLAT it should take the color of the first vertex of
8523 * each triangle. This requires EXT_provoking_vertex or similar
8524 * functionality being available. */
8525 /* PHONG should be the same as GOURAUD, since no hardware implements
8526 * this. */
8527 ok(color_match(color0, tests[i].color0, 1), "Test %u shading has color0 %08x, expected %08x.\n",
8528 i, color0, tests[i].color0);
8529 ok(color_match(color1, tests[i].color1, 1), "Test %u shading has color1 %08x, expected %08x.\n",
8530 i, color1, tests[i].color1);
8532 IDirect3DDevice8_SetVertexShader(device, 0);
8533 IDirect3DDevice8_SetPixelShader(device, 0);
8535 if (ps)
8536 IDirect3DDevice8_DeletePixelShader(device, ps);
8537 if (vs)
8538 IDirect3DDevice8_DeleteVertexShader(device, vs);
8541 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
8542 ok(hr == D3D_OK, "Failed to present, hr %#x.\n", hr);
8544 IDirect3DVertexBuffer8_Release(vb_strip);
8545 IDirect3DVertexBuffer8_Release(vb_list);
8546 refcount = IDirect3DDevice8_Release(device);
8547 ok(!refcount, "Device has %u references left.\n", refcount);
8548 IDirect3D8_Release(d3d);
8549 DestroyWindow(window);
8552 static void test_multisample_init(void)
8554 IDirect3DDevice8 *device;
8555 IDirect3D8 *d3d;
8556 IDirect3DSurface8 *back, *multi;
8557 ULONG refcount;
8558 HWND window;
8559 HRESULT hr;
8560 D3DCOLOR color;
8561 unsigned int x, y;
8562 struct surface_readback rb;
8563 BOOL all_zero = TRUE;
8565 window = create_window();
8566 d3d = Direct3DCreate8(D3D_SDK_VERSION);
8567 ok(!!d3d, "Failed to create a D3D object.\n");
8569 if (FAILED(IDirect3D8_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
8570 D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES)))
8572 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping multisample init test.\n");
8573 goto done;
8576 if (!(device = create_device(d3d, window, window, TRUE)))
8578 skip("Failed to create a D3D device, skipping tests.\n");
8579 goto done;
8582 hr = IDirect3DDevice8_GetBackBuffer(device, 0, D3DBACKBUFFER_TYPE_MONO, &back);
8583 ok(SUCCEEDED(hr), "Failed to get back buffer, hr %#x.\n", hr);
8584 hr = IDirect3DDevice8_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
8585 D3DMULTISAMPLE_2_SAMPLES, FALSE, &multi);
8586 ok(SUCCEEDED(hr), "Failed to create multisampled render target, hr %#x.\n", hr);
8588 hr = IDirect3DDevice8_CopyRects(device, multi, NULL, 0, back, NULL);
8589 ok(SUCCEEDED(hr), "CopyRects failed, hr %#x.\n", hr);
8591 get_rt_readback(back, &rb);
8592 for (y = 0; y < 480; ++y)
8594 for (x = 0; x < 640; ++x)
8596 color = get_readback_color(&rb, x, y);
8597 if (!color_match(color, 0x00000000, 0))
8599 all_zero = FALSE;
8600 break;
8603 if (!all_zero)
8604 break;
8606 release_surface_readback(&rb);
8607 ok(all_zero, "Got unexpected color 0x%08x, position %ux%u.\n", color, x, y);
8609 IDirect3DSurface8_Release(multi);
8610 IDirect3DSurface8_Release(back);
8612 refcount = IDirect3DDevice8_Release(device);
8613 ok(!refcount, "Device has %u references left.\n", refcount);
8615 done:
8616 IDirect3D8_Release(d3d);
8617 DestroyWindow(window);
8620 static void test_texture_blending(void)
8622 #define STATE_END() {0xffffffff, 0xffffffff}
8623 #define IS_STATE_END(s) (s.name == 0xffffffff && s.value == 0xffffffff)
8625 IDirect3DTexture8 *texture_bumpmap, *texture_red;
8626 IDirect3DSurface8 *backbuffer;
8627 struct surface_readback rb;
8628 D3DLOCKED_RECT locked_rect;
8629 IDirect3DDevice8 *device;
8630 unsigned int i, j, k;
8631 IDirect3D8 *d3d;
8632 D3DCOLOR color;
8633 ULONG refcount;
8634 D3DCAPS8 caps;
8635 HWND window;
8636 HRESULT hr;
8638 static const struct
8640 struct vec3 position;
8641 DWORD diffuse;
8643 quad[] =
8645 {{-1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0x80, 0xff, 0xff, 0x02)},
8646 {{-1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0x80, 0xff, 0xff, 0x02)},
8647 {{ 1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0x80, 0xff, 0xff, 0x02)},
8648 {{ 1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0x80, 0xff, 0xff, 0x02)},
8651 static const float bumpenvmat[4] = {1.0f, 1.0f, 0.0f, 0.0f};
8653 struct texture_stage_state
8655 D3DTEXTURESTAGESTATETYPE name;
8656 DWORD value;
8659 struct texture_stage
8661 enum
8663 TEXTURE_INVALID,
8664 TEXTURE_NONE,
8665 TEXTURE_BUMPMAP,
8666 TEXTURE_RED,
8668 texture;
8669 struct texture_stage_state state[20];
8672 static const struct texture_stage default_stage_state =
8674 TEXTURE_NONE,
8676 {D3DTSS_COLOROP, D3DTOP_DISABLE},
8677 {D3DTSS_COLORARG1, D3DTA_TEXTURE},
8678 {D3DTSS_COLORARG2, D3DTA_CURRENT},
8679 {D3DTSS_ALPHAOP, D3DTOP_DISABLE},
8680 {D3DTSS_ALPHAARG1, D3DTA_TEXTURE},
8681 {D3DTSS_ALPHAARG2, D3DTA_CURRENT},
8682 {D3DTSS_BUMPENVMAT00, 0},
8683 {D3DTSS_BUMPENVMAT01, 0},
8684 {D3DTSS_BUMPENVMAT10, 0},
8685 {D3DTSS_BUMPENVMAT11, 0},
8686 {D3DTSS_BUMPENVLSCALE, 0},
8687 {D3DTSS_BUMPENVLOFFSET, 0},
8688 {D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE},
8689 {D3DTSS_COLORARG0, D3DTA_CURRENT},
8690 {D3DTSS_ALPHAARG0, D3DTA_CURRENT},
8691 {D3DTSS_RESULTARG, D3DTA_CURRENT},
8692 STATE_END(),
8696 const struct test
8698 DWORD tex_op_caps;
8699 D3DCOLOR expected_color;
8700 struct texture_stage stage[8];
8702 tests[] =
8705 D3DTEXOPCAPS_DISABLE,
8706 0x80ffff02,
8709 TEXTURE_NONE,
8711 STATE_END(),
8717 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1,
8718 0x80ffff02,
8721 TEXTURE_NONE,
8723 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
8724 {D3DTSS_COLORARG1, D3DTA_CURRENT},
8725 STATE_END(),
8728 {TEXTURE_INVALID}
8732 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1,
8733 0x80ffff02,
8736 TEXTURE_NONE,
8738 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
8739 {D3DTSS_COLORARG1, D3DTA_CURRENT},
8740 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
8741 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
8742 STATE_END(),
8748 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1,
8749 0x80ffff02,
8752 TEXTURE_NONE,
8754 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
8755 {D3DTSS_COLORARG1, D3DTA_DIFFUSE},
8756 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
8757 {D3DTSS_ALPHAARG1, D3DTA_DIFFUSE},
8758 STATE_END(),
8764 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1,
8765 0x00000000,
8768 TEXTURE_NONE,
8770 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
8771 {D3DTSS_COLORARG1, D3DTA_TEMP},
8772 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
8773 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
8774 STATE_END(),
8781 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE,
8782 0x80ff0000,
8785 TEXTURE_BUMPMAP,
8787 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
8788 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
8789 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
8790 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
8791 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
8792 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
8793 {D3DTSS_ALPHAARG1, D3DTA_TEXTURE},
8794 STATE_END(),
8799 TEXTURE_RED,
8801 {D3DTSS_COLOROP, D3DTOP_MODULATE},
8802 STATE_END(),
8805 {TEXTURE_INVALID}
8809 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE,
8810 0x80ff0000,
8813 TEXTURE_BUMPMAP,
8815 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
8816 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
8817 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
8818 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
8819 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
8820 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
8821 {D3DTSS_ALPHAARG1, D3DTA_DIFFUSE},
8822 STATE_END(),
8826 TEXTURE_RED,
8828 {D3DTSS_COLOROP, D3DTOP_MODULATE},
8829 STATE_END(),
8832 {TEXTURE_INVALID}
8836 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE,
8837 0x80ff0000,
8840 TEXTURE_BUMPMAP,
8842 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
8843 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
8844 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
8845 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
8846 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
8847 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
8848 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
8849 STATE_END(),
8853 TEXTURE_RED,
8855 {D3DTSS_COLOROP, D3DTOP_MODULATE},
8856 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
8857 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
8858 STATE_END(),
8861 {TEXTURE_INVALID}
8865 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE,
8866 0x00ff0000,
8869 TEXTURE_BUMPMAP,
8871 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
8872 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
8873 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
8874 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
8875 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
8876 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
8877 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
8878 STATE_END(),
8882 TEXTURE_RED,
8884 {D3DTSS_COLOROP, D3DTOP_MODULATE},
8885 {D3DTSS_COLORARG1, D3DTA_TEXTURE},
8886 {D3DTSS_COLORARG2, D3DTA_CURRENT},
8887 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
8888 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
8889 STATE_END(),
8892 {TEXTURE_INVALID}
8896 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE,
8897 0x80ff0000,
8900 TEXTURE_BUMPMAP,
8902 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
8903 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
8904 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
8905 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
8906 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
8907 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
8908 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
8909 STATE_END(),
8913 TEXTURE_RED,
8915 {D3DTSS_COLOROP, D3DTOP_MODULATE},
8916 {D3DTSS_COLORARG1, D3DTA_TEXTURE},
8917 {D3DTSS_COLORARG2, D3DTA_CURRENT},
8918 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
8919 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
8920 STATE_END(),
8923 {TEXTURE_INVALID}
8928 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE
8929 | D3DTEXOPCAPS_ADD,
8930 0x80ff0000,
8933 TEXTURE_BUMPMAP,
8935 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
8936 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
8937 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
8938 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
8939 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
8940 {D3DTSS_ALPHAOP, D3DTOP_ADD},
8941 {D3DTSS_ALPHAARG1, D3DTA_DIFFUSE},
8942 {D3DTSS_ALPHAARG2, D3DTA_CURRENT},
8943 STATE_END(),
8947 TEXTURE_RED,
8949 {D3DTSS_COLOROP, D3DTOP_MODULATE},
8950 {D3DTSS_COLORARG1, D3DTA_TEXTURE},
8951 {D3DTSS_COLORARG2, D3DTA_CURRENT},
8952 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
8953 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
8954 STATE_END(),
8957 {TEXTURE_INVALID}
8961 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE
8962 | D3DTEXOPCAPS_MODULATE2X,
8963 0x80ffff00,
8966 TEXTURE_BUMPMAP,
8968 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
8969 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
8970 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
8971 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
8972 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
8973 {D3DTSS_ALPHAOP, D3DTOP_MODULATE2X},
8974 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
8975 {D3DTSS_ALPHAARG2, D3DTA_DIFFUSE},
8976 STATE_END(),
8980 TEXTURE_RED,
8982 {D3DTSS_COLOROP, D3DTOP_MODULATE},
8983 {D3DTSS_COLORARG1, D3DTA_CURRENT},
8984 {D3DTSS_COLORARG2, D3DTA_CURRENT},
8985 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
8986 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
8987 STATE_END(),
8990 {TEXTURE_INVALID}
8994 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP,
8995 0x80ffff02,
8998 TEXTURE_NONE,
9000 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
9001 {D3DTSS_COLORARG1, D3DTA_DIFFUSE},
9002 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
9003 {D3DTSS_ALPHAARG1, D3DTA_DIFFUSE},
9004 {D3DTSS_RESULTARG, D3DTA_TEMP},
9005 STATE_END(),
9009 TEXTURE_BUMPMAP,
9011 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
9012 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
9013 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
9014 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
9015 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
9016 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
9017 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
9018 {D3DTSS_RESULTARG, D3DTA_TEMP},
9019 STATE_END(),
9023 TEXTURE_RED,
9025 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
9026 {D3DTSS_COLORARG1, D3DTA_TEXTURE},
9027 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
9028 {D3DTSS_ALPHAARG1, D3DTA_TEXTURE},
9029 STATE_END(),
9033 TEXTURE_NONE,
9035 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
9036 {D3DTSS_COLORARG1, D3DTA_TEMP},
9037 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
9038 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
9039 STATE_END(),
9042 {TEXTURE_INVALID}
9047 window = create_window();
9048 d3d = Direct3DCreate8(D3D_SDK_VERSION);
9049 ok(!!d3d, "Failed to create a D3D object.\n");
9050 if (!(device = create_device(d3d, window, window, TRUE)))
9052 skip("Failed to create a D3D device.\n");
9053 goto done;
9056 memset(&caps, 0, sizeof(caps));
9057 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
9058 ok(hr == D3D_OK, "IDirect3DDevice8_GetDeviceCaps failed hr %#x.\n", hr);
9060 if(!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP))
9062 skip("D3DPMISCCAPS_TSSARGTEMP not supported.\n");
9063 IDirect3DDevice8_Release(device);
9064 goto done;
9067 if (FAILED(IDirect3D8_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
9068 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_V8U8)))
9070 skip("D3DFMT_V8U8 not supported for legacy bump mapping.\n");
9071 IDirect3DDevice8_Release(device);
9072 goto done;
9075 hr = IDirect3DDevice8_GetBackBuffer(device, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9076 ok(hr == D3D_OK, "Can't get back buffer, hr %#x.\n", hr);
9078 hr = IDirect3DDevice8_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture_bumpmap);
9079 ok(hr == D3D_OK, "IDirect3DDevice8_CreateTexture failed, hr %#x.\n", hr);
9080 hr = IDirect3DDevice8_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture_red);
9081 ok(hr == D3D_OK, "IDirect3DDevice8_CreateTexture failed, hr %#x.\n", hr);
9083 memset(&locked_rect, 0, sizeof(locked_rect));
9084 hr = IDirect3DTexture8_LockRect(texture_bumpmap, 0, &locked_rect, NULL, 0);
9085 ok(SUCCEEDED(hr), "LockRect failed, hr %#x.\n", hr);
9086 *((WORD *)locked_rect.pBits) = 0xff00;
9087 hr = IDirect3DTexture8_UnlockRect(texture_bumpmap, 0);
9088 ok(SUCCEEDED(hr), "UnlockRect failed, hr %#x.\n", hr);
9090 memset(&locked_rect, 0, sizeof(locked_rect));
9091 hr = IDirect3DTexture8_LockRect(texture_red, 0, &locked_rect, NULL, 0);
9092 ok(SUCCEEDED(hr), "LockRect failed, hr %#x.\n", hr);
9093 *((DWORD *)locked_rect.pBits) = 0x00ff0000;
9094 hr = IDirect3DTexture8_UnlockRect(texture_red, 0);
9095 ok(SUCCEEDED(hr), "UnlockRect failed, hr %#x.\n", hr);
9097 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9098 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
9099 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9100 ok(hr == D3D_OK, "Failed to disable lighting, hr %#x.\n", hr);
9102 for (i = 0; i < sizeof(tests) / sizeof(*tests); ++i)
9104 const struct test *current_test = &tests[i];
9106 if ((caps.TextureOpCaps & current_test->tex_op_caps) != current_test->tex_op_caps)
9108 skip("Texture operations %#x not supported.\n", current_test->tex_op_caps);
9109 continue;
9112 for (j = 0; j < caps.MaxTextureBlendStages; ++j)
9114 IDirect3DTexture8 *current_texture = NULL;
9116 for (k = 0; !IS_STATE_END(default_stage_state.state[k]); ++k)
9118 hr = IDirect3DDevice8_SetTextureStageState(device, j,
9119 default_stage_state.state[k].name, default_stage_state.state[k].value);
9120 ok(SUCCEEDED(hr), "Test %u: SetTextureStageState failed, hr %#x.\n", i, hr);
9123 if (current_test->stage[j].texture != TEXTURE_INVALID)
9125 const struct texture_stage_state *current_state = current_test->stage[j].state;
9127 switch (current_test->stage[j].texture)
9129 case TEXTURE_RED:
9130 current_texture = texture_red;
9131 break;
9132 case TEXTURE_BUMPMAP:
9133 current_texture = texture_bumpmap;
9134 break;
9135 default:
9136 current_texture = NULL;
9137 break;
9140 for (k = 0; !IS_STATE_END(current_state[k]); ++k)
9142 hr = IDirect3DDevice8_SetTextureStageState(device, j,
9143 current_state[k].name, current_state[k].value);
9144 ok(SUCCEEDED(hr), "Test %u: SetTextureStageState failed, hr %#x.\n", i, hr);
9148 hr = IDirect3DDevice8_SetTexture(device, j, (IDirect3DBaseTexture8 *)current_texture);
9149 ok(SUCCEEDED(hr), "Test %u: SetTexture failed, hr %#x.\n", i, hr);
9152 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
9153 ok(hr == D3D_OK, "Test %u: IDirect3DDevice8_Clear failed, hr %#x.\n", i, hr);
9155 hr = IDirect3DDevice8_BeginScene(device);
9156 ok(SUCCEEDED(hr), "Test %u: BeginScene failed, hr %#x.\n", i, hr);
9157 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
9158 ok(SUCCEEDED(hr), "Test %u: DrawPrimitiveUP failed, hr %#x.\n", i, hr);
9159 hr = IDirect3DDevice8_EndScene(device);
9160 ok(SUCCEEDED(hr), "Test %u: EndScene failed, hr %#x.\n", i, hr);
9162 get_rt_readback(backbuffer, &rb);
9163 color = get_readback_color(&rb, 320, 240);
9164 ok(color_match(color, current_test->expected_color, 1),
9165 "Test %u: Got color 0x%08x, expected 0x%08x.\n", i, color, current_test->expected_color);
9166 release_surface_readback(&rb);
9167 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
9168 ok(SUCCEEDED(hr), "Test %u: Present failed, hr %#x.\n", i, hr);
9171 IDirect3DTexture8_Release(texture_bumpmap);
9172 IDirect3DTexture8_Release(texture_red);
9173 IDirect3DSurface8_Release(backbuffer);
9174 refcount = IDirect3DDevice8_Release(device);
9175 ok(!refcount, "Device has %u references left.\n", refcount);
9176 done:
9177 IDirect3D8_Release(d3d);
9178 DestroyWindow(window);
9181 static void test_color_clamping(void)
9183 static const D3DMATRIX mat =
9185 1.0f, 0.0f, 0.0f, 0.0f,
9186 0.0f, 1.0f, 0.0f, 0.0f,
9187 0.0f, 0.0f, 1.0f, 0.0f,
9188 0.0f, 0.0f, 0.0f, 1.0f,
9189 }}};
9190 static const struct vec3 quad[] =
9192 {-1.0f, -1.0f, 0.1f},
9193 {-1.0f, 1.0f, 0.1f},
9194 { 1.0f, -1.0f, 0.1f},
9195 { 1.0f, 1.0f, 0.1f},
9197 static const DWORD decl[] =
9199 D3DVSD_STREAM(0),
9200 D3DVSD_REG(D3DVSDE_POSITION, D3DVSDT_FLOAT3),
9201 D3DVSD_CONST(0, 1), 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c0, 1.0, 1.0, 1.0, 1.0 */
9202 D3DVSD_END()
9204 static const DWORD vs1_code[] =
9206 0xfffe0101, /* vs_1_1 */
9207 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
9208 0x00000002, 0xd00f0000, 0xa0e40000, 0xa0e40000, /* add oD0, c0, c0 */
9209 0x00000002, 0xd00f0001, 0xa0e40000, 0xa0e40000, /* add oD1, c0, c0 */
9210 0x0000ffff
9212 static const DWORD ps1_code[] =
9214 0xffff0101, /* ps_1_1 */
9215 0x00000051, 0xa00f0000, 0x3e800000, 0x3e800000, 0x3e800000, 0x3e800000, /* def c0, 0.25, 0.25, 0.25, 0.25 */
9216 0x00000002, 0x800f0000, 0x90e40000, 0x90e40001, /* add r0, v0, v1 */
9217 0x00000005, 0x800f0000, 0x80e40000, 0xa0e40000, /* mul r0, r0, c0 */
9218 0x0000ffff
9220 static const struct
9222 DWORD vs_version;
9223 const DWORD *vs;
9224 DWORD ps_version;
9225 const DWORD *ps;
9226 D3DCOLOR expected, broken;
9228 tests[] =
9230 {0, NULL, 0, NULL, 0x00404040},
9231 {0, NULL, D3DPS_VERSION(1, 1), ps1_code, 0x00404040, 0x00808080},
9232 {D3DVS_VERSION(1, 1), vs1_code, 0, NULL, 0x00404040},
9233 {D3DVS_VERSION(1, 1), vs1_code, D3DPS_VERSION(1, 1), ps1_code, 0x007f7f7f},
9235 IDirect3DDevice8 *device;
9236 IDirect3D8 *d3d;
9237 unsigned int i;
9238 ULONG refcount;
9239 D3DCOLOR color;
9240 D3DCAPS8 caps;
9241 DWORD vs, ps;
9242 HWND window;
9243 HRESULT hr;
9245 window = create_window();
9246 d3d = Direct3DCreate8(D3D_SDK_VERSION);
9247 ok(!!d3d, "Failed to create a D3D object.\n");
9248 if (!(device = create_device(d3d, window, window, TRUE)))
9250 skip("Failed to create a D3D device, skipping tests.\n");
9251 IDirect3D8_Release(d3d);
9252 DestroyWindow(window);
9253 return;
9256 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
9257 ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
9259 hr = IDirect3DDevice8_SetTransform(device, D3DTS_WORLD, &mat);
9260 ok(SUCCEEDED(hr), "Failed to set world transform, hr %#x.\n", hr);
9261 hr = IDirect3DDevice8_SetTransform(device, D3DTS_VIEW, &mat);
9262 ok(SUCCEEDED(hr), "Failed to set view transform, hr %#x.\n", hr);
9263 hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, &mat);
9264 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
9265 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, FALSE);
9266 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#x.\n", hr);
9267 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, FALSE);
9268 ok(SUCCEEDED(hr), "Failed to disable Z test, hr %#x.\n", hr);
9269 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
9270 ok(SUCCEEDED(hr), "Failed to disable fog, hr %#x.\n", hr);
9271 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
9272 ok(SUCCEEDED(hr), "Failed to disable stencil test, hr %#x.\n", hr);
9273 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
9274 ok(SUCCEEDED(hr), "Failed to disable culling, hr %#x.\n", hr);
9275 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9276 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
9278 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xff404040);
9279 ok(SUCCEEDED(hr), "Failed to set texture factor, hr %#x.\n", hr);
9280 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
9281 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
9282 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9283 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
9284 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_SPECULAR);
9285 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
9286 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_MODULATE);
9287 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
9288 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TFACTOR);
9289 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
9290 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
9291 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
9293 for (i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i)
9295 if (caps.VertexShaderVersion < tests[i].vs_version
9296 || caps.PixelShaderVersion < tests[i].ps_version)
9298 skip("Vertex / pixel shader version not supported, skipping test %u.\n", i);
9299 continue;
9301 if (tests[i].vs)
9303 hr = IDirect3DDevice8_CreateVertexShader(device, decl, tests[i].vs, &vs, 0);
9304 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x (case %u).\n", hr, i);
9306 else
9308 vs = D3DFVF_XYZ;
9310 if (tests[i].ps)
9312 hr = IDirect3DDevice8_CreatePixelShader(device, tests[i].ps, &ps);
9313 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x (case %u).\n", hr, i);
9315 else
9317 ps = 0;
9320 hr = IDirect3DDevice8_SetVertexShader(device, vs);
9321 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
9322 hr = IDirect3DDevice8_SetPixelShader(device, ps);
9323 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
9325 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0f, 0);
9326 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
9328 hr = IDirect3DDevice8_BeginScene(device);
9329 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9331 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
9332 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9334 hr = IDirect3DDevice8_EndScene(device);
9335 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9337 color = getPixelColor(device, 320, 240);
9338 ok(color_match(color, tests[i].expected, 1) || broken(color_match(color, tests[i].broken, 1)),
9339 "Got unexpected color 0x%08x, case %u.\n", color, i);
9341 if (vs != D3DFVF_XYZ)
9342 IDirect3DDevice8_DeleteVertexShader(device, vs);
9343 if (ps)
9344 IDirect3DDevice8_DeletePixelShader(device, ps);
9347 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
9348 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
9350 refcount = IDirect3DDevice8_Release(device);
9351 ok(!refcount, "Device has %u references left.\n", refcount);
9352 IDirect3D8_Release(d3d);
9353 DestroyWindow(window);
9356 static void test_edge_antialiasing_blending(void)
9358 IDirect3DDevice8 *device;
9359 IDirect3D8 *d3d8;
9360 ULONG refcount;
9361 D3DCOLOR color;
9362 D3DCAPS8 caps;
9363 HWND window;
9364 HRESULT hr;
9366 static const struct
9368 struct vec3 position;
9369 DWORD diffuse;
9371 green_quad[] =
9373 {{-1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0x7f, 0x00, 0xff, 0x00)},
9374 {{-1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0x7f, 0x00, 0xff, 0x00)},
9375 {{ 1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0x7f, 0x00, 0xff, 0x00)},
9376 {{ 1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0x7f, 0x00, 0xff, 0x00)},
9378 static const struct
9380 struct vec3 position;
9381 DWORD diffuse;
9383 red_quad[] =
9385 {{-1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0xcc, 0xff, 0x00, 0x00)},
9386 {{-1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0xcc, 0xff, 0x00, 0x00)},
9387 {{ 1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0xcc, 0xff, 0x00, 0x00)},
9388 {{ 1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0xcc, 0xff, 0x00, 0x00)},
9391 window = create_window();
9392 d3d8 = Direct3DCreate8(D3D_SDK_VERSION);
9393 ok(!!d3d8, "Failed to create a D3D object.\n");
9394 if (!(device = create_device(d3d8, window, window, TRUE)))
9396 skip("Failed to create a D3D device.\n");
9397 IDirect3D8_Release(d3d8);
9398 DestroyWindow(window);
9399 return;
9402 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
9403 ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
9404 trace("Edge antialiasing support: %#x.\n", caps.RasterCaps & D3DPRASTERCAPS_ANTIALIASEDGES);
9406 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, FALSE);
9407 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#x.\n", hr);
9408 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, FALSE);
9409 ok(SUCCEEDED(hr), "Failed to disable Z test, hr %#x.\n", hr);
9410 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9411 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
9413 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
9414 ok(SUCCEEDED(hr), "Failed to enable blending, hr %#x.\n", hr);
9415 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_BLENDOP, D3DBLENDOP_ADD);
9416 ok(SUCCEEDED(hr), "Failed to set blend op, hr %#x.\n", hr);
9417 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
9418 ok(SUCCEEDED(hr), "Failed to set src blend, hr %#x.\n", hr);
9419 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_DESTALPHA);
9420 ok(SUCCEEDED(hr), "Failed to set dest blend, hr %#x.\n", hr);
9422 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9423 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
9424 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9425 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
9426 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
9427 ok(SUCCEEDED(hr), "Failed to set alpha op, hr %#x.\n", hr);
9428 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
9429 ok(SUCCEEDED(hr), "Failed to set alpha arg, hr %#x.\n", hr);
9431 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9432 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
9434 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xccff0000, 0.0f, 0);
9435 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
9436 hr = IDirect3DDevice8_BeginScene(device);
9437 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9438 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, green_quad, sizeof(*green_quad));
9439 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9440 hr = IDirect3DDevice8_EndScene(device);
9441 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9442 color = getPixelColor(device, 320, 240);
9443 ok(color_match(color, 0x00cc7f00, 1), "Got unexpected color 0x%08x.\n", color);
9445 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x7f00ff00, 0.0f, 0);
9446 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
9447 hr = IDirect3DDevice8_BeginScene(device);
9448 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9449 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, red_quad, sizeof(*red_quad));
9450 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9451 hr = IDirect3DDevice8_EndScene(device);
9452 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9453 color = getPixelColor(device, 320, 240);
9454 ok(color_match(color, 0x00cc7f00, 1), "Got unexpected color 0x%08x.\n", color);
9456 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
9457 ok(SUCCEEDED(hr), "Failed to disable blending, hr %#x.\n", hr);
9459 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xccff0000, 0.0f, 0);
9460 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
9461 hr = IDirect3DDevice8_BeginScene(device);
9462 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9463 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, green_quad, sizeof(*green_quad));
9464 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9465 hr = IDirect3DDevice8_EndScene(device);
9466 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9467 color = getPixelColor(device, 320, 240);
9468 ok(color_match(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
9470 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x7f00ff00, 0.0f, 0);
9471 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
9472 hr = IDirect3DDevice8_BeginScene(device);
9473 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9474 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, red_quad, sizeof(*red_quad));
9475 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9476 hr = IDirect3DDevice8_EndScene(device);
9477 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9478 color = getPixelColor(device, 320, 240);
9479 ok(color_match(color, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color);
9481 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_EDGEANTIALIAS, TRUE);
9482 ok(SUCCEEDED(hr), "Failed to enable edge antialiasing, hr %#x.\n", hr);
9484 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xccff0000, 0.0f, 0);
9485 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
9486 hr = IDirect3DDevice8_BeginScene(device);
9487 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9488 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, green_quad, sizeof(*green_quad));
9489 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9490 hr = IDirect3DDevice8_EndScene(device);
9491 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9492 color = getPixelColor(device, 320, 240);
9493 ok(color_match(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
9495 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x7f00ff00, 0.0f, 0);
9496 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
9497 hr = IDirect3DDevice8_BeginScene(device);
9498 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9499 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, red_quad, sizeof(*red_quad));
9500 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9501 hr = IDirect3DDevice8_EndScene(device);
9502 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9503 color = getPixelColor(device, 320, 240);
9504 ok(color_match(color, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color);
9506 refcount = IDirect3DDevice8_Release(device);
9507 ok(!refcount, "Device has %u references left.\n", refcount);
9508 IDirect3D8_Release(d3d8);
9509 DestroyWindow(window);
9512 /* This test shows that 0xffff is valid index in D3D8. */
9513 static void test_max_index16(void)
9515 static const struct vertex
9517 struct vec3 position;
9518 DWORD diffuse;
9520 green_quad[] =
9522 {{-1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
9523 {{-1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
9524 {{ 1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
9525 {{ 1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
9527 static const unsigned short indices[] = {0, 1, 2, 0xffff};
9528 static const unsigned int vertex_count = 0xffff + 1;
9530 D3DADAPTER_IDENTIFIER8 identifier;
9531 IDirect3DVertexBuffer8 *vb;
9532 IDirect3DIndexBuffer8 *ib;
9533 IDirect3DDevice8 *device;
9534 struct vertex *vb_data;
9535 IDirect3D8 *d3d8;
9536 ULONG refcount;
9537 D3DCOLOR color;
9538 D3DCAPS8 caps;
9539 HWND window;
9540 BYTE *data;
9541 HRESULT hr;
9542 BOOL warp;
9544 window = create_window();
9545 d3d8 = Direct3DCreate8(D3D_SDK_VERSION);
9546 ok(!!d3d8, "Failed to create a D3D object.\n");
9548 hr = IDirect3D8_GetAdapterIdentifier(d3d8, D3DADAPTER_DEFAULT, 0, &identifier);
9549 ok(SUCCEEDED(hr), "Failed to get adapter identifier, hr %#x.\n", hr);
9550 warp = adapter_is_warp(&identifier);
9552 if (!(device = create_device(d3d8, window, window, TRUE)))
9554 skip("Failed to create a D3D device.\n");
9555 IDirect3D8_Release(d3d8);
9556 DestroyWindow(window);
9557 return;
9560 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
9561 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
9562 if (caps.MaxVertexIndex < 0xffff)
9564 skip("Max vertex index is lower than 0xffff (%#x).\n", caps.MaxVertexIndex);
9565 IDirect3DDevice8_Release(device);
9566 IDirect3D8_Release(d3d8);
9567 DestroyWindow(window);
9568 return;
9571 hr = IDirect3DDevice8_CreateVertexBuffer(device, vertex_count * sizeof(*green_quad), 0,
9572 D3DFVF_XYZ | D3DFVF_DIFFUSE, D3DPOOL_MANAGED, &vb);
9573 ok(SUCCEEDED(hr), "Failed to create vertex buffer, hr %#x.\n", hr);
9575 hr = IDirect3DDevice8_CreateIndexBuffer(device, sizeof(indices), 0,
9576 D3DFMT_INDEX16, D3DPOOL_MANAGED, &ib);
9577 ok(SUCCEEDED(hr), "Failed to create index buffer, hr %#x.\n", hr);
9579 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, FALSE);
9580 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#x.\n", hr);
9581 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, FALSE);
9582 ok(SUCCEEDED(hr), "Failed to disable Z test, hr %#x.\n", hr);
9583 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9584 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
9586 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9587 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
9589 hr = IDirect3DVertexBuffer8_Lock(vb, 0, sizeof(green_quad), (BYTE **)&vb_data, 0);
9590 ok(hr == D3D_OK, "Failed to lock vertex buffer, hr %#x.\n", hr);
9591 vb_data[0] = green_quad[0];
9592 vb_data[1] = green_quad[1];
9593 vb_data[2] = green_quad[2];
9594 vb_data[0xffff] = green_quad[3];
9595 hr = IDirect3DVertexBuffer8_Unlock(vb);
9596 ok(hr == D3D_OK, "Failed to unlock vertex buffer, hr %#x.\n", hr);
9598 hr = IDirect3DIndexBuffer8_Lock(ib, 0, sizeof(indices), &data, 0);
9599 ok(hr == D3D_OK, "Failed to lock index buffer, hr %#x.\n", hr);
9600 memcpy(data, indices, sizeof(indices));
9601 hr = IDirect3DIndexBuffer8_Unlock(ib);
9602 ok(hr == D3D_OK, "Failed to unlock index buffer, hr %#x.\n", hr);
9604 hr = IDirect3DDevice8_SetIndices(device, ib, 0);
9605 ok(hr == D3D_OK, "Failed to set index buffer, hr %#x.\n", hr);
9606 hr = IDirect3DDevice8_SetStreamSource(device, 0, vb, sizeof(struct vertex));
9607 ok(hr == D3D_OK, "Failed to set stream source, hr %#x.\n", hr);
9609 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
9610 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
9611 hr = IDirect3DDevice8_BeginScene(device);
9612 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9613 hr = IDirect3DDevice8_DrawIndexedPrimitive(device, D3DPT_TRIANGLESTRIP, 0, vertex_count, 0, 2);
9614 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9615 hr = IDirect3DDevice8_EndScene(device);
9616 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9617 color = getPixelColor(device, 20, 20);
9618 ok(color_match(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
9619 color = getPixelColor(device, 320, 240);
9620 ok(color_match(color, 0x0000ff00, 1) || broken(warp), "Got unexpected color 0x%08x.\n", color);
9621 color = getPixelColor(device, 620, 460);
9622 ok(color_match(color, 0x0000ff00, 1) || broken(warp), "Got unexpected color 0x%08x.\n", color);
9624 IDirect3DIndexBuffer8_Release(ib);
9625 IDirect3DVertexBuffer8_Release(vb);
9626 refcount = IDirect3DDevice8_Release(device);
9627 ok(!refcount, "Device has %u references left.\n", refcount);
9628 IDirect3D8_Release(d3d8);
9629 DestroyWindow(window);
9632 static void test_backbuffer_resize(void)
9634 D3DPRESENT_PARAMETERS present_parameters = {0};
9635 IDirect3DSurface8 *backbuffer;
9636 IDirect3DDevice8 *device;
9637 IDirect3D8 *d3d;
9638 D3DCOLOR color;
9639 ULONG refcount;
9640 HWND window;
9641 HRESULT hr;
9643 static const struct
9645 struct vec3 position;
9646 DWORD diffuse;
9648 quad[] =
9650 {{-1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
9651 {{-1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
9652 {{ 1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
9653 {{ 1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
9656 window = create_window();
9657 d3d = Direct3DCreate8(D3D_SDK_VERSION);
9658 ok(!!d3d, "Failed to create a D3D object.\n");
9659 if (!(device = create_device(d3d, window, window, TRUE)))
9661 skip("Failed to create a D3D device.\n");
9662 goto done;
9665 /* Wine d3d8 implementation had a bug which was triggered by a
9666 * SetRenderTarget() call with an unreferenced surface. */
9667 hr = IDirect3DDevice8_GetBackBuffer(device, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9668 ok(SUCCEEDED(hr), "Failed to get backbuffer, hr %#x.\n", hr);
9669 refcount = IDirect3DSurface8_Release(backbuffer);
9670 ok(!refcount, "Surface has %u references left.\n", refcount);
9671 hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, NULL);
9672 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
9673 hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, NULL);
9674 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
9676 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 1.0f, 0);
9677 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
9678 color = getPixelColor(device, 1, 1);
9679 ok(color == 0x00ff0000, "Got unexpected color 0x%08x.\n", color);
9681 present_parameters.BackBufferWidth = 800;
9682 present_parameters.BackBufferHeight = 600;
9683 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
9684 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
9685 present_parameters.hDeviceWindow = NULL;
9686 present_parameters.Windowed = TRUE;
9687 present_parameters.EnableAutoDepthStencil = TRUE;
9688 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
9689 hr = IDirect3DDevice8_Reset(device, &present_parameters);
9690 ok(SUCCEEDED(hr), "Failed to reset, hr %#x.\n", hr);
9692 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, FALSE);
9693 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#x.\n", hr);
9694 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, FALSE);
9695 ok(SUCCEEDED(hr), "Failed to disable Z test, hr %#x.\n", hr);
9696 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9697 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
9698 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9699 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
9701 hr = IDirect3DDevice8_GetBackBuffer(device, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9702 ok(SUCCEEDED(hr), "Failed to get backbuffer, hr %#x.\n", hr);
9703 hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, NULL);
9704 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
9705 IDirect3DSurface8_Release(backbuffer);
9707 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 1.0f, 0);
9708 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
9709 color = getPixelColor(device, 1, 1);
9710 ok(color == 0x00ffff00, "Got unexpected color 0x%08x.\n", color);
9711 color = getPixelColor(device, 700, 500);
9712 ok(color == 0x00ffff00, "Got unexpected color 0x%08x.\n", color);
9714 hr = IDirect3DDevice8_BeginScene(device);
9715 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9716 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9717 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9718 hr = IDirect3DDevice8_EndScene(device);
9719 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9720 color = getPixelColor(device, 1, 1);
9721 ok(color == 0x0000ff00, "Got unexpected color 0x%08x.\n", color);
9722 color = getPixelColor(device, 700, 500);
9723 ok(color == 0x0000ff00, "Got unexpected color 0x%08x.\n", color);
9725 refcount = IDirect3DDevice8_Release(device);
9726 ok(!refcount, "Device has %u references left.\n", refcount);
9727 done:
9728 IDirect3D8_Release(d3d);
9729 DestroyWindow(window);
9732 static void test_drawindexedprimitiveup(void)
9734 static const struct vertex
9736 struct vec3 position;
9737 DWORD diffuse;
9739 quad[] =
9741 {{-1.0f, -1.0f, 0.1f}, 0xff00ff00},
9742 {{-1.0f, 1.0f, 0.1f}, 0xff0000ff},
9743 {{ 1.0f, -1.0f, 0.1f}, 0xffff0000},
9744 {{ 1.0f, 1.0f, 0.1f}, 0xff0000ff},
9746 {{-1.0f, -1.0f, 0.1f}, 0xff0000ff},
9747 {{-1.0f, 1.0f, 0.1f}, 0xff00ff00},
9748 {{ 1.0f, -1.0f, 0.1f}, 0xffff0000},
9749 {{ 1.0f, 1.0f, 0.1f}, 0xff00ff00},
9751 static const unsigned short indices[] = {0, 1, 2, 3, 4, 5, 6, 7};
9752 IDirect3DDevice8 *device;
9753 IDirect3D8 *d3d;
9754 ULONG refcount;
9755 D3DCOLOR color;
9756 HWND window;
9757 HRESULT hr;
9759 window = create_window();
9760 d3d = Direct3DCreate8(D3D_SDK_VERSION);
9761 ok(!!d3d, "Failed to create a D3D object.\n");
9763 if (!(device = create_device(d3d, window, window, TRUE)))
9765 skip("Failed to create a D3D device.\n");
9766 IDirect3D8_Release(d3d);
9767 DestroyWindow(window);
9768 return;
9771 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, FALSE);
9772 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#x.\n", hr);
9773 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, FALSE);
9774 ok(SUCCEEDED(hr), "Failed to disable Z test, hr %#x.\n", hr);
9775 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9776 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
9778 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9779 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
9780 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9781 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
9782 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
9783 ok(SUCCEEDED(hr), "Failed to set alpha op, hr %#x.\n", hr);
9784 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
9785 ok(SUCCEEDED(hr), "Failed to set alpha arg, hr %#x.\n", hr);
9787 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9788 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
9790 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
9791 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
9793 hr = IDirect3DDevice8_BeginScene(device);
9794 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9795 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 4, 4, 2, indices + 4, D3DFMT_INDEX16, quad, sizeof(*quad));
9796 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9797 hr = IDirect3DDevice8_EndScene(device);
9798 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9800 color = getPixelColor(device, 160, 120);
9801 ok(color_match(color, 0x0040bf00, 1), "Got unexpected color 0x%08x.\n", color);
9802 color = getPixelColor(device, 480, 120);
9803 ok(color_match(color, 0x0040bf00, 1), "Got unexpected color 0x%08x.\n", color);
9804 color = getPixelColor(device, 160, 360);
9805 ok(color_match(color, 0x00404080, 1), "Got unexpected color 0x%08x.\n", color);
9806 color = getPixelColor(device, 480, 360);
9807 ok(color_match(color, 0x00bf4000, 1), "Got unexpected color 0x%08x.\n", color);
9809 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
9810 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
9812 hr = IDirect3DDevice8_BeginScene(device);
9813 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9814 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 0, 4, 2, indices, D3DFMT_INDEX16, quad, sizeof(*quad));
9815 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9816 hr = IDirect3DDevice8_EndScene(device);
9817 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9819 color = getPixelColor(device, 160, 120);
9820 ok(color_match(color, 0x004000bf, 1), "Got unexpected color 0x%08x.\n", color);
9821 color = getPixelColor(device, 480, 120);
9822 ok(color_match(color, 0x004000bf, 1), "Got unexpected color 0x%08x.\n", color);
9823 color = getPixelColor(device, 160, 360);
9824 ok(color_match(color, 0x00408040, 1), "Got unexpected color 0x%08x.\n", color);
9825 color = getPixelColor(device, 480, 360);
9826 ok(color_match(color, 0x00bf0040, 1), "Got unexpected color 0x%08x.\n", color);
9828 refcount = IDirect3DDevice8_Release(device);
9829 ok(!refcount, "Device has %u references left.\n", refcount);
9830 IDirect3D8_Release(d3d);
9831 DestroyWindow(window);
9834 START_TEST(visual)
9836 D3DADAPTER_IDENTIFIER8 identifier;
9837 IDirect3D8 *d3d;
9838 HRESULT hr;
9840 if (!(d3d = Direct3DCreate8(D3D_SDK_VERSION)))
9842 skip("Failed to create D3D8 object.\n");
9843 return;
9846 memset(&identifier, 0, sizeof(identifier));
9847 hr = IDirect3D8_GetAdapterIdentifier(d3d, D3DADAPTER_DEFAULT, 0, &identifier);
9848 ok(SUCCEEDED(hr), "Failed to get adapter identifier, hr %#x.\n", hr);
9849 trace("Driver string: \"%s\"\n", identifier.Driver);
9850 trace("Description string: \"%s\"\n", identifier.Description);
9851 /* Only Windows XP's default VGA driver should have an empty description */
9852 ok(identifier.Description[0] || broken(!strcmp(identifier.Driver, "vga.dll")), "Empty driver description.\n");
9853 trace("Driver version %d.%d.%d.%d\n",
9854 HIWORD(U(identifier.DriverVersion).HighPart), LOWORD(U(identifier.DriverVersion).HighPart),
9855 HIWORD(U(identifier.DriverVersion).LowPart), LOWORD(U(identifier.DriverVersion).LowPart));
9857 IDirect3D8_Release(d3d);
9859 test_sanity();
9860 depth_clamp_test();
9861 lighting_test();
9862 test_specular_lighting();
9863 clear_test();
9864 fog_test();
9865 z_range_test();
9866 offscreen_test();
9867 test_blend();
9868 test_scalar_instructions();
9869 fog_with_shader_test();
9870 cnd_test();
9871 p8_texture_test();
9872 texop_test();
9873 depth_buffer_test();
9874 depth_buffer2_test();
9875 intz_test();
9876 shadow_test();
9877 multisample_copy_rects_test();
9878 zenable_test();
9879 resz_test();
9880 fog_special_test();
9881 volume_dxt5_test();
9882 volume_v16u16_test();
9883 add_dirty_rect_test();
9884 test_3dc_formats();
9885 test_fog_interpolation();
9886 test_negative_fixedfunction_fog();
9887 test_table_fog_zw();
9888 test_signed_formats();
9889 test_updatetexture();
9890 test_pointsize();
9891 test_multisample_mismatch();
9892 test_texcoordindex();
9893 test_vshader_input();
9894 test_fixed_function_fvf();
9895 test_flip();
9896 test_uninitialized_varyings();
9897 test_shademode();
9898 test_multisample_init();
9899 test_texture_blending();
9900 test_color_clamping();
9901 test_edge_antialiasing_blending();
9902 test_max_index16();
9903 test_backbuffer_resize();
9904 test_drawindexedprimitiveup();