d3d8/tests: Work around a r500 Windows point sprite bug.
[wine.git] / dlls / d3d8 / tests / visual.c
blobd314edbd5add41c6b657b5a9194d4f07bff9af93
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 /* The r500 Windows driver needs a draw with regular texture coordinates at least once during the
6941 * device's lifetime, otherwise texture coordinate generation only works for texture 0. */
6942 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX1);
6943 ok(SUCCEEDED(hr), "Failed to set FVF, hr=%#x.\n", hr);
6944 hr = IDirect3DDevice8_BeginScene(device);
6945 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6946 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, vertices, sizeof(float) * 5);
6947 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6948 hr = IDirect3DDevice8_EndScene(device);
6949 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6951 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
6952 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
6953 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6954 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
6955 hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, &matrix);
6956 ok(SUCCEEDED(hr), "Failed to set projection matrix, hr %#x.\n", hr);
6957 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ);
6958 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
6960 hr = IDirect3DDevice8_BeginScene(device);
6961 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6963 ptsize = 15.0f;
6964 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
6965 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6966 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
6967 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6969 ptsize = 31.0f;
6970 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
6971 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6972 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[3], sizeof(float) * 3);
6973 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6975 ptsize = 30.75f;
6976 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
6977 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6978 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[6], sizeof(float) * 3);
6979 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6981 if (caps.MaxPointSize >= 63.0f)
6983 ptsize = 63.0f;
6984 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
6985 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6986 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[9], sizeof(float) * 3);
6987 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6989 ptsize = 62.75f;
6990 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
6991 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6992 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[15], sizeof(float) * 3);
6993 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6996 ptsize = 1.0f;
6997 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
6998 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6999 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[12], sizeof(float) * 3);
7000 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7002 hr = IDirect3DDevice8_GetRenderState(device, D3DRS_POINTSIZE_MAX, (DWORD *)&ptsizemax_orig);
7003 ok(SUCCEEDED(hr), "Failed to get render state, hr %#x.\n", hr);
7004 hr = IDirect3DDevice8_GetRenderState(device, D3DRS_POINTSIZE_MIN, (DWORD *)&ptsizemin_orig);
7005 ok(SUCCEEDED(hr), "Failed to get render state, hr %#x.\n", hr);
7007 /* What happens if point scaling is disabled, and POINTSIZE_MAX < POINTSIZE? */
7008 ptsize = 15.0f;
7009 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
7010 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
7011 ptsize = 1.0f;
7012 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE_MAX, *(DWORD *)&ptsize);
7013 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
7014 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[18], sizeof(float) * 3);
7015 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7017 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE_MAX, *(DWORD *)&ptsizemax_orig);
7018 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
7020 /* pointsize < pointsize_min < pointsize_max?
7021 * pointsize = 1.0, pointsize_min = 15.0, pointsize_max = default(usually 64.0) */
7022 ptsize = 1.0f;
7023 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
7024 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
7025 ptsize = 15.0f;
7026 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE_MIN, *(DWORD *)&ptsize);
7027 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
7028 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[21], sizeof(float) * 3);
7029 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7031 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE_MIN, *(DWORD *)&ptsizemin_orig);
7032 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
7034 hr = IDirect3DDevice8_EndScene(device);
7035 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7037 ok(point_match(device, 64, 64, 7), "point_match(64, 64, 7) failed, expected point size 15.\n");
7038 ok(point_match(device, 128, 64, 15), "point_match(128, 64, 15) failed, expected point size 31.\n");
7039 ok(point_match(device, 192, 64, 15), "point_match(192, 64, 15) failed, expected point size 31.\n");
7041 if (caps.MaxPointSize >= 63.0f)
7043 ok(point_match(device, 256, 64, 31), "point_match(256, 64, 31) failed, expected point size 63.\n");
7044 ok(point_match(device, 384, 64, 31), "point_match(384, 64, 31) failed, expected point size 63.\n");
7047 ok(point_match(device, 320, 64, 0), "point_match(320, 64, 0) failed, expected point size 1.\n");
7048 /* ptsize = 15, ptsize_max = 1 --> point has size 1 */
7049 ok(point_match(device, 448, 64, 0), "point_match(448, 64, 0) failed, expected point size 1.\n");
7050 /* ptsize = 1, ptsize_max = default(64), ptsize_min = 15 --> point has size 15 */
7051 ok(point_match(device, 512, 64, 7), "point_match(512, 64, 7) failed, expected point size 15.\n");
7053 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
7055 /* The following code tests point sprites with two textures, to see if each texture coordinate unit
7056 * generates texture coordinates for the point(result: Yes, it does)
7058 * However, not all GL implementations support point sprites(they need GL_ARB_point_sprite), but there
7059 * is no point sprite cap bit in d3d because native d3d software emulates point sprites. Until the
7060 * SW emulation is implemented in wined3d, this test will fail on GL drivers that does not support them.
7062 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
7063 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
7065 hr = IDirect3DDevice8_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex1);
7066 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
7067 hr = IDirect3DDevice8_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex2);
7068 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
7069 memset(&lr, 0, sizeof(lr));
7070 hr = IDirect3DTexture8_LockRect(tex1, 0, &lr, NULL, 0);
7071 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
7072 memcpy(lr.pBits, tex1_data, sizeof(tex1_data));
7073 hr = IDirect3DTexture8_UnlockRect(tex1, 0);
7074 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
7075 memset(&lr, 0, sizeof(lr));
7076 hr = IDirect3DTexture8_LockRect(tex2, 0, &lr, NULL, 0);
7077 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
7078 memcpy(lr.pBits, tex2_data, sizeof(tex2_data));
7079 hr = IDirect3DTexture8_UnlockRect(tex2, 0);
7080 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
7081 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)tex1);
7082 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
7083 hr = IDirect3DDevice8_SetTexture(device, 1, (IDirect3DBaseTexture8 *)tex2);
7084 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
7085 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7086 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
7087 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7088 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
7089 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
7090 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
7091 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7092 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
7093 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
7094 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
7096 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSPRITEENABLE, TRUE);
7097 ok(SUCCEEDED(hr), "Failed to enable point sprites, hr %#x.\n", hr);
7098 ptsize = 32.0f;
7099 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
7100 ok(SUCCEEDED(hr), "Failed to set point size, hr %#x.\n", hr);
7102 hr = IDirect3DDevice8_BeginScene(device);
7103 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7104 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
7105 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7106 hr = IDirect3DDevice8_EndScene(device);
7107 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7109 color = getPixelColor(device, 64 - 4, 64 - 4);
7110 ok(color == 0x00ff0000, "pSprite: Pixel (64 - 4),(64 - 4) has color 0x%08x, expected 0x00ff0000\n", color);
7111 color = getPixelColor(device, 64 - 4, 64 + 4);
7112 ok(color == 0x00000000, "pSprite: Pixel (64 - 4),(64 + 4) has color 0x%08x, expected 0x00000000\n", color);
7113 color = getPixelColor(device, 64 + 4, 64 + 4);
7114 ok(color == 0x0000ff00, "pSprite: Pixel (64 + 4),(64 + 4) has color 0x%08x, expected 0x0000ff00\n", color);
7115 color = getPixelColor(device, 64 + 4, 64 - 4);
7116 ok(color == 0x00ffff00, "pSprite: Pixel (64 + 4),(64 - 4) has color 0x%08x, expected 0x00ffff00\n", color);
7117 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
7119 U(matrix).m[0][0] = 1.0f / 64.0f;
7120 U(matrix).m[1][1] = -1.0f / 64.0f;
7121 hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, &matrix);
7122 ok(SUCCEEDED(hr), "Failed to set projection matrix, hr %#x.\n", hr);
7124 hr = IDirect3DDevice8_GetRenderTarget(device, &backbuffer);
7125 ok(SUCCEEDED(hr), "Failed to get backbuffer, hr %#x.\n", hr);
7126 hr = IDirect3DDevice8_GetDepthStencilSurface(device, &depthstencil);
7127 ok(SUCCEEDED(hr), "Failed to get depth / stencil buffer, hr %#x.\n", hr);
7129 hr = IDirect3DDevice8_CreateRenderTarget(device, 128, 128, D3DFMT_A8R8G8B8,
7130 D3DMULTISAMPLE_NONE, TRUE, &rt);
7131 ok(SUCCEEDED(hr), "Failed to create a render target, hr %#x.\n", hr);
7133 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSCALE_A, *(DWORD *)&a);
7134 ok(SUCCEEDED(hr), "Failed setting point scale attenuation coefficient, hr %#x.\n", hr);
7135 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSCALE_B, *(DWORD *)&b);
7136 ok(SUCCEEDED(hr), "Failed setting point scale attenuation coefficient, hr %#x.\n", hr);
7137 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSCALE_C, *(DWORD *)&c);
7138 ok(SUCCEEDED(hr), "Failed setting point scale attenuation coefficient, hr %#x.\n", hr);
7139 hr = IDirect3DDevice8_SetVertexShaderConstant(device, 0, &S(U(matrix))._11, 4);
7140 ok(SUCCEEDED(hr), "Failed to set vertex shader constants, hr %#x.\n", hr);
7142 if (caps.MaxPointSize < 63.0f)
7144 skip("MaxPointSize %f < 63.0, skipping some tests.\n", caps.MaxPointSize);
7145 goto cleanup;
7148 hr = IDirect3DDevice8_SetRenderTarget(device, rt, depthstencil);
7149 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
7151 for (i = 0; i < sizeof(test_setups) / sizeof(test_setups[0]); ++i)
7153 if (caps.VertexShaderVersion < test_setups[i].vs->version
7154 || caps.PixelShaderVersion < test_setups[i].ps->version)
7156 skip("Vertex / pixel shader version not supported, skipping test.\n");
7157 continue;
7159 if (test_setups[i].vs->code)
7161 hr = IDirect3DDevice8_CreateVertexShader(device, test_setups[i].decl, test_setups[i].vs->code, &vs, 0);
7162 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x (case %u).\n", hr, i);
7164 else
7166 vs = 0;
7168 if (test_setups[i].ps->code)
7170 hr = IDirect3DDevice8_CreatePixelShader(device, test_setups[i].ps->code, &ps);
7171 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x (case %u).\n", hr, i);
7173 else
7175 ps = 0;
7178 hr = IDirect3DDevice8_SetVertexShader(device, vs ? vs : test_setups[i].accepted_fvf);
7179 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
7180 hr = IDirect3DDevice8_SetPixelShader(device, ps);
7181 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
7183 for (j = 0; j < sizeof(tests) / sizeof(tests[0]); ++j)
7185 unsigned int size = tests[j].override_min ? 63 : tests[j].zero_size ? 0 : tests[j].scale
7186 ? test_setups[i].scaled_size : test_setups[i].nonscaled_size;
7188 if (test_setups[i].accepted_fvf != tests[j].fvf)
7189 continue;
7191 ptsize = tests[j].zero_size ? 0.0f : 32.0f;
7192 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
7193 ok(SUCCEEDED(hr), "Failed to set pointsize, hr %#x.\n", hr);
7195 ptsize = tests[j].override_min ? 63.0f : tests[j].zero_size ? 0.0f : ptsizemin_orig;
7196 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE_MIN, *(DWORD *)&ptsize);
7197 ok(SUCCEEDED(hr), "Failed to set minimum pointsize, hr %#x.\n", hr);
7199 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSCALEENABLE, tests[j].scale);
7200 ok(SUCCEEDED(hr), "Failed setting point scale state, hr %#x.\n", hr);
7202 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
7203 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
7205 hr = IDirect3DDevice8_BeginScene(device);
7206 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7207 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1,
7208 tests[j].vertex_data, tests[j].vertex_size);
7209 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7210 hr = IDirect3DDevice8_EndScene(device);
7211 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7213 if (tests[j].zero_size)
7215 /* Technically 0 pointsize is undefined in OpenGL but in practice it seems like
7216 * it does the "useful" thing on all the drivers I tried. */
7217 /* On WARP it does draw some pixels, most of the time. */
7218 color = getPixelColor(device, 64, 64);
7219 ok(color_match(color, 0x0000ffff, 0)
7220 || broken(color_match(color, 0x00ff0000, 0))
7221 || broken(color_match(color, 0x00ffff00, 0))
7222 || broken(color_match(color, 0x00000000, 0))
7223 || broken(color_match(color, 0x0000ff00, 0)),
7224 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
7226 else
7228 struct surface_readback rb;
7230 get_rt_readback(rt, &rb);
7231 color = get_readback_color(&rb, 64 - size / 2 + 1, 64 - size / 2 + 1);
7232 ok(color_match(color, 0x00ff0000, 0),
7233 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
7234 color = get_readback_color(&rb, 64 + size / 2 - 1, 64 - size / 2 + 1);
7235 ok(color_match(color, 0x00ffff00, 0),
7236 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
7237 color = get_readback_color(&rb, 64 - size / 2 + 1, 64 + size / 2 - 1);
7238 ok(color_match(color, 0x00000000, 0),
7239 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
7240 color = get_readback_color(&rb, 64 + size / 2 - 1, 64 + size / 2 - 1);
7241 ok(color_match(color, 0x0000ff00, 0),
7242 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
7244 color = get_readback_color(&rb, 64 - size / 2 - 1, 64 - size / 2 - 1);
7245 ok(color_match(color, 0xff00ffff, 0),
7246 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
7247 color = get_readback_color(&rb, 64 + size / 2 + 1, 64 - size / 2 - 1);
7248 ok(color_match(color, 0xff00ffff, 0),
7249 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
7250 color = get_readback_color(&rb, 64 - size / 2 - 1, 64 + size / 2 + 1);
7251 ok(color_match(color, 0xff00ffff, 0),
7252 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
7253 color = get_readback_color(&rb, 64 + size / 2 + 1, 64 + size / 2 + 1);
7254 ok(color_match(color, 0xff00ffff, 0),
7255 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
7257 release_surface_readback(&rb);
7260 IDirect3DDevice8_SetVertexShader(device, 0);
7261 IDirect3DDevice8_SetPixelShader(device, 0);
7262 if (vs)
7263 IDirect3DDevice8_DeleteVertexShader(device, vs);
7264 if (ps)
7265 IDirect3DDevice8_DeletePixelShader(device, ps);
7267 hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, depthstencil);
7268 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
7270 cleanup:
7271 IDirect3DSurface8_Release(backbuffer);
7272 IDirect3DSurface8_Release(depthstencil);
7273 IDirect3DSurface8_Release(rt);
7275 IDirect3DTexture8_Release(tex1);
7276 IDirect3DTexture8_Release(tex2);
7277 refcount = IDirect3DDevice8_Release(device);
7278 ok(!refcount, "Device has %u references left.\n", refcount);
7279 done:
7280 IDirect3D8_Release(d3d);
7281 DestroyWindow(window);
7284 static void test_multisample_mismatch(void)
7286 IDirect3DDevice8 *device;
7287 IDirect3D8 *d3d;
7288 HWND window;
7289 HRESULT hr;
7290 ULONG refcount;
7291 IDirect3DSurface8 *rt_multi, *ds;
7293 window = create_window();
7294 d3d = Direct3DCreate8(D3D_SDK_VERSION);
7295 ok(!!d3d, "Failed to create a D3D object.\n");
7296 if (FAILED(IDirect3D8_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
7297 D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES)))
7299 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping multisample mismatch test.\n");
7300 IDirect3D8_Release(d3d);
7301 return;
7304 if (!(device = create_device(d3d, window, window, TRUE)))
7306 skip("Failed to create a D3D device, skipping tests.\n");
7307 goto done;
7310 hr = IDirect3DDevice8_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
7311 D3DMULTISAMPLE_2_SAMPLES, FALSE, &rt_multi);
7312 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
7313 hr = IDirect3DDevice8_GetDepthStencilSurface(device, &ds);
7314 ok(SUCCEEDED(hr), "Failed to get original depth/stencil, hr %#x.\n", hr);
7316 hr = IDirect3DDevice8_SetRenderTarget(device, rt_multi, ds);
7317 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
7319 IDirect3DSurface8_Release(ds);
7320 IDirect3DSurface8_Release(rt_multi);
7322 refcount = IDirect3DDevice8_Release(device);
7323 ok(!refcount, "Device has %u references left.\n", refcount);
7324 done:
7325 IDirect3D8_Release(d3d);
7326 DestroyWindow(window);
7329 static void test_texcoordindex(void)
7331 static const D3DMATRIX mat =
7333 1.0f, 0.0f, 0.0f, 0.0f,
7334 0.0f, 0.0f, 0.0f, 0.0f,
7335 0.0f, 0.0f, 0.0f, 0.0f,
7336 0.0f, 0.0f, 0.0f, 0.0f,
7337 }}};
7338 static const struct
7340 struct vec3 pos;
7341 struct vec2 texcoord1;
7342 struct vec2 texcoord2;
7343 struct vec2 texcoord3;
7345 quad[] =
7347 {{-1.0f, -1.0f, 0.0f}, {0.0f, 1.0f}, {0.0f, 0.0f}, {1.0f, 1.0f}},
7348 {{-1.0f, 1.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 1.0f}, {1.0f, 0.0f}},
7349 {{ 1.0f, -1.0f, 0.0f}, {1.0f, 1.0f}, {1.0f, 0.0f}, {0.0f, 1.0f}},
7350 {{ 1.0f, 1.0f, 0.0f}, {1.0f, 0.0f}, {1.0f, 1.0f}, {0.0f, 0.0f}},
7352 IDirect3DDevice8 *device;
7353 IDirect3D8 *d3d;
7354 HWND window;
7355 HRESULT hr;
7356 IDirect3DTexture8 *texture1, *texture2;
7357 D3DLOCKED_RECT locked_rect;
7358 ULONG refcount;
7359 D3DCOLOR color;
7360 DWORD *ptr;
7362 window = create_window();
7363 d3d = Direct3DCreate8(D3D_SDK_VERSION);
7364 ok(!!d3d, "Failed to create a D3D object.\n");
7365 if (!(device = create_device(d3d, window, window, TRUE)))
7367 skip("Failed to create a D3D device, skipping tests.\n");
7368 IDirect3D8_Release(d3d);
7369 DestroyWindow(window);
7370 return;
7373 hr = IDirect3DDevice8_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture1);
7374 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
7375 hr = IDirect3DDevice8_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture2);
7376 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
7378 hr = IDirect3DTexture8_LockRect(texture1, 0, &locked_rect, NULL, D3DLOCK_DISCARD);
7379 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
7380 ptr = locked_rect.pBits;
7381 ptr[0] = 0xff000000;
7382 ptr[1] = 0xff00ff00;
7383 ptr[2] = 0xff0000ff;
7384 ptr[3] = 0xff00ffff;
7385 hr = IDirect3DTexture8_UnlockRect(texture1, 0);
7386 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
7388 hr = IDirect3DTexture8_LockRect(texture2, 0, &locked_rect, NULL, D3DLOCK_DISCARD);
7389 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
7390 ptr = locked_rect.pBits;
7391 ptr[0] = 0xff000000;
7392 ptr[1] = 0xff0000ff;
7393 ptr[2] = 0xffff0000;
7394 ptr[3] = 0xffff00ff;
7395 hr = IDirect3DTexture8_UnlockRect(texture2, 0);
7396 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
7398 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture1);
7399 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
7400 hr = IDirect3DDevice8_SetTexture(device, 1, (IDirect3DBaseTexture8 *)texture2);
7401 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
7402 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX3);
7403 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
7404 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
7405 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
7406 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7407 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
7408 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7409 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
7410 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
7411 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
7412 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7413 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
7414 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
7415 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
7416 hr = IDirect3DDevice8_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
7417 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
7419 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_TEXCOORDINDEX, 1);
7420 ok(SUCCEEDED(hr), "Failed to set texcoord index, hr %#x.\n", hr);
7421 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_TEXCOORDINDEX, 0);
7422 ok(SUCCEEDED(hr), "Failed to set texcoord index, hr %#x.\n", hr);
7424 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 1.0f, 0);
7425 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
7427 hr = IDirect3DDevice8_BeginScene(device);
7428 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7429 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
7430 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7431 hr = IDirect3DDevice8_EndScene(device);
7432 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7434 color = getPixelColor(device, 160, 120);
7435 ok(color_match(color, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color);
7436 color = getPixelColor(device, 480, 120);
7437 ok(color_match(color, 0x0000ffff, 2), "Got unexpected color 0x%08x.\n", color);
7438 color = getPixelColor(device, 160, 360);
7439 ok(color_match(color, 0x00ff0000, 2), "Got unexpected color 0x%08x.\n", color);
7440 color = getPixelColor(device, 480, 360);
7441 ok(color_match(color, 0x00ffffff, 2), "Got unexpected color 0x%08x.\n", color);
7443 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
7444 ok(SUCCEEDED(hr), "Failed to set texture transform flags, hr %#x.\n", hr);
7445 hr = IDirect3DDevice8_SetTransform(device, D3DTS_TEXTURE1, &mat);
7446 ok(SUCCEEDED(hr), "Failed to set transformation matrix, hr %#x.\n", hr);
7448 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 1.0f, 0);
7449 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
7451 hr = IDirect3DDevice8_BeginScene(device);
7452 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7453 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
7454 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7455 hr = IDirect3DDevice8_EndScene(device);
7456 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7458 color = getPixelColor(device, 160, 120);
7459 ok(color_match(color, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color);
7460 color = getPixelColor(device, 480, 120);
7461 ok(color_match(color, 0x0000ffff, 2), "Got unexpected color 0x%08x.\n", color);
7462 color = getPixelColor(device, 160, 360);
7463 ok(color_match(color, 0x00000000, 2), "Got unexpected color 0x%08x.\n", color);
7464 color = getPixelColor(device, 480, 360);
7465 ok(color_match(color, 0x0000ffff, 2), "Got unexpected color 0x%08x.\n", color);
7467 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
7468 ok(SUCCEEDED(hr), "Failed to set texture transform flags, hr %#x.\n", hr);
7469 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_TEXCOORDINDEX, 2);
7470 ok(SUCCEEDED(hr), "Failed to set texcoord index, hr %#x.\n", hr);
7472 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 1.0f, 0);
7473 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
7475 hr = IDirect3DDevice8_BeginScene(device);
7476 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7477 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
7478 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7479 hr = IDirect3DDevice8_EndScene(device);
7480 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7482 color = getPixelColor(device, 160, 120);
7483 ok(color_match(color, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color);
7484 color = getPixelColor(device, 480, 120);
7485 ok(color_match(color, 0x0000ffff, 2), "Got unexpected color 0x%08x.\n", color);
7486 color = getPixelColor(device, 160, 360);
7487 ok(color_match(color, 0x00ff00ff, 2), "Got unexpected color 0x%08x.\n", color);
7488 color = getPixelColor(device, 480, 360);
7489 ok(color_match(color, 0x00ffff00, 2), "Got unexpected color 0x%08x.\n", color);
7491 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
7492 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
7494 IDirect3DTexture8_Release(texture1);
7495 IDirect3DTexture8_Release(texture2);
7497 refcount = IDirect3DDevice8_Release(device);
7498 ok(!refcount, "Device has %u references left.\n", refcount);
7499 IDirect3D8_Release(d3d);
7500 DestroyWindow(window);
7503 static void test_vshader_input(void)
7505 DWORD swapped_twotexcrd_shader, swapped_onetexcrd_shader = 0;
7506 DWORD swapped_twotex_wrongidx_shader = 0, swapped_twotexcrd_rightorder_shader;
7507 DWORD texcoord_color_shader, color_ubyte_shader, color_color_shader, color_float_shader;
7508 DWORD color_nocolor_shader = 0;
7509 IDirect3DDevice8 *device;
7510 IDirect3D8 *d3d;
7511 ULONG refcount;
7512 D3DCAPS8 caps;
7513 DWORD color;
7514 HWND window;
7515 HRESULT hr;
7517 static const DWORD swapped_shader_code[] =
7519 0xfffe0101, /* vs_1_1 */
7520 0x00000001, 0xc00f0000, 0x90e40000, /* mov o0, v0 */
7521 0x00000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
7522 0x00000002, 0xd00f0000, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
7523 0x0000ffff /* end */
7525 static const DWORD texcoord_color_shader_code[] =
7527 0xfffe0101, /* vs_1_1 */
7528 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
7529 0x00000001, 0xd00f0000, 0x90e40007, /* mov oD0, v7 */
7530 0x0000ffff /* end */
7532 static const DWORD color_color_shader_code[] =
7534 0xfffe0101, /* vs_1_1 */
7535 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
7536 0x00000005, 0xd00f0000, 0xa0e40000, 0x90e40005, /* mul oD0, c0, v5 */
7537 0x0000ffff /* end */
7539 static const float quad1[] =
7541 -1.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7542 -1.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7543 0.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7544 0.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7546 static const float quad4[] =
7548 0.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7549 0.0f, 1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7550 1.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7551 1.0f, 1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7553 static const struct
7555 struct vec3 position;
7556 DWORD diffuse;
7558 quad1_color[] =
7560 {{-1.0f, -1.0f, 0.1f}, 0x00ff8040},
7561 {{-1.0f, 0.0f, 0.1f}, 0x00ff8040},
7562 {{ 0.0f, -1.0f, 0.1f}, 0x00ff8040},
7563 {{ 0.0f, 0.0f, 0.1f}, 0x00ff8040},
7565 quad2_color[] =
7567 {{ 0.0f, -1.0f, 0.1f}, 0x00ff8040},
7568 {{ 0.0f, 0.0f, 0.1f}, 0x00ff8040},
7569 {{ 1.0f, -1.0f, 0.1f}, 0x00ff8040},
7570 {{ 1.0f, 0.0f, 0.1f}, 0x00ff8040},
7572 quad3_color[] =
7574 {{-1.0f, 0.0f, 0.1f}, 0x00ff8040},
7575 {{-1.0f, 1.0f, 0.1f}, 0x00ff8040},
7576 {{ 0.0f, 0.0f, 0.1f}, 0x00ff8040},
7577 {{ 0.0f, 1.0f, 0.1f}, 0x00ff8040},
7579 static const float quad4_color[] =
7581 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 0.0f, 0.0f,
7582 0.0f, 1.0f, 0.1f, 1.0f, 1.0f, 0.0f, 0.0f,
7583 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 0.0f, 1.0f,
7584 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 0.0f, 1.0f,
7586 static const DWORD decl_twotexcrd[] =
7588 D3DVSD_STREAM(0),
7589 D3DVSD_REG(0, D3DVSDT_FLOAT3), /* position */
7590 D3DVSD_REG(1, D3DVSDT_FLOAT4), /* texcoord0 */
7591 D3DVSD_REG(2, D3DVSDT_FLOAT4), /* texcoord1 */
7592 D3DVSD_END()
7594 static const DWORD decl_twotexcrd_rightorder[] =
7596 D3DVSD_STREAM(0),
7597 D3DVSD_REG(0, D3DVSDT_FLOAT3), /* position */
7598 D3DVSD_REG(2, D3DVSDT_FLOAT4), /* texcoord0 */
7599 D3DVSD_REG(1, D3DVSDT_FLOAT4), /* texcoord1 */
7600 D3DVSD_END()
7602 static const DWORD decl_onetexcrd[] =
7604 D3DVSD_STREAM(0),
7605 D3DVSD_REG(0, D3DVSDT_FLOAT3), /* position */
7606 D3DVSD_REG(1, D3DVSDT_FLOAT4), /* texcoord0 */
7607 D3DVSD_END()
7609 static const DWORD decl_twotexcrd_wrongidx[] =
7611 D3DVSD_STREAM(0),
7612 D3DVSD_REG(0, D3DVSDT_FLOAT3), /* position */
7613 D3DVSD_REG(2, D3DVSDT_FLOAT4), /* texcoord1 */
7614 D3DVSD_REG(3, D3DVSDT_FLOAT4), /* texcoord2 */
7615 D3DVSD_END()
7617 static const DWORD decl_texcoord_color[] =
7619 D3DVSD_STREAM(0),
7620 D3DVSD_REG(0, D3DVSDT_FLOAT3), /* position */
7621 D3DVSD_REG(7, D3DVSDT_D3DCOLOR), /* texcoord0 */
7622 D3DVSD_END()
7624 static const DWORD decl_color_color[] =
7626 D3DVSD_STREAM(0),
7627 D3DVSD_REG(0, D3DVSDT_FLOAT3), /* position */
7628 D3DVSD_REG(5, D3DVSDT_D3DCOLOR), /* diffuse */
7629 D3DVSD_END()
7631 static const DWORD decl_color_ubyte[] =
7633 D3DVSD_STREAM(0),
7634 D3DVSD_REG(0, D3DVSDT_FLOAT3),
7635 D3DVSD_REG(5, D3DVSDT_UBYTE4),
7636 D3DVSD_END()
7638 static const DWORD decl_color_float[] =
7640 D3DVSD_STREAM(0),
7641 D3DVSD_REG(0, D3DVSDT_FLOAT3),
7642 D3DVSD_REG(5, D3DVSDT_FLOAT4),
7643 D3DVSD_END()
7645 static const DWORD decl_nocolor[] =
7647 D3DVSD_STREAM(0),
7648 D3DVSD_REG(0, D3DVSDT_FLOAT3),
7649 D3DVSD_END()
7651 static const float normalize[4] = {1.0f / 256.0f, 1.0f / 256.0f, 1.0f / 256.0f, 1.0f / 256.0f};
7652 static const float no_normalize[4] = {1.0f, 1.0f, 1.0f, 1.0f};
7654 window = create_window();
7655 d3d = Direct3DCreate8(D3D_SDK_VERSION);
7656 ok(!!d3d, "Failed to create a D3D object.\n");
7657 if (!(device = create_device(d3d, window, window, TRUE)))
7659 skip("Failed to create a D3D device, skipping tests.\n");
7660 goto done;
7663 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
7664 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
7665 if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1))
7667 skip("No vs_1_1 support, skipping tests.\n");
7668 IDirect3DDevice8_Release(device);
7669 goto done;
7672 hr = IDirect3DDevice8_CreateVertexShader(device, decl_twotexcrd, swapped_shader_code, &swapped_twotexcrd_shader, 0);
7673 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
7674 hr = IDirect3DDevice8_CreateVertexShader(device, decl_onetexcrd, swapped_shader_code, &swapped_onetexcrd_shader, 0);
7675 todo_wine ok(hr == D3DERR_INVALIDCALL, "Unexpected error while creating vertex shader, hr %#x.\n", hr);
7676 hr = IDirect3DDevice8_CreateVertexShader(device, decl_twotexcrd_wrongidx, swapped_shader_code, &swapped_twotex_wrongidx_shader, 0);
7677 todo_wine ok(hr == D3DERR_INVALIDCALL, "Unexpected error while creating vertex shader, hr %#x.\n", hr);
7678 hr = IDirect3DDevice8_CreateVertexShader(device, decl_twotexcrd_rightorder, swapped_shader_code, &swapped_twotexcrd_rightorder_shader, 0);
7679 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
7681 hr = IDirect3DDevice8_CreateVertexShader(device, decl_texcoord_color, texcoord_color_shader_code, &texcoord_color_shader, 0);
7682 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
7683 hr = IDirect3DDevice8_CreateVertexShader(device, decl_color_ubyte, color_color_shader_code, &color_ubyte_shader, 0);
7684 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
7685 hr = IDirect3DDevice8_CreateVertexShader(device, decl_color_color, color_color_shader_code, &color_color_shader, 0);
7686 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
7687 hr = IDirect3DDevice8_CreateVertexShader(device, decl_color_float, color_color_shader_code, &color_float_shader, 0);
7688 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
7689 hr = IDirect3DDevice8_CreateVertexShader(device, decl_nocolor, color_color_shader_code, &color_nocolor_shader, 0);
7690 todo_wine ok(hr == D3DERR_INVALIDCALL, "Unexpected error while creating vertex shader, hr %#x.\n", hr);
7692 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 1.0f, 0);
7693 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
7695 hr = IDirect3DDevice8_BeginScene(device);
7696 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7698 hr = IDirect3DDevice8_SetVertexShader(device, swapped_twotexcrd_shader);
7699 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
7701 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 11);
7702 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7704 hr = IDirect3DDevice8_SetVertexShader(device, swapped_twotexcrd_rightorder_shader);
7705 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
7706 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 11);
7707 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7709 hr = IDirect3DDevice8_EndScene(device);
7710 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7712 color = getPixelColor(device, 160, 360);
7713 ok(color_match(color, 0x00ffff80, 1), "Got unexpected color 0x%08x for quad 1 (2crd).\n", color);
7714 color = getPixelColor(device, 480, 160);
7715 ok(color == 0x00000000, "Got unexpected color 0x%08x for quad 4 (2crd-rightorder).\n", color);
7717 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
7718 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
7720 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
7721 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
7723 hr = IDirect3DDevice8_BeginScene(device);
7724 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7726 hr = IDirect3DDevice8_SetVertexShader(device, texcoord_color_shader);
7727 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
7728 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1_color, sizeof(quad1_color[0]));
7729 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7731 hr = IDirect3DDevice8_SetVertexShader(device, color_ubyte_shader);
7732 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
7734 hr = IDirect3DDevice8_SetVertexShaderConstant(device, 0, normalize, 1);
7735 ok(SUCCEEDED(hr), "Failed to set vertex shader constant, hr %#x.\n", hr);
7736 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_color, sizeof(quad2_color[0]));
7737 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7739 hr = IDirect3DDevice8_SetVertexShaderConstant(device, 0, no_normalize, 1);
7740 ok(SUCCEEDED(hr), "Failed to set vertex shader constant, hr %#x.\n", hr);
7741 hr = IDirect3DDevice8_SetVertexShader(device, color_color_shader);
7742 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
7743 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3_color, sizeof(quad3_color[0]));
7744 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7746 hr = IDirect3DDevice8_SetVertexShader(device, color_float_shader);
7747 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
7748 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4_color, sizeof(float) * 7);
7749 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7751 hr = IDirect3DDevice8_EndScene(device);
7752 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7754 IDirect3DDevice8_SetVertexShader(device, 0);
7756 color = getPixelColor(device, 160, 360);
7757 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
7758 "Input test: Quad 1(color-texcoord) returned color 0x%08x, expected 0x00ff8040\n", color);
7759 color = getPixelColor(device, 480, 360);
7760 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x40, 0x80, 0xff), 1),
7761 "Input test: Quad 2(color-ubyte) returned color 0x%08x, expected 0x004080ff\n", color);
7762 color = getPixelColor(device, 160, 120);
7763 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
7764 "Input test: Quad 3(color-color) returned color 0x%08x, expected 0x00ff8040\n", color);
7765 color = getPixelColor(device, 480, 160);
7766 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 1),
7767 "Input test: Quad 4(color-float) returned color 0x%08x, expected 0x00ffff00\n", color);
7769 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
7770 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
7772 IDirect3DDevice8_DeleteVertexShader(device, swapped_twotexcrd_shader);
7773 IDirect3DDevice8_DeleteVertexShader(device, swapped_onetexcrd_shader);
7774 IDirect3DDevice8_DeleteVertexShader(device, swapped_twotex_wrongidx_shader);
7775 IDirect3DDevice8_DeleteVertexShader(device, swapped_twotexcrd_rightorder_shader);
7776 IDirect3DDevice8_DeleteVertexShader(device, texcoord_color_shader);
7777 IDirect3DDevice8_DeleteVertexShader(device, color_ubyte_shader);
7778 IDirect3DDevice8_DeleteVertexShader(device, color_color_shader);
7779 IDirect3DDevice8_DeleteVertexShader(device, color_float_shader);
7780 IDirect3DDevice8_DeleteVertexShader(device, color_nocolor_shader);
7782 refcount = IDirect3DDevice8_Release(device);
7783 ok(!refcount, "Device has %u references left.\n", refcount);
7784 done:
7785 IDirect3D8_Release(d3d);
7786 DestroyWindow(window);
7789 static void test_fixed_function_fvf(void)
7791 IDirect3DDevice8 *device;
7792 DWORD color;
7793 IDirect3D8 *d3d;
7794 ULONG refcount;
7795 D3DCAPS8 caps;
7796 HWND window;
7797 HRESULT hr;
7799 static const struct
7801 struct vec3 position;
7802 DWORD diffuse;
7804 quad1[] =
7806 {{-1.0f, -1.0f, 0.1f}, 0x00ffff00},
7807 {{-1.0f, 0.0f, 0.1f}, 0x00ffff00},
7808 {{ 0.0f, -1.0f, 0.1f}, 0x00ffff00},
7809 {{ 0.0f, 0.0f, 0.1f}, 0x00ffff00},
7811 static const struct vec3 quad2[] =
7813 {-1.0f, -1.0f, 0.1f},
7814 {-1.0f, 0.0f, 0.1f},
7815 { 0.0f, -1.0f, 0.1f},
7816 { 0.0f, 0.0f, 0.1f},
7818 static const struct
7820 struct vec4 position;
7821 DWORD diffuse;
7823 quad_transformed[] =
7825 {{ 90.0f, 110.0f, 0.1f, 2.0f}, 0x00ffff00},
7826 {{570.0f, 110.0f, 0.1f, 2.0f}, 0x00ffff00},
7827 {{ 90.0f, 300.0f, 0.1f, 2.0f}, 0x00ffff00},
7828 {{570.0f, 300.0f, 0.1f, 2.0f}, 0x00ffff00},
7831 window = create_window();
7832 d3d = Direct3DCreate8(D3D_SDK_VERSION);
7833 ok(!!d3d, "Failed to create a D3D object.\n");
7834 if (!(device = create_device(d3d, window, window, TRUE)))
7836 skip("Failed to create a D3D device, skipping tests.\n");
7837 goto done;
7840 memset(&caps, 0, sizeof(caps));
7841 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
7842 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
7844 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
7845 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
7847 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
7848 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
7850 hr = IDirect3DDevice8_BeginScene(device);
7851 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7853 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
7854 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
7855 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
7856 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7858 hr = IDirect3DDevice8_EndScene(device);
7859 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7861 color = getPixelColor(device, 160, 360);
7862 ok(color == 0x00ffff00,
7863 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7864 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
7866 /* Test with no diffuse color attribute. */
7867 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7868 ok(SUCCEEDED(hr), "IDirect3DDevice8_Clear failed with %08x\n", hr);
7870 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ);
7871 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
7872 hr = IDirect3DDevice8_BeginScene(device);
7873 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7874 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad2, sizeof(quad2[0]));
7875 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7876 hr = IDirect3DDevice8_EndScene(device);
7877 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7879 color = getPixelColor(device, 160, 360);
7880 ok(color == 0x00ffffff, "Got unexpected color 0x%08x in the no diffuse attribute test.\n", color);
7881 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
7883 /* Test what happens with specular lighting enabled and no specular color attribute. */
7884 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
7885 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
7886 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SPECULARENABLE, TRUE);
7887 ok(SUCCEEDED(hr), "Failed to enable specular lighting, hr %#x.\n", hr);
7888 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
7889 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
7890 hr = IDirect3DDevice8_BeginScene(device);
7891 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7893 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad1, sizeof(quad1[0]));
7894 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7896 hr = IDirect3DDevice8_EndScene(device);
7897 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7898 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SPECULARENABLE, FALSE);
7899 ok(SUCCEEDED(hr), "Failed to disable specular lighting, hr %#x.\n", hr);
7901 color = getPixelColor(device, 160, 360);
7902 ok(color == 0x00ffff00, "Got unexpected color 0x%08x in the no specular attribute test.\n", color);
7904 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
7906 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
7907 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
7909 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7910 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
7912 hr = IDirect3DDevice8_BeginScene(device);
7913 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7914 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad_transformed, sizeof(quad_transformed[0]));
7915 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7916 hr = IDirect3DDevice8_EndScene(device);
7917 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7919 color = getPixelColor(device, 88, 108);
7920 ok(color == 0x000000ff,
7921 "pixel 88/108 has color %08x, expected 0x000000ff\n", color);
7922 color = getPixelColor(device, 92, 108);
7923 ok(color == 0x000000ff,
7924 "pixel 92/108 has color %08x, expected 0x000000ff\n", color);
7925 color = getPixelColor(device, 88, 112);
7926 ok(color == 0x000000ff,
7927 "pixel 88/112 has color %08x, expected 0x000000ff\n", color);
7928 color = getPixelColor(device, 92, 112);
7929 ok(color == 0x00ffff00,
7930 "pixel 92/112 has color %08x, expected 0x00ffff00\n", color);
7932 color = getPixelColor(device, 568, 108);
7933 ok(color == 0x000000ff,
7934 "pixel 568/108 has color %08x, expected 0x000000ff\n", color);
7935 color = getPixelColor(device, 572, 108);
7936 ok(color == 0x000000ff,
7937 "pixel 572/108 has color %08x, expected 0x000000ff\n", color);
7938 color = getPixelColor(device, 568, 112);
7939 ok(color == 0x00ffff00,
7940 "pixel 568/112 has color %08x, expected 0x00ffff00\n", color);
7941 color = getPixelColor(device, 572, 112);
7942 ok(color == 0x000000ff,
7943 "pixel 572/112 has color %08x, expected 0x000000ff\n", color);
7945 color = getPixelColor(device, 88, 298);
7946 ok(color == 0x000000ff,
7947 "pixel 88/298 has color %08x, expected 0x000000ff\n", color);
7948 color = getPixelColor(device, 92, 298);
7949 ok(color == 0x00ffff00,
7950 "pixel 92/298 has color %08x, expected 0x00ffff00\n", color);
7951 color = getPixelColor(device, 88, 302);
7952 ok(color == 0x000000ff,
7953 "pixel 88/302 has color %08x, expected 0x000000ff\n", color);
7954 color = getPixelColor(device, 92, 302);
7955 ok(color == 0x000000ff,
7956 "pixel 92/302 has color %08x, expected 0x000000ff\n", color);
7958 color = getPixelColor(device, 568, 298);
7959 ok(color == 0x00ffff00,
7960 "pixel 568/298 has color %08x, expected 0x00ffff00\n", color);
7961 color = getPixelColor(device, 572, 298);
7962 ok(color == 0x000000ff,
7963 "pixel 572/298 has color %08x, expected 0x000000ff\n", color);
7964 color = getPixelColor(device, 568, 302);
7965 ok(color == 0x000000ff,
7966 "pixel 568/302 has color %08x, expected 0x000000ff\n", color);
7967 color = getPixelColor(device, 572, 302);
7968 ok(color == 0x000000ff,
7969 "pixel 572/302 has color %08x, expected 0x000000ff\n", color);
7971 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
7973 refcount = IDirect3DDevice8_Release(device);
7974 ok(!refcount, "Device has %u references left.\n", refcount);
7975 done:
7976 IDirect3D8_Release(d3d);
7977 DestroyWindow(window);
7980 static void test_flip(void)
7982 IDirect3DDevice8 *device;
7983 IDirect3D8 *d3d;
7984 ULONG refcount;
7985 HWND window;
7986 HRESULT hr;
7987 IDirect3DSurface8 *back_buffers[3], *test_surface;
7988 unsigned int i;
7989 D3DCOLOR color;
7990 D3DPRESENT_PARAMETERS present_parameters = {0};
7992 window = create_window();
7993 d3d = Direct3DCreate8(D3D_SDK_VERSION);
7994 ok(!!d3d, "Failed to create a D3D object.\n");
7996 present_parameters.BackBufferWidth = 640;
7997 present_parameters.BackBufferHeight = 480;
7998 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
7999 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
8000 present_parameters.hDeviceWindow = window;
8001 present_parameters.Windowed = TRUE;
8002 present_parameters.BackBufferCount = 3;
8003 present_parameters.Flags = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER;
8004 hr = IDirect3D8_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
8005 window, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device);
8006 if (!device)
8008 skip("Failed to create a D3D device, skipping tests.\n");
8009 IDirect3D8_Release(d3d);
8010 DestroyWindow(window);
8011 return;
8014 for (i = 0; i < sizeof(back_buffers) / sizeof(*back_buffers); ++i)
8016 hr = IDirect3DDevice8_GetBackBuffer(device, i, D3DBACKBUFFER_TYPE_MONO, &back_buffers[i]);
8017 ok(SUCCEEDED(hr), "Failed to get back buffer, hr %#x.\n", hr);
8019 hr = IDirect3DDevice8_GetRenderTarget(device, &test_surface);
8020 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
8021 ok(test_surface == back_buffers[0], "Expected render target %p, got %p.\n", back_buffers[0], test_surface);
8022 IDirect3DSurface8_Release(test_surface);
8025 hr = IDirect3DDevice8_SetRenderTarget(device, back_buffers[0], NULL);
8026 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
8027 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0f, 0);
8028 ok(SUCCEEDED(hr), "Failed to clear, hr %#x\n", hr);
8030 hr = IDirect3DDevice8_SetRenderTarget(device, back_buffers[1], NULL);
8031 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
8032 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0f, 0);
8033 ok(SUCCEEDED(hr), "Failed to clear, hr %#x\n", hr);
8035 hr = IDirect3DDevice8_SetRenderTarget(device, back_buffers[2], NULL);
8036 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
8037 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0f, 0);
8038 ok(SUCCEEDED(hr), "Failed to clear, hr %#x\n", hr);
8040 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
8041 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
8043 /* Render target is unmodified. */
8044 hr = IDirect3DDevice8_GetRenderTarget(device, &test_surface);
8045 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
8046 ok(test_surface == back_buffers[2], "Expected render target %p, got %p.\n", back_buffers[2], test_surface);
8047 IDirect3DSurface8_Release(test_surface);
8049 /* Backbuffer surface pointers are unmodified */
8050 for (i = 0; i < sizeof(back_buffers) / sizeof(*back_buffers); ++i)
8052 hr = IDirect3DDevice8_GetBackBuffer(device, i, D3DBACKBUFFER_TYPE_MONO, &test_surface);
8053 ok(SUCCEEDED(hr), "Failed to get back buffer, hr %#x.\n", hr);
8054 ok(test_surface == back_buffers[i], "Expected back buffer %u = %p, got %p.\n",
8055 i, back_buffers[i], test_surface);
8056 IDirect3DSurface8_Release(test_surface);
8059 /* Contents were changed. */
8060 color = get_surface_color(back_buffers[0], 1, 1);
8061 ok(color == 0xff00ff00, "Got unexpected color 0x%08x.\n", color);
8062 color = get_surface_color(back_buffers[1], 1, 1);
8063 ok(color == 0xff0000ff, "Got unexpected color 0x%08x.\n", color);
8065 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff808080, 0.0f, 0);
8066 ok(SUCCEEDED(hr), "Failed to clear, hr %#x\n", hr);
8068 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
8069 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
8071 color = get_surface_color(back_buffers[0], 1, 1);
8072 ok(color == 0xff0000ff, "Got unexpected color 0x%08x.\n", color);
8073 color = get_surface_color(back_buffers[1], 1, 1);
8074 ok(color == 0xff808080, "Got unexpected color 0x%08x.\n", color);
8076 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
8077 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
8079 color = get_surface_color(back_buffers[0], 1, 1);
8080 ok(color == 0xff808080, "Got unexpected color 0x%08x.\n", color);
8082 for (i = 0; i < sizeof(back_buffers) / sizeof(*back_buffers); ++i)
8083 IDirect3DSurface8_Release(back_buffers[i]);
8085 refcount = IDirect3DDevice8_Release(device);
8086 ok(!refcount, "Device has %u references left.\n", refcount);
8088 if (FAILED(IDirect3D8_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
8089 D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES)))
8091 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping multisample flip test.\n");
8092 goto done;
8095 present_parameters.BackBufferCount = 2;
8096 present_parameters.MultiSampleType = D3DMULTISAMPLE_2_SAMPLES;
8097 present_parameters.Flags = 0;
8098 hr = IDirect3D8_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
8099 window, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device);
8101 for (i = 0; i < present_parameters.BackBufferCount; ++i)
8103 hr = IDirect3DDevice8_GetBackBuffer(device, i, D3DBACKBUFFER_TYPE_MONO, &back_buffers[i]);
8104 ok(SUCCEEDED(hr), "Failed to get back buffer, hr %#x.\n", hr);
8107 hr = IDirect3DDevice8_SetRenderTarget(device, back_buffers[1], NULL);
8108 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
8109 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff808080, 0.0f, 0);
8110 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
8112 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
8113 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
8115 hr = IDirect3DDevice8_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
8116 D3DMULTISAMPLE_NONE, TRUE, &test_surface);
8117 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
8118 hr = IDirect3DDevice8_CopyRects(device, back_buffers[0], NULL, 0, test_surface, NULL);
8119 ok(SUCCEEDED(hr), "CopyRects failed, hr %#x.\n", hr);
8121 color = get_surface_color(test_surface, 1, 1);
8122 ok(color == 0xff808080, "Got unexpected color 0x%08x.\n", color);
8124 IDirect3DSurface8_Release(test_surface);
8125 for (i = 0; i < present_parameters.BackBufferCount; ++i)
8126 IDirect3DSurface8_Release(back_buffers[i]);
8128 refcount = IDirect3DDevice8_Release(device);
8129 ok(!refcount, "Device has %u references left.\n", refcount);
8131 done:
8132 IDirect3D8_Release(d3d);
8133 DestroyWindow(window);
8136 static void test_uninitialized_varyings(void)
8138 static const D3DMATRIX mat =
8140 1.0f, 0.0f, 0.0f, 0.0f,
8141 0.0f, 1.0f, 0.0f, 0.0f,
8142 0.0f, 0.0f, 1.0f, 0.0f,
8143 0.0f, 0.0f, 0.0f, 1.0f,
8144 }}};
8145 static const struct vec3 quad[] =
8147 {-1.0f, -1.0f, 0.1f},
8148 {-1.0f, 1.0f, 0.1f},
8149 { 1.0f, -1.0f, 0.1f},
8150 { 1.0f, 1.0f, 0.1f},
8152 static const DWORD decl[] =
8154 D3DVSD_STREAM(0),
8155 D3DVSD_REG(0, D3DVSDT_FLOAT3),
8156 D3DVSD_CONST(0, 1), 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, /* def c0, 0.5, 0.5, 0.5, 0.5 */
8157 D3DVSD_END()
8159 static const DWORD vs1_code[] =
8161 0xfffe0101, /* vs_1_1 */
8162 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
8163 0x0000ffff
8165 static const DWORD vs1_partial_code[] =
8167 0xfffe0101, /* vs_1_1 */
8168 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
8169 0x00000001, 0xd0010000, 0xa0e40000, /* mov oD0.x, c0 */
8170 0x00000001, 0xd0010001, 0xa0e40000, /* mov oD1.x, c0 */
8171 0x00000001, 0xe0010000, 0xa0e40000, /* mov oT0.x, c0 */
8172 0x0000ffff
8174 static const DWORD ps1_diffuse_code[] =
8176 0xffff0101, /* ps_1_1 */
8177 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
8178 0x0000ffff
8180 static const DWORD ps1_specular_code[] =
8182 0xffff0101, /* ps_1_1 */
8183 0x00000001, 0x800f0000, 0x90e40001, /* mov r0, v1 */
8184 0x0000ffff
8186 static const DWORD ps1_texcoord_code[] =
8188 0xffff0101, /* ps_1_1 */
8189 0x00000040, 0xb00f0000, /* texcoord t0 */
8190 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
8191 0x0000ffff
8193 static const struct
8195 DWORD vs_version;
8196 const DWORD *vs;
8197 DWORD ps_version;
8198 const DWORD *ps;
8199 D3DCOLOR expected;
8200 BOOL allow_zero_alpha;
8201 BOOL broken_warp;
8203 /* On AMD specular color is generally initialized to 0x00000000 and texcoords to 0xff000000
8204 * while on Nvidia it's the opposite. Just allow both. */
8205 tests[] =
8207 {D3DVS_VERSION(1, 1), vs1_code, 0, NULL, 0xffffffff},
8208 { 0, NULL, D3DPS_VERSION(1, 1), ps1_texcoord_code, 0xff000000, TRUE},
8209 {D3DVS_VERSION(1, 1), vs1_code, D3DPS_VERSION(1, 1), ps1_diffuse_code, 0xffffffff},
8210 {D3DVS_VERSION(1, 1), vs1_code, D3DPS_VERSION(1, 1), ps1_specular_code, 0xff000000, TRUE, TRUE},
8211 {D3DVS_VERSION(1, 1), vs1_code, D3DPS_VERSION(1, 1), ps1_texcoord_code, 0xff000000, TRUE},
8212 {D3DVS_VERSION(1, 1), vs1_partial_code, 0, NULL, 0xff7fffff, FALSE, TRUE},
8213 {D3DVS_VERSION(1, 1), vs1_partial_code, D3DPS_VERSION(1, 1), ps1_diffuse_code, 0xff7fffff, FALSE, TRUE},
8214 {D3DVS_VERSION(1, 1), vs1_partial_code, D3DPS_VERSION(1, 1), ps1_specular_code, 0xff7f0000, TRUE},
8215 {D3DVS_VERSION(1, 1), vs1_partial_code, D3DPS_VERSION(1, 1), ps1_texcoord_code, 0xff7f0000, TRUE},
8217 IDirect3DDevice8 *device;
8218 IDirect3D8 *d3d;
8219 HWND window;
8220 HRESULT hr;
8221 DWORD vs, ps;
8222 unsigned int i;
8223 ULONG refcount;
8224 D3DCAPS8 caps;
8225 IDirect3DSurface8 *backbuffer;
8226 D3DADAPTER_IDENTIFIER8 identifier;
8227 struct surface_readback rb;
8228 D3DCOLOR color;
8229 BOOL warp;
8231 window = create_window();
8232 d3d = Direct3DCreate8(D3D_SDK_VERSION);
8233 ok(!!d3d, "Failed to create a D3D object.\n");
8234 if (!(device = create_device(d3d, window, window, TRUE)))
8236 skip("Failed to create a D3D device, skipping tests.\n");
8237 IDirect3D8_Release(d3d);
8238 DestroyWindow(window);
8239 return;
8242 hr = IDirect3D8_GetAdapterIdentifier(d3d, D3DADAPTER_DEFAULT, 0, &identifier);
8243 ok(SUCCEEDED(hr), "Failed to get adapter identifier, hr %#x.\n", hr);
8244 warp = adapter_is_warp(&identifier);
8246 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
8247 ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
8249 hr = IDirect3DDevice8_GetBackBuffer(device, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8250 ok(SUCCEEDED(hr), "Failed to get back buffer, hr %#x.\n", hr);
8252 hr = IDirect3DDevice8_SetTransform(device, D3DTS_WORLD, &mat);
8253 ok(SUCCEEDED(hr), "Failed to set world transform, hr %#x.\n", hr);
8254 hr = IDirect3DDevice8_SetTransform(device, D3DTS_VIEW, &mat);
8255 ok(SUCCEEDED(hr), "Failed to set view transform, hr %#x.\n", hr);
8256 hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, &mat);
8257 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
8258 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, FALSE);
8259 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#x.\n", hr);
8260 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, FALSE);
8261 ok(SUCCEEDED(hr), "Failed to disable Z test, hr %#x.\n", hr);
8262 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
8263 ok(SUCCEEDED(hr), "Failed to disable fog, hr %#x.\n", hr);
8264 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
8265 ok(SUCCEEDED(hr), "Failed to disable stencil test, hr %#x.\n", hr);
8266 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8267 ok(SUCCEEDED(hr), "Failed to disable culling, hr %#x.\n", hr);
8269 for (i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i)
8271 if (caps.VertexShaderVersion < tests[i].vs_version
8272 || caps.PixelShaderVersion < tests[i].ps_version)
8274 skip("Vertex / pixel shader version not supported, skipping test %u.\n", i);
8275 continue;
8277 if (tests[i].vs)
8279 hr = IDirect3DDevice8_CreateVertexShader(device, decl, tests[i].vs, &vs, 0);
8280 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x (case %u).\n", hr, i);
8281 hr = IDirect3DDevice8_SetVertexShader(device, vs);
8282 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
8284 else
8286 vs = 0;
8287 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ);
8288 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
8290 if (tests[i].ps)
8292 hr = IDirect3DDevice8_CreatePixelShader(device, tests[i].ps, &ps);
8293 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x (case %u).\n", hr, i);
8295 else
8297 ps = 0;
8300 hr = IDirect3DDevice8_SetPixelShader(device, ps);
8301 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
8303 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0f, 0);
8304 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
8306 hr = IDirect3DDevice8_BeginScene(device);
8307 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
8309 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
8310 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8312 hr = IDirect3DDevice8_EndScene(device);
8313 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
8315 get_rt_readback(backbuffer, &rb);
8316 color = get_readback_color(&rb, 320, 240);
8317 ok(color_match(color, tests[i].expected, 1)
8318 || (tests[i].allow_zero_alpha && color_match(color, tests[i].expected & 0x00ffffff, 1))
8319 || (broken(warp && tests[i].broken_warp)),
8320 "Got unexpected color 0x%08x, case %u.\n", color, i);
8321 release_surface_readback(&rb);
8323 if (vs)
8324 IDirect3DDevice8_DeleteVertexShader(device, vs);
8325 if (ps)
8326 IDirect3DDevice8_DeletePixelShader(device, ps);
8329 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
8330 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
8332 IDirect3DSurface8_Release(backbuffer);
8333 refcount = IDirect3DDevice8_Release(device);
8334 ok(!refcount, "Device has %u references left.\n", refcount);
8335 IDirect3D8_Release(d3d);
8336 DestroyWindow(window);
8339 static void test_shademode(void)
8341 IDirect3DVertexBuffer8 *vb_strip;
8342 IDirect3DVertexBuffer8 *vb_list;
8343 IDirect3DDevice8 *device;
8344 DWORD color0, color1;
8345 BYTE *data = NULL;
8346 IDirect3D8 *d3d;
8347 ULONG refcount;
8348 D3DCAPS8 caps;
8349 DWORD vs, ps;
8350 HWND window;
8351 HRESULT hr;
8352 UINT i;
8353 static const DWORD decl[] =
8355 D3DVSD_STREAM(0),
8356 D3DVSD_REG(D3DVSDE_POSITION, D3DVSDT_FLOAT3),
8357 D3DVSD_REG(D3DVSDE_DIFFUSE, D3DVSDT_D3DCOLOR),
8358 D3DVSD_END()
8360 static const DWORD vs1_code[] =
8362 0xfffe0101, /* vs_1_1 */
8363 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
8364 0x00000001, 0xd00f0000, 0x90e40005, /* mov oD0, v5 */
8365 0x0000ffff
8367 static const DWORD ps1_code[] =
8369 0xffff0101, /* ps_1_1 */
8370 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
8371 0x0000ffff
8373 static const struct
8375 struct vec3 position;
8376 DWORD diffuse;
8378 quad_strip[] =
8380 {{-1.0f, -1.0f, 0.0f}, 0xffff0000},
8381 {{-1.0f, 1.0f, 0.0f}, 0xff00ff00},
8382 {{ 1.0f, -1.0f, 0.0f}, 0xff0000ff},
8383 {{ 1.0f, 1.0f, 0.0f}, 0xffffffff},
8385 quad_list[] =
8387 {{-1.0f, -1.0f, 0.0f}, 0xffff0000},
8388 {{-1.0f, 1.0f, 0.0f}, 0xff00ff00},
8389 {{ 1.0f, -1.0f, 0.0f}, 0xff0000ff},
8391 {{ 1.0f, -1.0f, 0.0f}, 0xff0000ff},
8392 {{-1.0f, 1.0f, 0.0f}, 0xff00ff00},
8393 {{ 1.0f, 1.0f, 0.0f}, 0xffffffff},
8395 static const struct test_shader
8397 DWORD version;
8398 const DWORD *code;
8400 novs = {0, NULL},
8401 vs_1 = {D3DVS_VERSION(1, 1), vs1_code},
8402 nops = {0, NULL},
8403 ps_1 = {D3DPS_VERSION(1, 1), ps1_code};
8404 static const struct
8406 const struct test_shader *vs, *ps;
8407 DWORD primtype;
8408 DWORD shademode;
8409 DWORD color0, color1;
8411 tests[] =
8413 {&novs, &nops, D3DPT_TRIANGLESTRIP, D3DSHADE_FLAT, 0x00ff0000, 0x0000ff00},
8414 {&novs, &nops, D3DPT_TRIANGLESTRIP, D3DSHADE_PHONG, 0x000dca28, 0x000d45c7},
8415 {&novs, &nops, D3DPT_TRIANGLESTRIP, D3DSHADE_GOURAUD, 0x000dca28, 0x000d45c7},
8416 {&novs, &nops, D3DPT_TRIANGLESTRIP, D3DSHADE_PHONG, 0x000dca28, 0x000d45c7},
8417 {&novs, &nops, D3DPT_TRIANGLELIST, D3DSHADE_FLAT, 0x00ff0000, 0x000000ff},
8418 {&novs, &nops, D3DPT_TRIANGLELIST, D3DSHADE_GOURAUD, 0x000dca28, 0x000d45c7},
8419 {&vs_1, &ps_1, D3DPT_TRIANGLESTRIP, D3DSHADE_FLAT, 0x00ff0000, 0x0000ff00},
8420 {&vs_1, &ps_1, D3DPT_TRIANGLESTRIP, D3DSHADE_GOURAUD, 0x000dca28, 0x000d45c7},
8421 {&vs_1, &ps_1, D3DPT_TRIANGLELIST, D3DSHADE_FLAT, 0x00ff0000, 0x000000ff},
8422 {&vs_1, &ps_1, D3DPT_TRIANGLELIST, D3DSHADE_GOURAUD, 0x000dca28, 0x000d45c7},
8423 {&novs, &ps_1, D3DPT_TRIANGLESTRIP, D3DSHADE_FLAT, 0x00ff0000, 0x0000ff00},
8424 {&vs_1, &nops, D3DPT_TRIANGLESTRIP, D3DSHADE_FLAT, 0x00ff0000, 0x0000ff00},
8427 window = create_window();
8428 d3d = Direct3DCreate8(D3D_SDK_VERSION);
8429 ok(!!d3d, "Failed to create a D3D object.\n");
8430 if (!(device = create_device(d3d, window, window, TRUE)))
8432 skip("Failed to create a D3D device, skipping tests.\n");
8433 IDirect3D8_Release(d3d);
8434 DestroyWindow(window);
8435 return;
8438 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
8439 ok(hr == D3D_OK, "Failed to disable lighting, hr %#x.\n", hr);
8440 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
8441 ok(SUCCEEDED(hr), "Failed to disable fog, hr %#x.\n", hr);
8443 hr = IDirect3DDevice8_CreateVertexBuffer(device, sizeof(quad_strip), 0, 0, D3DPOOL_MANAGED, &vb_strip);
8444 ok(hr == D3D_OK, "Failed to create vertex buffer, hr %#x.\n", hr);
8445 hr = IDirect3DVertexBuffer8_Lock(vb_strip, 0, sizeof(quad_strip), &data, 0);
8446 ok(hr == D3D_OK, "Failed to lock vertex buffer, hr %#x.\n", hr);
8447 memcpy(data, quad_strip, sizeof(quad_strip));
8448 hr = IDirect3DVertexBuffer8_Unlock(vb_strip);
8449 ok(hr == D3D_OK, "Failed to unlock vertex buffer, hr %#x.\n", hr);
8451 hr = IDirect3DDevice8_CreateVertexBuffer(device, sizeof(quad_list), 0, 0, D3DPOOL_MANAGED, &vb_list);
8452 ok(hr == D3D_OK, "Failed to create vertex buffer, hr %#x.\n", hr);
8453 hr = IDirect3DVertexBuffer8_Lock(vb_list, 0, sizeof(quad_list), &data, 0);
8454 ok(hr == D3D_OK, "Failed to lock vertex buffer, hr %#x.\n", hr);
8455 memcpy(data, quad_list, sizeof(quad_list));
8456 hr = IDirect3DVertexBuffer8_Unlock(vb_list);
8457 ok(hr == D3D_OK, "Failed to unlock vertex buffer, hr %#x.\n", hr);
8459 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
8460 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
8462 /* Try it first with a TRIANGLESTRIP. Do it with different geometry because
8463 * the color fixups we have to do for FLAT shading will be dependent on that. */
8465 for (i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i)
8467 if (tests[i].vs->version)
8469 if (caps.VertexShaderVersion >= tests[i].vs->version)
8471 hr = IDirect3DDevice8_CreateVertexShader(device, decl, tests[i].vs->code, &vs, 0);
8472 ok(hr == D3D_OK, "Failed to create vertex shader, hr %#x.\n", hr);
8473 hr = IDirect3DDevice8_SetVertexShader(device, vs);
8474 ok(hr == D3D_OK, "Failed to set vertex shader, hr %#x.\n", hr);
8476 else
8478 skip("Shader version unsupported, skipping some tests.\n");
8479 continue;
8482 else
8484 vs = 0;
8485 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8486 ok(hr == D3D_OK, "Failed to set FVF, hr %#x.\n", hr);
8488 if (tests[i].ps->version)
8490 if (caps.PixelShaderVersion >= tests[i].ps->version)
8492 hr = IDirect3DDevice8_CreatePixelShader(device, tests[i].ps->code, &ps);
8493 ok(hr == D3D_OK, "Failed to create pixel shader, hr %#x.\n", hr);
8494 hr = IDirect3DDevice8_SetPixelShader(device, ps);
8495 ok(hr == D3D_OK, "Failed to set pixel shader, hr %#x.\n", hr);
8497 else
8499 skip("Shader version unsupported, skipping some tests.\n");
8500 if (vs)
8502 IDirect3DDevice8_SetVertexShader(device, 0);
8503 IDirect3DDevice8_DeleteVertexShader(device, vs);
8505 continue;
8508 else
8510 ps = 0;
8513 hr = IDirect3DDevice8_SetStreamSource(device, 0,
8514 tests[i].primtype == D3DPT_TRIANGLESTRIP ? vb_strip : vb_list, sizeof(quad_strip[0]));
8515 ok(hr == D3D_OK, "Failed to set stream source, hr %#x.\n", hr);
8517 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
8518 ok(hr == D3D_OK, "Failed to clear, hr %#x.\n", hr);
8520 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SHADEMODE, tests[i].shademode);
8521 ok(hr == D3D_OK, "Failed to set shade mode, hr %#x.\n", hr);
8523 hr = IDirect3DDevice8_BeginScene(device);
8524 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
8525 hr = IDirect3DDevice8_DrawPrimitive(device, tests[i].primtype, 0, 2);
8526 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8527 hr = IDirect3DDevice8_EndScene(device);
8528 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
8530 color0 = getPixelColor(device, 100, 100); /* Inside first triangle */
8531 color1 = getPixelColor(device, 500, 350); /* Inside second triangle */
8533 /* For D3DSHADE_FLAT it should take the color of the first vertex of
8534 * each triangle. This requires EXT_provoking_vertex or similar
8535 * functionality being available. */
8536 /* PHONG should be the same as GOURAUD, since no hardware implements
8537 * this. */
8538 ok(color_match(color0, tests[i].color0, 1), "Test %u shading has color0 %08x, expected %08x.\n",
8539 i, color0, tests[i].color0);
8540 ok(color_match(color1, tests[i].color1, 1), "Test %u shading has color1 %08x, expected %08x.\n",
8541 i, color1, tests[i].color1);
8543 IDirect3DDevice8_SetVertexShader(device, 0);
8544 IDirect3DDevice8_SetPixelShader(device, 0);
8546 if (ps)
8547 IDirect3DDevice8_DeletePixelShader(device, ps);
8548 if (vs)
8549 IDirect3DDevice8_DeleteVertexShader(device, vs);
8552 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
8553 ok(hr == D3D_OK, "Failed to present, hr %#x.\n", hr);
8555 IDirect3DVertexBuffer8_Release(vb_strip);
8556 IDirect3DVertexBuffer8_Release(vb_list);
8557 refcount = IDirect3DDevice8_Release(device);
8558 ok(!refcount, "Device has %u references left.\n", refcount);
8559 IDirect3D8_Release(d3d);
8560 DestroyWindow(window);
8563 static void test_multisample_init(void)
8565 IDirect3DDevice8 *device;
8566 IDirect3D8 *d3d;
8567 IDirect3DSurface8 *back, *multi;
8568 ULONG refcount;
8569 HWND window;
8570 HRESULT hr;
8571 D3DCOLOR color;
8572 unsigned int x, y;
8573 struct surface_readback rb;
8574 BOOL all_zero = TRUE;
8576 window = create_window();
8577 d3d = Direct3DCreate8(D3D_SDK_VERSION);
8578 ok(!!d3d, "Failed to create a D3D object.\n");
8580 if (FAILED(IDirect3D8_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
8581 D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES)))
8583 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping multisample init test.\n");
8584 goto done;
8587 if (!(device = create_device(d3d, window, window, TRUE)))
8589 skip("Failed to create a D3D device, skipping tests.\n");
8590 goto done;
8593 hr = IDirect3DDevice8_GetBackBuffer(device, 0, D3DBACKBUFFER_TYPE_MONO, &back);
8594 ok(SUCCEEDED(hr), "Failed to get back buffer, hr %#x.\n", hr);
8595 hr = IDirect3DDevice8_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
8596 D3DMULTISAMPLE_2_SAMPLES, FALSE, &multi);
8597 ok(SUCCEEDED(hr), "Failed to create multisampled render target, hr %#x.\n", hr);
8599 hr = IDirect3DDevice8_CopyRects(device, multi, NULL, 0, back, NULL);
8600 ok(SUCCEEDED(hr), "CopyRects failed, hr %#x.\n", hr);
8602 get_rt_readback(back, &rb);
8603 for (y = 0; y < 480; ++y)
8605 for (x = 0; x < 640; ++x)
8607 color = get_readback_color(&rb, x, y);
8608 if (!color_match(color, 0x00000000, 0))
8610 all_zero = FALSE;
8611 break;
8614 if (!all_zero)
8615 break;
8617 release_surface_readback(&rb);
8618 ok(all_zero, "Got unexpected color 0x%08x, position %ux%u.\n", color, x, y);
8620 IDirect3DSurface8_Release(multi);
8621 IDirect3DSurface8_Release(back);
8623 refcount = IDirect3DDevice8_Release(device);
8624 ok(!refcount, "Device has %u references left.\n", refcount);
8626 done:
8627 IDirect3D8_Release(d3d);
8628 DestroyWindow(window);
8631 static void test_texture_blending(void)
8633 #define STATE_END() {0xffffffff, 0xffffffff}
8634 #define IS_STATE_END(s) (s.name == 0xffffffff && s.value == 0xffffffff)
8636 IDirect3DTexture8 *texture_bumpmap, *texture_red;
8637 IDirect3DSurface8 *backbuffer;
8638 struct surface_readback rb;
8639 D3DLOCKED_RECT locked_rect;
8640 IDirect3DDevice8 *device;
8641 unsigned int i, j, k;
8642 IDirect3D8 *d3d;
8643 D3DCOLOR color;
8644 ULONG refcount;
8645 D3DCAPS8 caps;
8646 HWND window;
8647 HRESULT hr;
8649 static const struct
8651 struct vec3 position;
8652 DWORD diffuse;
8654 quad[] =
8656 {{-1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0x80, 0xff, 0xff, 0x02)},
8657 {{-1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0x80, 0xff, 0xff, 0x02)},
8658 {{ 1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0x80, 0xff, 0xff, 0x02)},
8659 {{ 1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0x80, 0xff, 0xff, 0x02)},
8662 static const float bumpenvmat[4] = {1.0f, 1.0f, 0.0f, 0.0f};
8664 struct texture_stage_state
8666 D3DTEXTURESTAGESTATETYPE name;
8667 DWORD value;
8670 struct texture_stage
8672 enum
8674 TEXTURE_INVALID,
8675 TEXTURE_NONE,
8676 TEXTURE_BUMPMAP,
8677 TEXTURE_RED,
8679 texture;
8680 struct texture_stage_state state[20];
8683 static const struct texture_stage default_stage_state =
8685 TEXTURE_NONE,
8687 {D3DTSS_COLOROP, D3DTOP_DISABLE},
8688 {D3DTSS_COLORARG1, D3DTA_TEXTURE},
8689 {D3DTSS_COLORARG2, D3DTA_CURRENT},
8690 {D3DTSS_ALPHAOP, D3DTOP_DISABLE},
8691 {D3DTSS_ALPHAARG1, D3DTA_TEXTURE},
8692 {D3DTSS_ALPHAARG2, D3DTA_CURRENT},
8693 {D3DTSS_BUMPENVMAT00, 0},
8694 {D3DTSS_BUMPENVMAT01, 0},
8695 {D3DTSS_BUMPENVMAT10, 0},
8696 {D3DTSS_BUMPENVMAT11, 0},
8697 {D3DTSS_BUMPENVLSCALE, 0},
8698 {D3DTSS_BUMPENVLOFFSET, 0},
8699 {D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE},
8700 {D3DTSS_COLORARG0, D3DTA_CURRENT},
8701 {D3DTSS_ALPHAARG0, D3DTA_CURRENT},
8702 {D3DTSS_RESULTARG, D3DTA_CURRENT},
8703 STATE_END(),
8707 const struct test
8709 DWORD tex_op_caps;
8710 D3DCOLOR expected_color;
8711 struct texture_stage stage[8];
8713 tests[] =
8716 D3DTEXOPCAPS_DISABLE,
8717 0x80ffff02,
8720 TEXTURE_NONE,
8722 STATE_END(),
8728 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1,
8729 0x80ffff02,
8732 TEXTURE_NONE,
8734 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
8735 {D3DTSS_COLORARG1, D3DTA_CURRENT},
8736 STATE_END(),
8739 {TEXTURE_INVALID}
8743 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1,
8744 0x80ffff02,
8747 TEXTURE_NONE,
8749 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
8750 {D3DTSS_COLORARG1, D3DTA_CURRENT},
8751 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
8752 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
8753 STATE_END(),
8759 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1,
8760 0x80ffff02,
8763 TEXTURE_NONE,
8765 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
8766 {D3DTSS_COLORARG1, D3DTA_DIFFUSE},
8767 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
8768 {D3DTSS_ALPHAARG1, D3DTA_DIFFUSE},
8769 STATE_END(),
8775 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1,
8776 0x00000000,
8779 TEXTURE_NONE,
8781 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
8782 {D3DTSS_COLORARG1, D3DTA_TEMP},
8783 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
8784 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
8785 STATE_END(),
8792 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE,
8793 0x80ff0000,
8796 TEXTURE_BUMPMAP,
8798 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
8799 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
8800 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
8801 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
8802 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
8803 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
8804 {D3DTSS_ALPHAARG1, D3DTA_TEXTURE},
8805 STATE_END(),
8810 TEXTURE_RED,
8812 {D3DTSS_COLOROP, D3DTOP_MODULATE},
8813 STATE_END(),
8816 {TEXTURE_INVALID}
8820 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE,
8821 0x80ff0000,
8824 TEXTURE_BUMPMAP,
8826 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
8827 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
8828 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
8829 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
8830 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
8831 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
8832 {D3DTSS_ALPHAARG1, D3DTA_DIFFUSE},
8833 STATE_END(),
8837 TEXTURE_RED,
8839 {D3DTSS_COLOROP, D3DTOP_MODULATE},
8840 STATE_END(),
8843 {TEXTURE_INVALID}
8847 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE,
8848 0x80ff0000,
8851 TEXTURE_BUMPMAP,
8853 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
8854 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
8855 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
8856 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
8857 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
8858 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
8859 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
8860 STATE_END(),
8864 TEXTURE_RED,
8866 {D3DTSS_COLOROP, D3DTOP_MODULATE},
8867 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
8868 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
8869 STATE_END(),
8872 {TEXTURE_INVALID}
8876 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE,
8877 0x00ff0000,
8880 TEXTURE_BUMPMAP,
8882 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
8883 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
8884 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
8885 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
8886 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
8887 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
8888 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
8889 STATE_END(),
8893 TEXTURE_RED,
8895 {D3DTSS_COLOROP, D3DTOP_MODULATE},
8896 {D3DTSS_COLORARG1, D3DTA_TEXTURE},
8897 {D3DTSS_COLORARG2, D3DTA_CURRENT},
8898 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
8899 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
8900 STATE_END(),
8903 {TEXTURE_INVALID}
8907 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE,
8908 0x80ff0000,
8911 TEXTURE_BUMPMAP,
8913 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
8914 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
8915 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
8916 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
8917 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
8918 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
8919 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
8920 STATE_END(),
8924 TEXTURE_RED,
8926 {D3DTSS_COLOROP, D3DTOP_MODULATE},
8927 {D3DTSS_COLORARG1, D3DTA_TEXTURE},
8928 {D3DTSS_COLORARG2, D3DTA_CURRENT},
8929 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
8930 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
8931 STATE_END(),
8934 {TEXTURE_INVALID}
8939 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE
8940 | D3DTEXOPCAPS_ADD,
8941 0x80ff0000,
8944 TEXTURE_BUMPMAP,
8946 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
8947 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
8948 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
8949 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
8950 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
8951 {D3DTSS_ALPHAOP, D3DTOP_ADD},
8952 {D3DTSS_ALPHAARG1, D3DTA_DIFFUSE},
8953 {D3DTSS_ALPHAARG2, D3DTA_CURRENT},
8954 STATE_END(),
8958 TEXTURE_RED,
8960 {D3DTSS_COLOROP, D3DTOP_MODULATE},
8961 {D3DTSS_COLORARG1, D3DTA_TEXTURE},
8962 {D3DTSS_COLORARG2, D3DTA_CURRENT},
8963 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
8964 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
8965 STATE_END(),
8968 {TEXTURE_INVALID}
8972 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE
8973 | D3DTEXOPCAPS_MODULATE2X,
8974 0x80ffff00,
8977 TEXTURE_BUMPMAP,
8979 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
8980 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
8981 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
8982 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
8983 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
8984 {D3DTSS_ALPHAOP, D3DTOP_MODULATE2X},
8985 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
8986 {D3DTSS_ALPHAARG2, D3DTA_DIFFUSE},
8987 STATE_END(),
8991 TEXTURE_RED,
8993 {D3DTSS_COLOROP, D3DTOP_MODULATE},
8994 {D3DTSS_COLORARG1, D3DTA_CURRENT},
8995 {D3DTSS_COLORARG2, D3DTA_CURRENT},
8996 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
8997 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
8998 STATE_END(),
9001 {TEXTURE_INVALID}
9005 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP,
9006 0x80ffff02,
9009 TEXTURE_NONE,
9011 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
9012 {D3DTSS_COLORARG1, D3DTA_DIFFUSE},
9013 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
9014 {D3DTSS_ALPHAARG1, D3DTA_DIFFUSE},
9015 {D3DTSS_RESULTARG, D3DTA_TEMP},
9016 STATE_END(),
9020 TEXTURE_BUMPMAP,
9022 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
9023 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
9024 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
9025 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
9026 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
9027 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
9028 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
9029 {D3DTSS_RESULTARG, D3DTA_TEMP},
9030 STATE_END(),
9034 TEXTURE_RED,
9036 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
9037 {D3DTSS_COLORARG1, D3DTA_TEXTURE},
9038 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
9039 {D3DTSS_ALPHAARG1, D3DTA_TEXTURE},
9040 STATE_END(),
9044 TEXTURE_NONE,
9046 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
9047 {D3DTSS_COLORARG1, D3DTA_TEMP},
9048 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
9049 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
9050 STATE_END(),
9053 {TEXTURE_INVALID}
9058 window = create_window();
9059 d3d = Direct3DCreate8(D3D_SDK_VERSION);
9060 ok(!!d3d, "Failed to create a D3D object.\n");
9061 if (!(device = create_device(d3d, window, window, TRUE)))
9063 skip("Failed to create a D3D device.\n");
9064 goto done;
9067 memset(&caps, 0, sizeof(caps));
9068 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
9069 ok(hr == D3D_OK, "IDirect3DDevice8_GetDeviceCaps failed hr %#x.\n", hr);
9071 if(!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP))
9073 skip("D3DPMISCCAPS_TSSARGTEMP not supported.\n");
9074 IDirect3DDevice8_Release(device);
9075 goto done;
9078 if (FAILED(IDirect3D8_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
9079 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_V8U8)))
9081 skip("D3DFMT_V8U8 not supported for legacy bump mapping.\n");
9082 IDirect3DDevice8_Release(device);
9083 goto done;
9086 hr = IDirect3DDevice8_GetBackBuffer(device, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9087 ok(hr == D3D_OK, "Can't get back buffer, hr %#x.\n", hr);
9089 hr = IDirect3DDevice8_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture_bumpmap);
9090 ok(hr == D3D_OK, "IDirect3DDevice8_CreateTexture failed, hr %#x.\n", hr);
9091 hr = IDirect3DDevice8_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture_red);
9092 ok(hr == D3D_OK, "IDirect3DDevice8_CreateTexture failed, hr %#x.\n", hr);
9094 memset(&locked_rect, 0, sizeof(locked_rect));
9095 hr = IDirect3DTexture8_LockRect(texture_bumpmap, 0, &locked_rect, NULL, 0);
9096 ok(SUCCEEDED(hr), "LockRect failed, hr %#x.\n", hr);
9097 *((WORD *)locked_rect.pBits) = 0xff00;
9098 hr = IDirect3DTexture8_UnlockRect(texture_bumpmap, 0);
9099 ok(SUCCEEDED(hr), "UnlockRect failed, hr %#x.\n", hr);
9101 memset(&locked_rect, 0, sizeof(locked_rect));
9102 hr = IDirect3DTexture8_LockRect(texture_red, 0, &locked_rect, NULL, 0);
9103 ok(SUCCEEDED(hr), "LockRect failed, hr %#x.\n", hr);
9104 *((DWORD *)locked_rect.pBits) = 0x00ff0000;
9105 hr = IDirect3DTexture8_UnlockRect(texture_red, 0);
9106 ok(SUCCEEDED(hr), "UnlockRect failed, hr %#x.\n", hr);
9108 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9109 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
9110 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9111 ok(hr == D3D_OK, "Failed to disable lighting, hr %#x.\n", hr);
9113 for (i = 0; i < sizeof(tests) / sizeof(*tests); ++i)
9115 const struct test *current_test = &tests[i];
9117 if ((caps.TextureOpCaps & current_test->tex_op_caps) != current_test->tex_op_caps)
9119 skip("Texture operations %#x not supported.\n", current_test->tex_op_caps);
9120 continue;
9123 for (j = 0; j < caps.MaxTextureBlendStages; ++j)
9125 IDirect3DTexture8 *current_texture = NULL;
9127 for (k = 0; !IS_STATE_END(default_stage_state.state[k]); ++k)
9129 hr = IDirect3DDevice8_SetTextureStageState(device, j,
9130 default_stage_state.state[k].name, default_stage_state.state[k].value);
9131 ok(SUCCEEDED(hr), "Test %u: SetTextureStageState failed, hr %#x.\n", i, hr);
9134 if (current_test->stage[j].texture != TEXTURE_INVALID)
9136 const struct texture_stage_state *current_state = current_test->stage[j].state;
9138 switch (current_test->stage[j].texture)
9140 case TEXTURE_RED:
9141 current_texture = texture_red;
9142 break;
9143 case TEXTURE_BUMPMAP:
9144 current_texture = texture_bumpmap;
9145 break;
9146 default:
9147 current_texture = NULL;
9148 break;
9151 for (k = 0; !IS_STATE_END(current_state[k]); ++k)
9153 hr = IDirect3DDevice8_SetTextureStageState(device, j,
9154 current_state[k].name, current_state[k].value);
9155 ok(SUCCEEDED(hr), "Test %u: SetTextureStageState failed, hr %#x.\n", i, hr);
9159 hr = IDirect3DDevice8_SetTexture(device, j, (IDirect3DBaseTexture8 *)current_texture);
9160 ok(SUCCEEDED(hr), "Test %u: SetTexture failed, hr %#x.\n", i, hr);
9163 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
9164 ok(hr == D3D_OK, "Test %u: IDirect3DDevice8_Clear failed, hr %#x.\n", i, hr);
9166 hr = IDirect3DDevice8_BeginScene(device);
9167 ok(SUCCEEDED(hr), "Test %u: BeginScene failed, hr %#x.\n", i, hr);
9168 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
9169 ok(SUCCEEDED(hr), "Test %u: DrawPrimitiveUP failed, hr %#x.\n", i, hr);
9170 hr = IDirect3DDevice8_EndScene(device);
9171 ok(SUCCEEDED(hr), "Test %u: EndScene failed, hr %#x.\n", i, hr);
9173 get_rt_readback(backbuffer, &rb);
9174 color = get_readback_color(&rb, 320, 240);
9175 ok(color_match(color, current_test->expected_color, 1),
9176 "Test %u: Got color 0x%08x, expected 0x%08x.\n", i, color, current_test->expected_color);
9177 release_surface_readback(&rb);
9178 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
9179 ok(SUCCEEDED(hr), "Test %u: Present failed, hr %#x.\n", i, hr);
9182 IDirect3DTexture8_Release(texture_bumpmap);
9183 IDirect3DTexture8_Release(texture_red);
9184 IDirect3DSurface8_Release(backbuffer);
9185 refcount = IDirect3DDevice8_Release(device);
9186 ok(!refcount, "Device has %u references left.\n", refcount);
9187 done:
9188 IDirect3D8_Release(d3d);
9189 DestroyWindow(window);
9192 static void test_color_clamping(void)
9194 static const D3DMATRIX mat =
9196 1.0f, 0.0f, 0.0f, 0.0f,
9197 0.0f, 1.0f, 0.0f, 0.0f,
9198 0.0f, 0.0f, 1.0f, 0.0f,
9199 0.0f, 0.0f, 0.0f, 1.0f,
9200 }}};
9201 static const struct vec3 quad[] =
9203 {-1.0f, -1.0f, 0.1f},
9204 {-1.0f, 1.0f, 0.1f},
9205 { 1.0f, -1.0f, 0.1f},
9206 { 1.0f, 1.0f, 0.1f},
9208 static const DWORD decl[] =
9210 D3DVSD_STREAM(0),
9211 D3DVSD_REG(D3DVSDE_POSITION, D3DVSDT_FLOAT3),
9212 D3DVSD_CONST(0, 1), 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c0, 1.0, 1.0, 1.0, 1.0 */
9213 D3DVSD_END()
9215 static const DWORD vs1_code[] =
9217 0xfffe0101, /* vs_1_1 */
9218 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
9219 0x00000002, 0xd00f0000, 0xa0e40000, 0xa0e40000, /* add oD0, c0, c0 */
9220 0x00000002, 0xd00f0001, 0xa0e40000, 0xa0e40000, /* add oD1, c0, c0 */
9221 0x0000ffff
9223 static const DWORD ps1_code[] =
9225 0xffff0101, /* ps_1_1 */
9226 0x00000051, 0xa00f0000, 0x3e800000, 0x3e800000, 0x3e800000, 0x3e800000, /* def c0, 0.25, 0.25, 0.25, 0.25 */
9227 0x00000002, 0x800f0000, 0x90e40000, 0x90e40001, /* add r0, v0, v1 */
9228 0x00000005, 0x800f0000, 0x80e40000, 0xa0e40000, /* mul r0, r0, c0 */
9229 0x0000ffff
9231 static const struct
9233 DWORD vs_version;
9234 const DWORD *vs;
9235 DWORD ps_version;
9236 const DWORD *ps;
9237 D3DCOLOR expected, broken;
9239 tests[] =
9241 {0, NULL, 0, NULL, 0x00404040},
9242 {0, NULL, D3DPS_VERSION(1, 1), ps1_code, 0x00404040, 0x00808080},
9243 {D3DVS_VERSION(1, 1), vs1_code, 0, NULL, 0x00404040},
9244 {D3DVS_VERSION(1, 1), vs1_code, D3DPS_VERSION(1, 1), ps1_code, 0x007f7f7f},
9246 IDirect3DDevice8 *device;
9247 IDirect3D8 *d3d;
9248 unsigned int i;
9249 ULONG refcount;
9250 D3DCOLOR color;
9251 D3DCAPS8 caps;
9252 DWORD vs, ps;
9253 HWND window;
9254 HRESULT hr;
9256 window = create_window();
9257 d3d = Direct3DCreate8(D3D_SDK_VERSION);
9258 ok(!!d3d, "Failed to create a D3D object.\n");
9259 if (!(device = create_device(d3d, window, window, TRUE)))
9261 skip("Failed to create a D3D device, skipping tests.\n");
9262 IDirect3D8_Release(d3d);
9263 DestroyWindow(window);
9264 return;
9267 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
9268 ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
9270 hr = IDirect3DDevice8_SetTransform(device, D3DTS_WORLD, &mat);
9271 ok(SUCCEEDED(hr), "Failed to set world transform, hr %#x.\n", hr);
9272 hr = IDirect3DDevice8_SetTransform(device, D3DTS_VIEW, &mat);
9273 ok(SUCCEEDED(hr), "Failed to set view transform, hr %#x.\n", hr);
9274 hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, &mat);
9275 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
9276 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, FALSE);
9277 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#x.\n", hr);
9278 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, FALSE);
9279 ok(SUCCEEDED(hr), "Failed to disable Z test, hr %#x.\n", hr);
9280 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
9281 ok(SUCCEEDED(hr), "Failed to disable fog, hr %#x.\n", hr);
9282 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
9283 ok(SUCCEEDED(hr), "Failed to disable stencil test, hr %#x.\n", hr);
9284 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
9285 ok(SUCCEEDED(hr), "Failed to disable culling, hr %#x.\n", hr);
9286 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9287 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
9289 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xff404040);
9290 ok(SUCCEEDED(hr), "Failed to set texture factor, hr %#x.\n", hr);
9291 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
9292 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
9293 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9294 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
9295 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_SPECULAR);
9296 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
9297 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_MODULATE);
9298 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
9299 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TFACTOR);
9300 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
9301 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
9302 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
9304 for (i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i)
9306 if (caps.VertexShaderVersion < tests[i].vs_version
9307 || caps.PixelShaderVersion < tests[i].ps_version)
9309 skip("Vertex / pixel shader version not supported, skipping test %u.\n", i);
9310 continue;
9312 if (tests[i].vs)
9314 hr = IDirect3DDevice8_CreateVertexShader(device, decl, tests[i].vs, &vs, 0);
9315 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x (case %u).\n", hr, i);
9317 else
9319 vs = D3DFVF_XYZ;
9321 if (tests[i].ps)
9323 hr = IDirect3DDevice8_CreatePixelShader(device, tests[i].ps, &ps);
9324 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x (case %u).\n", hr, i);
9326 else
9328 ps = 0;
9331 hr = IDirect3DDevice8_SetVertexShader(device, vs);
9332 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
9333 hr = IDirect3DDevice8_SetPixelShader(device, ps);
9334 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
9336 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0f, 0);
9337 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
9339 hr = IDirect3DDevice8_BeginScene(device);
9340 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9342 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
9343 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9345 hr = IDirect3DDevice8_EndScene(device);
9346 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9348 color = getPixelColor(device, 320, 240);
9349 ok(color_match(color, tests[i].expected, 1) || broken(color_match(color, tests[i].broken, 1)),
9350 "Got unexpected color 0x%08x, case %u.\n", color, i);
9352 if (vs != D3DFVF_XYZ)
9353 IDirect3DDevice8_DeleteVertexShader(device, vs);
9354 if (ps)
9355 IDirect3DDevice8_DeletePixelShader(device, ps);
9358 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
9359 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
9361 refcount = IDirect3DDevice8_Release(device);
9362 ok(!refcount, "Device has %u references left.\n", refcount);
9363 IDirect3D8_Release(d3d);
9364 DestroyWindow(window);
9367 static void test_edge_antialiasing_blending(void)
9369 IDirect3DDevice8 *device;
9370 IDirect3D8 *d3d8;
9371 ULONG refcount;
9372 D3DCOLOR color;
9373 D3DCAPS8 caps;
9374 HWND window;
9375 HRESULT hr;
9377 static const struct
9379 struct vec3 position;
9380 DWORD diffuse;
9382 green_quad[] =
9384 {{-1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0x7f, 0x00, 0xff, 0x00)},
9385 {{-1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0x7f, 0x00, 0xff, 0x00)},
9386 {{ 1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0x7f, 0x00, 0xff, 0x00)},
9387 {{ 1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0x7f, 0x00, 0xff, 0x00)},
9389 static const struct
9391 struct vec3 position;
9392 DWORD diffuse;
9394 red_quad[] =
9396 {{-1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0xcc, 0xff, 0x00, 0x00)},
9397 {{-1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0xcc, 0xff, 0x00, 0x00)},
9398 {{ 1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0xcc, 0xff, 0x00, 0x00)},
9399 {{ 1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0xcc, 0xff, 0x00, 0x00)},
9402 window = create_window();
9403 d3d8 = Direct3DCreate8(D3D_SDK_VERSION);
9404 ok(!!d3d8, "Failed to create a D3D object.\n");
9405 if (!(device = create_device(d3d8, window, window, TRUE)))
9407 skip("Failed to create a D3D device.\n");
9408 IDirect3D8_Release(d3d8);
9409 DestroyWindow(window);
9410 return;
9413 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
9414 ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
9415 trace("Edge antialiasing support: %#x.\n", caps.RasterCaps & D3DPRASTERCAPS_ANTIALIASEDGES);
9417 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, FALSE);
9418 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#x.\n", hr);
9419 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, FALSE);
9420 ok(SUCCEEDED(hr), "Failed to disable Z test, hr %#x.\n", hr);
9421 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9422 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
9424 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
9425 ok(SUCCEEDED(hr), "Failed to enable blending, hr %#x.\n", hr);
9426 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_BLENDOP, D3DBLENDOP_ADD);
9427 ok(SUCCEEDED(hr), "Failed to set blend op, hr %#x.\n", hr);
9428 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
9429 ok(SUCCEEDED(hr), "Failed to set src blend, hr %#x.\n", hr);
9430 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_DESTALPHA);
9431 ok(SUCCEEDED(hr), "Failed to set dest blend, hr %#x.\n", hr);
9433 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9434 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
9435 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9436 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
9437 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
9438 ok(SUCCEEDED(hr), "Failed to set alpha op, hr %#x.\n", hr);
9439 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
9440 ok(SUCCEEDED(hr), "Failed to set alpha arg, hr %#x.\n", hr);
9442 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9443 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
9445 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xccff0000, 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, green_quad, sizeof(*green_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_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x7f00ff00, 0.0f, 0);
9457 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
9458 hr = IDirect3DDevice8_BeginScene(device);
9459 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9460 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, red_quad, sizeof(*red_quad));
9461 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9462 hr = IDirect3DDevice8_EndScene(device);
9463 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9464 color = getPixelColor(device, 320, 240);
9465 ok(color_match(color, 0x00cc7f00, 1), "Got unexpected color 0x%08x.\n", color);
9467 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
9468 ok(SUCCEEDED(hr), "Failed to disable blending, hr %#x.\n", hr);
9470 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xccff0000, 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, green_quad, sizeof(*green_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, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
9481 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x7f00ff00, 0.0f, 0);
9482 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
9483 hr = IDirect3DDevice8_BeginScene(device);
9484 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9485 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, red_quad, sizeof(*red_quad));
9486 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9487 hr = IDirect3DDevice8_EndScene(device);
9488 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9489 color = getPixelColor(device, 320, 240);
9490 ok(color_match(color, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color);
9492 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_EDGEANTIALIAS, TRUE);
9493 ok(SUCCEEDED(hr), "Failed to enable edge antialiasing, hr %#x.\n", hr);
9495 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xccff0000, 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, green_quad, sizeof(*green_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, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
9506 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x7f00ff00, 0.0f, 0);
9507 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
9508 hr = IDirect3DDevice8_BeginScene(device);
9509 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9510 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, red_quad, sizeof(*red_quad));
9511 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9512 hr = IDirect3DDevice8_EndScene(device);
9513 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9514 color = getPixelColor(device, 320, 240);
9515 ok(color_match(color, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color);
9517 refcount = IDirect3DDevice8_Release(device);
9518 ok(!refcount, "Device has %u references left.\n", refcount);
9519 IDirect3D8_Release(d3d8);
9520 DestroyWindow(window);
9523 /* This test shows that 0xffff is valid index in D3D8. */
9524 static void test_max_index16(void)
9526 static const struct vertex
9528 struct vec3 position;
9529 DWORD diffuse;
9531 green_quad[] =
9533 {{-1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
9534 {{-1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
9535 {{ 1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
9536 {{ 1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
9538 static const unsigned short indices[] = {0, 1, 2, 0xffff};
9539 static const unsigned int vertex_count = 0xffff + 1;
9541 D3DADAPTER_IDENTIFIER8 identifier;
9542 IDirect3DVertexBuffer8 *vb;
9543 IDirect3DIndexBuffer8 *ib;
9544 IDirect3DDevice8 *device;
9545 struct vertex *vb_data;
9546 IDirect3D8 *d3d8;
9547 ULONG refcount;
9548 D3DCOLOR color;
9549 D3DCAPS8 caps;
9550 HWND window;
9551 BYTE *data;
9552 HRESULT hr;
9553 BOOL warp;
9555 window = create_window();
9556 d3d8 = Direct3DCreate8(D3D_SDK_VERSION);
9557 ok(!!d3d8, "Failed to create a D3D object.\n");
9559 hr = IDirect3D8_GetAdapterIdentifier(d3d8, D3DADAPTER_DEFAULT, 0, &identifier);
9560 ok(SUCCEEDED(hr), "Failed to get adapter identifier, hr %#x.\n", hr);
9561 warp = adapter_is_warp(&identifier);
9563 if (!(device = create_device(d3d8, window, window, TRUE)))
9565 skip("Failed to create a D3D device.\n");
9566 IDirect3D8_Release(d3d8);
9567 DestroyWindow(window);
9568 return;
9571 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
9572 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
9573 if (caps.MaxVertexIndex < 0xffff)
9575 skip("Max vertex index is lower than 0xffff (%#x).\n", caps.MaxVertexIndex);
9576 IDirect3DDevice8_Release(device);
9577 IDirect3D8_Release(d3d8);
9578 DestroyWindow(window);
9579 return;
9582 hr = IDirect3DDevice8_CreateVertexBuffer(device, vertex_count * sizeof(*green_quad), 0,
9583 D3DFVF_XYZ | D3DFVF_DIFFUSE, D3DPOOL_MANAGED, &vb);
9584 ok(SUCCEEDED(hr), "Failed to create vertex buffer, hr %#x.\n", hr);
9586 hr = IDirect3DDevice8_CreateIndexBuffer(device, sizeof(indices), 0,
9587 D3DFMT_INDEX16, D3DPOOL_MANAGED, &ib);
9588 ok(SUCCEEDED(hr), "Failed to create index buffer, hr %#x.\n", hr);
9590 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, FALSE);
9591 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#x.\n", hr);
9592 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, FALSE);
9593 ok(SUCCEEDED(hr), "Failed to disable Z test, hr %#x.\n", hr);
9594 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9595 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
9597 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9598 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
9600 hr = IDirect3DVertexBuffer8_Lock(vb, 0, sizeof(green_quad), (BYTE **)&vb_data, 0);
9601 ok(hr == D3D_OK, "Failed to lock vertex buffer, hr %#x.\n", hr);
9602 vb_data[0] = green_quad[0];
9603 vb_data[1] = green_quad[1];
9604 vb_data[2] = green_quad[2];
9605 vb_data[0xffff] = green_quad[3];
9606 hr = IDirect3DVertexBuffer8_Unlock(vb);
9607 ok(hr == D3D_OK, "Failed to unlock vertex buffer, hr %#x.\n", hr);
9609 hr = IDirect3DIndexBuffer8_Lock(ib, 0, sizeof(indices), &data, 0);
9610 ok(hr == D3D_OK, "Failed to lock index buffer, hr %#x.\n", hr);
9611 memcpy(data, indices, sizeof(indices));
9612 hr = IDirect3DIndexBuffer8_Unlock(ib);
9613 ok(hr == D3D_OK, "Failed to unlock index buffer, hr %#x.\n", hr);
9615 hr = IDirect3DDevice8_SetIndices(device, ib, 0);
9616 ok(hr == D3D_OK, "Failed to set index buffer, hr %#x.\n", hr);
9617 hr = IDirect3DDevice8_SetStreamSource(device, 0, vb, sizeof(struct vertex));
9618 ok(hr == D3D_OK, "Failed to set stream source, hr %#x.\n", hr);
9620 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
9621 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
9622 hr = IDirect3DDevice8_BeginScene(device);
9623 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9624 hr = IDirect3DDevice8_DrawIndexedPrimitive(device, D3DPT_TRIANGLESTRIP, 0, vertex_count, 0, 2);
9625 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9626 hr = IDirect3DDevice8_EndScene(device);
9627 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9628 color = getPixelColor(device, 20, 20);
9629 ok(color_match(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
9630 color = getPixelColor(device, 320, 240);
9631 ok(color_match(color, 0x0000ff00, 1) || broken(warp), "Got unexpected color 0x%08x.\n", color);
9632 color = getPixelColor(device, 620, 460);
9633 ok(color_match(color, 0x0000ff00, 1) || broken(warp), "Got unexpected color 0x%08x.\n", color);
9635 IDirect3DIndexBuffer8_Release(ib);
9636 IDirect3DVertexBuffer8_Release(vb);
9637 refcount = IDirect3DDevice8_Release(device);
9638 ok(!refcount, "Device has %u references left.\n", refcount);
9639 IDirect3D8_Release(d3d8);
9640 DestroyWindow(window);
9643 static void test_backbuffer_resize(void)
9645 D3DPRESENT_PARAMETERS present_parameters = {0};
9646 IDirect3DSurface8 *backbuffer;
9647 IDirect3DDevice8 *device;
9648 IDirect3D8 *d3d;
9649 D3DCOLOR color;
9650 ULONG refcount;
9651 HWND window;
9652 HRESULT hr;
9654 static const struct
9656 struct vec3 position;
9657 DWORD diffuse;
9659 quad[] =
9661 {{-1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
9662 {{-1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
9663 {{ 1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
9664 {{ 1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
9667 window = create_window();
9668 d3d = Direct3DCreate8(D3D_SDK_VERSION);
9669 ok(!!d3d, "Failed to create a D3D object.\n");
9670 if (!(device = create_device(d3d, window, window, TRUE)))
9672 skip("Failed to create a D3D device.\n");
9673 goto done;
9676 /* Wine d3d8 implementation had a bug which was triggered by a
9677 * SetRenderTarget() call with an unreferenced surface. */
9678 hr = IDirect3DDevice8_GetBackBuffer(device, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9679 ok(SUCCEEDED(hr), "Failed to get backbuffer, hr %#x.\n", hr);
9680 refcount = IDirect3DSurface8_Release(backbuffer);
9681 ok(!refcount, "Surface has %u references left.\n", refcount);
9682 hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, NULL);
9683 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
9684 hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, NULL);
9685 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
9687 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 1.0f, 0);
9688 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
9689 color = getPixelColor(device, 1, 1);
9690 ok(color == 0x00ff0000, "Got unexpected color 0x%08x.\n", color);
9692 present_parameters.BackBufferWidth = 800;
9693 present_parameters.BackBufferHeight = 600;
9694 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
9695 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
9696 present_parameters.hDeviceWindow = NULL;
9697 present_parameters.Windowed = TRUE;
9698 present_parameters.EnableAutoDepthStencil = TRUE;
9699 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
9700 hr = IDirect3DDevice8_Reset(device, &present_parameters);
9701 ok(SUCCEEDED(hr), "Failed to reset, hr %#x.\n", hr);
9703 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, FALSE);
9704 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#x.\n", hr);
9705 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, FALSE);
9706 ok(SUCCEEDED(hr), "Failed to disable Z test, hr %#x.\n", hr);
9707 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9708 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
9709 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9710 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
9712 hr = IDirect3DDevice8_GetBackBuffer(device, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9713 ok(SUCCEEDED(hr), "Failed to get backbuffer, hr %#x.\n", hr);
9714 hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, NULL);
9715 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
9716 IDirect3DSurface8_Release(backbuffer);
9718 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 1.0f, 0);
9719 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
9720 color = getPixelColor(device, 1, 1);
9721 ok(color == 0x00ffff00, "Got unexpected color 0x%08x.\n", color);
9722 color = getPixelColor(device, 700, 500);
9723 ok(color == 0x00ffff00, "Got unexpected color 0x%08x.\n", color);
9725 hr = IDirect3DDevice8_BeginScene(device);
9726 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9727 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9728 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9729 hr = IDirect3DDevice8_EndScene(device);
9730 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9731 color = getPixelColor(device, 1, 1);
9732 ok(color == 0x0000ff00, "Got unexpected color 0x%08x.\n", color);
9733 color = getPixelColor(device, 700, 500);
9734 ok(color == 0x0000ff00, "Got unexpected color 0x%08x.\n", color);
9736 refcount = IDirect3DDevice8_Release(device);
9737 ok(!refcount, "Device has %u references left.\n", refcount);
9738 done:
9739 IDirect3D8_Release(d3d);
9740 DestroyWindow(window);
9743 static void test_drawindexedprimitiveup(void)
9745 static const struct vertex
9747 struct vec3 position;
9748 DWORD diffuse;
9750 quad[] =
9752 {{-1.0f, -1.0f, 0.1f}, 0xff00ff00},
9753 {{-1.0f, 1.0f, 0.1f}, 0xff0000ff},
9754 {{ 1.0f, -1.0f, 0.1f}, 0xffff0000},
9755 {{ 1.0f, 1.0f, 0.1f}, 0xff0000ff},
9757 {{-1.0f, -1.0f, 0.1f}, 0xff0000ff},
9758 {{-1.0f, 1.0f, 0.1f}, 0xff00ff00},
9759 {{ 1.0f, -1.0f, 0.1f}, 0xffff0000},
9760 {{ 1.0f, 1.0f, 0.1f}, 0xff00ff00},
9762 static const unsigned short indices[] = {0, 1, 2, 3, 4, 5, 6, 7};
9763 IDirect3DDevice8 *device;
9764 IDirect3D8 *d3d;
9765 ULONG refcount;
9766 D3DCOLOR color;
9767 HWND window;
9768 HRESULT hr;
9770 window = create_window();
9771 d3d = Direct3DCreate8(D3D_SDK_VERSION);
9772 ok(!!d3d, "Failed to create a D3D object.\n");
9774 if (!(device = create_device(d3d, window, window, TRUE)))
9776 skip("Failed to create a D3D device.\n");
9777 IDirect3D8_Release(d3d);
9778 DestroyWindow(window);
9779 return;
9782 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, FALSE);
9783 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#x.\n", hr);
9784 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, FALSE);
9785 ok(SUCCEEDED(hr), "Failed to disable Z test, hr %#x.\n", hr);
9786 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9787 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
9789 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9790 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
9791 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9792 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
9793 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
9794 ok(SUCCEEDED(hr), "Failed to set alpha op, hr %#x.\n", hr);
9795 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
9796 ok(SUCCEEDED(hr), "Failed to set alpha arg, hr %#x.\n", hr);
9798 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9799 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
9801 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
9802 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
9804 hr = IDirect3DDevice8_BeginScene(device);
9805 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9806 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 4, 4, 2, indices + 4, D3DFMT_INDEX16, quad, sizeof(*quad));
9807 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9808 hr = IDirect3DDevice8_EndScene(device);
9809 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9811 color = getPixelColor(device, 160, 120);
9812 ok(color_match(color, 0x0040bf00, 1), "Got unexpected color 0x%08x.\n", color);
9813 color = getPixelColor(device, 480, 120);
9814 ok(color_match(color, 0x0040bf00, 1), "Got unexpected color 0x%08x.\n", color);
9815 color = getPixelColor(device, 160, 360);
9816 ok(color_match(color, 0x00404080, 1), "Got unexpected color 0x%08x.\n", color);
9817 color = getPixelColor(device, 480, 360);
9818 ok(color_match(color, 0x00bf4000, 1), "Got unexpected color 0x%08x.\n", color);
9820 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
9821 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
9823 hr = IDirect3DDevice8_BeginScene(device);
9824 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9825 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 0, 4, 2, indices, D3DFMT_INDEX16, quad, sizeof(*quad));
9826 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9827 hr = IDirect3DDevice8_EndScene(device);
9828 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9830 color = getPixelColor(device, 160, 120);
9831 ok(color_match(color, 0x004000bf, 1), "Got unexpected color 0x%08x.\n", color);
9832 color = getPixelColor(device, 480, 120);
9833 ok(color_match(color, 0x004000bf, 1), "Got unexpected color 0x%08x.\n", color);
9834 color = getPixelColor(device, 160, 360);
9835 ok(color_match(color, 0x00408040, 1), "Got unexpected color 0x%08x.\n", color);
9836 color = getPixelColor(device, 480, 360);
9837 ok(color_match(color, 0x00bf0040, 1), "Got unexpected color 0x%08x.\n", color);
9839 refcount = IDirect3DDevice8_Release(device);
9840 ok(!refcount, "Device has %u references left.\n", refcount);
9841 IDirect3D8_Release(d3d);
9842 DestroyWindow(window);
9845 START_TEST(visual)
9847 D3DADAPTER_IDENTIFIER8 identifier;
9848 IDirect3D8 *d3d;
9849 HRESULT hr;
9851 if (!(d3d = Direct3DCreate8(D3D_SDK_VERSION)))
9853 skip("Failed to create D3D8 object.\n");
9854 return;
9857 memset(&identifier, 0, sizeof(identifier));
9858 hr = IDirect3D8_GetAdapterIdentifier(d3d, D3DADAPTER_DEFAULT, 0, &identifier);
9859 ok(SUCCEEDED(hr), "Failed to get adapter identifier, hr %#x.\n", hr);
9860 trace("Driver string: \"%s\"\n", identifier.Driver);
9861 trace("Description string: \"%s\"\n", identifier.Description);
9862 /* Only Windows XP's default VGA driver should have an empty description */
9863 ok(identifier.Description[0] || broken(!strcmp(identifier.Driver, "vga.dll")), "Empty driver description.\n");
9864 trace("Driver version %d.%d.%d.%d\n",
9865 HIWORD(U(identifier.DriverVersion).HighPart), LOWORD(U(identifier.DriverVersion).HighPart),
9866 HIWORD(U(identifier.DriverVersion).LowPart), LOWORD(U(identifier.DriverVersion).LowPart));
9868 IDirect3D8_Release(d3d);
9870 test_sanity();
9871 depth_clamp_test();
9872 lighting_test();
9873 test_specular_lighting();
9874 clear_test();
9875 fog_test();
9876 z_range_test();
9877 offscreen_test();
9878 test_blend();
9879 test_scalar_instructions();
9880 fog_with_shader_test();
9881 cnd_test();
9882 p8_texture_test();
9883 texop_test();
9884 depth_buffer_test();
9885 depth_buffer2_test();
9886 intz_test();
9887 shadow_test();
9888 multisample_copy_rects_test();
9889 zenable_test();
9890 resz_test();
9891 fog_special_test();
9892 volume_dxt5_test();
9893 volume_v16u16_test();
9894 add_dirty_rect_test();
9895 test_3dc_formats();
9896 test_fog_interpolation();
9897 test_negative_fixedfunction_fog();
9898 test_table_fog_zw();
9899 test_signed_formats();
9900 test_updatetexture();
9901 test_pointsize();
9902 test_multisample_mismatch();
9903 test_texcoordindex();
9904 test_vshader_input();
9905 test_fixed_function_fvf();
9906 test_flip();
9907 test_uninitialized_varyings();
9908 test_shademode();
9909 test_multisample_init();
9910 test_texture_blending();
9911 test_color_clamping();
9912 test_edge_antialiasing_blending();
9913 test_max_index16();
9914 test_backbuffer_resize();
9915 test_drawindexedprimitiveup();