d3d8/tests: Port test_texture_blending() from d3d9.
[wine.git] / dlls / d3d8 / tests / visual.c
blob0663e1839e9d05451aebc2ccaa797b06cbefb103
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 BOOL color_match(D3DCOLOR c1, D3DCOLOR c2, BYTE max_diff)
45 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
46 c1 >>= 8; c2 >>= 8;
47 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
48 c1 >>= 8; c2 >>= 8;
49 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
50 c1 >>= 8; c2 >>= 8;
51 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
52 return TRUE;
55 static BOOL adapter_is_warp(const D3DADAPTER_IDENTIFIER8 *identifier)
57 return !strcmp(identifier->Driver, "d3d10warp.dll");
60 struct surface_readback
62 IDirect3DSurface8 *surface;
63 D3DLOCKED_RECT locked_rect;
66 static void get_rt_readback(IDirect3DSurface8 *surface, struct surface_readback *rb)
68 IDirect3DDevice8 *device;
69 IDirect3DTexture8 *tex = NULL;
70 HRESULT hr;
72 memset(rb, 0, sizeof(*rb));
73 IDirect3DSurface8_GetDevice(surface, &device);
74 hr = IDirect3DDevice8_CreateTexture(device, 640, 480, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &tex);
75 if (FAILED(hr) || !tex)
77 trace("Can't create an offscreen plain surface to read the render target data, hr %#x.\n", hr);
78 goto error;
80 hr = IDirect3DTexture8_GetSurfaceLevel(tex, 0, &rb->surface);
81 if (FAILED(hr))
83 trace("Can't get surface from texture, hr %#x.\n", hr);
84 goto error;
86 hr = IDirect3DDevice8_CopyRects(device, surface, NULL, 0, rb->surface, NULL);
87 if (FAILED(hr))
89 trace("Can't read the render target, hr %#x.\n", hr);
90 goto error;
92 hr = IDirect3DSurface8_LockRect(rb->surface, &rb->locked_rect, NULL, D3DLOCK_READONLY);
93 if (FAILED(hr))
95 trace("Can't lock the offscreen surface, hr %#x.\n", hr);
96 goto error;
98 IDirect3DTexture8_Release(tex);
99 IDirect3DDevice8_Release(device);
100 return;
102 error:
103 if (rb->surface)
104 IDirect3DSurface8_Release(rb->surface);
105 rb->surface = NULL;
106 if (tex)
107 IDirect3DTexture8_Release(tex);
108 IDirect3DDevice8_Release(device);
111 static DWORD get_readback_color(struct surface_readback *rb, unsigned int x, unsigned int y)
113 return rb->locked_rect.pBits
114 ? ((DWORD *)rb->locked_rect.pBits)[y * rb->locked_rect.Pitch / sizeof(DWORD) + x] : 0xdeadbeef;
117 static void release_surface_readback(struct surface_readback *rb)
119 HRESULT hr;
121 if (!rb->surface)
122 return;
123 if (rb->locked_rect.pBits && FAILED(hr = IDirect3DSurface8_UnlockRect(rb->surface)))
124 trace("Can't unlock the offscreen surface, hr %#x.\n", hr);
125 IDirect3DSurface8_Release(rb->surface);
128 static DWORD getPixelColor(IDirect3DDevice8 *device, UINT x, UINT y)
130 DWORD ret;
131 IDirect3DSurface8 *rt;
132 struct surface_readback rb;
133 HRESULT hr;
135 hr = IDirect3DDevice8_GetRenderTarget(device, &rt);
136 if (FAILED(hr))
138 trace("Can't get the render target, hr %#x.\n", hr);
139 return 0xdeadbeef;
142 get_rt_readback(rt, &rb);
143 /* Remove the X channel for now. DirectX and OpenGL have different ideas how to treat it apparently, and it isn't
144 * really important for these tests
146 ret = get_readback_color(&rb, x, y) & 0x00ffffff;
147 release_surface_readback(&rb);
149 IDirect3DSurface8_Release(rt);
150 return ret;
153 static D3DCOLOR get_surface_color(IDirect3DSurface8 *surface, UINT x, UINT y)
155 DWORD color;
156 HRESULT hr;
157 D3DSURFACE_DESC desc;
158 RECT rectToLock = {x, y, x+1, y+1};
159 D3DLOCKED_RECT lockedRect;
161 hr = IDirect3DSurface8_GetDesc(surface, &desc);
162 ok(SUCCEEDED(hr), "Failed to get surface description, hr=%#x.\n", hr);
164 hr = IDirect3DSurface8_LockRect(surface, &lockedRect, &rectToLock, D3DLOCK_READONLY);
165 ok(SUCCEEDED(hr), "Failed to lock surface, hr=%#x.\n", hr);
167 switch(desc.Format)
169 case D3DFMT_A8R8G8B8:
170 color = ((D3DCOLOR *)lockedRect.pBits)[0];
171 break;
173 default:
174 trace("Error: unknown surface format: %u.\n", desc.Format);
175 color = 0xdeadbeef;
176 break;
179 hr = IDirect3DSurface8_UnlockRect(surface);
180 ok(SUCCEEDED(hr), "Failed to unlock surface, hr=%#x.\n", hr);
182 return color;
185 static IDirect3DDevice8 *create_device(IDirect3D8 *d3d, HWND device_window, HWND focus_window, BOOL windowed)
187 D3DPRESENT_PARAMETERS present_parameters = {0};
188 IDirect3DDevice8 *device;
190 present_parameters.Windowed = windowed;
191 present_parameters.hDeviceWindow = device_window;
192 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
193 present_parameters.BackBufferWidth = 640;
194 present_parameters.BackBufferHeight = 480;
195 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
196 present_parameters.EnableAutoDepthStencil = TRUE;
197 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
199 if (SUCCEEDED(IDirect3D8_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, focus_window,
200 D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device)))
201 return device;
203 return NULL;
206 static void test_sanity(void)
208 IDirect3DDevice8 *device;
209 IDirect3D8 *d3d;
210 D3DCOLOR color;
211 ULONG refcount;
212 HWND window;
213 HRESULT hr;
215 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
216 0, 0, 640, 480, NULL, NULL, NULL, NULL);
217 d3d = Direct3DCreate8(D3D_SDK_VERSION);
218 ok(!!d3d, "Failed to create a D3D object.\n");
219 if (!(device = create_device(d3d, window, window, TRUE)))
221 skip("Failed to create a D3D device, skipping tests.\n");
222 goto done;
225 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 1.0f, 0);
226 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
227 color = getPixelColor(device, 1, 1);
228 ok(color == 0x00ff0000, "Got unexpected color 0x%08x.\n", color);
230 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
231 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
233 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ddee, 1.0f, 0);
234 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
235 color = getPixelColor(device, 639, 479);
236 ok(color == 0x0000ddee, "Got unexpected color 0x%08x.\n", color);
238 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
239 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
241 refcount = IDirect3DDevice8_Release(device);
242 ok(!refcount, "Device has %u references left.\n", refcount);
243 done:
244 IDirect3D8_Release(d3d);
245 DestroyWindow(window);
248 static void lighting_test(void)
250 DWORD nfvf = D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_NORMAL;
251 DWORD fvf = D3DFVF_XYZ | D3DFVF_DIFFUSE;
252 IDirect3DDevice8 *device;
253 IDirect3D8 *d3d;
254 D3DCOLOR color;
255 ULONG refcount;
256 HWND window;
257 HRESULT hr;
258 unsigned int i;
260 static const struct
262 struct vec3 position;
263 DWORD diffuse;
265 unlitquad[] =
267 {{-1.0f, -1.0f, 0.1f}, 0xffff0000},
268 {{-1.0f, 0.0f, 0.1f}, 0xffff0000},
269 {{ 0.0f, 0.0f, 0.1f}, 0xffff0000},
270 {{ 0.0f, -1.0f, 0.1f}, 0xffff0000},
272 litquad[] =
274 {{-1.0f, 0.0f, 0.1f}, 0xff00ff00},
275 {{-1.0f, 1.0f, 0.1f}, 0xff00ff00},
276 {{ 0.0f, 1.0f, 0.1f}, 0xff00ff00},
277 {{ 0.0f, 0.0f, 0.1f}, 0xff00ff00},
279 static const struct
281 struct vec3 position;
282 struct vec3 normal;
283 DWORD diffuse;
285 unlitnquad[] =
287 {{0.0f, -1.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xff0000ff},
288 {{0.0f, 0.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xff0000ff},
289 {{1.0f, 0.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xff0000ff},
290 {{1.0f, -1.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xff0000ff},
292 litnquad[] =
294 {{0.0f, 0.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xffffff00},
295 {{0.0f, 1.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xffffff00},
296 {{1.0f, 1.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xffffff00},
297 {{1.0f, 0.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xffffff00},
299 nquad[] =
301 {{-1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
302 {{-1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
303 {{ 1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
304 {{ 1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
306 rotatedquad[] =
308 {{-10.0f, -11.0f, 11.0f}, {-1.0f, 0.0f, 0.0f}, 0xff0000ff},
309 {{-10.0f, -9.0f, 11.0f}, {-1.0f, 0.0f, 0.0f}, 0xff0000ff},
310 {{-10.0f, -9.0f, 9.0f}, {-1.0f, 0.0f, 0.0f}, 0xff0000ff},
311 {{-10.0f, -11.0f, 9.0f}, {-1.0f, 0.0f, 0.0f}, 0xff0000ff},
313 translatedquad[] =
315 {{-11.0f, -11.0f, -10.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
316 {{-11.0f, -9.0f, -10.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
317 {{ -9.0f, -9.0f, -10.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
318 {{ -9.0f, -11.0f, -10.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
320 static const WORD indices[] = {0, 1, 2, 2, 3, 0};
321 static const D3DMATRIX mat =
323 1.0f, 0.0f, 0.0f, 0.0f,
324 0.0f, 1.0f, 0.0f, 0.0f,
325 0.0f, 0.0f, 1.0f, 0.0f,
326 0.0f, 0.0f, 0.0f, 1.0f,
327 }}},
328 mat_singular =
330 1.0f, 0.0f, 1.0f, 0.0f,
331 0.0f, 1.0f, 0.0f, 0.0f,
332 1.0f, 0.0f, 1.0f, 0.0f,
333 0.0f, 0.0f, 0.5f, 1.0f,
334 }}},
335 mat_transf =
337 0.0f, 0.0f, 1.0f, 0.0f,
338 0.0f, 1.0f, 0.0f, 0.0f,
339 -1.0f, 0.0f, 0.0f, 0.0f,
340 10.f, 10.0f, 10.0f, 1.0f,
341 }}},
342 mat_nonaffine =
344 1.0f, 0.0f, 0.0f, 0.0f,
345 0.0f, 1.0f, 0.0f, 0.0f,
346 0.0f, 0.0f, 1.0f, -1.0f,
347 10.f, 10.0f, 10.0f, 0.0f,
348 }}};
349 static const struct
351 const D3DMATRIX *world_matrix;
352 const void *quad;
353 unsigned int size;
354 DWORD expected;
355 const char *message;
357 tests[] =
359 {&mat, nquad, sizeof(nquad[0]), 0x000000ff, "Lit quad with light"},
360 {&mat_singular, nquad, sizeof(nquad[0]), 0x000000ff, "Lit quad with singular world matrix"},
361 {&mat_transf, rotatedquad, sizeof(rotatedquad[0]), 0x000000ff, "Lit quad with transformation matrix"},
362 {&mat_nonaffine, translatedquad, sizeof(translatedquad[0]), 0x00000000, "Lit quad with non-affine matrix"},
365 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
366 0, 0, 640, 480, NULL, NULL, NULL, NULL);
367 d3d = Direct3DCreate8(D3D_SDK_VERSION);
368 ok(!!d3d, "Failed to create a D3D object.\n");
369 if (!(device = create_device(d3d, window, window, TRUE)))
371 skip("Failed to create a D3D device, skipping tests.\n");
372 goto done;
375 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
376 ok(hr == D3D_OK, "IDirect3DDevice8_Clear failed with %#08x\n", hr);
378 hr = IDirect3DDevice8_SetTransform(device, D3DTS_WORLDMATRIX(0), &mat);
379 ok(hr == D3D_OK, "IDirect3DDevice8_SetTransform returned %#08x\n", hr);
380 hr = IDirect3DDevice8_SetTransform(device, D3DTS_VIEW, &mat);
381 ok(hr == D3D_OK, "IDirect3DDevice8_SetTransform returned %#08x\n", hr);
382 hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, &mat);
383 ok(hr == D3D_OK, "IDirect3DDevice8_SetTransform returned %#08x\n", hr);
384 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, FALSE);
385 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %#08x\n", hr);
386 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, FALSE);
387 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %#08x\n", hr);
388 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
389 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %#08x\n", hr);
390 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
391 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %#08x\n", hr);
392 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
393 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed with %#08x\n", hr);
395 hr = IDirect3DDevice8_SetVertexShader(device, fvf);
396 ok(hr == D3D_OK, "IDirect3DDevice8_SetVertexShader returned %#08x\n", hr);
398 hr = IDirect3DDevice8_BeginScene(device);
399 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
401 /* No lights are defined... That means, lit vertices should be entirely black. */
402 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
403 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
404 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
405 2, indices, D3DFMT_INDEX16, unlitquad, sizeof(unlitquad[0]));
406 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
408 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, TRUE);
409 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
410 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
411 2, indices, D3DFMT_INDEX16, litquad, sizeof(litquad[0]));
412 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
414 hr = IDirect3DDevice8_SetVertexShader(device, nfvf);
415 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
417 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
418 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
419 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
420 2, indices, D3DFMT_INDEX16, unlitnquad, sizeof(unlitnquad[0]));
421 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
423 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, TRUE);
424 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
425 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
426 2, indices, D3DFMT_INDEX16, litnquad, sizeof(litnquad[0]));
427 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
429 hr = IDirect3DDevice8_EndScene(device);
430 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
432 color = getPixelColor(device, 160, 360); /* Lower left quad - unlit without normals */
433 ok(color == 0x00ff0000, "Unlit quad without normals has color 0x%08x, expected 0x00ff0000.\n", color);
434 color = getPixelColor(device, 160, 120); /* Upper left quad - lit without normals */
435 ok(color == 0x00000000, "Lit quad without normals has color 0x%08x, expected 0x00000000.\n", color);
436 color = getPixelColor(device, 480, 360); /* Lower right quad - unlit with normals */
437 ok(color == 0x000000ff, "Unlit quad with normals has color 0x%08x, expected 0x000000ff.\n", color);
438 color = getPixelColor(device, 480, 120); /* Upper right quad - lit with normals */
439 ok(color == 0x00000000, "Lit quad with normals has color 0x%08x, expected 0x00000000.\n", color);
441 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
443 hr = IDirect3DDevice8_LightEnable(device, 0, TRUE);
444 ok(SUCCEEDED(hr), "Failed to enable light 0, hr %#x.\n", hr);
446 for (i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i)
448 hr = IDirect3DDevice8_SetTransform(device, D3DTS_WORLD, tests[i].world_matrix);
449 ok(SUCCEEDED(hr), "Failed to set world transform, hr %#x.\n", hr);
451 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
452 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
454 hr = IDirect3DDevice8_BeginScene(device);
455 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
457 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
458 2, indices, D3DFMT_INDEX16, tests[i].quad, tests[i].size);
459 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
461 hr = IDirect3DDevice8_EndScene(device);
462 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
464 color = getPixelColor(device, 320, 240);
465 ok(color == tests[i].expected, "%s has color 0x%08x.\n", tests[i].message, color);
468 refcount = IDirect3DDevice8_Release(device);
469 ok(!refcount, "Device has %u references left.\n", refcount);
470 done:
471 IDirect3D8_Release(d3d);
472 DestroyWindow(window);
475 static void test_specular_lighting(void)
477 static const unsigned int vertices_side = 5;
478 const unsigned int indices_count = (vertices_side - 1) * (vertices_side - 1) * 2 * 3;
479 static const DWORD fvf = D3DFVF_XYZ | D3DFVF_NORMAL;
480 static const D3DMATRIX mat =
482 1.0f, 0.0f, 0.0f, 0.0f,
483 0.0f, 1.0f, 0.0f, 0.0f,
484 0.0f, 0.0f, 1.0f, 0.0f,
485 0.0f, 0.0f, 0.0f, 1.0f,
486 }}};
487 static const D3DLIGHT8 directional =
489 D3DLIGHT_DIRECTIONAL,
490 {0.0f, 0.0f, 0.0f, 0.0f},
491 {1.0f, 1.0f, 1.0f, 0.0f},
492 {0.0f, 0.0f, 0.0f, 0.0f},
493 {0.0f, 0.0f, 0.0f},
494 {0.0f, 0.0f, 1.0f},
496 point =
498 D3DLIGHT_POINT,
499 {0.0f, 0.0f, 0.0f, 0.0f},
500 {1.0f, 1.0f, 1.0f, 0.0f},
501 {0.0f, 0.0f, 0.0f, 0.0f},
502 {0.0f, 0.0f, 0.0f},
503 {0.0f, 0.0f, 0.0f},
504 100.0f,
505 0.0f,
506 0.0f, 0.0f, 1.0f,
508 spot =
510 D3DLIGHT_SPOT,
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, 1.0f},
516 100.0f,
517 1.0f,
518 0.0f, 0.0f, 1.0f,
519 M_PI / 12.0f, M_PI / 3.0f
521 /* The chosen range value makes the test fail when using a manhattan
522 * distance metric vs the correct euclidean distance. */
523 point_range =
525 D3DLIGHT_POINT,
526 {0.0f, 0.0f, 0.0f, 0.0f},
527 {1.0f, 1.0f, 1.0f, 0.0f},
528 {0.0f, 0.0f, 0.0f, 0.0f},
529 {0.0f, 0.0f, 0.0f},
530 {0.0f, 0.0f, 0.0f},
531 1.2f,
532 0.0f,
533 0.0f, 0.0f, 1.0f,
535 static const struct expected_color
537 unsigned int x, y;
538 D3DCOLOR color;
540 expected_directional[] =
542 {160, 120, 0x00ffffff},
543 {320, 120, 0x00ffffff},
544 {480, 120, 0x00ffffff},
545 {160, 240, 0x00ffffff},
546 {320, 240, 0x00ffffff},
547 {480, 240, 0x00ffffff},
548 {160, 360, 0x00ffffff},
549 {320, 360, 0x00ffffff},
550 {480, 360, 0x00ffffff},
552 expected_directional_local[] =
554 {160, 120, 0x003c3c3c},
555 {320, 120, 0x00717171},
556 {480, 120, 0x003c3c3c},
557 {160, 240, 0x00717171},
558 {320, 240, 0x00ffffff},
559 {480, 240, 0x00717171},
560 {160, 360, 0x003c3c3c},
561 {320, 360, 0x00717171},
562 {480, 360, 0x003c3c3c},
564 expected_point[] =
566 {160, 120, 0x00282828},
567 {320, 120, 0x005a5a5a},
568 {480, 120, 0x00282828},
569 {160, 240, 0x005a5a5a},
570 {320, 240, 0x00ffffff},
571 {480, 240, 0x005a5a5a},
572 {160, 360, 0x00282828},
573 {320, 360, 0x005a5a5a},
574 {480, 360, 0x00282828},
576 expected_point_local[] =
578 {160, 120, 0x00000000},
579 {320, 120, 0x00070707},
580 {480, 120, 0x00000000},
581 {160, 240, 0x00070707},
582 {320, 240, 0x00ffffff},
583 {480, 240, 0x00070707},
584 {160, 360, 0x00000000},
585 {320, 360, 0x00070707},
586 {480, 360, 0x00000000},
588 expected_spot[] =
590 {160, 120, 0x00000000},
591 {320, 120, 0x00141414},
592 {480, 120, 0x00000000},
593 {160, 240, 0x00141414},
594 {320, 240, 0x00ffffff},
595 {480, 240, 0x00141414},
596 {160, 360, 0x00000000},
597 {320, 360, 0x00141414},
598 {480, 360, 0x00000000},
600 expected_spot_local[] =
602 {160, 120, 0x00000000},
603 {320, 120, 0x00020202},
604 {480, 120, 0x00000000},
605 {160, 240, 0x00020202},
606 {320, 240, 0x00ffffff},
607 {480, 240, 0x00020202},
608 {160, 360, 0x00000000},
609 {320, 360, 0x00020202},
610 {480, 360, 0x00000000},
612 expected_point_range[] =
614 {160, 120, 0x00000000},
615 {320, 120, 0x005a5a5a},
616 {480, 120, 0x00000000},
617 {160, 240, 0x005a5a5a},
618 {320, 240, 0x00ffffff},
619 {480, 240, 0x005a5a5a},
620 {160, 360, 0x00000000},
621 {320, 360, 0x005a5a5a},
622 {480, 360, 0x00000000},
624 static const struct
626 const D3DLIGHT8 *light;
627 BOOL local_viewer;
628 const struct expected_color *expected;
629 unsigned int expected_count;
631 tests[] =
633 {&directional, FALSE, expected_directional,
634 sizeof(expected_directional) / sizeof(expected_directional[0])},
635 {&directional, TRUE, expected_directional_local,
636 sizeof(expected_directional_local) / sizeof(expected_directional_local[0])},
637 {&point, FALSE, expected_point,
638 sizeof(expected_point) / sizeof(expected_point[0])},
639 {&point, TRUE, expected_point_local,
640 sizeof(expected_point_local) / sizeof(expected_point_local[0])},
641 {&spot, FALSE, expected_spot,
642 sizeof(expected_spot) / sizeof(expected_spot[0])},
643 {&spot, TRUE, expected_spot_local,
644 sizeof(expected_spot_local) / sizeof(expected_spot_local[0])},
645 {&point_range, FALSE, expected_point_range,
646 sizeof(expected_point_range) / sizeof(expected_point_range[0])},
648 IDirect3DDevice8 *device;
649 D3DMATERIAL8 material;
650 IDirect3D8 *d3d;
651 D3DCOLOR color;
652 ULONG refcount;
653 HWND window;
654 HRESULT hr;
655 unsigned int i, j, x, y;
656 struct
658 struct vec3 position;
659 struct vec3 normal;
660 } *quad;
661 WORD *indices;
663 quad = HeapAlloc(GetProcessHeap(), 0, vertices_side * vertices_side * sizeof(*quad));
664 indices = HeapAlloc(GetProcessHeap(), 0, indices_count * sizeof(*indices));
665 for (i = 0, y = 0; y < vertices_side; ++y)
667 for (x = 0; x < vertices_side; ++x)
669 quad[i].position.x = x * 2.0f / (vertices_side - 1) - 1.0f;
670 quad[i].position.y = y * 2.0f / (vertices_side - 1) - 1.0f;
671 quad[i].position.z = 1.0f;
672 quad[i].normal.x = 0.0f;
673 quad[i].normal.y = 0.0f;
674 quad[i++].normal.z = -1.0f;
677 for (i = 0, y = 0; y < (vertices_side - 1); ++y)
679 for (x = 0; x < (vertices_side - 1); ++x)
681 indices[i++] = y * vertices_side + x + 1;
682 indices[i++] = y * vertices_side + x;
683 indices[i++] = (y + 1) * vertices_side + x;
684 indices[i++] = y * vertices_side + x + 1;
685 indices[i++] = (y + 1) * vertices_side + x;
686 indices[i++] = (y + 1) * vertices_side + x + 1;
690 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
691 0, 0, 640, 480, NULL, NULL, NULL, NULL);
692 d3d = Direct3DCreate8(D3D_SDK_VERSION);
693 ok(!!d3d, "Failed to create a D3D object.\n");
694 if (!(device = create_device(d3d, window, window, TRUE)))
696 skip("Failed to create a D3D device, skipping tests.\n");
697 goto done;
700 hr = IDirect3DDevice8_SetTransform(device, D3DTS_WORLD, &mat);
701 ok(SUCCEEDED(hr), "Failed to set world transform, hr %#x.\n", hr);
702 hr = IDirect3DDevice8_SetTransform(device, D3DTS_VIEW, &mat);
703 ok(SUCCEEDED(hr), "Failed to set view transform, hr %#x.\n", hr);
704 hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, &mat);
705 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
706 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, FALSE);
707 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#x.\n", hr);
708 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, FALSE);
709 ok(SUCCEEDED(hr), "Failed to disable z test, hr %#x.\n", hr);
710 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
711 ok(SUCCEEDED(hr), "Failed to disable fog, hr %#x.\n", hr);
713 hr = IDirect3DDevice8_SetVertexShader(device, fvf);
714 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
716 memset(&material, 0, sizeof(material));
717 material.Specular.r = 1.0f;
718 material.Specular.g = 1.0f;
719 material.Specular.b = 1.0f;
720 material.Specular.a = 1.0f;
721 material.Power = 30.0f;
722 hr = IDirect3DDevice8_SetMaterial(device, &material);
723 ok(SUCCEEDED(hr), "Failed to set material, hr %#x.\n", hr);
725 hr = IDirect3DDevice8_LightEnable(device, 0, TRUE);
726 ok(SUCCEEDED(hr), "Failed to enable light 0, hr %#x.\n", hr);
727 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SPECULARENABLE, TRUE);
728 ok(SUCCEEDED(hr), "Failed to enable specular lighting, hr %#x.\n", hr);
730 for (i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i)
732 hr = IDirect3DDevice8_SetLight(device, 0, tests[i].light);
733 ok(SUCCEEDED(hr), "Failed to set light parameters, hr %#x.\n", hr);
735 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LOCALVIEWER, tests[i].local_viewer);
736 ok(SUCCEEDED(hr), "Failed to set local viewer state, hr %#x.\n", hr);
738 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
739 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
741 hr = IDirect3DDevice8_BeginScene(device);
742 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
744 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST,
745 0, vertices_side * vertices_side, indices_count / 3, indices,
746 D3DFMT_INDEX16, quad, sizeof(quad[0]));
747 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
749 hr = IDirect3DDevice8_EndScene(device);
750 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
752 for (j = 0; j < tests[i].expected_count; ++j)
754 color = getPixelColor(device, tests[i].expected[j].x, tests[i].expected[j].y);
755 ok(color_match(color, tests[i].expected[j].color, 1),
756 "Expected color 0x%08x at location (%u, %u), got 0x%08x, case %u.\n",
757 tests[i].expected[j].color, tests[i].expected[j].x,
758 tests[i].expected[j].y, color, i);
762 refcount = IDirect3DDevice8_Release(device);
763 ok(!refcount, "Device has %u references left.\n", refcount);
764 done:
765 IDirect3D8_Release(d3d);
766 DestroyWindow(window);
767 HeapFree(GetProcessHeap(), 0, indices);
768 HeapFree(GetProcessHeap(), 0, quad);
771 static void clear_test(void)
773 /* Tests the correctness of clearing parameters */
774 D3DRECT rect_negneg, rect[2];
775 IDirect3DDevice8 *device;
776 IDirect3D8 *d3d;
777 D3DCOLOR color;
778 ULONG refcount;
779 HWND window;
780 HRESULT hr;
782 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
783 0, 0, 640, 480, NULL, NULL, NULL, NULL);
784 d3d = Direct3DCreate8(D3D_SDK_VERSION);
785 ok(!!d3d, "Failed to create a D3D object.\n");
786 if (!(device = create_device(d3d, window, window, TRUE)))
788 skip("Failed to create a D3D device, skipping tests.\n");
789 goto done;
792 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
793 ok(hr == D3D_OK, "IDirect3DDevice8_Clear failed with %#08x\n", hr);
795 /* Positive x, negative y */
796 rect[0].x1 = 0;
797 rect[0].y1 = 480;
798 rect[0].x2 = 320;
799 rect[0].y2 = 240;
801 /* Positive x, positive y */
802 rect[1].x1 = 0;
803 rect[1].y1 = 0;
804 rect[1].x2 = 320;
805 rect[1].y2 = 240;
806 /* Clear 2 rectangles with one call. Shows that a positive value is returned, but the negative rectangle
807 * is ignored, the positive is still cleared afterwards
809 hr = IDirect3DDevice8_Clear(device, 2, rect, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
810 ok(hr == D3D_OK, "IDirect3DDevice8_Clear failed with %#08x\n", hr);
812 /* negative x, negative y */
813 rect_negneg.x1 = 640;
814 rect_negneg.y1 = 240;
815 rect_negneg.x2 = 320;
816 rect_negneg.y2 = 0;
817 hr = IDirect3DDevice8_Clear(device, 1, &rect_negneg, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
818 ok(hr == D3D_OK, "IDirect3DDevice8_Clear failed with %#08x\n", hr);
820 color = getPixelColor(device, 160, 360); /* lower left quad */
821 ok(color == 0x00ffffff, "Clear rectangle 3(pos, neg) has color %08x\n", color);
822 color = getPixelColor(device, 160, 120); /* upper left quad */
823 ok(color == 0x00ff0000, "Clear rectangle 1(pos, pos) has color %08x\n", color);
824 color = getPixelColor(device, 480, 360); /* lower right quad */
825 ok(color == 0x00ffffff, "Clear rectangle 4(NULL) has color %08x\n", color);
826 color = getPixelColor(device, 480, 120); /* upper right quad */
827 ok(color == 0x00ffffff, "Clear rectangle 4(neg, neg) has color %08x\n", color);
829 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
831 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
832 ok(SUCCEEDED(hr), "IDirect3DDevice8_Clear failed with %#08x\n", hr);
834 rect[0].x1 = 0;
835 rect[0].y1 = 0;
836 rect[0].x2 = 640;
837 rect[0].y2 = 480;
838 hr = IDirect3DDevice8_Clear(device, 0, rect, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
839 ok(SUCCEEDED(hr), "IDirect3DDevice8_Clear failed with %#08x\n", hr);
841 color = getPixelColor(device, 320, 240);
842 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff), 1),
843 "Clear with count = 0, rect != NULL has color %#08x\n", color);
845 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
847 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
848 ok(SUCCEEDED(hr), "IDirect3DDevice8_Clear failed with %#08x\n", hr);
849 hr = IDirect3DDevice8_Clear(device, 1, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
850 ok(SUCCEEDED(hr), "IDirect3DDevice8_Clear failed with %#08x\n", hr);
852 color = getPixelColor(device, 320, 240);
853 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
854 "Clear with count = 1, rect = NULL has color %#08x\n", color);
856 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
858 refcount = IDirect3DDevice8_Release(device);
859 ok(!refcount, "Device has %u references left.\n", refcount);
860 done:
861 IDirect3D8_Release(d3d);
862 DestroyWindow(window);
865 static void fog_test(void)
867 float start = 0.0f, end = 1.0f;
868 IDirect3DDevice8 *device;
869 IDirect3D8 *d3d;
870 D3DCOLOR color;
871 ULONG refcount;
872 D3DCAPS8 caps;
873 HWND window;
874 HRESULT hr;
876 /* Gets full z based fog with linear fog, no fog with specular color. */
877 static const struct
879 float x, y, z;
880 D3DCOLOR diffuse;
881 D3DCOLOR specular;
883 untransformed_1[] =
885 {-1.0f, -1.0f, 0.1f, 0xffff0000, 0xff000000},
886 {-1.0f, 0.0f, 0.1f, 0xffff0000, 0xff000000},
887 { 0.0f, 0.0f, 0.1f, 0xffff0000, 0xff000000},
888 { 0.0f, -1.0f, 0.1f, 0xffff0000, 0xff000000},
890 /* Ok, I am too lazy to deal with transform matrices. */
891 untransformed_2[] =
893 {-1.0f, 0.0f, 1.0f, 0xffff0000, 0xff000000},
894 {-1.0f, 1.0f, 1.0f, 0xffff0000, 0xff000000},
895 { 0.0f, 1.0f, 1.0f, 0xffff0000, 0xff000000},
896 { 0.0f, 0.0f, 1.0f, 0xffff0000, 0xff000000},
898 far_quad1[] =
900 {-1.0f, -1.0f, 0.5f, 0xffff0000, 0xff000000},
901 {-1.0f, 0.0f, 0.5f, 0xffff0000, 0xff000000},
902 { 0.0f, 0.0f, 0.5f, 0xffff0000, 0xff000000},
903 { 0.0f, -1.0f, 0.5f, 0xffff0000, 0xff000000},
905 far_quad2[] =
907 {-1.0f, 0.0f, 1.5f, 0xffff0000, 0xff000000},
908 {-1.0f, 1.0f, 1.5f, 0xffff0000, 0xff000000},
909 { 0.0f, 1.0f, 1.5f, 0xffff0000, 0xff000000},
910 { 0.0f, 0.0f, 1.5f, 0xffff0000, 0xff000000},
913 /* Untransformed ones. Give them a different diffuse color to make the
914 * test look nicer. It also makes making sure that they are drawn
915 * correctly easier. */
916 static const struct
918 float x, y, z, rhw;
919 D3DCOLOR diffuse;
920 D3DCOLOR specular;
922 transformed_1[] =
924 {320.0f, 0.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
925 {640.0f, 0.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
926 {640.0f, 240.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
927 {320.0f, 240.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
929 transformed_2[] =
931 {320.0f, 240.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
932 {640.0f, 240.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
933 {640.0f, 480.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
934 {320.0f, 480.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
936 static const D3DMATRIX ident_mat =
938 1.0f, 0.0f, 0.0f, 0.0f,
939 0.0f, 1.0f, 0.0f, 0.0f,
940 0.0f, 0.0f, 1.0f, 0.0f,
941 0.0f, 0.0f, 0.0f, 1.0f,
942 }}};
943 static const D3DMATRIX world_mat1 =
945 1.0f, 0.0f, 0.0f, 0.0f,
946 0.0f, 1.0f, 0.0f, 0.0f,
947 0.0f, 0.0f, 1.0f, 0.0f,
948 0.0f, 0.0f, -0.5f, 1.0f,
949 }}};
950 static const D3DMATRIX world_mat2 =
952 1.0f, 0.0f, 0.0f, 0.0f,
953 0.0f, 1.0f, 0.0f, 0.0f,
954 0.0f, 0.0f, 1.0f, 0.0f,
955 0.0f, 0.0f, 1.0f, 1.0f,
956 }}};
957 static const D3DMATRIX proj_mat =
959 1.0f, 0.0f, 0.0f, 0.0f,
960 0.0f, 1.0f, 0.0f, 0.0f,
961 0.0f, 0.0f, 1.0f, 0.0f,
962 0.0f, 0.0f, -1.0f, 1.0f,
963 }}};
964 static const WORD Indices[] = {0, 1, 2, 2, 3, 0};
966 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
967 0, 0, 640, 480, NULL, NULL, NULL, NULL);
968 d3d = Direct3DCreate8(D3D_SDK_VERSION);
969 ok(!!d3d, "Failed to create a D3D object.\n");
970 if (!(device = create_device(d3d, window, window, TRUE)))
972 skip("Failed to create a D3D device, skipping tests.\n");
973 goto done;
976 memset(&caps, 0, sizeof(caps));
977 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
978 ok(hr == D3D_OK, "IDirect3DDevice8_GetDeviceCaps returned %08x\n", hr);
979 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
980 ok(hr == D3D_OK, "IDirect3DDevice8_Clear returned %#08x\n", hr);
982 /* Setup initial states: No lighting, fog on, fog color */
983 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, FALSE);
984 ok(SUCCEEDED(hr), "Failed to disable D3DRS_ZENABLE, hr %#x.\n", hr);
985 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
986 ok(hr == D3D_OK, "Turning off lighting returned %#08x\n", hr);
987 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
988 ok(hr == D3D_OK, "Turning on fog calculations returned %#08x\n", hr);
989 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
990 ok(hr == D3D_OK, "Setting fog color returned %#08x\n", hr);
991 /* Some of the tests seem to depend on the projection matrix explicitly
992 * being set to an identity matrix, even though that's the default.
993 * (AMD Radeon HD 6310, Windows 7) */
994 hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, &ident_mat);
995 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
997 /* First test: Both table fog and vertex fog off */
998 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
999 ok(hr == D3D_OK, "Turning off table fog returned %#08x\n", hr);
1000 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
1001 ok(hr == D3D_OK, "Turning off vertex fog returned %#08x\n", hr);
1003 /* Start = 0, end = 1. Should be default, but set them */
1004 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1005 ok(hr == D3D_OK, "Setting fog start returned %#08x\n", hr);
1006 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1007 ok(hr == D3D_OK, "Setting fog start returned %#08x\n", hr);
1009 hr = IDirect3DDevice8_BeginScene(device);
1010 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
1012 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1013 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
1014 /* Untransformed, vertex fog = NONE, table fog = NONE:
1015 * Read the fog weighting from the specular color. */
1016 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1017 2 /* PrimCount */, Indices, D3DFMT_INDEX16, untransformed_1, sizeof(untransformed_1[0]));
1018 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1020 /* This makes it use the Z value. */
1021 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1022 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
1023 /* Untransformed, vertex fog != none (or table fog != none):
1024 * Use the Z value as input into the equation. */
1025 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1026 2 /* PrimCount */, Indices, D3DFMT_INDEX16, untransformed_2, sizeof(untransformed_2[0]));
1027 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1029 /* Transformed vertices. */
1030 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1031 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
1032 /* Transformed, vertex fog != NONE, pixel fog == NONE:
1033 * Use specular color alpha component. */
1034 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1035 2 /* PrimCount */, Indices, D3DFMT_INDEX16, transformed_1, sizeof(transformed_1[0]));
1036 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1038 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
1039 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
1040 /* Transformed, table fog != none, vertex anything:
1041 * Use Z value as input to the fog equation. */
1042 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1043 2 /* PrimCount */, Indices, D3DFMT_INDEX16, transformed_2, sizeof(transformed_2[0]));
1044 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1046 hr = IDirect3DDevice8_EndScene(device);
1047 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
1049 color = getPixelColor(device, 160, 360);
1050 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xFF, 0x00, 0x00), 1),
1051 "Untransformed vertex with no table or vertex fog has color %08x\n", color);
1052 color = getPixelColor(device, 160, 120);
1053 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xFF, 0x00), 1),
1054 "Untransformed vertex with linear vertex fog has color %08x\n", color);
1055 color = getPixelColor(device, 480, 120);
1056 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xFF, 0xFF, 0x00), 1),
1057 "Transformed vertex with linear vertex fog has color %08x\n", color);
1058 color = getPixelColor(device, 480, 360);
1059 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xFF, 0x00), 1),
1060 "Transformed vertex with linear table fog has color %08x\n", color);
1062 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
1064 if (caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)
1066 /* A simple fog + non-identity world matrix test */
1067 hr = IDirect3DDevice8_SetTransform(device, D3DTS_WORLDMATRIX(0), &world_mat1);
1068 ok(hr == D3D_OK, "IDirect3DDevice8_SetTransform returned %#08x\n", hr);
1070 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
1071 ok(hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %#08x\n", hr);
1072 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
1073 ok(hr == D3D_OK, "Turning off vertex fog returned %#08x\n", hr);
1075 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1076 ok(hr == D3D_OK, "IDirect3DDevice8_Clear returned %#08x\n", hr);
1078 hr = IDirect3DDevice8_BeginScene(device);
1079 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
1080 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1081 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
1082 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
1083 2, Indices, D3DFMT_INDEX16, far_quad1, sizeof(far_quad1[0]));
1084 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1085 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
1086 2, Indices, D3DFMT_INDEX16, far_quad2, sizeof(far_quad2[0]));
1087 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1088 hr = IDirect3DDevice8_EndScene(device);
1089 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
1091 color = getPixelColor(device, 160, 360);
1092 ok(color_match(color, 0x00ff0000, 4), "Unfogged quad has color %08x\n", color);
1093 color = getPixelColor(device, 160, 120);
1094 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
1095 "Fogged out quad has color %08x\n", color);
1097 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
1099 /* Test fog behavior with an orthogonal (but not identity) projection matrix */
1100 hr = IDirect3DDevice8_SetTransform(device, D3DTS_WORLDMATRIX(0), &world_mat2);
1101 ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
1102 hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, &proj_mat);
1103 ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
1105 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1106 ok(hr == D3D_OK, "Clear returned %#08x\n", hr);
1108 hr = IDirect3DDevice8_BeginScene(device);
1109 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
1110 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1111 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
1112 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
1113 2, Indices, D3DFMT_INDEX16, untransformed_1, sizeof(untransformed_1[0]));
1114 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1115 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
1116 2, Indices, D3DFMT_INDEX16, untransformed_2, sizeof(untransformed_2[0]));
1117 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1118 hr = IDirect3DDevice8_EndScene(device);
1119 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
1121 color = getPixelColor(device, 160, 360);
1122 ok(color_match(color, 0x00e51900, 4), "Partially fogged quad has color %08x\n", color);
1123 color = getPixelColor(device, 160, 120);
1124 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
1125 "Fogged out quad has color %08x\n", color);
1127 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
1129 else
1131 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping some fog tests\n");
1134 refcount = IDirect3DDevice8_Release(device);
1135 ok(!refcount, "Device has %u references left.\n", refcount);
1136 done:
1137 IDirect3D8_Release(d3d);
1138 DestroyWindow(window);
1141 /* This tests fog in combination with shaders.
1142 * What's tested: linear fog (vertex and table) with pixel shader
1143 * linear table fog with non foggy vertex shader
1144 * vertex fog with foggy vertex shader, non-linear
1145 * fog with shader, non-linear fog with foggy shader,
1146 * linear table fog with foggy shader */
1147 static void fog_with_shader_test(void)
1149 /* Fill the null-shader entry with the FVF (SetVertexShader is "overloaded" on d3d8...) */
1150 DWORD vertex_shader[3] = {D3DFVF_XYZ | D3DFVF_DIFFUSE, 0, 0};
1151 DWORD pixel_shader[2] = {0, 0};
1152 IDirect3DDevice8 *device;
1153 unsigned int i, j;
1154 IDirect3D8 *d3d;
1155 D3DCOLOR color;
1156 ULONG refcount;
1157 D3DCAPS8 caps;
1158 HWND window;
1159 HRESULT hr;
1160 union
1162 float f;
1163 DWORD i;
1164 } start, end;
1166 /* Basic vertex shader without fog computation ("non foggy") */
1167 static const DWORD vertex_shader_code1[] =
1169 0xfffe0100, /* vs.1.0 */
1170 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1171 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
1172 0x0000ffff
1174 /* Basic vertex shader with reversed fog computation ("foggy") */
1175 static const DWORD vertex_shader_code2[] =
1177 0xfffe0100, /* vs.1.0 */
1178 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1179 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
1180 0x00000002, 0x800f0000, 0x90aa0000, 0xa0aa0000, /* add r0, v0.z, c0.z */
1181 0x00000005, 0xc00f0001, 0x80000000, 0xa0000000, /* mul oFog, r0.x, c0.x */
1182 0x0000ffff
1184 /* Basic pixel shader */
1185 static const DWORD pixel_shader_code[] =
1187 0xffff0101, /* ps_1_1 */
1188 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
1189 0x0000ffff
1191 static struct
1193 struct vec3 position;
1194 DWORD diffuse;
1196 quad[] =
1198 {{-1.0f, -1.0f, 0.0f}, 0xffff0000},
1199 {{-1.0f, 1.0f, 0.0f}, 0xffff0000},
1200 {{ 1.0f, -1.0f, 0.0f}, 0xffff0000},
1201 {{ 1.0f, 1.0f, 0.0f}, 0xffff0000},
1203 static const DWORD decl[] =
1205 D3DVSD_STREAM(0),
1206 D3DVSD_REG(0, D3DVSDT_FLOAT3), /* position, v0 */
1207 D3DVSD_REG(1, D3DVSDT_D3DCOLOR), /* diffuse color, v1 */
1208 D3DVSD_END()
1210 static const float vs_constant[4] = {-1.25f, 0.0f, -0.9f, 0.0f};
1211 /* This reference data was collected on a nVidia GeForce 7600GS
1212 * driver version 84.19 DirectX version 9.0c on Windows XP */
1213 static const struct test_data_t
1215 int vshader;
1216 int pshader;
1217 D3DFOGMODE vfog;
1218 D3DFOGMODE tfog;
1219 BOOL uninitialized_reg;
1220 unsigned int color[11];
1222 test_data[] =
1224 /* Only pixel shader */
1225 {0, 1, D3DFOG_NONE, D3DFOG_LINEAR, FALSE,
1226 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1227 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1228 {0, 1, D3DFOG_EXP, D3DFOG_LINEAR, FALSE,
1229 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1230 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1231 {0, 1, D3DFOG_EXP2, D3DFOG_LINEAR, FALSE,
1232 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1233 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1234 {0, 1, D3DFOG_LINEAR, D3DFOG_NONE, FALSE,
1235 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1236 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1237 {0, 1, D3DFOG_LINEAR, D3DFOG_LINEAR, FALSE,
1238 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1239 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1241 /* Vertex shader */
1242 {1, 0, D3DFOG_NONE, D3DFOG_NONE, TRUE,
1243 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1244 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1245 {1, 0, D3DFOG_NONE, D3DFOG_LINEAR, FALSE,
1246 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1247 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1248 {1, 0, D3DFOG_EXP, D3DFOG_LINEAR, FALSE,
1249 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1250 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1252 {1, 0, D3DFOG_EXP2, D3DFOG_LINEAR, FALSE,
1253 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1254 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1255 {1, 0, D3DFOG_LINEAR, D3DFOG_LINEAR, FALSE,
1256 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1257 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1259 /* Vertex shader and pixel shader */
1260 /* The next 4 tests would read the fog coord output, but it isn't available.
1261 * The result is a fully fogged quad, no matter what the Z coord is. */
1262 {1, 1, D3DFOG_NONE, D3DFOG_NONE, TRUE,
1263 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1264 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1265 {1, 1, D3DFOG_LINEAR, D3DFOG_NONE, TRUE,
1266 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1267 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1268 {1, 1, D3DFOG_EXP, D3DFOG_NONE, TRUE,
1269 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1270 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1271 {1, 1, D3DFOG_EXP2, D3DFOG_NONE, TRUE,
1272 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1273 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1275 /* These use the Z coordinate with linear table fog */
1276 {1, 1, D3DFOG_NONE, D3DFOG_LINEAR, FALSE,
1277 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1278 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1279 {1, 1, D3DFOG_EXP, D3DFOG_LINEAR, FALSE,
1280 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1281 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1282 {1, 1, D3DFOG_EXP2, D3DFOG_LINEAR, FALSE,
1283 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1284 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1285 {1, 1, D3DFOG_LINEAR, D3DFOG_LINEAR, FALSE,
1286 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1287 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1289 /* Non-linear table fog without fog coord */
1290 {1, 1, D3DFOG_NONE, D3DFOG_EXP, FALSE,
1291 {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
1292 0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
1293 {1, 1, D3DFOG_NONE, D3DFOG_EXP2, FALSE,
1294 {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
1295 0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
1297 /* These tests fail on older Nvidia drivers */
1298 /* Foggy vertex shader */
1299 {2, 0, D3DFOG_NONE, D3DFOG_NONE, FALSE,
1300 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1301 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1302 {2, 0, D3DFOG_EXP, D3DFOG_NONE, FALSE,
1303 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1304 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1305 {2, 0, D3DFOG_EXP2, D3DFOG_NONE, FALSE,
1306 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1307 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1308 {2, 0, D3DFOG_LINEAR, D3DFOG_NONE, FALSE,
1309 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1310 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1312 /* Foggy vertex shader and pixel shader. First 4 tests with vertex fog,
1313 * all using the fixed fog-coord linear fog */
1314 {2, 1, D3DFOG_NONE, D3DFOG_NONE, FALSE,
1315 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1316 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1317 {2, 1, D3DFOG_EXP, D3DFOG_NONE, FALSE,
1318 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1319 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1320 {2, 1, D3DFOG_EXP2, D3DFOG_NONE, FALSE,
1321 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1322 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1323 {2, 1, D3DFOG_LINEAR, D3DFOG_NONE, FALSE,
1324 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1325 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1327 /* These use table fog. Here the shader-provided fog coordinate is
1328 * ignored and the z coordinate used instead */
1329 {2, 1, D3DFOG_NONE, D3DFOG_EXP, FALSE,
1330 {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
1331 0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
1332 {2, 1, D3DFOG_NONE, D3DFOG_EXP2, FALSE,
1333 {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
1334 0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
1335 {2, 1, D3DFOG_NONE, D3DFOG_LINEAR, FALSE,
1336 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1337 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1339 static const D3DMATRIX identity =
1341 1.0f, 0.0f, 0.0f, 0.0f,
1342 0.0f, 1.0f, 0.0f, 0.0f,
1343 0.0f, 0.0f, 1.0f, 0.0f,
1344 0.0f, 0.0f, 0.0f, 1.0f,
1345 }}};
1347 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
1348 0, 0, 640, 480, NULL, NULL, NULL, NULL);
1349 d3d = Direct3DCreate8(D3D_SDK_VERSION);
1350 ok(!!d3d, "Failed to create a D3D object.\n");
1351 if (!(device = create_device(d3d, window, window, TRUE)))
1353 skip("Failed to create a D3D device, skipping tests.\n");
1354 goto done;
1357 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
1358 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
1359 if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1) || caps.PixelShaderVersion < D3DPS_VERSION(1, 1))
1361 skip("No vs_1_1 / ps_1_1 support, skipping tests.\n");
1362 IDirect3DDevice8_Release(device);
1363 goto done;
1366 /* NOTE: changing these values will not affect the tests with foggy vertex
1367 * shader, as the values are hardcoded in the shader constant. */
1368 start.f = 0.1f;
1369 end.f = 0.9f;
1371 /* Some of the tests seem to depend on the projection matrix explicitly
1372 * being set to an identity matrix, even though that's the default.
1373 * (AMD Radeon HD 6310, Windows 7) */
1374 hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, &identity);
1375 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
1377 hr = IDirect3DDevice8_CreateVertexShader(device, decl, vertex_shader_code1, &vertex_shader[1], 0);
1378 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1379 hr = IDirect3DDevice8_CreateVertexShader(device, decl, vertex_shader_code2, &vertex_shader[2], 0);
1380 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1381 hr = IDirect3DDevice8_CreatePixelShader(device, pixel_shader_code, &pixel_shader[1]);
1382 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1384 /* Set shader constant value */
1385 hr = IDirect3DDevice8_SetVertexShader(device, vertex_shader[2]);
1386 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1387 hr = IDirect3DDevice8_SetVertexShaderConstant(device, 0, vs_constant, 1);
1388 ok(hr == D3D_OK, "Setting vertex shader constant failed (%08x)\n", hr);
1390 /* Setup initial states: No lighting, fog on, fog color */
1391 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1392 ok(hr == D3D_OK, "Turning off lighting failed (%08x)\n", hr);
1393 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
1394 ok(hr == D3D_OK, "Turning on fog calculations failed (%08x)\n", hr);
1395 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
1396 ok(hr == D3D_OK, "Setting fog color failed (%08x)\n", hr);
1398 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1399 ok(hr == D3D_OK, "Turning off table fog failed (%08x)\n", hr);
1400 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
1401 ok(hr == D3D_OK, "Turning off vertex fog failed (%08x)\n", hr);
1403 /* Use fogtart = 0.1 and end = 0.9 to test behavior outside the fog transition phase, too */
1404 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGSTART, start.i);
1405 ok(hr == D3D_OK, "Setting fog start failed (%08x)\n", hr);
1406 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGEND, end.i);
1407 ok(hr == D3D_OK, "Setting fog end failed (%08x)\n", hr);
1409 for (i = 0; i < sizeof(test_data)/sizeof(test_data[0]); ++i)
1411 hr = IDirect3DDevice8_SetVertexShader(device, vertex_shader[test_data[i].vshader]);
1412 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1413 hr = IDirect3DDevice8_SetPixelShader(device, pixel_shader[test_data[i].pshader]);
1414 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1415 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGVERTEXMODE, test_data[i].vfog);
1416 ok( hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1417 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGTABLEMODE, test_data[i].tfog);
1418 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1420 for(j = 0; j < 11; ++j)
1422 /* Don't use the whole zrange to prevent rounding errors */
1423 quad[0].position.z = 0.001f + j / 10.02f;
1424 quad[1].position.z = 0.001f + j / 10.02f;
1425 quad[2].position.z = 0.001f + j / 10.02f;
1426 quad[3].position.z = 0.001f + j / 10.02f;
1428 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff00ff, 1.0f, 0);
1429 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
1431 hr = IDirect3DDevice8_BeginScene(device);
1432 ok( hr == D3D_OK, "BeginScene returned failed (%08x)\n", hr);
1434 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1435 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
1437 hr = IDirect3DDevice8_EndScene(device);
1438 ok(hr == D3D_OK, "EndScene failed (%08x)\n", hr);
1440 /* As the red and green component are the result of blending use 5% tolerance on the expected value */
1441 color = getPixelColor(device, 128, 240);
1442 ok(color_match(color, test_data[i].color[j], 13) || broken(test_data[i].uninitialized_reg),
1443 "fog vs%i ps%i fvm%i ftm%i %d: got color %08x, expected %08x +-5%%\n",
1444 test_data[i].vshader, test_data[i].pshader,
1445 test_data[i].vfog, test_data[i].tfog, j, color, test_data[i].color[j]);
1448 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
1450 IDirect3DDevice8_DeleteVertexShader(device, vertex_shader[1]);
1451 IDirect3DDevice8_DeleteVertexShader(device, vertex_shader[2]);
1452 IDirect3DDevice8_DeleteVertexShader(device, pixel_shader[1]);
1453 refcount = IDirect3DDevice8_Release(device);
1454 ok(!refcount, "Device has %u references left.\n", refcount);
1455 done:
1456 IDirect3D8_Release(d3d);
1457 DestroyWindow(window);
1460 static void cnd_test(void)
1462 DWORD shader_11_coissue_2, shader_12_coissue_2, shader_13_coissue_2, shader_14_coissue_2;
1463 DWORD shader_11_coissue, shader_12_coissue, shader_13_coissue, shader_14_coissue;
1464 DWORD shader_11, shader_12, shader_13, shader_14;
1465 IDirect3DDevice8 *device;
1466 IDirect3D8 *d3d;
1467 ULONG refcount;
1468 D3DCAPS8 caps;
1469 DWORD color;
1470 HWND window;
1471 HRESULT hr;
1473 /* ps 1.x shaders are rather picky with writemasks and source swizzles.
1474 * The dp3 is used to copy r0.r to all components of r1, then copy r1.a to
1475 * r0.a. Essentially it does a mov r0.a, r0.r, which isn't allowed as-is
1476 * in 1.x pixel shaders. */
1477 static const DWORD shader_code_11[] =
1479 0xffff0101, /* ps_1_1 */
1480 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
1481 0x00000040, 0xb00f0000, /* texcoord t0 */
1482 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
1483 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3 r1, r0, c0 */
1484 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
1485 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
1486 0x0000ffff /* end */
1488 static const DWORD shader_code_12[] =
1490 0xffff0102, /* ps_1_2 */
1491 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
1492 0x00000040, 0xb00f0000, /* texcoord t0 */
1493 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
1494 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3 r1, r0, c0 */
1495 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
1496 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
1497 0x0000ffff /* end */
1499 static const DWORD shader_code_13[] =
1501 0xffff0103, /* ps_1_3 */
1502 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
1503 0x00000040, 0xb00f0000, /* texcoord t0 */
1504 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
1505 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3, r1, r0, c0 */
1506 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
1507 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
1508 0x0000ffff /* end */
1510 static const DWORD shader_code_14[] =
1512 0xffff0104, /* ps_1_3 */
1513 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
1514 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0, t0 */
1515 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
1516 0x00000050, 0x800f0000, 0x80e40000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0, c1, c2 */
1517 0x0000ffff /* end */
1520 /* Special fun: The coissue flag on cnd: Apparently cnd always selects the 2nd source,
1521 * as if the src0 comparison against 0.5 always evaluates to true. The coissue flag isn't
1522 * set by the compiler, it was added manually after compilation. Note that the COISSUE
1523 * flag on a color(.xyz) operation is only allowed after an alpha operation. DirectX doesn't
1524 * have proper docs, but GL_ATI_fragment_shader explains the pairing of color and alpha ops
1525 * well enough.
1527 * The shader attempts to test the range [-1;1] against coissued cnd, which is a bit tricky.
1528 * The input from t0 is [0;1]. 0.5 is subtracted, then we have to multiply with 2. Since
1529 * constants are clamped to [-1;1], a 2.0 is constructed by adding c0.r(=1.0) to c0.r into r1.r,
1530 * then r1(2.0, 0.0, 0.0, 0.0) is passed to dp3(explained above).
1532 static const DWORD shader_code_11_coissue[] =
1534 0xffff0101, /* ps_1_1 */
1535 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
1536 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
1537 0x00000040, 0xb00f0000, /* texcoord t0 */
1538 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
1539 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
1540 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
1541 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
1542 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
1543 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.xyz, r0.a, c1, c2*/
1544 0x0000ffff /* end */
1546 static const DWORD shader_code_11_coissue_2[] =
1548 0xffff0101, /* ps_1_1 */
1549 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
1550 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
1551 0x00000040, 0xb00f0000, /* texcoord t0 */
1552 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
1553 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
1554 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
1555 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
1556 0x00000001, 0x800f0000, 0x80e40001, /* mov r0, r1 */
1557 0x00000001, 0x80070000, 0x80ff0001, /* mov r0.xyz, r1.a */
1558 0x40000050, 0x80080000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.a, r0.a, c1, c2 */
1559 0x00000001, 0x80070000, 0x80ff0000, /* mov r0.xyz, r0.a */
1560 0x0000ffff /* end */
1562 static const DWORD shader_code_12_coissue[] =
1564 0xffff0102, /* ps_1_2 */
1565 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
1566 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
1567 0x00000040, 0xb00f0000, /* texcoord t0 */
1568 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
1569 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
1570 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
1571 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
1572 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
1573 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.xyz, r0.a, c1, c2*/
1574 0x0000ffff /* end */
1576 static const DWORD shader_code_12_coissue_2[] =
1578 0xffff0102, /* ps_1_2 */
1579 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
1580 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
1581 0x00000040, 0xb00f0000, /* texcoord t0 */
1582 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
1583 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
1584 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
1585 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
1586 0x00000001, 0x800f0000, 0x80e40001, /* mov r0, r1 */
1587 0x00000001, 0x80070000, 0x80ff0001, /* mov r0.xyz, r1.a */
1588 0x40000050, 0x80080000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.a, r0.a, c1, c2 */
1589 0x00000001, 0x80070000, 0x80ff0000, /* mov r0.xyz, r0.a */
1590 0x0000ffff /* end */
1592 static const DWORD shader_code_13_coissue[] =
1594 0xffff0103, /* ps_1_3 */
1595 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
1596 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
1597 0x00000040, 0xb00f0000, /* texcoord t0 */
1598 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
1599 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
1600 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
1601 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
1602 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
1603 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.xyz, r0.a, c1, c2*/
1604 0x0000ffff /* end */
1606 static const DWORD shader_code_13_coissue_2[] =
1608 0xffff0103, /* ps_1_3 */
1609 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
1610 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
1611 0x00000040, 0xb00f0000, /* texcoord t0 */
1612 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
1613 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
1614 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
1615 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
1616 0x00000001, 0x800f0000, 0x80e40001, /* mov r0, r1 */
1617 0x00000001, 0x80070000, 0x80ff0001, /* mov r0.xyz, r1.a */
1618 0x40000050, 0x80080000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.a, r0.a, c1, c2 */
1619 0x00000001, 0x80070000, 0x80ff0000, /* mov r0.xyz, r0.a */
1620 0x0000ffff /* end */
1622 /* ps_1_4 does not have a different cnd behavior, just pass the [0;1]
1623 * texcrd result to cnd, it will compare against 0.5. */
1624 static const DWORD shader_code_14_coissue[] =
1626 0xffff0104, /* ps_1_4 */
1627 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
1628 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0.xyz, t0 */
1629 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
1630 0x40000050, 0x80070000, 0x80e40000, 0xa0e40001, 0xa0e40002, /* +cnd r0.xyz, r0, c1, c2 */
1631 0x0000ffff /* end */
1633 static const DWORD shader_code_14_coissue_2[] =
1635 0xffff0104, /* ps_1_4 */
1636 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
1637 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0.xyz, t0 */
1638 0x00000001, 0x80080000, 0x80000000, /* mov r0.a, r0.x */
1639 0x00000001, 0x80070001, 0xa0ff0000, /* mov r1.xyz, c0.a */
1640 0x40000050, 0x80080001, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r1.a, r0.a, c1, c2 */
1641 0x00000001, 0x80070000, 0x80ff0001, /* mov r0.xyz, r1.a */
1642 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
1643 0x0000ffff /* end */
1645 static const float quad1[] =
1647 -1.0f, -1.0f, 0.1f, 0.0f, 0.0f, 1.0f,
1648 -1.0f, 0.0f, 0.1f, 0.0f, 1.0f, 0.0f,
1649 0.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f,
1650 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 0.0f
1652 static const float quad2[] =
1654 0.0f, -1.0f, 0.1f, 0.0f, 0.0f, 1.0f,
1655 0.0f, 0.0f, 0.1f, 0.0f, 1.0f, 0.0f,
1656 1.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f,
1657 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 0.0f
1659 static const float quad3[] =
1661 0.0f, 0.0f, 0.1f, 0.0f, 0.0f, 1.0f,
1662 0.0f, 1.0f, 0.1f, 0.0f, 1.0f, 0.0f,
1663 1.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f,
1664 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 0.0f
1666 static const float quad4[] =
1668 -1.0f, 0.0f, 0.1f, 0.0f, 0.0f, 1.0f,
1669 -1.0f, 1.0f, 0.1f, 0.0f, 1.0f, 0.0f,
1670 0.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f,
1671 0.0f, 1.0f, 0.1f, 1.0f, 1.0f, 0.0f
1673 static const float test_data_c1[4] = {0.0f, 0.0f, 0.0f, 0.0f};
1674 static const float test_data_c2[4] = {1.0f, 1.0f, 1.0f, 1.0f};
1675 static const float test_data_c1_coi[4] = {0.0f, 1.0f, 0.0f, 0.0f};
1676 static const float test_data_c2_coi[4] = {1.0f, 0.0f, 1.0f, 1.0f};
1678 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
1679 0, 0, 640, 480, NULL, NULL, NULL, NULL);
1680 d3d = Direct3DCreate8(D3D_SDK_VERSION);
1681 ok(!!d3d, "Failed to create a D3D object.\n");
1682 if (!(device = create_device(d3d, window, window, TRUE)))
1684 skip("Failed to create a D3D device, skipping tests.\n");
1685 goto done;
1688 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
1689 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
1690 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 4))
1692 skip("No ps_1_4 support, skipping tests.\n");
1693 IDirect3DDevice8_Release(device);
1694 goto done;
1697 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
1698 ok(hr == D3D_OK, "IDirect3DDevice8_Clear returned %08x\n", hr);
1700 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code_11, &shader_11);
1701 ok(hr == D3D_OK, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr);
1702 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code_12, &shader_12);
1703 ok(hr == D3D_OK, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr);
1704 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code_13, &shader_13);
1705 ok(hr == D3D_OK, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr);
1706 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code_14, &shader_14);
1707 ok(hr == D3D_OK, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr);
1708 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code_11_coissue, &shader_11_coissue);
1709 ok(hr == D3D_OK, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr);
1710 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code_12_coissue, &shader_12_coissue);
1711 ok(hr == D3D_OK, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr);
1712 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code_13_coissue, &shader_13_coissue);
1713 ok(hr == D3D_OK, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr);
1714 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code_14_coissue, &shader_14_coissue);
1715 ok(hr == D3D_OK, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr);
1716 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code_11_coissue_2, &shader_11_coissue_2);
1717 ok(hr == D3D_OK, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr);
1718 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code_12_coissue_2, &shader_12_coissue_2);
1719 ok(hr == D3D_OK, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr);
1720 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code_13_coissue_2, &shader_13_coissue_2);
1721 ok(hr == D3D_OK, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr);
1722 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code_14_coissue_2, &shader_14_coissue_2);
1723 ok(hr == D3D_OK, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr);
1725 hr = IDirect3DDevice8_SetPixelShaderConstant(device, 1, test_data_c1, 1);
1726 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShaderConstant returned %08x\n", hr);
1727 hr = IDirect3DDevice8_SetPixelShaderConstant(device, 2, test_data_c2, 1);
1728 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShaderConstant returned %08x\n", hr);
1729 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX1);
1730 ok(hr == D3D_OK, "IDirect3DDevice8_SetVertexShader returned %#08x\n", hr);
1732 hr = IDirect3DDevice8_BeginScene(device);
1733 ok(hr == D3D_OK, "IDirect3DDevice8_BeginScene returned %08x\n", hr);
1735 hr = IDirect3DDevice8_SetPixelShader(device, shader_11);
1736 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr);
1737 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
1738 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
1740 hr = IDirect3DDevice8_SetPixelShader(device, shader_12);
1741 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr);
1742 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
1743 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
1745 hr = IDirect3DDevice8_SetPixelShader(device, shader_13);
1746 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr);
1747 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
1748 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
1750 hr = IDirect3DDevice8_SetPixelShader(device, shader_14);
1751 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr);
1752 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
1753 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
1755 hr = IDirect3DDevice8_EndScene(device);
1756 ok(hr == D3D_OK, "IDirect3DDevice8_EndScene returned %08x\n", hr);
1758 hr = IDirect3DDevice8_SetPixelShader(device, 0);
1759 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr);
1761 /* This is the 1.4 test. Each component(r, g, b) is tested separately against 0.5 */
1762 color = getPixelColor(device, 158, 118);
1763 ok(color == 0x00ff00ff, "pixel 158, 118 has color %08x, expected 0x00ff00ff\n", color);
1764 color = getPixelColor(device, 162, 118);
1765 ok(color == 0x000000ff, "pixel 162, 118 has color %08x, expected 0x000000ff\n", color);
1766 color = getPixelColor(device, 158, 122);
1767 ok(color == 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color);
1768 color = getPixelColor(device, 162, 122);
1769 ok(color == 0x0000ffff, "pixel 162, 122 has color %08x, expected 0x0000ffff\n", color);
1771 /* 1.1 shader. All 3 components get set, based on the .w comparison */
1772 color = getPixelColor(device, 158, 358);
1773 ok(color == 0x00ffffff, "pixel 158, 358 has color %08x, expected 0x00ffffff\n", color);
1774 color = getPixelColor(device, 162, 358);
1775 ok(color_match(color, 0x00000000, 1),
1776 "pixel 162, 358 has color %08x, expected 0x00000000\n", color);
1777 color = getPixelColor(device, 158, 362);
1778 ok(color == 0x00ffffff, "pixel 158, 362 has color %08x, expected 0x00ffffff\n", color);
1779 color = getPixelColor(device, 162, 362);
1780 ok(color_match(color, 0x00000000, 1),
1781 "pixel 162, 362 has color %08x, expected 0x00000000\n", color);
1783 /* 1.2 shader */
1784 color = getPixelColor(device, 478, 358);
1785 ok(color == 0x00ffffff, "pixel 478, 358 has color %08x, expected 0x00ffffff\n", color);
1786 color = getPixelColor(device, 482, 358);
1787 ok(color_match(color, 0x00000000, 1),
1788 "pixel 482, 358 has color %08x, expected 0x00000000\n", color);
1789 color = getPixelColor(device, 478, 362);
1790 ok(color == 0x00ffffff, "pixel 478, 362 has color %08x, expected 0x00ffffff\n", color);
1791 color = getPixelColor(device, 482, 362);
1792 ok(color_match(color, 0x00000000, 1),
1793 "pixel 482, 362 has color %08x, expected 0x00000000\n", color);
1795 /* 1.3 shader */
1796 color = getPixelColor(device, 478, 118);
1797 ok(color == 0x00ffffff, "pixel 478, 118 has color %08x, expected 0x00ffffff\n", color);
1798 color = getPixelColor(device, 482, 118);
1799 ok(color_match(color, 0x00000000, 1),
1800 "pixel 482, 118 has color %08x, expected 0x00000000\n", color);
1801 color = getPixelColor(device, 478, 122);
1802 ok(color == 0x00ffffff, "pixel 478, 122 has color %08x, expected 0x00ffffff\n", color);
1803 color = getPixelColor(device, 482, 122);
1804 ok(color_match(color, 0x00000000, 1),
1805 "pixel 482, 122 has color %08x, expected 0x00000000\n", color);
1807 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
1808 ok(hr == D3D_OK, "IDirect3DDevice8_Present failed with %08x\n", hr);
1810 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0f, 0);
1811 ok(hr == D3D_OK, "IDirect3DDevice8_Clear returned %08x\n", hr);
1812 hr = IDirect3DDevice8_SetPixelShaderConstant(device, 1, test_data_c1_coi, 1);
1813 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShaderConstant returned %08x\n", hr);
1814 hr = IDirect3DDevice8_SetPixelShaderConstant(device, 2, test_data_c2_coi, 1);
1815 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShaderConstant returned %08x\n", hr);
1817 hr = IDirect3DDevice8_BeginScene(device);
1818 ok(hr == D3D_OK, "IDirect3DDevice8_BeginScene returned %08x\n", hr);
1820 hr = IDirect3DDevice8_SetPixelShader(device, shader_11_coissue);
1821 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr);
1822 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
1823 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
1825 hr = IDirect3DDevice8_SetPixelShader(device, shader_12_coissue);
1826 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr);
1827 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
1828 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
1830 hr = IDirect3DDevice8_SetPixelShader(device, shader_13_coissue);
1831 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr);
1832 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
1833 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
1835 hr = IDirect3DDevice8_SetPixelShader(device, shader_14_coissue);
1836 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr);
1837 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
1838 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
1840 hr = IDirect3DDevice8_EndScene(device);
1841 ok(hr == D3D_OK, "IDirect3DDevice8_EndScene returned %08x\n", hr);
1843 hr = IDirect3DDevice8_SetPixelShader(device, 0);
1844 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr);
1846 /* This is the 1.4 test. The coissue doesn't change the behavior here, but keep in mind
1847 * that we swapped the values in c1 and c2 to make the other tests return some color
1849 color = getPixelColor(device, 158, 118);
1850 ok(color == 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color);
1851 color = getPixelColor(device, 162, 118);
1852 ok(color == 0x0000ffff, "pixel 162, 118 has color %08x, expected 0x0000ffff\n", color);
1853 color = getPixelColor(device, 158, 122);
1854 ok(color == 0x00ff00ff, "pixel 162, 122 has color %08x, expected 0x00ff00ff\n", color);
1855 color = getPixelColor(device, 162, 122);
1856 ok(color == 0x000000ff, "pixel 162, 122 has color %08x, expected 0x000000ff\n", color);
1858 /* 1.1 shader. coissue flag changed the semantic of cnd, c1 is always selected
1859 * (The Win7 nvidia driver always selects c2)
1861 color = getPixelColor(device, 158, 358);
1862 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
1863 "pixel 158, 358 has color %08x, expected 0x0000ff00\n", color);
1864 color = getPixelColor(device, 162, 358);
1865 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
1866 "pixel 162, 358 has color %08x, expected 0x0000ff00\n", color);
1867 color = getPixelColor(device, 158, 362);
1868 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
1869 "pixel 158, 362 has color %08x, expected 0x0000ff00\n", color);
1870 color = getPixelColor(device, 162, 362);
1871 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
1872 "pixel 162, 362 has color %08x, expected 0x0000ff00\n", color);
1874 /* 1.2 shader */
1875 color = getPixelColor(device, 478, 358);
1876 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
1877 "pixel 478, 358 has color %08x, expected 0x0000ff00\n", color);
1878 color = getPixelColor(device, 482, 358);
1879 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
1880 "pixel 482, 358 has color %08x, expected 0x0000ff00\n", color);
1881 color = getPixelColor(device, 478, 362);
1882 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
1883 "pixel 478, 362 has color %08x, expected 0x0000ff00\n", color);
1884 color = getPixelColor(device, 482, 362);
1885 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
1886 "pixel 482, 362 has color %08x, expected 0x0000ff00\n", color);
1888 /* 1.3 shader */
1889 color = getPixelColor(device, 478, 118);
1890 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
1891 "pixel 478, 118 has color %08x, expected 0x0000ff00\n", color);
1892 color = getPixelColor(device, 482, 118);
1893 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
1894 "pixel 482, 118 has color %08x, expected 0x0000ff00\n", color);
1895 color = getPixelColor(device, 478, 122);
1896 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
1897 "pixel 478, 122 has color %08x, expected 0x0000ff00\n", color);
1898 color = getPixelColor(device, 482, 122);
1899 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
1900 "pixel 482, 122 has color %08x, expected 0x0000ff00\n", color);
1902 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
1903 ok(hr == D3D_OK, "IDirect3DDevice8_Present failed with %08x\n", hr);
1905 /* Retest with the coissue flag on the alpha instruction instead. This
1906 * works "as expected". The Windows 8 testbot (WARP) seems to handle this
1907 * the same as coissue on .rgb. */
1908 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0f, 0);
1909 ok(hr == D3D_OK, "IDirect3DDevice8_Clear returned %08x\n", hr);
1911 hr = IDirect3DDevice8_BeginScene(device);
1912 ok(hr == D3D_OK, "IDirect3DDevice8_BeginScene returned %08x\n", hr);
1914 hr = IDirect3DDevice8_SetPixelShader(device, shader_11_coissue_2);
1915 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr);
1916 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
1917 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
1919 hr = IDirect3DDevice8_SetPixelShader(device, shader_12_coissue_2);
1920 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr);
1921 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
1922 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
1924 hr = IDirect3DDevice8_SetPixelShader(device, shader_13_coissue_2);
1925 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr);
1926 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
1927 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
1929 hr = IDirect3DDevice8_SetPixelShader(device, shader_14_coissue_2);
1930 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr);
1931 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
1932 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
1934 hr = IDirect3DDevice8_EndScene(device);
1935 ok(hr == D3D_OK, "IDirect3DDevice8_EndScene returned %08x\n", hr);
1937 /* 1.4 shader */
1938 color = getPixelColor(device, 158, 118);
1939 ok(color == 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color);
1940 color = getPixelColor(device, 162, 118);
1941 ok(color == 0x00000000, "pixel 162, 118 has color %08x, expected 0x00000000\n", color);
1942 color = getPixelColor(device, 158, 122);
1943 ok(color == 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color);
1944 color = getPixelColor(device, 162, 122);
1945 ok(color == 0x00000000, "pixel 162, 122 has color %08x, expected 0x00000000\n", color);
1947 /* 1.1 shader */
1948 color = getPixelColor(device, 238, 358);
1949 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
1950 "pixel 238, 358 has color %08x, expected 0x00ffffff\n", color);
1951 color = getPixelColor(device, 242, 358);
1952 ok(color_match(color, 0x00000000, 1),
1953 "pixel 242, 358 has color %08x, expected 0x00000000\n", color);
1954 color = getPixelColor(device, 238, 362);
1955 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
1956 "pixel 238, 362 has color %08x, expected 0x00ffffff\n", color);
1957 color = getPixelColor(device, 242, 362);
1958 ok(color_match(color, 0x00000000, 1),
1959 "pixel 242, 362 has color %08x, expected 0x00000000\n", color);
1961 /* 1.2 shader */
1962 color = getPixelColor(device, 558, 358);
1963 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
1964 "pixel 558, 358 has color %08x, expected 0x00ffffff\n", color);
1965 color = getPixelColor(device, 562, 358);
1966 ok(color_match(color, 0x00000000, 1),
1967 "pixel 562, 358 has color %08x, expected 0x00000000\n", color);
1968 color = getPixelColor(device, 558, 362);
1969 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
1970 "pixel 558, 362 has color %08x, expected 0x00ffffff\n", color);
1971 color = getPixelColor(device, 562, 362);
1972 ok(color_match(color, 0x00000000, 1),
1973 "pixel 562, 362 has color %08x, expected 0x00000000\n", color);
1975 /* 1.3 shader */
1976 color = getPixelColor(device, 558, 118);
1977 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
1978 "pixel 558, 118 has color %08x, expected 0x00ffffff\n", color);
1979 color = getPixelColor(device, 562, 118);
1980 ok(color_match(color, 0x00000000, 1),
1981 "pixel 562, 118 has color %08x, expected 0x00000000\n", color);
1982 color = getPixelColor(device, 558, 122);
1983 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
1984 "pixel 558, 122 has color %08x, expected 0x00ffffff\n", color);
1985 color = getPixelColor(device, 562, 122);
1986 ok(color_match(color, 0x00000000, 1),
1987 "pixel 562, 122 has color %08x, expected 0x00000000\n", color);
1989 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
1990 ok(hr == D3D_OK, "IDirect3DDevice8_Present failed with %08x\n", hr);
1992 IDirect3DDevice8_DeletePixelShader(device, shader_14_coissue_2);
1993 IDirect3DDevice8_DeletePixelShader(device, shader_13_coissue_2);
1994 IDirect3DDevice8_DeletePixelShader(device, shader_12_coissue_2);
1995 IDirect3DDevice8_DeletePixelShader(device, shader_11_coissue_2);
1996 IDirect3DDevice8_DeletePixelShader(device, shader_14_coissue);
1997 IDirect3DDevice8_DeletePixelShader(device, shader_13_coissue);
1998 IDirect3DDevice8_DeletePixelShader(device, shader_12_coissue);
1999 IDirect3DDevice8_DeletePixelShader(device, shader_11_coissue);
2000 IDirect3DDevice8_DeletePixelShader(device, shader_14);
2001 IDirect3DDevice8_DeletePixelShader(device, shader_13);
2002 IDirect3DDevice8_DeletePixelShader(device, shader_12);
2003 IDirect3DDevice8_DeletePixelShader(device, shader_11);
2004 refcount = IDirect3DDevice8_Release(device);
2005 ok(!refcount, "Device has %u references left.\n", refcount);
2006 done:
2007 IDirect3D8_Release(d3d);
2008 DestroyWindow(window);
2011 static void z_range_test(void)
2013 IDirect3DDevice8 *device;
2014 IDirect3D8 *d3d;
2015 D3DCOLOR color;
2016 ULONG refcount;
2017 D3DCAPS8 caps;
2018 DWORD shader;
2019 HWND window;
2020 HRESULT hr;
2022 static const struct
2024 struct vec3 position;
2025 DWORD diffuse;
2027 quad[] =
2029 {{-1.0f, 0.0f, 1.1f}, 0xffff0000},
2030 {{-1.0f, 1.0f, 1.1f}, 0xffff0000},
2031 {{ 1.0f, 0.0f, -1.1f}, 0xffff0000},
2032 {{ 1.0f, 1.0f, -1.1f}, 0xffff0000},
2034 quad2[] =
2036 {{-1.0f, 0.0f, 1.1f}, 0xff0000ff},
2037 {{-1.0f, 1.0f, 1.1f}, 0xff0000ff},
2038 {{ 1.0f, 0.0f, -1.1f}, 0xff0000ff},
2039 {{ 1.0f, 1.0f, -1.1f}, 0xff0000ff},
2041 static const struct
2043 struct vec4 position;
2044 DWORD diffuse;
2046 quad3[] =
2048 {{640.0f, 240.0f, -1.1f, 1.0f}, 0xffffff00},
2049 {{640.0f, 480.0f, -1.1f, 1.0f}, 0xffffff00},
2050 {{ 0.0f, 240.0f, 1.1f, 1.0f}, 0xffffff00},
2051 {{ 0.0f, 480.0f, 1.1f, 1.0f}, 0xffffff00},
2053 quad4[] =
2055 {{640.0f, 240.0f, -1.1f, 1.0f}, 0xff00ff00},
2056 {{640.0f, 480.0f, -1.1f, 1.0f}, 0xff00ff00},
2057 {{ 0.0f, 240.0f, 1.1f, 1.0f}, 0xff00ff00},
2058 {{ 0.0f, 480.0f, 1.1f, 1.0f}, 0xff00ff00},
2060 static const DWORD shader_code[] =
2062 0xfffe0101, /* vs_1_1 */
2063 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
2064 0x00000001, 0xd00f0000, 0xa0e40000, /* mov oD0, c0 */
2065 0x0000ffff /* end */
2067 static const float color_const_1[] = {1.0f, 0.0f, 0.0f, 1.0f};
2068 static const float color_const_2[] = {0.0f, 0.0f, 1.0f, 1.0f};
2069 static const DWORD vertex_declaration[] =
2071 D3DVSD_STREAM(0),
2072 D3DVSD_REG(D3DVSDE_POSITION, D3DVSDT_FLOAT3),
2073 D3DVSD_END()
2076 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
2077 0, 0, 640, 480, NULL, NULL, NULL, NULL);
2078 d3d = Direct3DCreate8(D3D_SDK_VERSION);
2079 ok(!!d3d, "Failed to create a D3D object.\n");
2080 if (!(device = create_device(d3d, window, window, TRUE)))
2082 skip("Failed to create a D3D device, skipping tests.\n");
2083 goto done;
2086 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
2087 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
2089 /* Does the Present clear the depth stencil? Clear the depth buffer with some value != 0,
2090 * then call Present. Then clear the color buffer to make sure it has some defined content
2091 * after the Present with D3DSWAPEFFECT_DISCARD. After that draw a plane that is somewhere cut
2092 * by the depth value. */
2093 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.75f, 0);
2094 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
2095 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
2096 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
2097 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
2098 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
2100 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
2101 ok(SUCCEEDED(hr), "Failed to disabled lighting, hr %#x.\n", hr);
2102 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, TRUE);
2103 ok(SUCCEEDED(hr), "Failed to enable clipping, hr %#x.\n", hr);
2104 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
2105 ok(SUCCEEDED(hr), "Failed to enable z test, hr %#x.\n", hr);
2106 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
2107 ok(SUCCEEDED(hr), "Failed to disable z writes, hr %#x.\n", hr);
2108 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
2109 ok(SUCCEEDED(hr), "Failed to set z function, hr %#x.\n", hr);
2110 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
2111 ok(SUCCEEDED(hr), "Failed set FVF, hr %#x.\n", hr);
2113 hr = IDirect3DDevice8_BeginScene(device);
2114 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
2116 /* Test the untransformed vertex path */
2117 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
2118 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2119 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
2120 ok(SUCCEEDED(hr), "Failed to set z function, hr %#x.\n", hr);
2121 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
2122 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2124 /* Test the transformed vertex path */
2125 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
2126 ok(SUCCEEDED(hr), "Failed set FVF, hr %#x.\n", hr);
2128 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(quad4[0]));
2129 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2130 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
2131 ok(SUCCEEDED(hr), "Failed to set z function, hr %#x.\n", hr);
2132 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(quad3[0]));
2133 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2135 hr = IDirect3DDevice8_EndScene(device);
2136 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
2138 /* Do not test the exact corner pixels, but go pretty close to them */
2140 /* Clipped because z > 1.0 */
2141 color = getPixelColor(device, 28, 238);
2142 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2143 color = getPixelColor(device, 28, 241);
2144 if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
2145 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2146 else
2147 ok(color_match(color, 0x00ffff00, 0), "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2149 /* Not clipped, > z buffer clear value(0.75).
2151 * On the r500 driver on Windows D3DCMP_GREATER and D3DCMP_GREATEREQUAL are broken for depth
2152 * values > 0.5. The range appears to be distorted, apparently an incoming value of ~0.875 is
2153 * equal to a stored depth buffer value of 0.5. */
2154 color = getPixelColor(device, 31, 238);
2155 ok(color_match(color, 0x00ff0000, 0), "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2156 color = getPixelColor(device, 31, 241);
2157 ok(color_match(color, 0x00ffff00, 0), "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2158 color = getPixelColor(device, 100, 238);
2159 ok(color_match(color, 0x00ff0000, 0) || broken(color_match(color, 0x00ffffff, 0)),
2160 "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2161 color = getPixelColor(device, 100, 241);
2162 ok(color_match(color, 0x00ffff00, 0) || broken(color_match(color, 0x00ffffff, 0)),
2163 "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2165 /* Not clipped, < z buffer clear value */
2166 color = getPixelColor(device, 104, 238);
2167 ok(color_match(color, 0x000000ff, 0), "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2168 color = getPixelColor(device, 104, 241);
2169 ok(color_match(color, 0x0000ff00, 0), "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
2170 color = getPixelColor(device, 318, 238);
2171 ok(color_match(color, 0x000000ff, 0), "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2172 color = getPixelColor(device, 318, 241);
2173 ok(color_match(color, 0x0000ff00, 0), "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
2175 /* Clipped because z < 0.0 */
2176 color = getPixelColor(device, 321, 238);
2177 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2178 color = getPixelColor(device, 321, 241);
2179 if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
2180 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2181 else
2182 ok(color_match(color, 0x0000ff00, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2184 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
2185 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
2187 /* Test the shader path */
2188 if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1))
2190 skip("Vertex shaders not supported\n");
2191 IDirect3DDevice8_Release(device);
2192 goto done;
2194 hr = IDirect3DDevice8_CreateVertexShader(device, vertex_declaration, shader_code, &shader, 0);
2195 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
2197 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
2198 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
2200 hr = IDirect3DDevice8_SetVertexShader(device, shader);
2201 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
2203 hr = IDirect3DDevice8_BeginScene(device);
2204 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
2206 hr = IDirect3DDevice8_SetVertexShaderConstant(device, 0, color_const_1, 1);
2207 ok(SUCCEEDED(hr), "Failed to set vs constant 0, hr %#x.\n", hr);
2208 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
2209 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2211 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
2212 ok(SUCCEEDED(hr), "Failed to set z function, hr %#x.\n", hr);
2213 hr = IDirect3DDevice8_SetVertexShaderConstant(device, 0, color_const_2, 1);
2214 ok(SUCCEEDED(hr), "Failed to set vs constant 0, hr %#x.\n", hr);
2215 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
2216 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2218 hr = IDirect3DDevice8_EndScene(device);
2219 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
2221 hr = IDirect3DDevice8_SetVertexShader(device, 0);
2222 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
2224 hr = IDirect3DDevice8_DeleteVertexShader(device, shader);
2225 ok(SUCCEEDED(hr), "Failed to delete vertex shader, hr %#x.\n", hr);
2227 /* Z < 1.0 */
2228 color = getPixelColor(device, 28, 238);
2229 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2231 /* 1.0 < z < 0.75 */
2232 color = getPixelColor(device, 31, 238);
2233 ok(color_match(color, 0x00ff0000, 0), "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2234 color = getPixelColor(device, 100, 238);
2235 ok(color_match(color, 0x00ff0000, 0) || broken(color_match(color, 0x00ffffff, 0)),
2236 "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2238 /* 0.75 < z < 0.0 */
2239 color = getPixelColor(device, 104, 238);
2240 ok(color_match(color, 0x000000ff, 0), "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2241 color = getPixelColor(device, 318, 238);
2242 ok(color_match(color, 0x000000ff, 0), "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2244 /* 0.0 < z */
2245 color = getPixelColor(device, 321, 238);
2246 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2248 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
2249 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
2251 refcount = IDirect3DDevice8_Release(device);
2252 ok(!refcount, "Device has %u references left.\n", refcount);
2253 done:
2254 IDirect3D8_Release(d3d);
2255 DestroyWindow(window);
2258 static void test_scalar_instructions(void)
2260 IDirect3DDevice8 *device;
2261 IDirect3D8 *d3d;
2262 unsigned int i;
2263 D3DCOLOR color;
2264 ULONG refcount;
2265 D3DCAPS8 caps;
2266 DWORD shader;
2267 HWND window;
2268 HRESULT hr;
2270 static const struct vec3 quad[] =
2272 {-1.0f, -1.0f, 0.0f},
2273 {-1.0f, 1.0f, 0.0f},
2274 { 1.0f, -1.0f, 0.0f},
2275 { 1.0f, 1.0f, 0.0f},
2277 static const DWORD decl[] =
2279 D3DVSD_STREAM(0),
2280 D3DVSD_REG(D3DVSDE_POSITION, D3DVSDT_FLOAT3), /* dcl_position v0 */
2281 D3DVSD_CONST(0, 1), 0x3e800000, 0x3f000000, 0x3f800000, 0x40000000, /* def c0, 0.25, 0.5, 1.0, 2.0 */
2282 D3DVSD_END()
2284 static const DWORD rcp_test[] =
2286 0xfffe0101, /* vs_1_1 */
2287 0x0009fffe, 0x30303030, 0x30303030, /* Shaders have to have a minimal size. */
2288 0x30303030, 0x30303030, 0x30303030, /* Add a filler comment. Usually d3dx8's */
2289 0x30303030, 0x30303030, 0x30303030, /* version comment makes the shader big */
2290 0x00303030, /* enough to make Windows happy. */
2291 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
2292 0x00000006, 0xd00f0000, 0xa0e40000, /* rcp oD0, c0 */
2293 0x0000ffff /* END */
2295 static const DWORD rsq_test[] =
2297 0xfffe0101, /* vs_1_1 */
2298 0x0009fffe, 0x30303030, 0x30303030, /* Shaders have to have a minimal size. */
2299 0x30303030, 0x30303030, 0x30303030, /* Add a filler comment. Usually d3dx8's */
2300 0x30303030, 0x30303030, 0x30303030, /* version comment makes the shader big */
2301 0x00303030, /* enough to make Windows happy. */
2302 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
2303 0x00000007, 0xd00f0000, 0xa0e40000, /* rsq oD0, c0 */
2304 0x0000ffff /* END */
2306 static const DWORD exp_test[] =
2308 0xfffe0101, /* vs_1_1 */
2309 0x0009fffe, 0x30303030, 0x30303030, /* Shaders have to have a minimal size. */
2310 0x30303030, 0x30303030, 0x30303030, /* Add a filler comment. Usually d3dx8's */
2311 0x30303030, 0x30303030, 0x30303030, /* version comment makes the shader big */
2312 0x00303030, /* enough to make Windows happy. */
2313 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
2314 0x0000000e, 0x800f0000, 0xa0e40000, /* exp r0, c0 */
2315 0x00000006, 0xd00f0000, 0x80000000, /* rcp oD0, r0.x */
2316 0x0000ffff, /* END */
2318 static const DWORD expp_test[] =
2320 0xfffe0101, /* vs_1_1 */
2321 0x0009fffe, 0x30303030, 0x30303030, /* Shaders have to have a minimal size. */
2322 0x30303030, 0x30303030, 0x30303030, /* Add a filler comment. Usually d3dx8's */
2323 0x30303030, 0x30303030, 0x30303030, /* version comment makes the shader big */
2324 0x00303030, /* enough to make Windows happy. */
2325 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
2326 0x0000004e, 0x800f0000, 0xa0e40000, /* expp r0, c0 */
2327 0x00000006, 0xd00f0000, 0x80000000, /* rcp oD0, r0.x */
2328 0x0000ffff, /* END */
2330 static const DWORD log_test[] =
2332 0xfffe0101, /* vs_1_1 */
2333 0x0009fffe, 0x30303030, 0x30303030, /* Shaders have to have a minimal size. */
2334 0x30303030, 0x30303030, 0x30303030, /* Add a filler comment. Usually d3dx8's */
2335 0x30303030, 0x30303030, 0x30303030, /* version comment makes the shader big */
2336 0x00303030, /* enough to make Windows happy. */
2337 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
2338 0x0000000f, 0xd00f0000, 0xa0e40000, /* log oD0, c0 */
2339 0x0000ffff, /* END */
2341 static const DWORD logp_test[] =
2343 0xfffe0101, /* vs_1_1 */
2344 0x0009fffe, 0x30303030, 0x30303030, /* Shaders have to have a minimal size. */
2345 0x30303030, 0x30303030, 0x30303030, /* Add a filler comment. Usually d3dx8's */
2346 0x30303030, 0x30303030, 0x30303030, /* version comment makes the shader big */
2347 0x00303030, /* enough to make Windows happy. */
2348 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
2349 0x0000004f, 0xd00f0000, 0xa0e40000, /* logp oD0, c0 */
2350 0x0000ffff, /* END */
2352 static const struct
2354 const char *name;
2355 const DWORD *byte_code;
2356 D3DCOLOR color;
2357 /* Some drivers, including Intel HD4000 10.18.10.3345 and VMware SVGA
2358 * 3D 7.14.1.5025, use the .x component instead of the .w one. */
2359 D3DCOLOR broken_color;
2361 test_data[] =
2363 {"rcp_test", rcp_test, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x80), D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff)},
2364 {"rsq_test", rsq_test, D3DCOLOR_ARGB(0x00, 0xb4, 0xb4, 0xb4), D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff)},
2365 {"exp_test", exp_test, D3DCOLOR_ARGB(0x00, 0x40, 0x40, 0x40), D3DCOLOR_ARGB(0x00, 0xd6, 0xd6, 0xd6)},
2366 {"expp_test", expp_test, D3DCOLOR_ARGB(0x00, 0x40, 0x40, 0x40), D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff)},
2367 {"log_test", log_test, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff), D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
2368 {"logp_test", logp_test, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff), D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
2371 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
2372 0, 0, 640, 480, NULL, NULL, NULL, NULL);
2373 d3d = Direct3DCreate8(D3D_SDK_VERSION);
2374 ok(!!d3d, "Failed to create a D3D object.\n");
2375 if (!(device = create_device(d3d, window, window, TRUE)))
2377 skip("Failed to create a D3D device, skipping tests.\n");
2378 goto done;
2381 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
2382 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
2383 if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1))
2385 skip("No vs_1_1 support, skipping tests.\n");
2386 IDirect3DDevice8_Release(device);
2387 goto done;
2390 for (i = 0; i < sizeof(test_data) / sizeof(*test_data); ++i)
2392 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff336699, 0.0f, 0);
2393 ok(SUCCEEDED(hr), "%s: Failed to clear, hr %#x.\n", test_data[i].name, hr);
2395 hr = IDirect3DDevice8_CreateVertexShader(device, decl, test_data[i].byte_code, &shader, 0);
2396 ok(SUCCEEDED(hr), "%s: Failed to create vertex shader, hr %#x.\n", test_data[i].name, hr);
2397 hr = IDirect3DDevice8_SetVertexShader(device, shader);
2398 ok(SUCCEEDED(hr), "%s: Failed to set vertex shader, hr %#x.\n", test_data[i].name, hr);
2400 hr = IDirect3DDevice8_BeginScene(device);
2401 ok(SUCCEEDED(hr), "%s: Failed to begin scene, hr %#x.\n", test_data[i].name, hr);
2402 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], 3 * sizeof(float));
2403 ok(SUCCEEDED(hr), "%s: Failed to draw primitive, hr %#x.\n", test_data[i].name, hr);
2404 hr = IDirect3DDevice8_EndScene(device);
2405 ok(SUCCEEDED(hr), "%s: Failed to end scene, hr %#x.\n", test_data[i].name, hr);
2407 color = getPixelColor(device, 320, 240);
2408 ok(color_match(color, test_data[i].color, 4) || broken(color_match(color, test_data[i].broken_color, 4)),
2409 "%s: Got unexpected color 0x%08x, expected 0x%08x.\n",
2410 test_data[i].name, color, test_data[i].color);
2412 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
2413 ok(SUCCEEDED(hr), "%s: Failed to present, hr %#x.\n", test_data[i].name, hr);
2415 hr = IDirect3DDevice8_SetVertexShader(device, 0);
2416 ok(SUCCEEDED(hr), "%s: Failed to set vertex shader, hr %#x.\n", test_data[i].name, hr);
2417 hr = IDirect3DDevice8_DeleteVertexShader(device, shader);
2418 ok(SUCCEEDED(hr), "%s: Failed to delete vertex shader, hr %#x.\n", test_data[i].name, hr);
2421 refcount = IDirect3DDevice8_Release(device);
2422 ok(!refcount, "Device has %u references left.\n", refcount);
2423 done:
2424 IDirect3D8_Release(d3d);
2425 DestroyWindow(window);
2428 static void offscreen_test(void)
2430 IDirect3DSurface8 *backbuffer, *offscreen, *depthstencil;
2431 IDirect3DTexture8 *offscreenTexture;
2432 IDirect3DDevice8 *device;
2433 IDirect3D8 *d3d;
2434 D3DCOLOR color;
2435 ULONG refcount;
2436 HWND window;
2437 HRESULT hr;
2439 static const float quad[][5] =
2441 {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
2442 {-0.5f, 0.5f, 0.1f, 0.0f, 1.0f},
2443 { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
2444 { 0.5f, 0.5f, 0.1f, 1.0f, 1.0f},
2447 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
2448 0, 0, 640, 480, NULL, NULL, NULL, NULL);
2449 d3d = Direct3DCreate8(D3D_SDK_VERSION);
2450 ok(!!d3d, "Failed to create a D3D object.\n");
2451 if (!(device = create_device(d3d, window, window, TRUE)))
2453 skip("Failed to create a D3D device, skipping tests.\n");
2454 goto done;
2457 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 1.0f, 0);
2458 ok(hr == D3D_OK, "Clear failed, hr = %#08x\n", hr);
2460 hr = IDirect3DDevice8_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET,
2461 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture);
2462 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %#08x\n", hr);
2463 if (!offscreenTexture)
2465 trace("Failed to create an X8R8G8B8 offscreen texture, trying R5G6B5\n");
2466 hr = IDirect3DDevice8_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET,
2467 D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &offscreenTexture);
2468 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %#08x\n", hr);
2469 if (!offscreenTexture)
2471 skip("Cannot create an offscreen render target.\n");
2472 IDirect3DDevice8_Release(device);
2473 goto done;
2477 hr = IDirect3DDevice8_GetDepthStencilSurface(device, &depthstencil);
2478 ok(hr == D3D_OK, "IDirect3DDevice8_GetDepthStencilSurface failed, hr = %#08x\n", hr);
2480 hr = IDirect3DDevice8_GetBackBuffer(device, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
2481 ok(hr == D3D_OK, "Can't get back buffer, hr = %#08x\n", hr);
2483 hr = IDirect3DTexture8_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
2484 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %#08x\n", hr);
2486 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX1);
2487 ok(hr == D3D_OK, "SetVertexShader failed, hr = %#08x\n", hr);
2489 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
2490 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %#08x\n", hr);
2491 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
2492 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %#08x\n", hr);
2493 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MINFILTER, D3DTEXF_NONE);
2494 ok(SUCCEEDED(hr), "SetTextureStageState D3DSAMP_MINFILTER failed (%#08x)\n", hr);
2495 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MAGFILTER, D3DTEXF_NONE);
2496 ok(SUCCEEDED(hr), "SetTextureStageState D3DSAMP_MAGFILTER failed (%#08x)\n", hr);
2497 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
2498 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %08x\n", hr);
2500 hr = IDirect3DDevice8_BeginScene(device);
2501 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
2503 hr = IDirect3DDevice8_SetRenderTarget(device, offscreen, depthstencil);
2504 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
2505 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 1.0f, 0);
2506 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
2508 /* Draw without textures - Should result in a white quad. */
2509 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
2510 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2512 hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, depthstencil);
2513 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
2514 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)offscreenTexture);
2515 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
2517 /* This time with the texture .*/
2518 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
2519 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2521 hr = IDirect3DDevice8_EndScene(device);
2522 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
2524 /* Center quad - should be white */
2525 color = getPixelColor(device, 320, 240);
2526 ok(color == 0x00ffffff, "Offscreen failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2527 /* Some quad in the cleared part of the texture */
2528 color = getPixelColor(device, 170, 240);
2529 ok(color == 0x00ff00ff, "Offscreen failed: Got color 0x%08x, expected 0x00ff00ff.\n", color);
2530 /* Part of the originally cleared back buffer */
2531 color = getPixelColor(device, 10, 10);
2532 ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2533 color = getPixelColor(device, 10, 470);
2534 ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2536 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
2538 IDirect3DSurface8_Release(backbuffer);
2539 IDirect3DTexture8_Release(offscreenTexture);
2540 IDirect3DSurface8_Release(offscreen);
2541 IDirect3DSurface8_Release(depthstencil);
2542 refcount = IDirect3DDevice8_Release(device);
2543 ok(!refcount, "Device has %u references left.\n", refcount);
2544 done:
2545 IDirect3D8_Release(d3d);
2546 DestroyWindow(window);
2549 static void test_blend(void)
2551 IDirect3DSurface8 *backbuffer, *offscreen, *depthstencil;
2552 IDirect3DTexture8 *offscreenTexture;
2553 IDirect3DDevice8 *device;
2554 IDirect3D8 *d3d;
2555 D3DCOLOR color;
2556 ULONG refcount;
2557 HWND window;
2558 HRESULT hr;
2560 static const struct
2562 struct vec3 position;
2563 DWORD diffuse;
2565 quad1[] =
2567 {{-1.0f, -1.0f, 0.1f}, 0x4000ff00},
2568 {{-1.0f, 0.0f, 0.1f}, 0x4000ff00},
2569 {{ 1.0f, -1.0f, 0.1f}, 0x4000ff00},
2570 {{ 1.0f, 0.0f, 0.1f}, 0x4000ff00},
2572 quad2[] =
2574 {{-1.0f, 0.0f, 0.1f}, 0xc00000ff},
2575 {{-1.0f, 1.0f, 0.1f}, 0xc00000ff},
2576 {{ 1.0f, 0.0f, 0.1f}, 0xc00000ff},
2577 {{ 1.0f, 1.0f, 0.1f}, 0xc00000ff},
2579 static const float composite_quad[][5] =
2581 { 0.0f, -1.0f, 0.1f, 0.0f, 1.0f},
2582 { 0.0f, 1.0f, 0.1f, 0.0f, 0.0f},
2583 { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f},
2584 { 1.0f, 1.0f, 0.1f, 1.0f, 0.0f},
2587 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
2588 0, 0, 640, 480, NULL, NULL, NULL, NULL);
2589 d3d = Direct3DCreate8(D3D_SDK_VERSION);
2590 ok(!!d3d, "Failed to create a D3D object.\n");
2591 if (!(device = create_device(d3d, window, window, TRUE)))
2593 skip("Failed to create a D3D device, skipping tests.\n");
2594 goto done;
2597 /* Clear the render target with alpha = 0.5 */
2598 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x80ff0000, 1.0f, 0);
2599 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
2601 hr = IDirect3DDevice8_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET,
2602 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture);
2603 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
2605 hr = IDirect3DDevice8_GetDepthStencilSurface(device, &depthstencil);
2606 ok(SUCCEEDED(hr), "Failed to get depth/stencil buffer, hr %#x.\n", hr);
2607 hr = IDirect3DDevice8_GetBackBuffer(device, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
2608 ok(SUCCEEDED(hr), "Failed to get back buffer, hr %#x.\n", hr);
2610 hr = IDirect3DTexture8_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
2611 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %#08x\n", hr);
2613 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
2614 ok(hr == D3D_OK, "SetVertexShader failed, hr = %#08x\n", hr);
2616 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
2617 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %#08x\n", hr);
2618 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
2619 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %#08x\n", hr);
2620 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MINFILTER, D3DTEXF_NONE);
2621 ok(SUCCEEDED(hr), "SetTextureStageState D3DSAMP_MINFILTER failed (%#08x)\n", hr);
2622 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MAGFILTER, D3DTEXF_NONE);
2623 ok(SUCCEEDED(hr), "SetTextureStageState D3DSAMP_MAGFILTER failed (%#08x)\n", hr);
2624 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
2625 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %08x\n", hr);
2627 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
2628 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
2629 hr = IDirect3DDevice8_BeginScene(device);
2630 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
2632 /* Draw two quads, one with src alpha blending, one with dest alpha blending. */
2633 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
2634 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
2635 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
2636 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
2637 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
2638 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2640 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
2641 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
2642 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
2643 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
2644 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
2645 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2647 /* Switch to the offscreen buffer, and redo the testing. The offscreen
2648 * render target doesn't have an alpha channel. DESTALPHA and INVDESTALPHA
2649 * "don't work" on render targets without alpha channel, they give
2650 * essentially ZERO and ONE blend factors. */
2651 hr = IDirect3DDevice8_SetRenderTarget(device, offscreen, 0);
2652 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
2653 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
2654 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
2656 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
2657 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
2658 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
2659 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
2660 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
2661 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2663 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
2664 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
2665 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
2666 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
2667 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
2668 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2670 hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, depthstencil);
2671 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
2673 /* Render the offscreen texture onto the frame buffer to be able to
2674 * compare it regularly. Disable alpha blending for the final
2675 * composition. */
2676 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
2677 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
2678 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX1);
2679 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
2681 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *) offscreenTexture);
2682 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
2683 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, composite_quad, sizeof(float) * 5);
2684 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2686 hr = IDirect3DDevice8_EndScene(device);
2687 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
2689 color = getPixelColor(device, 160, 360);
2690 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
2691 "SRCALPHA on frame buffer returned color %08x, expected 0x00bf4000\n", color);
2693 color = getPixelColor(device, 160, 120);
2694 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x00, 0x80), 2),
2695 "DSTALPHA on frame buffer returned color %08x, expected 0x007f0080\n", color);
2697 color = getPixelColor(device, 480, 360);
2698 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
2699 "SRCALPHA on texture returned color %08x, expected 0x00bf4000\n", color);
2701 color = getPixelColor(device, 480, 120);
2702 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
2703 "DSTALPHA on texture returned color %08x, expected 0x000000ff\n", color);
2705 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
2707 IDirect3DSurface8_Release(backbuffer);
2708 IDirect3DTexture8_Release(offscreenTexture);
2709 IDirect3DSurface8_Release(offscreen);
2710 IDirect3DSurface8_Release(depthstencil);
2711 refcount = IDirect3DDevice8_Release(device);
2712 ok(!refcount, "Device has %u references left.\n", refcount);
2713 done:
2714 IDirect3D8_Release(d3d);
2715 DestroyWindow(window);
2718 static void p8_texture_test(void)
2720 IDirect3DTexture8 *texture, *texture2;
2721 IDirect3DDevice8 *device;
2722 PALETTEENTRY table[256];
2723 unsigned char *data;
2724 D3DLOCKED_RECT lr;
2725 IDirect3D8 *d3d;
2726 D3DCOLOR color;
2727 ULONG refcount;
2728 D3DCAPS8 caps;
2729 HWND window;
2730 HRESULT hr;
2731 UINT i;
2733 static const float quad[] =
2735 -1.0f, 0.0f, 0.1f, 0.0f, 0.0f,
2736 -1.0f, 1.0f, 0.1f, 0.0f, 1.0f,
2737 1.0f, 0.0f, 0.1f, 1.0f, 0.0f,
2738 1.0f, 1.0f, 0.1f, 1.0f, 1.0f,
2740 static const float quad2[] =
2742 -1.0f, -1.0f, 0.1f, 0.0f, 0.0f,
2743 -1.0f, 0.0f, 0.1f, 0.0f, 1.0f,
2744 1.0f, -1.0f, 0.1f, 1.0f, 0.0f,
2745 1.0f, 0.0f, 0.1f, 1.0f, 1.0f,
2748 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
2749 0, 0, 640, 480, NULL, NULL, NULL, NULL);
2750 d3d = Direct3DCreate8(D3D_SDK_VERSION);
2751 ok(!!d3d, "Failed to create a D3D object.\n");
2752 if (!(device = create_device(d3d, window, window, TRUE)))
2754 skip("Failed to create a D3D device, skipping tests.\n");
2755 goto done;
2758 if (IDirect3D8_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
2759 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_P8) != D3D_OK)
2761 skip("D3DFMT_P8 textures not supported.\n");
2762 IDirect3DDevice8_Release(device);
2763 goto done;
2766 hr = IDirect3DDevice8_CreateTexture(device, 1, 1, 1, 0, D3DFMT_P8, D3DPOOL_MANAGED, &texture2);
2767 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
2768 memset(&lr, 0, sizeof(lr));
2769 hr = IDirect3DTexture8_LockRect(texture2, 0, &lr, NULL, 0);
2770 ok(hr == D3D_OK, "IDirect3DTexture8_LockRect failed, hr = %08x\n", hr);
2771 data = lr.pBits;
2772 *data = 1;
2773 hr = IDirect3DTexture8_UnlockRect(texture2, 0);
2774 ok(hr == D3D_OK, "IDirect3DTexture8_UnlockRect failed, hr = %08x\n", hr);
2776 hr = IDirect3DDevice8_CreateTexture(device, 1, 1, 1, 0, D3DFMT_P8, D3DPOOL_MANAGED, &texture);
2777 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
2778 memset(&lr, 0, sizeof(lr));
2779 hr = IDirect3DTexture8_LockRect(texture, 0, &lr, NULL, 0);
2780 ok(hr == D3D_OK, "IDirect3DTexture8_LockRect failed, hr = %08x\n", hr);
2781 data = lr.pBits;
2782 *data = 1;
2783 hr = IDirect3DTexture8_UnlockRect(texture, 0);
2784 ok(hr == D3D_OK, "IDirect3DTexture8_UnlockRect failed, hr = %08x\n", hr);
2786 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff000000, 1.0f, 0);
2787 ok(hr == D3D_OK, "IDirect3DDevice8_Clear failed, hr = %08x\n", hr);
2789 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
2790 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
2791 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
2792 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
2794 /* The first part of the test should work both with and without D3DPTEXTURECAPS_ALPHAPALETTE;
2795 alpha of every entry is set to 1.0, which MS says is required when there's no
2796 D3DPTEXTURECAPS_ALPHAPALETTE capability */
2797 for (i = 0; i < 256; i++) {
2798 table[i].peRed = table[i].peGreen = table[i].peBlue = 0;
2799 table[i].peFlags = 0xff;
2801 table[1].peRed = 0xff;
2802 hr = IDirect3DDevice8_SetPaletteEntries(device, 0, table);
2803 ok(hr == D3D_OK, "IDirect3DDevice8_SetPaletteEntries failed, hr = %08x\n", hr);
2805 table[1].peRed = 0;
2806 table[1].peBlue = 0xff;
2807 hr = IDirect3DDevice8_SetPaletteEntries(device, 1, table);
2808 ok(hr == D3D_OK, "IDirect3DDevice8_SetPaletteEntries failed, hr = %08x\n", hr);
2810 hr = IDirect3DDevice8_BeginScene(device);
2811 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
2813 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
2814 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
2815 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
2816 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
2817 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX1);
2818 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
2819 hr = IDirect3DDevice8_SetCurrentTexturePalette(device, 0);
2820 ok(SUCCEEDED(hr), "Failed to set texture palette, hr %#x.\n", hr);
2821 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture2);
2822 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
2823 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
2824 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2826 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
2827 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
2828 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
2829 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2831 hr = IDirect3DDevice8_SetCurrentTexturePalette(device, 1);
2832 ok(SUCCEEDED(hr), "Failed to set texture palette, hr %#x.\n", hr);
2833 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
2834 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2836 hr = IDirect3DDevice8_EndScene(device);
2837 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
2839 color = getPixelColor(device, 32, 32);
2840 ok(color_match(color, 0x00ff0000, 0), "Got unexpected color 0x%08x.\n", color);
2841 color = getPixelColor(device, 32, 320);
2842 ok(color_match(color, 0x000000ff, 0), "Got unexpected color 0x%08x.\n", color);
2844 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
2845 ok(hr == D3D_OK, "IDirect3DDevice8_Present failed, hr = %08x\n", hr);
2847 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
2848 ok(hr == D3D_OK, "IDirect3DDevice8_Clear failed, hr = %08x\n", hr);
2850 hr = IDirect3DDevice8_BeginScene(device);
2851 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
2852 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture2);
2853 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
2854 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
2855 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2856 hr = IDirect3DDevice8_EndScene(device);
2857 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
2859 color = getPixelColor(device, 32, 32);
2860 ok(color_match(color, 0x000000ff, 0), "Got unexpected color 0x%08x.\n", color);
2862 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
2863 ok(hr == D3D_OK, "IDirect3DDevice8_Present failed, hr = %08x\n", hr);
2865 /* Test palettes with alpha */
2866 IDirect3DDevice8_GetDeviceCaps(device, &caps);
2867 if (!(caps.TextureCaps & D3DPTEXTURECAPS_ALPHAPALETTE)) {
2868 skip("no D3DPTEXTURECAPS_ALPHAPALETTE capability, tests with alpha in palette will be skipped\n");
2869 } else {
2870 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
2871 ok(hr == D3D_OK, "IDirect3DDevice8_Clear failed, hr = %08x\n", hr);
2873 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
2874 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
2876 for (i = 0; i < 256; i++) {
2877 table[i].peRed = table[i].peGreen = table[i].peBlue = 0;
2878 table[i].peFlags = 0xff;
2880 table[1].peRed = 0xff;
2881 table[1].peFlags = 0x80;
2882 hr = IDirect3DDevice8_SetPaletteEntries(device, 0, table);
2883 ok(hr == D3D_OK, "IDirect3DDevice8_SetPaletteEntries failed, hr = %08x\n", hr);
2885 table[1].peRed = 0;
2886 table[1].peBlue = 0xff;
2887 table[1].peFlags = 0x80;
2888 hr = IDirect3DDevice8_SetPaletteEntries(device, 1, table);
2889 ok(hr == D3D_OK, "IDirect3DDevice8_SetPaletteEntries failed, hr = %08x\n", hr);
2891 hr = IDirect3DDevice8_BeginScene(device);
2892 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
2894 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
2895 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
2896 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
2897 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
2898 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX1);
2899 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
2901 hr = IDirect3DDevice8_SetCurrentTexturePalette(device, 0);
2902 ok(SUCCEEDED(hr), "Failed to set texture palette, hr %#x.\n", hr);
2903 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
2904 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2906 hr = IDirect3DDevice8_SetCurrentTexturePalette(device, 1);
2907 ok(SUCCEEDED(hr), "Failed to set texture palette, hr %#x.\n", hr);
2908 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
2909 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2911 hr = IDirect3DDevice8_EndScene(device);
2912 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
2914 color = getPixelColor(device, 32, 32);
2915 ok(color_match(color, 0x00800000, 1), "Got unexpected color 0x%08x.\n", color);
2916 color = getPixelColor(device, 32, 320);
2917 ok(color_match(color, 0x00000080, 1), "Got unexpected color 0x%08x.\n", color);
2919 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
2920 ok(hr == D3D_OK, "IDirect3DDevice8_Present failed, hr = %08x\n", hr);
2923 IDirect3DTexture8_Release(texture);
2924 IDirect3DTexture8_Release(texture2);
2925 refcount = IDirect3DDevice8_Release(device);
2926 ok(!refcount, "Device has %u references left.\n", refcount);
2927 done:
2928 IDirect3D8_Release(d3d);
2929 DestroyWindow(window);
2932 static void texop_test(void)
2934 IDirect3DTexture8 *texture;
2935 D3DLOCKED_RECT locked_rect;
2936 IDirect3DDevice8 *device;
2937 IDirect3D8 *d3d;
2938 unsigned int i;
2939 D3DCOLOR color;
2940 ULONG refcount;
2941 D3DCAPS8 caps;
2942 HWND window;
2943 HRESULT hr;
2945 static const struct {
2946 float x, y, z;
2947 D3DCOLOR diffuse;
2948 float s, t;
2949 } quad[] = {
2950 {-1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00), -1.0f, -1.0f},
2951 {-1.0f, 1.0f, 0.1f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00), -1.0f, 1.0f},
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}
2956 static const struct {
2957 D3DTEXTUREOP op;
2958 const char *name;
2959 DWORD caps_flag;
2960 D3DCOLOR result;
2961 } test_data[] = {
2962 {D3DTOP_SELECTARG1, "SELECTARG1", D3DTEXOPCAPS_SELECTARG1, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
2963 {D3DTOP_SELECTARG2, "SELECTARG2", D3DTEXOPCAPS_SELECTARG2, D3DCOLOR_ARGB(0x00, 0x33, 0x33, 0x33)},
2964 {D3DTOP_MODULATE, "MODULATE", D3DTEXOPCAPS_MODULATE, D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x00)},
2965 {D3DTOP_MODULATE2X, "MODULATE2X", D3DTEXOPCAPS_MODULATE2X, D3DCOLOR_ARGB(0x00, 0x00, 0x66, 0x00)},
2966 {D3DTOP_MODULATE4X, "MODULATE4X", D3DTEXOPCAPS_MODULATE4X, D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
2967 {D3DTOP_ADD, "ADD", D3DTEXOPCAPS_ADD, D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
2969 {D3DTOP_ADDSIGNED, "ADDSIGNED", D3DTEXOPCAPS_ADDSIGNED, D3DCOLOR_ARGB(0x00, 0x00, 0xb2, 0x00)},
2970 {D3DTOP_ADDSIGNED2X, "ADDSIGNED2X", D3DTEXOPCAPS_ADDSIGNED2X, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
2972 {D3DTOP_SUBTRACT, "SUBTRACT", D3DTEXOPCAPS_SUBTRACT, D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
2973 {D3DTOP_ADDSMOOTH, "ADDSMOOTH", D3DTEXOPCAPS_ADDSMOOTH, D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
2974 {D3DTOP_BLENDDIFFUSEALPHA, "BLENDDIFFUSEALPHA", D3DTEXOPCAPS_BLENDDIFFUSEALPHA, D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
2975 {D3DTOP_BLENDTEXTUREALPHA, "BLENDTEXTUREALPHA", D3DTEXOPCAPS_BLENDTEXTUREALPHA, D3DCOLOR_ARGB(0x00, 0x14, 0xad, 0x14)},
2976 {D3DTOP_BLENDFACTORALPHA, "BLENDFACTORALPHA", D3DTEXOPCAPS_BLENDFACTORALPHA, D3DCOLOR_ARGB(0x00, 0x07, 0xe4, 0x07)},
2977 {D3DTOP_BLENDTEXTUREALPHAPM, "BLENDTEXTUREALPHAPM", D3DTEXOPCAPS_BLENDTEXTUREALPHAPM, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
2978 {D3DTOP_BLENDCURRENTALPHA, "BLENDCURRENTALPHA", D3DTEXOPCAPS_BLENDCURRENTALPHA, D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
2979 {D3DTOP_MODULATEALPHA_ADDCOLOR, "MODULATEALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x1f, 0xff, 0x1f)},
2980 {D3DTOP_MODULATECOLOR_ADDALPHA, "MODULATECOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0x99, 0xcc, 0x99)},
2981 {D3DTOP_MODULATEINVALPHA_ADDCOLOR, "MODULATEINVALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
2982 {D3DTOP_MODULATEINVCOLOR_ADDALPHA, "MODULATEINVCOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0xcc, 0x99, 0xcc)},
2983 /* BUMPENVMAP & BUMPENVMAPLUMINANCE have their own tests */
2984 {D3DTOP_DOTPRODUCT3, "DOTPRODUCT2", D3DTEXOPCAPS_DOTPRODUCT3, D3DCOLOR_ARGB(0x00, 0x99, 0x99, 0x99)},
2985 {D3DTOP_MULTIPLYADD, "MULTIPLYADD", D3DTEXOPCAPS_MULTIPLYADD, D3DCOLOR_ARGB(0x00, 0xff, 0x33, 0x00)},
2986 {D3DTOP_LERP, "LERP", D3DTEXOPCAPS_LERP, D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x33)},
2989 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
2990 0, 0, 640, 480, NULL, NULL, NULL, NULL);
2991 d3d = Direct3DCreate8(D3D_SDK_VERSION);
2992 ok(!!d3d, "Failed to create a D3D object.\n");
2993 if (!(device = create_device(d3d, window, window, TRUE)))
2995 skip("Failed to create a D3D device, skipping tests.\n");
2996 goto done;
2999 memset(&caps, 0, sizeof(caps));
3000 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
3001 ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
3003 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX0);
3004 ok(SUCCEEDED(hr), "SetVertexShader failed with 0x%08x\n", hr);
3006 hr = IDirect3DDevice8_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture);
3007 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
3008 hr = IDirect3DTexture8_LockRect(texture, 0, &locked_rect, NULL, 0);
3009 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
3010 *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x99, 0x00, 0xff, 0x00);
3011 hr = IDirect3DTexture8_UnlockRect(texture, 0);
3012 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
3013 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
3014 ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
3016 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG0, D3DTA_DIFFUSE);
3017 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
3018 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
3019 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
3020 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
3021 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
3023 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
3024 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
3026 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3027 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
3028 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xdd333333);
3029 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
3030 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_ALPHA);
3031 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
3033 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
3034 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
3036 for (i = 0; i < sizeof(test_data) / sizeof(*test_data); ++i)
3038 if (!(caps.TextureOpCaps & test_data[i].caps_flag))
3040 skip("tex operation %s not supported\n", test_data[i].name);
3041 continue;
3044 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLOROP, test_data[i].op);
3045 ok(SUCCEEDED(hr), "SetTextureStageState (%s) failed with 0x%08x\n", test_data[i].name, hr);
3047 hr = IDirect3DDevice8_BeginScene(device);
3048 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
3050 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
3051 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
3053 hr = IDirect3DDevice8_EndScene(device);
3054 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
3056 color = getPixelColor(device, 320, 240);
3057 ok(color_match(color, test_data[i].result, 3), "Operation %s returned color 0x%08x, expected 0x%08x\n",
3058 test_data[i].name, color, test_data[i].result);
3060 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
3061 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
3063 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
3064 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
3067 IDirect3DTexture8_Release(texture);
3068 refcount = IDirect3DDevice8_Release(device);
3069 ok(!refcount, "Device has %u references left.\n", refcount);
3070 done:
3071 IDirect3D8_Release(d3d);
3072 DestroyWindow(window);
3075 /* This test tests depth clamping / clipping behaviour:
3076 * - With software vertex processing, depth values are clamped to the
3077 * minimum / maximum z value when D3DRS_CLIPPING is disabled, and clipped
3078 * when D3DRS_CLIPPING is enabled. Pretransformed vertices behave the
3079 * same as regular vertices here.
3080 * - With hardware vertex processing, D3DRS_CLIPPING seems to be ignored.
3081 * Normal vertices are always clipped. Pretransformed vertices are
3082 * clipped when D3DPMISCCAPS_CLIPTLVERTS is set, clamped when it isn't.
3083 * - The viewport's MinZ/MaxZ is irrelevant for this.
3085 static void depth_clamp_test(void)
3087 IDirect3DDevice8 *device;
3088 D3DVIEWPORT8 vp;
3089 IDirect3D8 *d3d;
3090 D3DCOLOR color;
3091 ULONG refcount;
3092 D3DCAPS8 caps;
3093 HWND window;
3094 HRESULT hr;
3096 static const struct
3098 struct vec4 position;
3099 DWORD diffuse;
3101 quad1[] =
3103 {{ 0.0f, 0.0f, 5.0f, 1.0f}, 0xff002b7f},
3104 {{640.0f, 0.0f, 5.0f, 1.0f}, 0xff002b7f},
3105 {{ 0.0f, 480.0f, 5.0f, 1.0f}, 0xff002b7f},
3106 {{640.0f, 480.0f, 5.0f, 1.0f}, 0xff002b7f},
3108 quad2[] =
3110 {{ 0.0f, 300.0f, 10.0f, 1.0f}, 0xfff9e814},
3111 {{640.0f, 300.0f, 10.0f, 1.0f}, 0xfff9e814},
3112 {{ 0.0f, 360.0f, 10.0f, 1.0f}, 0xfff9e814},
3113 {{640.0f, 360.0f, 10.0f, 1.0f}, 0xfff9e814},
3115 quad3[] =
3117 {{112.0f, 108.0f, 5.0f, 1.0f}, 0xffffffff},
3118 {{208.0f, 108.0f, 5.0f, 1.0f}, 0xffffffff},
3119 {{112.0f, 204.0f, 5.0f, 1.0f}, 0xffffffff},
3120 {{208.0f, 204.0f, 5.0f, 1.0f}, 0xffffffff},
3122 quad4[] =
3124 {{ 42.0f, 41.0f, 10.0f, 1.0f}, 0xffffffff},
3125 {{112.0f, 41.0f, 10.0f, 1.0f}, 0xffffffff},
3126 {{ 42.0f, 108.0f, 10.0f, 1.0f}, 0xffffffff},
3127 {{112.0f, 108.0f, 10.0f, 1.0f}, 0xffffffff},
3129 static const struct
3131 struct vec3 position;
3132 DWORD diffuse;
3134 quad5[] =
3136 {{-0.5f, 0.5f, 10.0f}, 0xff14f914},
3137 {{ 0.5f, 0.5f, 10.0f}, 0xff14f914},
3138 {{-0.5f, -0.5f, 10.0f}, 0xff14f914},
3139 {{ 0.5f, -0.5f, 10.0f}, 0xff14f914},
3141 quad6[] =
3143 {{-1.0f, 0.5f, 10.0f}, 0xfff91414},
3144 {{ 1.0f, 0.5f, 10.0f}, 0xfff91414},
3145 {{-1.0f, 0.25f, 10.0f}, 0xfff91414},
3146 {{ 1.0f, 0.25f, 10.0f}, 0xfff91414},
3149 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
3150 0, 0, 640, 480, NULL, NULL, NULL, NULL);
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), "SetVertexSahder 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 = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
3305 0, 0, 640, 480, NULL, NULL, NULL, NULL);
3306 d3d = Direct3DCreate8(D3D_SDK_VERSION);
3307 ok(!!d3d, "Failed to create a D3D object.\n");
3308 if (!(device = create_device(d3d, window, window, TRUE)))
3310 skip("Failed to create a D3D device, skipping tests.\n");
3311 goto done;
3314 vp.X = 0;
3315 vp.Y = 0;
3316 vp.Width = 640;
3317 vp.Height = 480;
3318 vp.MinZ = 0.0;
3319 vp.MaxZ = 1.0;
3321 hr = IDirect3DDevice8_SetViewport(device, &vp);
3322 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
3324 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3325 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3326 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
3327 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3328 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
3329 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3330 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
3331 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3332 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
3333 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
3335 hr = IDirect3DDevice8_GetDepthStencilSurface(device, &depth_stencil);
3336 ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
3337 hr = IDirect3DDevice8_GetRenderTarget(device, &backbuffer);
3338 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
3339 hr = IDirect3DDevice8_CreateRenderTarget(device, 320, 240, D3DFMT_A8R8G8B8,
3340 D3DMULTISAMPLE_NONE, FALSE, &rt1);
3341 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
3342 hr = IDirect3DDevice8_CreateRenderTarget(device, 480, 360, D3DFMT_A8R8G8B8,
3343 D3DMULTISAMPLE_NONE, FALSE, &rt2);
3344 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
3345 hr = IDirect3DDevice8_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
3346 D3DMULTISAMPLE_NONE, FALSE, &rt3);
3347 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
3349 hr = IDirect3DDevice8_SetRenderTarget(device, rt3, depth_stencil);
3350 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
3351 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0f, 0);
3352 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
3354 hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, depth_stencil);
3355 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
3356 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
3357 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
3359 hr = IDirect3DDevice8_SetRenderTarget(device, rt1, depth_stencil);
3360 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
3361 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0f, 0);
3362 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
3364 hr = IDirect3DDevice8_SetRenderTarget(device, rt2, depth_stencil);
3365 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
3366 hr = IDirect3DDevice8_BeginScene(device);
3367 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
3368 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
3369 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3370 hr = IDirect3DDevice8_EndScene(device);
3371 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
3373 hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, depth_stencil);
3374 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
3376 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
3377 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3379 hr = IDirect3DDevice8_BeginScene(device);
3380 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
3381 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
3382 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3383 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
3384 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3385 hr = IDirect3DDevice8_EndScene(device);
3386 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
3388 for (i = 0; i < 4; ++i)
3390 for (j = 0; j < 4; ++j)
3392 unsigned int x = 80 * ((2 * j) + 1);
3393 unsigned int y = 60 * ((2 * i) + 1);
3394 color = getPixelColor(device, x, y);
3395 ok(color_match(color, expected_colors[i][j], 0),
3396 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors[i][j], x, y, color);
3400 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
3401 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3403 IDirect3DSurface8_Release(depth_stencil);
3404 IDirect3DSurface8_Release(backbuffer);
3405 IDirect3DSurface8_Release(rt3);
3406 IDirect3DSurface8_Release(rt2);
3407 IDirect3DSurface8_Release(rt1);
3408 refcount = IDirect3DDevice8_Release(device);
3409 ok(!refcount, "Device has %u references left.\n", refcount);
3410 done:
3411 IDirect3D8_Release(d3d);
3412 DestroyWindow(window);
3415 /* Test that partial depth copies work the way they're supposed to. The clear
3416 * on rt2 only needs a partial copy of the onscreen depth/stencil buffer, and
3417 * the following draw should only copy back the part that was modified. */
3418 static void depth_buffer2_test(void)
3420 IDirect3DSurface8 *backbuffer, *rt1, *rt2;
3421 IDirect3DSurface8 *depth_stencil;
3422 IDirect3DDevice8 *device;
3423 unsigned int i, j;
3424 D3DVIEWPORT8 vp;
3425 IDirect3D8 *d3d;
3426 D3DCOLOR color;
3427 ULONG refcount;
3428 HWND window;
3429 HRESULT hr;
3431 static const struct
3433 struct vec3 position;
3434 DWORD diffuse;
3436 quad[] =
3438 {{-1.0f, 1.0f, 0.66f}, 0xffff0000},
3439 {{ 1.0f, 1.0f, 0.66f}, 0xffff0000},
3440 {{-1.0f, -1.0f, 0.66f}, 0xffff0000},
3441 {{ 1.0f, -1.0f, 0.66f}, 0xffff0000},
3444 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
3445 0, 0, 640, 480, NULL, NULL, NULL, NULL);
3446 d3d = Direct3DCreate8(D3D_SDK_VERSION);
3447 ok(!!d3d, "Failed to create a D3D object.\n");
3448 if (!(device = create_device(d3d, window, window, TRUE)))
3450 skip("Failed to create a D3D device, skipping tests.\n");
3451 goto done;
3454 vp.X = 0;
3455 vp.Y = 0;
3456 vp.Width = 640;
3457 vp.Height = 480;
3458 vp.MinZ = 0.0;
3459 vp.MaxZ = 1.0;
3461 hr = IDirect3DDevice8_SetViewport(device, &vp);
3462 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
3464 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3465 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3466 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
3467 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3468 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
3469 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3470 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
3471 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3472 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
3473 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
3475 hr = IDirect3DDevice8_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
3476 D3DMULTISAMPLE_NONE, FALSE, &rt1);
3477 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
3478 hr = IDirect3DDevice8_CreateRenderTarget(device, 480, 360, D3DFMT_A8R8G8B8,
3479 D3DMULTISAMPLE_NONE, FALSE, &rt2);
3480 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
3481 hr = IDirect3DDevice8_GetDepthStencilSurface(device, &depth_stencil);
3482 ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
3483 hr = IDirect3DDevice8_GetRenderTarget(device, &backbuffer);
3484 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
3486 hr = IDirect3DDevice8_SetRenderTarget(device, rt1, depth_stencil);
3487 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
3488 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
3489 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
3491 hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, depth_stencil);
3492 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
3493 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 0.5f, 0);
3494 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
3496 hr = IDirect3DDevice8_SetRenderTarget(device, rt2, depth_stencil);
3497 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
3498 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0f, 0);
3499 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
3501 hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, depth_stencil);
3502 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
3504 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
3505 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3507 hr = IDirect3DDevice8_BeginScene(device);
3508 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
3509 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
3510 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3511 hr = IDirect3DDevice8_EndScene(device);
3512 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
3514 for (i = 0; i < 4; ++i)
3516 for (j = 0; j < 4; ++j)
3518 unsigned int x = 80 * ((2 * j) + 1);
3519 unsigned int y = 60 * ((2 * i) + 1);
3520 color = getPixelColor(device, x, y);
3521 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
3522 "Expected color 0x0000ff00 %u,%u, got 0x%08x.\n", x, y, color);
3526 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
3527 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3529 IDirect3DSurface8_Release(depth_stencil);
3530 IDirect3DSurface8_Release(backbuffer);
3531 IDirect3DSurface8_Release(rt2);
3532 IDirect3DSurface8_Release(rt1);
3533 refcount = IDirect3DDevice8_Release(device);
3534 ok(!refcount, "Device has %u references left.\n", refcount);
3535 done:
3536 IDirect3D8_Release(d3d);
3537 DestroyWindow(window);
3540 static void intz_test(void)
3542 IDirect3DSurface8 *original_rt, *rt;
3543 struct surface_readback rb;
3544 IDirect3DTexture8 *texture;
3545 IDirect3DDevice8 *device;
3546 IDirect3DSurface8 *ds;
3547 IDirect3D8 *d3d;
3548 ULONG refcount;
3549 D3DCAPS8 caps;
3550 HWND window;
3551 HRESULT hr;
3552 DWORD ps;
3553 UINT i;
3555 static const DWORD ps_code[] =
3557 0xffff0101, /* ps_1_1 */
3558 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c0, 1.0, 0.0, 1.0, 1.0 */
3559 0x00000051, 0xa00f0001, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c1, 0.0, 1.0, 0.0, 0.0 */
3560 0x00000042, 0xb00f0000, /* tex t0 */
3561 0x00000042, 0xb00f0001, /* tex t1 */
3562 0x00000005, 0xb00f0000, 0xa0e40000, 0xb0e40000, /* mul t0, c0, t0 */
3563 0x00000004, 0x800f0000, 0xa0e40001, 0xb0e40001, 0xb0e40000, /* mad r0, c1, t1, t0 */
3564 0x0000ffff, /* end */
3566 static const struct
3568 float x, y, z;
3569 float s0, t0, p0;
3570 float s1, t1, p1, q1;
3572 quad[] =
3574 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.5f},
3575 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
3576 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
3577 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.5f},
3579 half_quad_1[] =
3581 { -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.5f},
3582 { 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
3583 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
3584 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.5f},
3586 half_quad_2[] =
3588 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.5f},
3589 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
3590 { -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
3591 { 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.5f},
3593 static const struct
3595 UINT x, y;
3596 D3DCOLOR color;
3598 expected_colors[] =
3600 { 80, 100, 0x20204020},
3601 {240, 100, 0x6060bf60},
3602 {400, 100, 0x9f9f409f},
3603 {560, 100, 0xdfdfbfdf},
3604 { 80, 450, 0x20204020},
3605 {240, 450, 0x6060bf60},
3606 {400, 450, 0x9f9f409f},
3607 {560, 450, 0xdfdfbfdf},
3610 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
3611 0, 0, 640, 480, NULL, NULL, NULL, NULL);
3612 d3d = Direct3DCreate8(D3D_SDK_VERSION);
3613 ok(!!d3d, "Failed to create a D3D object.\n");
3614 if (!(device = create_device(d3d, window, window, TRUE)))
3616 skip("Failed to create a D3D device, skipping tests.\n");
3617 goto done;
3620 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
3621 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
3622 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 1))
3624 skip("No pixel shader 1.1 support, skipping INTZ test.\n");
3625 IDirect3DDevice8_Release(device);
3626 goto done;
3628 if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
3630 skip("No unconditional NP2 texture support, skipping INTZ test.\n");
3631 IDirect3DDevice8_Release(device);
3632 goto done;
3635 if (FAILED(hr = IDirect3D8_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
3636 D3DFMT_X8R8G8B8, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, MAKEFOURCC('I','N','T','Z'))))
3638 skip("No INTZ support, skipping INTZ test.\n");
3639 IDirect3DDevice8_Release(device);
3640 goto done;
3643 hr = IDirect3DDevice8_GetRenderTarget(device, &original_rt);
3644 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
3646 hr = IDirect3DDevice8_CreateTexture(device, 640, 480, 1,
3647 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture);
3648 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
3649 hr = IDirect3DDevice8_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
3650 D3DMULTISAMPLE_NONE, FALSE, &rt);
3651 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
3652 hr = IDirect3DDevice8_CreatePixelShader(device, ps_code, &ps);
3653 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
3655 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX2
3656 | D3DFVF_TEXCOORDSIZE3(0) | D3DFVF_TEXCOORDSIZE4(1));
3657 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
3658 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
3659 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3660 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
3661 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3662 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
3663 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3664 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3665 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3667 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MINFILTER, D3DTEXF_POINT);
3668 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3669 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MIPFILTER, D3DTEXF_POINT);
3670 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3671 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MAGFILTER, D3DTEXF_POINT);
3672 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3673 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
3674 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3676 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP);
3677 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3678 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP);
3679 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3680 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MAGFILTER, D3DTEXF_POINT);
3681 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3682 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MINFILTER, D3DTEXF_POINT);
3683 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3684 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MIPFILTER, D3DTEXF_POINT);
3685 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3686 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS,
3687 D3DTTFF_COUNT4 | D3DTTFF_PROJECTED);
3688 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3690 hr = IDirect3DTexture8_GetSurfaceLevel(texture, 0, &ds);
3691 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
3693 /* Render offscreen, using the INTZ texture as depth buffer */
3694 hr = IDirect3DDevice8_SetRenderTarget(device, rt, ds);
3695 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
3696 hr = IDirect3DDevice8_SetPixelShader(device, 0);
3697 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
3699 /* Setup the depth/stencil surface. */
3700 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
3701 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
3703 hr = IDirect3DDevice8_BeginScene(device);
3704 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
3705 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
3706 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3707 hr = IDirect3DDevice8_EndScene(device);
3708 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
3710 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, NULL);
3711 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
3712 IDirect3DSurface8_Release(ds);
3713 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
3714 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
3715 hr = IDirect3DDevice8_SetTexture(device, 1, (IDirect3DBaseTexture8 *)texture);
3716 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
3717 hr = IDirect3DDevice8_SetPixelShader(device, ps);
3718 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
3720 /* Read the depth values back. */
3721 hr = IDirect3DDevice8_BeginScene(device);
3722 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
3723 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
3724 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3725 hr = IDirect3DDevice8_EndScene(device);
3726 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
3728 get_rt_readback(original_rt, &rb);
3729 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
3731 D3DCOLOR color = get_readback_color(&rb, expected_colors[i].x, expected_colors[i].y);
3732 ok(color_match(color, expected_colors[i].color, 1),
3733 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
3734 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
3736 release_surface_readback(&rb);
3738 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
3739 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
3741 hr = IDirect3DDevice8_SetTexture(device, 0, NULL);
3742 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
3743 hr = IDirect3DDevice8_SetTexture(device, 1, NULL);
3744 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
3745 IDirect3DTexture8_Release(texture);
3747 /* Render onscreen while using the INTZ texture as depth buffer */
3748 hr = IDirect3DDevice8_CreateTexture(device, 640, 480, 1,
3749 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture);
3750 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
3751 hr = IDirect3DTexture8_GetSurfaceLevel(texture, 0, &ds);
3752 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
3753 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, ds);
3754 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
3755 hr = IDirect3DDevice8_SetPixelShader(device, 0);
3756 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
3758 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
3759 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
3761 hr = IDirect3DDevice8_BeginScene(device);
3762 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
3763 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
3764 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3765 hr = IDirect3DDevice8_EndScene(device);
3766 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
3768 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, NULL);
3769 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
3770 IDirect3DSurface8_Release(ds);
3771 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
3772 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
3773 hr = IDirect3DDevice8_SetTexture(device, 1, (IDirect3DBaseTexture8 *)texture);
3774 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
3775 hr = IDirect3DDevice8_SetPixelShader(device, ps);
3776 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
3778 /* Read the depth values back. */
3779 hr = IDirect3DDevice8_BeginScene(device);
3780 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
3781 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
3782 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3783 hr = IDirect3DDevice8_EndScene(device);
3784 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
3786 get_rt_readback(original_rt, &rb);
3787 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
3789 D3DCOLOR color = get_readback_color(&rb, expected_colors[i].x, expected_colors[i].y);
3790 ok(color_match(color, expected_colors[i].color, 1),
3791 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
3792 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
3794 release_surface_readback(&rb);
3796 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
3797 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
3799 hr = IDirect3DDevice8_SetTexture(device, 0, NULL);
3800 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
3801 hr = IDirect3DDevice8_SetTexture(device, 1, NULL);
3802 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
3803 IDirect3DTexture8_Release(texture);
3805 /* Render offscreen, then onscreen, and finally check the INTZ texture in both areas */
3806 hr = IDirect3DDevice8_CreateTexture(device, 640, 480, 1,
3807 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture);
3808 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
3809 hr = IDirect3DTexture8_GetSurfaceLevel(texture, 0, &ds);
3810 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
3811 hr = IDirect3DDevice8_SetRenderTarget(device, rt, ds);
3812 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
3813 hr = IDirect3DDevice8_SetPixelShader(device, 0);
3814 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
3816 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
3817 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
3819 hr = IDirect3DDevice8_BeginScene(device);
3820 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
3821 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, half_quad_1, sizeof(*half_quad_1));
3822 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3823 hr = IDirect3DDevice8_EndScene(device);
3824 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
3826 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, ds);
3827 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
3829 hr = IDirect3DDevice8_BeginScene(device);
3830 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
3831 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, half_quad_2, sizeof(*half_quad_2));
3832 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3833 hr = IDirect3DDevice8_EndScene(device);
3834 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
3836 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, NULL);
3837 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
3838 IDirect3DSurface8_Release(ds);
3839 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
3840 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
3841 hr = IDirect3DDevice8_SetTexture(device, 1, (IDirect3DBaseTexture8 *)texture);
3842 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
3843 hr = IDirect3DDevice8_SetPixelShader(device, ps);
3844 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
3846 /* Read the depth values back. */
3847 hr = IDirect3DDevice8_BeginScene(device);
3848 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
3849 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
3850 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3851 hr = IDirect3DDevice8_EndScene(device);
3852 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
3854 get_rt_readback(original_rt, &rb);
3855 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
3857 D3DCOLOR color = get_readback_color(&rb, expected_colors[i].x, expected_colors[i].y);
3858 ok(color_match(color, expected_colors[i].color, 1),
3859 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
3860 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
3862 release_surface_readback(&rb);
3864 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
3865 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
3867 IDirect3DTexture8_Release(texture);
3868 hr = IDirect3DDevice8_DeletePixelShader(device, ps);
3869 ok(SUCCEEDED(hr), "DeletePixelShader failed, hr %#x.\n", hr);
3870 IDirect3DSurface8_Release(original_rt);
3871 IDirect3DSurface8_Release(rt);
3872 refcount = IDirect3DDevice8_Release(device);
3873 ok(!refcount, "Device has %u references left.\n", refcount);
3874 done:
3875 IDirect3D8_Release(d3d);
3876 DestroyWindow(window);
3879 static void shadow_test(void)
3881 IDirect3DSurface8 *original_rt, *rt;
3882 struct surface_readback rb;
3883 IDirect3DDevice8 *device;
3884 IDirect3D8 *d3d;
3885 ULONG refcount;
3886 D3DCAPS8 caps;
3887 HWND window;
3888 HRESULT hr;
3889 DWORD ps;
3890 UINT i;
3892 static const DWORD ps_code[] =
3894 0xffff0101, /* ps_1_1 */
3895 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c0, 1.0, 0.0, 1.0, 1.0 */
3896 0x00000051, 0xa00f0001, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c1, 0.0, 1.0, 0.0, 0.0 */
3897 0x00000042, 0xb00f0000, /* tex t0 */
3898 0x00000042, 0xb00f0001, /* tex t1 */
3899 0x00000005, 0xb00f0000, 0xa0e40000, 0xb0e40000, /* mul t0, c0, t0 */
3900 0x00000004, 0x800f0000, 0xa0e40001, 0xb0e40001, 0xb0e40000, /* mad r0, c1, t1, t0 */
3901 0x0000ffff, /* end */
3903 static const struct
3905 D3DFORMAT format;
3906 const char *name;
3908 formats[] =
3910 {D3DFMT_D16_LOCKABLE, "D3DFMT_D16_LOCKABLE"},
3911 {D3DFMT_D32, "D3DFMT_D32"},
3912 {D3DFMT_D15S1, "D3DFMT_D15S1"},
3913 {D3DFMT_D24S8, "D3DFMT_D24S8"},
3914 {D3DFMT_D24X8, "D3DFMT_D24X8"},
3915 {D3DFMT_D24X4S4, "D3DFMT_D24X4S4"},
3916 {D3DFMT_D16, "D3DFMT_D16"},
3918 static const struct
3920 float x, y, z;
3921 float s0, t0, p0;
3922 float s1, t1, p1, q1;
3924 quad[] =
3926 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f},
3927 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f},
3928 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
3929 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f},
3931 static const struct
3933 UINT x, y;
3934 D3DCOLOR color;
3936 expected_colors[] =
3938 {400, 60, 0x00000000},
3939 {560, 180, 0xffff00ff},
3940 {560, 300, 0xffff00ff},
3941 {400, 420, 0xffffffff},
3942 {240, 420, 0xffffffff},
3943 { 80, 300, 0x00000000},
3944 { 80, 180, 0x00000000},
3945 {240, 60, 0x00000000},
3948 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
3949 0, 0, 640, 480, NULL, NULL, NULL, NULL);
3950 d3d = Direct3DCreate8(D3D_SDK_VERSION);
3951 ok(!!d3d, "Failed to create a D3D object.\n");
3952 if (!(device = create_device(d3d, window, window, TRUE)))
3954 skip("Failed to create a D3D device, skipping tests.\n");
3955 goto done;
3958 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
3959 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
3960 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 1))
3962 skip("No pixel shader 1.1 support, skipping shadow test.\n");
3963 IDirect3DDevice8_Release(device);
3964 goto done;
3967 hr = IDirect3DDevice8_GetRenderTarget(device, &original_rt);
3968 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
3970 hr = IDirect3DDevice8_CreateRenderTarget(device, 1024, 1024, D3DFMT_A8R8G8B8,
3971 D3DMULTISAMPLE_NONE, FALSE, &rt);
3972 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
3973 hr = IDirect3DDevice8_CreatePixelShader(device, ps_code, &ps);
3974 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
3976 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX2
3977 | D3DFVF_TEXCOORDSIZE3(0) | D3DFVF_TEXCOORDSIZE4(1));
3978 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
3979 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
3980 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3981 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
3982 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3983 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
3984 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3985 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3986 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3988 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MINFILTER, D3DTEXF_POINT);
3989 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3990 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MIPFILTER, D3DTEXF_POINT);
3991 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3992 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MAGFILTER, D3DTEXF_POINT);
3993 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3994 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
3995 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3997 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP);
3998 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3999 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP);
4000 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
4001 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MAGFILTER, D3DTEXF_POINT);
4002 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
4003 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MINFILTER, D3DTEXF_POINT);
4004 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
4005 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MIPFILTER, D3DTEXF_POINT);
4006 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
4007 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS,
4008 D3DTTFF_COUNT4 | D3DTTFF_PROJECTED);
4009 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
4011 for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
4013 D3DFORMAT format = formats[i].format;
4014 IDirect3DTexture8 *texture;
4015 IDirect3DSurface8 *ds;
4016 unsigned int j;
4018 if (FAILED(IDirect3D8_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
4019 D3DFMT_X8R8G8B8, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, format)))
4020 continue;
4022 hr = IDirect3DDevice8_CreateTexture(device, 1024, 1024, 1,
4023 D3DUSAGE_DEPTHSTENCIL, format, D3DPOOL_DEFAULT, &texture);
4024 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
4026 hr = IDirect3DTexture8_GetSurfaceLevel(texture, 0, &ds);
4027 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
4029 hr = IDirect3DDevice8_SetRenderTarget(device, rt, ds);
4030 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
4032 hr = IDirect3DDevice8_SetPixelShader(device, 0);
4033 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
4035 /* Setup the depth/stencil surface. */
4036 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
4037 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
4039 hr = IDirect3DDevice8_BeginScene(device);
4040 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
4041 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
4042 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
4043 hr = IDirect3DDevice8_EndScene(device);
4044 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
4046 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, NULL);
4047 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
4048 IDirect3DSurface8_Release(ds);
4050 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
4051 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
4052 hr = IDirect3DDevice8_SetTexture(device, 1, (IDirect3DBaseTexture8 *)texture);
4053 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
4055 hr = IDirect3DDevice8_SetPixelShader(device, ps);
4056 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
4058 /* Do the actual shadow mapping. */
4059 hr = IDirect3DDevice8_BeginScene(device);
4060 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
4061 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
4062 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
4063 hr = IDirect3DDevice8_EndScene(device);
4064 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
4066 hr = IDirect3DDevice8_SetTexture(device, 0, NULL);
4067 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
4068 hr = IDirect3DDevice8_SetTexture(device, 1, NULL);
4069 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
4070 IDirect3DTexture8_Release(texture);
4072 get_rt_readback(original_rt, &rb);
4073 for (j = 0; j < sizeof(expected_colors) / sizeof(*expected_colors); ++j)
4075 D3DCOLOR color = get_readback_color(&rb, expected_colors[j].x, expected_colors[j].y);
4076 ok(color_match(color, expected_colors[j].color, 0),
4077 "Expected color 0x%08x at (%u, %u) for format %s, got 0x%08x.\n",
4078 expected_colors[j].color, expected_colors[j].x, expected_colors[j].y,
4079 formats[i].name, color);
4081 release_surface_readback(&rb);
4083 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
4084 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
4087 hr = IDirect3DDevice8_DeletePixelShader(device, ps);
4088 ok(SUCCEEDED(hr), "DeletePixelShader failed, hr %#x.\n", hr);
4089 IDirect3DSurface8_Release(original_rt);
4090 IDirect3DSurface8_Release(rt);
4091 refcount = IDirect3DDevice8_Release(device);
4092 ok(!refcount, "Device has %u references left.\n", refcount);
4093 done:
4094 IDirect3D8_Release(d3d);
4095 DestroyWindow(window);
4098 static void multisample_copy_rects_test(void)
4100 IDirect3DSurface8 *ds, *ds_plain, *rt, *readback;
4101 RECT src_rect = {64, 64, 128, 128};
4102 POINT dst_point = {96, 96};
4103 D3DLOCKED_RECT locked_rect;
4104 IDirect3DDevice8 *device;
4105 IDirect3D8 *d3d;
4106 D3DCOLOR color;
4107 ULONG refcount;
4108 HWND window;
4109 HRESULT hr;
4111 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
4112 0, 0, 640, 480, NULL, NULL, NULL, NULL);
4113 d3d = Direct3DCreate8(D3D_SDK_VERSION);
4114 ok(!!d3d, "Failed to create a D3D object.\n");
4115 if (!(device = create_device(d3d, window, window, TRUE)))
4117 skip("Failed to create a D3D device, skipping tests.\n");
4118 goto done;
4121 if (FAILED(IDirect3D8_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT,
4122 D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES)))
4124 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping multisampled CopyRects test.\n");
4125 IDirect3DDevice8_Release(device);
4126 goto done;
4129 hr = IDirect3DDevice8_CreateRenderTarget(device, 256, 256, D3DFMT_A8R8G8B8,
4130 D3DMULTISAMPLE_2_SAMPLES, FALSE, &rt);
4131 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
4132 hr = IDirect3DDevice8_CreateDepthStencilSurface(device, 256, 256, D3DFMT_D24S8,
4133 D3DMULTISAMPLE_2_SAMPLES, &ds);
4134 ok(SUCCEEDED(hr), "Failed to create depth stencil surface, hr %#x.\n", hr);
4135 hr = IDirect3DDevice8_CreateDepthStencilSurface(device, 256, 256, D3DFMT_D24S8,
4136 D3DMULTISAMPLE_NONE, &ds_plain);
4137 ok(SUCCEEDED(hr), "Failed to create depth stencil surface, hr %#x.\n", hr);
4138 hr = IDirect3DDevice8_CreateImageSurface(device, 256, 256, D3DFMT_A8R8G8B8, &readback);
4139 ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
4141 hr = IDirect3DDevice8_SetRenderTarget(device, rt, ds);
4142 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
4144 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
4145 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
4147 hr = IDirect3DDevice8_CopyRects(device, rt, NULL, 0, readback, NULL);
4148 ok(SUCCEEDED(hr), "Failed to read render target back, hr %#x.\n", hr);
4150 hr = IDirect3DDevice8_CopyRects(device, ds, NULL, 0, ds_plain, NULL);
4151 ok(hr == D3DERR_INVALIDCALL, "Depth buffer copy, hr %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
4153 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4154 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
4156 hr = IDirect3DDevice8_CopyRects(device, rt, &src_rect, 1, readback, &dst_point);
4157 ok(SUCCEEDED(hr), "Failed to read render target back, hr %#x.\n", hr);
4159 hr = IDirect3DSurface8_LockRect(readback, &locked_rect, NULL, D3DLOCK_READONLY);
4160 ok(SUCCEEDED(hr), "Failed to lock readback surface, hr %#x.\n", hr);
4162 color = *(DWORD *)((BYTE *)locked_rect.pBits + 31 * locked_rect.Pitch + 31 * 4);
4163 ok(color == 0xff00ff00, "Got unexpected color 0x%08x.\n", color);
4165 color = *(DWORD *)((BYTE *)locked_rect.pBits + 127 * locked_rect.Pitch + 127 * 4);
4166 ok(color == 0xffff0000, "Got unexpected color 0x%08x.\n", color);
4168 hr = IDirect3DSurface8_UnlockRect(readback);
4169 ok(SUCCEEDED(hr), "Failed to unlock readback surface, hr %#x.\n", hr);
4171 IDirect3DSurface8_Release(readback);
4172 IDirect3DSurface8_Release(ds_plain);
4173 IDirect3DSurface8_Release(ds);
4174 IDirect3DSurface8_Release(rt);
4175 refcount = IDirect3DDevice8_Release(device);
4176 ok(!refcount, "Device has %u references left.\n", refcount);
4177 done:
4178 IDirect3D8_Release(d3d);
4179 DestroyWindow(window);
4182 static void resz_test(void)
4184 IDirect3DSurface8 *rt, *original_rt, *ds, *original_ds, *intz_ds;
4185 IDirect3DTexture8 *texture;
4186 IDirect3DDevice8 *device;
4187 IDirect3D8 *d3d;
4188 DWORD ps, value;
4189 unsigned int i;
4190 ULONG refcount;
4191 D3DCAPS8 caps;
4192 HWND window;
4193 HRESULT hr;
4195 static const DWORD ps_code[] =
4197 0xffff0101, /* ps_1_1 */
4198 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1.0, 0.0, 0.0, 0.0 */
4199 0x00000051, 0xa00f0001, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c1, 0.0, 1.0, 0.0, 0.0 */
4200 0x00000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c2, 0.0, 0.0, 1.0, 0.0 */
4201 0x00000042, 0xb00f0000, /* tex t0 */
4202 0x00000042, 0xb00f0001, /* tex t1 */
4203 0x00000008, 0xb0070001, 0xa0e40000, 0xb0e40001, /* dp3 t1.xyz, c0, t1 */
4204 0x00000005, 0x80070000, 0xa0e40001, 0xb0e40001, /* mul r0.xyz, c1, t1 */
4205 0x00000004, 0x80070000, 0xa0e40000, 0xb0e40000, 0x80e40000, /* mad r0.xyz, c0, t0, r0 */
4206 0x40000001, 0x80080000, 0xa0aa0002, /* +mov r0.w, c2.z */
4207 0x0000ffff, /* end */
4209 static const struct
4211 float x, y, z;
4212 float s0, t0, p0;
4213 float s1, t1, p1, q1;
4215 quad[] =
4217 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.5f},
4218 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
4219 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
4220 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.5f},
4222 static const struct
4224 UINT x, y;
4225 D3DCOLOR color;
4227 expected_colors[] =
4229 { 80, 100, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
4230 {240, 100, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
4231 {400, 100, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
4232 {560, 100, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
4233 { 80, 450, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
4234 {240, 450, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
4235 {400, 450, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
4236 {560, 450, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
4239 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
4240 0, 0, 640, 480, NULL, NULL, NULL, NULL);
4241 d3d = Direct3DCreate8(D3D_SDK_VERSION);
4242 ok(!!d3d, "Failed to create a D3D object.\n");
4243 if (!(device = create_device(d3d, window, window, TRUE)))
4245 skip("Failed to create a D3D device, skipping tests.\n");
4246 goto done;
4249 if (FAILED(IDirect3D8_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT,
4250 D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES)))
4252 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping RESZ test.\n");
4253 IDirect3DDevice8_Release(device);
4254 goto done;
4256 if (FAILED(IDirect3D8_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT,
4257 D3DDEVTYPE_HAL, D3DFMT_D24S8, TRUE, D3DMULTISAMPLE_2_SAMPLES)))
4259 skip("Multisampling not supported for D3DFMT_D24S8, skipping RESZ test.\n");
4260 IDirect3DDevice8_Release(device);
4261 goto done;
4263 if (FAILED(IDirect3D8_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
4264 D3DFMT_X8R8G8B8, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, MAKEFOURCC('I','N','T','Z'))))
4266 skip("No INTZ support, skipping RESZ test.\n");
4267 IDirect3DDevice8_Release(device);
4268 goto done;
4270 if (FAILED(IDirect3D8_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
4271 D3DFMT_X8R8G8B8, D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE, MAKEFOURCC('R','E','S','Z'))))
4273 skip("No RESZ support, skipping RESZ test.\n");
4274 IDirect3DDevice8_Release(device);
4275 goto done;
4278 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
4279 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
4280 if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
4282 skip("No unconditional NP2 texture support, skipping INTZ test.\n");
4283 IDirect3DDevice8_Release(device);
4284 goto done;
4287 hr = IDirect3DDevice8_GetRenderTarget(device, &original_rt);
4288 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
4289 hr = IDirect3DDevice8_GetDepthStencilSurface(device, &original_ds);
4290 ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#x.\n", hr);
4292 hr = IDirect3DDevice8_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
4293 D3DMULTISAMPLE_2_SAMPLES, FALSE, &rt);
4294 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
4295 hr = IDirect3DDevice8_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
4296 D3DMULTISAMPLE_2_SAMPLES, &ds);
4298 hr = IDirect3DDevice8_CreateTexture(device, 640, 480, 1,
4299 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture);
4300 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
4301 hr = IDirect3DTexture8_GetSurfaceLevel(texture, 0, &intz_ds);
4302 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
4304 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, intz_ds);
4305 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
4306 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
4307 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
4309 hr = IDirect3DDevice8_SetRenderTarget(device, rt, ds);
4310 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
4311 IDirect3DSurface8_Release(intz_ds);
4312 hr = IDirect3DDevice8_CreatePixelShader(device, ps_code, &ps);
4313 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
4315 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX2
4316 | D3DFVF_TEXCOORDSIZE3(0) | D3DFVF_TEXCOORDSIZE4(1));
4317 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
4318 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
4319 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
4320 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
4321 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
4322 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
4323 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
4324 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
4325 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
4327 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MINFILTER, D3DTEXF_POINT);
4328 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
4329 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MIPFILTER, D3DTEXF_POINT);
4330 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
4331 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MAGFILTER, D3DTEXF_POINT);
4332 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
4333 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
4334 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
4336 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP);
4337 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
4338 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP);
4339 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
4340 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MAGFILTER, D3DTEXF_POINT);
4341 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
4342 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MINFILTER, D3DTEXF_POINT);
4343 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
4344 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MIPFILTER, D3DTEXF_POINT);
4345 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
4346 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS,
4347 D3DTTFF_COUNT4 | D3DTTFF_PROJECTED);
4348 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
4350 /* Render offscreen (multisampled), blit the depth buffer into the INTZ texture and then check its contents. */
4351 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
4352 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
4354 hr = IDirect3DDevice8_BeginScene(device);
4355 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
4356 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
4357 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
4359 /* The destination depth texture has to be bound to sampler 0 */
4360 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
4361 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
4363 /* the ATI "spec" says you have to do a dummy draw to ensure correct commands ordering */
4364 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, FALSE);
4365 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
4366 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
4367 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
4368 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0);
4369 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
4370 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
4371 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
4372 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, TRUE);
4373 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
4374 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
4375 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
4376 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0xf);
4377 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
4379 /* The actual multisampled depth buffer resolve happens here */
4380 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
4381 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
4382 hr = IDirect3DDevice8_GetRenderState(device, D3DRS_POINTSIZE, &value);
4383 ok(SUCCEEDED(hr) && value == 0x7fa05000, "GetRenderState failed, hr %#x, value %#x.\n", hr, value);
4385 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, NULL);
4386 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
4387 hr = IDirect3DDevice8_SetTexture(device, 1, (IDirect3DBaseTexture8 *)texture);
4388 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
4389 hr = IDirect3DDevice8_SetPixelShader(device, ps);
4390 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
4392 /* Read the depth values back. */
4393 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
4394 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
4395 hr = IDirect3DDevice8_EndScene(device);
4396 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
4398 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
4400 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
4401 ok(color_match(color, expected_colors[i].color, 1),
4402 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
4403 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
4406 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
4407 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
4409 /* Test edge cases - try with no texture at all */
4410 hr = IDirect3DDevice8_SetTexture(device, 0, NULL);
4411 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
4412 hr = IDirect3DDevice8_SetTexture(device, 1, NULL);
4413 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
4414 hr = IDirect3DDevice8_SetRenderTarget(device, rt, ds);
4415 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
4417 hr = IDirect3DDevice8_BeginScene(device);
4418 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
4419 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
4420 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
4421 hr = IDirect3DDevice8_EndScene(device);
4422 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
4424 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
4425 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
4427 /* With a non-multisampled depth buffer */
4428 IDirect3DSurface8_Release(ds);
4429 IDirect3DSurface8_Release(rt);
4430 hr = IDirect3DDevice8_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
4431 D3DMULTISAMPLE_NONE, &ds);
4433 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, ds);
4434 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
4435 hr = IDirect3DDevice8_SetPixelShader(device, 0);
4436 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
4438 hr = IDirect3DDevice8_BeginScene(device);
4439 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
4440 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
4441 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
4442 hr = IDirect3DDevice8_EndScene(device);
4443 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
4445 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
4446 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
4448 hr = IDirect3DDevice8_BeginScene(device);
4449 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
4450 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, FALSE);
4451 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
4452 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
4453 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
4454 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0);
4455 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
4456 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
4457 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
4458 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, TRUE);
4459 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
4460 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
4461 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
4462 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0xf);
4463 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
4464 hr = IDirect3DDevice8_EndScene(device);
4465 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
4467 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
4468 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
4470 hr = IDirect3DDevice8_SetTexture(device, 1, (IDirect3DBaseTexture8 *)texture);
4471 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
4472 hr = IDirect3DDevice8_SetPixelShader(device, ps);
4473 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
4475 /* Read the depth values back. */
4476 hr = IDirect3DDevice8_BeginScene(device);
4477 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
4478 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
4479 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
4480 hr = IDirect3DDevice8_EndScene(device);
4481 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
4483 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
4485 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
4486 ok(color_match(color, expected_colors[i].color, 1),
4487 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
4488 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
4491 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
4492 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
4494 IDirect3DSurface8_Release(ds);
4495 IDirect3DTexture8_Release(texture);
4496 hr = IDirect3DDevice8_DeletePixelShader(device, ps);
4497 ok(SUCCEEDED(hr), "DeletePixelShader failed, hr %#x.\n", hr);
4498 IDirect3DSurface8_Release(original_ds);
4499 IDirect3DSurface8_Release(original_rt);
4501 refcount = IDirect3DDevice8_Release(device);
4502 ok(!refcount, "Device has %u references left.\n", refcount);
4503 done:
4504 IDirect3D8_Release(d3d);
4505 DestroyWindow(window);
4508 static void zenable_test(void)
4510 IDirect3DDevice8 *device;
4511 IDirect3D8 *d3d;
4512 D3DCOLOR color;
4513 ULONG refcount;
4514 D3DCAPS8 caps;
4515 HWND window;
4516 HRESULT hr;
4517 UINT x, y;
4518 UINT i, j;
4519 UINT test;
4520 IDirect3DSurface8 *ds, *rt;
4522 static const struct
4524 struct vec4 position;
4525 D3DCOLOR diffuse;
4527 tquad[] =
4529 {{ 0.0f, 480.0f, -0.5f, 1.0f}, 0xff00ff00},
4530 {{ 0.0f, 0.0f, -0.5f, 1.0f}, 0xff00ff00},
4531 {{640.0f, 480.0f, 1.5f, 1.0f}, 0xff00ff00},
4532 {{640.0f, 0.0f, 1.5f, 1.0f}, 0xff00ff00},
4535 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
4536 0, 0, 640, 480, NULL, NULL, NULL, NULL);
4537 d3d = Direct3DCreate8(D3D_SDK_VERSION);
4538 ok(!!d3d, "Failed to create a D3D object.\n");
4539 if (!(device = create_device(d3d, window, window, TRUE)))
4541 skip("Failed to create a D3D device, skipping tests.\n");
4542 goto done;
4545 hr = IDirect3DDevice8_GetDepthStencilSurface(device, &ds);
4546 ok(SUCCEEDED(hr), "Failed to get depth stencil surface, hr %#x.\n", hr);
4547 hr = IDirect3DDevice8_GetRenderTarget(device, &rt);
4548 ok(SUCCEEDED(hr), "Failed to get render target surface, hr %#x.\n", hr);
4550 for (test = 0; test < 2; ++test)
4552 /* The Windows 8 testbot (WARP) appears to clip with
4553 * ZENABLE = D3DZB_TRUE and no depth buffer set. */
4554 static const D3DCOLOR expected_broken[] =
4556 0x00ff0000, 0x0000ff00, 0x0000ff00, 0x00ff0000,
4557 0x00ff0000, 0x0000ff00, 0x0000ff00, 0x00ff0000,
4558 0x00ff0000, 0x0000ff00, 0x0000ff00, 0x00ff0000,
4559 0x00ff0000, 0x0000ff00, 0x0000ff00, 0x00ff0000,
4562 if (!test)
4564 hr = IDirect3DDevice8_SetRenderTarget(device, rt, NULL);
4565 ok(SUCCEEDED(hr), "Failed to set depth stencil surface, hr %#x.\n", hr);
4567 else
4569 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
4570 ok(SUCCEEDED(hr), "Failed to disable z-buffering, hr %#x.\n", hr);
4571 hr = IDirect3DDevice8_SetRenderTarget(device, rt, ds);
4572 ok(SUCCEEDED(hr), "Failed to set depth stencil surface, hr %#x.\n", hr);
4573 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 0.0f, 0);
4574 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
4576 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
4577 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
4579 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0f, 0);
4580 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
4581 hr = IDirect3DDevice8_BeginScene(device);
4582 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
4583 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, tquad, sizeof(*tquad));
4584 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4585 hr = IDirect3DDevice8_EndScene(device);
4586 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
4588 for (i = 0; i < 4; ++i)
4590 for (j = 0; j < 4; ++j)
4592 x = 80 * ((2 * j) + 1);
4593 y = 60 * ((2 * i) + 1);
4594 color = getPixelColor(device, x, y);
4595 ok(color_match(color, 0x0000ff00, 1)
4596 || broken(color_match(color, expected_broken[i * 4 + j], 1) && !test),
4597 "Expected color 0x0000ff00 at %u, %u, got 0x%08x.\n", x, y, color);
4601 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
4602 ok(SUCCEEDED(hr), "Failed to present backbuffer, hr %#x.\n", hr);
4605 IDirect3DSurface8_Release(ds);
4606 IDirect3DSurface8_Release(rt);
4608 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
4609 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
4611 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1)
4612 && caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
4614 static const DWORD vs_code[] =
4616 0xfffe0101, /* vs_1_1 */
4617 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4618 0x00000001, 0xd00f0000, 0x90e40000, /* mov oD0, v0 */
4619 0x0000ffff
4621 static const DWORD ps_code[] =
4623 0xffff0101, /* ps_1_1 */
4624 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
4625 0x0000ffff /* end */
4627 static const struct vec3 quad[] =
4629 {-1.0f, -1.0f, -0.5f},
4630 {-1.0f, 1.0f, -0.5f},
4631 { 1.0f, -1.0f, 1.5f},
4632 { 1.0f, 1.0f, 1.5f},
4634 static const D3DCOLOR expected[] =
4636 0x00ff0000, 0x0060df60, 0x009fdf9f, 0x00ff0000,
4637 0x00ff0000, 0x00609f60, 0x009f9f9f, 0x00ff0000,
4638 0x00ff0000, 0x00606060, 0x009f609f, 0x00ff0000,
4639 0x00ff0000, 0x00602060, 0x009f209f, 0x00ff0000,
4641 /* The Windows 8 testbot (WARP) appears to not clip z for regular
4642 * vertices either. */
4643 static const D3DCOLOR expected_broken[] =
4645 0x0020df20, 0x0060df60, 0x009fdf9f, 0x00dfdfdf,
4646 0x00209f20, 0x00609f60, 0x009f9f9f, 0x00df9fdf,
4647 0x00206020, 0x00606060, 0x009f609f, 0x00df60df,
4648 0x00202020, 0x00602060, 0x009f209f, 0x00df20df,
4650 static const DWORD decl[] =
4652 D3DVSD_STREAM(0),
4653 D3DVSD_REG(D3DVSDE_POSITION, D3DVSDT_FLOAT3),
4654 D3DVSD_END()
4656 DWORD vs, ps;
4658 hr = IDirect3DDevice8_CreateVertexShader(device, decl, vs_code, &vs, 0);
4659 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
4660 hr = IDirect3DDevice8_CreatePixelShader(device, ps_code, &ps);
4661 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
4662 hr = IDirect3DDevice8_SetVertexShader(device, vs);
4663 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
4664 hr = IDirect3DDevice8_SetPixelShader(device, ps);
4665 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
4667 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0f, 0);
4668 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
4669 hr = IDirect3DDevice8_BeginScene(device);
4670 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
4671 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
4672 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4673 hr = IDirect3DDevice8_EndScene(device);
4674 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
4676 for (i = 0; i < 4; ++i)
4678 for (j = 0; j < 4; ++j)
4680 x = 80 * ((2 * j) + 1);
4681 y = 60 * ((2 * i) + 1);
4682 color = getPixelColor(device, x, y);
4683 ok(color_match(color, expected[i * 4 + j], 1)
4684 || broken(color_match(color, expected_broken[i * 4 + j], 1)),
4685 "Expected color 0x%08x at %u, %u, got 0x%08x.\n", expected[i * 4 + j], x, y, color);
4689 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
4690 ok(SUCCEEDED(hr), "Failed to present backbuffer, hr %#x.\n", hr);
4692 hr = IDirect3DDevice8_DeletePixelShader(device, ps);
4693 ok(SUCCEEDED(hr), "Failed to delete pixel shader, hr %#x.\n", hr);
4694 hr = IDirect3DDevice8_DeleteVertexShader(device, vs);
4695 ok(SUCCEEDED(hr), "Failed to delete vertex shader, hr %#x.\n", hr);
4698 refcount = IDirect3DDevice8_Release(device);
4699 ok(!refcount, "Device has %u references left.\n", refcount);
4700 done:
4701 IDirect3D8_Release(d3d);
4702 DestroyWindow(window);
4705 static void fog_special_test(void)
4707 IDirect3DDevice8 *device;
4708 IDirect3D8 *d3d;
4709 unsigned int i;
4710 D3DCOLOR color;
4711 ULONG refcount;
4712 D3DCAPS8 caps;
4713 DWORD ps, vs;
4714 HWND window;
4715 HRESULT hr;
4716 union
4718 float f;
4719 DWORD d;
4720 } conv;
4722 static const struct
4724 struct vec3 position;
4725 D3DCOLOR diffuse;
4727 quad[] =
4729 {{ -1.0f, -1.0f, 0.0f}, 0xff00ff00},
4730 {{ -1.0f, 1.0f, 0.0f}, 0xff00ff00},
4731 {{ 1.0f, -1.0f, 1.0f}, 0xff00ff00},
4732 {{ 1.0f, 1.0f, 1.0f}, 0xff00ff00}
4734 static const struct
4736 DWORD vertexmode, tablemode;
4737 BOOL vs, ps;
4738 D3DCOLOR color_left, color_right;
4740 tests[] =
4742 {D3DFOG_LINEAR, D3DFOG_NONE, FALSE, FALSE, 0x00ff0000, 0x00ff0000},
4743 {D3DFOG_LINEAR, D3DFOG_NONE, FALSE, TRUE, 0x00ff0000, 0x00ff0000},
4744 {D3DFOG_LINEAR, D3DFOG_NONE, TRUE, FALSE, 0x00ff0000, 0x00ff0000},
4745 {D3DFOG_LINEAR, D3DFOG_NONE, TRUE, TRUE, 0x00ff0000, 0x00ff0000},
4747 {D3DFOG_NONE, D3DFOG_LINEAR, FALSE, FALSE, 0x0000ff00, 0x00ff0000},
4748 {D3DFOG_NONE, D3DFOG_LINEAR, FALSE, TRUE, 0x0000ff00, 0x00ff0000},
4749 {D3DFOG_NONE, D3DFOG_LINEAR, TRUE, FALSE, 0x0000ff00, 0x00ff0000},
4750 {D3DFOG_NONE, D3DFOG_LINEAR, TRUE, TRUE, 0x0000ff00, 0x00ff0000},
4752 static const DWORD pixel_shader_code[] =
4754 0xffff0101, /* ps.1.1 */
4755 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
4756 0x0000ffff
4758 static const DWORD vertex_decl[] =
4760 D3DVSD_STREAM(0),
4761 D3DVSD_REG(0, D3DVSDT_FLOAT3), /* position, v0 */
4762 D3DVSD_REG(1, D3DVSDT_D3DCOLOR), /* diffuse color, v1 */
4763 D3DVSD_END()
4765 static const DWORD vertex_shader_code[] =
4767 0xfffe0101, /* vs.1.1 */
4768 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4769 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
4770 0x0000ffff
4772 static const D3DMATRIX identity =
4774 1.0f, 0.0f, 0.0f, 0.0f,
4775 0.0f, 1.0f, 0.0f, 0.0f,
4776 0.0f, 0.0f, 1.0f, 0.0f,
4777 0.0f, 0.0f, 0.0f, 1.0f,
4778 }}};
4780 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
4781 0, 0, 640, 480, NULL, NULL, NULL, NULL);
4782 d3d = Direct3DCreate8(D3D_SDK_VERSION);
4783 ok(!!d3d, "Failed to create a D3D object.\n");
4784 if (!(device = create_device(d3d, window, window, TRUE)))
4786 skip("Failed to create a D3D device, skipping tests.\n");
4787 goto done;
4790 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
4791 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
4792 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
4794 hr = IDirect3DDevice8_CreateVertexShader(device, vertex_decl, vertex_shader_code, &vs, 0);
4795 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
4797 else
4799 skip("Vertex Shaders not supported, skipping some fog tests.\n");
4800 vs = 0;
4802 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
4804 hr = IDirect3DDevice8_CreatePixelShader(device, pixel_shader_code, &ps);
4805 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
4807 else
4809 skip("Pixel Shaders not supported, skipping some fog tests.\n");
4810 ps = 0;
4813 /* The table fog tests seem to depend on the projection matrix explicitly
4814 * being set to an identity matrix, even though that's the default.
4815 * (AMD Radeon HD 6310, Windows 7) */
4816 hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, &identity);
4817 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
4819 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
4820 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
4821 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
4822 ok(SUCCEEDED(hr), "Failed to enable fog, hr %#x.\n", hr);
4823 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGCOLOR, 0xffff0000);
4824 ok(SUCCEEDED(hr), "Failed to set fog color, hr %#x.\n", hr);
4826 conv.f = 0.5f;
4827 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGSTART, conv.d);
4828 ok(SUCCEEDED(hr), "Failed to set fog start, hr %#x.\n", hr);
4829 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGEND, conv.d);
4830 ok(SUCCEEDED(hr), "Failed to set fog end, hr %#x.\n", hr);
4832 for (i = 0; i < sizeof(tests) / sizeof(*tests); i++)
4834 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
4835 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
4837 if (!tests[i].vs)
4839 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
4840 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr);
4842 else if (vs)
4844 hr = IDirect3DDevice8_SetVertexShader(device, vs);
4845 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
4847 else
4849 continue;
4852 if (!tests[i].ps)
4854 hr = IDirect3DDevice8_SetPixelShader(device, 0);
4855 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
4857 else if (ps)
4859 hr = IDirect3DDevice8_SetPixelShader(device, ps);
4860 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
4862 else
4864 continue;
4867 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGVERTEXMODE, tests[i].vertexmode);
4868 ok(SUCCEEDED(hr), "Failed to set fogvertexmode, hr %#x.\n", hr);
4869 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGTABLEMODE, tests[i].tablemode);
4870 ok(SUCCEEDED(hr), "Failed to set fogtablemode, hr %#x.\n", hr);
4872 hr = IDirect3DDevice8_BeginScene(device);
4873 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
4874 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
4875 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4876 hr = IDirect3DDevice8_EndScene(device);
4877 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
4879 color = getPixelColor(device, 310, 240);
4880 ok(color_match(color, tests[i].color_left, 1),
4881 "Expected left color 0x%08x, got 0x%08x, case %u.\n", tests[i].color_left, color, i);
4882 color = getPixelColor(device, 330, 240);
4883 ok(color_match(color, tests[i].color_right, 1),
4884 "Expected right color 0x%08x, got 0x%08x, case %u.\n", tests[i].color_right, color, i);
4886 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
4887 ok(SUCCEEDED(hr), "Failed to present backbuffer, hr %#x.\n", hr);
4890 if (vs)
4891 IDirect3DDevice8_DeleteVertexShader(device, vs);
4892 if (ps)
4893 IDirect3DDevice8_DeletePixelShader(device, ps);
4894 refcount = IDirect3DDevice8_Release(device);
4895 ok(!refcount, "Device has %u references left.\n", refcount);
4896 done:
4897 IDirect3D8_Release(d3d);
4898 DestroyWindow(window);
4901 static void volume_dxt5_test(void)
4903 IDirect3DVolumeTexture8 *texture;
4904 IDirect3DDevice8 *device;
4905 D3DLOCKED_BOX box;
4906 IDirect3D8 *d3d;
4907 unsigned int i;
4908 D3DCOLOR color;
4909 ULONG refcount;
4910 HWND window;
4911 HRESULT hr;
4913 static const char texture_data[] =
4915 /* A 8x4x2 texture consisting of 4 4x4 blocks. The colors of the blocks are red, green, blue and white. */
4916 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00,
4917 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00,
4918 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00,
4919 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00
4921 static const struct
4923 struct vec3 position;
4924 struct vec3 texcrd;
4926 quads[] =
4928 {{ -1.0f, -1.0f, 0.0f}, { 0.0f, 0.0f, 0.25f}},
4929 {{ -1.0f, 1.0f, 0.0f}, { 0.0f, 1.0f, 0.25f}},
4930 {{ 0.0f, -1.0f, 1.0f}, { 1.0f, 0.0f, 0.25f}},
4931 {{ 0.0f, 1.0f, 1.0f}, { 1.0f, 1.0f, 0.25f}},
4933 {{ 0.0f, -1.0f, 0.0f}, { 0.0f, 0.0f, 0.75f}},
4934 {{ 0.0f, 1.0f, 0.0f}, { 0.0f, 1.0f, 0.75f}},
4935 {{ 1.0f, -1.0f, 1.0f}, { 1.0f, 0.0f, 0.75f}},
4936 {{ 1.0f, 1.0f, 1.0f}, { 1.0f, 1.0f, 0.75f}},
4938 static const DWORD expected_colors[] = {0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff};
4940 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
4941 0, 0, 640, 480, NULL, NULL, NULL, NULL);
4942 d3d = Direct3DCreate8(D3D_SDK_VERSION);
4943 ok(!!d3d, "Failed to create a D3D object.\n");
4944 if (!(device = create_device(d3d, window, window, TRUE)))
4946 skip("Failed to create a D3D device, skipping tests.\n");
4947 goto done;
4950 if (FAILED(IDirect3D8_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
4951 D3DFMT_X8R8G8B8, 0, D3DRTYPE_VOLUMETEXTURE, D3DFMT_DXT5)))
4953 skip("Volume DXT5 textures are not supported, skipping test.\n");
4954 IDirect3DDevice8_Release(device);
4955 goto done;
4958 hr = IDirect3DDevice8_CreateVolumeTexture(device, 8, 4, 2, 1, 0, D3DFMT_DXT5,
4959 D3DPOOL_MANAGED, &texture);
4960 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
4962 hr = IDirect3DVolumeTexture8_LockBox(texture, 0, &box, NULL, 0);
4963 ok(SUCCEEDED(hr), "Failed to lock volume texture, hr %#x.\n", hr);
4964 memcpy(box.pBits, texture_data, sizeof(texture_data));
4965 hr = IDirect3DVolumeTexture8_UnlockBox(texture, 0);
4966 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#x.\n", hr);
4968 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE3(0));
4969 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
4970 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
4971 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
4972 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
4973 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
4974 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
4975 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
4976 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
4977 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
4978 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MAGFILTER, D3DTEXF_POINT);
4979 ok(SUCCEEDED(hr), "Failed to set mag filter, hr %#x.\n", hr);
4981 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff00ff, 1.0f, 0);
4982 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
4983 hr = IDirect3DDevice8_BeginScene(device);
4984 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
4985 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads));
4986 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4987 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[4], sizeof(*quads));
4988 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4989 hr = IDirect3DDevice8_EndScene(device);
4990 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
4992 for (i = 0; i < 4; i++)
4994 color = getPixelColor(device, 80 + 160 * i, 240);
4995 ok (color_match(color, expected_colors[i], 1),
4996 "Expected color 0x%08x, got 0x%08x, case %u.\n", expected_colors[i], color, i);
4999 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5000 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5001 IDirect3DVolumeTexture8_Release(texture);
5002 refcount = IDirect3DDevice8_Release(device);
5003 ok(!refcount, "Device has %u references left.\n", refcount);
5004 done:
5005 IDirect3D8_Release(d3d);
5006 DestroyWindow(window);
5009 static void volume_v16u16_test(void)
5011 IDirect3DVolumeTexture8 *texture;
5012 IDirect3DDevice8 *device;
5013 D3DLOCKED_BOX box;
5014 IDirect3D8 *d3d;
5015 unsigned int i;
5016 D3DCOLOR color;
5017 ULONG refcount;
5018 D3DCAPS8 caps;
5019 DWORD shader;
5020 SHORT *texel;
5021 HWND window;
5022 HRESULT hr;
5024 static const struct
5026 struct vec3 position;
5027 struct vec3 texcrd;
5029 quads[] =
5031 {{ -1.0f, -1.0f, 0.0f}, { 0.0f, 0.0f, 0.25f}},
5032 {{ -1.0f, 1.0f, 0.0f}, { 0.0f, 1.0f, 0.25f}},
5033 {{ 0.0f, -1.0f, 1.0f}, { 1.0f, 0.0f, 0.25f}},
5034 {{ 0.0f, 1.0f, 1.0f}, { 1.0f, 1.0f, 0.25f}},
5036 {{ 0.0f, -1.0f, 0.0f}, { 0.0f, 0.0f, 0.75f}},
5037 {{ 0.0f, 1.0f, 0.0f}, { 0.0f, 1.0f, 0.75f}},
5038 {{ 1.0f, -1.0f, 1.0f}, { 1.0f, 0.0f, 0.75f}},
5039 {{ 1.0f, 1.0f, 1.0f}, { 1.0f, 1.0f, 0.75f}},
5041 static const DWORD shader_code[] =
5043 0xffff0101, /* ps_1_1 */
5044 0x00000051, 0xa00f0000, 0x3f000000, 0x3f000000, /* def c0, 0.5, 0.5, */
5045 0x3f000000, 0x3f000000, /* 0.5, 0.5 */
5046 0x00000042, 0xb00f0000, /* tex t0 */
5047 0x00000004, 0x800f0000, 0xb0e40000, 0xa0e40000, 0xa0e40000, /* mad r0, t0, c0, c0 */
5048 0x0000ffff /* end */
5051 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
5052 0, 0, 640, 480, NULL, NULL, NULL, NULL);
5053 d3d = Direct3DCreate8(D3D_SDK_VERSION);
5054 ok(!!d3d, "Failed to create a D3D object.\n");
5055 if (!(device = create_device(d3d, window, window, TRUE)))
5057 skip("Failed to create a D3D device, skipping tests.\n");
5058 goto done;
5061 if (FAILED(IDirect3D8_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
5062 D3DFMT_X8R8G8B8, 0, D3DRTYPE_VOLUMETEXTURE, D3DFMT_V16U16)))
5064 skip("Volume V16U16 textures are not supported, skipping test.\n");
5065 IDirect3DDevice8_Release(device);
5066 goto done;
5068 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
5069 ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
5070 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 1))
5072 skip("No pixel shader 1.1 support, skipping test.\n");
5073 IDirect3DDevice8_Release(device);
5074 goto done;
5077 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE3(0));
5078 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
5079 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code, &shader);
5080 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
5081 hr = IDirect3DDevice8_SetPixelShader(device, shader);
5082 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
5083 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MAGFILTER, D3DTEXF_POINT);
5084 ok(SUCCEEDED(hr), "Failed to set filter, hr %#x.\n", hr);
5086 for (i = 0; i < 2; i++)
5088 D3DPOOL pool;
5090 if (i)
5091 pool = D3DPOOL_SYSTEMMEM;
5092 else
5093 pool = D3DPOOL_MANAGED;
5095 hr = IDirect3DDevice8_CreateVolumeTexture(device, 1, 2, 2, 1, 0, D3DFMT_V16U16,
5096 pool, &texture);
5097 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
5099 hr = IDirect3DVolumeTexture8_LockBox(texture, 0, &box, NULL, 0);
5100 ok(SUCCEEDED(hr), "Failed to lock volume texture, hr %#x.\n", hr);
5102 texel = (SHORT *)((BYTE *)box.pBits + 0 * box.RowPitch + 0 * box.SlicePitch);
5103 texel[0] = 32767;
5104 texel[1] = 32767;
5105 texel = (SHORT *)((BYTE *)box.pBits + 1 * box.RowPitch + 0 * box.SlicePitch);
5106 texel[0] = -32768;
5107 texel[1] = 0;
5108 texel = (SHORT *)((BYTE *)box.pBits + 0 * box.RowPitch + 1 * box.SlicePitch);
5109 texel[0] = -16384;
5110 texel[1] = 16384;
5111 texel = (SHORT *)((BYTE *)box.pBits + 1 * box.RowPitch + 1 * box.SlicePitch);
5112 texel[0] = 0;
5113 texel[1] = 0;
5115 hr = IDirect3DVolumeTexture8_UnlockBox(texture, 0);
5116 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#x.\n", hr);
5118 if (i)
5120 IDirect3DVolumeTexture8 *texture2;
5122 hr = IDirect3DDevice8_CreateVolumeTexture(device, 1, 2, 2, 1, 0, D3DFMT_V16U16,
5123 D3DPOOL_DEFAULT, &texture2);
5124 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
5126 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)texture,
5127 (IDirect3DBaseTexture8 *)texture2);
5128 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
5130 IDirect3DVolumeTexture8_Release(texture);
5131 texture = texture2;
5134 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *) texture);
5135 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
5137 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff00ff, 1.0f, 0);
5138 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
5139 hr = IDirect3DDevice8_BeginScene(device);
5140 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5141 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads));
5142 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5143 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[4], sizeof(*quads));
5144 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5145 hr = IDirect3DDevice8_EndScene(device);
5146 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5148 color = getPixelColor(device, 120, 160);
5149 ok (color_match(color, 0x000080ff, 2),
5150 "Expected color 0x000080ff, got 0x%08x, V16U16 input -32768, 0.\n", color);
5151 color = getPixelColor(device, 120, 400);
5152 ok (color_match(color, 0x00ffffff, 2),
5153 "Expected color 0x00ffffff, got 0x%08x, V16U16 input 32767, 32767.\n", color);
5154 color = getPixelColor(device, 360, 160);
5155 ok (color_match(color, 0x007f7fff, 2),
5156 "Expected color 0x007f7fff, got 0x%08x, V16U16 input 0, 0.\n", color);
5157 color = getPixelColor(device, 360, 400);
5158 ok (color_match(color, 0x0040c0ff, 2),
5159 "Expected color 0x0040c0ff, got 0x%08x, V16U16 input -16384, 16384.\n", color);
5161 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5162 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5164 IDirect3DVolumeTexture8_Release(texture);
5167 hr = IDirect3DDevice8_DeletePixelShader(device, shader);
5168 ok(SUCCEEDED(hr), "Failed delete pixel shader, hr %#x.\n", hr);
5169 refcount = IDirect3DDevice8_Release(device);
5170 ok(!refcount, "Device has %u references left.\n", refcount);
5171 done:
5172 IDirect3D8_Release(d3d);
5173 DestroyWindow(window);
5176 static void fill_surface(IDirect3DSurface8 *surface, DWORD color, DWORD flags)
5178 D3DSURFACE_DESC desc;
5179 D3DLOCKED_RECT l;
5180 HRESULT hr;
5181 unsigned int x, y;
5182 DWORD *mem;
5184 hr = IDirect3DSurface8_GetDesc(surface, &desc);
5185 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
5186 hr = IDirect3DSurface8_LockRect(surface, &l, NULL, flags);
5187 ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
5188 if (FAILED(hr))
5189 return;
5191 for (y = 0; y < desc.Height; y++)
5193 mem = (DWORD *)((BYTE *)l.pBits + y * l.Pitch);
5194 for (x = 0; x < l.Pitch / sizeof(DWORD); x++)
5196 mem[x] = color;
5199 hr = IDirect3DSurface8_UnlockRect(surface);
5200 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
5203 static void add_dirty_rect_test_draw(IDirect3DDevice8 *device)
5205 HRESULT hr;
5206 static const struct
5208 struct vec3 position;
5209 struct vec2 texcoord;
5211 quad[] =
5213 {{-1.0f, -1.0f, 0.0f}, {0.0f, 0.0f}},
5214 {{-1.0f, 1.0f, 0.0f}, {0.0f, 1.0f}},
5215 {{ 1.0f, -1.0f, 0.0f}, {1.0f, 0.0f}},
5216 {{ 1.0f, 1.0f, 0.0f}, {1.0f, 1.0f}},
5219 hr = IDirect3DDevice8_BeginScene(device);
5220 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5221 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad, sizeof(*quad));
5222 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5223 hr = IDirect3DDevice8_EndScene(device);
5224 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5227 static void add_dirty_rect_test(void)
5229 IDirect3DSurface8 *surface_dst2, *surface_src_green, *surface_src_red, *surface_managed;
5230 IDirect3DTexture8 *tex_dst1, *tex_dst2, *tex_src_red, *tex_src_green, *tex_managed;
5231 D3DLOCKED_RECT locked_rect;
5232 IDirect3DDevice8 *device;
5233 IDirect3D8 *d3d;
5234 unsigned int i;
5235 D3DCOLOR color;
5236 ULONG refcount;
5237 DWORD *texel;
5238 HWND window;
5239 HRESULT hr;
5241 static const RECT part_rect = {96, 96, 160, 160};
5243 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
5244 0, 0, 640, 480, NULL, NULL, NULL, NULL);
5245 d3d = Direct3DCreate8(D3D_SDK_VERSION);
5246 ok(!!d3d, "Failed to create a D3D object.\n");
5247 if (!(device = create_device(d3d, window, window, TRUE)))
5249 skip("Failed to create a D3D device, skipping tests.\n");
5250 goto done;
5253 hr = IDirect3DDevice8_CreateTexture(device, 256, 256, 1, 0, D3DFMT_X8R8G8B8,
5254 D3DPOOL_DEFAULT, &tex_dst1);
5255 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
5256 hr = IDirect3DDevice8_CreateTexture(device, 256, 256, 1, 0, D3DFMT_X8R8G8B8,
5257 D3DPOOL_DEFAULT, &tex_dst2);
5258 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
5259 hr = IDirect3DDevice8_CreateTexture(device, 256, 256, 1, 0, D3DFMT_X8R8G8B8,
5260 D3DPOOL_SYSTEMMEM, &tex_src_red);
5261 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
5262 hr = IDirect3DDevice8_CreateTexture(device, 256, 256, 1, 0, D3DFMT_X8R8G8B8,
5263 D3DPOOL_SYSTEMMEM, &tex_src_green);
5264 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
5265 hr = IDirect3DDevice8_CreateTexture(device, 256, 256, 1, 0, D3DFMT_X8R8G8B8,
5266 D3DPOOL_MANAGED, &tex_managed);
5267 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
5269 hr = IDirect3DTexture8_GetSurfaceLevel(tex_dst2, 0, &surface_dst2);
5270 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
5271 hr = IDirect3DTexture8_GetSurfaceLevel(tex_src_green, 0, &surface_src_green);
5272 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
5273 hr = IDirect3DTexture8_GetSurfaceLevel(tex_src_red, 0, &surface_src_red);
5274 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
5275 hr = IDirect3DTexture8_GetSurfaceLevel(tex_managed, 0, &surface_managed);
5276 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
5278 fill_surface(surface_src_red, 0x00ff0000, 0);
5279 fill_surface(surface_src_green, 0x0000ff00, 0);
5281 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX1);
5282 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr);
5283 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
5284 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
5285 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
5286 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
5288 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_green,
5289 (IDirect3DBaseTexture8 *)tex_dst1);
5290 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
5292 /* The second UpdateTexture call writing to tex_dst2 is ignored because tex_src_green is not dirty. */
5293 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_red,
5294 (IDirect3DBaseTexture8 *)tex_dst2);
5295 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
5296 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_green,
5297 (IDirect3DBaseTexture8 *)tex_dst2);
5298 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
5300 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)tex_dst1);
5301 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
5302 add_dirty_rect_test_draw(device);
5303 color = getPixelColor(device, 320, 240);
5304 ok(color_match(color, 0x0000ff00, 1),
5305 "Expected color 0x0000ff00, got 0x%08x.\n", color);
5306 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5307 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5309 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)tex_dst2);
5310 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
5311 add_dirty_rect_test_draw(device);
5312 color = getPixelColor(device, 320, 240);
5313 todo_wine ok(color_match(color, 0x00ff0000, 1),
5314 "Expected color 0x00ff0000, got 0x%08x.\n", color);
5315 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5316 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5318 /* AddDirtyRect on the destination is ignored. */
5319 hr = IDirect3DTexture8_AddDirtyRect(tex_dst2, &part_rect);
5320 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
5321 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_green,
5322 (IDirect3DBaseTexture8 *)tex_dst2);
5323 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
5324 add_dirty_rect_test_draw(device);
5325 color = getPixelColor(device, 320, 240);
5326 todo_wine ok(color_match(color, 0x00ff0000, 1),
5327 "Expected color 0x00ff0000, got 0x%08x.\n", color);
5328 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5329 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5331 hr = IDirect3DTexture8_AddDirtyRect(tex_dst2, NULL);
5332 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
5333 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_green,
5334 (IDirect3DBaseTexture8 *)tex_dst2);
5335 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
5336 add_dirty_rect_test_draw(device);
5337 color = getPixelColor(device, 320, 240);
5338 todo_wine ok(color_match(color, 0x00ff0000, 1),
5339 "Expected color 0x00ff0000, got 0x%08x.\n", color);
5340 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5341 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5343 /* AddDirtyRect on the source makes UpdateTexture work. Partial rectangle
5344 * tracking is supported. */
5345 hr = IDirect3DTexture8_AddDirtyRect(tex_src_green, &part_rect);
5346 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
5347 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_green,
5348 (IDirect3DBaseTexture8 *)tex_dst2);
5349 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
5350 add_dirty_rect_test_draw(device);
5351 color = getPixelColor(device, 320, 240);
5352 ok(color_match(color, 0x0000ff00, 1),
5353 "Expected color 0x0000ff00, got 0x%08x.\n", color);
5354 color = getPixelColor(device, 1, 1);
5355 todo_wine ok(color_match(color, 0x00ff0000, 1),
5356 "Expected color 0x00ff0000, got 0x%08x.\n", color);
5357 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5358 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5360 hr = IDirect3DTexture8_AddDirtyRect(tex_src_green, NULL);
5361 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
5362 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_green,
5363 (IDirect3DBaseTexture8 *)tex_dst2);
5364 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
5365 add_dirty_rect_test_draw(device);
5366 color = getPixelColor(device, 1, 1);
5367 ok(color_match(color, 0x0000ff00, 1),
5368 "Expected color 0x0000ff00, got 0x%08x.\n", color);
5370 /* Locks with NO_DIRTY_UPDATE are ignored. */
5371 fill_surface(surface_src_green, 0x00000080, D3DLOCK_NO_DIRTY_UPDATE);
5372 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_green,
5373 (IDirect3DBaseTexture8 *)tex_dst2);
5374 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
5375 add_dirty_rect_test_draw(device);
5376 color = getPixelColor(device, 320, 240);
5377 todo_wine ok(color_match(color, 0x0000ff00, 1),
5378 "Expected color 0x0000ff00, got 0x%08x.\n", color);
5379 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5380 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5382 /* Readonly maps write to D3DPOOL_SYSTEMMEM, but don't record a dirty rectangle. */
5383 fill_surface(surface_src_green, 0x000000ff, D3DLOCK_READONLY);
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 todo_wine ok(color_match(color, 0x0000ff00, 1),
5390 "Expected color 0x0000ff00, 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 hr = IDirect3DTexture8_AddDirtyRect(tex_src_green, NULL);
5395 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_green,
5396 (IDirect3DBaseTexture8 *)tex_dst2);
5397 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
5398 add_dirty_rect_test_draw(device);
5399 color = getPixelColor(device, 320, 240);
5400 ok(color_match(color, 0x000000ff, 1),
5401 "Expected color 0x000000ff, got 0x%08x.\n", color);
5402 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5403 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5405 /* Maps without either of these flags record a dirty rectangle. */
5406 fill_surface(surface_src_green, 0x00ffffff, 0);
5407 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_green,
5408 (IDirect3DBaseTexture8 *)tex_dst2);
5409 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
5410 add_dirty_rect_test_draw(device);
5411 color = getPixelColor(device, 320, 240);
5412 ok(color_match(color, 0x00ffffff, 1),
5413 "Expected color 0x00ffffff, got 0x%08x.\n", color);
5414 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5415 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5417 /* Partial LockRect works just like a partial AddDirtyRect call. */
5418 hr = IDirect3DTexture8_LockRect(tex_src_green, 0, &locked_rect, &part_rect, 0);
5419 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
5420 texel = locked_rect.pBits;
5421 for (i = 0; i < 64; i++)
5422 texel[i] = 0x00ff00ff;
5423 for (i = 1; i < 64; i++)
5424 memcpy((BYTE *)locked_rect.pBits + i * locked_rect.Pitch, locked_rect.pBits, locked_rect.Pitch);
5425 hr = IDirect3DTexture8_UnlockRect(tex_src_green, 0);
5426 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
5427 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_green,
5428 (IDirect3DBaseTexture8 *)tex_dst2);
5429 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
5430 add_dirty_rect_test_draw(device);
5431 color = getPixelColor(device, 320, 240);
5432 ok(color_match(color, 0x00ff00ff, 1),
5433 "Expected color 0x00ff00ff, got 0x%08x.\n", color);
5434 color = getPixelColor(device, 1, 1);
5435 ok(color_match(color, 0x00ffffff, 1),
5436 "Expected color 0x00ffffff, got 0x%08x.\n", color);
5437 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5438 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5440 fill_surface(surface_src_red, 0x00ff0000, 0);
5441 fill_surface(surface_src_green, 0x0000ff00, 0);
5443 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_green,
5444 (IDirect3DBaseTexture8 *)tex_dst1);
5445 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
5446 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)tex_dst1);
5447 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
5448 add_dirty_rect_test_draw(device);
5449 color = getPixelColor(device, 320, 240);
5450 ok(color_match(color, 0x0000ff00, 1),
5451 "Expected color 0x0000ff00, got 0x%08x.\n", color);
5452 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5453 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5455 /* UpdateSurface ignores the missing dirty marker. */
5456 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_red,
5457 (IDirect3DBaseTexture8 *)tex_dst2);
5458 hr = IDirect3DDevice8_CopyRects(device, surface_src_green, NULL, 0, surface_dst2, NULL);
5459 ok(SUCCEEDED(hr), "Failed to update surface, hr %#x.\n", hr);
5460 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)tex_dst2);
5461 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
5462 add_dirty_rect_test_draw(device);
5463 color = getPixelColor(device, 320, 240);
5464 ok(color_match(color, 0x0000ff00, 1),
5465 "Expected color 0x0000ff00, got 0x%08x.\n", color);
5466 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5467 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5469 fill_surface(surface_managed, 0x00ff0000, 0);
5470 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)tex_managed);
5471 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
5472 add_dirty_rect_test_draw(device);
5473 color = getPixelColor(device, 320, 240);
5474 ok(color_match(color, 0x00ff0000, 1),
5475 "Expected color 0x00ff0000, got 0x%08x.\n", color);
5476 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5477 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5479 /* Managed textures also honor D3DLOCK_NO_DIRTY_UPDATE. */
5480 fill_surface(surface_managed, 0x0000ff00, D3DLOCK_NO_DIRTY_UPDATE);
5481 add_dirty_rect_test_draw(device);
5482 color = getPixelColor(device, 320, 240);
5483 ok(color_match(color, 0x00ff0000, 1),
5484 "Expected color 0x00ff0000, got 0x%08x.\n", color);
5485 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5486 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5488 /* AddDirtyRect uploads the new contents.
5489 * Side note, not tested in the test: Partial surface updates work, and two separate
5490 * dirty rectangles are tracked individually. Tested on Nvidia Kepler, other drivers
5491 * untested. */
5492 hr = IDirect3DTexture8_AddDirtyRect(tex_managed, NULL);
5493 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
5494 add_dirty_rect_test_draw(device);
5495 color = getPixelColor(device, 320, 240);
5496 ok(color_match(color, 0x0000ff00, 1),
5497 "Expected color 0x0000ff00, got 0x%08x.\n", color);
5498 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5499 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5501 /* So does ResourceManagerDiscardBytes. */
5502 fill_surface(surface_managed, 0x000000ff, D3DLOCK_NO_DIRTY_UPDATE);
5503 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
5504 hr = IDirect3DDevice8_ResourceManagerDiscardBytes(device, 0);
5505 ok(SUCCEEDED(hr), "Failed to evict managed resources, hr %#x.\n", hr);
5506 add_dirty_rect_test_draw(device);
5507 color = getPixelColor(device, 320, 240);
5508 ok(color_match(color, 0x000000ff, 1),
5509 "Expected color 0x000000ff, got 0x%08x.\n", color);
5510 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5511 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5513 /* AddDirtyRect on a locked texture is allowed. */
5514 hr = IDirect3DTexture8_LockRect(tex_src_red, 0, &locked_rect, NULL, 0);
5515 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
5516 hr = IDirect3DTexture8_AddDirtyRect(tex_src_red, NULL);
5517 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
5518 hr = IDirect3DTexture8_UnlockRect(tex_src_red, 0);
5519 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
5521 /* Redundant AddDirtyRect calls are ok. */
5522 hr = IDirect3DTexture8_AddDirtyRect(tex_managed, NULL);
5523 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
5524 hr = IDirect3DTexture8_AddDirtyRect(tex_managed, NULL);
5525 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
5527 IDirect3DSurface8_Release(surface_dst2);
5528 IDirect3DSurface8_Release(surface_managed);
5529 IDirect3DSurface8_Release(surface_src_red);
5530 IDirect3DSurface8_Release(surface_src_green);
5531 IDirect3DTexture8_Release(tex_src_red);
5532 IDirect3DTexture8_Release(tex_src_green);
5533 IDirect3DTexture8_Release(tex_dst1);
5534 IDirect3DTexture8_Release(tex_dst2);
5535 IDirect3DTexture8_Release(tex_managed);
5536 refcount = IDirect3DDevice8_Release(device);
5537 ok(!refcount, "Device has %u references left.\n", refcount);
5538 done:
5539 IDirect3D8_Release(d3d);
5540 DestroyWindow(window);
5543 static void test_3dc_formats(void)
5545 static const char ati1n_data[] =
5547 /* A 4x4 texture with the color component at 50%. */
5548 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5550 static const char ati2n_data[] =
5552 /* A 8x4 texture consisting of 2 4x4 blocks. The first block has 50% first color component,
5553 * 0% second component. Second block is the opposite. */
5554 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5555 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5557 static const struct
5559 struct vec3 position;
5560 struct vec2 texcoord;
5562 quads[] =
5564 {{-1.0f, -1.0f, 0.0f}, {0.0f, 0.0f}},
5565 {{-1.0f, 1.0f, 0.0f}, {0.0f, 1.0f}},
5566 {{ 0.0f, -1.0f, 1.0f}, {1.0f, 0.0f}},
5567 {{ 0.0f, 1.0f, 1.0f}, {1.0f, 1.0f}},
5569 {{ 0.0f, -1.0f, 0.0f}, {0.0f, 0.0f}},
5570 {{ 0.0f, 1.0f, 0.0f}, {0.0f, 1.0f}},
5571 {{ 1.0f, -1.0f, 1.0f}, {1.0f, 0.0f}},
5572 {{ 1.0f, 1.0f, 1.0f}, {1.0f, 1.0f}},
5574 static const DWORD ati1n_fourcc = MAKEFOURCC('A','T','I','1');
5575 static const DWORD ati2n_fourcc = MAKEFOURCC('A','T','I','2');
5576 static const struct
5578 struct vec2 position;
5579 D3DCOLOR amd_r500;
5580 D3DCOLOR amd_r600;
5581 D3DCOLOR nvidia_old;
5582 D3DCOLOR nvidia_new;
5584 expected_colors[] =
5586 {{ 80, 240}, 0x007fffff, 0x003f3f3f, 0x007f7f7f, 0x007f0000},
5587 {{240, 240}, 0x007fffff, 0x003f3f3f, 0x007f7f7f, 0x007f0000},
5588 {{400, 240}, 0x00007fff, 0x00007fff, 0x00007fff, 0x00007fff},
5589 {{560, 240}, 0x007f00ff, 0x007f00ff, 0x007f00ff, 0x007f00ff},
5591 IDirect3D8 *d3d;
5592 IDirect3DDevice8 *device;
5593 IDirect3DTexture8 *ati1n_texture, *ati2n_texture;
5594 D3DCAPS8 caps;
5595 D3DLOCKED_RECT rect;
5596 D3DCOLOR color;
5597 ULONG refcount;
5598 HWND window;
5599 HRESULT hr;
5600 unsigned int i;
5602 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
5603 0, 0, 640, 480, NULL, NULL, NULL, NULL);
5604 d3d = Direct3DCreate8(D3D_SDK_VERSION);
5605 ok(!!d3d, "Failed to create a D3D object.\n");
5606 if (FAILED(IDirect3D8_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
5607 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, ati1n_fourcc)))
5609 skip("ATI1N textures are not supported, skipping test.\n");
5610 goto done;
5612 if (FAILED(IDirect3D8_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
5613 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, ati2n_fourcc)))
5615 skip("ATI2N textures are not supported, skipping test.\n");
5616 goto done;
5618 if (!(device = create_device(d3d, window, window, TRUE)))
5620 skip("Failed to create a D3D device, skipping tests.\n");
5621 goto done;
5623 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
5624 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
5625 if (!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP))
5627 skip("D3DTA_TEMP not supported, skipping tests.\n");
5628 IDirect3DDevice8_Release(device);
5629 goto done;
5632 hr = IDirect3DDevice8_CreateTexture(device, 4, 4, 1, 0, ati1n_fourcc,
5633 D3DPOOL_MANAGED, &ati1n_texture);
5634 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
5636 hr = IDirect3DTexture8_LockRect(ati1n_texture, 0, &rect, NULL, 0);
5637 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
5638 memcpy(rect.pBits, ati1n_data, sizeof(ati1n_data));
5639 hr = IDirect3DTexture8_UnlockRect(ati1n_texture, 0);
5640 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
5642 hr = IDirect3DDevice8_CreateTexture(device, 8, 4, 1, 0, ati2n_fourcc,
5643 D3DPOOL_MANAGED, &ati2n_texture);
5644 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
5646 hr = IDirect3DTexture8_LockRect(ati2n_texture, 0, &rect, NULL, 0);
5647 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
5648 memcpy(rect.pBits, ati2n_data, sizeof(ati2n_data));
5649 hr = IDirect3DTexture8_UnlockRect(ati2n_texture, 0);
5650 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
5652 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE2(0));
5653 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
5654 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BLENDTEXTUREALPHA);
5655 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
5656 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
5657 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
5658 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TEMP);
5659 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
5660 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
5661 ok(SUCCEEDED(hr), "Failed to set alpha op, hr %#x.\n", hr);
5662 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
5663 ok(SUCCEEDED(hr), "Failed to set alpha arg, hr %#x.\n", hr);
5664 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
5665 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
5666 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MAGFILTER, D3DTEXF_POINT);
5667 ok(SUCCEEDED(hr), "Failed to set mag filter, hr %#x.\n", hr);
5669 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff00ff, 1.0f, 0);
5670 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
5671 hr = IDirect3DDevice8_BeginScene(device);
5672 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5673 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)ati1n_texture);
5674 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
5675 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads));
5676 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5677 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)ati2n_texture);
5678 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
5679 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[4], sizeof(*quads));
5680 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5681 hr = IDirect3DDevice8_EndScene(device);
5682 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5684 for (i = 0; i < 4; ++i)
5686 color = getPixelColor(device, expected_colors[i].position.x, expected_colors[i].position.y);
5687 ok (color_match(color, expected_colors[i].amd_r500, 1)
5688 || color_match(color, expected_colors[i].amd_r600, 1)
5689 || color_match(color, expected_colors[i].nvidia_old, 1)
5690 || color_match(color, expected_colors[i].nvidia_new, 1),
5691 "Got unexpected color 0x%08x, case %u.\n", color, i);
5694 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5695 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5696 IDirect3DTexture8_Release(ati2n_texture);
5697 IDirect3DTexture8_Release(ati1n_texture);
5698 refcount = IDirect3DDevice8_Release(device);
5699 ok(!refcount, "Device has %u references left.\n", refcount);
5701 done:
5702 IDirect3D8_Release(d3d);
5703 DestroyWindow(window);
5706 static void test_fog_interpolation(void)
5708 HRESULT hr;
5709 IDirect3DDevice8 *device;
5710 IDirect3D8 *d3d;
5711 ULONG refcount;
5712 HWND window;
5713 D3DCOLOR color;
5714 static const struct
5716 struct vec3 position;
5717 D3DCOLOR diffuse;
5718 D3DCOLOR specular;
5720 quad[] =
5722 {{-1.0f, -1.0f, 0.0f}, 0xffff0000, 0xff000000},
5723 {{-1.0f, 1.0f, 0.0f}, 0xffff0000, 0xff000000},
5724 {{ 1.0f, -1.0f, 1.0f}, 0xffff0000, 0x00000000},
5725 {{ 1.0f, 1.0f, 1.0f}, 0xffff0000, 0x00000000},
5727 union
5729 DWORD d;
5730 float f;
5731 } conv;
5732 unsigned int i;
5733 static const struct
5735 D3DFOGMODE vfog, tfog;
5736 D3DSHADEMODE shade;
5737 D3DCOLOR middle_color;
5738 BOOL todo;
5740 tests[] =
5742 {D3DFOG_NONE, D3DFOG_NONE, D3DSHADE_FLAT, 0x00007f80, FALSE},
5743 {D3DFOG_NONE, D3DFOG_NONE, D3DSHADE_GOURAUD, 0x00007f80, FALSE},
5744 {D3DFOG_EXP, D3DFOG_NONE, D3DSHADE_FLAT, 0x00007f80, TRUE},
5745 {D3DFOG_EXP, D3DFOG_NONE, D3DSHADE_GOURAUD, 0x00007f80, TRUE},
5746 {D3DFOG_NONE, D3DFOG_EXP, D3DSHADE_FLAT, 0x0000ea15, FALSE},
5747 {D3DFOG_NONE, D3DFOG_EXP, D3DSHADE_GOURAUD, 0x0000ea15, FALSE},
5748 {D3DFOG_EXP, D3DFOG_EXP, D3DSHADE_FLAT, 0x0000ea15, FALSE},
5749 {D3DFOG_EXP, D3DFOG_EXP, D3DSHADE_GOURAUD, 0x0000ea15, FALSE},
5751 static const D3DMATRIX ident_mat =
5753 1.0f, 0.0f, 0.0f, 0.0f,
5754 0.0f, 1.0f, 0.0f, 0.0f,
5755 0.0f, 0.0f, 1.0f, 0.0f,
5756 0.0f, 0.0f, 0.0f, 1.0f
5757 }}};
5758 D3DCAPS8 caps;
5760 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
5761 0, 0, 640, 480, NULL, NULL, NULL, NULL);
5762 d3d = Direct3DCreate8(D3D_SDK_VERSION);
5763 ok(!!d3d, "Failed to create a D3D object.\n");
5765 if (!(device = create_device(d3d, window, window, TRUE)))
5767 skip("Failed to create a D3D device, skipping tests.\n");
5768 IDirect3D8_Release(d3d);
5769 DestroyWindow(window);
5770 return;
5773 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
5774 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
5775 if (!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE))
5776 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping some fog tests\n");
5778 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
5779 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr);
5780 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
5781 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
5782 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, FALSE);
5783 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
5784 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
5785 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
5786 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGCOLOR, 0x0000ff00);
5787 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
5788 conv.f = 5.0;
5789 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGDENSITY, conv.d);
5790 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
5792 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
5793 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
5794 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TFACTOR);
5795 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
5796 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x000000ff);
5797 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
5799 /* Some of the tests seem to depend on the projection matrix explicitly
5800 * being set to an identity matrix, even though that's the default.
5801 * (AMD Radeon X1600, AMD Radeon HD 6310, Windows 7). Without this,
5802 * the drivers seem to use a static z = 1.0 input for the fog equation.
5803 * The input value is independent of the actual z and w component of
5804 * the vertex position. */
5805 hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, &ident_mat);
5806 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
5808 for (i = 0; i < sizeof(tests) / sizeof(*tests); i++)
5810 if(!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE) && tests[i].tfog)
5811 continue;
5813 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00808080, 0.0f, 0);
5814 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
5816 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SHADEMODE, tests[i].shade);
5817 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
5818 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGVERTEXMODE, tests[i].vfog);
5819 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
5820 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGTABLEMODE, tests[i].tfog);
5821 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
5822 hr = IDirect3DDevice8_BeginScene(device);
5823 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5824 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
5825 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5826 hr = IDirect3DDevice8_EndScene(device);
5827 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5829 color = getPixelColor(device, 0, 240);
5830 ok(color_match(color, 0x000000ff, 2), "Got unexpected color 0x%08x, case %u.\n", color, i);
5831 color = getPixelColor(device, 320, 240);
5832 if (tests[i].todo)
5833 todo_wine ok(color_match(color, tests[i].middle_color, 2),
5834 "Got unexpected color 0x%08x, case %u.\n", color, i);
5835 else
5836 ok(color_match(color, tests[i].middle_color, 2),
5837 "Got unexpected color 0x%08x, case %u.\n", color, i);
5838 color = getPixelColor(device, 639, 240);
5839 ok(color_match(color, 0x0000fd02, 2), "Got unexpected color 0x%08x, case %u.\n", color, i);
5840 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5841 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5844 refcount = IDirect3DDevice8_Release(device);
5845 ok(!refcount, "Device has %u references left.\n", refcount);
5846 IDirect3D8_Release(d3d);
5847 DestroyWindow(window);
5850 static void test_negative_fixedfunction_fog(void)
5852 HRESULT hr;
5853 IDirect3DDevice8 *device;
5854 IDirect3D8 *d3d;
5855 ULONG refcount;
5856 HWND window;
5857 D3DCOLOR color;
5858 static const struct
5860 struct vec3 position;
5861 D3DCOLOR diffuse;
5863 quad[] =
5865 {{-1.0f, -1.0f, -0.5f}, 0xffff0000},
5866 {{-1.0f, 1.0f, -0.5f}, 0xffff0000},
5867 {{ 1.0f, -1.0f, -0.5f}, 0xffff0000},
5868 {{ 1.0f, 1.0f, -0.5f}, 0xffff0000},
5870 static const struct
5872 struct vec4 position;
5873 D3DCOLOR diffuse;
5875 tquad[] =
5877 {{ 0.0f, 0.0f, -0.5f, 1.0f}, 0xffff0000},
5878 {{640.0f, 0.0f, -0.5f, 1.0f}, 0xffff0000},
5879 {{ 0.0f, 480.0f, -0.5f, 1.0f}, 0xffff0000},
5880 {{640.0f, 480.0f, -0.5f, 1.0f}, 0xffff0000},
5882 unsigned int i;
5883 static const D3DMATRIX zero =
5885 1.0f, 0.0f, 0.0f, 0.0f,
5886 0.0f, 1.0f, 0.0f, 0.0f,
5887 0.0f, 0.0f, 0.0f, 0.0f,
5888 0.0f, 0.0f, 0.0f, 1.0f
5889 }}};
5890 /* Needed to make AMD drivers happy. Yeah, it is not supposed to
5891 * have an effect on RHW draws. */
5892 static const D3DMATRIX identity =
5894 1.0f, 0.0f, 0.0f, 0.0f,
5895 0.0f, 1.0f, 0.0f, 0.0f,
5896 0.0f, 0.0f, 1.0f, 0.0f,
5897 0.0f, 0.0f, 0.0f, 1.0f
5898 }}};
5899 static const struct
5901 DWORD pos_type;
5902 const void *quad;
5903 size_t stride;
5904 const D3DMATRIX *matrix;
5905 union
5907 float f;
5908 DWORD d;
5909 } start, end;
5910 D3DFOGMODE vfog, tfog;
5911 DWORD color, color_broken, color_broken2;
5913 tests[] =
5915 /* Run the XYZRHW tests first. Depth clamping is broken after RHW draws on the testbot.
5917 * Geforce8+ GPUs on Windows abs() table fog, everything else does not. */
5918 {D3DFVF_XYZRHW, tquad, sizeof(*tquad), &identity, { 0.0f}, {1.0f},
5919 D3DFOG_NONE, D3DFOG_LINEAR, 0x00ff0000, 0x00808000, 0x00808000},
5920 /* r200 GPUs and presumably all d3d8 and older HW clamp the fog
5921 * parameters to 0.0 and 1.0 in the table fog case. */
5922 {D3DFVF_XYZRHW, tquad, sizeof(*tquad), &identity, {-1.0f}, {0.0f},
5923 D3DFOG_NONE, D3DFOG_LINEAR, 0x00808000, 0x00ff0000, 0x0000ff00},
5924 /* test_fog_interpolation shows that vertex fog evaluates the fog
5925 * equation in the vertex pipeline. Start = -1.0 && end = 0.0 shows
5926 * that the abs happens before the fog equation is evaluated.
5928 * Vertex fog abs() behavior is the same on all GPUs. */
5929 {D3DFVF_XYZ, quad, sizeof(*quad), &zero, { 0.0f}, {1.0f},
5930 D3DFOG_LINEAR, D3DFOG_NONE, 0x00808000, 0x00808000, 0x00808000},
5931 {D3DFVF_XYZ, quad, sizeof(*quad), &zero, {-1.0f}, {0.0f},
5932 D3DFOG_LINEAR, D3DFOG_NONE, 0x0000ff00, 0x0000ff00, 0x0000ff00},
5933 {D3DFVF_XYZ, quad, sizeof(*quad), &zero, { 0.0f}, {1.0f},
5934 D3DFOG_EXP, D3DFOG_NONE, 0x009b6400, 0x009b6400, 0x009b6400},
5936 D3DCAPS8 caps;
5938 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
5939 0, 0, 640, 480, NULL, NULL, NULL, NULL);
5940 d3d = Direct3DCreate8(D3D_SDK_VERSION);
5941 ok(!!d3d, "Failed to create a D3D object.\n");
5943 if (!(device = create_device(d3d, window, window, TRUE)))
5945 skip("Failed to create a D3D device, skipping tests.\n");
5946 IDirect3D8_Release(d3d);
5947 DestroyWindow(window);
5948 return;
5951 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
5952 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
5953 if (!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE))
5954 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping some fog tests.\n");
5956 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
5957 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
5958 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
5959 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
5960 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
5961 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
5962 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGCOLOR, 0x0000ff00);
5963 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
5964 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, FALSE);
5965 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
5967 for (i = 0; i < sizeof(tests) / sizeof(*tests); i++)
5969 if (!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE) && tests[i].tfog)
5970 continue;
5972 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x000000ff, 0.0f, 0);
5973 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
5975 hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, tests[i].matrix);
5976 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
5977 hr = IDirect3DDevice8_SetVertexShader(device, tests[i].pos_type | D3DFVF_DIFFUSE);
5978 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr);
5979 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGSTART, tests[i].start.d);
5980 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
5981 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGEND, tests[i].end.d);
5982 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
5983 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGVERTEXMODE, tests[i].vfog);
5984 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
5985 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGTABLEMODE, tests[i].tfog);
5986 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
5988 hr = IDirect3DDevice8_BeginScene(device);
5989 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5990 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, tests[i].quad, tests[i].stride);
5991 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5992 hr = IDirect3DDevice8_EndScene(device);
5993 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5995 color = getPixelColor(device, 320, 240);
5996 ok(color_match(color, tests[i].color, 2) || broken(color_match(color, tests[i].color_broken, 2))
5997 || broken(color_match(color, tests[i].color_broken2, 2)),
5998 "Got unexpected color 0x%08x, case %u.\n", color, i);
5999 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
6000 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
6003 refcount = IDirect3DDevice8_Release(device);
6004 ok(!refcount, "Device has %u references left.\n", refcount);
6005 IDirect3D8_Release(d3d);
6006 DestroyWindow(window);
6009 static void test_table_fog_zw(void)
6011 HRESULT hr;
6012 IDirect3DDevice8 *device;
6013 IDirect3D8 *d3d;
6014 ULONG refcount;
6015 HWND window;
6016 D3DCOLOR color;
6017 D3DCAPS8 caps;
6018 static struct
6020 struct vec4 position;
6021 D3DCOLOR diffuse;
6023 quad[] =
6025 {{ 0.0f, 0.0f, 0.0f, 0.0f}, 0xffff0000},
6026 {{640.0f, 0.0f, 0.0f, 0.0f}, 0xffff0000},
6027 {{ 0.0f, 480.0f, 0.0f, 0.0f}, 0xffff0000},
6028 {{640.0f, 480.0f, 0.0f, 0.0f}, 0xffff0000},
6030 static const D3DMATRIX identity =
6032 1.0f, 0.0f, 0.0f, 0.0f,
6033 0.0f, 1.0f, 0.0f, 0.0f,
6034 0.0f, 0.0f, 1.0f, 0.0f,
6035 0.0f, 0.0f, 0.0f, 1.0f
6036 }}};
6037 static const struct
6039 float z, w;
6040 D3DZBUFFERTYPE z_test;
6041 D3DCOLOR color;
6043 tests[] =
6045 {0.7f, 0.0f, D3DZB_TRUE, 0x004cb200},
6046 {0.7f, 0.0f, D3DZB_FALSE, 0x004cb200},
6047 {0.7f, 0.3f, D3DZB_TRUE, 0x004cb200},
6048 {0.7f, 0.3f, D3DZB_FALSE, 0x004cb200},
6049 {0.7f, 3.0f, D3DZB_TRUE, 0x004cb200},
6050 {0.7f, 3.0f, D3DZB_FALSE, 0x004cb200},
6051 {0.3f, 0.0f, D3DZB_TRUE, 0x00b24c00},
6052 {0.3f, 0.0f, D3DZB_FALSE, 0x00b24c00},
6054 unsigned int i;
6056 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
6057 0, 0, 640, 480, NULL, NULL, NULL, NULL);
6058 d3d = Direct3DCreate8(D3D_SDK_VERSION);
6059 ok(!!d3d, "Failed to create a D3D object.\n");
6061 if (!(device = create_device(d3d, window, window, TRUE)))
6063 skip("Failed to create a D3D device, skipping tests.\n");
6064 IDirect3D8_Release(d3d);
6065 DestroyWindow(window);
6066 return;
6069 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
6070 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
6071 if (!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE))
6073 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping POSITIONT table fog test.\n");
6074 goto done;
6077 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6078 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6079 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
6080 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6081 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGCOLOR, 0x0000ff00);
6082 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6083 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, FALSE);
6084 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
6085 /* Work around an AMD Windows driver bug. Needs a proj matrix applied redundantly. */
6086 hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, &identity);
6087 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
6088 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
6089 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6090 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
6091 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr);
6093 for (i = 0; i < sizeof(tests) / sizeof(*tests); ++i)
6095 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
6096 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
6098 quad[0].position.z = tests[i].z;
6099 quad[1].position.z = tests[i].z;
6100 quad[2].position.z = tests[i].z;
6101 quad[3].position.z = tests[i].z;
6102 quad[0].position.w = tests[i].w;
6103 quad[1].position.w = tests[i].w;
6104 quad[2].position.w = tests[i].w;
6105 quad[3].position.w = tests[i].w;
6106 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, tests[i].z_test);
6107 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6109 hr = IDirect3DDevice8_BeginScene(device);
6110 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6111 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
6112 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6113 hr = IDirect3DDevice8_EndScene(device);
6114 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6116 color = getPixelColor(device, 320, 240);
6117 ok(color_match(color, tests[i].color, 2),
6118 "Got unexpected color 0x%08x, expected 0x%08x, case %u.\n", color, tests[i].color, i);
6119 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
6120 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
6123 done:
6124 refcount = IDirect3DDevice8_Release(device);
6125 ok(!refcount, "Device has %u references left.\n", refcount);
6126 IDirect3D8_Release(d3d);
6127 DestroyWindow(window);
6130 static void test_signed_formats(void)
6132 IDirect3DDevice8 *device;
6133 HWND window;
6134 HRESULT hr;
6135 unsigned int i, j, x, y;
6136 IDirect3DTexture8 *texture, *texture_sysmem;
6137 D3DLOCKED_RECT locked_rect;
6138 DWORD shader, shader_alpha;
6139 IDirect3D8 *d3d;
6140 D3DCOLOR color;
6141 D3DCAPS8 caps;
6142 ULONG refcount;
6144 /* See comments in the d3d9 version of this test for an
6145 * explanation of these values. */
6146 static const USHORT content_v8u8[4][4] =
6148 {0x0000, 0x7f7f, 0x8880, 0x0000},
6149 {0x0080, 0x8000, 0x7f00, 0x007f},
6150 {0x193b, 0xe8c8, 0x0808, 0xf8f8},
6151 {0x4444, 0xc0c0, 0xa066, 0x22e0},
6153 static const DWORD content_v16u16[4][4] =
6155 {0x00000000, 0x7fff7fff, 0x88008000, 0x00000000},
6156 {0x00008000, 0x80000000, 0x7fff0000, 0x00007fff},
6157 {0x19993bbb, 0xe800c800, 0x08880888, 0xf800f800},
6158 {0x44444444, 0xc000c000, 0xa0006666, 0x2222e000},
6160 static const DWORD content_q8w8v8u8[4][4] =
6162 {0x00000000, 0xff7f7f7f, 0x7f008880, 0x817f0000},
6163 {0x10000080, 0x20008000, 0x30007f00, 0x4000007f},
6164 {0x5020193b, 0x6028e8c8, 0x70020808, 0x807ff8f8},
6165 {0x90414444, 0xa000c0c0, 0x8261a066, 0x834922e0},
6167 static const DWORD content_x8l8v8u8[4][4] =
6169 {0x00000000, 0x00ff7f7f, 0x00008880, 0x00ff0000},
6170 {0x00000080, 0x00008000, 0x00007f00, 0x0000007f},
6171 {0x0041193b, 0x0051e8c8, 0x00040808, 0x00fff8f8},
6172 {0x00824444, 0x0000c0c0, 0x00c2a066, 0x009222e0},
6174 static const USHORT content_l6v5u5[4][4] =
6176 {0x0000, 0xfdef, 0x0230, 0xfc00},
6177 {0x0010, 0x0200, 0x01e0, 0x000f},
6178 {0x4067, 0x53b9, 0x0421, 0xffff},
6179 {0x8108, 0x0318, 0xc28c, 0x909c},
6181 static const struct
6183 D3DFORMAT format;
6184 const char *name;
6185 const void *content;
6186 SIZE_T pixel_size;
6187 BOOL blue, alpha;
6188 unsigned int slop, slop_broken, alpha_broken;
6190 formats[] =
6192 {D3DFMT_V8U8, "D3DFMT_V8U8", content_v8u8, sizeof(WORD), FALSE, FALSE, 1, 0, FALSE},
6193 {D3DFMT_V16U16, "D3DFMT_V16U16", content_v16u16, sizeof(DWORD), FALSE, FALSE, 1, 0, FALSE},
6194 {D3DFMT_Q8W8V8U8, "D3DFMT_Q8W8V8U8", content_q8w8v8u8, sizeof(DWORD), TRUE, TRUE, 1, 0, TRUE },
6195 {D3DFMT_X8L8V8U8, "D3DFMT_X8L8V8U8", content_x8l8v8u8, sizeof(DWORD), TRUE, FALSE, 1, 0, FALSE},
6196 {D3DFMT_L6V5U5, "D3DFMT_L6V5U5", content_l6v5u5, sizeof(WORD), TRUE, FALSE, 4, 7, FALSE},
6198 static const struct
6200 D3DPOOL pool;
6201 UINT width;
6203 tests[] =
6205 {D3DPOOL_SYSTEMMEM, 4},
6206 {D3DPOOL_SYSTEMMEM, 1},
6207 {D3DPOOL_MANAGED, 4},
6208 {D3DPOOL_MANAGED, 1},
6210 static const DWORD shader_code[] =
6212 0xffff0101, /* ps_1_1 */
6213 0x00000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, /* def c0, 0.5, 0.5, 0,5, 0,5 */
6214 0x00000042, 0xb00f0000, /* tex t0 */
6215 0x00000004, 0x800f0000, 0xb0e40000, 0xa0e40000, 0xa0e40000, /* mad r0, t0, c0, c0 */
6216 0x0000ffff /* end */
6218 static const DWORD shader_code_alpha[] =
6220 /* The idea of this shader is to replicate the alpha value in .rg, and set
6221 * blue to 1.0 iff the alpha value is < -1.0 and 0.0 otherwise. */
6222 0xffff0101, /* ps_1_1 */
6223 0x00000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, /* def c0, 0.5, 0.5, 0.5, 0.5 */
6224 0x00000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0 */
6225 0x00000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c2, 0.0, 0.0, 1.0, 0.0 */
6226 0x00000042, 0xb00f0000, /* tex t0 */
6227 0x00000004, 0x80070000, 0xb0ff0000, 0xa0e40000, 0xa0e40000, /* mad r0.rgb, t0.a, c0, c0 */
6228 0x00000003, 0x80080000, 0xb1ff0000, 0xa0e40000, /* sub r0.a, -t0.a, c0 */
6229 0x00000050, 0x80080000, 0x80ff0000, 0xa0ff0001, 0xa0ff0002, /* cnd r0.a, r0.a, c1.a, c2.a */
6230 0x00000005, 0x80070001, 0xa0e40001, 0x80e40000, /* mul r1.rgb, c1, r0 */
6231 0x00000004, 0x80070000, 0x80ff0000, 0xa0e40002, 0x80e40001, /* mad r0.rgb, r0.a, c2, r1 */
6232 0x0000ffff /* end */
6234 static const struct
6236 struct vec3 position;
6237 struct vec2 texcrd;
6239 quad[] =
6241 /* Flip the y coordinate to make the input and
6242 * output arrays easier to compare. */
6243 {{ -1.0f, -1.0f, 0.0f}, { 0.0f, 1.0f}},
6244 {{ -1.0f, 1.0f, 0.0f}, { 0.0f, 0.0f}},
6245 {{ 1.0f, -1.0f, 0.0f}, { 1.0f, 1.0f}},
6246 {{ 1.0f, 1.0f, 0.0f}, { 1.0f, 0.0f}},
6248 static const D3DCOLOR expected_alpha[4][4] =
6250 {0x00808000, 0x007f7f00, 0x00ffff00, 0x00000000},
6251 {0x00909000, 0x00a0a000, 0x00b0b000, 0x00c0c000},
6252 {0x00d0d000, 0x00e0e000, 0x00f0f000, 0x00000000},
6253 {0x00101000, 0x00202000, 0x00010100, 0x00020200},
6255 static const BOOL alpha_broken[4][4] =
6257 {FALSE, FALSE, FALSE, FALSE},
6258 {FALSE, FALSE, FALSE, FALSE},
6259 {FALSE, FALSE, FALSE, TRUE },
6260 {FALSE, FALSE, FALSE, FALSE},
6262 static const D3DCOLOR expected_colors[4][4] =
6264 {0x00808080, 0x00fefeff, 0x00010780, 0x008080ff},
6265 {0x00018080, 0x00800180, 0x0080fe80, 0x00fe8080},
6266 {0x00ba98a0, 0x004767a8, 0x00888881, 0x007878ff},
6267 {0x00c3c3c0, 0x003f3f80, 0x00e51fe1, 0x005fa2c8},
6269 D3DCOLOR expected_color;
6271 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
6272 0, 0, 640, 480, NULL, NULL, NULL, NULL);
6273 d3d = Direct3DCreate8(D3D_SDK_VERSION);
6274 ok(!!d3d, "Failed to create a D3D object.\n");
6276 if (!(device = create_device(d3d, window, window, TRUE)))
6278 skip("Failed to create a D3D device, skipping tests.\n");
6279 IDirect3D8_Release(d3d);
6280 DestroyWindow(window);
6281 return;
6284 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
6285 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
6287 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 1))
6289 skip("Pixel shaders not supported, skipping converted format test.\n");
6290 goto done;
6293 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
6294 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6295 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX1);
6296 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
6297 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code, &shader);
6298 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
6299 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code_alpha, &shader_alpha);
6300 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
6302 for (i = 0; i < sizeof(formats) / sizeof(*formats); i++)
6304 hr = IDirect3D8_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
6305 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, formats[i].format);
6306 if (FAILED(hr))
6308 skip("Format %s not supported, skipping.\n", formats[i].name);
6309 continue;
6312 for (j = 0; j < sizeof(tests) / sizeof(*tests); j++)
6314 texture_sysmem = NULL;
6315 hr = IDirect3DDevice8_CreateTexture(device, tests[j].width, 4, 1, 0,
6316 formats[i].format, tests[j].pool, &texture);
6317 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
6319 hr = IDirect3DTexture8_LockRect(texture, 0, &locked_rect, NULL, 0);
6320 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
6321 for (y = 0; y < 4; y++)
6323 memcpy((char *)locked_rect.pBits + y * locked_rect.Pitch,
6324 (char *)formats[i].content + y * 4 * formats[i].pixel_size,
6325 tests[j].width * formats[i].pixel_size);
6327 hr = IDirect3DTexture8_UnlockRect(texture, 0);
6328 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
6330 if (tests[j].pool == D3DPOOL_SYSTEMMEM)
6332 texture_sysmem = texture;
6333 hr = IDirect3DDevice8_CreateTexture(device, tests[j].width, 4, 1, 0,
6334 formats[i].format, D3DPOOL_DEFAULT, &texture);
6335 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
6337 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)texture_sysmem,
6338 (IDirect3DBaseTexture8 *)texture);
6339 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
6340 IDirect3DTexture8_Release(texture_sysmem);
6343 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
6344 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
6345 hr = IDirect3DDevice8_SetPixelShader(device, shader_alpha);
6346 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6348 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00330033, 0.0f, 0);
6349 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
6350 hr = IDirect3DDevice8_BeginScene(device);
6351 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6352 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(*quad));
6353 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6354 hr = IDirect3DDevice8_EndScene(device);
6355 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6357 for (y = 0; y < 4; y++)
6359 for (x = 0; x < tests[j].width; x++)
6361 BOOL r200_broken = formats[i].alpha_broken && alpha_broken[y][x];
6362 if (formats[i].alpha)
6363 expected_color = expected_alpha[y][x];
6364 else
6365 expected_color = 0x00ffff00;
6367 color = getPixelColor(device, 80 + 160 * x, 60 + 120 * y);
6368 ok(color_match(color, expected_color, 1) || broken(r200_broken),
6369 "Expected color 0x%08x, got 0x%08x, format %s, location %ux%u.\n",
6370 expected_color, color, formats[i].name, x, y);
6373 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
6374 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
6376 hr = IDirect3DDevice8_SetPixelShader(device, shader);
6377 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6379 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00330033, 0.0f, 0);
6380 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
6381 hr = IDirect3DDevice8_BeginScene(device);
6382 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6383 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(*quad));
6384 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6385 hr = IDirect3DDevice8_EndScene(device);
6386 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6388 for (y = 0; y < 4; y++)
6390 for (x = 0; x < tests[j].width; x++)
6392 expected_color = expected_colors[y][x];
6393 if (!formats[i].blue)
6394 expected_color |= 0x000000ff;
6396 color = getPixelColor(device, 80 + 160 * x, 60 + 120 * y);
6397 ok(color_match(color, expected_color, formats[i].slop)
6398 || broken(color_match(color, expected_color, formats[i].slop_broken)),
6399 "Expected color 0x%08x, got 0x%08x, format %s, location %ux%u.\n",
6400 expected_color, color, formats[i].name, x, y);
6403 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
6404 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
6406 IDirect3DTexture8_Release(texture);
6410 IDirect3DDevice8_DeletePixelShader(device, shader);
6411 IDirect3DDevice8_DeletePixelShader(device, shader_alpha);
6413 done:
6414 refcount = IDirect3DDevice8_Release(device);
6415 ok(!refcount, "Device has %u references left.\n", refcount);
6416 IDirect3D8_Release(d3d);
6417 DestroyWindow(window);
6420 static void test_updatetexture(void)
6422 IDirect3DDevice8 *device;
6423 IDirect3D8 *d3d;
6424 HWND window;
6425 HRESULT hr;
6426 IDirect3DBaseTexture8 *src, *dst;
6427 unsigned int t, i, f, l, x, y, z;
6428 D3DLOCKED_RECT locked_rect;
6429 D3DLOCKED_BOX locked_box;
6430 ULONG refcount;
6431 D3DCAPS8 caps;
6432 D3DCOLOR color;
6433 BOOL ati2n_supported, do_visual_test;
6434 static const struct
6436 struct vec3 pos;
6437 struct vec2 texcoord;
6439 quad[] =
6441 {{-1.0f, -1.0f, 0.0f}, {0.0f, 1.0f}},
6442 {{-1.0f, 1.0f, 0.0f}, {0.0f, 0.0f}},
6443 {{ 1.0f, -1.0f, 0.0f}, {1.0f, 1.0f}},
6444 {{ 1.0f, 1.0f, 0.0f}, {1.0f, 0.0f}},
6446 static const struct
6448 struct vec3 pos;
6449 struct vec3 texcoord;
6451 quad_cube_tex[] =
6453 {{-1.0f, -1.0f, 0.0f}, {1.0f, -0.5f, 0.5f}},
6454 {{-1.0f, 1.0f, 0.0f}, {1.0f, 0.5f, 0.5f}},
6455 {{ 1.0f, -1.0f, 0.0f}, {1.0f, -0.5f, -0.5f}},
6456 {{ 1.0f, 1.0f, 0.0f}, {1.0f, 0.5f, -0.5f}},
6458 static const struct
6460 UINT src_width, src_height;
6461 UINT dst_width, dst_height;
6462 UINT src_levels, dst_levels;
6463 D3DFORMAT src_format, dst_format;
6464 BOOL broken;
6466 tests[] =
6468 {8, 8, 8, 8, 0, 0, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 0 */
6469 {8, 8, 8, 8, 4, 4, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 1 */
6470 {8, 8, 8, 8, 2, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 2 */
6471 {8, 8, 8, 8, 1, 1, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 3 */
6472 {8, 8, 8, 8, 4, 0, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 4 */
6473 {8, 8, 2, 2, 4, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 5 */
6474 /* The WARP renderer doesn't handle these cases correctly. */
6475 {8, 8, 8, 8, 4, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, TRUE}, /* 6 */
6476 {8, 8, 4, 4, 4, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, TRUE}, /* 7 */
6477 /* Not clear what happens here on Windows, it doesn't make much sense
6478 * though (on Nvidia it seems to upload the 4x4 surface into the 7x7
6479 * one or something like that). */
6480 /* {8, 8, 7, 7, 4, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, */
6481 {8, 8, 8, 8, 1, 4, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 8 */
6482 {4, 4, 8, 8, 1, 1, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 9 */
6483 /* This one causes weird behavior on Windows (it probably writes out
6484 * of the texture memory). */
6485 /* {8, 8, 4, 4, 1, 1, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, */
6486 {8, 4, 4, 2, 4, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 10 */
6487 {8, 4, 2, 4, 4, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 11 */
6488 {8, 8, 8, 8, 4, 4, D3DFMT_A8R8G8B8, D3DFMT_X8R8G8B8, FALSE}, /* 12 */
6489 {8, 8, 8, 8, 4, 4, D3DFMT_X8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 13 */
6490 /* The data is converted correctly on AMD, on Nvidia nothing happens
6491 * (it draws a black quad). */
6492 {8, 8, 8, 8, 4, 4, D3DFMT_A8R8G8B8, D3DFMT_R5G6B5, TRUE}, /* 14 */
6493 /* This one doesn't seem to give the expected results on AMD. */
6494 /* {8, 8, 8, 8, 4, 4, D3DFMT_A8R8G8B8, D3DFMT_Q8W8V8U8, FALSE}, */
6495 {8, 8, 8, 8, 4, 4, MAKEFOURCC('A','T','I','2'), MAKEFOURCC('A','T','I','2'), FALSE}, /* 15 */
6496 {8, 8, 8, 8, 4, 2, MAKEFOURCC('A','T','I','2'), MAKEFOURCC('A','T','I','2'), FALSE}, /* 16 */
6497 {8, 8, 2, 2, 4, 2, MAKEFOURCC('A','T','I','2'), MAKEFOURCC('A','T','I','2'), FALSE}, /* 17 */
6499 static const struct
6501 D3DRESOURCETYPE type;
6502 DWORD fvf;
6503 const void *quad;
6504 unsigned int vertex_size;
6505 DWORD cap;
6506 const char *name;
6508 texture_types[] =
6510 {D3DRTYPE_TEXTURE, D3DFVF_XYZ | D3DFVF_TEX1,
6511 quad, sizeof(*quad), D3DPTEXTURECAPS_MIPMAP, "2D mipmapped"},
6513 {D3DRTYPE_CUBETEXTURE, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE3(0),
6514 quad_cube_tex, sizeof(*quad_cube_tex), D3DPTEXTURECAPS_CUBEMAP, "Cube"},
6516 {D3DRTYPE_VOLUMETEXTURE, D3DFVF_XYZ | D3DFVF_TEX1,
6517 quad, sizeof(*quad), D3DPTEXTURECAPS_VOLUMEMAP, "Volume"}
6520 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
6521 0, 0, 640, 480, NULL, NULL, NULL, NULL);
6522 d3d = Direct3DCreate8(D3D_SDK_VERSION);
6523 ok(!!d3d, "Failed to create a D3D object.\n");
6524 if (!(device = create_device(d3d, window, window, TRUE)))
6526 skip("Failed to create a D3D device, skipping tests.\n");
6527 IDirect3D8_Release(d3d);
6528 DestroyWindow(window);
6529 return;
6532 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
6533 ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
6535 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR);
6536 ok(SUCCEEDED(hr), "Failed to set texture filtering state, hr %#x.\n", hr);
6537 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP);
6538 ok(SUCCEEDED(hr), "Failed to set texture filtering state, hr %#x.\n", hr);
6539 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP);
6540 ok(SUCCEEDED(hr), "Failed to set texture filtering state, hr %#x.\n", hr);
6541 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_ADDRESSW, D3DTADDRESS_CLAMP);
6542 ok(SUCCEEDED(hr), "Failed to set texture filtering state, hr %#x.\n", hr);
6543 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6544 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6545 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
6546 ok(hr == D3D_OK, "Failed to set texture stage state, hr %#x.\n", hr);
6547 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
6548 ok(hr == D3D_OK, "Failed to set texture stage state, hr %#x.\n", hr);
6550 for (t = 0; t < sizeof(texture_types) / sizeof(*texture_types); ++t)
6552 if (!(caps.TextureCaps & texture_types[t].cap))
6554 skip("%s textures not supported, skipping some tests.\n", texture_types[t].name);
6555 continue;
6558 if (FAILED(IDirect3D8_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
6559 D3DFMT_X8R8G8B8, 0, texture_types[t].type, MAKEFOURCC('A','T','I','2'))))
6561 skip("%s ATI2N textures are not supported, skipping some tests.\n", texture_types[t].name);
6562 ati2n_supported = FALSE;
6564 else
6566 ati2n_supported = TRUE;
6569 hr = IDirect3DDevice8_SetVertexShader(device, texture_types[t].fvf);
6570 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
6572 for (i = 0; i < sizeof(tests) / sizeof(*tests); ++i)
6574 if (tests[i].src_format == MAKEFOURCC('A','T','I','2') && !ati2n_supported)
6575 continue;
6577 switch (texture_types[t].type)
6579 case D3DRTYPE_TEXTURE:
6580 hr = IDirect3DDevice8_CreateTexture(device,
6581 tests[i].src_width, tests[i].src_height,
6582 tests[i].src_levels, 0, tests[i].src_format, D3DPOOL_SYSTEMMEM,
6583 (IDirect3DTexture8 **)&src);
6584 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x, case %u, %u.\n", hr, t, i);
6585 hr = IDirect3DDevice8_CreateTexture(device,
6586 tests[i].dst_width, tests[i].dst_height,
6587 tests[i].dst_levels, 0, tests[i].dst_format, D3DPOOL_DEFAULT,
6588 (IDirect3DTexture8 **)&dst);
6589 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x, case %u, %u.\n", hr, t, i);
6590 break;
6591 case D3DRTYPE_CUBETEXTURE:
6592 hr = IDirect3DDevice8_CreateCubeTexture(device,
6593 tests[i].src_width,
6594 tests[i].src_levels, 0, tests[i].src_format, D3DPOOL_SYSTEMMEM,
6595 (IDirect3DCubeTexture8 **)&src);
6596 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x, case %u, %u.\n", hr, t, i);
6597 hr = IDirect3DDevice8_CreateCubeTexture(device,
6598 tests[i].dst_width,
6599 tests[i].dst_levels, 0, tests[i].dst_format, D3DPOOL_DEFAULT,
6600 (IDirect3DCubeTexture8 **)&dst);
6601 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x, case %u, %u.\n", hr, t, i);
6602 break;
6603 case D3DRTYPE_VOLUMETEXTURE:
6604 hr = IDirect3DDevice8_CreateVolumeTexture(device,
6605 tests[i].src_width, tests[i].src_height, tests[i].src_width,
6606 tests[i].src_levels, 0, tests[i].src_format, D3DPOOL_SYSTEMMEM,
6607 (IDirect3DVolumeTexture8 **)&src);
6608 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x, case %u, %u.\n", hr, t, i);
6609 hr = IDirect3DDevice8_CreateVolumeTexture(device,
6610 tests[i].dst_width, tests[i].dst_height, tests[i].dst_width,
6611 tests[i].dst_levels, 0, tests[i].dst_format, D3DPOOL_DEFAULT,
6612 (IDirect3DVolumeTexture8 **)&dst);
6613 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x, case %u, %u.\n", hr, t, i);
6614 break;
6615 default:
6616 trace("Unexpected resource type.\n");
6619 /* Skip the visual part of the test for ATI2N (laziness) and cases that
6620 * give a different (and unlikely to be useful) result. */
6621 do_visual_test = (tests[i].src_format == D3DFMT_A8R8G8B8 || tests[i].src_format == D3DFMT_X8R8G8B8)
6622 && tests[i].src_levels != 0
6623 && tests[i].src_width >= tests[i].dst_width && tests[i].src_height >= tests[i].dst_height
6624 && !(tests[i].src_width > tests[i].src_height && tests[i].dst_width < tests[i].dst_height);
6626 if (do_visual_test)
6628 DWORD *ptr = NULL;
6629 unsigned int width, height, depth, row_pitch = 0, slice_pitch = 0;
6631 for (f = 0; f < (texture_types[t].type == D3DRTYPE_CUBETEXTURE ? 6 : 1); ++f)
6633 width = tests[i].src_width;
6634 height = texture_types[t].type != D3DRTYPE_CUBETEXTURE ? tests[i].src_height : tests[i].src_width;
6635 depth = texture_types[t].type == D3DRTYPE_VOLUMETEXTURE ? width : 1;
6637 for (l = 0; l < tests[i].src_levels; ++l)
6639 switch (texture_types[t].type)
6641 case D3DRTYPE_TEXTURE:
6642 hr = IDirect3DTexture8_LockRect((IDirect3DTexture8 *)src,
6643 l, &locked_rect, NULL, 0);
6644 ptr = locked_rect.pBits;
6645 row_pitch = locked_rect.Pitch / sizeof(*ptr);
6646 break;
6647 case D3DRTYPE_CUBETEXTURE:
6648 hr = IDirect3DCubeTexture8_LockRect((IDirect3DCubeTexture8 *)src,
6649 f, l, &locked_rect, NULL, 0);
6650 ptr = locked_rect.pBits;
6651 row_pitch = locked_rect.Pitch / sizeof(*ptr);
6652 break;
6653 case D3DRTYPE_VOLUMETEXTURE:
6654 hr = IDirect3DVolumeTexture8_LockBox((IDirect3DVolumeTexture8 *)src,
6655 l, &locked_box, NULL, 0);
6656 ptr = locked_box.pBits;
6657 row_pitch = locked_box.RowPitch / sizeof(*ptr);
6658 slice_pitch = locked_box.SlicePitch / sizeof(*ptr);
6659 break;
6660 default:
6661 trace("Unexpected resource type.\n");
6663 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
6665 for (z = 0; z < depth; ++z)
6667 for (y = 0; y < height; ++y)
6669 for (x = 0; x < width; ++x)
6671 ptr[z * slice_pitch + y * row_pitch + x] = 0xff000000
6672 | (DWORD)(x / (width - 1.0f) * 255.0f) << 16
6673 | (DWORD)(y / (height - 1.0f) * 255.0f) << 8;
6678 switch (texture_types[t].type)
6680 case D3DRTYPE_TEXTURE:
6681 hr = IDirect3DTexture8_UnlockRect((IDirect3DTexture8 *)src, l);
6682 break;
6683 case D3DRTYPE_CUBETEXTURE:
6684 hr = IDirect3DCubeTexture8_UnlockRect((IDirect3DCubeTexture8 *)src, f, l);
6685 break;
6686 case D3DRTYPE_VOLUMETEXTURE:
6687 hr = IDirect3DVolumeTexture8_UnlockBox((IDirect3DVolumeTexture8 *)src, l);
6688 break;
6689 default:
6690 trace("Unexpected resource type.\n");
6692 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
6694 width >>= 1;
6695 if (!width)
6696 width = 1;
6697 height >>= 1;
6698 if (!height)
6699 height = 1;
6700 depth >>= 1;
6701 if (!depth)
6702 depth = 1;
6707 hr = IDirect3DDevice8_UpdateTexture(device, src, dst);
6708 if (FAILED(hr))
6710 todo_wine ok(SUCCEEDED(hr), "Failed to update texture, hr %#x, case %u, %u.\n", hr, t, i);
6711 IDirect3DBaseTexture8_Release(src);
6712 IDirect3DBaseTexture8_Release(dst);
6713 continue;
6715 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x, case %u, %u.\n", hr, t, i);
6717 if (do_visual_test)
6719 hr = IDirect3DDevice8_SetTexture(device, 0, dst);
6720 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
6722 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 1.0f, 0);
6723 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
6725 hr = IDirect3DDevice8_BeginScene(device);
6726 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6727 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,
6728 texture_types[t].quad, texture_types[t].vertex_size);
6729 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6730 hr = IDirect3DDevice8_EndScene(device);
6731 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6733 color = getPixelColor(device, 320, 240);
6734 ok (color_match(color, 0x007f7f00, 2) || broken(tests[i].broken)
6735 || broken(color == 0x00adbeef), /* WARP device often just breaks down. */
6736 "Got unexpected color 0x%08x, case %u, %u.\n", color, t, i);
6739 IDirect3DBaseTexture8_Release(src);
6740 IDirect3DBaseTexture8_Release(dst);
6744 refcount = IDirect3DDevice8_Release(device);
6745 ok(!refcount, "Device has %u references left.\n", refcount);
6746 IDirect3D8_Release(d3d);
6747 DestroyWindow(window);
6750 static BOOL point_match(IDirect3DDevice8 *device, UINT x, UINT y, UINT r)
6752 D3DCOLOR color;
6754 color = D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff);
6755 if (!color_match(getPixelColor(device, x + r, y), color, 1))
6756 return FALSE;
6757 if (!color_match(getPixelColor(device, x - r, y), color, 1))
6758 return FALSE;
6759 if (!color_match(getPixelColor(device, x, y + r), color, 1))
6760 return FALSE;
6761 if (!color_match(getPixelColor(device, x, y - r), color, 1))
6762 return FALSE;
6764 ++r;
6765 color = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff);
6766 if (!color_match(getPixelColor(device, x + r, y), color, 1))
6767 return FALSE;
6768 if (!color_match(getPixelColor(device, x - r, y), color, 1))
6769 return FALSE;
6770 if (!color_match(getPixelColor(device, x, y + r), color, 1))
6771 return FALSE;
6772 if (!color_match(getPixelColor(device, x, y - r), color, 1))
6773 return FALSE;
6775 return TRUE;
6778 static void test_pointsize(void)
6780 static const float a = 0.5f, b = 0.5f, c = 0.5f;
6781 float ptsize, ptsizemax_orig, ptsizemin_orig;
6782 IDirect3DSurface8 *rt, *backbuffer, *depthstencil;
6783 IDirect3DTexture8 *tex1, *tex2;
6784 IDirect3DDevice8 *device;
6785 DWORD vs, ps;
6786 D3DLOCKED_RECT lr;
6787 IDirect3D8 *d3d;
6788 D3DCOLOR color;
6789 ULONG refcount;
6790 D3DCAPS8 caps;
6791 HWND window;
6792 HRESULT hr;
6793 unsigned int i, j;
6795 static const DWORD tex1_data[4] = {0x00ff0000, 0x00ff0000, 0x00000000, 0x00000000};
6796 static const DWORD tex2_data[4] = {0x00000000, 0x0000ff00, 0x00000000, 0x0000ff00};
6797 static const float vertices[] =
6799 64.0f, 64.0f, 0.1f,
6800 128.0f, 64.0f, 0.1f,
6801 192.0f, 64.0f, 0.1f,
6802 256.0f, 64.0f, 0.1f,
6803 320.0f, 64.0f, 0.1f,
6804 384.0f, 64.0f, 0.1f,
6805 448.0f, 64.0f, 0.1f,
6806 512.0f, 64.0f, 0.1f,
6808 static const struct
6810 float x, y, z;
6811 float point_size;
6813 vertex_pointsize = {64.0f, 64.0f, 0.1f, 48.0f},
6814 vertex_pointsize_scaled = {64.0f, 64.0f, 0.1f, 24.0f},
6815 vertex_pointsize_zero = {64.0f, 64.0f, 0.1f, 0.0f};
6816 static const DWORD decl[] =
6818 D3DVSD_STREAM(0),
6819 D3DVSD_REG(0, D3DVSDT_FLOAT3), /* position */
6820 D3DVSD_END()
6822 decl_psize[] =
6824 D3DVSD_STREAM(0),
6825 D3DVSD_REG(0, D3DVSDT_FLOAT3), /* position, v0 */
6826 D3DVSD_REG(1, D3DVSDT_FLOAT1), /* point size, v1 */
6827 D3DVSD_END()
6829 static const DWORD vshader_code[] =
6831 0xfffe0101, /* vs_1_1 */
6832 0x00000005, 0x800f0000, 0x90000000, 0xa0e40000, /* mul r0, v0.x, c0 */
6833 0x00000004, 0x800f0000, 0x90550000, 0xa0e40001, 0x80e40000, /* mad r0, v0.y, c1, r0 */
6834 0x00000004, 0x800f0000, 0x90aa0000, 0xa0e40002, 0x80e40000, /* mad r0, v0.z, c2, r0 */
6835 0x00000004, 0xc00f0000, 0x90ff0000, 0xa0e40003, 0x80e40000, /* mad oPos, v0.w, c3, r0 */
6836 0x0000ffff
6838 static const DWORD vshader_psize_code[] =
6840 0xfffe0101, /* vs_1_1 */
6841 0x00000005, 0x800f0000, 0x90000000, 0xa0e40000, /* mul r0, v0.x, c0 */
6842 0x00000004, 0x800f0000, 0x90550000, 0xa0e40001, 0x80e40000, /* mad r0, v0.y, c1, r0 */
6843 0x00000004, 0x800f0000, 0x90aa0000, 0xa0e40002, 0x80e40000, /* mad r0, v0.z, c2, r0 */
6844 0x00000004, 0xc00f0000, 0x90ff0000, 0xa0e40003, 0x80e40000, /* mad oPos, v0.w, c3, r0 */
6845 0x00000001, 0xc00f0002, 0x90000001, /* mov oPts, v1.x */
6846 0x0000ffff
6848 static const DWORD pshader_code[] =
6850 0xffff0101, /* ps_1_1 */
6851 0x00000042, 0xb00f0000, /* tex t0 */
6852 0x00000042, 0xb00f0001, /* tex t1 */
6853 0x00000002, 0x800f0000, 0xb0e40000, 0xb0e40001, /* add r0, t0, t1 */
6854 0x0000ffff
6856 static const struct test_shader
6858 DWORD version;
6859 const DWORD *code;
6861 novs = {0, NULL},
6862 vs1 = {D3DVS_VERSION(1, 1), vshader_code},
6863 vs1_psize = {D3DVS_VERSION(1, 1), vshader_psize_code},
6864 nops = {0, NULL},
6865 ps1 = {D3DPS_VERSION(1, 1), pshader_code};
6866 static const struct
6868 const DWORD *decl;
6869 const struct test_shader *vs;
6870 const struct test_shader *ps;
6871 DWORD accepted_fvf;
6872 unsigned int nonscaled_size, scaled_size;
6874 test_setups[] =
6876 {NULL, &novs, &nops, D3DFVF_XYZ, 32, 62},
6877 {decl, &vs1, &ps1, D3DFVF_XYZ, 32, 32},
6878 {NULL, &novs, &ps1, D3DFVF_XYZ, 32, 62},
6879 {decl, &vs1, &nops, D3DFVF_XYZ, 32, 32},
6880 {NULL, &novs, &nops, D3DFVF_XYZ | D3DFVF_PSIZE, 48, 48},
6881 {decl_psize, &vs1_psize, &ps1, D3DFVF_XYZ | D3DFVF_PSIZE, 48, 24},
6883 static const struct
6885 BOOL zero_size;
6886 BOOL scale;
6887 BOOL override_min;
6888 DWORD fvf;
6889 const void *vertex_data;
6890 unsigned int vertex_size;
6892 tests[] =
6894 {FALSE, FALSE, FALSE, D3DFVF_XYZ, vertices, sizeof(float) * 3},
6895 {FALSE, TRUE, FALSE, D3DFVF_XYZ, vertices, sizeof(float) * 3},
6896 {FALSE, FALSE, TRUE, D3DFVF_XYZ, vertices, sizeof(float) * 3},
6897 {TRUE, FALSE, FALSE, D3DFVF_XYZ, vertices, sizeof(float) * 3},
6898 {FALSE, FALSE, FALSE, D3DFVF_XYZ | D3DFVF_PSIZE, &vertex_pointsize, sizeof(vertex_pointsize)},
6899 {FALSE, TRUE, FALSE, D3DFVF_XYZ | D3DFVF_PSIZE, &vertex_pointsize_scaled, sizeof(vertex_pointsize_scaled)},
6900 {FALSE, FALSE, TRUE, D3DFVF_XYZ | D3DFVF_PSIZE, &vertex_pointsize, sizeof(vertex_pointsize)},
6901 {TRUE, FALSE, FALSE, D3DFVF_XYZ | D3DFVF_PSIZE, &vertex_pointsize_zero, sizeof(vertex_pointsize_zero)},
6903 /* Transforms the coordinate system [-1.0;1.0]x[1.0;-1.0] to
6904 * [0.0;0.0]x[640.0;480.0]. Z is untouched. */
6905 D3DMATRIX matrix =
6907 2.0f / 640.0f, 0.0f, 0.0f, 0.0f,
6908 0.0f, -2.0f / 480.0f, 0.0f, 0.0f,
6909 0.0f, 0.0f, 1.0f, 0.0f,
6910 -1.0f, 1.0f, 0.0f, 1.0f,
6911 }}};
6913 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
6914 0, 0, 640, 480, NULL, NULL, NULL, NULL);
6915 d3d = Direct3DCreate8(D3D_SDK_VERSION);
6916 ok(!!d3d, "Failed to create a D3D object.\n");
6917 if (!(device = create_device(d3d, window, window, TRUE)))
6919 skip("Failed to create a D3D device, skipping tests.\n");
6920 goto done;
6923 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
6924 ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
6925 if (caps.MaxPointSize < 32.0f)
6927 skip("MaxPointSize %f < 32.0, skipping.\n", caps.MaxPointSize);
6928 IDirect3DDevice8_Release(device);
6929 goto done;
6932 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
6933 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
6934 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6935 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
6936 hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, &matrix);
6937 ok(SUCCEEDED(hr), "Failed to set projection matrix, hr %#x.\n", hr);
6938 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ);
6939 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
6941 hr = IDirect3DDevice8_BeginScene(device);
6942 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6944 ptsize = 15.0f;
6945 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
6946 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6947 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
6948 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6950 ptsize = 31.0f;
6951 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
6952 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6953 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[3], sizeof(float) * 3);
6954 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6956 ptsize = 30.75f;
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[6], sizeof(float) * 3);
6960 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6962 if (caps.MaxPointSize >= 63.0f)
6964 ptsize = 63.0f;
6965 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
6966 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6967 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[9], sizeof(float) * 3);
6968 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6970 ptsize = 62.75f;
6971 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
6972 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6973 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[15], sizeof(float) * 3);
6974 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6977 ptsize = 1.0f;
6978 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
6979 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6980 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[12], sizeof(float) * 3);
6981 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6983 hr = IDirect3DDevice8_GetRenderState(device, D3DRS_POINTSIZE_MAX, (DWORD *)&ptsizemax_orig);
6984 ok(SUCCEEDED(hr), "Failed to get render state, hr %#x.\n", hr);
6985 hr = IDirect3DDevice8_GetRenderState(device, D3DRS_POINTSIZE_MIN, (DWORD *)&ptsizemin_orig);
6986 ok(SUCCEEDED(hr), "Failed to get render state, hr %#x.\n", hr);
6988 /* What happens if point scaling is disabled, and POINTSIZE_MAX < POINTSIZE? */
6989 ptsize = 15.0f;
6990 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
6991 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6992 ptsize = 1.0f;
6993 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE_MAX, *(DWORD *)&ptsize);
6994 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6995 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[18], sizeof(float) * 3);
6996 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6998 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE_MAX, *(DWORD *)&ptsizemax_orig);
6999 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
7001 /* pointsize < pointsize_min < pointsize_max?
7002 * pointsize = 1.0, pointsize_min = 15.0, pointsize_max = default(usually 64.0) */
7003 ptsize = 1.0f;
7004 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
7005 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
7006 ptsize = 15.0f;
7007 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE_MIN, *(DWORD *)&ptsize);
7008 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
7009 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[21], sizeof(float) * 3);
7010 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7012 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE_MIN, *(DWORD *)&ptsizemin_orig);
7013 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
7015 hr = IDirect3DDevice8_EndScene(device);
7016 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7018 ok(point_match(device, 64, 64, 7), "point_match(64, 64, 7) failed, expected point size 15.\n");
7019 ok(point_match(device, 128, 64, 15), "point_match(128, 64, 15) failed, expected point size 31.\n");
7020 ok(point_match(device, 192, 64, 15), "point_match(192, 64, 15) failed, expected point size 31.\n");
7022 if (caps.MaxPointSize >= 63.0f)
7024 ok(point_match(device, 256, 64, 31), "point_match(256, 64, 31) failed, expected point size 63.\n");
7025 ok(point_match(device, 384, 64, 31), "point_match(384, 64, 31) failed, expected point size 63.\n");
7028 ok(point_match(device, 320, 64, 0), "point_match(320, 64, 0) failed, expected point size 1.\n");
7029 /* ptsize = 15, ptsize_max = 1 --> point has size 1 */
7030 ok(point_match(device, 448, 64, 0), "point_match(448, 64, 0) failed, expected point size 1.\n");
7031 /* ptsize = 1, ptsize_max = default(64), ptsize_min = 15 --> point has size 15 */
7032 ok(point_match(device, 512, 64, 7), "point_match(512, 64, 7) failed, expected point size 15.\n");
7034 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
7036 /* The following code tests point sprites with two textures, to see if each texture coordinate unit
7037 * generates texture coordinates for the point(result: Yes, it does)
7039 * However, not all GL implementations support point sprites(they need GL_ARB_point_sprite), but there
7040 * is no point sprite cap bit in d3d because native d3d software emulates point sprites. Until the
7041 * SW emulation is implemented in wined3d, this test will fail on GL drivers that does not support them.
7043 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
7044 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
7046 hr = IDirect3DDevice8_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex1);
7047 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
7048 hr = IDirect3DDevice8_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex2);
7049 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
7050 memset(&lr, 0, sizeof(lr));
7051 hr = IDirect3DTexture8_LockRect(tex1, 0, &lr, NULL, 0);
7052 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
7053 memcpy(lr.pBits, tex1_data, sizeof(tex1_data));
7054 hr = IDirect3DTexture8_UnlockRect(tex1, 0);
7055 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
7056 memset(&lr, 0, sizeof(lr));
7057 hr = IDirect3DTexture8_LockRect(tex2, 0, &lr, NULL, 0);
7058 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
7059 memcpy(lr.pBits, tex2_data, sizeof(tex2_data));
7060 hr = IDirect3DTexture8_UnlockRect(tex2, 0);
7061 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
7062 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)tex1);
7063 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
7064 hr = IDirect3DDevice8_SetTexture(device, 1, (IDirect3DBaseTexture8 *)tex2);
7065 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
7066 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7067 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
7068 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7069 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
7070 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
7071 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
7072 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7073 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
7074 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
7075 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
7077 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSPRITEENABLE, TRUE);
7078 ok(SUCCEEDED(hr), "Failed to enable point sprites, hr %#x.\n", hr);
7079 ptsize = 32.0f;
7080 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
7081 ok(SUCCEEDED(hr), "Failed to set point size, hr %#x.\n", hr);
7083 hr = IDirect3DDevice8_BeginScene(device);
7084 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7085 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
7086 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7087 hr = IDirect3DDevice8_EndScene(device);
7088 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7090 color = getPixelColor(device, 64 - 4, 64 - 4);
7091 ok(color == 0x00ff0000, "pSprite: Pixel (64 - 4),(64 - 4) has color 0x%08x, expected 0x00ff0000\n", color);
7092 color = getPixelColor(device, 64 - 4, 64 + 4);
7093 ok(color == 0x00000000, "pSprite: Pixel (64 - 4),(64 + 4) has color 0x%08x, expected 0x00000000\n", color);
7094 color = getPixelColor(device, 64 + 4, 64 + 4);
7095 ok(color == 0x0000ff00, "pSprite: Pixel (64 + 4),(64 + 4) has color 0x%08x, expected 0x0000ff00\n", color);
7096 color = getPixelColor(device, 64 + 4, 64 - 4);
7097 ok(color == 0x00ffff00, "pSprite: Pixel (64 + 4),(64 - 4) has color 0x%08x, expected 0x00ffff00\n", color);
7098 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
7100 U(matrix).m[0][0] = 1.0f / 64.0f;
7101 U(matrix).m[1][1] = -1.0f / 64.0f;
7102 hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, &matrix);
7103 ok(SUCCEEDED(hr), "Failed to set projection matrix, hr %#x.\n", hr);
7105 hr = IDirect3DDevice8_GetRenderTarget(device, &backbuffer);
7106 ok(SUCCEEDED(hr), "Failed to get backbuffer, hr %#x.\n", hr);
7107 hr = IDirect3DDevice8_GetDepthStencilSurface(device, &depthstencil);
7108 ok(SUCCEEDED(hr), "Failed to get depth / stencil buffer, hr %#x.\n", hr);
7110 hr = IDirect3DDevice8_CreateRenderTarget(device, 128, 128, D3DFMT_A8R8G8B8,
7111 D3DMULTISAMPLE_NONE, TRUE, &rt);
7112 ok(SUCCEEDED(hr), "Failed to create a render target, hr %#x.\n", hr);
7114 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSCALE_A, *(DWORD *)&a);
7115 ok(SUCCEEDED(hr), "Failed setting point scale attenuation coefficient, hr %#x.\n", hr);
7116 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSCALE_B, *(DWORD *)&b);
7117 ok(SUCCEEDED(hr), "Failed setting point scale attenuation coefficient, hr %#x.\n", hr);
7118 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSCALE_C, *(DWORD *)&c);
7119 ok(SUCCEEDED(hr), "Failed setting point scale attenuation coefficient, hr %#x.\n", hr);
7120 hr = IDirect3DDevice8_SetVertexShaderConstant(device, 0, &S(U(matrix))._11, 4);
7121 ok(SUCCEEDED(hr), "Failed to set vertex shader constants, hr %#x.\n", hr);
7123 if (caps.MaxPointSize < 63.0f)
7125 skip("MaxPointSize %f < 63.0, skipping some tests.\n", caps.MaxPointSize);
7126 goto cleanup;
7129 hr = IDirect3DDevice8_SetRenderTarget(device, rt, depthstencil);
7130 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
7132 for (i = 0; i < sizeof(test_setups) / sizeof(test_setups[0]); ++i)
7134 if (caps.VertexShaderVersion < test_setups[i].vs->version
7135 || caps.PixelShaderVersion < test_setups[i].ps->version)
7137 skip("Vertex / pixel shader version not supported, skipping test.\n");
7138 continue;
7140 if (test_setups[i].vs->code)
7142 hr = IDirect3DDevice8_CreateVertexShader(device, test_setups[i].decl, test_setups[i].vs->code, &vs, 0);
7143 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x (case %u).\n", hr, i);
7145 else
7147 vs = 0;
7149 if (test_setups[i].ps->code)
7151 hr = IDirect3DDevice8_CreatePixelShader(device, test_setups[i].ps->code, &ps);
7152 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x (case %u).\n", hr, i);
7154 else
7156 ps = 0;
7159 hr = IDirect3DDevice8_SetVertexShader(device, vs ? vs : test_setups[i].accepted_fvf);
7160 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
7161 hr = IDirect3DDevice8_SetPixelShader(device, ps);
7162 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
7164 for (j = 0; j < sizeof(tests) / sizeof(tests[0]); ++j)
7166 unsigned int size = tests[j].override_min ? 63 : tests[j].zero_size ? 0 : tests[j].scale
7167 ? test_setups[i].scaled_size : test_setups[i].nonscaled_size;
7169 if (test_setups[i].accepted_fvf != tests[j].fvf)
7170 continue;
7172 ptsize = tests[j].zero_size ? 0.0f : 32.0f;
7173 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
7174 ok(SUCCEEDED(hr), "Failed to set pointsize, hr %#x.\n", hr);
7176 ptsize = tests[j].override_min ? 63.0f : tests[j].zero_size ? 0.0f : ptsizemin_orig;
7177 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE_MIN, *(DWORD *)&ptsize);
7178 ok(SUCCEEDED(hr), "Failed to set minimum pointsize, hr %#x.\n", hr);
7180 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSCALEENABLE, tests[j].scale);
7181 ok(SUCCEEDED(hr), "Failed setting point scale state, hr %#x.\n", hr);
7183 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
7184 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
7186 hr = IDirect3DDevice8_BeginScene(device);
7187 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7188 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1,
7189 tests[j].vertex_data, tests[j].vertex_size);
7190 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7191 hr = IDirect3DDevice8_EndScene(device);
7192 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7194 if (tests[j].zero_size)
7196 /* Technically 0 pointsize is undefined in OpenGL but in practice it seems like
7197 * it does the "useful" thing on all the drivers I tried. */
7198 /* On WARP it does draw some pixels, most of the time. */
7199 color = getPixelColor(device, 64, 64);
7200 ok(color_match(color, 0x0000ffff, 0)
7201 || broken(color_match(color, 0x00ff0000, 0))
7202 || broken(color_match(color, 0x00ffff00, 0))
7203 || broken(color_match(color, 0x00000000, 0))
7204 || broken(color_match(color, 0x0000ff00, 0)),
7205 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
7207 else
7209 struct surface_readback rb;
7211 get_rt_readback(rt, &rb);
7212 color = get_readback_color(&rb, 64 - size / 2 + 1, 64 - size / 2 + 1);
7213 ok(color_match(color, 0x00ff0000, 0),
7214 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
7215 color = get_readback_color(&rb, 64 + size / 2 - 1, 64 - size / 2 + 1);
7216 ok(color_match(color, 0x00ffff00, 0),
7217 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
7218 color = get_readback_color(&rb, 64 - size / 2 + 1, 64 + size / 2 - 1);
7219 ok(color_match(color, 0x00000000, 0),
7220 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
7221 color = get_readback_color(&rb, 64 + size / 2 - 1, 64 + size / 2 - 1);
7222 ok(color_match(color, 0x0000ff00, 0),
7223 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
7225 color = get_readback_color(&rb, 64 - size / 2 - 1, 64 - size / 2 - 1);
7226 ok(color_match(color, 0xff00ffff, 0),
7227 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
7228 color = get_readback_color(&rb, 64 + size / 2 + 1, 64 - size / 2 - 1);
7229 ok(color_match(color, 0xff00ffff, 0),
7230 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
7231 color = get_readback_color(&rb, 64 - size / 2 - 1, 64 + size / 2 + 1);
7232 ok(color_match(color, 0xff00ffff, 0),
7233 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
7234 color = get_readback_color(&rb, 64 + size / 2 + 1, 64 + size / 2 + 1);
7235 ok(color_match(color, 0xff00ffff, 0),
7236 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
7238 release_surface_readback(&rb);
7241 IDirect3DDevice8_SetVertexShader(device, 0);
7242 IDirect3DDevice8_SetPixelShader(device, 0);
7243 if (vs)
7244 IDirect3DDevice8_DeleteVertexShader(device, vs);
7245 if (ps)
7246 IDirect3DDevice8_DeletePixelShader(device, ps);
7248 hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, depthstencil);
7249 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
7251 cleanup:
7252 IDirect3DSurface8_Release(backbuffer);
7253 IDirect3DSurface8_Release(depthstencil);
7254 IDirect3DSurface8_Release(rt);
7256 IDirect3DTexture8_Release(tex1);
7257 IDirect3DTexture8_Release(tex2);
7258 refcount = IDirect3DDevice8_Release(device);
7259 ok(!refcount, "Device has %u references left.\n", refcount);
7260 done:
7261 IDirect3D8_Release(d3d);
7262 DestroyWindow(window);
7265 static void test_multisample_mismatch(void)
7267 IDirect3DDevice8 *device;
7268 IDirect3D8 *d3d;
7269 HWND window;
7270 HRESULT hr;
7271 ULONG refcount;
7272 IDirect3DSurface8 *rt_multi, *ds;
7274 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
7275 0, 0, 640, 480, NULL, NULL, NULL, NULL);
7276 d3d = Direct3DCreate8(D3D_SDK_VERSION);
7277 ok(!!d3d, "Failed to create a D3D object.\n");
7278 if (FAILED(IDirect3D8_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
7279 D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES)))
7281 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping multisample mismatch test.\n");
7282 IDirect3D8_Release(d3d);
7283 return;
7286 if (!(device = create_device(d3d, window, window, TRUE)))
7288 skip("Failed to create a D3D device, skipping tests.\n");
7289 goto done;
7292 hr = IDirect3DDevice8_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
7293 D3DMULTISAMPLE_2_SAMPLES, FALSE, &rt_multi);
7294 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
7295 hr = IDirect3DDevice8_GetDepthStencilSurface(device, &ds);
7296 ok(SUCCEEDED(hr), "Failed to get original depth/stencil, hr %#x.\n", hr);
7298 hr = IDirect3DDevice8_SetRenderTarget(device, rt_multi, ds);
7299 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
7301 IDirect3DSurface8_Release(ds);
7302 IDirect3DSurface8_Release(rt_multi);
7304 refcount = IDirect3DDevice8_Release(device);
7305 ok(!refcount, "Device has %u references left.\n", refcount);
7306 done:
7307 IDirect3D8_Release(d3d);
7308 DestroyWindow(window);
7311 static void test_texcoordindex(void)
7313 static const D3DMATRIX mat =
7315 1.0f, 0.0f, 0.0f, 0.0f,
7316 0.0f, 0.0f, 0.0f, 0.0f,
7317 0.0f, 0.0f, 0.0f, 0.0f,
7318 0.0f, 0.0f, 0.0f, 0.0f,
7319 }}};
7320 static const struct
7322 struct vec3 pos;
7323 struct vec2 texcoord1;
7324 struct vec2 texcoord2;
7325 struct vec2 texcoord3;
7327 quad[] =
7329 {{-1.0f, -1.0f, 0.0f}, {0.0f, 1.0f}, {0.0f, 0.0f}, {1.0f, 1.0f}},
7330 {{-1.0f, 1.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 1.0f}, {1.0f, 0.0f}},
7331 {{ 1.0f, -1.0f, 0.0f}, {1.0f, 1.0f}, {1.0f, 0.0f}, {0.0f, 1.0f}},
7332 {{ 1.0f, 1.0f, 0.0f}, {1.0f, 0.0f}, {1.0f, 1.0f}, {0.0f, 0.0f}},
7334 IDirect3DDevice8 *device;
7335 IDirect3D8 *d3d;
7336 HWND window;
7337 HRESULT hr;
7338 IDirect3DTexture8 *texture1, *texture2;
7339 D3DLOCKED_RECT locked_rect;
7340 ULONG refcount;
7341 D3DCOLOR color;
7342 DWORD *ptr;
7344 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
7345 0, 0, 640, 480, NULL, NULL, NULL, NULL);
7346 d3d = Direct3DCreate8(D3D_SDK_VERSION);
7347 ok(!!d3d, "Failed to create a D3D object.\n");
7348 if (!(device = create_device(d3d, window, window, TRUE)))
7350 skip("Failed to create a D3D device, skipping tests.\n");
7351 IDirect3D8_Release(d3d);
7352 DestroyWindow(window);
7353 return;
7356 hr = IDirect3DDevice8_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture1);
7357 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
7358 hr = IDirect3DDevice8_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture2);
7359 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
7361 hr = IDirect3DTexture8_LockRect(texture1, 0, &locked_rect, NULL, D3DLOCK_DISCARD);
7362 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
7363 ptr = locked_rect.pBits;
7364 ptr[0] = 0xff000000;
7365 ptr[1] = 0xff00ff00;
7366 ptr[2] = 0xff0000ff;
7367 ptr[3] = 0xff00ffff;
7368 hr = IDirect3DTexture8_UnlockRect(texture1, 0);
7369 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
7371 hr = IDirect3DTexture8_LockRect(texture2, 0, &locked_rect, NULL, D3DLOCK_DISCARD);
7372 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
7373 ptr = locked_rect.pBits;
7374 ptr[0] = 0xff000000;
7375 ptr[1] = 0xff0000ff;
7376 ptr[2] = 0xffff0000;
7377 ptr[3] = 0xffff00ff;
7378 hr = IDirect3DTexture8_UnlockRect(texture2, 0);
7379 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
7381 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture1);
7382 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
7383 hr = IDirect3DDevice8_SetTexture(device, 1, (IDirect3DBaseTexture8 *)texture2);
7384 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
7385 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX3);
7386 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
7387 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
7388 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
7389 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7390 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
7391 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7392 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
7393 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
7394 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
7395 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7396 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
7397 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
7398 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
7399 hr = IDirect3DDevice8_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
7400 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
7402 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_TEXCOORDINDEX, 1);
7403 ok(SUCCEEDED(hr), "Failed to set texcoord index, hr %#x.\n", hr);
7404 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_TEXCOORDINDEX, 0);
7405 ok(SUCCEEDED(hr), "Failed to set texcoord index, hr %#x.\n", hr);
7407 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 1.0f, 0);
7408 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
7410 hr = IDirect3DDevice8_BeginScene(device);
7411 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7412 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
7413 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7414 hr = IDirect3DDevice8_EndScene(device);
7415 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7417 color = getPixelColor(device, 160, 120);
7418 ok(color_match(color, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color);
7419 color = getPixelColor(device, 480, 120);
7420 ok(color_match(color, 0x0000ffff, 2), "Got unexpected color 0x%08x.\n", color);
7421 color = getPixelColor(device, 160, 360);
7422 ok(color_match(color, 0x00ff0000, 2), "Got unexpected color 0x%08x.\n", color);
7423 color = getPixelColor(device, 480, 360);
7424 ok(color_match(color, 0x00ffffff, 2), "Got unexpected color 0x%08x.\n", color);
7426 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
7427 ok(SUCCEEDED(hr), "Failed to set texture transform flags, hr %#x.\n", hr);
7428 hr = IDirect3DDevice8_SetTransform(device, D3DTS_TEXTURE1, &mat);
7429 ok(SUCCEEDED(hr), "Failed to set transformation matrix, hr %#x.\n", hr);
7431 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 1.0f, 0);
7432 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
7434 hr = IDirect3DDevice8_BeginScene(device);
7435 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7436 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
7437 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7438 hr = IDirect3DDevice8_EndScene(device);
7439 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7441 color = getPixelColor(device, 160, 120);
7442 ok(color_match(color, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color);
7443 color = getPixelColor(device, 480, 120);
7444 ok(color_match(color, 0x0000ffff, 2), "Got unexpected color 0x%08x.\n", color);
7445 color = getPixelColor(device, 160, 360);
7446 ok(color_match(color, 0x00000000, 2), "Got unexpected color 0x%08x.\n", color);
7447 color = getPixelColor(device, 480, 360);
7448 ok(color_match(color, 0x0000ffff, 2), "Got unexpected color 0x%08x.\n", color);
7450 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
7451 ok(SUCCEEDED(hr), "Failed to set texture transform flags, hr %#x.\n", hr);
7452 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_TEXCOORDINDEX, 2);
7453 ok(SUCCEEDED(hr), "Failed to set texcoord index, hr %#x.\n", hr);
7455 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 1.0f, 0);
7456 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
7458 hr = IDirect3DDevice8_BeginScene(device);
7459 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7460 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
7461 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7462 hr = IDirect3DDevice8_EndScene(device);
7463 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7465 color = getPixelColor(device, 160, 120);
7466 ok(color_match(color, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color);
7467 color = getPixelColor(device, 480, 120);
7468 ok(color_match(color, 0x0000ffff, 2), "Got unexpected color 0x%08x.\n", color);
7469 color = getPixelColor(device, 160, 360);
7470 ok(color_match(color, 0x00ff00ff, 2), "Got unexpected color 0x%08x.\n", color);
7471 color = getPixelColor(device, 480, 360);
7472 ok(color_match(color, 0x00ffff00, 2), "Got unexpected color 0x%08x.\n", color);
7474 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
7475 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
7477 IDirect3DTexture8_Release(texture1);
7478 IDirect3DTexture8_Release(texture2);
7480 refcount = IDirect3DDevice8_Release(device);
7481 ok(!refcount, "Device has %u references left.\n", refcount);
7482 IDirect3D8_Release(d3d);
7483 DestroyWindow(window);
7486 static void test_vshader_input(void)
7488 DWORD swapped_twotexcrd_shader, swapped_onetexcrd_shader = 0;
7489 DWORD swapped_twotex_wrongidx_shader = 0, swapped_twotexcrd_rightorder_shader;
7490 DWORD texcoord_color_shader, color_ubyte_shader, color_color_shader, color_float_shader;
7491 DWORD color_nocolor_shader = 0;
7492 IDirect3DDevice8 *device;
7493 IDirect3D8 *d3d;
7494 ULONG refcount;
7495 D3DCAPS8 caps;
7496 DWORD color;
7497 HWND window;
7498 HRESULT hr;
7500 static const DWORD swapped_shader_code[] =
7502 0xfffe0101, /* vs_1_1 */
7503 0x00000001, 0xc00f0000, 0x90e40000, /* mov o0, v0 */
7504 0x00000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
7505 0x00000002, 0xd00f0000, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
7506 0x0000ffff /* end */
7508 static const DWORD texcoord_color_shader_code[] =
7510 0xfffe0101, /* vs_1_1 */
7511 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
7512 0x00000001, 0xd00f0000, 0x90e40007, /* mov oD0, v7 */
7513 0x0000ffff /* end */
7515 static const DWORD color_color_shader_code[] =
7517 0xfffe0101, /* vs_1_1 */
7518 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
7519 0x00000005, 0xd00f0000, 0xa0e40000, 0x90e40005, /* mul oD0, c0, v5 */
7520 0x0000ffff /* end */
7522 static const float quad1[] =
7524 -1.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7525 -1.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7526 0.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7527 0.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7529 static const float quad4[] =
7531 0.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7532 0.0f, 1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7533 1.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7534 1.0f, 1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7536 static const struct
7538 struct vec3 position;
7539 DWORD diffuse;
7541 quad1_color[] =
7543 {{-1.0f, -1.0f, 0.1f}, 0x00ff8040},
7544 {{-1.0f, 0.0f, 0.1f}, 0x00ff8040},
7545 {{ 0.0f, -1.0f, 0.1f}, 0x00ff8040},
7546 {{ 0.0f, 0.0f, 0.1f}, 0x00ff8040},
7548 quad2_color[] =
7550 {{ 0.0f, -1.0f, 0.1f}, 0x00ff8040},
7551 {{ 0.0f, 0.0f, 0.1f}, 0x00ff8040},
7552 {{ 1.0f, -1.0f, 0.1f}, 0x00ff8040},
7553 {{ 1.0f, 0.0f, 0.1f}, 0x00ff8040},
7555 quad3_color[] =
7557 {{-1.0f, 0.0f, 0.1f}, 0x00ff8040},
7558 {{-1.0f, 1.0f, 0.1f}, 0x00ff8040},
7559 {{ 0.0f, 0.0f, 0.1f}, 0x00ff8040},
7560 {{ 0.0f, 1.0f, 0.1f}, 0x00ff8040},
7562 static const float quad4_color[] =
7564 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 0.0f, 0.0f,
7565 0.0f, 1.0f, 0.1f, 1.0f, 1.0f, 0.0f, 0.0f,
7566 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 0.0f, 1.0f,
7567 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 0.0f, 1.0f,
7569 static const DWORD decl_twotexcrd[] =
7571 D3DVSD_STREAM(0),
7572 D3DVSD_REG(0, D3DVSDT_FLOAT3), /* position */
7573 D3DVSD_REG(1, D3DVSDT_FLOAT4), /* texcoord0 */
7574 D3DVSD_REG(2, D3DVSDT_FLOAT4), /* texcoord1 */
7575 D3DVSD_END()
7577 static const DWORD decl_twotexcrd_rightorder[] =
7579 D3DVSD_STREAM(0),
7580 D3DVSD_REG(0, D3DVSDT_FLOAT3), /* position */
7581 D3DVSD_REG(2, D3DVSDT_FLOAT4), /* texcoord0 */
7582 D3DVSD_REG(1, D3DVSDT_FLOAT4), /* texcoord1 */
7583 D3DVSD_END()
7585 static const DWORD decl_onetexcrd[] =
7587 D3DVSD_STREAM(0),
7588 D3DVSD_REG(0, D3DVSDT_FLOAT3), /* position */
7589 D3DVSD_REG(1, D3DVSDT_FLOAT4), /* texcoord0 */
7590 D3DVSD_END()
7592 static const DWORD decl_twotexcrd_wrongidx[] =
7594 D3DVSD_STREAM(0),
7595 D3DVSD_REG(0, D3DVSDT_FLOAT3), /* position */
7596 D3DVSD_REG(2, D3DVSDT_FLOAT4), /* texcoord1 */
7597 D3DVSD_REG(3, D3DVSDT_FLOAT4), /* texcoord2 */
7598 D3DVSD_END()
7600 static const DWORD decl_texcoord_color[] =
7602 D3DVSD_STREAM(0),
7603 D3DVSD_REG(0, D3DVSDT_FLOAT3), /* position */
7604 D3DVSD_REG(7, D3DVSDT_D3DCOLOR), /* texcoord0 */
7605 D3DVSD_END()
7607 static const DWORD decl_color_color[] =
7609 D3DVSD_STREAM(0),
7610 D3DVSD_REG(0, D3DVSDT_FLOAT3), /* position */
7611 D3DVSD_REG(5, D3DVSDT_D3DCOLOR), /* diffuse */
7612 D3DVSD_END()
7614 static const DWORD decl_color_ubyte[] =
7616 D3DVSD_STREAM(0),
7617 D3DVSD_REG(0, D3DVSDT_FLOAT3),
7618 D3DVSD_REG(5, D3DVSDT_UBYTE4),
7619 D3DVSD_END()
7621 static const DWORD decl_color_float[] =
7623 D3DVSD_STREAM(0),
7624 D3DVSD_REG(0, D3DVSDT_FLOAT3),
7625 D3DVSD_REG(5, D3DVSDT_FLOAT4),
7626 D3DVSD_END()
7628 static const DWORD decl_nocolor[] =
7630 D3DVSD_STREAM(0),
7631 D3DVSD_REG(0, D3DVSDT_FLOAT3),
7632 D3DVSD_END()
7634 static const float normalize[4] = {1.0f / 256.0f, 1.0f / 256.0f, 1.0f / 256.0f, 1.0f / 256.0f};
7635 static const float no_normalize[4] = {1.0f, 1.0f, 1.0f, 1.0f};
7637 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
7638 0, 0, 640, 480, NULL, NULL, NULL, NULL);
7639 d3d = Direct3DCreate8(D3D_SDK_VERSION);
7640 ok(!!d3d, "Failed to create a D3D object.\n");
7641 if (!(device = create_device(d3d, window, window, TRUE)))
7643 skip("Failed to create a D3D device, skipping tests.\n");
7644 goto done;
7647 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
7648 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
7649 if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1))
7651 skip("No vs_1_1 support, skipping tests.\n");
7652 IDirect3DDevice8_Release(device);
7653 goto done;
7656 hr = IDirect3DDevice8_CreateVertexShader(device, decl_twotexcrd, swapped_shader_code, &swapped_twotexcrd_shader, 0);
7657 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
7658 hr = IDirect3DDevice8_CreateVertexShader(device, decl_onetexcrd, swapped_shader_code, &swapped_onetexcrd_shader, 0);
7659 todo_wine ok(hr == D3DERR_INVALIDCALL, "Unexpected error while creating vertex shader, hr %#x.\n", hr);
7660 hr = IDirect3DDevice8_CreateVertexShader(device, decl_twotexcrd_wrongidx, swapped_shader_code, &swapped_twotex_wrongidx_shader, 0);
7661 todo_wine ok(hr == D3DERR_INVALIDCALL, "Unexpected error while creating vertex shader, hr %#x.\n", hr);
7662 hr = IDirect3DDevice8_CreateVertexShader(device, decl_twotexcrd_rightorder, swapped_shader_code, &swapped_twotexcrd_rightorder_shader, 0);
7663 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
7665 hr = IDirect3DDevice8_CreateVertexShader(device, decl_texcoord_color, texcoord_color_shader_code, &texcoord_color_shader, 0);
7666 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
7667 hr = IDirect3DDevice8_CreateVertexShader(device, decl_color_ubyte, color_color_shader_code, &color_ubyte_shader, 0);
7668 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
7669 hr = IDirect3DDevice8_CreateVertexShader(device, decl_color_color, color_color_shader_code, &color_color_shader, 0);
7670 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
7671 hr = IDirect3DDevice8_CreateVertexShader(device, decl_color_float, color_color_shader_code, &color_float_shader, 0);
7672 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
7673 hr = IDirect3DDevice8_CreateVertexShader(device, decl_nocolor, color_color_shader_code, &color_nocolor_shader, 0);
7674 todo_wine ok(hr == D3DERR_INVALIDCALL, "Unexpected error while creating vertex shader, hr %#x.\n", hr);
7676 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 1.0f, 0);
7677 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
7679 hr = IDirect3DDevice8_BeginScene(device);
7680 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7682 hr = IDirect3DDevice8_SetVertexShader(device, swapped_twotexcrd_shader);
7683 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
7685 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 11);
7686 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7688 hr = IDirect3DDevice8_SetVertexShader(device, swapped_twotexcrd_rightorder_shader);
7689 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
7690 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 11);
7691 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7693 hr = IDirect3DDevice8_EndScene(device);
7694 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7696 color = getPixelColor(device, 160, 360);
7697 ok(color_match(color, 0x00ffff80, 1), "Got unexpected color 0x%08x for quad 1 (2crd).\n", color);
7698 color = getPixelColor(device, 480, 160);
7699 ok(color == 0x00000000, "Got unexpected color 0x%08x for quad 4 (2crd-rightorder).\n", color);
7701 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
7702 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
7704 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
7705 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
7707 hr = IDirect3DDevice8_BeginScene(device);
7708 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7710 hr = IDirect3DDevice8_SetVertexShader(device, texcoord_color_shader);
7711 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
7712 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1_color, sizeof(quad1_color[0]));
7713 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7715 hr = IDirect3DDevice8_SetVertexShader(device, color_ubyte_shader);
7716 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
7718 hr = IDirect3DDevice8_SetVertexShaderConstant(device, 0, normalize, 1);
7719 ok(SUCCEEDED(hr), "Failed to set vertex shader constant, hr %#x.\n", hr);
7720 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_color, sizeof(quad2_color[0]));
7721 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7723 hr = IDirect3DDevice8_SetVertexShaderConstant(device, 0, no_normalize, 1);
7724 ok(SUCCEEDED(hr), "Failed to set vertex shader constant, hr %#x.\n", hr);
7725 hr = IDirect3DDevice8_SetVertexShader(device, color_color_shader);
7726 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
7727 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3_color, sizeof(quad3_color[0]));
7728 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7730 hr = IDirect3DDevice8_SetVertexShader(device, color_float_shader);
7731 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
7732 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4_color, sizeof(float) * 7);
7733 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7735 hr = IDirect3DDevice8_EndScene(device);
7736 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7738 IDirect3DDevice8_SetVertexShader(device, 0);
7740 color = getPixelColor(device, 160, 360);
7741 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
7742 "Input test: Quad 1(color-texcoord) returned color 0x%08x, expected 0x00ff8040\n", color);
7743 color = getPixelColor(device, 480, 360);
7744 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x40, 0x80, 0xff), 1),
7745 "Input test: Quad 2(color-ubyte) returned color 0x%08x, expected 0x004080ff\n", color);
7746 color = getPixelColor(device, 160, 120);
7747 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
7748 "Input test: Quad 3(color-color) returned color 0x%08x, expected 0x00ff8040\n", color);
7749 color = getPixelColor(device, 480, 160);
7750 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 1),
7751 "Input test: Quad 4(color-float) returned color 0x%08x, expected 0x00ffff00\n", color);
7753 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
7754 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
7756 IDirect3DDevice8_DeleteVertexShader(device, swapped_twotexcrd_shader);
7757 IDirect3DDevice8_DeleteVertexShader(device, swapped_onetexcrd_shader);
7758 IDirect3DDevice8_DeleteVertexShader(device, swapped_twotex_wrongidx_shader);
7759 IDirect3DDevice8_DeleteVertexShader(device, swapped_twotexcrd_rightorder_shader);
7760 IDirect3DDevice8_DeleteVertexShader(device, texcoord_color_shader);
7761 IDirect3DDevice8_DeleteVertexShader(device, color_ubyte_shader);
7762 IDirect3DDevice8_DeleteVertexShader(device, color_color_shader);
7763 IDirect3DDevice8_DeleteVertexShader(device, color_float_shader);
7764 IDirect3DDevice8_DeleteVertexShader(device, color_nocolor_shader);
7766 refcount = IDirect3DDevice8_Release(device);
7767 ok(!refcount, "Device has %u references left.\n", refcount);
7768 done:
7769 IDirect3D8_Release(d3d);
7770 DestroyWindow(window);
7773 static void test_fixed_function_fvf(void)
7775 IDirect3DDevice8 *device;
7776 DWORD color;
7777 IDirect3D8 *d3d;
7778 ULONG refcount;
7779 D3DCAPS8 caps;
7780 HWND window;
7781 HRESULT hr;
7783 static const struct
7785 struct vec3 position;
7786 DWORD diffuse;
7788 quad1[] =
7790 {{-1.0f, -1.0f, 0.1f}, 0x00ffff00},
7791 {{-1.0f, 0.0f, 0.1f}, 0x00ffff00},
7792 {{ 0.0f, -1.0f, 0.1f}, 0x00ffff00},
7793 {{ 0.0f, 0.0f, 0.1f}, 0x00ffff00},
7795 static const struct vec3 quad2[] =
7797 {-1.0f, -1.0f, 0.1f},
7798 {-1.0f, 0.0f, 0.1f},
7799 { 0.0f, -1.0f, 0.1f},
7800 { 0.0f, 0.0f, 0.1f},
7802 static const struct
7804 struct vec4 position;
7805 DWORD diffuse;
7807 quad_transformed[] =
7809 {{ 90.0f, 110.0f, 0.1f, 2.0f}, 0x00ffff00},
7810 {{570.0f, 110.0f, 0.1f, 2.0f}, 0x00ffff00},
7811 {{ 90.0f, 300.0f, 0.1f, 2.0f}, 0x00ffff00},
7812 {{570.0f, 300.0f, 0.1f, 2.0f}, 0x00ffff00},
7815 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
7816 0, 0, 640, 480, NULL, NULL, NULL, NULL);
7817 d3d = Direct3DCreate8(D3D_SDK_VERSION);
7818 ok(!!d3d, "Failed to create a D3D object.\n");
7819 if (!(device = create_device(d3d, window, window, TRUE)))
7821 skip("Failed to create a D3D device, skipping tests.\n");
7822 goto done;
7825 memset(&caps, 0, sizeof(caps));
7826 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
7827 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
7829 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
7830 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
7832 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
7833 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
7835 hr = IDirect3DDevice8_BeginScene(device);
7836 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7838 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
7839 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
7840 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
7841 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7843 hr = IDirect3DDevice8_EndScene(device);
7844 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7846 color = getPixelColor(device, 160, 360);
7847 ok(color == 0x00ffff00,
7848 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7849 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
7851 /* Test with no diffuse color attribute. */
7852 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7853 ok(SUCCEEDED(hr), "IDirect3DDevice8_Clear failed with %08x\n", hr);
7855 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ);
7856 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
7857 hr = IDirect3DDevice8_BeginScene(device);
7858 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7859 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad2, sizeof(quad2[0]));
7860 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7861 hr = IDirect3DDevice8_EndScene(device);
7862 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7864 color = getPixelColor(device, 160, 360);
7865 ok(color == 0x00ffffff, "Got unexpected color 0x%08x in the no diffuse attribute test.\n", color);
7866 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
7868 /* Test what happens with specular lighting enabled and no specular color attribute. */
7869 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
7870 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
7871 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SPECULARENABLE, TRUE);
7872 ok(SUCCEEDED(hr), "Failed to enable specular lighting, hr %#x.\n", hr);
7873 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
7874 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
7875 hr = IDirect3DDevice8_BeginScene(device);
7876 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7878 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad1, sizeof(quad1[0]));
7879 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7881 hr = IDirect3DDevice8_EndScene(device);
7882 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7883 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SPECULARENABLE, FALSE);
7884 ok(SUCCEEDED(hr), "Failed to disable specular lighting, hr %#x.\n", hr);
7886 color = getPixelColor(device, 160, 360);
7887 ok(color == 0x00ffff00, "Got unexpected color 0x%08x in the no specular attribute test.\n", color);
7889 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
7891 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
7892 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
7894 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7895 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
7897 hr = IDirect3DDevice8_BeginScene(device);
7898 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7899 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad_transformed, sizeof(quad_transformed[0]));
7900 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7901 hr = IDirect3DDevice8_EndScene(device);
7902 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7904 color = getPixelColor(device, 88, 108);
7905 ok(color == 0x000000ff,
7906 "pixel 88/108 has color %08x, expected 0x000000ff\n", color);
7907 color = getPixelColor(device, 92, 108);
7908 ok(color == 0x000000ff,
7909 "pixel 92/108 has color %08x, expected 0x000000ff\n", color);
7910 color = getPixelColor(device, 88, 112);
7911 ok(color == 0x000000ff,
7912 "pixel 88/112 has color %08x, expected 0x000000ff\n", color);
7913 color = getPixelColor(device, 92, 112);
7914 ok(color == 0x00ffff00,
7915 "pixel 92/112 has color %08x, expected 0x00ffff00\n", color);
7917 color = getPixelColor(device, 568, 108);
7918 ok(color == 0x000000ff,
7919 "pixel 568/108 has color %08x, expected 0x000000ff\n", color);
7920 color = getPixelColor(device, 572, 108);
7921 ok(color == 0x000000ff,
7922 "pixel 572/108 has color %08x, expected 0x000000ff\n", color);
7923 color = getPixelColor(device, 568, 112);
7924 ok(color == 0x00ffff00,
7925 "pixel 568/112 has color %08x, expected 0x00ffff00\n", color);
7926 color = getPixelColor(device, 572, 112);
7927 ok(color == 0x000000ff,
7928 "pixel 572/112 has color %08x, expected 0x000000ff\n", color);
7930 color = getPixelColor(device, 88, 298);
7931 ok(color == 0x000000ff,
7932 "pixel 88/298 has color %08x, expected 0x000000ff\n", color);
7933 color = getPixelColor(device, 92, 298);
7934 ok(color == 0x00ffff00,
7935 "pixel 92/298 has color %08x, expected 0x00ffff00\n", color);
7936 color = getPixelColor(device, 88, 302);
7937 ok(color == 0x000000ff,
7938 "pixel 88/302 has color %08x, expected 0x000000ff\n", color);
7939 color = getPixelColor(device, 92, 302);
7940 ok(color == 0x000000ff,
7941 "pixel 92/302 has color %08x, expected 0x000000ff\n", color);
7943 color = getPixelColor(device, 568, 298);
7944 ok(color == 0x00ffff00,
7945 "pixel 568/298 has color %08x, expected 0x00ffff00\n", color);
7946 color = getPixelColor(device, 572, 298);
7947 ok(color == 0x000000ff,
7948 "pixel 572/298 has color %08x, expected 0x000000ff\n", color);
7949 color = getPixelColor(device, 568, 302);
7950 ok(color == 0x000000ff,
7951 "pixel 568/302 has color %08x, expected 0x000000ff\n", color);
7952 color = getPixelColor(device, 572, 302);
7953 ok(color == 0x000000ff,
7954 "pixel 572/302 has color %08x, expected 0x000000ff\n", color);
7956 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
7958 refcount = IDirect3DDevice8_Release(device);
7959 ok(!refcount, "Device has %u references left.\n", refcount);
7960 done:
7961 IDirect3D8_Release(d3d);
7962 DestroyWindow(window);
7965 static void test_flip(void)
7967 IDirect3DDevice8 *device;
7968 IDirect3D8 *d3d;
7969 ULONG refcount;
7970 HWND window;
7971 HRESULT hr;
7972 IDirect3DSurface8 *back_buffers[3], *test_surface;
7973 unsigned int i;
7974 D3DCOLOR color;
7975 D3DPRESENT_PARAMETERS present_parameters = {0};
7977 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW,
7978 0, 0, 640, 480, NULL, NULL, NULL, NULL);
7979 d3d = Direct3DCreate8(D3D_SDK_VERSION);
7980 ok(!!d3d, "Failed to create a D3D object.\n");
7982 present_parameters.BackBufferWidth = 640;
7983 present_parameters.BackBufferHeight = 480;
7984 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
7985 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
7986 present_parameters.hDeviceWindow = window;
7987 present_parameters.Windowed = TRUE;
7988 present_parameters.BackBufferCount = 3;
7989 present_parameters.Flags = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER;
7990 hr = IDirect3D8_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
7991 window, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device);
7992 if (!device)
7994 skip("Failed to create a D3D device, skipping tests.\n");
7995 IDirect3D8_Release(d3d);
7996 DestroyWindow(window);
7997 return;
8000 for (i = 0; i < sizeof(back_buffers) / sizeof(*back_buffers); ++i)
8002 hr = IDirect3DDevice8_GetBackBuffer(device, i, D3DBACKBUFFER_TYPE_MONO, &back_buffers[i]);
8003 ok(SUCCEEDED(hr), "Failed to get back buffer, hr %#x.\n", hr);
8005 hr = IDirect3DDevice8_GetRenderTarget(device, &test_surface);
8006 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
8007 ok(test_surface == back_buffers[0], "Expected render target %p, got %p.\n", back_buffers[0], test_surface);
8008 IDirect3DSurface8_Release(test_surface);
8011 hr = IDirect3DDevice8_SetRenderTarget(device, back_buffers[0], NULL);
8012 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
8013 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0f, 0);
8014 ok(SUCCEEDED(hr), "Failed to clear, hr %#x\n", hr);
8016 hr = IDirect3DDevice8_SetRenderTarget(device, back_buffers[1], NULL);
8017 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
8018 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0f, 0);
8019 ok(SUCCEEDED(hr), "Failed to clear, hr %#x\n", hr);
8021 hr = IDirect3DDevice8_SetRenderTarget(device, back_buffers[2], NULL);
8022 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
8023 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0f, 0);
8024 ok(SUCCEEDED(hr), "Failed to clear, hr %#x\n", hr);
8026 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
8027 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
8029 /* Render target is unmodified. */
8030 hr = IDirect3DDevice8_GetRenderTarget(device, &test_surface);
8031 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
8032 ok(test_surface == back_buffers[2], "Expected render target %p, got %p.\n", back_buffers[2], test_surface);
8033 IDirect3DSurface8_Release(test_surface);
8035 /* Backbuffer surface pointers are unmodified */
8036 for (i = 0; i < sizeof(back_buffers) / sizeof(*back_buffers); ++i)
8038 hr = IDirect3DDevice8_GetBackBuffer(device, i, D3DBACKBUFFER_TYPE_MONO, &test_surface);
8039 ok(SUCCEEDED(hr), "Failed to get back buffer, hr %#x.\n", hr);
8040 ok(test_surface == back_buffers[i], "Expected back buffer %u = %p, got %p.\n",
8041 i, back_buffers[i], test_surface);
8042 IDirect3DSurface8_Release(test_surface);
8045 /* Contents were changed. */
8046 color = get_surface_color(back_buffers[0], 1, 1);
8047 todo_wine ok(color == 0xff00ff00, "Got unexpected color 0x%08x.\n", color);
8048 color = get_surface_color(back_buffers[1], 1, 1);
8049 todo_wine ok(color == 0xff0000ff, "Got unexpected color 0x%08x.\n", color);
8051 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff808080, 0.0f, 0);
8052 ok(SUCCEEDED(hr), "Failed to clear, hr %#x\n", hr);
8054 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
8055 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
8057 color = get_surface_color(back_buffers[0], 1, 1);
8058 todo_wine ok(color == 0xff0000ff, "Got unexpected color 0x%08x.\n", color);
8059 color = get_surface_color(back_buffers[1], 1, 1);
8060 todo_wine ok(color == 0xff808080, "Got unexpected color 0x%08x.\n", color);
8062 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
8063 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
8065 color = get_surface_color(back_buffers[0], 1, 1);
8066 todo_wine ok(color == 0xff808080, "Got unexpected color 0x%08x.\n", color);
8068 for (i = 0; i < sizeof(back_buffers) / sizeof(*back_buffers); ++i)
8069 IDirect3DSurface8_Release(back_buffers[i]);
8071 refcount = IDirect3DDevice8_Release(device);
8072 ok(!refcount, "Device has %u references left.\n", refcount);
8073 IDirect3D8_Release(d3d);
8074 DestroyWindow(window);
8077 static void test_uninitialized_varyings(void)
8079 static const D3DMATRIX mat =
8081 1.0f, 0.0f, 0.0f, 0.0f,
8082 0.0f, 1.0f, 0.0f, 0.0f,
8083 0.0f, 0.0f, 1.0f, 0.0f,
8084 0.0f, 0.0f, 0.0f, 1.0f,
8085 }}};
8086 static const struct vec3 quad[] =
8088 {-1.0f, -1.0f, 0.1f},
8089 {-1.0f, 1.0f, 0.1f},
8090 { 1.0f, -1.0f, 0.1f},
8091 { 1.0f, 1.0f, 0.1f},
8093 static const DWORD decl[] =
8095 D3DVSD_STREAM(0),
8096 D3DVSD_REG(0, D3DVSDT_FLOAT3),
8097 D3DVSD_CONST(0, 1), 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, /* def c0, 0.5, 0.5, 0.5, 0.5 */
8098 D3DVSD_END()
8100 static const DWORD vs1_code[] =
8102 0xfffe0101, /* vs_1_1 */
8103 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
8104 0x0000ffff
8106 static const DWORD vs1_partial_code[] =
8108 0xfffe0101, /* vs_1_1 */
8109 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
8110 0x00000001, 0xd0010000, 0xa0e40000, /* mov oD0.x, c0 */
8111 0x00000001, 0xd0010001, 0xa0e40000, /* mov oD1.x, c0 */
8112 0x00000001, 0xe0010000, 0xa0e40000, /* mov oT0.x, c0 */
8113 0x0000ffff
8115 static const DWORD ps1_diffuse_code[] =
8117 0xffff0101, /* ps_1_1 */
8118 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
8119 0x0000ffff
8121 static const DWORD ps1_specular_code[] =
8123 0xffff0101, /* ps_1_1 */
8124 0x00000001, 0x800f0000, 0x90e40001, /* mov r0, v1 */
8125 0x0000ffff
8127 static const DWORD ps1_texcoord_code[] =
8129 0xffff0101, /* ps_1_1 */
8130 0x00000040, 0xb00f0000, /* texcoord t0 */
8131 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
8132 0x0000ffff
8134 static const struct
8136 DWORD vs_version;
8137 const DWORD *vs;
8138 DWORD ps_version;
8139 const DWORD *ps;
8140 D3DCOLOR expected;
8141 BOOL allow_zero_alpha;
8142 BOOL broken_warp;
8144 /* On AMD specular color is generally initialized to 0x00000000 and texcoords to 0xff000000
8145 * while on Nvidia it's the opposite. Just allow both. */
8146 tests[] =
8148 {D3DVS_VERSION(1, 1), vs1_code, 0, NULL, 0xffffffff},
8149 { 0, NULL, D3DPS_VERSION(1, 1), ps1_texcoord_code, 0xff000000, TRUE},
8150 {D3DVS_VERSION(1, 1), vs1_code, D3DPS_VERSION(1, 1), ps1_diffuse_code, 0xffffffff},
8151 {D3DVS_VERSION(1, 1), vs1_code, D3DPS_VERSION(1, 1), ps1_specular_code, 0xff000000, TRUE, TRUE},
8152 {D3DVS_VERSION(1, 1), vs1_code, D3DPS_VERSION(1, 1), ps1_texcoord_code, 0xff000000, TRUE},
8153 {D3DVS_VERSION(1, 1), vs1_partial_code, 0, NULL, 0xff7fffff, FALSE, TRUE},
8154 {D3DVS_VERSION(1, 1), vs1_partial_code, D3DPS_VERSION(1, 1), ps1_diffuse_code, 0xff7fffff, FALSE, TRUE},
8155 {D3DVS_VERSION(1, 1), vs1_partial_code, D3DPS_VERSION(1, 1), ps1_specular_code, 0xff7f0000, TRUE},
8156 {D3DVS_VERSION(1, 1), vs1_partial_code, D3DPS_VERSION(1, 1), ps1_texcoord_code, 0xff7f0000, TRUE},
8158 IDirect3DDevice8 *device;
8159 IDirect3D8 *d3d;
8160 HWND window;
8161 HRESULT hr;
8162 DWORD vs, ps;
8163 unsigned int i;
8164 ULONG refcount;
8165 D3DCAPS8 caps;
8166 IDirect3DSurface8 *backbuffer;
8167 D3DADAPTER_IDENTIFIER8 identifier;
8168 struct surface_readback rb;
8169 D3DCOLOR color;
8170 BOOL warp;
8172 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
8173 0, 0, 640, 480, NULL, NULL, NULL, NULL);
8174 d3d = Direct3DCreate8(D3D_SDK_VERSION);
8175 ok(!!d3d, "Failed to create a D3D object.\n");
8176 if (!(device = create_device(d3d, window, window, TRUE)))
8178 skip("Failed to create a D3D device, skipping tests.\n");
8179 IDirect3D8_Release(d3d);
8180 DestroyWindow(window);
8181 return;
8184 hr = IDirect3D8_GetAdapterIdentifier(d3d, D3DADAPTER_DEFAULT, 0, &identifier);
8185 ok(SUCCEEDED(hr), "Failed to get adapter identifier, hr %#x.\n", hr);
8186 warp = adapter_is_warp(&identifier);
8188 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
8189 ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
8191 hr = IDirect3DDevice8_GetBackBuffer(device, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8192 ok(SUCCEEDED(hr), "Failed to get back buffer, hr %#x.\n", hr);
8194 hr = IDirect3DDevice8_SetTransform(device, D3DTS_WORLD, &mat);
8195 ok(SUCCEEDED(hr), "Failed to set world transform, hr %#x.\n", hr);
8196 hr = IDirect3DDevice8_SetTransform(device, D3DTS_VIEW, &mat);
8197 ok(SUCCEEDED(hr), "Failed to set view transform, hr %#x.\n", hr);
8198 hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, &mat);
8199 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
8200 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, FALSE);
8201 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#x.\n", hr);
8202 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, FALSE);
8203 ok(SUCCEEDED(hr), "Failed to disable Z test, hr %#x.\n", hr);
8204 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
8205 ok(SUCCEEDED(hr), "Failed to disable fog, hr %#x.\n", hr);
8206 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
8207 ok(SUCCEEDED(hr), "Failed to disable stencil test, hr %#x.\n", hr);
8208 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
8209 ok(SUCCEEDED(hr), "Failed to disable culling, hr %#x.\n", hr);
8211 for (i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i)
8213 if (caps.VertexShaderVersion < tests[i].vs_version
8214 || caps.PixelShaderVersion < tests[i].ps_version)
8216 skip("Vertex / pixel shader version not supported, skipping test %u.\n", i);
8217 continue;
8219 if (tests[i].vs)
8221 hr = IDirect3DDevice8_CreateVertexShader(device, decl, tests[i].vs, &vs, 0);
8222 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x (case %u).\n", hr, i);
8223 hr = IDirect3DDevice8_SetVertexShader(device, vs);
8224 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
8226 else
8228 vs = 0;
8229 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ);
8230 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
8232 if (tests[i].ps)
8234 hr = IDirect3DDevice8_CreatePixelShader(device, tests[i].ps, &ps);
8235 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x (case %u).\n", hr, i);
8237 else
8239 ps = 0;
8242 hr = IDirect3DDevice8_SetPixelShader(device, ps);
8243 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
8245 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0f, 0);
8246 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
8248 hr = IDirect3DDevice8_BeginScene(device);
8249 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
8251 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
8252 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8254 hr = IDirect3DDevice8_EndScene(device);
8255 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
8257 get_rt_readback(backbuffer, &rb);
8258 color = get_readback_color(&rb, 320, 240);
8259 ok(color_match(color, tests[i].expected, 1)
8260 || (tests[i].allow_zero_alpha && color_match(color, tests[i].expected & 0x00ffffff, 1))
8261 || (broken(warp && tests[i].broken_warp)),
8262 "Got unexpected color 0x%08x, case %u.\n", color, i);
8263 release_surface_readback(&rb);
8265 if (vs)
8266 IDirect3DDevice8_DeleteVertexShader(device, vs);
8267 if (ps)
8268 IDirect3DDevice8_DeletePixelShader(device, ps);
8271 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
8272 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
8274 IDirect3DSurface8_Release(backbuffer);
8275 refcount = IDirect3DDevice8_Release(device);
8276 ok(!refcount, "Device has %u references left.\n", refcount);
8277 IDirect3D8_Release(d3d);
8278 DestroyWindow(window);
8281 static void test_shademode(void)
8283 IDirect3DVertexBuffer8 *vb_strip;
8284 IDirect3DVertexBuffer8 *vb_list;
8285 IDirect3DDevice8 *device;
8286 DWORD color0, color1;
8287 BYTE *data = NULL;
8288 IDirect3D8 *d3d;
8289 ULONG refcount;
8290 D3DCAPS8 caps;
8291 DWORD vs, ps;
8292 HWND window;
8293 HRESULT hr;
8294 UINT i;
8295 static const DWORD decl[] =
8297 D3DVSD_STREAM(0),
8298 D3DVSD_REG(D3DVSDE_POSITION, D3DVSDT_FLOAT3),
8299 D3DVSD_REG(D3DVSDE_DIFFUSE, D3DVSDT_D3DCOLOR),
8300 D3DVSD_END()
8302 static const DWORD vs1_code[] =
8304 0xfffe0101, /* vs_1_1 */
8305 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
8306 0x00000001, 0xd00f0000, 0x90e40005, /* mov oD0, v5 */
8307 0x0000ffff
8309 static const DWORD ps1_code[] =
8311 0xffff0101, /* ps_1_1 */
8312 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
8313 0x0000ffff
8315 static const struct
8317 struct vec3 position;
8318 DWORD diffuse;
8320 quad_strip[] =
8322 {{-1.0f, -1.0f, 0.0f}, 0xffff0000},
8323 {{-1.0f, 1.0f, 0.0f}, 0xff00ff00},
8324 {{ 1.0f, -1.0f, 0.0f}, 0xff0000ff},
8325 {{ 1.0f, 1.0f, 0.0f}, 0xffffffff},
8327 quad_list[] =
8329 {{-1.0f, -1.0f, 0.0f}, 0xffff0000},
8330 {{-1.0f, 1.0f, 0.0f}, 0xff00ff00},
8331 {{ 1.0f, -1.0f, 0.0f}, 0xff0000ff},
8333 {{ 1.0f, -1.0f, 0.0f}, 0xff0000ff},
8334 {{-1.0f, 1.0f, 0.0f}, 0xff00ff00},
8335 {{ 1.0f, 1.0f, 0.0f}, 0xffffffff},
8337 static const struct test_shader
8339 DWORD version;
8340 const DWORD *code;
8342 novs = {0, NULL},
8343 vs_1 = {D3DVS_VERSION(1, 1), vs1_code},
8344 nops = {0, NULL},
8345 ps_1 = {D3DPS_VERSION(1, 1), ps1_code};
8346 static const struct
8348 const struct test_shader *vs, *ps;
8349 DWORD primtype;
8350 DWORD shademode;
8351 DWORD color0, color1;
8353 tests[] =
8355 {&novs, &nops, D3DPT_TRIANGLESTRIP, D3DSHADE_FLAT, 0x00ff0000, 0x0000ff00},
8356 {&novs, &nops, D3DPT_TRIANGLESTRIP, D3DSHADE_PHONG, 0x000dca28, 0x000d45c7},
8357 {&novs, &nops, D3DPT_TRIANGLESTRIP, D3DSHADE_GOURAUD, 0x000dca28, 0x000d45c7},
8358 {&novs, &nops, D3DPT_TRIANGLESTRIP, D3DSHADE_PHONG, 0x000dca28, 0x000d45c7},
8359 {&novs, &nops, D3DPT_TRIANGLELIST, D3DSHADE_FLAT, 0x00ff0000, 0x000000ff},
8360 {&novs, &nops, D3DPT_TRIANGLELIST, D3DSHADE_GOURAUD, 0x000dca28, 0x000d45c7},
8361 {&vs_1, &ps_1, D3DPT_TRIANGLESTRIP, D3DSHADE_FLAT, 0x00ff0000, 0x0000ff00},
8362 {&vs_1, &ps_1, D3DPT_TRIANGLESTRIP, D3DSHADE_GOURAUD, 0x000dca28, 0x000d45c7},
8363 {&vs_1, &ps_1, D3DPT_TRIANGLELIST, D3DSHADE_FLAT, 0x00ff0000, 0x000000ff},
8364 {&vs_1, &ps_1, D3DPT_TRIANGLELIST, D3DSHADE_GOURAUD, 0x000dca28, 0x000d45c7},
8365 {&novs, &ps_1, D3DPT_TRIANGLESTRIP, D3DSHADE_FLAT, 0x00ff0000, 0x0000ff00},
8366 {&vs_1, &nops, D3DPT_TRIANGLESTRIP, D3DSHADE_FLAT, 0x00ff0000, 0x0000ff00},
8369 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
8370 0, 0, 640, 480, NULL, NULL, NULL, NULL);
8371 d3d = Direct3DCreate8(D3D_SDK_VERSION);
8372 ok(!!d3d, "Failed to create a D3D object.\n");
8373 if (!(device = create_device(d3d, window, window, TRUE)))
8375 skip("Failed to create a D3D device, skipping tests.\n");
8376 IDirect3D8_Release(d3d);
8377 DestroyWindow(window);
8378 return;
8381 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
8382 ok(hr == D3D_OK, "Failed to disable lighting, hr %#x.\n", hr);
8383 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
8384 ok(SUCCEEDED(hr), "Failed to disable fog, hr %#x.\n", hr);
8386 hr = IDirect3DDevice8_CreateVertexBuffer(device, sizeof(quad_strip), 0, 0, D3DPOOL_MANAGED, &vb_strip);
8387 ok(hr == D3D_OK, "Failed to create vertex buffer, hr %#x.\n", hr);
8388 hr = IDirect3DVertexBuffer8_Lock(vb_strip, 0, sizeof(quad_strip), &data, 0);
8389 ok(hr == D3D_OK, "Failed to lock vertex buffer, hr %#x.\n", hr);
8390 memcpy(data, quad_strip, sizeof(quad_strip));
8391 hr = IDirect3DVertexBuffer8_Unlock(vb_strip);
8392 ok(hr == D3D_OK, "Failed to unlock vertex buffer, hr %#x.\n", hr);
8394 hr = IDirect3DDevice8_CreateVertexBuffer(device, sizeof(quad_list), 0, 0, D3DPOOL_MANAGED, &vb_list);
8395 ok(hr == D3D_OK, "Failed to create vertex buffer, hr %#x.\n", hr);
8396 hr = IDirect3DVertexBuffer8_Lock(vb_list, 0, sizeof(quad_list), &data, 0);
8397 ok(hr == D3D_OK, "Failed to lock vertex buffer, hr %#x.\n", hr);
8398 memcpy(data, quad_list, sizeof(quad_list));
8399 hr = IDirect3DVertexBuffer8_Unlock(vb_list);
8400 ok(hr == D3D_OK, "Failed to unlock vertex buffer, hr %#x.\n", hr);
8402 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
8403 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
8405 /* Try it first with a TRIANGLESTRIP. Do it with different geometry because
8406 * the color fixups we have to do for FLAT shading will be dependent on that. */
8408 for (i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i)
8410 if (tests[i].vs->version)
8412 if (caps.VertexShaderVersion >= tests[i].vs->version)
8414 hr = IDirect3DDevice8_CreateVertexShader(device, decl, tests[i].vs->code, &vs, 0);
8415 ok(hr == D3D_OK, "Failed to create vertex shader, hr %#x.\n", hr);
8416 hr = IDirect3DDevice8_SetVertexShader(device, vs);
8417 ok(hr == D3D_OK, "Failed to set vertex shader, hr %#x.\n", hr);
8419 else
8421 skip("Shader version unsupported, skipping some tests.\n");
8422 continue;
8425 else
8427 vs = 0;
8428 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8429 ok(hr == D3D_OK, "Failed to set FVF, hr %#x.\n", hr);
8431 if (tests[i].ps->version)
8433 if (caps.PixelShaderVersion >= tests[i].ps->version)
8435 hr = IDirect3DDevice8_CreatePixelShader(device, tests[i].ps->code, &ps);
8436 ok(hr == D3D_OK, "Failed to create pixel shader, hr %#x.\n", hr);
8437 hr = IDirect3DDevice8_SetPixelShader(device, ps);
8438 ok(hr == D3D_OK, "Failed to set pixel shader, hr %#x.\n", hr);
8440 else
8442 skip("Shader version unsupported, skipping some tests.\n");
8443 if (vs)
8445 IDirect3DDevice8_SetVertexShader(device, 0);
8446 IDirect3DDevice8_DeleteVertexShader(device, vs);
8448 continue;
8451 else
8453 ps = 0;
8456 hr = IDirect3DDevice8_SetStreamSource(device, 0,
8457 tests[i].primtype == D3DPT_TRIANGLESTRIP ? vb_strip : vb_list, sizeof(quad_strip[0]));
8458 ok(hr == D3D_OK, "Failed to set stream source, hr %#x.\n", hr);
8460 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
8461 ok(hr == D3D_OK, "Failed to clear, hr %#x.\n", hr);
8463 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SHADEMODE, tests[i].shademode);
8464 ok(hr == D3D_OK, "Failed to set shade mode, hr %#x.\n", hr);
8466 hr = IDirect3DDevice8_BeginScene(device);
8467 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
8468 hr = IDirect3DDevice8_DrawPrimitive(device, tests[i].primtype, 0, 2);
8469 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8470 hr = IDirect3DDevice8_EndScene(device);
8471 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
8473 color0 = getPixelColor(device, 100, 100); /* Inside first triangle */
8474 color1 = getPixelColor(device, 500, 350); /* Inside second triangle */
8476 /* For D3DSHADE_FLAT it should take the color of the first vertex of
8477 * each triangle. This requires EXT_provoking_vertex or similar
8478 * functionality being available. */
8479 /* PHONG should be the same as GOURAUD, since no hardware implements
8480 * this. */
8481 ok(color0 == tests[i].color0, "Test %u shading has color0 %08x, expected %08x.\n",
8482 i, color0, tests[i].color0);
8483 ok(color1 == tests[i].color1, "Test %u shading has color1 %08x, expected %08x.\n",
8484 i, color1, tests[i].color1);
8486 IDirect3DDevice8_SetVertexShader(device, 0);
8487 IDirect3DDevice8_SetPixelShader(device, 0);
8489 if (ps)
8490 IDirect3DDevice8_DeletePixelShader(device, ps);
8491 if (vs)
8492 IDirect3DDevice8_DeleteVertexShader(device, vs);
8495 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
8496 ok(hr == D3D_OK, "Failed to present, hr %#x.\n", hr);
8498 IDirect3DVertexBuffer8_Release(vb_strip);
8499 IDirect3DVertexBuffer8_Release(vb_list);
8500 refcount = IDirect3DDevice8_Release(device);
8501 ok(!refcount, "Device has %u references left.\n", refcount);
8502 IDirect3D8_Release(d3d);
8503 DestroyWindow(window);
8506 static void test_multisample_init(void)
8508 IDirect3DDevice8 *device;
8509 IDirect3D8 *d3d;
8510 IDirect3DSurface8 *back, *multi;
8511 ULONG refcount;
8512 HWND window;
8513 HRESULT hr;
8514 D3DCOLOR color;
8515 unsigned int x, y;
8516 struct surface_readback rb;
8517 BOOL all_zero = TRUE;
8519 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
8520 0, 0, 640, 480, NULL, NULL, NULL, NULL);
8521 d3d = Direct3DCreate8(D3D_SDK_VERSION);
8522 ok(!!d3d, "Failed to create a D3D object.\n");
8524 if (FAILED(IDirect3D8_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
8525 D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES)))
8527 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping multisample init test.\n");
8528 goto done;
8531 if (!(device = create_device(d3d, window, window, TRUE)))
8533 skip("Failed to create a D3D device, skipping tests.\n");
8534 goto done;
8537 hr = IDirect3DDevice8_GetBackBuffer(device, 0, D3DBACKBUFFER_TYPE_MONO, &back);
8538 ok(SUCCEEDED(hr), "Failed to get back buffer, hr %#x.\n", hr);
8539 hr = IDirect3DDevice8_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
8540 D3DMULTISAMPLE_2_SAMPLES, FALSE, &multi);
8541 ok(SUCCEEDED(hr), "Failed to create multisampled render target, hr %#x.\n", hr);
8543 hr = IDirect3DDevice8_CopyRects(device, multi, NULL, 0, back, NULL);
8544 ok(SUCCEEDED(hr), "CopyRects failed, hr %#x.\n", hr);
8546 get_rt_readback(back, &rb);
8547 for (y = 0; y < 480; ++y)
8549 for (x = 0; x < 640; ++x)
8551 color = get_readback_color(&rb, x, y);
8552 if (!color_match(color, 0x00000000, 0))
8554 all_zero = FALSE;
8555 break;
8558 if (!all_zero)
8559 break;
8561 release_surface_readback(&rb);
8562 ok(all_zero, "Got unexpected color 0x%08x, position %ux%u.\n", color, x, y);
8564 IDirect3DSurface8_Release(multi);
8565 IDirect3DSurface8_Release(back);
8567 refcount = IDirect3DDevice8_Release(device);
8568 ok(!refcount, "Device has %u references left.\n", refcount);
8570 done:
8571 IDirect3D8_Release(d3d);
8572 DestroyWindow(window);
8575 static void test_texture_blending(void)
8577 #define STATE_END() {0xffffffff, 0xffffffff}
8578 #define IS_STATE_END(s) (s.name == 0xffffffff && s.value == 0xffffffff)
8580 IDirect3DTexture8 *texture_bumpmap, *texture_red;
8581 IDirect3DSurface8 *backbuffer;
8582 struct surface_readback rb;
8583 D3DLOCKED_RECT locked_rect;
8584 IDirect3DDevice8 *device;
8585 unsigned int i, j, k;
8586 IDirect3D8 *d3d;
8587 D3DCOLOR color;
8588 ULONG refcount;
8589 D3DCAPS8 caps;
8590 HWND window;
8591 HRESULT hr;
8593 static const struct
8595 struct vec3 position;
8596 DWORD diffuse;
8598 quad[] =
8600 {{-1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0x80, 0xff, 0xff, 0x02)},
8601 {{-1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0x80, 0xff, 0xff, 0x02)},
8602 {{ 1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0x80, 0xff, 0xff, 0x02)},
8603 {{ 1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0x80, 0xff, 0xff, 0x02)},
8606 static const float bumpenvmat[4] = {1.0f, 1.0f, 0.0f, 0.0f};
8608 struct texture_stage_state
8610 D3DTEXTURESTAGESTATETYPE name;
8611 DWORD value;
8614 struct texture_stage
8616 enum
8618 TEXTURE_INVALID,
8619 TEXTURE_NONE,
8620 TEXTURE_BUMPMAP,
8621 TEXTURE_RED,
8623 texture;
8624 struct texture_stage_state state[20];
8627 static const struct texture_stage default_stage_state =
8629 TEXTURE_NONE,
8631 {D3DTSS_COLOROP, D3DTOP_DISABLE},
8632 {D3DTSS_COLORARG1, D3DTA_TEXTURE},
8633 {D3DTSS_COLORARG2, D3DTA_CURRENT},
8634 {D3DTSS_ALPHAOP, D3DTOP_DISABLE},
8635 {D3DTSS_ALPHAARG1, D3DTA_TEXTURE},
8636 {D3DTSS_ALPHAARG2, D3DTA_CURRENT},
8637 {D3DTSS_BUMPENVMAT00, 0},
8638 {D3DTSS_BUMPENVMAT01, 0},
8639 {D3DTSS_BUMPENVMAT10, 0},
8640 {D3DTSS_BUMPENVMAT11, 0},
8641 {D3DTSS_BUMPENVLSCALE, 0},
8642 {D3DTSS_BUMPENVLOFFSET, 0},
8643 {D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE},
8644 {D3DTSS_COLORARG0, D3DTA_CURRENT},
8645 {D3DTSS_ALPHAARG0, D3DTA_CURRENT},
8646 {D3DTSS_RESULTARG, D3DTA_CURRENT},
8647 STATE_END(),
8651 const struct test
8653 BOOL todo;
8654 DWORD tex_op_caps;
8655 D3DCOLOR expected_color;
8656 struct texture_stage stage[8];
8658 tests[] =
8661 FALSE,
8662 D3DTEXOPCAPS_DISABLE,
8663 0x80ffff02,
8666 TEXTURE_NONE,
8668 STATE_END(),
8674 FALSE,
8675 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1,
8676 0x80ffff02,
8679 TEXTURE_NONE,
8681 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
8682 {D3DTSS_COLORARG1, D3DTA_CURRENT},
8683 STATE_END(),
8686 {TEXTURE_INVALID}
8690 FALSE,
8691 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1,
8692 0x80ffff02,
8695 TEXTURE_NONE,
8697 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
8698 {D3DTSS_COLORARG1, D3DTA_CURRENT},
8699 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
8700 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
8701 STATE_END(),
8707 FALSE,
8708 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1,
8709 0x80ffff02,
8712 TEXTURE_NONE,
8714 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
8715 {D3DTSS_COLORARG1, D3DTA_DIFFUSE},
8716 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
8717 {D3DTSS_ALPHAARG1, D3DTA_DIFFUSE},
8718 STATE_END(),
8724 FALSE,
8725 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1,
8726 0x00000000,
8729 TEXTURE_NONE,
8731 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
8732 {D3DTSS_COLORARG1, D3DTA_TEMP},
8733 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
8734 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
8735 STATE_END(),
8742 TRUE,
8743 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE,
8744 0x80ff0000,
8747 TEXTURE_BUMPMAP,
8749 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
8750 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
8751 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
8752 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
8753 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
8754 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
8755 {D3DTSS_ALPHAARG1, D3DTA_TEXTURE},
8756 STATE_END(),
8761 TEXTURE_RED,
8763 {D3DTSS_COLOROP, D3DTOP_MODULATE},
8764 STATE_END(),
8767 {TEXTURE_INVALID}
8771 FALSE,
8772 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE,
8773 0x80ff0000,
8776 TEXTURE_BUMPMAP,
8778 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
8779 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
8780 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
8781 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
8782 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
8783 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
8784 {D3DTSS_ALPHAARG1, D3DTA_DIFFUSE},
8785 STATE_END(),
8789 TEXTURE_RED,
8791 {D3DTSS_COLOROP, D3DTOP_MODULATE},
8792 STATE_END(),
8795 {TEXTURE_INVALID}
8799 TRUE,
8800 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE,
8801 0x80ff0000,
8804 TEXTURE_BUMPMAP,
8806 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
8807 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
8808 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
8809 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
8810 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
8811 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
8812 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
8813 STATE_END(),
8817 TEXTURE_RED,
8819 {D3DTSS_COLOROP, D3DTOP_MODULATE},
8820 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
8821 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
8822 STATE_END(),
8825 {TEXTURE_INVALID}
8829 FALSE,
8830 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE,
8831 0x00ff0000,
8834 TEXTURE_BUMPMAP,
8836 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
8837 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
8838 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
8839 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
8840 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
8841 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
8842 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
8843 STATE_END(),
8847 TEXTURE_RED,
8849 {D3DTSS_COLOROP, D3DTOP_MODULATE},
8850 {D3DTSS_COLORARG1, D3DTA_TEXTURE},
8851 {D3DTSS_COLORARG2, D3DTA_CURRENT},
8852 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
8853 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
8854 STATE_END(),
8857 {TEXTURE_INVALID}
8861 FALSE,
8862 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE,
8863 0x80ff0000,
8866 TEXTURE_BUMPMAP,
8868 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
8869 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
8870 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
8871 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
8872 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
8873 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
8874 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
8875 STATE_END(),
8879 TEXTURE_RED,
8881 {D3DTSS_COLOROP, D3DTOP_MODULATE},
8882 {D3DTSS_COLORARG1, D3DTA_TEXTURE},
8883 {D3DTSS_COLORARG2, D3DTA_CURRENT},
8884 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
8885 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
8886 STATE_END(),
8889 {TEXTURE_INVALID}
8894 TRUE,
8895 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE
8896 | D3DTEXOPCAPS_ADD,
8897 0x80ff0000,
8900 TEXTURE_BUMPMAP,
8902 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
8903 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
8904 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
8905 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
8906 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
8907 {D3DTSS_ALPHAOP, D3DTOP_ADD},
8908 {D3DTSS_ALPHAARG1, D3DTA_DIFFUSE},
8909 {D3DTSS_ALPHAARG2, D3DTA_CURRENT},
8910 STATE_END(),
8914 TEXTURE_RED,
8916 {D3DTSS_COLOROP, D3DTOP_MODULATE},
8917 {D3DTSS_COLORARG1, D3DTA_TEXTURE},
8918 {D3DTSS_COLORARG2, D3DTA_CURRENT},
8919 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
8920 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
8921 STATE_END(),
8924 {TEXTURE_INVALID}
8928 FALSE,
8929 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE
8930 | D3DTEXOPCAPS_MODULATE2X,
8931 0x80ffff00,
8934 TEXTURE_BUMPMAP,
8936 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
8937 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
8938 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
8939 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
8940 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
8941 {D3DTSS_ALPHAOP, D3DTOP_MODULATE2X},
8942 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
8943 {D3DTSS_ALPHAARG2, D3DTA_DIFFUSE},
8944 STATE_END(),
8948 TEXTURE_RED,
8950 {D3DTSS_COLOROP, D3DTOP_MODULATE},
8951 {D3DTSS_COLORARG1, D3DTA_CURRENT},
8952 {D3DTSS_COLORARG2, D3DTA_CURRENT},
8953 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
8954 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
8955 STATE_END(),
8958 {TEXTURE_INVALID}
8962 FALSE,
8963 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP,
8964 0x80ffff02,
8967 TEXTURE_NONE,
8969 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
8970 {D3DTSS_COLORARG1, D3DTA_DIFFUSE},
8971 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
8972 {D3DTSS_ALPHAARG1, D3DTA_DIFFUSE},
8973 {D3DTSS_RESULTARG, D3DTA_TEMP},
8974 STATE_END(),
8978 TEXTURE_BUMPMAP,
8980 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
8981 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
8982 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
8983 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
8984 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
8985 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
8986 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
8987 {D3DTSS_RESULTARG, D3DTA_TEMP},
8988 STATE_END(),
8992 TEXTURE_RED,
8994 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
8995 {D3DTSS_COLORARG1, D3DTA_TEXTURE},
8996 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
8997 {D3DTSS_ALPHAARG1, D3DTA_TEXTURE},
8998 STATE_END(),
9002 TEXTURE_NONE,
9004 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
9005 {D3DTSS_COLORARG1, D3DTA_TEMP},
9006 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
9007 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
9008 STATE_END(),
9011 {TEXTURE_INVALID}
9016 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
9017 0, 0, 640, 480, NULL, NULL, NULL, NULL);
9018 d3d = Direct3DCreate8(D3D_SDK_VERSION);
9019 ok(!!d3d, "Failed to create a D3D object.\n");
9020 if (!(device = create_device(d3d, window, window, TRUE)))
9022 skip("Failed to create a D3D device.\n");
9023 goto done;
9026 memset(&caps, 0, sizeof(caps));
9027 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
9028 ok(hr == D3D_OK, "IDirect3DDevice8_GetDeviceCaps failed hr %#x.\n", hr);
9030 if(!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP))
9032 skip("D3DPMISCCAPS_TSSARGTEMP not supported.\n");
9033 IDirect3DDevice8_Release(device);
9034 goto done;
9037 if (FAILED(IDirect3D8_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
9038 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_V8U8)))
9040 skip("D3DFMT_V8U8 not supported for legacy bump mapping.\n");
9041 IDirect3DDevice8_Release(device);
9042 goto done;
9045 hr = IDirect3DDevice8_GetBackBuffer(device, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9046 ok(hr == D3D_OK, "Can't get back buffer, hr %#x.\n", hr);
9048 hr = IDirect3DDevice8_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture_bumpmap);
9049 ok(hr == D3D_OK, "IDirect3DDevice8_CreateTexture failed, hr %#x.\n", hr);
9050 hr = IDirect3DDevice8_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture_red);
9051 ok(hr == D3D_OK, "IDirect3DDevice8_CreateTexture failed, hr %#x.\n", hr);
9053 memset(&locked_rect, 0, sizeof(locked_rect));
9054 hr = IDirect3DTexture8_LockRect(texture_bumpmap, 0, &locked_rect, NULL, 0);
9055 ok(SUCCEEDED(hr), "LockRect failed, hr %#x.\n", hr);
9056 *((WORD *)locked_rect.pBits) = 0xff00;
9057 hr = IDirect3DTexture8_UnlockRect(texture_bumpmap, 0);
9058 ok(SUCCEEDED(hr), "UnlockRect failed, hr %#x.\n", hr);
9060 memset(&locked_rect, 0, sizeof(locked_rect));
9061 hr = IDirect3DTexture8_LockRect(texture_red, 0, &locked_rect, NULL, 0);
9062 ok(SUCCEEDED(hr), "LockRect failed, hr %#x.\n", hr);
9063 *((DWORD *)locked_rect.pBits) = 0x00ff0000;
9064 hr = IDirect3DTexture8_UnlockRect(texture_red, 0);
9065 ok(SUCCEEDED(hr), "UnlockRect failed, hr %#x.\n", hr);
9067 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
9068 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
9069 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9070 ok(hr == D3D_OK, "Failed to disable lighting, hr %#x.\n", hr);
9072 for (i = 0; i < sizeof(tests) / sizeof(*tests); ++i)
9074 const struct test *current_test = &tests[i];
9076 if ((caps.TextureOpCaps & current_test->tex_op_caps) != current_test->tex_op_caps)
9078 skip("Texture operations %#x not supported.\n", current_test->tex_op_caps);
9079 continue;
9082 for (j = 0; j < caps.MaxTextureBlendStages; ++j)
9084 IDirect3DTexture8 *current_texture = NULL;
9086 for (k = 0; !IS_STATE_END(default_stage_state.state[k]); ++k)
9088 hr = IDirect3DDevice8_SetTextureStageState(device, j,
9089 default_stage_state.state[k].name, default_stage_state.state[k].value);
9090 ok(SUCCEEDED(hr), "Test %u: SetTextureStageState failed, hr %#x.\n", i, hr);
9093 if (current_test->stage[j].texture != TEXTURE_INVALID)
9095 const struct texture_stage_state *current_state = current_test->stage[j].state;
9097 switch (current_test->stage[j].texture)
9099 case TEXTURE_RED:
9100 current_texture = texture_red;
9101 break;
9102 case TEXTURE_BUMPMAP:
9103 current_texture = texture_bumpmap;
9104 break;
9105 default:
9106 current_texture = NULL;
9107 break;
9110 for (k = 0; !IS_STATE_END(current_state[k]); ++k)
9112 hr = IDirect3DDevice8_SetTextureStageState(device, j,
9113 current_state[k].name, current_state[k].value);
9114 ok(SUCCEEDED(hr), "Test %u: SetTextureStageState failed, hr %#x.\n", i, hr);
9118 hr = IDirect3DDevice8_SetTexture(device, j, (IDirect3DBaseTexture8 *)current_texture);
9119 ok(SUCCEEDED(hr), "Test %u: SetTexture failed, hr %#x.\n", i, hr);
9122 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
9123 ok(hr == D3D_OK, "Test %u: IDirect3DDevice8_Clear failed, hr %#x.\n", i, hr);
9125 hr = IDirect3DDevice8_BeginScene(device);
9126 ok(SUCCEEDED(hr), "Test %u: BeginScene failed, hr %#x.\n", i, hr);
9127 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
9128 ok(SUCCEEDED(hr), "Test %u: DrawPrimitiveUP failed, hr %#x.\n", i, hr);
9129 hr = IDirect3DDevice8_EndScene(device);
9130 ok(SUCCEEDED(hr), "Test %u: EndScene failed, hr %#x.\n", i, hr);
9132 get_rt_readback(backbuffer, &rb);
9133 color = get_readback_color(&rb, 320, 240);
9134 if (current_test->todo)
9136 todo_wine ok(color_match(color, current_test->expected_color, 1),
9137 "Test %u: Got color 0x%08x, expected 0x%08x.\n", i, color, current_test->expected_color);
9139 else
9141 ok(color_match(color, current_test->expected_color, 1),
9142 "Test %u: Got color 0x%08x, expected 0x%08x.\n", i, color, current_test->expected_color);
9144 release_surface_readback(&rb);
9145 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
9146 ok(SUCCEEDED(hr), "Test %u: Present failed, hr %#x.\n", i, hr);
9149 IDirect3DTexture8_Release(texture_bumpmap);
9150 IDirect3DTexture8_Release(texture_red);
9151 IDirect3DSurface8_Release(backbuffer);
9152 refcount = IDirect3DDevice8_Release(device);
9153 ok(!refcount, "Device has %u references left.\n", refcount);
9154 done:
9155 IDirect3D8_Release(d3d);
9156 DestroyWindow(window);
9159 START_TEST(visual)
9161 D3DADAPTER_IDENTIFIER8 identifier;
9162 IDirect3D8 *d3d;
9163 HRESULT hr;
9165 if (!(d3d = Direct3DCreate8(D3D_SDK_VERSION)))
9167 skip("Failed to create D3D8 object.\n");
9168 return;
9171 memset(&identifier, 0, sizeof(identifier));
9172 hr = IDirect3D8_GetAdapterIdentifier(d3d, D3DADAPTER_DEFAULT, 0, &identifier);
9173 ok(SUCCEEDED(hr), "Failed to get adapter identifier, hr %#x.\n", hr);
9174 trace("Driver string: \"%s\"\n", identifier.Driver);
9175 trace("Description string: \"%s\"\n", identifier.Description);
9176 /* Only Windows XP's default VGA driver should have an empty description */
9177 ok(identifier.Description[0] || broken(!strcmp(identifier.Driver, "vga.dll")), "Empty driver description.\n");
9178 trace("Driver version %d.%d.%d.%d\n",
9179 HIWORD(U(identifier.DriverVersion).HighPart), LOWORD(U(identifier.DriverVersion).HighPart),
9180 HIWORD(U(identifier.DriverVersion).LowPart), LOWORD(U(identifier.DriverVersion).LowPart));
9182 IDirect3D8_Release(d3d);
9184 test_sanity();
9185 depth_clamp_test();
9186 lighting_test();
9187 test_specular_lighting();
9188 clear_test();
9189 fog_test();
9190 z_range_test();
9191 offscreen_test();
9192 test_blend();
9193 test_scalar_instructions();
9194 fog_with_shader_test();
9195 cnd_test();
9196 p8_texture_test();
9197 texop_test();
9198 depth_buffer_test();
9199 depth_buffer2_test();
9200 intz_test();
9201 shadow_test();
9202 multisample_copy_rects_test();
9203 zenable_test();
9204 resz_test();
9205 fog_special_test();
9206 volume_dxt5_test();
9207 volume_v16u16_test();
9208 add_dirty_rect_test();
9209 test_3dc_formats();
9210 test_fog_interpolation();
9211 test_negative_fixedfunction_fog();
9212 test_table_fog_zw();
9213 test_signed_formats();
9214 test_updatetexture();
9215 test_pointsize();
9216 test_multisample_mismatch();
9217 test_texcoordindex();
9218 test_vshader_input();
9219 test_fixed_function_fvf();
9220 test_flip();
9221 test_uninitialized_varyings();
9222 test_shademode();
9223 test_multisample_init();
9224 test_texture_blending();