d3d8/tests: Make the window client rect match the d3d swapchain size.
[wine.git] / dlls / d3d8 / tests / visual.c
blob20005d0ed8fb260f4b85f58fc703e3a14a54ffa9
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 IDirect3DSurface8 *surface_dst2, *surface_src_green, *surface_src_red, *surface_managed;
5220 IDirect3DTexture8 *tex_dst1, *tex_dst2, *tex_src_red, *tex_src_green, *tex_managed;
5221 D3DLOCKED_RECT locked_rect;
5222 IDirect3DDevice8 *device;
5223 IDirect3D8 *d3d;
5224 unsigned int i;
5225 D3DCOLOR color;
5226 ULONG refcount;
5227 DWORD *texel;
5228 HWND window;
5229 HRESULT hr;
5231 static const RECT part_rect = {96, 96, 160, 160};
5233 window = create_window();
5234 d3d = Direct3DCreate8(D3D_SDK_VERSION);
5235 ok(!!d3d, "Failed to create a D3D object.\n");
5236 if (!(device = create_device(d3d, window, window, TRUE)))
5238 skip("Failed to create a D3D device, skipping tests.\n");
5239 goto done;
5242 hr = IDirect3DDevice8_CreateTexture(device, 256, 256, 1, 0, D3DFMT_X8R8G8B8,
5243 D3DPOOL_DEFAULT, &tex_dst1);
5244 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
5245 hr = IDirect3DDevice8_CreateTexture(device, 256, 256, 1, 0, D3DFMT_X8R8G8B8,
5246 D3DPOOL_DEFAULT, &tex_dst2);
5247 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
5248 hr = IDirect3DDevice8_CreateTexture(device, 256, 256, 1, 0, D3DFMT_X8R8G8B8,
5249 D3DPOOL_SYSTEMMEM, &tex_src_red);
5250 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
5251 hr = IDirect3DDevice8_CreateTexture(device, 256, 256, 1, 0, D3DFMT_X8R8G8B8,
5252 D3DPOOL_SYSTEMMEM, &tex_src_green);
5253 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
5254 hr = IDirect3DDevice8_CreateTexture(device, 256, 256, 1, 0, D3DFMT_X8R8G8B8,
5255 D3DPOOL_MANAGED, &tex_managed);
5256 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
5258 hr = IDirect3DTexture8_GetSurfaceLevel(tex_dst2, 0, &surface_dst2);
5259 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
5260 hr = IDirect3DTexture8_GetSurfaceLevel(tex_src_green, 0, &surface_src_green);
5261 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
5262 hr = IDirect3DTexture8_GetSurfaceLevel(tex_src_red, 0, &surface_src_red);
5263 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
5264 hr = IDirect3DTexture8_GetSurfaceLevel(tex_managed, 0, &surface_managed);
5265 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
5267 fill_surface(surface_src_red, 0x00ff0000, 0);
5268 fill_surface(surface_src_green, 0x0000ff00, 0);
5270 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX1);
5271 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr);
5272 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
5273 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
5274 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
5275 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
5277 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_green,
5278 (IDirect3DBaseTexture8 *)tex_dst1);
5279 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
5281 /* The second UpdateTexture call writing to tex_dst2 is ignored because tex_src_green is not dirty. */
5282 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_red,
5283 (IDirect3DBaseTexture8 *)tex_dst2);
5284 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
5285 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_green,
5286 (IDirect3DBaseTexture8 *)tex_dst2);
5287 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
5289 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)tex_dst1);
5290 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
5291 add_dirty_rect_test_draw(device);
5292 color = getPixelColor(device, 320, 240);
5293 ok(color_match(color, 0x0000ff00, 1),
5294 "Expected color 0x0000ff00, got 0x%08x.\n", color);
5295 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5296 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5298 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)tex_dst2);
5299 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
5300 add_dirty_rect_test_draw(device);
5301 color = getPixelColor(device, 320, 240);
5302 todo_wine ok(color_match(color, 0x00ff0000, 1),
5303 "Expected color 0x00ff0000, got 0x%08x.\n", color);
5304 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5305 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5307 /* AddDirtyRect on the destination is ignored. */
5308 hr = IDirect3DTexture8_AddDirtyRect(tex_dst2, &part_rect);
5309 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
5310 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_green,
5311 (IDirect3DBaseTexture8 *)tex_dst2);
5312 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
5313 add_dirty_rect_test_draw(device);
5314 color = getPixelColor(device, 320, 240);
5315 todo_wine ok(color_match(color, 0x00ff0000, 1),
5316 "Expected color 0x00ff0000, got 0x%08x.\n", color);
5317 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5318 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5320 hr = IDirect3DTexture8_AddDirtyRect(tex_dst2, NULL);
5321 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
5322 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_green,
5323 (IDirect3DBaseTexture8 *)tex_dst2);
5324 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
5325 add_dirty_rect_test_draw(device);
5326 color = getPixelColor(device, 320, 240);
5327 todo_wine ok(color_match(color, 0x00ff0000, 1),
5328 "Expected color 0x00ff0000, got 0x%08x.\n", color);
5329 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5330 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5332 /* AddDirtyRect on the source makes UpdateTexture work. Partial rectangle
5333 * tracking is supported. */
5334 hr = IDirect3DTexture8_AddDirtyRect(tex_src_green, &part_rect);
5335 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
5336 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_green,
5337 (IDirect3DBaseTexture8 *)tex_dst2);
5338 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
5339 add_dirty_rect_test_draw(device);
5340 color = getPixelColor(device, 320, 240);
5341 ok(color_match(color, 0x0000ff00, 1),
5342 "Expected color 0x0000ff00, got 0x%08x.\n", color);
5343 color = getPixelColor(device, 1, 1);
5344 todo_wine ok(color_match(color, 0x00ff0000, 1),
5345 "Expected color 0x00ff0000, got 0x%08x.\n", color);
5346 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5347 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5349 hr = IDirect3DTexture8_AddDirtyRect(tex_src_green, NULL);
5350 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
5351 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_green,
5352 (IDirect3DBaseTexture8 *)tex_dst2);
5353 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
5354 add_dirty_rect_test_draw(device);
5355 color = getPixelColor(device, 1, 1);
5356 ok(color_match(color, 0x0000ff00, 1),
5357 "Expected color 0x0000ff00, got 0x%08x.\n", color);
5359 /* Locks with NO_DIRTY_UPDATE are ignored. */
5360 fill_surface(surface_src_green, 0x00000080, D3DLOCK_NO_DIRTY_UPDATE);
5361 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_green,
5362 (IDirect3DBaseTexture8 *)tex_dst2);
5363 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
5364 add_dirty_rect_test_draw(device);
5365 color = getPixelColor(device, 320, 240);
5366 todo_wine ok(color_match(color, 0x0000ff00, 1),
5367 "Expected color 0x0000ff00, got 0x%08x.\n", color);
5368 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5369 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5371 /* Readonly maps write to D3DPOOL_SYSTEMMEM, but don't record a dirty rectangle. */
5372 fill_surface(surface_src_green, 0x000000ff, D3DLOCK_READONLY);
5373 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_green,
5374 (IDirect3DBaseTexture8 *)tex_dst2);
5375 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
5376 add_dirty_rect_test_draw(device);
5377 color = getPixelColor(device, 320, 240);
5378 todo_wine ok(color_match(color, 0x0000ff00, 1),
5379 "Expected color 0x0000ff00, got 0x%08x.\n", color);
5380 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5381 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5383 hr = IDirect3DTexture8_AddDirtyRect(tex_src_green, NULL);
5384 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_green,
5385 (IDirect3DBaseTexture8 *)tex_dst2);
5386 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
5387 add_dirty_rect_test_draw(device);
5388 color = getPixelColor(device, 320, 240);
5389 ok(color_match(color, 0x000000ff, 1),
5390 "Expected color 0x000000ff, got 0x%08x.\n", color);
5391 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5392 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5394 /* Maps without either of these flags record a dirty rectangle. */
5395 fill_surface(surface_src_green, 0x00ffffff, 0);
5396 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_green,
5397 (IDirect3DBaseTexture8 *)tex_dst2);
5398 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
5399 add_dirty_rect_test_draw(device);
5400 color = getPixelColor(device, 320, 240);
5401 ok(color_match(color, 0x00ffffff, 1),
5402 "Expected color 0x00ffffff, got 0x%08x.\n", color);
5403 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5404 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5406 /* Partial LockRect works just like a partial AddDirtyRect call. */
5407 hr = IDirect3DTexture8_LockRect(tex_src_green, 0, &locked_rect, &part_rect, 0);
5408 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
5409 texel = locked_rect.pBits;
5410 for (i = 0; i < 64; i++)
5411 texel[i] = 0x00ff00ff;
5412 for (i = 1; i < 64; i++)
5413 memcpy((BYTE *)locked_rect.pBits + i * locked_rect.Pitch, locked_rect.pBits, locked_rect.Pitch);
5414 hr = IDirect3DTexture8_UnlockRect(tex_src_green, 0);
5415 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
5416 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_green,
5417 (IDirect3DBaseTexture8 *)tex_dst2);
5418 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
5419 add_dirty_rect_test_draw(device);
5420 color = getPixelColor(device, 320, 240);
5421 ok(color_match(color, 0x00ff00ff, 1),
5422 "Expected color 0x00ff00ff, got 0x%08x.\n", color);
5423 color = getPixelColor(device, 1, 1);
5424 ok(color_match(color, 0x00ffffff, 1),
5425 "Expected color 0x00ffffff, got 0x%08x.\n", color);
5426 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5427 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5429 fill_surface(surface_src_red, 0x00ff0000, 0);
5430 fill_surface(surface_src_green, 0x0000ff00, 0);
5432 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_green,
5433 (IDirect3DBaseTexture8 *)tex_dst1);
5434 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
5435 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)tex_dst1);
5436 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
5437 add_dirty_rect_test_draw(device);
5438 color = getPixelColor(device, 320, 240);
5439 ok(color_match(color, 0x0000ff00, 1),
5440 "Expected color 0x0000ff00, got 0x%08x.\n", color);
5441 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5442 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5444 /* UpdateSurface ignores the missing dirty marker. */
5445 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_red,
5446 (IDirect3DBaseTexture8 *)tex_dst2);
5447 hr = IDirect3DDevice8_CopyRects(device, surface_src_green, NULL, 0, surface_dst2, NULL);
5448 ok(SUCCEEDED(hr), "Failed to update surface, hr %#x.\n", hr);
5449 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)tex_dst2);
5450 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
5451 add_dirty_rect_test_draw(device);
5452 color = getPixelColor(device, 320, 240);
5453 ok(color_match(color, 0x0000ff00, 1),
5454 "Expected color 0x0000ff00, got 0x%08x.\n", color);
5455 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5456 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5458 fill_surface(surface_managed, 0x00ff0000, 0);
5459 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)tex_managed);
5460 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
5461 add_dirty_rect_test_draw(device);
5462 color = getPixelColor(device, 320, 240);
5463 ok(color_match(color, 0x00ff0000, 1),
5464 "Expected color 0x00ff0000, got 0x%08x.\n", color);
5465 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5466 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5468 /* Managed textures also honor D3DLOCK_NO_DIRTY_UPDATE. */
5469 fill_surface(surface_managed, 0x0000ff00, D3DLOCK_NO_DIRTY_UPDATE);
5470 add_dirty_rect_test_draw(device);
5471 color = getPixelColor(device, 320, 240);
5472 ok(color_match(color, 0x00ff0000, 1),
5473 "Expected color 0x00ff0000, got 0x%08x.\n", color);
5474 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5475 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5477 /* AddDirtyRect uploads the new contents.
5478 * Side note, not tested in the test: Partial surface updates work, and two separate
5479 * dirty rectangles are tracked individually. Tested on Nvidia Kepler, other drivers
5480 * untested. */
5481 hr = IDirect3DTexture8_AddDirtyRect(tex_managed, NULL);
5482 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
5483 add_dirty_rect_test_draw(device);
5484 color = getPixelColor(device, 320, 240);
5485 ok(color_match(color, 0x0000ff00, 1),
5486 "Expected color 0x0000ff00, got 0x%08x.\n", color);
5487 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5488 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5490 /* So does ResourceManagerDiscardBytes. */
5491 fill_surface(surface_managed, 0x000000ff, D3DLOCK_NO_DIRTY_UPDATE);
5492 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
5493 hr = IDirect3DDevice8_ResourceManagerDiscardBytes(device, 0);
5494 ok(SUCCEEDED(hr), "Failed to evict managed resources, hr %#x.\n", hr);
5495 add_dirty_rect_test_draw(device);
5496 color = getPixelColor(device, 320, 240);
5497 ok(color_match(color, 0x000000ff, 1),
5498 "Expected color 0x000000ff, got 0x%08x.\n", color);
5499 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5500 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5502 /* AddDirtyRect on a locked texture is allowed. */
5503 hr = IDirect3DTexture8_LockRect(tex_src_red, 0, &locked_rect, NULL, 0);
5504 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
5505 hr = IDirect3DTexture8_AddDirtyRect(tex_src_red, NULL);
5506 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
5507 hr = IDirect3DTexture8_UnlockRect(tex_src_red, 0);
5508 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
5510 /* Redundant AddDirtyRect calls are ok. */
5511 hr = IDirect3DTexture8_AddDirtyRect(tex_managed, NULL);
5512 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
5513 hr = IDirect3DTexture8_AddDirtyRect(tex_managed, NULL);
5514 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
5516 IDirect3DSurface8_Release(surface_dst2);
5517 IDirect3DSurface8_Release(surface_managed);
5518 IDirect3DSurface8_Release(surface_src_red);
5519 IDirect3DSurface8_Release(surface_src_green);
5520 IDirect3DTexture8_Release(tex_src_red);
5521 IDirect3DTexture8_Release(tex_src_green);
5522 IDirect3DTexture8_Release(tex_dst1);
5523 IDirect3DTexture8_Release(tex_dst2);
5524 IDirect3DTexture8_Release(tex_managed);
5525 refcount = IDirect3DDevice8_Release(device);
5526 ok(!refcount, "Device has %u references left.\n", refcount);
5527 done:
5528 IDirect3D8_Release(d3d);
5529 DestroyWindow(window);
5532 static void test_3dc_formats(void)
5534 static const char ati1n_data[] =
5536 /* A 4x4 texture with the color component at 50%. */
5537 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5539 static const char ati2n_data[] =
5541 /* A 8x4 texture consisting of 2 4x4 blocks. The first block has 50% first color component,
5542 * 0% second component. Second block is the opposite. */
5543 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5544 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5546 static const struct
5548 struct vec3 position;
5549 struct vec2 texcoord;
5551 quads[] =
5553 {{-1.0f, -1.0f, 0.0f}, {0.0f, 0.0f}},
5554 {{-1.0f, 1.0f, 0.0f}, {0.0f, 1.0f}},
5555 {{ 0.0f, -1.0f, 1.0f}, {1.0f, 0.0f}},
5556 {{ 0.0f, 1.0f, 1.0f}, {1.0f, 1.0f}},
5558 {{ 0.0f, -1.0f, 0.0f}, {0.0f, 0.0f}},
5559 {{ 0.0f, 1.0f, 0.0f}, {0.0f, 1.0f}},
5560 {{ 1.0f, -1.0f, 1.0f}, {1.0f, 0.0f}},
5561 {{ 1.0f, 1.0f, 1.0f}, {1.0f, 1.0f}},
5563 static const DWORD ati1n_fourcc = MAKEFOURCC('A','T','I','1');
5564 static const DWORD ati2n_fourcc = MAKEFOURCC('A','T','I','2');
5565 static const struct
5567 struct vec2 position;
5568 D3DCOLOR amd_r500;
5569 D3DCOLOR amd_r600;
5570 D3DCOLOR nvidia_old;
5571 D3DCOLOR nvidia_new;
5573 expected_colors[] =
5575 {{ 80, 240}, 0x007fffff, 0x003f3f3f, 0x007f7f7f, 0x007f0000},
5576 {{240, 240}, 0x007fffff, 0x003f3f3f, 0x007f7f7f, 0x007f0000},
5577 {{400, 240}, 0x00007fff, 0x00007fff, 0x00007fff, 0x00007fff},
5578 {{560, 240}, 0x007f00ff, 0x007f00ff, 0x007f00ff, 0x007f00ff},
5580 IDirect3D8 *d3d;
5581 IDirect3DDevice8 *device;
5582 IDirect3DTexture8 *ati1n_texture, *ati2n_texture;
5583 D3DCAPS8 caps;
5584 D3DLOCKED_RECT rect;
5585 D3DCOLOR color;
5586 ULONG refcount;
5587 HWND window;
5588 HRESULT hr;
5589 unsigned int i;
5591 window = create_window();
5592 d3d = Direct3DCreate8(D3D_SDK_VERSION);
5593 ok(!!d3d, "Failed to create a D3D object.\n");
5594 if (FAILED(IDirect3D8_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
5595 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, ati1n_fourcc)))
5597 skip("ATI1N textures are not supported, skipping test.\n");
5598 goto done;
5600 if (FAILED(IDirect3D8_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
5601 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, ati2n_fourcc)))
5603 skip("ATI2N textures are not supported, skipping test.\n");
5604 goto done;
5606 if (!(device = create_device(d3d, window, window, TRUE)))
5608 skip("Failed to create a D3D device, skipping tests.\n");
5609 goto done;
5611 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
5612 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
5613 if (!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP))
5615 skip("D3DTA_TEMP not supported, skipping tests.\n");
5616 IDirect3DDevice8_Release(device);
5617 goto done;
5620 hr = IDirect3DDevice8_CreateTexture(device, 4, 4, 1, 0, ati1n_fourcc,
5621 D3DPOOL_MANAGED, &ati1n_texture);
5622 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
5624 hr = IDirect3DTexture8_LockRect(ati1n_texture, 0, &rect, NULL, 0);
5625 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
5626 memcpy(rect.pBits, ati1n_data, sizeof(ati1n_data));
5627 hr = IDirect3DTexture8_UnlockRect(ati1n_texture, 0);
5628 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
5630 hr = IDirect3DDevice8_CreateTexture(device, 8, 4, 1, 0, ati2n_fourcc,
5631 D3DPOOL_MANAGED, &ati2n_texture);
5632 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
5634 hr = IDirect3DTexture8_LockRect(ati2n_texture, 0, &rect, NULL, 0);
5635 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
5636 memcpy(rect.pBits, ati2n_data, sizeof(ati2n_data));
5637 hr = IDirect3DTexture8_UnlockRect(ati2n_texture, 0);
5638 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
5640 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE2(0));
5641 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
5642 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BLENDTEXTUREALPHA);
5643 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
5644 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
5645 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
5646 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TEMP);
5647 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
5648 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
5649 ok(SUCCEEDED(hr), "Failed to set alpha op, hr %#x.\n", hr);
5650 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
5651 ok(SUCCEEDED(hr), "Failed to set alpha arg, hr %#x.\n", hr);
5652 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
5653 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
5654 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MAGFILTER, D3DTEXF_POINT);
5655 ok(SUCCEEDED(hr), "Failed to set mag filter, hr %#x.\n", hr);
5657 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff00ff, 1.0f, 0);
5658 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
5659 hr = IDirect3DDevice8_BeginScene(device);
5660 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5661 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)ati1n_texture);
5662 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
5663 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads));
5664 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5665 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)ati2n_texture);
5666 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
5667 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[4], sizeof(*quads));
5668 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5669 hr = IDirect3DDevice8_EndScene(device);
5670 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5672 for (i = 0; i < 4; ++i)
5674 color = getPixelColor(device, expected_colors[i].position.x, expected_colors[i].position.y);
5675 ok (color_match(color, expected_colors[i].amd_r500, 1)
5676 || color_match(color, expected_colors[i].amd_r600, 1)
5677 || color_match(color, expected_colors[i].nvidia_old, 1)
5678 || color_match(color, expected_colors[i].nvidia_new, 1),
5679 "Got unexpected color 0x%08x, case %u.\n", color, i);
5682 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5683 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5684 IDirect3DTexture8_Release(ati2n_texture);
5685 IDirect3DTexture8_Release(ati1n_texture);
5686 refcount = IDirect3DDevice8_Release(device);
5687 ok(!refcount, "Device has %u references left.\n", refcount);
5689 done:
5690 IDirect3D8_Release(d3d);
5691 DestroyWindow(window);
5694 static void test_fog_interpolation(void)
5696 HRESULT hr;
5697 IDirect3DDevice8 *device;
5698 IDirect3D8 *d3d;
5699 ULONG refcount;
5700 HWND window;
5701 D3DCOLOR color;
5702 static const struct
5704 struct vec3 position;
5705 D3DCOLOR diffuse;
5706 D3DCOLOR specular;
5708 quad[] =
5710 {{-1.0f, -1.0f, 0.0f}, 0xffff0000, 0xff000000},
5711 {{-1.0f, 1.0f, 0.0f}, 0xffff0000, 0xff000000},
5712 {{ 1.0f, -1.0f, 1.0f}, 0xffff0000, 0x00000000},
5713 {{ 1.0f, 1.0f, 1.0f}, 0xffff0000, 0x00000000},
5715 union
5717 DWORD d;
5718 float f;
5719 } conv;
5720 unsigned int i;
5721 static const struct
5723 D3DFOGMODE vfog, tfog;
5724 D3DSHADEMODE shade;
5725 D3DCOLOR middle_color;
5726 BOOL todo;
5728 tests[] =
5730 {D3DFOG_NONE, D3DFOG_NONE, D3DSHADE_FLAT, 0x00007f80, FALSE},
5731 {D3DFOG_NONE, D3DFOG_NONE, D3DSHADE_GOURAUD, 0x00007f80, FALSE},
5732 {D3DFOG_EXP, D3DFOG_NONE, D3DSHADE_FLAT, 0x00007f80, TRUE},
5733 {D3DFOG_EXP, D3DFOG_NONE, D3DSHADE_GOURAUD, 0x00007f80, TRUE},
5734 {D3DFOG_NONE, D3DFOG_EXP, D3DSHADE_FLAT, 0x0000ea15, FALSE},
5735 {D3DFOG_NONE, D3DFOG_EXP, D3DSHADE_GOURAUD, 0x0000ea15, FALSE},
5736 {D3DFOG_EXP, D3DFOG_EXP, D3DSHADE_FLAT, 0x0000ea15, FALSE},
5737 {D3DFOG_EXP, D3DFOG_EXP, D3DSHADE_GOURAUD, 0x0000ea15, FALSE},
5739 static const D3DMATRIX ident_mat =
5741 1.0f, 0.0f, 0.0f, 0.0f,
5742 0.0f, 1.0f, 0.0f, 0.0f,
5743 0.0f, 0.0f, 1.0f, 0.0f,
5744 0.0f, 0.0f, 0.0f, 1.0f
5745 }}};
5746 D3DCAPS8 caps;
5748 window = create_window();
5749 d3d = Direct3DCreate8(D3D_SDK_VERSION);
5750 ok(!!d3d, "Failed to create a D3D object.\n");
5752 if (!(device = create_device(d3d, window, window, TRUE)))
5754 skip("Failed to create a D3D device, skipping tests.\n");
5755 IDirect3D8_Release(d3d);
5756 DestroyWindow(window);
5757 return;
5760 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
5761 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
5762 if (!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE))
5763 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping some fog tests\n");
5765 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
5766 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr);
5767 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
5768 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
5769 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, FALSE);
5770 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
5771 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
5772 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
5773 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGCOLOR, 0x0000ff00);
5774 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
5775 conv.f = 5.0;
5776 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGDENSITY, conv.d);
5777 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
5779 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
5780 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
5781 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TFACTOR);
5782 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
5783 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x000000ff);
5784 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
5786 /* Some of the tests seem to depend on the projection matrix explicitly
5787 * being set to an identity matrix, even though that's the default.
5788 * (AMD Radeon X1600, AMD Radeon HD 6310, Windows 7). Without this,
5789 * the drivers seem to use a static z = 1.0 input for the fog equation.
5790 * The input value is independent of the actual z and w component of
5791 * the vertex position. */
5792 hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, &ident_mat);
5793 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
5795 for (i = 0; i < sizeof(tests) / sizeof(*tests); i++)
5797 if(!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE) && tests[i].tfog)
5798 continue;
5800 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00808080, 0.0f, 0);
5801 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
5803 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SHADEMODE, tests[i].shade);
5804 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
5805 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGVERTEXMODE, tests[i].vfog);
5806 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
5807 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGTABLEMODE, tests[i].tfog);
5808 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
5809 hr = IDirect3DDevice8_BeginScene(device);
5810 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5811 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
5812 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5813 hr = IDirect3DDevice8_EndScene(device);
5814 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5816 color = getPixelColor(device, 0, 240);
5817 ok(color_match(color, 0x000000ff, 2), "Got unexpected color 0x%08x, case %u.\n", color, i);
5818 color = getPixelColor(device, 320, 240);
5819 todo_wine_if (tests[i].todo)
5820 ok(color_match(color, tests[i].middle_color, 2),
5821 "Got unexpected color 0x%08x, case %u.\n", color, i);
5822 color = getPixelColor(device, 639, 240);
5823 ok(color_match(color, 0x0000fd02, 2), "Got unexpected color 0x%08x, case %u.\n", color, i);
5824 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5825 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5828 refcount = IDirect3DDevice8_Release(device);
5829 ok(!refcount, "Device has %u references left.\n", refcount);
5830 IDirect3D8_Release(d3d);
5831 DestroyWindow(window);
5834 static void test_negative_fixedfunction_fog(void)
5836 HRESULT hr;
5837 IDirect3DDevice8 *device;
5838 IDirect3D8 *d3d;
5839 ULONG refcount;
5840 HWND window;
5841 D3DCOLOR color;
5842 static const struct
5844 struct vec3 position;
5845 D3DCOLOR diffuse;
5847 quad[] =
5849 {{-1.0f, -1.0f, -0.5f}, 0xffff0000},
5850 {{-1.0f, 1.0f, -0.5f}, 0xffff0000},
5851 {{ 1.0f, -1.0f, -0.5f}, 0xffff0000},
5852 {{ 1.0f, 1.0f, -0.5f}, 0xffff0000},
5854 static const struct
5856 struct vec4 position;
5857 D3DCOLOR diffuse;
5859 tquad[] =
5861 {{ 0.0f, 0.0f, -0.5f, 1.0f}, 0xffff0000},
5862 {{640.0f, 0.0f, -0.5f, 1.0f}, 0xffff0000},
5863 {{ 0.0f, 480.0f, -0.5f, 1.0f}, 0xffff0000},
5864 {{640.0f, 480.0f, -0.5f, 1.0f}, 0xffff0000},
5866 unsigned int i;
5867 static const D3DMATRIX zero =
5869 1.0f, 0.0f, 0.0f, 0.0f,
5870 0.0f, 1.0f, 0.0f, 0.0f,
5871 0.0f, 0.0f, 0.0f, 0.0f,
5872 0.0f, 0.0f, 0.0f, 1.0f
5873 }}};
5874 /* Needed to make AMD drivers happy. Yeah, it is not supposed to
5875 * have an effect on RHW draws. */
5876 static const D3DMATRIX identity =
5878 1.0f, 0.0f, 0.0f, 0.0f,
5879 0.0f, 1.0f, 0.0f, 0.0f,
5880 0.0f, 0.0f, 1.0f, 0.0f,
5881 0.0f, 0.0f, 0.0f, 1.0f
5882 }}};
5883 static const struct
5885 DWORD pos_type;
5886 const void *quad;
5887 size_t stride;
5888 const D3DMATRIX *matrix;
5889 union
5891 float f;
5892 DWORD d;
5893 } start, end;
5894 D3DFOGMODE vfog, tfog;
5895 DWORD color, color_broken, color_broken2;
5897 tests[] =
5899 /* Run the XYZRHW tests first. Depth clamping is broken after RHW draws on the testbot.
5901 * Geforce8+ GPUs on Windows abs() table fog, everything else does not. */
5902 {D3DFVF_XYZRHW, tquad, sizeof(*tquad), &identity, { 0.0f}, {1.0f},
5903 D3DFOG_NONE, D3DFOG_LINEAR, 0x00ff0000, 0x00808000, 0x00808000},
5904 /* r200 GPUs and presumably all d3d8 and older HW clamp the fog
5905 * parameters to 0.0 and 1.0 in the table fog case. */
5906 {D3DFVF_XYZRHW, tquad, sizeof(*tquad), &identity, {-1.0f}, {0.0f},
5907 D3DFOG_NONE, D3DFOG_LINEAR, 0x00808000, 0x00ff0000, 0x0000ff00},
5908 /* test_fog_interpolation shows that vertex fog evaluates the fog
5909 * equation in the vertex pipeline. Start = -1.0 && end = 0.0 shows
5910 * that the abs happens before the fog equation is evaluated.
5912 * Vertex fog abs() behavior is the same on all GPUs. */
5913 {D3DFVF_XYZ, quad, sizeof(*quad), &zero, { 0.0f}, {1.0f},
5914 D3DFOG_LINEAR, D3DFOG_NONE, 0x00808000, 0x00808000, 0x00808000},
5915 {D3DFVF_XYZ, quad, sizeof(*quad), &zero, {-1.0f}, {0.0f},
5916 D3DFOG_LINEAR, D3DFOG_NONE, 0x0000ff00, 0x0000ff00, 0x0000ff00},
5917 {D3DFVF_XYZ, quad, sizeof(*quad), &zero, { 0.0f}, {1.0f},
5918 D3DFOG_EXP, D3DFOG_NONE, 0x009b6400, 0x009b6400, 0x009b6400},
5920 D3DCAPS8 caps;
5922 window = create_window();
5923 d3d = Direct3DCreate8(D3D_SDK_VERSION);
5924 ok(!!d3d, "Failed to create a D3D object.\n");
5926 if (!(device = create_device(d3d, window, window, TRUE)))
5928 skip("Failed to create a D3D device, skipping tests.\n");
5929 IDirect3D8_Release(d3d);
5930 DestroyWindow(window);
5931 return;
5934 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
5935 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
5936 if (!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE))
5937 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping some fog tests.\n");
5939 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
5940 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
5941 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
5942 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
5943 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
5944 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
5945 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGCOLOR, 0x0000ff00);
5946 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
5947 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, FALSE);
5948 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
5950 for (i = 0; i < sizeof(tests) / sizeof(*tests); i++)
5952 if (!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE) && tests[i].tfog)
5953 continue;
5955 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x000000ff, 0.0f, 0);
5956 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
5958 hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, tests[i].matrix);
5959 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
5960 hr = IDirect3DDevice8_SetVertexShader(device, tests[i].pos_type | D3DFVF_DIFFUSE);
5961 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr);
5962 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGSTART, tests[i].start.d);
5963 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
5964 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGEND, tests[i].end.d);
5965 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
5966 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGVERTEXMODE, tests[i].vfog);
5967 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
5968 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGTABLEMODE, tests[i].tfog);
5969 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
5971 hr = IDirect3DDevice8_BeginScene(device);
5972 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5973 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, tests[i].quad, tests[i].stride);
5974 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5975 hr = IDirect3DDevice8_EndScene(device);
5976 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5978 color = getPixelColor(device, 320, 240);
5979 ok(color_match(color, tests[i].color, 2) || broken(color_match(color, tests[i].color_broken, 2))
5980 || broken(color_match(color, tests[i].color_broken2, 2)),
5981 "Got unexpected color 0x%08x, case %u.\n", color, i);
5982 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5983 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5986 refcount = IDirect3DDevice8_Release(device);
5987 ok(!refcount, "Device has %u references left.\n", refcount);
5988 IDirect3D8_Release(d3d);
5989 DestroyWindow(window);
5992 static void test_table_fog_zw(void)
5994 HRESULT hr;
5995 IDirect3DDevice8 *device;
5996 IDirect3D8 *d3d;
5997 ULONG refcount;
5998 HWND window;
5999 D3DCOLOR color;
6000 D3DCAPS8 caps;
6001 static struct
6003 struct vec4 position;
6004 D3DCOLOR diffuse;
6006 quad[] =
6008 {{ 0.0f, 0.0f, 0.0f, 0.0f}, 0xffff0000},
6009 {{640.0f, 0.0f, 0.0f, 0.0f}, 0xffff0000},
6010 {{ 0.0f, 480.0f, 0.0f, 0.0f}, 0xffff0000},
6011 {{640.0f, 480.0f, 0.0f, 0.0f}, 0xffff0000},
6013 static const D3DMATRIX identity =
6015 1.0f, 0.0f, 0.0f, 0.0f,
6016 0.0f, 1.0f, 0.0f, 0.0f,
6017 0.0f, 0.0f, 1.0f, 0.0f,
6018 0.0f, 0.0f, 0.0f, 1.0f
6019 }}};
6020 static const struct
6022 float z, w;
6023 D3DZBUFFERTYPE z_test;
6024 D3DCOLOR color;
6026 tests[] =
6028 {0.7f, 0.0f, D3DZB_TRUE, 0x004cb200},
6029 {0.7f, 0.0f, D3DZB_FALSE, 0x004cb200},
6030 {0.7f, 0.3f, D3DZB_TRUE, 0x004cb200},
6031 {0.7f, 0.3f, D3DZB_FALSE, 0x004cb200},
6032 {0.7f, 3.0f, D3DZB_TRUE, 0x004cb200},
6033 {0.7f, 3.0f, D3DZB_FALSE, 0x004cb200},
6034 {0.3f, 0.0f, D3DZB_TRUE, 0x00b24c00},
6035 {0.3f, 0.0f, D3DZB_FALSE, 0x00b24c00},
6037 unsigned int i;
6039 window = create_window();
6040 d3d = Direct3DCreate8(D3D_SDK_VERSION);
6041 ok(!!d3d, "Failed to create a D3D object.\n");
6043 if (!(device = create_device(d3d, window, window, TRUE)))
6045 skip("Failed to create a D3D device, skipping tests.\n");
6046 IDirect3D8_Release(d3d);
6047 DestroyWindow(window);
6048 return;
6051 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
6052 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
6053 if (!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE))
6055 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping POSITIONT table fog test.\n");
6056 goto done;
6059 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6060 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6061 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
6062 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6063 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGCOLOR, 0x0000ff00);
6064 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6065 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, FALSE);
6066 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
6067 /* Work around an AMD Windows driver bug. Needs a proj matrix applied redundantly. */
6068 hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, &identity);
6069 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
6070 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
6071 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6072 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
6073 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr);
6075 for (i = 0; i < sizeof(tests) / sizeof(*tests); ++i)
6077 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
6078 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
6080 quad[0].position.z = tests[i].z;
6081 quad[1].position.z = tests[i].z;
6082 quad[2].position.z = tests[i].z;
6083 quad[3].position.z = tests[i].z;
6084 quad[0].position.w = tests[i].w;
6085 quad[1].position.w = tests[i].w;
6086 quad[2].position.w = tests[i].w;
6087 quad[3].position.w = tests[i].w;
6088 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, tests[i].z_test);
6089 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6091 hr = IDirect3DDevice8_BeginScene(device);
6092 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6093 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
6094 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6095 hr = IDirect3DDevice8_EndScene(device);
6096 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6098 color = getPixelColor(device, 320, 240);
6099 ok(color_match(color, tests[i].color, 2),
6100 "Got unexpected color 0x%08x, expected 0x%08x, case %u.\n", color, tests[i].color, i);
6101 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
6102 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
6105 done:
6106 refcount = IDirect3DDevice8_Release(device);
6107 ok(!refcount, "Device has %u references left.\n", refcount);
6108 IDirect3D8_Release(d3d);
6109 DestroyWindow(window);
6112 static void test_signed_formats(void)
6114 IDirect3DDevice8 *device;
6115 HWND window;
6116 HRESULT hr;
6117 unsigned int i, j, x, y;
6118 IDirect3DTexture8 *texture, *texture_sysmem;
6119 D3DLOCKED_RECT locked_rect;
6120 DWORD shader, shader_alpha;
6121 IDirect3D8 *d3d;
6122 D3DCOLOR color;
6123 D3DCAPS8 caps;
6124 ULONG refcount;
6126 /* See comments in the d3d9 version of this test for an
6127 * explanation of these values. */
6128 static const USHORT content_v8u8[4][4] =
6130 {0x0000, 0x7f7f, 0x8880, 0x0000},
6131 {0x0080, 0x8000, 0x7f00, 0x007f},
6132 {0x193b, 0xe8c8, 0x0808, 0xf8f8},
6133 {0x4444, 0xc0c0, 0xa066, 0x22e0},
6135 static const DWORD content_v16u16[4][4] =
6137 {0x00000000, 0x7fff7fff, 0x88008000, 0x00000000},
6138 {0x00008000, 0x80000000, 0x7fff0000, 0x00007fff},
6139 {0x19993bbb, 0xe800c800, 0x08880888, 0xf800f800},
6140 {0x44444444, 0xc000c000, 0xa0006666, 0x2222e000},
6142 static const DWORD content_q8w8v8u8[4][4] =
6144 {0x00000000, 0xff7f7f7f, 0x7f008880, 0x817f0000},
6145 {0x10000080, 0x20008000, 0x30007f00, 0x4000007f},
6146 {0x5020193b, 0x6028e8c8, 0x70020808, 0x807ff8f8},
6147 {0x90414444, 0xa000c0c0, 0x8261a066, 0x834922e0},
6149 static const DWORD content_x8l8v8u8[4][4] =
6151 {0x00000000, 0x00ff7f7f, 0x00008880, 0x00ff0000},
6152 {0x00000080, 0x00008000, 0x00007f00, 0x0000007f},
6153 {0x0041193b, 0x0051e8c8, 0x00040808, 0x00fff8f8},
6154 {0x00824444, 0x0000c0c0, 0x00c2a066, 0x009222e0},
6156 static const USHORT content_l6v5u5[4][4] =
6158 {0x0000, 0xfdef, 0x0230, 0xfc00},
6159 {0x0010, 0x0200, 0x01e0, 0x000f},
6160 {0x4067, 0x53b9, 0x0421, 0xffff},
6161 {0x8108, 0x0318, 0xc28c, 0x909c},
6163 static const struct
6165 D3DFORMAT format;
6166 const char *name;
6167 const void *content;
6168 SIZE_T pixel_size;
6169 BOOL blue, alpha;
6170 unsigned int slop, slop_broken, alpha_broken;
6172 formats[] =
6174 {D3DFMT_V8U8, "D3DFMT_V8U8", content_v8u8, sizeof(WORD), FALSE, FALSE, 1, 0, FALSE},
6175 {D3DFMT_V16U16, "D3DFMT_V16U16", content_v16u16, sizeof(DWORD), FALSE, FALSE, 1, 0, FALSE},
6176 {D3DFMT_Q8W8V8U8, "D3DFMT_Q8W8V8U8", content_q8w8v8u8, sizeof(DWORD), TRUE, TRUE, 1, 0, TRUE },
6177 {D3DFMT_X8L8V8U8, "D3DFMT_X8L8V8U8", content_x8l8v8u8, sizeof(DWORD), TRUE, FALSE, 1, 0, FALSE},
6178 {D3DFMT_L6V5U5, "D3DFMT_L6V5U5", content_l6v5u5, sizeof(WORD), TRUE, FALSE, 4, 7, FALSE},
6180 static const struct
6182 D3DPOOL pool;
6183 UINT width;
6185 tests[] =
6187 {D3DPOOL_SYSTEMMEM, 4},
6188 {D3DPOOL_SYSTEMMEM, 1},
6189 {D3DPOOL_MANAGED, 4},
6190 {D3DPOOL_MANAGED, 1},
6192 static const DWORD shader_code[] =
6194 0xffff0101, /* ps_1_1 */
6195 0x00000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, /* def c0, 0.5, 0.5, 0,5, 0,5 */
6196 0x00000042, 0xb00f0000, /* tex t0 */
6197 0x00000004, 0x800f0000, 0xb0e40000, 0xa0e40000, 0xa0e40000, /* mad r0, t0, c0, c0 */
6198 0x0000ffff /* end */
6200 static const DWORD shader_code_alpha[] =
6202 /* The idea of this shader is to replicate the alpha value in .rg, and set
6203 * blue to 1.0 iff the alpha value is < -1.0 and 0.0 otherwise. */
6204 0xffff0101, /* ps_1_1 */
6205 0x00000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, /* def c0, 0.5, 0.5, 0.5, 0.5 */
6206 0x00000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0 */
6207 0x00000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c2, 0.0, 0.0, 1.0, 0.0 */
6208 0x00000042, 0xb00f0000, /* tex t0 */
6209 0x00000004, 0x80070000, 0xb0ff0000, 0xa0e40000, 0xa0e40000, /* mad r0.rgb, t0.a, c0, c0 */
6210 0x00000003, 0x80080000, 0xb1ff0000, 0xa0e40000, /* sub r0.a, -t0.a, c0 */
6211 0x00000050, 0x80080000, 0x80ff0000, 0xa0ff0001, 0xa0ff0002, /* cnd r0.a, r0.a, c1.a, c2.a */
6212 0x00000005, 0x80070001, 0xa0e40001, 0x80e40000, /* mul r1.rgb, c1, r0 */
6213 0x00000004, 0x80070000, 0x80ff0000, 0xa0e40002, 0x80e40001, /* mad r0.rgb, r0.a, c2, r1 */
6214 0x0000ffff /* end */
6216 static const struct
6218 struct vec3 position;
6219 struct vec2 texcrd;
6221 quad[] =
6223 /* Flip the y coordinate to make the input and
6224 * output arrays easier to compare. */
6225 {{ -1.0f, -1.0f, 0.0f}, { 0.0f, 1.0f}},
6226 {{ -1.0f, 1.0f, 0.0f}, { 0.0f, 0.0f}},
6227 {{ 1.0f, -1.0f, 0.0f}, { 1.0f, 1.0f}},
6228 {{ 1.0f, 1.0f, 0.0f}, { 1.0f, 0.0f}},
6230 static const D3DCOLOR expected_alpha[4][4] =
6232 {0x00808000, 0x007f7f00, 0x00ffff00, 0x00000000},
6233 {0x00909000, 0x00a0a000, 0x00b0b000, 0x00c0c000},
6234 {0x00d0d000, 0x00e0e000, 0x00f0f000, 0x00000000},
6235 {0x00101000, 0x00202000, 0x00010100, 0x00020200},
6237 static const BOOL alpha_broken[4][4] =
6239 {FALSE, FALSE, FALSE, FALSE},
6240 {FALSE, FALSE, FALSE, FALSE},
6241 {FALSE, FALSE, FALSE, TRUE },
6242 {FALSE, FALSE, FALSE, FALSE},
6244 static const D3DCOLOR expected_colors[4][4] =
6246 {0x00808080, 0x00fefeff, 0x00010780, 0x008080ff},
6247 {0x00018080, 0x00800180, 0x0080fe80, 0x00fe8080},
6248 {0x00ba98a0, 0x004767a8, 0x00888881, 0x007878ff},
6249 {0x00c3c3c0, 0x003f3f80, 0x00e51fe1, 0x005fa2c8},
6251 D3DCOLOR expected_color;
6253 window = create_window();
6254 d3d = Direct3DCreate8(D3D_SDK_VERSION);
6255 ok(!!d3d, "Failed to create a D3D object.\n");
6257 if (!(device = create_device(d3d, window, window, TRUE)))
6259 skip("Failed to create a D3D device, skipping tests.\n");
6260 IDirect3D8_Release(d3d);
6261 DestroyWindow(window);
6262 return;
6265 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
6266 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
6268 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 1))
6270 skip("Pixel shaders not supported, skipping converted format test.\n");
6271 goto done;
6274 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
6275 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6276 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX1);
6277 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
6278 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code, &shader);
6279 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
6280 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code_alpha, &shader_alpha);
6281 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
6283 for (i = 0; i < sizeof(formats) / sizeof(*formats); i++)
6285 hr = IDirect3D8_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
6286 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, formats[i].format);
6287 if (FAILED(hr))
6289 skip("Format %s not supported, skipping.\n", formats[i].name);
6290 continue;
6293 for (j = 0; j < sizeof(tests) / sizeof(*tests); j++)
6295 texture_sysmem = NULL;
6296 hr = IDirect3DDevice8_CreateTexture(device, tests[j].width, 4, 1, 0,
6297 formats[i].format, tests[j].pool, &texture);
6298 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
6300 hr = IDirect3DTexture8_LockRect(texture, 0, &locked_rect, NULL, 0);
6301 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
6302 for (y = 0; y < 4; y++)
6304 memcpy((char *)locked_rect.pBits + y * locked_rect.Pitch,
6305 (char *)formats[i].content + y * 4 * formats[i].pixel_size,
6306 tests[j].width * formats[i].pixel_size);
6308 hr = IDirect3DTexture8_UnlockRect(texture, 0);
6309 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
6311 if (tests[j].pool == D3DPOOL_SYSTEMMEM)
6313 texture_sysmem = texture;
6314 hr = IDirect3DDevice8_CreateTexture(device, tests[j].width, 4, 1, 0,
6315 formats[i].format, D3DPOOL_DEFAULT, &texture);
6316 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
6318 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)texture_sysmem,
6319 (IDirect3DBaseTexture8 *)texture);
6320 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
6321 IDirect3DTexture8_Release(texture_sysmem);
6324 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
6325 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
6326 hr = IDirect3DDevice8_SetPixelShader(device, shader_alpha);
6327 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6329 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00330033, 0.0f, 0);
6330 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
6331 hr = IDirect3DDevice8_BeginScene(device);
6332 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6333 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(*quad));
6334 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6335 hr = IDirect3DDevice8_EndScene(device);
6336 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6338 for (y = 0; y < 4; y++)
6340 for (x = 0; x < tests[j].width; x++)
6342 BOOL r200_broken = formats[i].alpha_broken && alpha_broken[y][x];
6343 if (formats[i].alpha)
6344 expected_color = expected_alpha[y][x];
6345 else
6346 expected_color = 0x00ffff00;
6348 color = getPixelColor(device, 80 + 160 * x, 60 + 120 * y);
6349 ok(color_match(color, expected_color, 1) || broken(r200_broken),
6350 "Expected color 0x%08x, got 0x%08x, format %s, location %ux%u.\n",
6351 expected_color, color, formats[i].name, x, y);
6354 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
6355 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
6357 hr = IDirect3DDevice8_SetPixelShader(device, shader);
6358 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6360 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00330033, 0.0f, 0);
6361 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
6362 hr = IDirect3DDevice8_BeginScene(device);
6363 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6364 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(*quad));
6365 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6366 hr = IDirect3DDevice8_EndScene(device);
6367 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6369 for (y = 0; y < 4; y++)
6371 for (x = 0; x < tests[j].width; x++)
6373 expected_color = expected_colors[y][x];
6374 if (!formats[i].blue)
6375 expected_color |= 0x000000ff;
6377 color = getPixelColor(device, 80 + 160 * x, 60 + 120 * y);
6378 ok(color_match(color, expected_color, formats[i].slop)
6379 || broken(color_match(color, expected_color, formats[i].slop_broken)),
6380 "Expected color 0x%08x, got 0x%08x, format %s, location %ux%u.\n",
6381 expected_color, color, formats[i].name, x, y);
6384 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
6385 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
6387 IDirect3DTexture8_Release(texture);
6391 IDirect3DDevice8_DeletePixelShader(device, shader);
6392 IDirect3DDevice8_DeletePixelShader(device, shader_alpha);
6394 done:
6395 refcount = IDirect3DDevice8_Release(device);
6396 ok(!refcount, "Device has %u references left.\n", refcount);
6397 IDirect3D8_Release(d3d);
6398 DestroyWindow(window);
6401 static void test_updatetexture(void)
6403 IDirect3DDevice8 *device;
6404 IDirect3D8 *d3d;
6405 HWND window;
6406 HRESULT hr;
6407 IDirect3DBaseTexture8 *src, *dst;
6408 unsigned int t, i, f, l, x, y, z;
6409 D3DLOCKED_RECT locked_rect;
6410 D3DLOCKED_BOX locked_box;
6411 ULONG refcount;
6412 D3DCAPS8 caps;
6413 D3DCOLOR color;
6414 BOOL ati2n_supported, do_visual_test;
6415 static const struct
6417 struct vec3 pos;
6418 struct vec2 texcoord;
6420 quad[] =
6422 {{-1.0f, -1.0f, 0.0f}, {0.0f, 1.0f}},
6423 {{-1.0f, 1.0f, 0.0f}, {0.0f, 0.0f}},
6424 {{ 1.0f, -1.0f, 0.0f}, {1.0f, 1.0f}},
6425 {{ 1.0f, 1.0f, 0.0f}, {1.0f, 0.0f}},
6427 static const struct
6429 struct vec3 pos;
6430 struct vec3 texcoord;
6432 quad_cube_tex[] =
6434 {{-1.0f, -1.0f, 0.0f}, {1.0f, -0.5f, 0.5f}},
6435 {{-1.0f, 1.0f, 0.0f}, {1.0f, 0.5f, 0.5f}},
6436 {{ 1.0f, -1.0f, 0.0f}, {1.0f, -0.5f, -0.5f}},
6437 {{ 1.0f, 1.0f, 0.0f}, {1.0f, 0.5f, -0.5f}},
6439 static const struct
6441 UINT src_width, src_height;
6442 UINT dst_width, dst_height;
6443 UINT src_levels, dst_levels;
6444 D3DFORMAT src_format, dst_format;
6445 BOOL broken;
6447 tests[] =
6449 {8, 8, 8, 8, 0, 0, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 0 */
6450 {8, 8, 8, 8, 4, 4, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 1 */
6451 {8, 8, 8, 8, 2, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 2 */
6452 {8, 8, 8, 8, 1, 1, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 3 */
6453 {8, 8, 8, 8, 4, 0, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 4 */
6454 {8, 8, 2, 2, 4, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 5 */
6455 /* The WARP renderer doesn't handle these cases correctly. */
6456 {8, 8, 8, 8, 4, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, TRUE}, /* 6 */
6457 {8, 8, 4, 4, 4, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, TRUE}, /* 7 */
6458 /* Not clear what happens here on Windows, it doesn't make much sense
6459 * though (on Nvidia it seems to upload the 4x4 surface into the 7x7
6460 * one or something like that). */
6461 /* {8, 8, 7, 7, 4, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, */
6462 {8, 8, 8, 8, 1, 4, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 8 */
6463 {4, 4, 8, 8, 1, 1, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 9 */
6464 /* This one causes weird behavior on Windows (it probably writes out
6465 * of the texture memory). */
6466 /* {8, 8, 4, 4, 1, 1, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, */
6467 {8, 4, 4, 2, 4, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 10 */
6468 {8, 4, 2, 4, 4, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 11 */
6469 {8, 8, 8, 8, 4, 4, D3DFMT_A8R8G8B8, D3DFMT_X8R8G8B8, FALSE}, /* 12 */
6470 {8, 8, 8, 8, 4, 4, D3DFMT_X8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 13 */
6471 /* The data is converted correctly on AMD, on Nvidia nothing happens
6472 * (it draws a black quad). */
6473 {8, 8, 8, 8, 4, 4, D3DFMT_A8R8G8B8, D3DFMT_R5G6B5, TRUE}, /* 14 */
6474 /* This one doesn't seem to give the expected results on AMD. */
6475 /* {8, 8, 8, 8, 4, 4, D3DFMT_A8R8G8B8, D3DFMT_Q8W8V8U8, FALSE}, */
6476 {8, 8, 8, 8, 4, 4, MAKEFOURCC('A','T','I','2'), MAKEFOURCC('A','T','I','2'), FALSE}, /* 15 */
6477 {8, 8, 8, 8, 4, 2, MAKEFOURCC('A','T','I','2'), MAKEFOURCC('A','T','I','2'), FALSE}, /* 16 */
6478 {8, 8, 2, 2, 4, 2, MAKEFOURCC('A','T','I','2'), MAKEFOURCC('A','T','I','2'), FALSE}, /* 17 */
6480 static const struct
6482 D3DRESOURCETYPE type;
6483 DWORD fvf;
6484 const void *quad;
6485 unsigned int vertex_size;
6486 DWORD cap;
6487 const char *name;
6489 texture_types[] =
6491 {D3DRTYPE_TEXTURE, D3DFVF_XYZ | D3DFVF_TEX1,
6492 quad, sizeof(*quad), D3DPTEXTURECAPS_MIPMAP, "2D mipmapped"},
6494 {D3DRTYPE_CUBETEXTURE, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE3(0),
6495 quad_cube_tex, sizeof(*quad_cube_tex), D3DPTEXTURECAPS_CUBEMAP, "Cube"},
6497 {D3DRTYPE_VOLUMETEXTURE, D3DFVF_XYZ | D3DFVF_TEX1,
6498 quad, sizeof(*quad), D3DPTEXTURECAPS_VOLUMEMAP, "Volume"}
6501 window = create_window();
6502 d3d = Direct3DCreate8(D3D_SDK_VERSION);
6503 ok(!!d3d, "Failed to create a D3D object.\n");
6504 if (!(device = create_device(d3d, window, window, TRUE)))
6506 skip("Failed to create a D3D device, skipping tests.\n");
6507 IDirect3D8_Release(d3d);
6508 DestroyWindow(window);
6509 return;
6512 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
6513 ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
6515 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR);
6516 ok(SUCCEEDED(hr), "Failed to set texture filtering state, hr %#x.\n", hr);
6517 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP);
6518 ok(SUCCEEDED(hr), "Failed to set texture filtering state, hr %#x.\n", hr);
6519 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP);
6520 ok(SUCCEEDED(hr), "Failed to set texture filtering state, hr %#x.\n", hr);
6521 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_ADDRESSW, D3DTADDRESS_CLAMP);
6522 ok(SUCCEEDED(hr), "Failed to set texture filtering state, hr %#x.\n", hr);
6523 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6524 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6525 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
6526 ok(hr == D3D_OK, "Failed to set texture stage state, hr %#x.\n", hr);
6527 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
6528 ok(hr == D3D_OK, "Failed to set texture stage state, hr %#x.\n", hr);
6530 for (t = 0; t < sizeof(texture_types) / sizeof(*texture_types); ++t)
6532 if (!(caps.TextureCaps & texture_types[t].cap))
6534 skip("%s textures not supported, skipping some tests.\n", texture_types[t].name);
6535 continue;
6538 if (FAILED(IDirect3D8_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
6539 D3DFMT_X8R8G8B8, 0, texture_types[t].type, MAKEFOURCC('A','T','I','2'))))
6541 skip("%s ATI2N textures are not supported, skipping some tests.\n", texture_types[t].name);
6542 ati2n_supported = FALSE;
6544 else
6546 ati2n_supported = TRUE;
6549 hr = IDirect3DDevice8_SetVertexShader(device, texture_types[t].fvf);
6550 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
6552 for (i = 0; i < sizeof(tests) / sizeof(*tests); ++i)
6554 if (tests[i].src_format == MAKEFOURCC('A','T','I','2') && !ati2n_supported)
6555 continue;
6557 switch (texture_types[t].type)
6559 case D3DRTYPE_TEXTURE:
6560 hr = IDirect3DDevice8_CreateTexture(device,
6561 tests[i].src_width, tests[i].src_height,
6562 tests[i].src_levels, 0, tests[i].src_format, D3DPOOL_SYSTEMMEM,
6563 (IDirect3DTexture8 **)&src);
6564 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x, case %u, %u.\n", hr, t, i);
6565 hr = IDirect3DDevice8_CreateTexture(device,
6566 tests[i].dst_width, tests[i].dst_height,
6567 tests[i].dst_levels, 0, tests[i].dst_format, D3DPOOL_DEFAULT,
6568 (IDirect3DTexture8 **)&dst);
6569 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x, case %u, %u.\n", hr, t, i);
6570 break;
6571 case D3DRTYPE_CUBETEXTURE:
6572 hr = IDirect3DDevice8_CreateCubeTexture(device,
6573 tests[i].src_width,
6574 tests[i].src_levels, 0, tests[i].src_format, D3DPOOL_SYSTEMMEM,
6575 (IDirect3DCubeTexture8 **)&src);
6576 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x, case %u, %u.\n", hr, t, i);
6577 hr = IDirect3DDevice8_CreateCubeTexture(device,
6578 tests[i].dst_width,
6579 tests[i].dst_levels, 0, tests[i].dst_format, D3DPOOL_DEFAULT,
6580 (IDirect3DCubeTexture8 **)&dst);
6581 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x, case %u, %u.\n", hr, t, i);
6582 break;
6583 case D3DRTYPE_VOLUMETEXTURE:
6584 hr = IDirect3DDevice8_CreateVolumeTexture(device,
6585 tests[i].src_width, tests[i].src_height, tests[i].src_width,
6586 tests[i].src_levels, 0, tests[i].src_format, D3DPOOL_SYSTEMMEM,
6587 (IDirect3DVolumeTexture8 **)&src);
6588 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x, case %u, %u.\n", hr, t, i);
6589 hr = IDirect3DDevice8_CreateVolumeTexture(device,
6590 tests[i].dst_width, tests[i].dst_height, tests[i].dst_width,
6591 tests[i].dst_levels, 0, tests[i].dst_format, D3DPOOL_DEFAULT,
6592 (IDirect3DVolumeTexture8 **)&dst);
6593 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x, case %u, %u.\n", hr, t, i);
6594 break;
6595 default:
6596 trace("Unexpected resource type.\n");
6599 /* Skip the visual part of the test for ATI2N (laziness) and cases that
6600 * give a different (and unlikely to be useful) result. */
6601 do_visual_test = (tests[i].src_format == D3DFMT_A8R8G8B8 || tests[i].src_format == D3DFMT_X8R8G8B8)
6602 && tests[i].src_levels != 0
6603 && tests[i].src_width >= tests[i].dst_width && tests[i].src_height >= tests[i].dst_height
6604 && !(tests[i].src_width > tests[i].src_height && tests[i].dst_width < tests[i].dst_height);
6606 if (do_visual_test)
6608 DWORD *ptr = NULL;
6609 unsigned int width, height, depth, row_pitch = 0, slice_pitch = 0;
6611 for (f = 0; f < (texture_types[t].type == D3DRTYPE_CUBETEXTURE ? 6 : 1); ++f)
6613 width = tests[i].src_width;
6614 height = texture_types[t].type != D3DRTYPE_CUBETEXTURE ? tests[i].src_height : tests[i].src_width;
6615 depth = texture_types[t].type == D3DRTYPE_VOLUMETEXTURE ? width : 1;
6617 for (l = 0; l < tests[i].src_levels; ++l)
6619 switch (texture_types[t].type)
6621 case D3DRTYPE_TEXTURE:
6622 hr = IDirect3DTexture8_LockRect((IDirect3DTexture8 *)src,
6623 l, &locked_rect, NULL, 0);
6624 ptr = locked_rect.pBits;
6625 row_pitch = locked_rect.Pitch / sizeof(*ptr);
6626 break;
6627 case D3DRTYPE_CUBETEXTURE:
6628 hr = IDirect3DCubeTexture8_LockRect((IDirect3DCubeTexture8 *)src,
6629 f, l, &locked_rect, NULL, 0);
6630 ptr = locked_rect.pBits;
6631 row_pitch = locked_rect.Pitch / sizeof(*ptr);
6632 break;
6633 case D3DRTYPE_VOLUMETEXTURE:
6634 hr = IDirect3DVolumeTexture8_LockBox((IDirect3DVolumeTexture8 *)src,
6635 l, &locked_box, NULL, 0);
6636 ptr = locked_box.pBits;
6637 row_pitch = locked_box.RowPitch / sizeof(*ptr);
6638 slice_pitch = locked_box.SlicePitch / sizeof(*ptr);
6639 break;
6640 default:
6641 trace("Unexpected resource type.\n");
6643 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
6645 for (z = 0; z < depth; ++z)
6647 for (y = 0; y < height; ++y)
6649 for (x = 0; x < width; ++x)
6651 ptr[z * slice_pitch + y * row_pitch + x] = 0xff000000
6652 | (DWORD)(x / (width - 1.0f) * 255.0f) << 16
6653 | (DWORD)(y / (height - 1.0f) * 255.0f) << 8;
6658 switch (texture_types[t].type)
6660 case D3DRTYPE_TEXTURE:
6661 hr = IDirect3DTexture8_UnlockRect((IDirect3DTexture8 *)src, l);
6662 break;
6663 case D3DRTYPE_CUBETEXTURE:
6664 hr = IDirect3DCubeTexture8_UnlockRect((IDirect3DCubeTexture8 *)src, f, l);
6665 break;
6666 case D3DRTYPE_VOLUMETEXTURE:
6667 hr = IDirect3DVolumeTexture8_UnlockBox((IDirect3DVolumeTexture8 *)src, l);
6668 break;
6669 default:
6670 trace("Unexpected resource type.\n");
6672 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
6674 width >>= 1;
6675 if (!width)
6676 width = 1;
6677 height >>= 1;
6678 if (!height)
6679 height = 1;
6680 depth >>= 1;
6681 if (!depth)
6682 depth = 1;
6687 hr = IDirect3DDevice8_UpdateTexture(device, src, dst);
6688 if (FAILED(hr))
6690 todo_wine ok(SUCCEEDED(hr), "Failed to update texture, hr %#x, case %u, %u.\n", hr, t, i);
6691 IDirect3DBaseTexture8_Release(src);
6692 IDirect3DBaseTexture8_Release(dst);
6693 continue;
6695 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x, case %u, %u.\n", hr, t, i);
6697 if (do_visual_test)
6699 hr = IDirect3DDevice8_SetTexture(device, 0, dst);
6700 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
6702 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 1.0f, 0);
6703 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
6705 hr = IDirect3DDevice8_BeginScene(device);
6706 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6707 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,
6708 texture_types[t].quad, texture_types[t].vertex_size);
6709 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6710 hr = IDirect3DDevice8_EndScene(device);
6711 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6713 color = getPixelColor(device, 320, 240);
6714 ok (color_match(color, 0x007f7f00, 2) || broken(tests[i].broken)
6715 || broken(color == 0x00adbeef), /* WARP device often just breaks down. */
6716 "Got unexpected color 0x%08x, case %u, %u.\n", color, t, i);
6719 IDirect3DBaseTexture8_Release(src);
6720 IDirect3DBaseTexture8_Release(dst);
6724 refcount = IDirect3DDevice8_Release(device);
6725 ok(!refcount, "Device has %u references left.\n", refcount);
6726 IDirect3D8_Release(d3d);
6727 DestroyWindow(window);
6730 static BOOL point_match(IDirect3DDevice8 *device, UINT x, UINT y, UINT r)
6732 D3DCOLOR color;
6734 color = D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff);
6735 if (!color_match(getPixelColor(device, x + r, y), color, 1))
6736 return FALSE;
6737 if (!color_match(getPixelColor(device, x - r, y), color, 1))
6738 return FALSE;
6739 if (!color_match(getPixelColor(device, x, y + r), color, 1))
6740 return FALSE;
6741 if (!color_match(getPixelColor(device, x, y - r), color, 1))
6742 return FALSE;
6744 ++r;
6745 color = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff);
6746 if (!color_match(getPixelColor(device, x + r, y), color, 1))
6747 return FALSE;
6748 if (!color_match(getPixelColor(device, x - r, y), color, 1))
6749 return FALSE;
6750 if (!color_match(getPixelColor(device, x, y + r), color, 1))
6751 return FALSE;
6752 if (!color_match(getPixelColor(device, x, y - r), color, 1))
6753 return FALSE;
6755 return TRUE;
6758 static void test_pointsize(void)
6760 static const float a = 0.5f, b = 0.5f, c = 0.5f;
6761 float ptsize, ptsizemax_orig, ptsizemin_orig;
6762 IDirect3DSurface8 *rt, *backbuffer, *depthstencil;
6763 IDirect3DTexture8 *tex1, *tex2;
6764 IDirect3DDevice8 *device;
6765 DWORD vs, ps;
6766 D3DLOCKED_RECT lr;
6767 IDirect3D8 *d3d;
6768 D3DCOLOR color;
6769 ULONG refcount;
6770 D3DCAPS8 caps;
6771 HWND window;
6772 HRESULT hr;
6773 unsigned int i, j;
6775 static const DWORD tex1_data[4] = {0x00ff0000, 0x00ff0000, 0x00000000, 0x00000000};
6776 static const DWORD tex2_data[4] = {0x00000000, 0x0000ff00, 0x00000000, 0x0000ff00};
6777 static const float vertices[] =
6779 64.0f, 64.0f, 0.1f,
6780 128.0f, 64.0f, 0.1f,
6781 192.0f, 64.0f, 0.1f,
6782 256.0f, 64.0f, 0.1f,
6783 320.0f, 64.0f, 0.1f,
6784 384.0f, 64.0f, 0.1f,
6785 448.0f, 64.0f, 0.1f,
6786 512.0f, 64.0f, 0.1f,
6788 static const struct
6790 float x, y, z;
6791 float point_size;
6793 vertex_pointsize = {64.0f, 64.0f, 0.1f, 48.0f},
6794 vertex_pointsize_scaled = {64.0f, 64.0f, 0.1f, 24.0f},
6795 vertex_pointsize_zero = {64.0f, 64.0f, 0.1f, 0.0f};
6796 static const DWORD decl[] =
6798 D3DVSD_STREAM(0),
6799 D3DVSD_REG(0, D3DVSDT_FLOAT3), /* position */
6800 D3DVSD_END()
6802 decl_psize[] =
6804 D3DVSD_STREAM(0),
6805 D3DVSD_REG(0, D3DVSDT_FLOAT3), /* position, v0 */
6806 D3DVSD_REG(1, D3DVSDT_FLOAT1), /* point size, v1 */
6807 D3DVSD_END()
6809 static const DWORD vshader_code[] =
6811 0xfffe0101, /* vs_1_1 */
6812 0x00000005, 0x800f0000, 0x90000000, 0xa0e40000, /* mul r0, v0.x, c0 */
6813 0x00000004, 0x800f0000, 0x90550000, 0xa0e40001, 0x80e40000, /* mad r0, v0.y, c1, r0 */
6814 0x00000004, 0x800f0000, 0x90aa0000, 0xa0e40002, 0x80e40000, /* mad r0, v0.z, c2, r0 */
6815 0x00000004, 0xc00f0000, 0x90ff0000, 0xa0e40003, 0x80e40000, /* mad oPos, v0.w, c3, r0 */
6816 0x0000ffff
6818 static const DWORD vshader_psize_code[] =
6820 0xfffe0101, /* vs_1_1 */
6821 0x00000005, 0x800f0000, 0x90000000, 0xa0e40000, /* mul r0, v0.x, c0 */
6822 0x00000004, 0x800f0000, 0x90550000, 0xa0e40001, 0x80e40000, /* mad r0, v0.y, c1, r0 */
6823 0x00000004, 0x800f0000, 0x90aa0000, 0xa0e40002, 0x80e40000, /* mad r0, v0.z, c2, r0 */
6824 0x00000004, 0xc00f0000, 0x90ff0000, 0xa0e40003, 0x80e40000, /* mad oPos, v0.w, c3, r0 */
6825 0x00000001, 0xc00f0002, 0x90000001, /* mov oPts, v1.x */
6826 0x0000ffff
6828 static const DWORD pshader_code[] =
6830 0xffff0101, /* ps_1_1 */
6831 0x00000042, 0xb00f0000, /* tex t0 */
6832 0x00000042, 0xb00f0001, /* tex t1 */
6833 0x00000002, 0x800f0000, 0xb0e40000, 0xb0e40001, /* add r0, t0, t1 */
6834 0x0000ffff
6836 static const struct test_shader
6838 DWORD version;
6839 const DWORD *code;
6841 novs = {0, NULL},
6842 vs1 = {D3DVS_VERSION(1, 1), vshader_code},
6843 vs1_psize = {D3DVS_VERSION(1, 1), vshader_psize_code},
6844 nops = {0, NULL},
6845 ps1 = {D3DPS_VERSION(1, 1), pshader_code};
6846 static const struct
6848 const DWORD *decl;
6849 const struct test_shader *vs;
6850 const struct test_shader *ps;
6851 DWORD accepted_fvf;
6852 unsigned int nonscaled_size, scaled_size;
6854 test_setups[] =
6856 {NULL, &novs, &nops, D3DFVF_XYZ, 32, 62},
6857 {decl, &vs1, &ps1, D3DFVF_XYZ, 32, 32},
6858 {NULL, &novs, &ps1, D3DFVF_XYZ, 32, 62},
6859 {decl, &vs1, &nops, D3DFVF_XYZ, 32, 32},
6860 {NULL, &novs, &nops, D3DFVF_XYZ | D3DFVF_PSIZE, 48, 48},
6861 {decl_psize, &vs1_psize, &ps1, D3DFVF_XYZ | D3DFVF_PSIZE, 48, 24},
6863 static const struct
6865 BOOL zero_size;
6866 BOOL scale;
6867 BOOL override_min;
6868 DWORD fvf;
6869 const void *vertex_data;
6870 unsigned int vertex_size;
6872 tests[] =
6874 {FALSE, FALSE, FALSE, D3DFVF_XYZ, vertices, sizeof(float) * 3},
6875 {FALSE, TRUE, FALSE, D3DFVF_XYZ, vertices, sizeof(float) * 3},
6876 {FALSE, FALSE, TRUE, D3DFVF_XYZ, vertices, sizeof(float) * 3},
6877 {TRUE, FALSE, FALSE, D3DFVF_XYZ, vertices, sizeof(float) * 3},
6878 {FALSE, FALSE, FALSE, D3DFVF_XYZ | D3DFVF_PSIZE, &vertex_pointsize, sizeof(vertex_pointsize)},
6879 {FALSE, TRUE, FALSE, D3DFVF_XYZ | D3DFVF_PSIZE, &vertex_pointsize_scaled, sizeof(vertex_pointsize_scaled)},
6880 {FALSE, FALSE, TRUE, D3DFVF_XYZ | D3DFVF_PSIZE, &vertex_pointsize, sizeof(vertex_pointsize)},
6881 {TRUE, FALSE, FALSE, D3DFVF_XYZ | D3DFVF_PSIZE, &vertex_pointsize_zero, sizeof(vertex_pointsize_zero)},
6883 /* Transforms the coordinate system [-1.0;1.0]x[1.0;-1.0] to
6884 * [0.0;0.0]x[640.0;480.0]. Z is untouched. */
6885 D3DMATRIX matrix =
6887 2.0f / 640.0f, 0.0f, 0.0f, 0.0f,
6888 0.0f, -2.0f / 480.0f, 0.0f, 0.0f,
6889 0.0f, 0.0f, 1.0f, 0.0f,
6890 -1.0f, 1.0f, 0.0f, 1.0f,
6891 }}};
6893 window = create_window();
6894 d3d = Direct3DCreate8(D3D_SDK_VERSION);
6895 ok(!!d3d, "Failed to create a D3D object.\n");
6896 if (!(device = create_device(d3d, window, window, TRUE)))
6898 skip("Failed to create a D3D device, skipping tests.\n");
6899 goto done;
6902 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
6903 ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
6904 if (caps.MaxPointSize < 32.0f)
6906 skip("MaxPointSize %f < 32.0, skipping.\n", caps.MaxPointSize);
6907 IDirect3DDevice8_Release(device);
6908 goto done;
6911 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
6912 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
6913 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6914 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
6915 hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, &matrix);
6916 ok(SUCCEEDED(hr), "Failed to set projection matrix, hr %#x.\n", hr);
6917 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ);
6918 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
6920 hr = IDirect3DDevice8_BeginScene(device);
6921 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6923 ptsize = 15.0f;
6924 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
6925 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6926 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
6927 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6929 ptsize = 31.0f;
6930 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
6931 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6932 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[3], sizeof(float) * 3);
6933 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6935 ptsize = 30.75f;
6936 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
6937 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6938 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[6], sizeof(float) * 3);
6939 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6941 if (caps.MaxPointSize >= 63.0f)
6943 ptsize = 63.0f;
6944 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
6945 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6946 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[9], sizeof(float) * 3);
6947 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6949 ptsize = 62.75f;
6950 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
6951 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6952 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[15], sizeof(float) * 3);
6953 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6956 ptsize = 1.0f;
6957 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
6958 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6959 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[12], sizeof(float) * 3);
6960 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6962 hr = IDirect3DDevice8_GetRenderState(device, D3DRS_POINTSIZE_MAX, (DWORD *)&ptsizemax_orig);
6963 ok(SUCCEEDED(hr), "Failed to get render state, hr %#x.\n", hr);
6964 hr = IDirect3DDevice8_GetRenderState(device, D3DRS_POINTSIZE_MIN, (DWORD *)&ptsizemin_orig);
6965 ok(SUCCEEDED(hr), "Failed to get render state, hr %#x.\n", hr);
6967 /* What happens if point scaling is disabled, and POINTSIZE_MAX < POINTSIZE? */
6968 ptsize = 15.0f;
6969 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
6970 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6971 ptsize = 1.0f;
6972 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE_MAX, *(DWORD *)&ptsize);
6973 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6974 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[18], sizeof(float) * 3);
6975 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6977 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE_MAX, *(DWORD *)&ptsizemax_orig);
6978 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6980 /* pointsize < pointsize_min < pointsize_max?
6981 * pointsize = 1.0, pointsize_min = 15.0, pointsize_max = default(usually 64.0) */
6982 ptsize = 1.0f;
6983 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
6984 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6985 ptsize = 15.0f;
6986 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE_MIN, *(DWORD *)&ptsize);
6987 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6988 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[21], sizeof(float) * 3);
6989 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6991 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE_MIN, *(DWORD *)&ptsizemin_orig);
6992 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6994 hr = IDirect3DDevice8_EndScene(device);
6995 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6997 ok(point_match(device, 64, 64, 7), "point_match(64, 64, 7) failed, expected point size 15.\n");
6998 ok(point_match(device, 128, 64, 15), "point_match(128, 64, 15) failed, expected point size 31.\n");
6999 ok(point_match(device, 192, 64, 15), "point_match(192, 64, 15) failed, expected point size 31.\n");
7001 if (caps.MaxPointSize >= 63.0f)
7003 ok(point_match(device, 256, 64, 31), "point_match(256, 64, 31) failed, expected point size 63.\n");
7004 ok(point_match(device, 384, 64, 31), "point_match(384, 64, 31) failed, expected point size 63.\n");
7007 ok(point_match(device, 320, 64, 0), "point_match(320, 64, 0) failed, expected point size 1.\n");
7008 /* ptsize = 15, ptsize_max = 1 --> point has size 1 */
7009 ok(point_match(device, 448, 64, 0), "point_match(448, 64, 0) failed, expected point size 1.\n");
7010 /* ptsize = 1, ptsize_max = default(64), ptsize_min = 15 --> point has size 15 */
7011 ok(point_match(device, 512, 64, 7), "point_match(512, 64, 7) failed, expected point size 15.\n");
7013 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
7015 /* The following code tests point sprites with two textures, to see if each texture coordinate unit
7016 * generates texture coordinates for the point(result: Yes, it does)
7018 * However, not all GL implementations support point sprites(they need GL_ARB_point_sprite), but there
7019 * is no point sprite cap bit in d3d because native d3d software emulates point sprites. Until the
7020 * SW emulation is implemented in wined3d, this test will fail on GL drivers that does not support them.
7022 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
7023 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
7025 hr = IDirect3DDevice8_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex1);
7026 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
7027 hr = IDirect3DDevice8_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex2);
7028 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
7029 memset(&lr, 0, sizeof(lr));
7030 hr = IDirect3DTexture8_LockRect(tex1, 0, &lr, NULL, 0);
7031 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
7032 memcpy(lr.pBits, tex1_data, sizeof(tex1_data));
7033 hr = IDirect3DTexture8_UnlockRect(tex1, 0);
7034 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
7035 memset(&lr, 0, sizeof(lr));
7036 hr = IDirect3DTexture8_LockRect(tex2, 0, &lr, NULL, 0);
7037 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
7038 memcpy(lr.pBits, tex2_data, sizeof(tex2_data));
7039 hr = IDirect3DTexture8_UnlockRect(tex2, 0);
7040 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
7041 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)tex1);
7042 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
7043 hr = IDirect3DDevice8_SetTexture(device, 1, (IDirect3DBaseTexture8 *)tex2);
7044 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
7045 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7046 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
7047 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7048 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
7049 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
7050 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
7051 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7052 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
7053 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
7054 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
7056 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSPRITEENABLE, TRUE);
7057 ok(SUCCEEDED(hr), "Failed to enable point sprites, hr %#x.\n", hr);
7058 ptsize = 32.0f;
7059 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
7060 ok(SUCCEEDED(hr), "Failed to set point size, hr %#x.\n", hr);
7062 hr = IDirect3DDevice8_BeginScene(device);
7063 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7064 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
7065 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7066 hr = IDirect3DDevice8_EndScene(device);
7067 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7069 color = getPixelColor(device, 64 - 4, 64 - 4);
7070 ok(color == 0x00ff0000, "pSprite: Pixel (64 - 4),(64 - 4) has color 0x%08x, expected 0x00ff0000\n", color);
7071 color = getPixelColor(device, 64 - 4, 64 + 4);
7072 ok(color == 0x00000000, "pSprite: Pixel (64 - 4),(64 + 4) has color 0x%08x, expected 0x00000000\n", color);
7073 color = getPixelColor(device, 64 + 4, 64 + 4);
7074 ok(color == 0x0000ff00, "pSprite: Pixel (64 + 4),(64 + 4) has color 0x%08x, expected 0x0000ff00\n", color);
7075 color = getPixelColor(device, 64 + 4, 64 - 4);
7076 ok(color == 0x00ffff00, "pSprite: Pixel (64 + 4),(64 - 4) has color 0x%08x, expected 0x00ffff00\n", color);
7077 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
7079 U(matrix).m[0][0] = 1.0f / 64.0f;
7080 U(matrix).m[1][1] = -1.0f / 64.0f;
7081 hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, &matrix);
7082 ok(SUCCEEDED(hr), "Failed to set projection matrix, hr %#x.\n", hr);
7084 hr = IDirect3DDevice8_GetRenderTarget(device, &backbuffer);
7085 ok(SUCCEEDED(hr), "Failed to get backbuffer, hr %#x.\n", hr);
7086 hr = IDirect3DDevice8_GetDepthStencilSurface(device, &depthstencil);
7087 ok(SUCCEEDED(hr), "Failed to get depth / stencil buffer, hr %#x.\n", hr);
7089 hr = IDirect3DDevice8_CreateRenderTarget(device, 128, 128, D3DFMT_A8R8G8B8,
7090 D3DMULTISAMPLE_NONE, TRUE, &rt);
7091 ok(SUCCEEDED(hr), "Failed to create a render target, hr %#x.\n", hr);
7093 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSCALE_A, *(DWORD *)&a);
7094 ok(SUCCEEDED(hr), "Failed setting point scale attenuation coefficient, hr %#x.\n", hr);
7095 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSCALE_B, *(DWORD *)&b);
7096 ok(SUCCEEDED(hr), "Failed setting point scale attenuation coefficient, hr %#x.\n", hr);
7097 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSCALE_C, *(DWORD *)&c);
7098 ok(SUCCEEDED(hr), "Failed setting point scale attenuation coefficient, hr %#x.\n", hr);
7099 hr = IDirect3DDevice8_SetVertexShaderConstant(device, 0, &S(U(matrix))._11, 4);
7100 ok(SUCCEEDED(hr), "Failed to set vertex shader constants, hr %#x.\n", hr);
7102 if (caps.MaxPointSize < 63.0f)
7104 skip("MaxPointSize %f < 63.0, skipping some tests.\n", caps.MaxPointSize);
7105 goto cleanup;
7108 hr = IDirect3DDevice8_SetRenderTarget(device, rt, depthstencil);
7109 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
7111 for (i = 0; i < sizeof(test_setups) / sizeof(test_setups[0]); ++i)
7113 if (caps.VertexShaderVersion < test_setups[i].vs->version
7114 || caps.PixelShaderVersion < test_setups[i].ps->version)
7116 skip("Vertex / pixel shader version not supported, skipping test.\n");
7117 continue;
7119 if (test_setups[i].vs->code)
7121 hr = IDirect3DDevice8_CreateVertexShader(device, test_setups[i].decl, test_setups[i].vs->code, &vs, 0);
7122 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x (case %u).\n", hr, i);
7124 else
7126 vs = 0;
7128 if (test_setups[i].ps->code)
7130 hr = IDirect3DDevice8_CreatePixelShader(device, test_setups[i].ps->code, &ps);
7131 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x (case %u).\n", hr, i);
7133 else
7135 ps = 0;
7138 hr = IDirect3DDevice8_SetVertexShader(device, vs ? vs : test_setups[i].accepted_fvf);
7139 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
7140 hr = IDirect3DDevice8_SetPixelShader(device, ps);
7141 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
7143 for (j = 0; j < sizeof(tests) / sizeof(tests[0]); ++j)
7145 unsigned int size = tests[j].override_min ? 63 : tests[j].zero_size ? 0 : tests[j].scale
7146 ? test_setups[i].scaled_size : test_setups[i].nonscaled_size;
7148 if (test_setups[i].accepted_fvf != tests[j].fvf)
7149 continue;
7151 ptsize = tests[j].zero_size ? 0.0f : 32.0f;
7152 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
7153 ok(SUCCEEDED(hr), "Failed to set pointsize, hr %#x.\n", hr);
7155 ptsize = tests[j].override_min ? 63.0f : tests[j].zero_size ? 0.0f : ptsizemin_orig;
7156 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE_MIN, *(DWORD *)&ptsize);
7157 ok(SUCCEEDED(hr), "Failed to set minimum pointsize, hr %#x.\n", hr);
7159 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSCALEENABLE, tests[j].scale);
7160 ok(SUCCEEDED(hr), "Failed setting point scale state, hr %#x.\n", hr);
7162 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
7163 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
7165 hr = IDirect3DDevice8_BeginScene(device);
7166 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7167 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1,
7168 tests[j].vertex_data, tests[j].vertex_size);
7169 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7170 hr = IDirect3DDevice8_EndScene(device);
7171 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7173 if (tests[j].zero_size)
7175 /* Technically 0 pointsize is undefined in OpenGL but in practice it seems like
7176 * it does the "useful" thing on all the drivers I tried. */
7177 /* On WARP it does draw some pixels, most of the time. */
7178 color = getPixelColor(device, 64, 64);
7179 ok(color_match(color, 0x0000ffff, 0)
7180 || broken(color_match(color, 0x00ff0000, 0))
7181 || broken(color_match(color, 0x00ffff00, 0))
7182 || broken(color_match(color, 0x00000000, 0))
7183 || broken(color_match(color, 0x0000ff00, 0)),
7184 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
7186 else
7188 struct surface_readback rb;
7190 get_rt_readback(rt, &rb);
7191 color = get_readback_color(&rb, 64 - size / 2 + 1, 64 - size / 2 + 1);
7192 ok(color_match(color, 0x00ff0000, 0),
7193 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
7194 color = get_readback_color(&rb, 64 + size / 2 - 1, 64 - size / 2 + 1);
7195 ok(color_match(color, 0x00ffff00, 0),
7196 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
7197 color = get_readback_color(&rb, 64 - size / 2 + 1, 64 + size / 2 - 1);
7198 ok(color_match(color, 0x00000000, 0),
7199 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
7200 color = get_readback_color(&rb, 64 + size / 2 - 1, 64 + size / 2 - 1);
7201 ok(color_match(color, 0x0000ff00, 0),
7202 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
7204 color = get_readback_color(&rb, 64 - size / 2 - 1, 64 - size / 2 - 1);
7205 ok(color_match(color, 0xff00ffff, 0),
7206 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
7207 color = get_readback_color(&rb, 64 + size / 2 + 1, 64 - size / 2 - 1);
7208 ok(color_match(color, 0xff00ffff, 0),
7209 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
7210 color = get_readback_color(&rb, 64 - size / 2 - 1, 64 + size / 2 + 1);
7211 ok(color_match(color, 0xff00ffff, 0),
7212 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
7213 color = get_readback_color(&rb, 64 + size / 2 + 1, 64 + size / 2 + 1);
7214 ok(color_match(color, 0xff00ffff, 0),
7215 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
7217 release_surface_readback(&rb);
7220 IDirect3DDevice8_SetVertexShader(device, 0);
7221 IDirect3DDevice8_SetPixelShader(device, 0);
7222 if (vs)
7223 IDirect3DDevice8_DeleteVertexShader(device, vs);
7224 if (ps)
7225 IDirect3DDevice8_DeletePixelShader(device, ps);
7227 hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, depthstencil);
7228 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
7230 cleanup:
7231 IDirect3DSurface8_Release(backbuffer);
7232 IDirect3DSurface8_Release(depthstencil);
7233 IDirect3DSurface8_Release(rt);
7235 IDirect3DTexture8_Release(tex1);
7236 IDirect3DTexture8_Release(tex2);
7237 refcount = IDirect3DDevice8_Release(device);
7238 ok(!refcount, "Device has %u references left.\n", refcount);
7239 done:
7240 IDirect3D8_Release(d3d);
7241 DestroyWindow(window);
7244 static void test_multisample_mismatch(void)
7246 IDirect3DDevice8 *device;
7247 IDirect3D8 *d3d;
7248 HWND window;
7249 HRESULT hr;
7250 ULONG refcount;
7251 IDirect3DSurface8 *rt_multi, *ds;
7253 window = create_window();
7254 d3d = Direct3DCreate8(D3D_SDK_VERSION);
7255 ok(!!d3d, "Failed to create a D3D object.\n");
7256 if (FAILED(IDirect3D8_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
7257 D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES)))
7259 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping multisample mismatch test.\n");
7260 IDirect3D8_Release(d3d);
7261 return;
7264 if (!(device = create_device(d3d, window, window, TRUE)))
7266 skip("Failed to create a D3D device, skipping tests.\n");
7267 goto done;
7270 hr = IDirect3DDevice8_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
7271 D3DMULTISAMPLE_2_SAMPLES, FALSE, &rt_multi);
7272 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
7273 hr = IDirect3DDevice8_GetDepthStencilSurface(device, &ds);
7274 ok(SUCCEEDED(hr), "Failed to get original depth/stencil, hr %#x.\n", hr);
7276 hr = IDirect3DDevice8_SetRenderTarget(device, rt_multi, ds);
7277 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
7279 IDirect3DSurface8_Release(ds);
7280 IDirect3DSurface8_Release(rt_multi);
7282 refcount = IDirect3DDevice8_Release(device);
7283 ok(!refcount, "Device has %u references left.\n", refcount);
7284 done:
7285 IDirect3D8_Release(d3d);
7286 DestroyWindow(window);
7289 static void test_texcoordindex(void)
7291 static const D3DMATRIX mat =
7293 1.0f, 0.0f, 0.0f, 0.0f,
7294 0.0f, 0.0f, 0.0f, 0.0f,
7295 0.0f, 0.0f, 0.0f, 0.0f,
7296 0.0f, 0.0f, 0.0f, 0.0f,
7297 }}};
7298 static const struct
7300 struct vec3 pos;
7301 struct vec2 texcoord1;
7302 struct vec2 texcoord2;
7303 struct vec2 texcoord3;
7305 quad[] =
7307 {{-1.0f, -1.0f, 0.0f}, {0.0f, 1.0f}, {0.0f, 0.0f}, {1.0f, 1.0f}},
7308 {{-1.0f, 1.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 1.0f}, {1.0f, 0.0f}},
7309 {{ 1.0f, -1.0f, 0.0f}, {1.0f, 1.0f}, {1.0f, 0.0f}, {0.0f, 1.0f}},
7310 {{ 1.0f, 1.0f, 0.0f}, {1.0f, 0.0f}, {1.0f, 1.0f}, {0.0f, 0.0f}},
7312 IDirect3DDevice8 *device;
7313 IDirect3D8 *d3d;
7314 HWND window;
7315 HRESULT hr;
7316 IDirect3DTexture8 *texture1, *texture2;
7317 D3DLOCKED_RECT locked_rect;
7318 ULONG refcount;
7319 D3DCOLOR color;
7320 DWORD *ptr;
7322 window = create_window();
7323 d3d = Direct3DCreate8(D3D_SDK_VERSION);
7324 ok(!!d3d, "Failed to create a D3D object.\n");
7325 if (!(device = create_device(d3d, window, window, TRUE)))
7327 skip("Failed to create a D3D device, skipping tests.\n");
7328 IDirect3D8_Release(d3d);
7329 DestroyWindow(window);
7330 return;
7333 hr = IDirect3DDevice8_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture1);
7334 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
7335 hr = IDirect3DDevice8_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture2);
7336 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
7338 hr = IDirect3DTexture8_LockRect(texture1, 0, &locked_rect, NULL, D3DLOCK_DISCARD);
7339 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
7340 ptr = locked_rect.pBits;
7341 ptr[0] = 0xff000000;
7342 ptr[1] = 0xff00ff00;
7343 ptr[2] = 0xff0000ff;
7344 ptr[3] = 0xff00ffff;
7345 hr = IDirect3DTexture8_UnlockRect(texture1, 0);
7346 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
7348 hr = IDirect3DTexture8_LockRect(texture2, 0, &locked_rect, NULL, D3DLOCK_DISCARD);
7349 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
7350 ptr = locked_rect.pBits;
7351 ptr[0] = 0xff000000;
7352 ptr[1] = 0xff0000ff;
7353 ptr[2] = 0xffff0000;
7354 ptr[3] = 0xffff00ff;
7355 hr = IDirect3DTexture8_UnlockRect(texture2, 0);
7356 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
7358 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture1);
7359 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
7360 hr = IDirect3DDevice8_SetTexture(device, 1, (IDirect3DBaseTexture8 *)texture2);
7361 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
7362 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX3);
7363 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
7364 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
7365 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
7366 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7367 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
7368 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7369 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
7370 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
7371 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
7372 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7373 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
7374 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
7375 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
7376 hr = IDirect3DDevice8_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
7377 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
7379 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_TEXCOORDINDEX, 1);
7380 ok(SUCCEEDED(hr), "Failed to set texcoord index, hr %#x.\n", hr);
7381 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_TEXCOORDINDEX, 0);
7382 ok(SUCCEEDED(hr), "Failed to set texcoord index, hr %#x.\n", hr);
7384 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 1.0f, 0);
7385 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
7387 hr = IDirect3DDevice8_BeginScene(device);
7388 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7389 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
7390 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7391 hr = IDirect3DDevice8_EndScene(device);
7392 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7394 color = getPixelColor(device, 160, 120);
7395 ok(color_match(color, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color);
7396 color = getPixelColor(device, 480, 120);
7397 ok(color_match(color, 0x0000ffff, 2), "Got unexpected color 0x%08x.\n", color);
7398 color = getPixelColor(device, 160, 360);
7399 ok(color_match(color, 0x00ff0000, 2), "Got unexpected color 0x%08x.\n", color);
7400 color = getPixelColor(device, 480, 360);
7401 ok(color_match(color, 0x00ffffff, 2), "Got unexpected color 0x%08x.\n", color);
7403 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
7404 ok(SUCCEEDED(hr), "Failed to set texture transform flags, hr %#x.\n", hr);
7405 hr = IDirect3DDevice8_SetTransform(device, D3DTS_TEXTURE1, &mat);
7406 ok(SUCCEEDED(hr), "Failed to set transformation matrix, hr %#x.\n", hr);
7408 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 1.0f, 0);
7409 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
7411 hr = IDirect3DDevice8_BeginScene(device);
7412 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7413 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
7414 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7415 hr = IDirect3DDevice8_EndScene(device);
7416 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7418 color = getPixelColor(device, 160, 120);
7419 ok(color_match(color, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color);
7420 color = getPixelColor(device, 480, 120);
7421 ok(color_match(color, 0x0000ffff, 2), "Got unexpected color 0x%08x.\n", color);
7422 color = getPixelColor(device, 160, 360);
7423 ok(color_match(color, 0x00000000, 2), "Got unexpected color 0x%08x.\n", color);
7424 color = getPixelColor(device, 480, 360);
7425 ok(color_match(color, 0x0000ffff, 2), "Got unexpected color 0x%08x.\n", color);
7427 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
7428 ok(SUCCEEDED(hr), "Failed to set texture transform flags, hr %#x.\n", hr);
7429 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_TEXCOORDINDEX, 2);
7430 ok(SUCCEEDED(hr), "Failed to set texcoord index, hr %#x.\n", hr);
7432 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 1.0f, 0);
7433 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
7435 hr = IDirect3DDevice8_BeginScene(device);
7436 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7437 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
7438 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7439 hr = IDirect3DDevice8_EndScene(device);
7440 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7442 color = getPixelColor(device, 160, 120);
7443 ok(color_match(color, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color);
7444 color = getPixelColor(device, 480, 120);
7445 ok(color_match(color, 0x0000ffff, 2), "Got unexpected color 0x%08x.\n", color);
7446 color = getPixelColor(device, 160, 360);
7447 ok(color_match(color, 0x00ff00ff, 2), "Got unexpected color 0x%08x.\n", color);
7448 color = getPixelColor(device, 480, 360);
7449 ok(color_match(color, 0x00ffff00, 2), "Got unexpected color 0x%08x.\n", color);
7451 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
7452 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
7454 IDirect3DTexture8_Release(texture1);
7455 IDirect3DTexture8_Release(texture2);
7457 refcount = IDirect3DDevice8_Release(device);
7458 ok(!refcount, "Device has %u references left.\n", refcount);
7459 IDirect3D8_Release(d3d);
7460 DestroyWindow(window);
7463 static void test_vshader_input(void)
7465 DWORD swapped_twotexcrd_shader, swapped_onetexcrd_shader = 0;
7466 DWORD swapped_twotex_wrongidx_shader = 0, swapped_twotexcrd_rightorder_shader;
7467 DWORD texcoord_color_shader, color_ubyte_shader, color_color_shader, color_float_shader;
7468 DWORD color_nocolor_shader = 0;
7469 IDirect3DDevice8 *device;
7470 IDirect3D8 *d3d;
7471 ULONG refcount;
7472 D3DCAPS8 caps;
7473 DWORD color;
7474 HWND window;
7475 HRESULT hr;
7477 static const DWORD swapped_shader_code[] =
7479 0xfffe0101, /* vs_1_1 */
7480 0x00000001, 0xc00f0000, 0x90e40000, /* mov o0, v0 */
7481 0x00000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
7482 0x00000002, 0xd00f0000, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
7483 0x0000ffff /* end */
7485 static const DWORD texcoord_color_shader_code[] =
7487 0xfffe0101, /* vs_1_1 */
7488 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
7489 0x00000001, 0xd00f0000, 0x90e40007, /* mov oD0, v7 */
7490 0x0000ffff /* end */
7492 static const DWORD color_color_shader_code[] =
7494 0xfffe0101, /* vs_1_1 */
7495 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
7496 0x00000005, 0xd00f0000, 0xa0e40000, 0x90e40005, /* mul oD0, c0, v5 */
7497 0x0000ffff /* end */
7499 static const float quad1[] =
7501 -1.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7502 -1.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7503 0.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7504 0.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7506 static const float quad4[] =
7508 0.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7509 0.0f, 1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7510 1.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7511 1.0f, 1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7513 static const struct
7515 struct vec3 position;
7516 DWORD diffuse;
7518 quad1_color[] =
7520 {{-1.0f, -1.0f, 0.1f}, 0x00ff8040},
7521 {{-1.0f, 0.0f, 0.1f}, 0x00ff8040},
7522 {{ 0.0f, -1.0f, 0.1f}, 0x00ff8040},
7523 {{ 0.0f, 0.0f, 0.1f}, 0x00ff8040},
7525 quad2_color[] =
7527 {{ 0.0f, -1.0f, 0.1f}, 0x00ff8040},
7528 {{ 0.0f, 0.0f, 0.1f}, 0x00ff8040},
7529 {{ 1.0f, -1.0f, 0.1f}, 0x00ff8040},
7530 {{ 1.0f, 0.0f, 0.1f}, 0x00ff8040},
7532 quad3_color[] =
7534 {{-1.0f, 0.0f, 0.1f}, 0x00ff8040},
7535 {{-1.0f, 1.0f, 0.1f}, 0x00ff8040},
7536 {{ 0.0f, 0.0f, 0.1f}, 0x00ff8040},
7537 {{ 0.0f, 1.0f, 0.1f}, 0x00ff8040},
7539 static const float quad4_color[] =
7541 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 0.0f, 0.0f,
7542 0.0f, 1.0f, 0.1f, 1.0f, 1.0f, 0.0f, 0.0f,
7543 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 0.0f, 1.0f,
7544 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 0.0f, 1.0f,
7546 static const DWORD decl_twotexcrd[] =
7548 D3DVSD_STREAM(0),
7549 D3DVSD_REG(0, D3DVSDT_FLOAT3), /* position */
7550 D3DVSD_REG(1, D3DVSDT_FLOAT4), /* texcoord0 */
7551 D3DVSD_REG(2, D3DVSDT_FLOAT4), /* texcoord1 */
7552 D3DVSD_END()
7554 static const DWORD decl_twotexcrd_rightorder[] =
7556 D3DVSD_STREAM(0),
7557 D3DVSD_REG(0, D3DVSDT_FLOAT3), /* position */
7558 D3DVSD_REG(2, D3DVSDT_FLOAT4), /* texcoord0 */
7559 D3DVSD_REG(1, D3DVSDT_FLOAT4), /* texcoord1 */
7560 D3DVSD_END()
7562 static const DWORD decl_onetexcrd[] =
7564 D3DVSD_STREAM(0),
7565 D3DVSD_REG(0, D3DVSDT_FLOAT3), /* position */
7566 D3DVSD_REG(1, D3DVSDT_FLOAT4), /* texcoord0 */
7567 D3DVSD_END()
7569 static const DWORD decl_twotexcrd_wrongidx[] =
7571 D3DVSD_STREAM(0),
7572 D3DVSD_REG(0, D3DVSDT_FLOAT3), /* position */
7573 D3DVSD_REG(2, D3DVSDT_FLOAT4), /* texcoord1 */
7574 D3DVSD_REG(3, D3DVSDT_FLOAT4), /* texcoord2 */
7575 D3DVSD_END()
7577 static const DWORD decl_texcoord_color[] =
7579 D3DVSD_STREAM(0),
7580 D3DVSD_REG(0, D3DVSDT_FLOAT3), /* position */
7581 D3DVSD_REG(7, D3DVSDT_D3DCOLOR), /* texcoord0 */
7582 D3DVSD_END()
7584 static const DWORD decl_color_color[] =
7586 D3DVSD_STREAM(0),
7587 D3DVSD_REG(0, D3DVSDT_FLOAT3), /* position */
7588 D3DVSD_REG(5, D3DVSDT_D3DCOLOR), /* diffuse */
7589 D3DVSD_END()
7591 static const DWORD decl_color_ubyte[] =
7593 D3DVSD_STREAM(0),
7594 D3DVSD_REG(0, D3DVSDT_FLOAT3),
7595 D3DVSD_REG(5, D3DVSDT_UBYTE4),
7596 D3DVSD_END()
7598 static const DWORD decl_color_float[] =
7600 D3DVSD_STREAM(0),
7601 D3DVSD_REG(0, D3DVSDT_FLOAT3),
7602 D3DVSD_REG(5, D3DVSDT_FLOAT4),
7603 D3DVSD_END()
7605 static const DWORD decl_nocolor[] =
7607 D3DVSD_STREAM(0),
7608 D3DVSD_REG(0, D3DVSDT_FLOAT3),
7609 D3DVSD_END()
7611 static const float normalize[4] = {1.0f / 256.0f, 1.0f / 256.0f, 1.0f / 256.0f, 1.0f / 256.0f};
7612 static const float no_normalize[4] = {1.0f, 1.0f, 1.0f, 1.0f};
7614 window = create_window();
7615 d3d = Direct3DCreate8(D3D_SDK_VERSION);
7616 ok(!!d3d, "Failed to create a D3D object.\n");
7617 if (!(device = create_device(d3d, window, window, TRUE)))
7619 skip("Failed to create a D3D device, skipping tests.\n");
7620 goto done;
7623 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
7624 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
7625 if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1))
7627 skip("No vs_1_1 support, skipping tests.\n");
7628 IDirect3DDevice8_Release(device);
7629 goto done;
7632 hr = IDirect3DDevice8_CreateVertexShader(device, decl_twotexcrd, swapped_shader_code, &swapped_twotexcrd_shader, 0);
7633 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
7634 hr = IDirect3DDevice8_CreateVertexShader(device, decl_onetexcrd, swapped_shader_code, &swapped_onetexcrd_shader, 0);
7635 todo_wine ok(hr == D3DERR_INVALIDCALL, "Unexpected error while creating vertex shader, hr %#x.\n", hr);
7636 hr = IDirect3DDevice8_CreateVertexShader(device, decl_twotexcrd_wrongidx, swapped_shader_code, &swapped_twotex_wrongidx_shader, 0);
7637 todo_wine ok(hr == D3DERR_INVALIDCALL, "Unexpected error while creating vertex shader, hr %#x.\n", hr);
7638 hr = IDirect3DDevice8_CreateVertexShader(device, decl_twotexcrd_rightorder, swapped_shader_code, &swapped_twotexcrd_rightorder_shader, 0);
7639 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
7641 hr = IDirect3DDevice8_CreateVertexShader(device, decl_texcoord_color, texcoord_color_shader_code, &texcoord_color_shader, 0);
7642 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
7643 hr = IDirect3DDevice8_CreateVertexShader(device, decl_color_ubyte, color_color_shader_code, &color_ubyte_shader, 0);
7644 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
7645 hr = IDirect3DDevice8_CreateVertexShader(device, decl_color_color, color_color_shader_code, &color_color_shader, 0);
7646 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
7647 hr = IDirect3DDevice8_CreateVertexShader(device, decl_color_float, color_color_shader_code, &color_float_shader, 0);
7648 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
7649 hr = IDirect3DDevice8_CreateVertexShader(device, decl_nocolor, color_color_shader_code, &color_nocolor_shader, 0);
7650 todo_wine ok(hr == D3DERR_INVALIDCALL, "Unexpected error while creating vertex shader, hr %#x.\n", hr);
7652 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 1.0f, 0);
7653 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
7655 hr = IDirect3DDevice8_BeginScene(device);
7656 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7658 hr = IDirect3DDevice8_SetVertexShader(device, swapped_twotexcrd_shader);
7659 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
7661 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 11);
7662 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7664 hr = IDirect3DDevice8_SetVertexShader(device, swapped_twotexcrd_rightorder_shader);
7665 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
7666 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 11);
7667 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7669 hr = IDirect3DDevice8_EndScene(device);
7670 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7672 color = getPixelColor(device, 160, 360);
7673 ok(color_match(color, 0x00ffff80, 1), "Got unexpected color 0x%08x for quad 1 (2crd).\n", color);
7674 color = getPixelColor(device, 480, 160);
7675 ok(color == 0x00000000, "Got unexpected color 0x%08x for quad 4 (2crd-rightorder).\n", color);
7677 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
7678 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
7680 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
7681 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
7683 hr = IDirect3DDevice8_BeginScene(device);
7684 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7686 hr = IDirect3DDevice8_SetVertexShader(device, texcoord_color_shader);
7687 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
7688 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1_color, sizeof(quad1_color[0]));
7689 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7691 hr = IDirect3DDevice8_SetVertexShader(device, color_ubyte_shader);
7692 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
7694 hr = IDirect3DDevice8_SetVertexShaderConstant(device, 0, normalize, 1);
7695 ok(SUCCEEDED(hr), "Failed to set vertex shader constant, hr %#x.\n", hr);
7696 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_color, sizeof(quad2_color[0]));
7697 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7699 hr = IDirect3DDevice8_SetVertexShaderConstant(device, 0, no_normalize, 1);
7700 ok(SUCCEEDED(hr), "Failed to set vertex shader constant, hr %#x.\n", hr);
7701 hr = IDirect3DDevice8_SetVertexShader(device, color_color_shader);
7702 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
7703 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3_color, sizeof(quad3_color[0]));
7704 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7706 hr = IDirect3DDevice8_SetVertexShader(device, color_float_shader);
7707 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
7708 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4_color, sizeof(float) * 7);
7709 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7711 hr = IDirect3DDevice8_EndScene(device);
7712 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7714 IDirect3DDevice8_SetVertexShader(device, 0);
7716 color = getPixelColor(device, 160, 360);
7717 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
7718 "Input test: Quad 1(color-texcoord) returned color 0x%08x, expected 0x00ff8040\n", color);
7719 color = getPixelColor(device, 480, 360);
7720 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x40, 0x80, 0xff), 1),
7721 "Input test: Quad 2(color-ubyte) returned color 0x%08x, expected 0x004080ff\n", color);
7722 color = getPixelColor(device, 160, 120);
7723 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
7724 "Input test: Quad 3(color-color) returned color 0x%08x, expected 0x00ff8040\n", color);
7725 color = getPixelColor(device, 480, 160);
7726 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 1),
7727 "Input test: Quad 4(color-float) returned color 0x%08x, expected 0x00ffff00\n", color);
7729 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
7730 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
7732 IDirect3DDevice8_DeleteVertexShader(device, swapped_twotexcrd_shader);
7733 IDirect3DDevice8_DeleteVertexShader(device, swapped_onetexcrd_shader);
7734 IDirect3DDevice8_DeleteVertexShader(device, swapped_twotex_wrongidx_shader);
7735 IDirect3DDevice8_DeleteVertexShader(device, swapped_twotexcrd_rightorder_shader);
7736 IDirect3DDevice8_DeleteVertexShader(device, texcoord_color_shader);
7737 IDirect3DDevice8_DeleteVertexShader(device, color_ubyte_shader);
7738 IDirect3DDevice8_DeleteVertexShader(device, color_color_shader);
7739 IDirect3DDevice8_DeleteVertexShader(device, color_float_shader);
7740 IDirect3DDevice8_DeleteVertexShader(device, color_nocolor_shader);
7742 refcount = IDirect3DDevice8_Release(device);
7743 ok(!refcount, "Device has %u references left.\n", refcount);
7744 done:
7745 IDirect3D8_Release(d3d);
7746 DestroyWindow(window);
7749 static void test_fixed_function_fvf(void)
7751 IDirect3DDevice8 *device;
7752 DWORD color;
7753 IDirect3D8 *d3d;
7754 ULONG refcount;
7755 D3DCAPS8 caps;
7756 HWND window;
7757 HRESULT hr;
7759 static const struct
7761 struct vec3 position;
7762 DWORD diffuse;
7764 quad1[] =
7766 {{-1.0f, -1.0f, 0.1f}, 0x00ffff00},
7767 {{-1.0f, 0.0f, 0.1f}, 0x00ffff00},
7768 {{ 0.0f, -1.0f, 0.1f}, 0x00ffff00},
7769 {{ 0.0f, 0.0f, 0.1f}, 0x00ffff00},
7771 static const struct vec3 quad2[] =
7773 {-1.0f, -1.0f, 0.1f},
7774 {-1.0f, 0.0f, 0.1f},
7775 { 0.0f, -1.0f, 0.1f},
7776 { 0.0f, 0.0f, 0.1f},
7778 static const struct
7780 struct vec4 position;
7781 DWORD diffuse;
7783 quad_transformed[] =
7785 {{ 90.0f, 110.0f, 0.1f, 2.0f}, 0x00ffff00},
7786 {{570.0f, 110.0f, 0.1f, 2.0f}, 0x00ffff00},
7787 {{ 90.0f, 300.0f, 0.1f, 2.0f}, 0x00ffff00},
7788 {{570.0f, 300.0f, 0.1f, 2.0f}, 0x00ffff00},
7791 window = create_window();
7792 d3d = Direct3DCreate8(D3D_SDK_VERSION);
7793 ok(!!d3d, "Failed to create a D3D object.\n");
7794 if (!(device = create_device(d3d, window, window, TRUE)))
7796 skip("Failed to create a D3D device, skipping tests.\n");
7797 goto done;
7800 memset(&caps, 0, sizeof(caps));
7801 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
7802 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
7804 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
7805 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
7807 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
7808 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
7810 hr = IDirect3DDevice8_BeginScene(device);
7811 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7813 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
7814 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
7815 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
7816 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7818 hr = IDirect3DDevice8_EndScene(device);
7819 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7821 color = getPixelColor(device, 160, 360);
7822 ok(color == 0x00ffff00,
7823 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7824 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
7826 /* Test with no diffuse color attribute. */
7827 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7828 ok(SUCCEEDED(hr), "IDirect3DDevice8_Clear failed with %08x\n", hr);
7830 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ);
7831 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
7832 hr = IDirect3DDevice8_BeginScene(device);
7833 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7834 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad2, sizeof(quad2[0]));
7835 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7836 hr = IDirect3DDevice8_EndScene(device);
7837 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7839 color = getPixelColor(device, 160, 360);
7840 ok(color == 0x00ffffff, "Got unexpected color 0x%08x in the no diffuse attribute test.\n", color);
7841 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
7843 /* Test what happens with specular lighting enabled and no specular color attribute. */
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);
7846 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SPECULARENABLE, TRUE);
7847 ok(SUCCEEDED(hr), "Failed to enable specular lighting, hr %#x.\n", hr);
7848 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
7849 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
7850 hr = IDirect3DDevice8_BeginScene(device);
7851 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7853 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad1, sizeof(quad1[0]));
7854 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7856 hr = IDirect3DDevice8_EndScene(device);
7857 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7858 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SPECULARENABLE, FALSE);
7859 ok(SUCCEEDED(hr), "Failed to disable specular lighting, hr %#x.\n", hr);
7861 color = getPixelColor(device, 160, 360);
7862 ok(color == 0x00ffff00, "Got unexpected color 0x%08x in the no specular attribute test.\n", color);
7864 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
7866 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
7867 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
7869 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7870 ok(SUCCEEDED(hr), "Failed to clear, 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, &quad_transformed, sizeof(quad_transformed[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, 88, 108);
7880 ok(color == 0x000000ff,
7881 "pixel 88/108 has color %08x, expected 0x000000ff\n", color);
7882 color = getPixelColor(device, 92, 108);
7883 ok(color == 0x000000ff,
7884 "pixel 92/108 has color %08x, expected 0x000000ff\n", color);
7885 color = getPixelColor(device, 88, 112);
7886 ok(color == 0x000000ff,
7887 "pixel 88/112 has color %08x, expected 0x000000ff\n", color);
7888 color = getPixelColor(device, 92, 112);
7889 ok(color == 0x00ffff00,
7890 "pixel 92/112 has color %08x, expected 0x00ffff00\n", color);
7892 color = getPixelColor(device, 568, 108);
7893 ok(color == 0x000000ff,
7894 "pixel 568/108 has color %08x, expected 0x000000ff\n", color);
7895 color = getPixelColor(device, 572, 108);
7896 ok(color == 0x000000ff,
7897 "pixel 572/108 has color %08x, expected 0x000000ff\n", color);
7898 color = getPixelColor(device, 568, 112);
7899 ok(color == 0x00ffff00,
7900 "pixel 568/112 has color %08x, expected 0x00ffff00\n", color);
7901 color = getPixelColor(device, 572, 112);
7902 ok(color == 0x000000ff,
7903 "pixel 572/112 has color %08x, expected 0x000000ff\n", color);
7905 color = getPixelColor(device, 88, 298);
7906 ok(color == 0x000000ff,
7907 "pixel 88/298 has color %08x, expected 0x000000ff\n", color);
7908 color = getPixelColor(device, 92, 298);
7909 ok(color == 0x00ffff00,
7910 "pixel 92/298 has color %08x, expected 0x00ffff00\n", color);
7911 color = getPixelColor(device, 88, 302);
7912 ok(color == 0x000000ff,
7913 "pixel 88/302 has color %08x, expected 0x000000ff\n", color);
7914 color = getPixelColor(device, 92, 302);
7915 ok(color == 0x000000ff,
7916 "pixel 92/302 has color %08x, expected 0x000000ff\n", color);
7918 color = getPixelColor(device, 568, 298);
7919 ok(color == 0x00ffff00,
7920 "pixel 568/298 has color %08x, expected 0x00ffff00\n", color);
7921 color = getPixelColor(device, 572, 298);
7922 ok(color == 0x000000ff,
7923 "pixel 572/298 has color %08x, expected 0x000000ff\n", color);
7924 color = getPixelColor(device, 568, 302);
7925 ok(color == 0x000000ff,
7926 "pixel 568/302 has color %08x, expected 0x000000ff\n", color);
7927 color = getPixelColor(device, 572, 302);
7928 ok(color == 0x000000ff,
7929 "pixel 572/302 has color %08x, expected 0x000000ff\n", color);
7931 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
7933 refcount = IDirect3DDevice8_Release(device);
7934 ok(!refcount, "Device has %u references left.\n", refcount);
7935 done:
7936 IDirect3D8_Release(d3d);
7937 DestroyWindow(window);
7940 static void test_flip(void)
7942 IDirect3DDevice8 *device;
7943 IDirect3D8 *d3d;
7944 ULONG refcount;
7945 HWND window;
7946 HRESULT hr;
7947 IDirect3DSurface8 *back_buffers[3], *test_surface;
7948 unsigned int i;
7949 D3DCOLOR color;
7950 D3DPRESENT_PARAMETERS present_parameters = {0};
7952 window = create_window();
7953 d3d = Direct3DCreate8(D3D_SDK_VERSION);
7954 ok(!!d3d, "Failed to create a D3D object.\n");
7956 present_parameters.BackBufferWidth = 640;
7957 present_parameters.BackBufferHeight = 480;
7958 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
7959 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
7960 present_parameters.hDeviceWindow = window;
7961 present_parameters.Windowed = TRUE;
7962 present_parameters.BackBufferCount = 3;
7963 present_parameters.Flags = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER;
7964 hr = IDirect3D8_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
7965 window, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device);
7966 if (!device)
7968 skip("Failed to create a D3D device, skipping tests.\n");
7969 IDirect3D8_Release(d3d);
7970 DestroyWindow(window);
7971 return;
7974 for (i = 0; i < sizeof(back_buffers) / sizeof(*back_buffers); ++i)
7976 hr = IDirect3DDevice8_GetBackBuffer(device, i, D3DBACKBUFFER_TYPE_MONO, &back_buffers[i]);
7977 ok(SUCCEEDED(hr), "Failed to get back buffer, hr %#x.\n", hr);
7979 hr = IDirect3DDevice8_GetRenderTarget(device, &test_surface);
7980 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
7981 ok(test_surface == back_buffers[0], "Expected render target %p, got %p.\n", back_buffers[0], test_surface);
7982 IDirect3DSurface8_Release(test_surface);
7985 hr = IDirect3DDevice8_SetRenderTarget(device, back_buffers[0], NULL);
7986 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
7987 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0f, 0);
7988 ok(SUCCEEDED(hr), "Failed to clear, hr %#x\n", hr);
7990 hr = IDirect3DDevice8_SetRenderTarget(device, back_buffers[1], NULL);
7991 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
7992 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0f, 0);
7993 ok(SUCCEEDED(hr), "Failed to clear, hr %#x\n", hr);
7995 hr = IDirect3DDevice8_SetRenderTarget(device, back_buffers[2], NULL);
7996 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
7997 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0f, 0);
7998 ok(SUCCEEDED(hr), "Failed to clear, hr %#x\n", hr);
8000 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
8001 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
8003 /* Render target is unmodified. */
8004 hr = IDirect3DDevice8_GetRenderTarget(device, &test_surface);
8005 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
8006 ok(test_surface == back_buffers[2], "Expected render target %p, got %p.\n", back_buffers[2], test_surface);
8007 IDirect3DSurface8_Release(test_surface);
8009 /* Backbuffer surface pointers are unmodified */
8010 for (i = 0; i < sizeof(back_buffers) / sizeof(*back_buffers); ++i)
8012 hr = IDirect3DDevice8_GetBackBuffer(device, i, D3DBACKBUFFER_TYPE_MONO, &test_surface);
8013 ok(SUCCEEDED(hr), "Failed to get back buffer, hr %#x.\n", hr);
8014 ok(test_surface == back_buffers[i], "Expected back buffer %u = %p, got %p.\n",
8015 i, back_buffers[i], test_surface);
8016 IDirect3DSurface8_Release(test_surface);
8019 /* Contents were changed. */
8020 color = get_surface_color(back_buffers[0], 1, 1);
8021 ok(color == 0xff00ff00, "Got unexpected color 0x%08x.\n", color);
8022 color = get_surface_color(back_buffers[1], 1, 1);
8023 ok(color == 0xff0000ff, "Got unexpected color 0x%08x.\n", color);
8025 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff808080, 0.0f, 0);
8026 ok(SUCCEEDED(hr), "Failed to clear, hr %#x\n", hr);
8028 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
8029 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
8031 color = get_surface_color(back_buffers[0], 1, 1);
8032 ok(color == 0xff0000ff, "Got unexpected color 0x%08x.\n", color);
8033 color = get_surface_color(back_buffers[1], 1, 1);
8034 ok(color == 0xff808080, "Got unexpected color 0x%08x.\n", color);
8036 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
8037 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
8039 color = get_surface_color(back_buffers[0], 1, 1);
8040 ok(color == 0xff808080, "Got unexpected color 0x%08x.\n", color);
8042 for (i = 0; i < sizeof(back_buffers) / sizeof(*back_buffers); ++i)
8043 IDirect3DSurface8_Release(back_buffers[i]);
8045 refcount = IDirect3DDevice8_Release(device);
8046 ok(!refcount, "Device has %u references left.\n", refcount);
8048 if (FAILED(IDirect3D8_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
8049 D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES)))
8051 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping multisample flip test.\n");
8052 goto done;
8055 present_parameters.BackBufferCount = 2;
8056 present_parameters.MultiSampleType = D3DMULTISAMPLE_2_SAMPLES;
8057 present_parameters.Flags = 0;
8058 hr = IDirect3D8_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
8059 window, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device);
8061 for (i = 0; i < present_parameters.BackBufferCount; ++i)
8063 hr = IDirect3DDevice8_GetBackBuffer(device, i, D3DBACKBUFFER_TYPE_MONO, &back_buffers[i]);
8064 ok(SUCCEEDED(hr), "Failed to get back buffer, hr %#x.\n", hr);
8067 hr = IDirect3DDevice8_SetRenderTarget(device, back_buffers[1], NULL);
8068 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
8069 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff808080, 0.0f, 0);
8070 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
8072 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
8073 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
8075 hr = IDirect3DDevice8_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
8076 D3DMULTISAMPLE_NONE, TRUE, &test_surface);
8077 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
8078 hr = IDirect3DDevice8_CopyRects(device, back_buffers[0], NULL, 0, test_surface, NULL);
8079 ok(SUCCEEDED(hr), "CopyRects failed, hr %#x.\n", hr);
8081 color = get_surface_color(test_surface, 1, 1);
8082 ok(color == 0xff808080, "Got unexpected color 0x%08x.\n", color);
8084 IDirect3DSurface8_Release(test_surface);
8085 for (i = 0; i < present_parameters.BackBufferCount; ++i)
8086 IDirect3DSurface8_Release(back_buffers[i]);
8088 refcount = IDirect3DDevice8_Release(device);
8089 ok(!refcount, "Device has %u references left.\n", refcount);
8091 done:
8092 IDirect3D8_Release(d3d);
8093 DestroyWindow(window);
8096 static void test_uninitialized_varyings(void)
8098 static const D3DMATRIX mat =
8100 1.0f, 0.0f, 0.0f, 0.0f,
8101 0.0f, 1.0f, 0.0f, 0.0f,
8102 0.0f, 0.0f, 1.0f, 0.0f,
8103 0.0f, 0.0f, 0.0f, 1.0f,
8104 }}};
8105 static const struct vec3 quad[] =
8107 {-1.0f, -1.0f, 0.1f},
8108 {-1.0f, 1.0f, 0.1f},
8109 { 1.0f, -1.0f, 0.1f},
8110 { 1.0f, 1.0f, 0.1f},
8112 static const DWORD decl[] =
8114 D3DVSD_STREAM(0),
8115 D3DVSD_REG(0, D3DVSDT_FLOAT3),
8116 D3DVSD_CONST(0, 1), 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, /* def c0, 0.5, 0.5, 0.5, 0.5 */
8117 D3DVSD_END()
8119 static const DWORD vs1_code[] =
8121 0xfffe0101, /* vs_1_1 */
8122 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
8123 0x0000ffff
8125 static const DWORD vs1_partial_code[] =
8127 0xfffe0101, /* vs_1_1 */
8128 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
8129 0x00000001, 0xd0010000, 0xa0e40000, /* mov oD0.x, c0 */
8130 0x00000001, 0xd0010001, 0xa0e40000, /* mov oD1.x, c0 */
8131 0x00000001, 0xe0010000, 0xa0e40000, /* mov oT0.x, c0 */
8132 0x0000ffff
8134 static const DWORD ps1_diffuse_code[] =
8136 0xffff0101, /* ps_1_1 */
8137 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
8138 0x0000ffff
8140 static const DWORD ps1_specular_code[] =
8142 0xffff0101, /* ps_1_1 */
8143 0x00000001, 0x800f0000, 0x90e40001, /* mov r0, v1 */
8144 0x0000ffff
8146 static const DWORD ps1_texcoord_code[] =
8148 0xffff0101, /* ps_1_1 */
8149 0x00000040, 0xb00f0000, /* texcoord t0 */
8150 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
8151 0x0000ffff
8153 static const struct
8155 DWORD vs_version;
8156 const DWORD *vs;
8157 DWORD ps_version;
8158 const DWORD *ps;
8159 D3DCOLOR expected;
8160 BOOL allow_zero_alpha;
8161 BOOL broken_warp;
8163 /* On AMD specular color is generally initialized to 0x00000000 and texcoords to 0xff000000
8164 * while on Nvidia it's the opposite. Just allow both. */
8165 tests[] =
8167 {D3DVS_VERSION(1, 1), vs1_code, 0, NULL, 0xffffffff},
8168 { 0, NULL, D3DPS_VERSION(1, 1), ps1_texcoord_code, 0xff000000, TRUE},
8169 {D3DVS_VERSION(1, 1), vs1_code, D3DPS_VERSION(1, 1), ps1_diffuse_code, 0xffffffff},
8170 {D3DVS_VERSION(1, 1), vs1_code, D3DPS_VERSION(1, 1), ps1_specular_code, 0xff000000, TRUE, TRUE},
8171 {D3DVS_VERSION(1, 1), vs1_code, D3DPS_VERSION(1, 1), ps1_texcoord_code, 0xff000000, TRUE},
8172 {D3DVS_VERSION(1, 1), vs1_partial_code, 0, NULL, 0xff7fffff, FALSE, TRUE},
8173 {D3DVS_VERSION(1, 1), vs1_partial_code, D3DPS_VERSION(1, 1), ps1_diffuse_code, 0xff7fffff, FALSE, TRUE},
8174 {D3DVS_VERSION(1, 1), vs1_partial_code, D3DPS_VERSION(1, 1), ps1_specular_code, 0xff7f0000, TRUE},
8175 {D3DVS_VERSION(1, 1), vs1_partial_code, D3DPS_VERSION(1, 1), ps1_texcoord_code, 0xff7f0000, TRUE},
8177 IDirect3DDevice8 *device;
8178 IDirect3D8 *d3d;
8179 HWND window;
8180 HRESULT hr;
8181 DWORD vs, ps;
8182 unsigned int i;
8183 ULONG refcount;
8184 D3DCAPS8 caps;
8185 IDirect3DSurface8 *backbuffer;
8186 D3DADAPTER_IDENTIFIER8 identifier;
8187 struct surface_readback rb;
8188 D3DCOLOR color;
8189 BOOL warp;
8191 window = create_window();
8192 d3d = Direct3DCreate8(D3D_SDK_VERSION);
8193 ok(!!d3d, "Failed to create a D3D object.\n");
8194 if (!(device = create_device(d3d, window, window, TRUE)))
8196 skip("Failed to create a D3D device, skipping tests.\n");
8197 IDirect3D8_Release(d3d);
8198 DestroyWindow(window);
8199 return;
8202 hr = IDirect3D8_GetAdapterIdentifier(d3d, D3DADAPTER_DEFAULT, 0, &identifier);
8203 ok(SUCCEEDED(hr), "Failed to get adapter identifier, hr %#x.\n", hr);
8204 warp = adapter_is_warp(&identifier);
8206 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
8207 ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
8209 hr = IDirect3DDevice8_GetBackBuffer(device, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8210 ok(SUCCEEDED(hr), "Failed to get back buffer, hr %#x.\n", hr);
8212 hr = IDirect3DDevice8_SetTransform(device, D3DTS_WORLD, &mat);
8213 ok(SUCCEEDED(hr), "Failed to set world transform, hr %#x.\n", hr);
8214 hr = IDirect3DDevice8_SetTransform(device, D3DTS_VIEW, &mat);
8215 ok(SUCCEEDED(hr), "Failed to set view transform, hr %#x.\n", hr);
8216 hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, &mat);
8217 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
8218 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, FALSE);
8219 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#x.\n", hr);
8220 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, FALSE);
8221 ok(SUCCEEDED(hr), "Failed to disable Z test, hr %#x.\n", hr);
8222 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
8223 ok(SUCCEEDED(hr), "Failed to disable fog, hr %#x.\n", hr);
8224 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
8225 ok(SUCCEEDED(hr), "Failed to disable stencil test, hr %#x.\n", hr);
8226 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8227 ok(SUCCEEDED(hr), "Failed to disable culling, hr %#x.\n", hr);
8229 for (i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i)
8231 if (caps.VertexShaderVersion < tests[i].vs_version
8232 || caps.PixelShaderVersion < tests[i].ps_version)
8234 skip("Vertex / pixel shader version not supported, skipping test %u.\n", i);
8235 continue;
8237 if (tests[i].vs)
8239 hr = IDirect3DDevice8_CreateVertexShader(device, decl, tests[i].vs, &vs, 0);
8240 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x (case %u).\n", hr, i);
8241 hr = IDirect3DDevice8_SetVertexShader(device, vs);
8242 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
8244 else
8246 vs = 0;
8247 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ);
8248 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
8250 if (tests[i].ps)
8252 hr = IDirect3DDevice8_CreatePixelShader(device, tests[i].ps, &ps);
8253 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x (case %u).\n", hr, i);
8255 else
8257 ps = 0;
8260 hr = IDirect3DDevice8_SetPixelShader(device, ps);
8261 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
8263 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0f, 0);
8264 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
8266 hr = IDirect3DDevice8_BeginScene(device);
8267 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
8269 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
8270 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8272 hr = IDirect3DDevice8_EndScene(device);
8273 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
8275 get_rt_readback(backbuffer, &rb);
8276 color = get_readback_color(&rb, 320, 240);
8277 ok(color_match(color, tests[i].expected, 1)
8278 || (tests[i].allow_zero_alpha && color_match(color, tests[i].expected & 0x00ffffff, 1))
8279 || (broken(warp && tests[i].broken_warp)),
8280 "Got unexpected color 0x%08x, case %u.\n", color, i);
8281 release_surface_readback(&rb);
8283 if (vs)
8284 IDirect3DDevice8_DeleteVertexShader(device, vs);
8285 if (ps)
8286 IDirect3DDevice8_DeletePixelShader(device, ps);
8289 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
8290 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
8292 IDirect3DSurface8_Release(backbuffer);
8293 refcount = IDirect3DDevice8_Release(device);
8294 ok(!refcount, "Device has %u references left.\n", refcount);
8295 IDirect3D8_Release(d3d);
8296 DestroyWindow(window);
8299 static void test_shademode(void)
8301 IDirect3DVertexBuffer8 *vb_strip;
8302 IDirect3DVertexBuffer8 *vb_list;
8303 IDirect3DDevice8 *device;
8304 DWORD color0, color1;
8305 BYTE *data = NULL;
8306 IDirect3D8 *d3d;
8307 ULONG refcount;
8308 D3DCAPS8 caps;
8309 DWORD vs, ps;
8310 HWND window;
8311 HRESULT hr;
8312 UINT i;
8313 static const DWORD decl[] =
8315 D3DVSD_STREAM(0),
8316 D3DVSD_REG(D3DVSDE_POSITION, D3DVSDT_FLOAT3),
8317 D3DVSD_REG(D3DVSDE_DIFFUSE, D3DVSDT_D3DCOLOR),
8318 D3DVSD_END()
8320 static const DWORD vs1_code[] =
8322 0xfffe0101, /* vs_1_1 */
8323 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
8324 0x00000001, 0xd00f0000, 0x90e40005, /* mov oD0, v5 */
8325 0x0000ffff
8327 static const DWORD ps1_code[] =
8329 0xffff0101, /* ps_1_1 */
8330 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
8331 0x0000ffff
8333 static const struct
8335 struct vec3 position;
8336 DWORD diffuse;
8338 quad_strip[] =
8340 {{-1.0f, -1.0f, 0.0f}, 0xffff0000},
8341 {{-1.0f, 1.0f, 0.0f}, 0xff00ff00},
8342 {{ 1.0f, -1.0f, 0.0f}, 0xff0000ff},
8343 {{ 1.0f, 1.0f, 0.0f}, 0xffffffff},
8345 quad_list[] =
8347 {{-1.0f, -1.0f, 0.0f}, 0xffff0000},
8348 {{-1.0f, 1.0f, 0.0f}, 0xff00ff00},
8349 {{ 1.0f, -1.0f, 0.0f}, 0xff0000ff},
8351 {{ 1.0f, -1.0f, 0.0f}, 0xff0000ff},
8352 {{-1.0f, 1.0f, 0.0f}, 0xff00ff00},
8353 {{ 1.0f, 1.0f, 0.0f}, 0xffffffff},
8355 static const struct test_shader
8357 DWORD version;
8358 const DWORD *code;
8360 novs = {0, NULL},
8361 vs_1 = {D3DVS_VERSION(1, 1), vs1_code},
8362 nops = {0, NULL},
8363 ps_1 = {D3DPS_VERSION(1, 1), ps1_code};
8364 static const struct
8366 const struct test_shader *vs, *ps;
8367 DWORD primtype;
8368 DWORD shademode;
8369 DWORD color0, color1;
8371 tests[] =
8373 {&novs, &nops, D3DPT_TRIANGLESTRIP, D3DSHADE_FLAT, 0x00ff0000, 0x0000ff00},
8374 {&novs, &nops, D3DPT_TRIANGLESTRIP, D3DSHADE_PHONG, 0x000dca28, 0x000d45c7},
8375 {&novs, &nops, D3DPT_TRIANGLESTRIP, D3DSHADE_GOURAUD, 0x000dca28, 0x000d45c7},
8376 {&novs, &nops, D3DPT_TRIANGLESTRIP, D3DSHADE_PHONG, 0x000dca28, 0x000d45c7},
8377 {&novs, &nops, D3DPT_TRIANGLELIST, D3DSHADE_FLAT, 0x00ff0000, 0x000000ff},
8378 {&novs, &nops, D3DPT_TRIANGLELIST, D3DSHADE_GOURAUD, 0x000dca28, 0x000d45c7},
8379 {&vs_1, &ps_1, D3DPT_TRIANGLESTRIP, D3DSHADE_FLAT, 0x00ff0000, 0x0000ff00},
8380 {&vs_1, &ps_1, D3DPT_TRIANGLESTRIP, D3DSHADE_GOURAUD, 0x000dca28, 0x000d45c7},
8381 {&vs_1, &ps_1, D3DPT_TRIANGLELIST, D3DSHADE_FLAT, 0x00ff0000, 0x000000ff},
8382 {&vs_1, &ps_1, D3DPT_TRIANGLELIST, D3DSHADE_GOURAUD, 0x000dca28, 0x000d45c7},
8383 {&novs, &ps_1, D3DPT_TRIANGLESTRIP, D3DSHADE_FLAT, 0x00ff0000, 0x0000ff00},
8384 {&vs_1, &nops, D3DPT_TRIANGLESTRIP, D3DSHADE_FLAT, 0x00ff0000, 0x0000ff00},
8387 window = create_window();
8388 d3d = Direct3DCreate8(D3D_SDK_VERSION);
8389 ok(!!d3d, "Failed to create a D3D object.\n");
8390 if (!(device = create_device(d3d, window, window, TRUE)))
8392 skip("Failed to create a D3D device, skipping tests.\n");
8393 IDirect3D8_Release(d3d);
8394 DestroyWindow(window);
8395 return;
8398 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
8399 ok(hr == D3D_OK, "Failed to disable lighting, hr %#x.\n", hr);
8400 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
8401 ok(SUCCEEDED(hr), "Failed to disable fog, hr %#x.\n", hr);
8403 hr = IDirect3DDevice8_CreateVertexBuffer(device, sizeof(quad_strip), 0, 0, D3DPOOL_MANAGED, &vb_strip);
8404 ok(hr == D3D_OK, "Failed to create vertex buffer, hr %#x.\n", hr);
8405 hr = IDirect3DVertexBuffer8_Lock(vb_strip, 0, sizeof(quad_strip), &data, 0);
8406 ok(hr == D3D_OK, "Failed to lock vertex buffer, hr %#x.\n", hr);
8407 memcpy(data, quad_strip, sizeof(quad_strip));
8408 hr = IDirect3DVertexBuffer8_Unlock(vb_strip);
8409 ok(hr == D3D_OK, "Failed to unlock vertex buffer, hr %#x.\n", hr);
8411 hr = IDirect3DDevice8_CreateVertexBuffer(device, sizeof(quad_list), 0, 0, D3DPOOL_MANAGED, &vb_list);
8412 ok(hr == D3D_OK, "Failed to create vertex buffer, hr %#x.\n", hr);
8413 hr = IDirect3DVertexBuffer8_Lock(vb_list, 0, sizeof(quad_list), &data, 0);
8414 ok(hr == D3D_OK, "Failed to lock vertex buffer, hr %#x.\n", hr);
8415 memcpy(data, quad_list, sizeof(quad_list));
8416 hr = IDirect3DVertexBuffer8_Unlock(vb_list);
8417 ok(hr == D3D_OK, "Failed to unlock vertex buffer, hr %#x.\n", hr);
8419 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
8420 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
8422 /* Try it first with a TRIANGLESTRIP. Do it with different geometry because
8423 * the color fixups we have to do for FLAT shading will be dependent on that. */
8425 for (i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i)
8427 if (tests[i].vs->version)
8429 if (caps.VertexShaderVersion >= tests[i].vs->version)
8431 hr = IDirect3DDevice8_CreateVertexShader(device, decl, tests[i].vs->code, &vs, 0);
8432 ok(hr == D3D_OK, "Failed to create vertex shader, hr %#x.\n", hr);
8433 hr = IDirect3DDevice8_SetVertexShader(device, vs);
8434 ok(hr == D3D_OK, "Failed to set vertex shader, hr %#x.\n", hr);
8436 else
8438 skip("Shader version unsupported, skipping some tests.\n");
8439 continue;
8442 else
8444 vs = 0;
8445 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8446 ok(hr == D3D_OK, "Failed to set FVF, hr %#x.\n", hr);
8448 if (tests[i].ps->version)
8450 if (caps.PixelShaderVersion >= tests[i].ps->version)
8452 hr = IDirect3DDevice8_CreatePixelShader(device, tests[i].ps->code, &ps);
8453 ok(hr == D3D_OK, "Failed to create pixel shader, hr %#x.\n", hr);
8454 hr = IDirect3DDevice8_SetPixelShader(device, ps);
8455 ok(hr == D3D_OK, "Failed to set pixel shader, hr %#x.\n", hr);
8457 else
8459 skip("Shader version unsupported, skipping some tests.\n");
8460 if (vs)
8462 IDirect3DDevice8_SetVertexShader(device, 0);
8463 IDirect3DDevice8_DeleteVertexShader(device, vs);
8465 continue;
8468 else
8470 ps = 0;
8473 hr = IDirect3DDevice8_SetStreamSource(device, 0,
8474 tests[i].primtype == D3DPT_TRIANGLESTRIP ? vb_strip : vb_list, sizeof(quad_strip[0]));
8475 ok(hr == D3D_OK, "Failed to set stream source, hr %#x.\n", hr);
8477 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
8478 ok(hr == D3D_OK, "Failed to clear, hr %#x.\n", hr);
8480 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SHADEMODE, tests[i].shademode);
8481 ok(hr == D3D_OK, "Failed to set shade mode, hr %#x.\n", hr);
8483 hr = IDirect3DDevice8_BeginScene(device);
8484 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
8485 hr = IDirect3DDevice8_DrawPrimitive(device, tests[i].primtype, 0, 2);
8486 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8487 hr = IDirect3DDevice8_EndScene(device);
8488 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
8490 color0 = getPixelColor(device, 100, 100); /* Inside first triangle */
8491 color1 = getPixelColor(device, 500, 350); /* Inside second triangle */
8493 /* For D3DSHADE_FLAT it should take the color of the first vertex of
8494 * each triangle. This requires EXT_provoking_vertex or similar
8495 * functionality being available. */
8496 /* PHONG should be the same as GOURAUD, since no hardware implements
8497 * this. */
8498 ok(color_match(color0, tests[i].color0, 1), "Test %u shading has color0 %08x, expected %08x.\n",
8499 i, color0, tests[i].color0);
8500 ok(color_match(color1, tests[i].color1, 1), "Test %u shading has color1 %08x, expected %08x.\n",
8501 i, color1, tests[i].color1);
8503 IDirect3DDevice8_SetVertexShader(device, 0);
8504 IDirect3DDevice8_SetPixelShader(device, 0);
8506 if (ps)
8507 IDirect3DDevice8_DeletePixelShader(device, ps);
8508 if (vs)
8509 IDirect3DDevice8_DeleteVertexShader(device, vs);
8512 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
8513 ok(hr == D3D_OK, "Failed to present, hr %#x.\n", hr);
8515 IDirect3DVertexBuffer8_Release(vb_strip);
8516 IDirect3DVertexBuffer8_Release(vb_list);
8517 refcount = IDirect3DDevice8_Release(device);
8518 ok(!refcount, "Device has %u references left.\n", refcount);
8519 IDirect3D8_Release(d3d);
8520 DestroyWindow(window);
8523 static void test_multisample_init(void)
8525 IDirect3DDevice8 *device;
8526 IDirect3D8 *d3d;
8527 IDirect3DSurface8 *back, *multi;
8528 ULONG refcount;
8529 HWND window;
8530 HRESULT hr;
8531 D3DCOLOR color;
8532 unsigned int x, y;
8533 struct surface_readback rb;
8534 BOOL all_zero = TRUE;
8536 window = create_window();
8537 d3d = Direct3DCreate8(D3D_SDK_VERSION);
8538 ok(!!d3d, "Failed to create a D3D object.\n");
8540 if (FAILED(IDirect3D8_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
8541 D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES)))
8543 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping multisample init test.\n");
8544 goto done;
8547 if (!(device = create_device(d3d, window, window, TRUE)))
8549 skip("Failed to create a D3D device, skipping tests.\n");
8550 goto done;
8553 hr = IDirect3DDevice8_GetBackBuffer(device, 0, D3DBACKBUFFER_TYPE_MONO, &back);
8554 ok(SUCCEEDED(hr), "Failed to get back buffer, hr %#x.\n", hr);
8555 hr = IDirect3DDevice8_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
8556 D3DMULTISAMPLE_2_SAMPLES, FALSE, &multi);
8557 ok(SUCCEEDED(hr), "Failed to create multisampled render target, hr %#x.\n", hr);
8559 hr = IDirect3DDevice8_CopyRects(device, multi, NULL, 0, back, NULL);
8560 ok(SUCCEEDED(hr), "CopyRects failed, hr %#x.\n", hr);
8562 get_rt_readback(back, &rb);
8563 for (y = 0; y < 480; ++y)
8565 for (x = 0; x < 640; ++x)
8567 color = get_readback_color(&rb, x, y);
8568 if (!color_match(color, 0x00000000, 0))
8570 all_zero = FALSE;
8571 break;
8574 if (!all_zero)
8575 break;
8577 release_surface_readback(&rb);
8578 ok(all_zero, "Got unexpected color 0x%08x, position %ux%u.\n", color, x, y);
8580 IDirect3DSurface8_Release(multi);
8581 IDirect3DSurface8_Release(back);
8583 refcount = IDirect3DDevice8_Release(device);
8584 ok(!refcount, "Device has %u references left.\n", refcount);
8586 done:
8587 IDirect3D8_Release(d3d);
8588 DestroyWindow(window);
8591 static void test_texture_blending(void)
8593 #define STATE_END() {0xffffffff, 0xffffffff}
8594 #define IS_STATE_END(s) (s.name == 0xffffffff && s.value == 0xffffffff)
8596 IDirect3DTexture8 *texture_bumpmap, *texture_red;
8597 IDirect3DSurface8 *backbuffer;
8598 struct surface_readback rb;
8599 D3DLOCKED_RECT locked_rect;
8600 IDirect3DDevice8 *device;
8601 unsigned int i, j, k;
8602 IDirect3D8 *d3d;
8603 D3DCOLOR color;
8604 ULONG refcount;
8605 D3DCAPS8 caps;
8606 HWND window;
8607 HRESULT hr;
8609 static const struct
8611 struct vec3 position;
8612 DWORD diffuse;
8614 quad[] =
8616 {{-1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0x80, 0xff, 0xff, 0x02)},
8617 {{-1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0x80, 0xff, 0xff, 0x02)},
8618 {{ 1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0x80, 0xff, 0xff, 0x02)},
8619 {{ 1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0x80, 0xff, 0xff, 0x02)},
8622 static const float bumpenvmat[4] = {1.0f, 1.0f, 0.0f, 0.0f};
8624 struct texture_stage_state
8626 D3DTEXTURESTAGESTATETYPE name;
8627 DWORD value;
8630 struct texture_stage
8632 enum
8634 TEXTURE_INVALID,
8635 TEXTURE_NONE,
8636 TEXTURE_BUMPMAP,
8637 TEXTURE_RED,
8639 texture;
8640 struct texture_stage_state state[20];
8643 static const struct texture_stage default_stage_state =
8645 TEXTURE_NONE,
8647 {D3DTSS_COLOROP, D3DTOP_DISABLE},
8648 {D3DTSS_COLORARG1, D3DTA_TEXTURE},
8649 {D3DTSS_COLORARG2, D3DTA_CURRENT},
8650 {D3DTSS_ALPHAOP, D3DTOP_DISABLE},
8651 {D3DTSS_ALPHAARG1, D3DTA_TEXTURE},
8652 {D3DTSS_ALPHAARG2, D3DTA_CURRENT},
8653 {D3DTSS_BUMPENVMAT00, 0},
8654 {D3DTSS_BUMPENVMAT01, 0},
8655 {D3DTSS_BUMPENVMAT10, 0},
8656 {D3DTSS_BUMPENVMAT11, 0},
8657 {D3DTSS_BUMPENVLSCALE, 0},
8658 {D3DTSS_BUMPENVLOFFSET, 0},
8659 {D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE},
8660 {D3DTSS_COLORARG0, D3DTA_CURRENT},
8661 {D3DTSS_ALPHAARG0, D3DTA_CURRENT},
8662 {D3DTSS_RESULTARG, D3DTA_CURRENT},
8663 STATE_END(),
8667 const struct test
8669 DWORD tex_op_caps;
8670 D3DCOLOR expected_color;
8671 struct texture_stage stage[8];
8673 tests[] =
8676 D3DTEXOPCAPS_DISABLE,
8677 0x80ffff02,
8680 TEXTURE_NONE,
8682 STATE_END(),
8688 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1,
8689 0x80ffff02,
8692 TEXTURE_NONE,
8694 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
8695 {D3DTSS_COLORARG1, D3DTA_CURRENT},
8696 STATE_END(),
8699 {TEXTURE_INVALID}
8703 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1,
8704 0x80ffff02,
8707 TEXTURE_NONE,
8709 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
8710 {D3DTSS_COLORARG1, D3DTA_CURRENT},
8711 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
8712 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
8713 STATE_END(),
8719 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1,
8720 0x80ffff02,
8723 TEXTURE_NONE,
8725 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
8726 {D3DTSS_COLORARG1, D3DTA_DIFFUSE},
8727 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
8728 {D3DTSS_ALPHAARG1, D3DTA_DIFFUSE},
8729 STATE_END(),
8735 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1,
8736 0x00000000,
8739 TEXTURE_NONE,
8741 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
8742 {D3DTSS_COLORARG1, D3DTA_TEMP},
8743 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
8744 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
8745 STATE_END(),
8752 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE,
8753 0x80ff0000,
8756 TEXTURE_BUMPMAP,
8758 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
8759 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
8760 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
8761 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
8762 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
8763 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
8764 {D3DTSS_ALPHAARG1, D3DTA_TEXTURE},
8765 STATE_END(),
8770 TEXTURE_RED,
8772 {D3DTSS_COLOROP, D3DTOP_MODULATE},
8773 STATE_END(),
8776 {TEXTURE_INVALID}
8780 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE,
8781 0x80ff0000,
8784 TEXTURE_BUMPMAP,
8786 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
8787 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
8788 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
8789 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
8790 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
8791 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
8792 {D3DTSS_ALPHAARG1, D3DTA_DIFFUSE},
8793 STATE_END(),
8797 TEXTURE_RED,
8799 {D3DTSS_COLOROP, D3DTOP_MODULATE},
8800 STATE_END(),
8803 {TEXTURE_INVALID}
8807 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE,
8808 0x80ff0000,
8811 TEXTURE_BUMPMAP,
8813 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
8814 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
8815 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
8816 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
8817 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
8818 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
8819 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
8820 STATE_END(),
8824 TEXTURE_RED,
8826 {D3DTSS_COLOROP, D3DTOP_MODULATE},
8827 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
8828 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
8829 STATE_END(),
8832 {TEXTURE_INVALID}
8836 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE,
8837 0x00ff0000,
8840 TEXTURE_BUMPMAP,
8842 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
8843 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
8844 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
8845 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
8846 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
8847 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
8848 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
8849 STATE_END(),
8853 TEXTURE_RED,
8855 {D3DTSS_COLOROP, D3DTOP_MODULATE},
8856 {D3DTSS_COLORARG1, D3DTA_TEXTURE},
8857 {D3DTSS_COLORARG2, D3DTA_CURRENT},
8858 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
8859 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
8860 STATE_END(),
8863 {TEXTURE_INVALID}
8867 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE,
8868 0x80ff0000,
8871 TEXTURE_BUMPMAP,
8873 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
8874 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
8875 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
8876 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
8877 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
8878 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
8879 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
8880 STATE_END(),
8884 TEXTURE_RED,
8886 {D3DTSS_COLOROP, D3DTOP_MODULATE},
8887 {D3DTSS_COLORARG1, D3DTA_TEXTURE},
8888 {D3DTSS_COLORARG2, D3DTA_CURRENT},
8889 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
8890 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
8891 STATE_END(),
8894 {TEXTURE_INVALID}
8899 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE
8900 | D3DTEXOPCAPS_ADD,
8901 0x80ff0000,
8904 TEXTURE_BUMPMAP,
8906 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
8907 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
8908 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
8909 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
8910 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
8911 {D3DTSS_ALPHAOP, D3DTOP_ADD},
8912 {D3DTSS_ALPHAARG1, D3DTA_DIFFUSE},
8913 {D3DTSS_ALPHAARG2, D3DTA_CURRENT},
8914 STATE_END(),
8918 TEXTURE_RED,
8920 {D3DTSS_COLOROP, D3DTOP_MODULATE},
8921 {D3DTSS_COLORARG1, D3DTA_TEXTURE},
8922 {D3DTSS_COLORARG2, D3DTA_CURRENT},
8923 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
8924 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
8925 STATE_END(),
8928 {TEXTURE_INVALID}
8932 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE
8933 | D3DTEXOPCAPS_MODULATE2X,
8934 0x80ffff00,
8937 TEXTURE_BUMPMAP,
8939 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
8940 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
8941 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
8942 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
8943 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
8944 {D3DTSS_ALPHAOP, D3DTOP_MODULATE2X},
8945 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
8946 {D3DTSS_ALPHAARG2, D3DTA_DIFFUSE},
8947 STATE_END(),
8951 TEXTURE_RED,
8953 {D3DTSS_COLOROP, D3DTOP_MODULATE},
8954 {D3DTSS_COLORARG1, D3DTA_CURRENT},
8955 {D3DTSS_COLORARG2, D3DTA_CURRENT},
8956 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
8957 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
8958 STATE_END(),
8961 {TEXTURE_INVALID}
8965 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP,
8966 0x80ffff02,
8969 TEXTURE_NONE,
8971 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
8972 {D3DTSS_COLORARG1, D3DTA_DIFFUSE},
8973 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
8974 {D3DTSS_ALPHAARG1, D3DTA_DIFFUSE},
8975 {D3DTSS_RESULTARG, D3DTA_TEMP},
8976 STATE_END(),
8980 TEXTURE_BUMPMAP,
8982 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
8983 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
8984 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
8985 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
8986 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
8987 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
8988 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
8989 {D3DTSS_RESULTARG, D3DTA_TEMP},
8990 STATE_END(),
8994 TEXTURE_RED,
8996 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
8997 {D3DTSS_COLORARG1, D3DTA_TEXTURE},
8998 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
8999 {D3DTSS_ALPHAARG1, D3DTA_TEXTURE},
9000 STATE_END(),
9004 TEXTURE_NONE,
9006 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
9007 {D3DTSS_COLORARG1, D3DTA_TEMP},
9008 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
9009 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
9010 STATE_END(),
9013 {TEXTURE_INVALID}
9018 window = create_window();
9019 d3d = Direct3DCreate8(D3D_SDK_VERSION);
9020 ok(!!d3d, "Failed to create a D3D object.\n");
9021 if (!(device = create_device(d3d, window, window, TRUE)))
9023 skip("Failed to create a D3D device.\n");
9024 goto done;
9027 memset(&caps, 0, sizeof(caps));
9028 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
9029 ok(hr == D3D_OK, "IDirect3DDevice8_GetDeviceCaps failed hr %#x.\n", hr);
9031 if(!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP))
9033 skip("D3DPMISCCAPS_TSSARGTEMP not supported.\n");
9034 IDirect3DDevice8_Release(device);
9035 goto done;
9038 if (FAILED(IDirect3D8_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
9039 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_V8U8)))
9041 skip("D3DFMT_V8U8 not supported for legacy bump mapping.\n");
9042 IDirect3DDevice8_Release(device);
9043 goto done;
9046 hr = IDirect3DDevice8_GetBackBuffer(device, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9047 ok(hr == D3D_OK, "Can't get back buffer, hr %#x.\n", hr);
9049 hr = IDirect3DDevice8_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture_bumpmap);
9050 ok(hr == D3D_OK, "IDirect3DDevice8_CreateTexture failed, hr %#x.\n", hr);
9051 hr = IDirect3DDevice8_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture_red);
9052 ok(hr == D3D_OK, "IDirect3DDevice8_CreateTexture failed, hr %#x.\n", hr);
9054 memset(&locked_rect, 0, sizeof(locked_rect));
9055 hr = IDirect3DTexture8_LockRect(texture_bumpmap, 0, &locked_rect, NULL, 0);
9056 ok(SUCCEEDED(hr), "LockRect failed, hr %#x.\n", hr);
9057 *((WORD *)locked_rect.pBits) = 0xff00;
9058 hr = IDirect3DTexture8_UnlockRect(texture_bumpmap, 0);
9059 ok(SUCCEEDED(hr), "UnlockRect failed, hr %#x.\n", hr);
9061 memset(&locked_rect, 0, sizeof(locked_rect));
9062 hr = IDirect3DTexture8_LockRect(texture_red, 0, &locked_rect, NULL, 0);
9063 ok(SUCCEEDED(hr), "LockRect failed, hr %#x.\n", hr);
9064 *((DWORD *)locked_rect.pBits) = 0x00ff0000;
9065 hr = IDirect3DTexture8_UnlockRect(texture_red, 0);
9066 ok(SUCCEEDED(hr), "UnlockRect failed, hr %#x.\n", hr);
9068 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9069 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
9070 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9071 ok(hr == D3D_OK, "Failed to disable lighting, hr %#x.\n", hr);
9073 for (i = 0; i < sizeof(tests) / sizeof(*tests); ++i)
9075 const struct test *current_test = &tests[i];
9077 if ((caps.TextureOpCaps & current_test->tex_op_caps) != current_test->tex_op_caps)
9079 skip("Texture operations %#x not supported.\n", current_test->tex_op_caps);
9080 continue;
9083 for (j = 0; j < caps.MaxTextureBlendStages; ++j)
9085 IDirect3DTexture8 *current_texture = NULL;
9087 for (k = 0; !IS_STATE_END(default_stage_state.state[k]); ++k)
9089 hr = IDirect3DDevice8_SetTextureStageState(device, j,
9090 default_stage_state.state[k].name, default_stage_state.state[k].value);
9091 ok(SUCCEEDED(hr), "Test %u: SetTextureStageState failed, hr %#x.\n", i, hr);
9094 if (current_test->stage[j].texture != TEXTURE_INVALID)
9096 const struct texture_stage_state *current_state = current_test->stage[j].state;
9098 switch (current_test->stage[j].texture)
9100 case TEXTURE_RED:
9101 current_texture = texture_red;
9102 break;
9103 case TEXTURE_BUMPMAP:
9104 current_texture = texture_bumpmap;
9105 break;
9106 default:
9107 current_texture = NULL;
9108 break;
9111 for (k = 0; !IS_STATE_END(current_state[k]); ++k)
9113 hr = IDirect3DDevice8_SetTextureStageState(device, j,
9114 current_state[k].name, current_state[k].value);
9115 ok(SUCCEEDED(hr), "Test %u: SetTextureStageState failed, hr %#x.\n", i, hr);
9119 hr = IDirect3DDevice8_SetTexture(device, j, (IDirect3DBaseTexture8 *)current_texture);
9120 ok(SUCCEEDED(hr), "Test %u: SetTexture failed, hr %#x.\n", i, hr);
9123 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
9124 ok(hr == D3D_OK, "Test %u: IDirect3DDevice8_Clear failed, hr %#x.\n", i, hr);
9126 hr = IDirect3DDevice8_BeginScene(device);
9127 ok(SUCCEEDED(hr), "Test %u: BeginScene failed, hr %#x.\n", i, hr);
9128 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
9129 ok(SUCCEEDED(hr), "Test %u: DrawPrimitiveUP failed, hr %#x.\n", i, hr);
9130 hr = IDirect3DDevice8_EndScene(device);
9131 ok(SUCCEEDED(hr), "Test %u: EndScene failed, hr %#x.\n", i, hr);
9133 get_rt_readback(backbuffer, &rb);
9134 color = get_readback_color(&rb, 320, 240);
9135 ok(color_match(color, current_test->expected_color, 1),
9136 "Test %u: Got color 0x%08x, expected 0x%08x.\n", i, color, current_test->expected_color);
9137 release_surface_readback(&rb);
9138 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
9139 ok(SUCCEEDED(hr), "Test %u: Present failed, hr %#x.\n", i, hr);
9142 IDirect3DTexture8_Release(texture_bumpmap);
9143 IDirect3DTexture8_Release(texture_red);
9144 IDirect3DSurface8_Release(backbuffer);
9145 refcount = IDirect3DDevice8_Release(device);
9146 ok(!refcount, "Device has %u references left.\n", refcount);
9147 done:
9148 IDirect3D8_Release(d3d);
9149 DestroyWindow(window);
9152 static void test_color_clamping(void)
9154 static const D3DMATRIX mat =
9156 1.0f, 0.0f, 0.0f, 0.0f,
9157 0.0f, 1.0f, 0.0f, 0.0f,
9158 0.0f, 0.0f, 1.0f, 0.0f,
9159 0.0f, 0.0f, 0.0f, 1.0f,
9160 }}};
9161 static const struct vec3 quad[] =
9163 {-1.0f, -1.0f, 0.1f},
9164 {-1.0f, 1.0f, 0.1f},
9165 { 1.0f, -1.0f, 0.1f},
9166 { 1.0f, 1.0f, 0.1f},
9168 static const DWORD decl[] =
9170 D3DVSD_STREAM(0),
9171 D3DVSD_REG(D3DVSDE_POSITION, D3DVSDT_FLOAT3),
9172 D3DVSD_CONST(0, 1), 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c0, 1.0, 1.0, 1.0, 1.0 */
9173 D3DVSD_END()
9175 static const DWORD vs1_code[] =
9177 0xfffe0101, /* vs_1_1 */
9178 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
9179 0x00000002, 0xd00f0000, 0xa0e40000, 0xa0e40000, /* add oD0, c0, c0 */
9180 0x00000002, 0xd00f0001, 0xa0e40000, 0xa0e40000, /* add oD1, c0, c0 */
9181 0x0000ffff
9183 static const DWORD ps1_code[] =
9185 0xffff0101, /* ps_1_1 */
9186 0x00000051, 0xa00f0000, 0x3e800000, 0x3e800000, 0x3e800000, 0x3e800000, /* def c0, 0.25, 0.25, 0.25, 0.25 */
9187 0x00000002, 0x800f0000, 0x90e40000, 0x90e40001, /* add r0, v0, v1 */
9188 0x00000005, 0x800f0000, 0x80e40000, 0xa0e40000, /* mul r0, r0, c0 */
9189 0x0000ffff
9191 static const struct
9193 DWORD vs_version;
9194 const DWORD *vs;
9195 DWORD ps_version;
9196 const DWORD *ps;
9197 D3DCOLOR expected, broken;
9199 tests[] =
9201 {0, NULL, 0, NULL, 0x00404040},
9202 {0, NULL, D3DPS_VERSION(1, 1), ps1_code, 0x00404040, 0x00808080},
9203 {D3DVS_VERSION(1, 1), vs1_code, 0, NULL, 0x00404040},
9204 {D3DVS_VERSION(1, 1), vs1_code, D3DPS_VERSION(1, 1), ps1_code, 0x007f7f7f},
9206 IDirect3DDevice8 *device;
9207 IDirect3D8 *d3d;
9208 unsigned int i;
9209 ULONG refcount;
9210 D3DCOLOR color;
9211 D3DCAPS8 caps;
9212 DWORD vs, ps;
9213 HWND window;
9214 HRESULT hr;
9216 window = create_window();
9217 d3d = Direct3DCreate8(D3D_SDK_VERSION);
9218 ok(!!d3d, "Failed to create a D3D object.\n");
9219 if (!(device = create_device(d3d, window, window, TRUE)))
9221 skip("Failed to create a D3D device, skipping tests.\n");
9222 IDirect3D8_Release(d3d);
9223 DestroyWindow(window);
9224 return;
9227 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
9228 ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
9230 hr = IDirect3DDevice8_SetTransform(device, D3DTS_WORLD, &mat);
9231 ok(SUCCEEDED(hr), "Failed to set world transform, hr %#x.\n", hr);
9232 hr = IDirect3DDevice8_SetTransform(device, D3DTS_VIEW, &mat);
9233 ok(SUCCEEDED(hr), "Failed to set view transform, hr %#x.\n", hr);
9234 hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, &mat);
9235 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
9236 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, FALSE);
9237 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#x.\n", hr);
9238 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, FALSE);
9239 ok(SUCCEEDED(hr), "Failed to disable Z test, hr %#x.\n", hr);
9240 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
9241 ok(SUCCEEDED(hr), "Failed to disable fog, hr %#x.\n", hr);
9242 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
9243 ok(SUCCEEDED(hr), "Failed to disable stencil test, hr %#x.\n", hr);
9244 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
9245 ok(SUCCEEDED(hr), "Failed to disable culling, hr %#x.\n", hr);
9246 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9247 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
9249 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xff404040);
9250 ok(SUCCEEDED(hr), "Failed to set texture factor, hr %#x.\n", hr);
9251 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
9252 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
9253 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9254 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
9255 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_SPECULAR);
9256 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
9257 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_MODULATE);
9258 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
9259 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TFACTOR);
9260 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
9261 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
9262 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
9264 for (i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i)
9266 if (caps.VertexShaderVersion < tests[i].vs_version
9267 || caps.PixelShaderVersion < tests[i].ps_version)
9269 skip("Vertex / pixel shader version not supported, skipping test %u.\n", i);
9270 continue;
9272 if (tests[i].vs)
9274 hr = IDirect3DDevice8_CreateVertexShader(device, decl, tests[i].vs, &vs, 0);
9275 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x (case %u).\n", hr, i);
9277 else
9279 vs = D3DFVF_XYZ;
9281 if (tests[i].ps)
9283 hr = IDirect3DDevice8_CreatePixelShader(device, tests[i].ps, &ps);
9284 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x (case %u).\n", hr, i);
9286 else
9288 ps = 0;
9291 hr = IDirect3DDevice8_SetVertexShader(device, vs);
9292 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
9293 hr = IDirect3DDevice8_SetPixelShader(device, ps);
9294 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
9296 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0f, 0);
9297 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
9299 hr = IDirect3DDevice8_BeginScene(device);
9300 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9302 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
9303 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9305 hr = IDirect3DDevice8_EndScene(device);
9306 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9308 color = getPixelColor(device, 320, 240);
9309 ok(color_match(color, tests[i].expected, 1) || broken(color_match(color, tests[i].broken, 1)),
9310 "Got unexpected color 0x%08x, case %u.\n", color, i);
9312 if (vs != D3DFVF_XYZ)
9313 IDirect3DDevice8_DeleteVertexShader(device, vs);
9314 if (ps)
9315 IDirect3DDevice8_DeletePixelShader(device, ps);
9318 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
9319 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
9321 refcount = IDirect3DDevice8_Release(device);
9322 ok(!refcount, "Device has %u references left.\n", refcount);
9323 IDirect3D8_Release(d3d);
9324 DestroyWindow(window);
9327 static void test_edge_antialiasing_blending(void)
9329 IDirect3DDevice8 *device;
9330 IDirect3D8 *d3d8;
9331 ULONG refcount;
9332 D3DCOLOR color;
9333 D3DCAPS8 caps;
9334 HWND window;
9335 HRESULT hr;
9337 static const D3DMATRIX mat =
9339 1.0f, 0.0f, 0.0f, 0.0f,
9340 0.0f, 1.0f, 0.0f, 0.0f,
9341 0.0f, 0.0f, 1.0f, 0.0f,
9342 0.0f, 0.0f, 0.0f, 1.0f,
9343 }}};
9344 static const struct
9346 struct vec3 position;
9347 DWORD diffuse;
9349 green_quad[] =
9351 {{-1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0x7f, 0x00, 0xff, 0x00)},
9352 {{-1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0x7f, 0x00, 0xff, 0x00)},
9353 {{ 1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0x7f, 0x00, 0xff, 0x00)},
9354 {{ 1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0x7f, 0x00, 0xff, 0x00)},
9356 static const struct
9358 struct vec3 position;
9359 DWORD diffuse;
9361 red_quad[] =
9363 {{-1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0xcc, 0xff, 0x00, 0x00)},
9364 {{-1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0xcc, 0xff, 0x00, 0x00)},
9365 {{ 1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0xcc, 0xff, 0x00, 0x00)},
9366 {{ 1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0xcc, 0xff, 0x00, 0x00)},
9369 window = create_window();
9370 d3d8 = Direct3DCreate8(D3D_SDK_VERSION);
9371 ok(!!d3d8, "Failed to create a D3D object.\n");
9372 if (!(device = create_device(d3d8, window, window, TRUE)))
9374 skip("Failed to create a D3D device.\n");
9375 IDirect3D8_Release(d3d8);
9376 DestroyWindow(window);
9377 return;
9380 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
9381 ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
9382 trace("Edge antialiasing support: %#x.\n", caps.RasterCaps & D3DPRASTERCAPS_ANTIALIASEDGES);
9384 hr = IDirect3DDevice8_SetTransform(device, D3DTS_WORLD, &mat);
9385 ok(SUCCEEDED(hr), "Failed to set world transform, hr %#x.\n", hr);
9386 hr = IDirect3DDevice8_SetTransform(device, D3DTS_VIEW, &mat);
9387 ok(SUCCEEDED(hr), "Failed to set view transform, hr %#x.\n", hr);
9388 hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, &mat);
9389 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
9390 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, FALSE);
9391 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#x.\n", hr);
9392 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, FALSE);
9393 ok(SUCCEEDED(hr), "Failed to disable Z test, hr %#x.\n", hr);
9394 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
9395 ok(SUCCEEDED(hr), "Failed to disable fog, hr %#x.\n", hr);
9396 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
9397 ok(SUCCEEDED(hr), "Failed to disable stencil test, hr %#x.\n", hr);
9398 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
9399 ok(SUCCEEDED(hr), "Failed to disable culling, hr %#x.\n", hr);
9400 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9401 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
9403 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
9404 ok(SUCCEEDED(hr), "Failed to enable blending, hr %#x.\n", hr);
9405 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_BLENDOP, D3DBLENDOP_ADD);
9406 ok(SUCCEEDED(hr), "Failed to set blend op, hr %#x.\n", hr);
9407 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
9408 ok(SUCCEEDED(hr), "Failed to set src blend, hr %#x.\n", hr);
9409 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_DESTALPHA);
9410 ok(SUCCEEDED(hr), "Failed to set dest blend, hr %#x.\n", hr);
9412 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9413 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
9414 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9415 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
9416 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
9417 ok(SUCCEEDED(hr), "Failed to set alpha op, hr %#x.\n", hr);
9418 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
9419 ok(SUCCEEDED(hr), "Failed to set alpha arg, hr %#x.\n", hr);
9421 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9422 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
9424 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xccff0000, 0.0f, 0);
9425 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
9426 hr = IDirect3DDevice8_BeginScene(device);
9427 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9428 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, green_quad, sizeof(*green_quad));
9429 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9430 hr = IDirect3DDevice8_EndScene(device);
9431 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9432 color = getPixelColor(device, 320, 240);
9433 ok(color_match(color, 0x00cc7f00, 1), "Got unexpected color 0x%08x.\n", color);
9435 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x7f00ff00, 0.0f, 0);
9436 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
9437 hr = IDirect3DDevice8_BeginScene(device);
9438 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9439 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, red_quad, sizeof(*red_quad));
9440 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9441 hr = IDirect3DDevice8_EndScene(device);
9442 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9443 color = getPixelColor(device, 320, 240);
9444 ok(color_match(color, 0x00cc7f00, 1), "Got unexpected color 0x%08x.\n", color);
9446 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
9447 ok(SUCCEEDED(hr), "Failed to disable blending, hr %#x.\n", hr);
9449 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xccff0000, 0.0f, 0);
9450 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
9451 hr = IDirect3DDevice8_BeginScene(device);
9452 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9453 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, green_quad, sizeof(*green_quad));
9454 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9455 hr = IDirect3DDevice8_EndScene(device);
9456 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9457 color = getPixelColor(device, 320, 240);
9458 ok(color_match(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
9460 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x7f00ff00, 0.0f, 0);
9461 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
9462 hr = IDirect3DDevice8_BeginScene(device);
9463 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9464 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, red_quad, sizeof(*red_quad));
9465 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9466 hr = IDirect3DDevice8_EndScene(device);
9467 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9468 color = getPixelColor(device, 320, 240);
9469 ok(color_match(color, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color);
9471 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_EDGEANTIALIAS, TRUE);
9472 ok(SUCCEEDED(hr), "Failed to enable edge antialiasing, hr %#x.\n", hr);
9474 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xccff0000, 0.0f, 0);
9475 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
9476 hr = IDirect3DDevice8_BeginScene(device);
9477 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9478 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, green_quad, sizeof(*green_quad));
9479 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9480 hr = IDirect3DDevice8_EndScene(device);
9481 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9482 color = getPixelColor(device, 320, 240);
9483 ok(color_match(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
9485 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x7f00ff00, 0.0f, 0);
9486 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
9487 hr = IDirect3DDevice8_BeginScene(device);
9488 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9489 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, red_quad, sizeof(*red_quad));
9490 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9491 hr = IDirect3DDevice8_EndScene(device);
9492 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9493 color = getPixelColor(device, 320, 240);
9494 ok(color_match(color, 0x00ff0000, 1), "Got unexpected color 0x%08x.\n", color);
9496 refcount = IDirect3DDevice8_Release(device);
9497 ok(!refcount, "Device has %u references left.\n", refcount);
9498 IDirect3D8_Release(d3d8);
9499 DestroyWindow(window);
9502 /* This test shows that 0xffff is valid index in D3D8. */
9503 static void test_max_index16(void)
9505 static const D3DMATRIX mat =
9507 1.0f, 0.0f, 0.0f, 0.0f,
9508 0.0f, 1.0f, 0.0f, 0.0f,
9509 0.0f, 0.0f, 1.0f, 0.0f,
9510 0.0f, 0.0f, 0.0f, 1.0f,
9511 }}};
9512 static const struct vertex
9514 struct vec3 position;
9515 DWORD diffuse;
9517 green_quad[] =
9519 {{-1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
9520 {{-1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
9521 {{ 1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
9522 {{ 1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
9524 static const unsigned short indices[] = {0, 1, 2, 0xffff};
9525 static const unsigned int vertex_count = 0xffff + 1;
9527 D3DADAPTER_IDENTIFIER8 identifier;
9528 IDirect3DVertexBuffer8 *vb;
9529 IDirect3DIndexBuffer8 *ib;
9530 IDirect3DDevice8 *device;
9531 struct vertex *vb_data;
9532 IDirect3D8 *d3d8;
9533 ULONG refcount;
9534 D3DCOLOR color;
9535 D3DCAPS8 caps;
9536 HWND window;
9537 BYTE *data;
9538 HRESULT hr;
9539 BOOL warp;
9541 window = create_window();
9542 d3d8 = Direct3DCreate8(D3D_SDK_VERSION);
9543 ok(!!d3d8, "Failed to create a D3D object.\n");
9545 hr = IDirect3D8_GetAdapterIdentifier(d3d8, D3DADAPTER_DEFAULT, 0, &identifier);
9546 ok(SUCCEEDED(hr), "Failed to get adapter identifier, hr %#x.\n", hr);
9547 warp = adapter_is_warp(&identifier);
9549 if (!(device = create_device(d3d8, window, window, TRUE)))
9551 skip("Failed to create a D3D device.\n");
9552 IDirect3D8_Release(d3d8);
9553 DestroyWindow(window);
9554 return;
9557 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
9558 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
9559 if (caps.MaxVertexIndex < 0xffff)
9561 skip("Max vertex index is lower than 0xffff (%#x).\n", caps.MaxVertexIndex);
9562 IDirect3DDevice8_Release(device);
9563 IDirect3D8_Release(d3d8);
9564 DestroyWindow(window);
9565 return;
9568 hr = IDirect3DDevice8_CreateVertexBuffer(device, vertex_count * sizeof(*green_quad), 0,
9569 D3DFVF_XYZ | D3DFVF_DIFFUSE, D3DPOOL_MANAGED, &vb);
9570 ok(SUCCEEDED(hr), "Failed to create vertex buffer, hr %#x.\n", hr);
9572 hr = IDirect3DDevice8_CreateIndexBuffer(device, sizeof(indices), 0,
9573 D3DFMT_INDEX16, D3DPOOL_MANAGED, &ib);
9574 ok(SUCCEEDED(hr), "Failed to create index buffer, hr %#x.\n", hr);
9576 hr = IDirect3DDevice8_SetTransform(device, D3DTS_WORLD, &mat);
9577 ok(SUCCEEDED(hr), "Failed to set world transform, hr %#x.\n", hr);
9578 hr = IDirect3DDevice8_SetTransform(device, D3DTS_VIEW, &mat);
9579 ok(SUCCEEDED(hr), "Failed to set view transform, hr %#x.\n", hr);
9580 hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, &mat);
9581 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
9582 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, FALSE);
9583 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#x.\n", hr);
9584 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, FALSE);
9585 ok(SUCCEEDED(hr), "Failed to disable Z test, hr %#x.\n", hr);
9586 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
9587 ok(SUCCEEDED(hr), "Failed to disable fog, hr %#x.\n", hr);
9588 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
9589 ok(SUCCEEDED(hr), "Failed to disable stencil test, hr %#x.\n", hr);
9590 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
9591 ok(SUCCEEDED(hr), "Failed to disable culling, hr %#x.\n", hr);
9592 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9593 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
9595 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
9596 ok(SUCCEEDED(hr), "Failed to disable blending, hr %#x.\n", hr);
9598 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9599 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
9600 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
9601 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
9602 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
9603 ok(SUCCEEDED(hr), "Failed to set alpha op, hr %#x.\n", hr);
9604 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
9605 ok(SUCCEEDED(hr), "Failed to set alpha arg, hr %#x.\n", hr);
9607 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9608 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
9610 hr = IDirect3DVertexBuffer8_Lock(vb, 0, sizeof(green_quad), (BYTE **)&vb_data, 0);
9611 ok(hr == D3D_OK, "Failed to lock vertex buffer, hr %#x.\n", hr);
9612 vb_data[0] = green_quad[0];
9613 vb_data[1] = green_quad[1];
9614 vb_data[2] = green_quad[2];
9615 vb_data[0xffff] = green_quad[3];
9616 hr = IDirect3DVertexBuffer8_Unlock(vb);
9617 ok(hr == D3D_OK, "Failed to unlock vertex buffer, hr %#x.\n", hr);
9619 hr = IDirect3DIndexBuffer8_Lock(ib, 0, sizeof(indices), &data, 0);
9620 ok(hr == D3D_OK, "Failed to lock index buffer, hr %#x.\n", hr);
9621 memcpy(data, indices, sizeof(indices));
9622 hr = IDirect3DIndexBuffer8_Unlock(ib);
9623 ok(hr == D3D_OK, "Failed to unlock index buffer, hr %#x.\n", hr);
9625 hr = IDirect3DDevice8_SetIndices(device, ib, 0);
9626 ok(hr == D3D_OK, "Failed to set index buffer, hr %#x.\n", hr);
9627 hr = IDirect3DDevice8_SetStreamSource(device, 0, vb, sizeof(struct vertex));
9628 ok(hr == D3D_OK, "Failed to set stream source, hr %#x.\n", hr);
9630 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
9631 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
9632 hr = IDirect3DDevice8_BeginScene(device);
9633 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9634 hr = IDirect3DDevice8_DrawIndexedPrimitive(device, D3DPT_TRIANGLESTRIP, 0, vertex_count, 0, 2);
9635 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9636 hr = IDirect3DDevice8_EndScene(device);
9637 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9638 color = getPixelColor(device, 20, 20);
9639 ok(color_match(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
9640 color = getPixelColor(device, 320, 240);
9641 ok(color_match(color, 0x0000ff00, 1) || broken(warp), "Got unexpected color 0x%08x.\n", color);
9642 color = getPixelColor(device, 620, 460);
9643 ok(color_match(color, 0x0000ff00, 1) || broken(warp), "Got unexpected color 0x%08x.\n", color);
9645 IDirect3DIndexBuffer8_Release(ib);
9646 IDirect3DVertexBuffer8_Release(vb);
9647 refcount = IDirect3DDevice8_Release(device);
9648 ok(!refcount, "Device has %u references left.\n", refcount);
9649 IDirect3D8_Release(d3d8);
9650 DestroyWindow(window);
9653 static void test_backbuffer_resize(void)
9655 D3DPRESENT_PARAMETERS present_parameters = {0};
9656 IDirect3DSurface8 *backbuffer;
9657 IDirect3DDevice8 *device;
9658 IDirect3D8 *d3d;
9659 D3DCOLOR color;
9660 ULONG refcount;
9661 HWND window;
9662 HRESULT hr;
9664 static const struct
9666 struct vec3 position;
9667 DWORD diffuse;
9669 quad[] =
9671 {{-1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
9672 {{-1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
9673 {{ 1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
9674 {{ 1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00)},
9677 window = create_window();
9678 d3d = Direct3DCreate8(D3D_SDK_VERSION);
9679 ok(!!d3d, "Failed to create a D3D object.\n");
9680 if (!(device = create_device(d3d, window, window, TRUE)))
9682 skip("Failed to create a D3D device.\n");
9683 goto done;
9686 /* Wine d3d8 implementation had a bug which was triggered by a
9687 * SetRenderTarget() call with an unreferenced surface. */
9688 hr = IDirect3DDevice8_GetBackBuffer(device, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9689 ok(SUCCEEDED(hr), "Failed to get backbuffer, hr %#x.\n", hr);
9690 refcount = IDirect3DSurface8_Release(backbuffer);
9691 ok(!refcount, "Surface has %u references left.\n", refcount);
9692 hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, NULL);
9693 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
9694 hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, NULL);
9695 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
9697 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 1.0f, 0);
9698 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
9699 color = getPixelColor(device, 1, 1);
9700 ok(color == 0x00ff0000, "Got unexpected color 0x%08x.\n", color);
9702 present_parameters.BackBufferWidth = 800;
9703 present_parameters.BackBufferHeight = 600;
9704 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
9705 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
9706 present_parameters.hDeviceWindow = NULL;
9707 present_parameters.Windowed = TRUE;
9708 present_parameters.EnableAutoDepthStencil = TRUE;
9709 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
9710 hr = IDirect3DDevice8_Reset(device, &present_parameters);
9711 ok(SUCCEEDED(hr), "Failed to reset, hr %#x.\n", hr);
9713 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, FALSE);
9714 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#x.\n", hr);
9715 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, FALSE);
9716 ok(SUCCEEDED(hr), "Failed to disable Z test, hr %#x.\n", hr);
9717 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9718 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
9719 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9720 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
9722 hr = IDirect3DDevice8_GetBackBuffer(device, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9723 ok(SUCCEEDED(hr), "Failed to get backbuffer, hr %#x.\n", hr);
9724 hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, NULL);
9725 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
9726 IDirect3DSurface8_Release(backbuffer);
9728 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 1.0f, 0);
9729 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
9730 color = getPixelColor(device, 1, 1);
9731 ok(color == 0x00ffff00, "Got unexpected color 0x%08x.\n", color);
9732 color = getPixelColor(device, 700, 500);
9733 ok(color == 0x00ffff00, "Got unexpected color 0x%08x.\n", color);
9735 hr = IDirect3DDevice8_BeginScene(device);
9736 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9737 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
9738 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9739 hr = IDirect3DDevice8_EndScene(device);
9740 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9741 color = getPixelColor(device, 1, 1);
9742 ok(color == 0x0000ff00, "Got unexpected color 0x%08x.\n", color);
9743 color = getPixelColor(device, 700, 500);
9744 ok(color == 0x0000ff00, "Got unexpected color 0x%08x.\n", color);
9746 refcount = IDirect3DDevice8_Release(device);
9747 ok(!refcount, "Device has %u references left.\n", refcount);
9748 done:
9749 IDirect3D8_Release(d3d);
9750 DestroyWindow(window);
9753 START_TEST(visual)
9755 D3DADAPTER_IDENTIFIER8 identifier;
9756 IDirect3D8 *d3d;
9757 HRESULT hr;
9759 if (!(d3d = Direct3DCreate8(D3D_SDK_VERSION)))
9761 skip("Failed to create D3D8 object.\n");
9762 return;
9765 memset(&identifier, 0, sizeof(identifier));
9766 hr = IDirect3D8_GetAdapterIdentifier(d3d, D3DADAPTER_DEFAULT, 0, &identifier);
9767 ok(SUCCEEDED(hr), "Failed to get adapter identifier, hr %#x.\n", hr);
9768 trace("Driver string: \"%s\"\n", identifier.Driver);
9769 trace("Description string: \"%s\"\n", identifier.Description);
9770 /* Only Windows XP's default VGA driver should have an empty description */
9771 ok(identifier.Description[0] || broken(!strcmp(identifier.Driver, "vga.dll")), "Empty driver description.\n");
9772 trace("Driver version %d.%d.%d.%d\n",
9773 HIWORD(U(identifier.DriverVersion).HighPart), LOWORD(U(identifier.DriverVersion).HighPart),
9774 HIWORD(U(identifier.DriverVersion).LowPart), LOWORD(U(identifier.DriverVersion).LowPart));
9776 IDirect3D8_Release(d3d);
9778 test_sanity();
9779 depth_clamp_test();
9780 lighting_test();
9781 test_specular_lighting();
9782 clear_test();
9783 fog_test();
9784 z_range_test();
9785 offscreen_test();
9786 test_blend();
9787 test_scalar_instructions();
9788 fog_with_shader_test();
9789 cnd_test();
9790 p8_texture_test();
9791 texop_test();
9792 depth_buffer_test();
9793 depth_buffer2_test();
9794 intz_test();
9795 shadow_test();
9796 multisample_copy_rects_test();
9797 zenable_test();
9798 resz_test();
9799 fog_special_test();
9800 volume_dxt5_test();
9801 volume_v16u16_test();
9802 add_dirty_rect_test();
9803 test_3dc_formats();
9804 test_fog_interpolation();
9805 test_negative_fixedfunction_fog();
9806 test_table_fog_zw();
9807 test_signed_formats();
9808 test_updatetexture();
9809 test_pointsize();
9810 test_multisample_mismatch();
9811 test_texcoordindex();
9812 test_vshader_input();
9813 test_fixed_function_fvf();
9814 test_flip();
9815 test_uninitialized_varyings();
9816 test_shademode();
9817 test_multisample_init();
9818 test_texture_blending();
9819 test_color_clamping();
9820 test_edge_antialiasing_blending();
9821 test_max_index16();
9822 test_backbuffer_resize();