d3d8/tests: Port part of the fixed function attributes test to D3D8.
[wine.git] / dlls / d3d8 / tests / visual.c
blobdb9fb79b302d7274abc3c79ab155d26d64e32bee
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 DWORD getPixelColor(IDirect3DDevice8 *device, UINT x, UINT y)
57 DWORD ret;
58 IDirect3DTexture8 *tex = NULL;
59 IDirect3DSurface8 *surf = NULL, *backbuf = NULL;
60 HRESULT hr;
61 D3DLOCKED_RECT lockedRect;
62 RECT rectToLock = {x, y, x+1, y+1};
64 hr = IDirect3DDevice8_CreateTexture(device, 640, 480, 1 /* Levels */, 0, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &tex);
65 if(FAILED(hr) || !tex ) /* This is not a test */
67 trace("Can't create an offscreen plain surface to read the render target data, hr=%#08x\n", hr);
68 return 0xdeadbeef;
70 hr = IDirect3DTexture8_GetSurfaceLevel(tex, 0, &surf);
71 if (FAILED(hr)) /* This is not a test */
73 trace("Can't get surface from texture, hr=%#08x\n", hr);
74 ret = 0xdeadbeee;
75 goto out;
78 hr = IDirect3DDevice8_GetRenderTarget(device, &backbuf);
79 if(FAILED(hr))
81 trace("Can't get the render target, hr=%#08x\n", hr);
82 ret = 0xdeadbeed;
83 goto out;
85 hr = IDirect3DDevice8_CopyRects(device, backbuf, NULL, 0, surf, NULL);
86 if(FAILED(hr))
88 trace("Can't read the render target, hr=%#08x\n", hr);
89 ret = 0xdeadbeec;
90 goto out;
93 hr = IDirect3DSurface8_LockRect(surf, &lockedRect, &rectToLock, D3DLOCK_READONLY);
94 if(FAILED(hr))
96 trace("Can't lock the offscreen surface, hr=%#08x\n", hr);
97 ret = 0xdeadbeeb;
98 goto out;
100 /* Remove the X channel for now. DirectX and OpenGL have different ideas how to treat it apparently, and it isn't
101 * really important for these tests
103 ret = ((DWORD *) lockedRect.pBits)[0] & 0x00ffffff;
104 hr = IDirect3DSurface8_UnlockRect(surf);
105 if(FAILED(hr))
107 trace("Can't unlock the offscreen surface, hr=%#08x\n", hr);
110 out:
111 if(backbuf) IDirect3DSurface8_Release(backbuf);
112 if(surf) IDirect3DSurface8_Release(surf);
113 if(tex) IDirect3DTexture8_Release(tex);
114 return ret;
117 static IDirect3DDevice8 *create_device(IDirect3D8 *d3d, HWND device_window, HWND focus_window, BOOL windowed)
119 D3DPRESENT_PARAMETERS present_parameters = {0};
120 IDirect3DDevice8 *device;
122 present_parameters.Windowed = windowed;
123 present_parameters.hDeviceWindow = device_window;
124 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
125 present_parameters.BackBufferWidth = 640;
126 present_parameters.BackBufferHeight = 480;
127 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
128 present_parameters.EnableAutoDepthStencil = TRUE;
129 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
131 if (SUCCEEDED(IDirect3D8_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, focus_window,
132 D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device)))
133 return device;
135 return NULL;
138 static void test_sanity(void)
140 IDirect3DDevice8 *device;
141 IDirect3D8 *d3d;
142 D3DCOLOR color;
143 ULONG refcount;
144 HWND window;
145 HRESULT hr;
147 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
148 0, 0, 640, 480, NULL, NULL, NULL, NULL);
149 d3d = Direct3DCreate8(D3D_SDK_VERSION);
150 ok(!!d3d, "Failed to create a D3D object.\n");
151 if (!(device = create_device(d3d, window, window, TRUE)))
153 skip("Failed to create a D3D device, skipping tests.\n");
154 goto done;
157 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 1.0f, 0);
158 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
159 color = getPixelColor(device, 1, 1);
160 ok(color == 0x00ff0000, "Got unexpected color 0x%08x.\n", color);
162 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
163 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
165 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ddee, 1.0f, 0);
166 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
167 color = getPixelColor(device, 639, 479);
168 ok(color == 0x0000ddee, "Got unexpected color 0x%08x.\n", color);
170 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
171 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
173 refcount = IDirect3DDevice8_Release(device);
174 ok(!refcount, "Device has %u references left.\n", refcount);
175 done:
176 IDirect3D8_Release(d3d);
177 DestroyWindow(window);
180 static void lighting_test(void)
182 DWORD nfvf = D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_NORMAL;
183 DWORD fvf = D3DFVF_XYZ | D3DFVF_DIFFUSE;
184 IDirect3DDevice8 *device;
185 IDirect3D8 *d3d;
186 D3DCOLOR color;
187 ULONG refcount;
188 HWND window;
189 HRESULT hr;
190 unsigned int i;
192 static const struct
194 struct vec3 position;
195 DWORD diffuse;
197 unlitquad[] =
199 {{-1.0f, -1.0f, 0.1f}, 0xffff0000},
200 {{-1.0f, 0.0f, 0.1f}, 0xffff0000},
201 {{ 0.0f, 0.0f, 0.1f}, 0xffff0000},
202 {{ 0.0f, -1.0f, 0.1f}, 0xffff0000},
204 litquad[] =
206 {{-1.0f, 0.0f, 0.1f}, 0xff00ff00},
207 {{-1.0f, 1.0f, 0.1f}, 0xff00ff00},
208 {{ 0.0f, 1.0f, 0.1f}, 0xff00ff00},
209 {{ 0.0f, 0.0f, 0.1f}, 0xff00ff00},
211 static const struct
213 struct vec3 position;
214 struct vec3 normal;
215 DWORD diffuse;
217 unlitnquad[] =
219 {{0.0f, -1.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xff0000ff},
220 {{0.0f, 0.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xff0000ff},
221 {{1.0f, 0.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xff0000ff},
222 {{1.0f, -1.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xff0000ff},
224 litnquad[] =
226 {{0.0f, 0.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xffffff00},
227 {{0.0f, 1.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xffffff00},
228 {{1.0f, 1.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xffffff00},
229 {{1.0f, 0.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xffffff00},
231 nquad[] =
233 {{-1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
234 {{-1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
235 {{ 1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
236 {{ 1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
238 rotatedquad[] =
240 {{-10.0f, -11.0f, 11.0f}, {-1.0f, 0.0f, 0.0f}, 0xff0000ff},
241 {{-10.0f, -9.0f, 11.0f}, {-1.0f, 0.0f, 0.0f}, 0xff0000ff},
242 {{-10.0f, -9.0f, 9.0f}, {-1.0f, 0.0f, 0.0f}, 0xff0000ff},
243 {{-10.0f, -11.0f, 9.0f}, {-1.0f, 0.0f, 0.0f}, 0xff0000ff},
245 translatedquad[] =
247 {{-11.0f, -11.0f, -10.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
248 {{-11.0f, -9.0f, -10.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
249 {{ -9.0f, -9.0f, -10.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
250 {{ -9.0f, -11.0f, -10.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
252 static const WORD indices[] = {0, 1, 2, 2, 3, 0};
253 static const D3DMATRIX mat =
255 1.0f, 0.0f, 0.0f, 0.0f,
256 0.0f, 1.0f, 0.0f, 0.0f,
257 0.0f, 0.0f, 1.0f, 0.0f,
258 0.0f, 0.0f, 0.0f, 1.0f,
259 }}},
260 mat_singular =
262 1.0f, 0.0f, 1.0f, 0.0f,
263 0.0f, 1.0f, 0.0f, 0.0f,
264 1.0f, 0.0f, 1.0f, 0.0f,
265 0.0f, 0.0f, 0.5f, 1.0f,
266 }}},
267 mat_transf =
269 0.0f, 0.0f, 1.0f, 0.0f,
270 0.0f, 1.0f, 0.0f, 0.0f,
271 -1.0f, 0.0f, 0.0f, 0.0f,
272 10.f, 10.0f, 10.0f, 1.0f,
273 }}},
274 mat_nonaffine =
276 1.0f, 0.0f, 0.0f, 0.0f,
277 0.0f, 1.0f, 0.0f, 0.0f,
278 0.0f, 0.0f, 1.0f, -1.0f,
279 10.f, 10.0f, 10.0f, 0.0f,
280 }}};
281 static const struct
283 const D3DMATRIX *world_matrix;
284 const void *quad;
285 unsigned int size;
286 DWORD expected;
287 const char *message;
289 tests[] =
291 {&mat, nquad, sizeof(nquad[0]), 0x000000ff, "Lit quad with light"},
292 {&mat_singular, nquad, sizeof(nquad[0]), 0x000000ff, "Lit quad with singular world matrix"},
293 {&mat_transf, rotatedquad, sizeof(rotatedquad[0]), 0x000000ff, "Lit quad with transformation matrix"},
294 {&mat_nonaffine, translatedquad, sizeof(translatedquad[0]), 0x00000000, "Lit quad with non-affine matrix"},
297 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
298 0, 0, 640, 480, NULL, NULL, NULL, NULL);
299 d3d = Direct3DCreate8(D3D_SDK_VERSION);
300 ok(!!d3d, "Failed to create a D3D object.\n");
301 if (!(device = create_device(d3d, window, window, TRUE)))
303 skip("Failed to create a D3D device, skipping tests.\n");
304 goto done;
307 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
308 ok(hr == D3D_OK, "IDirect3DDevice8_Clear failed with %#08x\n", hr);
310 hr = IDirect3DDevice8_SetTransform(device, D3DTS_WORLDMATRIX(0), &mat);
311 ok(hr == D3D_OK, "IDirect3DDevice8_SetTransform returned %#08x\n", hr);
312 hr = IDirect3DDevice8_SetTransform(device, D3DTS_VIEW, &mat);
313 ok(hr == D3D_OK, "IDirect3DDevice8_SetTransform returned %#08x\n", hr);
314 hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, &mat);
315 ok(hr == D3D_OK, "IDirect3DDevice8_SetTransform returned %#08x\n", hr);
316 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, FALSE);
317 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %#08x\n", hr);
318 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, FALSE);
319 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %#08x\n", hr);
320 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
321 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %#08x\n", hr);
322 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
323 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %#08x\n", hr);
324 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
325 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed with %#08x\n", hr);
327 hr = IDirect3DDevice8_SetVertexShader(device, fvf);
328 ok(hr == D3D_OK, "IDirect3DDevice8_SetVertexShader returned %#08x\n", hr);
330 hr = IDirect3DDevice8_BeginScene(device);
331 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
333 /* No lights are defined... That means, lit vertices should be entirely black. */
334 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
335 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
336 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
337 2, indices, D3DFMT_INDEX16, unlitquad, sizeof(unlitquad[0]));
338 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
340 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, TRUE);
341 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
342 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
343 2, indices, D3DFMT_INDEX16, litquad, sizeof(litquad[0]));
344 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
346 hr = IDirect3DDevice8_SetVertexShader(device, nfvf);
347 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
349 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
350 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
351 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
352 2, indices, D3DFMT_INDEX16, unlitnquad, sizeof(unlitnquad[0]));
353 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
355 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, TRUE);
356 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
357 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
358 2, indices, D3DFMT_INDEX16, litnquad, sizeof(litnquad[0]));
359 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
361 hr = IDirect3DDevice8_EndScene(device);
362 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
364 color = getPixelColor(device, 160, 360); /* Lower left quad - unlit without normals */
365 ok(color == 0x00ff0000, "Unlit quad without normals has color 0x%08x, expected 0x00ff0000.\n", color);
366 color = getPixelColor(device, 160, 120); /* Upper left quad - lit without normals */
367 ok(color == 0x00000000, "Lit quad without normals has color 0x%08x, expected 0x00000000.\n", color);
368 color = getPixelColor(device, 480, 360); /* Lower right quad - unlit with normals */
369 ok(color == 0x000000ff, "Unlit quad with normals has color 0x%08x, expected 0x000000ff.\n", color);
370 color = getPixelColor(device, 480, 120); /* Upper right quad - lit with normals */
371 ok(color == 0x00000000, "Lit quad with normals has color 0x%08x, expected 0x00000000.\n", color);
373 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
375 hr = IDirect3DDevice8_LightEnable(device, 0, TRUE);
376 ok(SUCCEEDED(hr), "Failed to enable light 0, hr %#x.\n", hr);
378 for (i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i)
380 hr = IDirect3DDevice8_SetTransform(device, D3DTS_WORLD, tests[i].world_matrix);
381 ok(SUCCEEDED(hr), "Failed to set world transform, hr %#x.\n", hr);
383 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
384 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
386 hr = IDirect3DDevice8_BeginScene(device);
387 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
389 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
390 2, indices, D3DFMT_INDEX16, tests[i].quad, tests[i].size);
391 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
393 hr = IDirect3DDevice8_EndScene(device);
394 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
396 color = getPixelColor(device, 320, 240);
397 ok(color == tests[i].expected, "%s has color 0x%08x.\n", tests[i].message, color);
400 refcount = IDirect3DDevice8_Release(device);
401 ok(!refcount, "Device has %u references left.\n", refcount);
402 done:
403 IDirect3D8_Release(d3d);
404 DestroyWindow(window);
407 static void test_specular_lighting(void)
409 static const unsigned int vertices_side = 5;
410 const unsigned int indices_count = (vertices_side - 1) * (vertices_side - 1) * 2 * 3;
411 static const DWORD fvf = D3DFVF_XYZ | D3DFVF_NORMAL;
412 static const D3DMATRIX mat =
414 1.0f, 0.0f, 0.0f, 0.0f,
415 0.0f, 1.0f, 0.0f, 0.0f,
416 0.0f, 0.0f, 1.0f, 0.0f,
417 0.0f, 0.0f, 0.0f, 1.0f,
418 }}};
419 static const D3DLIGHT8 directional =
421 D3DLIGHT_DIRECTIONAL,
422 {0.0f, 0.0f, 0.0f, 0.0f},
423 {1.0f, 1.0f, 1.0f, 0.0f},
424 {0.0f, 0.0f, 0.0f, 0.0f},
425 {0.0f, 0.0f, 0.0f},
426 {0.0f, 0.0f, 1.0f},
428 point =
430 D3DLIGHT_POINT,
431 {0.0f, 0.0f, 0.0f, 0.0f},
432 {1.0f, 1.0f, 1.0f, 0.0f},
433 {0.0f, 0.0f, 0.0f, 0.0f},
434 {0.0f, 0.0f, 0.0f},
435 {0.0f, 0.0f, 0.0f},
436 100.0f,
437 0.0f,
438 0.0f, 0.0f, 1.0f,
440 spot =
442 D3DLIGHT_SPOT,
443 {0.0f, 0.0f, 0.0f, 0.0f},
444 {1.0f, 1.0f, 1.0f, 0.0f},
445 {0.0f, 0.0f, 0.0f, 0.0f},
446 {0.0f, 0.0f, 0.0f},
447 {0.0f, 0.0f, 1.0f},
448 100.0f,
449 1.0f,
450 0.0f, 0.0f, 1.0f,
451 M_PI / 12.0f, M_PI / 3.0f
453 /* The chosen range value makes the test fail when using a manhattan
454 * distance metric vs the correct euclidean distance. */
455 point_range =
457 D3DLIGHT_POINT,
458 {0.0f, 0.0f, 0.0f, 0.0f},
459 {1.0f, 1.0f, 1.0f, 0.0f},
460 {0.0f, 0.0f, 0.0f, 0.0f},
461 {0.0f, 0.0f, 0.0f},
462 {0.0f, 0.0f, 0.0f},
463 1.2f,
464 0.0f,
465 0.0f, 0.0f, 1.0f,
467 static const struct expected_color
469 unsigned int x, y;
470 D3DCOLOR color;
472 expected_directional[] =
474 {160, 120, 0x00ffffff},
475 {320, 120, 0x00ffffff},
476 {480, 120, 0x00ffffff},
477 {160, 240, 0x00ffffff},
478 {320, 240, 0x00ffffff},
479 {480, 240, 0x00ffffff},
480 {160, 360, 0x00ffffff},
481 {320, 360, 0x00ffffff},
482 {480, 360, 0x00ffffff},
484 expected_directional_local[] =
486 {160, 120, 0x003c3c3c},
487 {320, 120, 0x00717171},
488 {480, 120, 0x003c3c3c},
489 {160, 240, 0x00717171},
490 {320, 240, 0x00ffffff},
491 {480, 240, 0x00717171},
492 {160, 360, 0x003c3c3c},
493 {320, 360, 0x00717171},
494 {480, 360, 0x003c3c3c},
496 expected_point[] =
498 {160, 120, 0x00282828},
499 {320, 120, 0x005a5a5a},
500 {480, 120, 0x00282828},
501 {160, 240, 0x005a5a5a},
502 {320, 240, 0x00ffffff},
503 {480, 240, 0x005a5a5a},
504 {160, 360, 0x00282828},
505 {320, 360, 0x005a5a5a},
506 {480, 360, 0x00282828},
508 expected_point_local[] =
510 {160, 120, 0x00000000},
511 {320, 120, 0x00070707},
512 {480, 120, 0x00000000},
513 {160, 240, 0x00070707},
514 {320, 240, 0x00ffffff},
515 {480, 240, 0x00070707},
516 {160, 360, 0x00000000},
517 {320, 360, 0x00070707},
518 {480, 360, 0x00000000},
520 expected_spot[] =
522 {160, 120, 0x00000000},
523 {320, 120, 0x00141414},
524 {480, 120, 0x00000000},
525 {160, 240, 0x00141414},
526 {320, 240, 0x00ffffff},
527 {480, 240, 0x00141414},
528 {160, 360, 0x00000000},
529 {320, 360, 0x00141414},
530 {480, 360, 0x00000000},
532 expected_spot_local[] =
534 {160, 120, 0x00000000},
535 {320, 120, 0x00020202},
536 {480, 120, 0x00000000},
537 {160, 240, 0x00020202},
538 {320, 240, 0x00ffffff},
539 {480, 240, 0x00020202},
540 {160, 360, 0x00000000},
541 {320, 360, 0x00020202},
542 {480, 360, 0x00000000},
544 expected_point_range[] =
546 {160, 120, 0x00000000},
547 {320, 120, 0x005a5a5a},
548 {480, 120, 0x00000000},
549 {160, 240, 0x005a5a5a},
550 {320, 240, 0x00ffffff},
551 {480, 240, 0x005a5a5a},
552 {160, 360, 0x00000000},
553 {320, 360, 0x005a5a5a},
554 {480, 360, 0x00000000},
556 static const struct
558 const D3DLIGHT8 *light;
559 BOOL local_viewer;
560 const struct expected_color *expected;
561 unsigned int expected_count;
563 tests[] =
565 {&directional, FALSE, expected_directional,
566 sizeof(expected_directional) / sizeof(expected_directional[0])},
567 {&directional, TRUE, expected_directional_local,
568 sizeof(expected_directional_local) / sizeof(expected_directional_local[0])},
569 {&point, FALSE, expected_point,
570 sizeof(expected_point) / sizeof(expected_point[0])},
571 {&point, TRUE, expected_point_local,
572 sizeof(expected_point_local) / sizeof(expected_point_local[0])},
573 {&spot, FALSE, expected_spot,
574 sizeof(expected_spot) / sizeof(expected_spot[0])},
575 {&spot, TRUE, expected_spot_local,
576 sizeof(expected_spot_local) / sizeof(expected_spot_local[0])},
577 {&point_range, FALSE, expected_point_range,
578 sizeof(expected_point_range) / sizeof(expected_point_range[0])},
580 IDirect3DDevice8 *device;
581 D3DMATERIAL8 material;
582 IDirect3D8 *d3d;
583 D3DCOLOR color;
584 ULONG refcount;
585 HWND window;
586 HRESULT hr;
587 unsigned int i, j, x, y;
588 struct
590 struct vec3 position;
591 struct vec3 normal;
592 } *quad;
593 WORD *indices;
595 quad = HeapAlloc(GetProcessHeap(), 0, vertices_side * vertices_side * sizeof(*quad));
596 indices = HeapAlloc(GetProcessHeap(), 0, indices_count * sizeof(*indices));
597 for (i = 0, y = 0; y < vertices_side; ++y)
599 for (x = 0; x < vertices_side; ++x)
601 quad[i].position.x = x * 2.0f / (vertices_side - 1) - 1.0f;
602 quad[i].position.y = y * 2.0f / (vertices_side - 1) - 1.0f;
603 quad[i].position.z = 1.0f;
604 quad[i].normal.x = 0.0f;
605 quad[i].normal.y = 0.0f;
606 quad[i++].normal.z = -1.0f;
609 for (i = 0, y = 0; y < (vertices_side - 1); ++y)
611 for (x = 0; x < (vertices_side - 1); ++x)
613 indices[i++] = y * vertices_side + x + 1;
614 indices[i++] = y * vertices_side + x;
615 indices[i++] = (y + 1) * vertices_side + x;
616 indices[i++] = y * vertices_side + x + 1;
617 indices[i++] = (y + 1) * vertices_side + x;
618 indices[i++] = (y + 1) * vertices_side + x + 1;
622 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
623 0, 0, 640, 480, NULL, NULL, NULL, NULL);
624 d3d = Direct3DCreate8(D3D_SDK_VERSION);
625 ok(!!d3d, "Failed to create a D3D object.\n");
626 if (!(device = create_device(d3d, window, window, TRUE)))
628 skip("Failed to create a D3D device, skipping tests.\n");
629 goto done;
632 hr = IDirect3DDevice8_SetTransform(device, D3DTS_WORLD, &mat);
633 ok(SUCCEEDED(hr), "Failed to set world transform, hr %#x.\n", hr);
634 hr = IDirect3DDevice8_SetTransform(device, D3DTS_VIEW, &mat);
635 ok(SUCCEEDED(hr), "Failed to set view transform, hr %#x.\n", hr);
636 hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, &mat);
637 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
638 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, FALSE);
639 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#x.\n", hr);
640 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, FALSE);
641 ok(SUCCEEDED(hr), "Failed to disable z test, hr %#x.\n", hr);
642 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
643 ok(SUCCEEDED(hr), "Failed to disable fog, hr %#x.\n", hr);
645 hr = IDirect3DDevice8_SetVertexShader(device, fvf);
646 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
648 memset(&material, 0, sizeof(material));
649 material.Specular.r = 1.0f;
650 material.Specular.g = 1.0f;
651 material.Specular.b = 1.0f;
652 material.Specular.a = 1.0f;
653 material.Power = 30.0f;
654 hr = IDirect3DDevice8_SetMaterial(device, &material);
655 ok(SUCCEEDED(hr), "Failed to set material, hr %#x.\n", hr);
657 hr = IDirect3DDevice8_LightEnable(device, 0, TRUE);
658 ok(SUCCEEDED(hr), "Failed to enable light 0, hr %#x.\n", hr);
659 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SPECULARENABLE, TRUE);
660 ok(SUCCEEDED(hr), "Failed to enable specular lighting, hr %#x.\n", hr);
662 for (i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i)
664 hr = IDirect3DDevice8_SetLight(device, 0, tests[i].light);
665 ok(SUCCEEDED(hr), "Failed to set light parameters, hr %#x.\n", hr);
667 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LOCALVIEWER, tests[i].local_viewer);
668 ok(SUCCEEDED(hr), "Failed to set local viewer state, hr %#x.\n", hr);
670 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
671 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
673 hr = IDirect3DDevice8_BeginScene(device);
674 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
676 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST,
677 0, vertices_side * vertices_side, indices_count / 3, indices,
678 D3DFMT_INDEX16, quad, sizeof(quad[0]));
679 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
681 hr = IDirect3DDevice8_EndScene(device);
682 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
684 for (j = 0; j < tests[i].expected_count; ++j)
686 color = getPixelColor(device, tests[i].expected[j].x, tests[i].expected[j].y);
687 ok(color_match(color, tests[i].expected[j].color, 1),
688 "Expected color 0x%08x at location (%u, %u), got 0x%08x, case %u.\n",
689 tests[i].expected[j].color, tests[i].expected[j].x,
690 tests[i].expected[j].y, color, i);
694 refcount = IDirect3DDevice8_Release(device);
695 ok(!refcount, "Device has %u references left.\n", refcount);
696 done:
697 IDirect3D8_Release(d3d);
698 DestroyWindow(window);
699 HeapFree(GetProcessHeap(), 0, indices);
700 HeapFree(GetProcessHeap(), 0, quad);
703 static void clear_test(void)
705 /* Tests the correctness of clearing parameters */
706 D3DRECT rect_negneg, rect[2];
707 IDirect3DDevice8 *device;
708 IDirect3D8 *d3d;
709 D3DCOLOR color;
710 ULONG refcount;
711 HWND window;
712 HRESULT hr;
714 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
715 0, 0, 640, 480, NULL, NULL, NULL, NULL);
716 d3d = Direct3DCreate8(D3D_SDK_VERSION);
717 ok(!!d3d, "Failed to create a D3D object.\n");
718 if (!(device = create_device(d3d, window, window, TRUE)))
720 skip("Failed to create a D3D device, skipping tests.\n");
721 goto done;
724 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
725 ok(hr == D3D_OK, "IDirect3DDevice8_Clear failed with %#08x\n", hr);
727 /* Positive x, negative y */
728 rect[0].x1 = 0;
729 rect[0].y1 = 480;
730 rect[0].x2 = 320;
731 rect[0].y2 = 240;
733 /* Positive x, positive y */
734 rect[1].x1 = 0;
735 rect[1].y1 = 0;
736 rect[1].x2 = 320;
737 rect[1].y2 = 240;
738 /* Clear 2 rectangles with one call. Shows that a positive value is returned, but the negative rectangle
739 * is ignored, the positive is still cleared afterwards
741 hr = IDirect3DDevice8_Clear(device, 2, rect, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
742 ok(hr == D3D_OK, "IDirect3DDevice8_Clear failed with %#08x\n", hr);
744 /* negative x, negative y */
745 rect_negneg.x1 = 640;
746 rect_negneg.y1 = 240;
747 rect_negneg.x2 = 320;
748 rect_negneg.y2 = 0;
749 hr = IDirect3DDevice8_Clear(device, 1, &rect_negneg, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
750 ok(hr == D3D_OK, "IDirect3DDevice8_Clear failed with %#08x\n", hr);
752 color = getPixelColor(device, 160, 360); /* lower left quad */
753 ok(color == 0x00ffffff, "Clear rectangle 3(pos, neg) has color %08x\n", color);
754 color = getPixelColor(device, 160, 120); /* upper left quad */
755 ok(color == 0x00ff0000, "Clear rectangle 1(pos, pos) has color %08x\n", color);
756 color = getPixelColor(device, 480, 360); /* lower right quad */
757 ok(color == 0x00ffffff, "Clear rectangle 4(NULL) has color %08x\n", color);
758 color = getPixelColor(device, 480, 120); /* upper right quad */
759 ok(color == 0x00ffffff, "Clear rectangle 4(neg, neg) has color %08x\n", color);
761 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
763 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
764 ok(SUCCEEDED(hr), "IDirect3DDevice8_Clear failed with %#08x\n", hr);
766 rect[0].x1 = 0;
767 rect[0].y1 = 0;
768 rect[0].x2 = 640;
769 rect[0].y2 = 480;
770 hr = IDirect3DDevice8_Clear(device, 0, rect, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
771 ok(SUCCEEDED(hr), "IDirect3DDevice8_Clear failed with %#08x\n", hr);
773 color = getPixelColor(device, 320, 240);
774 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff), 1),
775 "Clear with count = 0, rect != NULL has color %#08x\n", color);
777 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
779 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
780 ok(SUCCEEDED(hr), "IDirect3DDevice8_Clear failed with %#08x\n", hr);
781 hr = IDirect3DDevice8_Clear(device, 1, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
782 ok(SUCCEEDED(hr), "IDirect3DDevice8_Clear failed with %#08x\n", hr);
784 color = getPixelColor(device, 320, 240);
785 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
786 "Clear with count = 1, rect = NULL has color %#08x\n", color);
788 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
790 refcount = IDirect3DDevice8_Release(device);
791 ok(!refcount, "Device has %u references left.\n", refcount);
792 done:
793 IDirect3D8_Release(d3d);
794 DestroyWindow(window);
797 static void fog_test(void)
799 float start = 0.0f, end = 1.0f;
800 IDirect3DDevice8 *device;
801 IDirect3D8 *d3d;
802 D3DCOLOR color;
803 ULONG refcount;
804 D3DCAPS8 caps;
805 HWND window;
806 HRESULT hr;
808 /* Gets full z based fog with linear fog, no fog with specular color. */
809 static const struct
811 float x, y, z;
812 D3DCOLOR diffuse;
813 D3DCOLOR specular;
815 untransformed_1[] =
817 {-1.0f, -1.0f, 0.1f, 0xffff0000, 0xff000000},
818 {-1.0f, 0.0f, 0.1f, 0xffff0000, 0xff000000},
819 { 0.0f, 0.0f, 0.1f, 0xffff0000, 0xff000000},
820 { 0.0f, -1.0f, 0.1f, 0xffff0000, 0xff000000},
822 /* Ok, I am too lazy to deal with transform matrices. */
823 untransformed_2[] =
825 {-1.0f, 0.0f, 1.0f, 0xffff0000, 0xff000000},
826 {-1.0f, 1.0f, 1.0f, 0xffff0000, 0xff000000},
827 { 0.0f, 1.0f, 1.0f, 0xffff0000, 0xff000000},
828 { 0.0f, 0.0f, 1.0f, 0xffff0000, 0xff000000},
830 far_quad1[] =
832 {-1.0f, -1.0f, 0.5f, 0xffff0000, 0xff000000},
833 {-1.0f, 0.0f, 0.5f, 0xffff0000, 0xff000000},
834 { 0.0f, 0.0f, 0.5f, 0xffff0000, 0xff000000},
835 { 0.0f, -1.0f, 0.5f, 0xffff0000, 0xff000000},
837 far_quad2[] =
839 {-1.0f, 0.0f, 1.5f, 0xffff0000, 0xff000000},
840 {-1.0f, 1.0f, 1.5f, 0xffff0000, 0xff000000},
841 { 0.0f, 1.0f, 1.5f, 0xffff0000, 0xff000000},
842 { 0.0f, 0.0f, 1.5f, 0xffff0000, 0xff000000},
845 /* Untransformed ones. Give them a different diffuse color to make the
846 * test look nicer. It also makes making sure that they are drawn
847 * correctly easier. */
848 static const struct
850 float x, y, z, rhw;
851 D3DCOLOR diffuse;
852 D3DCOLOR specular;
854 transformed_1[] =
856 {320.0f, 0.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
857 {640.0f, 0.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
858 {640.0f, 240.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
859 {320.0f, 240.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
861 transformed_2[] =
863 {320.0f, 240.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
864 {640.0f, 240.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
865 {640.0f, 480.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
866 {320.0f, 480.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
868 static const D3DMATRIX ident_mat =
870 1.0f, 0.0f, 0.0f, 0.0f,
871 0.0f, 1.0f, 0.0f, 0.0f,
872 0.0f, 0.0f, 1.0f, 0.0f,
873 0.0f, 0.0f, 0.0f, 1.0f,
874 }}};
875 static const D3DMATRIX world_mat1 =
877 1.0f, 0.0f, 0.0f, 0.0f,
878 0.0f, 1.0f, 0.0f, 0.0f,
879 0.0f, 0.0f, 1.0f, 0.0f,
880 0.0f, 0.0f, -0.5f, 1.0f,
881 }}};
882 static const D3DMATRIX world_mat2 =
884 1.0f, 0.0f, 0.0f, 0.0f,
885 0.0f, 1.0f, 0.0f, 0.0f,
886 0.0f, 0.0f, 1.0f, 0.0f,
887 0.0f, 0.0f, 1.0f, 1.0f,
888 }}};
889 static const D3DMATRIX proj_mat =
891 1.0f, 0.0f, 0.0f, 0.0f,
892 0.0f, 1.0f, 0.0f, 0.0f,
893 0.0f, 0.0f, 1.0f, 0.0f,
894 0.0f, 0.0f, -1.0f, 1.0f,
895 }}};
896 static const WORD Indices[] = {0, 1, 2, 2, 3, 0};
898 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
899 0, 0, 640, 480, NULL, NULL, NULL, NULL);
900 d3d = Direct3DCreate8(D3D_SDK_VERSION);
901 ok(!!d3d, "Failed to create a D3D object.\n");
902 if (!(device = create_device(d3d, window, window, TRUE)))
904 skip("Failed to create a D3D device, skipping tests.\n");
905 goto done;
908 memset(&caps, 0, sizeof(caps));
909 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
910 ok(hr == D3D_OK, "IDirect3DDevice8_GetDeviceCaps returned %08x\n", hr);
911 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
912 ok(hr == D3D_OK, "IDirect3DDevice8_Clear returned %#08x\n", hr);
914 /* Setup initial states: No lighting, fog on, fog color */
915 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, FALSE);
916 ok(SUCCEEDED(hr), "Failed to disable D3DRS_ZENABLE, hr %#x.\n", hr);
917 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
918 ok(hr == D3D_OK, "Turning off lighting returned %#08x\n", hr);
919 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
920 ok(hr == D3D_OK, "Turning on fog calculations returned %#08x\n", hr);
921 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
922 ok(hr == D3D_OK, "Setting fog color returned %#08x\n", hr);
923 /* Some of the tests seem to depend on the projection matrix explicitly
924 * being set to an identity matrix, even though that's the default.
925 * (AMD Radeon HD 6310, Windows 7) */
926 hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, &ident_mat);
927 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
929 /* First test: Both table fog and vertex fog off */
930 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
931 ok(hr == D3D_OK, "Turning off table fog returned %#08x\n", hr);
932 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
933 ok(hr == D3D_OK, "Turning off vertex fog returned %#08x\n", hr);
935 /* Start = 0, end = 1. Should be default, but set them */
936 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
937 ok(hr == D3D_OK, "Setting fog start returned %#08x\n", hr);
938 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
939 ok(hr == D3D_OK, "Setting fog start returned %#08x\n", hr);
941 hr = IDirect3DDevice8_BeginScene(device);
942 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
944 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
945 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
946 /* Untransformed, vertex fog = NONE, table fog = NONE:
947 * Read the fog weighting from the specular color. */
948 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
949 2 /* PrimCount */, Indices, D3DFMT_INDEX16, untransformed_1, sizeof(untransformed_1[0]));
950 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
952 /* This makes it use the Z value. */
953 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
954 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
955 /* Untransformed, vertex fog != none (or table fog != none):
956 * Use the Z value as input into the equation. */
957 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
958 2 /* PrimCount */, Indices, D3DFMT_INDEX16, untransformed_2, sizeof(untransformed_2[0]));
959 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
961 /* Transformed vertices. */
962 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
963 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
964 /* Transformed, vertex fog != NONE, pixel fog == NONE:
965 * Use specular color alpha component. */
966 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
967 2 /* PrimCount */, Indices, D3DFMT_INDEX16, transformed_1, sizeof(transformed_1[0]));
968 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
970 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
971 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
972 /* Transformed, table fog != none, vertex anything:
973 * Use Z value as input to the fog equation. */
974 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
975 2 /* PrimCount */, Indices, D3DFMT_INDEX16, transformed_2, sizeof(transformed_2[0]));
976 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
978 hr = IDirect3DDevice8_EndScene(device);
979 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
981 color = getPixelColor(device, 160, 360);
982 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xFF, 0x00, 0x00), 1),
983 "Untransformed vertex with no table or vertex fog has color %08x\n", color);
984 color = getPixelColor(device, 160, 120);
985 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xFF, 0x00), 1),
986 "Untransformed vertex with linear vertex fog has color %08x\n", color);
987 color = getPixelColor(device, 480, 120);
988 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xFF, 0xFF, 0x00), 1),
989 "Transformed vertex with linear vertex fog has color %08x\n", color);
990 color = getPixelColor(device, 480, 360);
991 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xFF, 0x00), 1),
992 "Transformed vertex with linear table fog has color %08x\n", color);
994 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
996 if (caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)
998 /* A simple fog + non-identity world matrix test */
999 hr = IDirect3DDevice8_SetTransform(device, D3DTS_WORLDMATRIX(0), &world_mat1);
1000 ok(hr == D3D_OK, "IDirect3DDevice8_SetTransform returned %#08x\n", hr);
1002 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
1003 ok(hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %#08x\n", hr);
1004 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
1005 ok(hr == D3D_OK, "Turning off vertex fog returned %#08x\n", hr);
1007 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1008 ok(hr == D3D_OK, "IDirect3DDevice8_Clear returned %#08x\n", hr);
1010 hr = IDirect3DDevice8_BeginScene(device);
1011 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 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
1015 2, Indices, D3DFMT_INDEX16, far_quad1, sizeof(far_quad1[0]));
1016 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1017 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
1018 2, Indices, D3DFMT_INDEX16, far_quad2, sizeof(far_quad2[0]));
1019 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1020 hr = IDirect3DDevice8_EndScene(device);
1021 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
1023 color = getPixelColor(device, 160, 360);
1024 ok(color_match(color, 0x00ff0000, 4), "Unfogged quad has color %08x\n", color);
1025 color = getPixelColor(device, 160, 120);
1026 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
1027 "Fogged out quad has color %08x\n", color);
1029 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
1031 /* Test fog behavior with an orthogonal (but not identity) projection matrix */
1032 hr = IDirect3DDevice8_SetTransform(device, D3DTS_WORLDMATRIX(0), &world_mat2);
1033 ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
1034 hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, &proj_mat);
1035 ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
1037 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1038 ok(hr == D3D_OK, "Clear returned %#08x\n", hr);
1040 hr = IDirect3DDevice8_BeginScene(device);
1041 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
1042 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1043 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
1044 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
1045 2, Indices, D3DFMT_INDEX16, untransformed_1, sizeof(untransformed_1[0]));
1046 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1047 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
1048 2, Indices, D3DFMT_INDEX16, untransformed_2, sizeof(untransformed_2[0]));
1049 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1050 hr = IDirect3DDevice8_EndScene(device);
1051 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
1053 color = getPixelColor(device, 160, 360);
1054 ok(color_match(color, 0x00e51900, 4), "Partially fogged quad has color %08x\n", color);
1055 color = getPixelColor(device, 160, 120);
1056 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
1057 "Fogged out quad has color %08x\n", color);
1059 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
1061 else
1063 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping some fog tests\n");
1066 refcount = IDirect3DDevice8_Release(device);
1067 ok(!refcount, "Device has %u references left.\n", refcount);
1068 done:
1069 IDirect3D8_Release(d3d);
1070 DestroyWindow(window);
1073 /* This tests fog in combination with shaders.
1074 * What's tested: linear fog (vertex and table) with pixel shader
1075 * linear table fog with non foggy vertex shader
1076 * vertex fog with foggy vertex shader, non-linear
1077 * fog with shader, non-linear fog with foggy shader,
1078 * linear table fog with foggy shader */
1079 static void fog_with_shader_test(void)
1081 /* Fill the null-shader entry with the FVF (SetVertexShader is "overloaded" on d3d8...) */
1082 DWORD vertex_shader[3] = {D3DFVF_XYZ | D3DFVF_DIFFUSE, 0, 0};
1083 DWORD pixel_shader[2] = {0, 0};
1084 IDirect3DDevice8 *device;
1085 unsigned int i, j;
1086 IDirect3D8 *d3d;
1087 D3DCOLOR color;
1088 ULONG refcount;
1089 D3DCAPS8 caps;
1090 HWND window;
1091 HRESULT hr;
1092 union
1094 float f;
1095 DWORD i;
1096 } start, end;
1098 /* Basic vertex shader without fog computation ("non foggy") */
1099 static const DWORD vertex_shader_code1[] =
1101 0xfffe0100, /* vs.1.0 */
1102 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1103 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
1104 0x0000ffff
1106 /* Basic vertex shader with reversed fog computation ("foggy") */
1107 static const DWORD vertex_shader_code2[] =
1109 0xfffe0100, /* vs.1.0 */
1110 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1111 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
1112 0x00000002, 0x800f0000, 0x90aa0000, 0xa0aa0000, /* add r0, v0.z, c0.z */
1113 0x00000005, 0xc00f0001, 0x80000000, 0xa0000000, /* mul oFog, r0.x, c0.x */
1114 0x0000ffff
1116 /* Basic pixel shader */
1117 static const DWORD pixel_shader_code[] =
1119 0xffff0101, /* ps_1_1 */
1120 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
1121 0x0000ffff
1123 static struct
1125 struct vec3 position;
1126 DWORD diffuse;
1128 quad[] =
1130 {{-1.0f, -1.0f, 0.0f}, 0xffff0000},
1131 {{-1.0f, 1.0f, 0.0f}, 0xffff0000},
1132 {{ 1.0f, -1.0f, 0.0f}, 0xffff0000},
1133 {{ 1.0f, 1.0f, 0.0f}, 0xffff0000},
1135 static const DWORD decl[] =
1137 D3DVSD_STREAM(0),
1138 D3DVSD_REG(0, D3DVSDT_FLOAT3), /* position, v0 */
1139 D3DVSD_REG(1, D3DVSDT_D3DCOLOR), /* diffuse color, v1 */
1140 D3DVSD_END()
1142 static const float vs_constant[4] = {-1.25f, 0.0f, -0.9f, 0.0f};
1143 /* This reference data was collected on a nVidia GeForce 7600GS
1144 * driver version 84.19 DirectX version 9.0c on Windows XP */
1145 static const struct test_data_t
1147 int vshader;
1148 int pshader;
1149 D3DFOGMODE vfog;
1150 D3DFOGMODE tfog;
1151 BOOL uninitialized_reg;
1152 unsigned int color[11];
1154 test_data[] =
1156 /* Only pixel shader */
1157 {0, 1, D3DFOG_NONE, D3DFOG_LINEAR, FALSE,
1158 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1159 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1160 {0, 1, D3DFOG_EXP, D3DFOG_LINEAR, FALSE,
1161 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1162 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1163 {0, 1, D3DFOG_EXP2, D3DFOG_LINEAR, FALSE,
1164 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1165 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1166 {0, 1, D3DFOG_LINEAR, D3DFOG_NONE, FALSE,
1167 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1168 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1169 {0, 1, D3DFOG_LINEAR, D3DFOG_LINEAR, FALSE,
1170 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1171 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1173 /* Vertex shader */
1174 {1, 0, D3DFOG_NONE, D3DFOG_NONE, TRUE,
1175 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1176 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1177 {1, 0, D3DFOG_NONE, D3DFOG_LINEAR, FALSE,
1178 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1179 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1180 {1, 0, D3DFOG_EXP, D3DFOG_LINEAR, FALSE,
1181 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1182 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1184 {1, 0, D3DFOG_EXP2, D3DFOG_LINEAR, FALSE,
1185 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1186 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1187 {1, 0, D3DFOG_LINEAR, D3DFOG_LINEAR, FALSE,
1188 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1189 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1191 /* Vertex shader and pixel shader */
1192 /* The next 4 tests would read the fog coord output, but it isn't available.
1193 * The result is a fully fogged quad, no matter what the Z coord is. */
1194 {1, 1, D3DFOG_NONE, D3DFOG_NONE, TRUE,
1195 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1196 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1197 {1, 1, D3DFOG_LINEAR, D3DFOG_NONE, TRUE,
1198 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1199 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1200 {1, 1, D3DFOG_EXP, D3DFOG_NONE, TRUE,
1201 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1202 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1203 {1, 1, D3DFOG_EXP2, D3DFOG_NONE, TRUE,
1204 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1205 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1207 /* These use the Z coordinate with linear table fog */
1208 {1, 1, D3DFOG_NONE, D3DFOG_LINEAR, FALSE,
1209 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1210 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1211 {1, 1, D3DFOG_EXP, D3DFOG_LINEAR, FALSE,
1212 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1213 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1214 {1, 1, D3DFOG_EXP2, D3DFOG_LINEAR, FALSE,
1215 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1216 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1217 {1, 1, D3DFOG_LINEAR, D3DFOG_LINEAR, FALSE,
1218 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1219 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1221 /* Non-linear table fog without fog coord */
1222 {1, 1, D3DFOG_NONE, D3DFOG_EXP, FALSE,
1223 {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
1224 0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
1225 {1, 1, D3DFOG_NONE, D3DFOG_EXP2, FALSE,
1226 {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
1227 0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
1229 /* These tests fail on older Nvidia drivers */
1230 /* Foggy vertex shader */
1231 {2, 0, D3DFOG_NONE, D3DFOG_NONE, FALSE,
1232 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1233 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1234 {2, 0, D3DFOG_EXP, D3DFOG_NONE, FALSE,
1235 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1236 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1237 {2, 0, D3DFOG_EXP2, D3DFOG_NONE, FALSE,
1238 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1239 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1240 {2, 0, D3DFOG_LINEAR, D3DFOG_NONE, FALSE,
1241 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1242 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1244 /* Foggy vertex shader and pixel shader. First 4 tests with vertex fog,
1245 * all using the fixed fog-coord linear fog */
1246 {2, 1, D3DFOG_NONE, D3DFOG_NONE, FALSE,
1247 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1248 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1249 {2, 1, D3DFOG_EXP, D3DFOG_NONE, FALSE,
1250 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1251 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1252 {2, 1, D3DFOG_EXP2, D3DFOG_NONE, FALSE,
1253 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1254 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1255 {2, 1, D3DFOG_LINEAR, D3DFOG_NONE, FALSE,
1256 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1257 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1259 /* These use table fog. Here the shader-provided fog coordinate is
1260 * ignored and the z coordinate used instead */
1261 {2, 1, D3DFOG_NONE, D3DFOG_EXP, FALSE,
1262 {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
1263 0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
1264 {2, 1, D3DFOG_NONE, D3DFOG_EXP2, FALSE,
1265 {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
1266 0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
1267 {2, 1, D3DFOG_NONE, D3DFOG_LINEAR, FALSE,
1268 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1269 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1271 static const D3DMATRIX identity =
1273 1.0f, 0.0f, 0.0f, 0.0f,
1274 0.0f, 1.0f, 0.0f, 0.0f,
1275 0.0f, 0.0f, 1.0f, 0.0f,
1276 0.0f, 0.0f, 0.0f, 1.0f,
1277 }}};
1279 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
1280 0, 0, 640, 480, NULL, NULL, NULL, NULL);
1281 d3d = Direct3DCreate8(D3D_SDK_VERSION);
1282 ok(!!d3d, "Failed to create a D3D object.\n");
1283 if (!(device = create_device(d3d, window, window, TRUE)))
1285 skip("Failed to create a D3D device, skipping tests.\n");
1286 goto done;
1289 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
1290 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
1291 if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1) || caps.PixelShaderVersion < D3DPS_VERSION(1, 1))
1293 skip("No vs_1_1 / ps_1_1 support, skipping tests.\n");
1294 IDirect3DDevice8_Release(device);
1295 goto done;
1298 /* NOTE: changing these values will not affect the tests with foggy vertex
1299 * shader, as the values are hardcoded in the shader constant. */
1300 start.f = 0.1f;
1301 end.f = 0.9f;
1303 /* Some of the tests seem to depend on the projection matrix explicitly
1304 * being set to an identity matrix, even though that's the default.
1305 * (AMD Radeon HD 6310, Windows 7) */
1306 hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, &identity);
1307 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
1309 hr = IDirect3DDevice8_CreateVertexShader(device, decl, vertex_shader_code1, &vertex_shader[1], 0);
1310 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1311 hr = IDirect3DDevice8_CreateVertexShader(device, decl, vertex_shader_code2, &vertex_shader[2], 0);
1312 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1313 hr = IDirect3DDevice8_CreatePixelShader(device, pixel_shader_code, &pixel_shader[1]);
1314 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1316 /* Set shader constant value */
1317 hr = IDirect3DDevice8_SetVertexShader(device, vertex_shader[2]);
1318 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1319 hr = IDirect3DDevice8_SetVertexShaderConstant(device, 0, vs_constant, 1);
1320 ok(hr == D3D_OK, "Setting vertex shader constant failed (%08x)\n", hr);
1322 /* Setup initial states: No lighting, fog on, fog color */
1323 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1324 ok(hr == D3D_OK, "Turning off lighting failed (%08x)\n", hr);
1325 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
1326 ok(hr == D3D_OK, "Turning on fog calculations failed (%08x)\n", hr);
1327 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
1328 ok(hr == D3D_OK, "Setting fog color failed (%08x)\n", hr);
1330 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1331 ok(hr == D3D_OK, "Turning off table fog failed (%08x)\n", hr);
1332 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
1333 ok(hr == D3D_OK, "Turning off vertex fog failed (%08x)\n", hr);
1335 /* Use fogtart = 0.1 and end = 0.9 to test behavior outside the fog transition phase, too */
1336 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGSTART, start.i);
1337 ok(hr == D3D_OK, "Setting fog start failed (%08x)\n", hr);
1338 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGEND, end.i);
1339 ok(hr == D3D_OK, "Setting fog end failed (%08x)\n", hr);
1341 for (i = 0; i < sizeof(test_data)/sizeof(test_data[0]); ++i)
1343 hr = IDirect3DDevice8_SetVertexShader(device, vertex_shader[test_data[i].vshader]);
1344 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1345 hr = IDirect3DDevice8_SetPixelShader(device, pixel_shader[test_data[i].pshader]);
1346 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1347 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGVERTEXMODE, test_data[i].vfog);
1348 ok( hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1349 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGTABLEMODE, test_data[i].tfog);
1350 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1352 for(j = 0; j < 11; ++j)
1354 /* Don't use the whole zrange to prevent rounding errors */
1355 quad[0].position.z = 0.001f + j / 10.02f;
1356 quad[1].position.z = 0.001f + j / 10.02f;
1357 quad[2].position.z = 0.001f + j / 10.02f;
1358 quad[3].position.z = 0.001f + j / 10.02f;
1360 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff00ff, 1.0f, 0);
1361 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
1363 hr = IDirect3DDevice8_BeginScene(device);
1364 ok( hr == D3D_OK, "BeginScene returned failed (%08x)\n", hr);
1366 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1367 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
1369 hr = IDirect3DDevice8_EndScene(device);
1370 ok(hr == D3D_OK, "EndScene failed (%08x)\n", hr);
1372 /* As the red and green component are the result of blending use 5% tolerance on the expected value */
1373 color = getPixelColor(device, 128, 240);
1374 ok(color_match(color, test_data[i].color[j], 13) || broken(test_data[i].uninitialized_reg),
1375 "fog vs%i ps%i fvm%i ftm%i %d: got color %08x, expected %08x +-5%%\n",
1376 test_data[i].vshader, test_data[i].pshader,
1377 test_data[i].vfog, test_data[i].tfog, j, color, test_data[i].color[j]);
1380 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
1382 IDirect3DDevice8_DeleteVertexShader(device, vertex_shader[1]);
1383 IDirect3DDevice8_DeleteVertexShader(device, vertex_shader[2]);
1384 IDirect3DDevice8_DeleteVertexShader(device, pixel_shader[1]);
1385 refcount = IDirect3DDevice8_Release(device);
1386 ok(!refcount, "Device has %u references left.\n", refcount);
1387 done:
1388 IDirect3D8_Release(d3d);
1389 DestroyWindow(window);
1392 static void cnd_test(void)
1394 DWORD shader_11_coissue_2, shader_12_coissue_2, shader_13_coissue_2, shader_14_coissue_2;
1395 DWORD shader_11_coissue, shader_12_coissue, shader_13_coissue, shader_14_coissue;
1396 DWORD shader_11, shader_12, shader_13, shader_14;
1397 IDirect3DDevice8 *device;
1398 IDirect3D8 *d3d;
1399 ULONG refcount;
1400 D3DCAPS8 caps;
1401 DWORD color;
1402 HWND window;
1403 HRESULT hr;
1405 /* ps 1.x shaders are rather picky with writemasks and source swizzles.
1406 * The dp3 is used to copy r0.r to all components of r1, then copy r1.a to
1407 * r0.a. Essentially it does a mov r0.a, r0.r, which isn't allowed as-is
1408 * in 1.x pixel shaders. */
1409 static const DWORD shader_code_11[] =
1411 0xffff0101, /* ps_1_1 */
1412 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
1413 0x00000040, 0xb00f0000, /* texcoord t0 */
1414 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
1415 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3 r1, r0, c0 */
1416 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
1417 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
1418 0x0000ffff /* end */
1420 static const DWORD shader_code_12[] =
1422 0xffff0102, /* ps_1_2 */
1423 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
1424 0x00000040, 0xb00f0000, /* texcoord t0 */
1425 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
1426 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3 r1, r0, c0 */
1427 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
1428 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
1429 0x0000ffff /* end */
1431 static const DWORD shader_code_13[] =
1433 0xffff0103, /* ps_1_3 */
1434 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
1435 0x00000040, 0xb00f0000, /* texcoord t0 */
1436 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
1437 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3, r1, r0, c0 */
1438 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
1439 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
1440 0x0000ffff /* end */
1442 static const DWORD shader_code_14[] =
1444 0xffff0104, /* ps_1_3 */
1445 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
1446 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0, t0 */
1447 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
1448 0x00000050, 0x800f0000, 0x80e40000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0, c1, c2 */
1449 0x0000ffff /* end */
1452 /* Special fun: The coissue flag on cnd: Apparently cnd always selects the 2nd source,
1453 * as if the src0 comparison against 0.5 always evaluates to true. The coissue flag isn't
1454 * set by the compiler, it was added manually after compilation. Note that the COISSUE
1455 * flag on a color(.xyz) operation is only allowed after an alpha operation. DirectX doesn't
1456 * have proper docs, but GL_ATI_fragment_shader explains the pairing of color and alpha ops
1457 * well enough.
1459 * The shader attempts to test the range [-1;1] against coissued cnd, which is a bit tricky.
1460 * The input from t0 is [0;1]. 0.5 is subtracted, then we have to multiply with 2. Since
1461 * constants are clamped to [-1;1], a 2.0 is constructed by adding c0.r(=1.0) to c0.r into r1.r,
1462 * then r1(2.0, 0.0, 0.0, 0.0) is passed to dp3(explained above).
1464 static const DWORD shader_code_11_coissue[] =
1466 0xffff0101, /* ps_1_1 */
1467 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
1468 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
1469 0x00000040, 0xb00f0000, /* texcoord t0 */
1470 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
1471 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
1472 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
1473 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
1474 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
1475 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.xyz, r0.a, c1, c2*/
1476 0x0000ffff /* end */
1478 static const DWORD shader_code_11_coissue_2[] =
1480 0xffff0101, /* ps_1_1 */
1481 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
1482 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
1483 0x00000040, 0xb00f0000, /* texcoord t0 */
1484 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
1485 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
1486 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
1487 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
1488 0x00000001, 0x800f0000, 0x80e40001, /* mov r0, r1 */
1489 0x00000001, 0x80070000, 0x80ff0001, /* mov r0.xyz, r1.a */
1490 0x40000050, 0x80080000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.a, r0.a, c1, c2 */
1491 0x00000001, 0x80070000, 0x80ff0000, /* mov r0.xyz, r0.a */
1492 0x0000ffff /* end */
1494 static const DWORD shader_code_12_coissue[] =
1496 0xffff0102, /* ps_1_2 */
1497 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
1498 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
1499 0x00000040, 0xb00f0000, /* texcoord t0 */
1500 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
1501 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
1502 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
1503 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
1504 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
1505 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.xyz, r0.a, c1, c2*/
1506 0x0000ffff /* end */
1508 static const DWORD shader_code_12_coissue_2[] =
1510 0xffff0102, /* ps_1_2 */
1511 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
1512 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
1513 0x00000040, 0xb00f0000, /* texcoord t0 */
1514 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
1515 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
1516 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
1517 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
1518 0x00000001, 0x800f0000, 0x80e40001, /* mov r0, r1 */
1519 0x00000001, 0x80070000, 0x80ff0001, /* mov r0.xyz, r1.a */
1520 0x40000050, 0x80080000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.a, r0.a, c1, c2 */
1521 0x00000001, 0x80070000, 0x80ff0000, /* mov r0.xyz, r0.a */
1522 0x0000ffff /* end */
1524 static const DWORD shader_code_13_coissue[] =
1526 0xffff0103, /* ps_1_3 */
1527 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
1528 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
1529 0x00000040, 0xb00f0000, /* texcoord t0 */
1530 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
1531 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
1532 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
1533 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
1534 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
1535 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.xyz, r0.a, c1, c2*/
1536 0x0000ffff /* end */
1538 static const DWORD shader_code_13_coissue_2[] =
1540 0xffff0103, /* ps_1_3 */
1541 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
1542 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
1543 0x00000040, 0xb00f0000, /* texcoord t0 */
1544 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
1545 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
1546 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
1547 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
1548 0x00000001, 0x800f0000, 0x80e40001, /* mov r0, r1 */
1549 0x00000001, 0x80070000, 0x80ff0001, /* mov r0.xyz, r1.a */
1550 0x40000050, 0x80080000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.a, r0.a, c1, c2 */
1551 0x00000001, 0x80070000, 0x80ff0000, /* mov r0.xyz, r0.a */
1552 0x0000ffff /* end */
1554 /* ps_1_4 does not have a different cnd behavior, just pass the [0;1]
1555 * texcrd result to cnd, it will compare against 0.5. */
1556 static const DWORD shader_code_14_coissue[] =
1558 0xffff0104, /* ps_1_4 */
1559 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
1560 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0.xyz, t0 */
1561 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
1562 0x40000050, 0x80070000, 0x80e40000, 0xa0e40001, 0xa0e40002, /* +cnd r0.xyz, r0, c1, c2 */
1563 0x0000ffff /* end */
1565 static const DWORD shader_code_14_coissue_2[] =
1567 0xffff0104, /* ps_1_4 */
1568 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
1569 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0.xyz, t0 */
1570 0x00000001, 0x80080000, 0x80000000, /* mov r0.a, r0.x */
1571 0x00000001, 0x80070001, 0xa0ff0000, /* mov r1.xyz, c0.a */
1572 0x40000050, 0x80080001, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r1.a, r0.a, c1, c2 */
1573 0x00000001, 0x80070000, 0x80ff0001, /* mov r0.xyz, r1.a */
1574 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
1575 0x0000ffff /* end */
1577 static const float quad1[] =
1579 -1.0f, -1.0f, 0.1f, 0.0f, 0.0f, 1.0f,
1580 -1.0f, 0.0f, 0.1f, 0.0f, 1.0f, 0.0f,
1581 0.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f,
1582 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 0.0f
1584 static const float quad2[] =
1586 0.0f, -1.0f, 0.1f, 0.0f, 0.0f, 1.0f,
1587 0.0f, 0.0f, 0.1f, 0.0f, 1.0f, 0.0f,
1588 1.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f,
1589 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 0.0f
1591 static const float quad3[] =
1593 0.0f, 0.0f, 0.1f, 0.0f, 0.0f, 1.0f,
1594 0.0f, 1.0f, 0.1f, 0.0f, 1.0f, 0.0f,
1595 1.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f,
1596 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 0.0f
1598 static const float quad4[] =
1600 -1.0f, 0.0f, 0.1f, 0.0f, 0.0f, 1.0f,
1601 -1.0f, 1.0f, 0.1f, 0.0f, 1.0f, 0.0f,
1602 0.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f,
1603 0.0f, 1.0f, 0.1f, 1.0f, 1.0f, 0.0f
1605 static const float test_data_c1[4] = {0.0f, 0.0f, 0.0f, 0.0f};
1606 static const float test_data_c2[4] = {1.0f, 1.0f, 1.0f, 1.0f};
1607 static const float test_data_c1_coi[4] = {0.0f, 1.0f, 0.0f, 0.0f};
1608 static const float test_data_c2_coi[4] = {1.0f, 0.0f, 1.0f, 1.0f};
1610 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
1611 0, 0, 640, 480, NULL, NULL, NULL, NULL);
1612 d3d = Direct3DCreate8(D3D_SDK_VERSION);
1613 ok(!!d3d, "Failed to create a D3D object.\n");
1614 if (!(device = create_device(d3d, window, window, TRUE)))
1616 skip("Failed to create a D3D device, skipping tests.\n");
1617 goto done;
1620 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
1621 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
1622 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 4))
1624 skip("No ps_1_4 support, skipping tests.\n");
1625 IDirect3DDevice8_Release(device);
1626 goto done;
1629 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
1630 ok(hr == D3D_OK, "IDirect3DDevice8_Clear returned %08x\n", hr);
1632 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code_11, &shader_11);
1633 ok(hr == D3D_OK, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr);
1634 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code_12, &shader_12);
1635 ok(hr == D3D_OK, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr);
1636 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code_13, &shader_13);
1637 ok(hr == D3D_OK, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr);
1638 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code_14, &shader_14);
1639 ok(hr == D3D_OK, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr);
1640 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code_11_coissue, &shader_11_coissue);
1641 ok(hr == D3D_OK, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr);
1642 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code_12_coissue, &shader_12_coissue);
1643 ok(hr == D3D_OK, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr);
1644 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code_13_coissue, &shader_13_coissue);
1645 ok(hr == D3D_OK, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr);
1646 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code_14_coissue, &shader_14_coissue);
1647 ok(hr == D3D_OK, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr);
1648 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code_11_coissue_2, &shader_11_coissue_2);
1649 ok(hr == D3D_OK, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr);
1650 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code_12_coissue_2, &shader_12_coissue_2);
1651 ok(hr == D3D_OK, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr);
1652 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code_13_coissue_2, &shader_13_coissue_2);
1653 ok(hr == D3D_OK, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr);
1654 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code_14_coissue_2, &shader_14_coissue_2);
1655 ok(hr == D3D_OK, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr);
1657 hr = IDirect3DDevice8_SetPixelShaderConstant(device, 1, test_data_c1, 1);
1658 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShaderConstant returned %08x\n", hr);
1659 hr = IDirect3DDevice8_SetPixelShaderConstant(device, 2, test_data_c2, 1);
1660 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShaderConstant returned %08x\n", hr);
1661 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX1);
1662 ok(hr == D3D_OK, "IDirect3DDevice8_SetVertexShader returned %#08x\n", hr);
1664 hr = IDirect3DDevice8_BeginScene(device);
1665 ok(hr == D3D_OK, "IDirect3DDevice8_BeginScene returned %08x\n", hr);
1667 hr = IDirect3DDevice8_SetPixelShader(device, shader_11);
1668 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr);
1669 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
1670 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
1672 hr = IDirect3DDevice8_SetPixelShader(device, shader_12);
1673 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr);
1674 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
1675 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
1677 hr = IDirect3DDevice8_SetPixelShader(device, shader_13);
1678 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr);
1679 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
1680 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
1682 hr = IDirect3DDevice8_SetPixelShader(device, shader_14);
1683 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr);
1684 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
1685 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
1687 hr = IDirect3DDevice8_EndScene(device);
1688 ok(hr == D3D_OK, "IDirect3DDevice8_EndScene returned %08x\n", hr);
1690 hr = IDirect3DDevice8_SetPixelShader(device, 0);
1691 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr);
1693 /* This is the 1.4 test. Each component(r, g, b) is tested separately against 0.5 */
1694 color = getPixelColor(device, 158, 118);
1695 ok(color == 0x00ff00ff, "pixel 158, 118 has color %08x, expected 0x00ff00ff\n", color);
1696 color = getPixelColor(device, 162, 118);
1697 ok(color == 0x000000ff, "pixel 162, 118 has color %08x, expected 0x000000ff\n", color);
1698 color = getPixelColor(device, 158, 122);
1699 ok(color == 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color);
1700 color = getPixelColor(device, 162, 122);
1701 ok(color == 0x0000ffff, "pixel 162, 122 has color %08x, expected 0x0000ffff\n", color);
1703 /* 1.1 shader. All 3 components get set, based on the .w comparison */
1704 color = getPixelColor(device, 158, 358);
1705 ok(color == 0x00ffffff, "pixel 158, 358 has color %08x, expected 0x00ffffff\n", color);
1706 color = getPixelColor(device, 162, 358);
1707 ok(color_match(color, 0x00000000, 1),
1708 "pixel 162, 358 has color %08x, expected 0x00000000\n", color);
1709 color = getPixelColor(device, 158, 362);
1710 ok(color == 0x00ffffff, "pixel 158, 362 has color %08x, expected 0x00ffffff\n", color);
1711 color = getPixelColor(device, 162, 362);
1712 ok(color_match(color, 0x00000000, 1),
1713 "pixel 162, 362 has color %08x, expected 0x00000000\n", color);
1715 /* 1.2 shader */
1716 color = getPixelColor(device, 478, 358);
1717 ok(color == 0x00ffffff, "pixel 478, 358 has color %08x, expected 0x00ffffff\n", color);
1718 color = getPixelColor(device, 482, 358);
1719 ok(color_match(color, 0x00000000, 1),
1720 "pixel 482, 358 has color %08x, expected 0x00000000\n", color);
1721 color = getPixelColor(device, 478, 362);
1722 ok(color == 0x00ffffff, "pixel 478, 362 has color %08x, expected 0x00ffffff\n", color);
1723 color = getPixelColor(device, 482, 362);
1724 ok(color_match(color, 0x00000000, 1),
1725 "pixel 482, 362 has color %08x, expected 0x00000000\n", color);
1727 /* 1.3 shader */
1728 color = getPixelColor(device, 478, 118);
1729 ok(color == 0x00ffffff, "pixel 478, 118 has color %08x, expected 0x00ffffff\n", color);
1730 color = getPixelColor(device, 482, 118);
1731 ok(color_match(color, 0x00000000, 1),
1732 "pixel 482, 118 has color %08x, expected 0x00000000\n", color);
1733 color = getPixelColor(device, 478, 122);
1734 ok(color == 0x00ffffff, "pixel 478, 122 has color %08x, expected 0x00ffffff\n", color);
1735 color = getPixelColor(device, 482, 122);
1736 ok(color_match(color, 0x00000000, 1),
1737 "pixel 482, 122 has color %08x, expected 0x00000000\n", color);
1739 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
1740 ok(hr == D3D_OK, "IDirect3DDevice8_Present failed with %08x\n", hr);
1742 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0f, 0);
1743 ok(hr == D3D_OK, "IDirect3DDevice8_Clear returned %08x\n", hr);
1744 hr = IDirect3DDevice8_SetPixelShaderConstant(device, 1, test_data_c1_coi, 1);
1745 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShaderConstant returned %08x\n", hr);
1746 hr = IDirect3DDevice8_SetPixelShaderConstant(device, 2, test_data_c2_coi, 1);
1747 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShaderConstant returned %08x\n", hr);
1749 hr = IDirect3DDevice8_BeginScene(device);
1750 ok(hr == D3D_OK, "IDirect3DDevice8_BeginScene returned %08x\n", hr);
1752 hr = IDirect3DDevice8_SetPixelShader(device, shader_11_coissue);
1753 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr);
1754 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
1755 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
1757 hr = IDirect3DDevice8_SetPixelShader(device, shader_12_coissue);
1758 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr);
1759 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
1760 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
1762 hr = IDirect3DDevice8_SetPixelShader(device, shader_13_coissue);
1763 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr);
1764 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
1765 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
1767 hr = IDirect3DDevice8_SetPixelShader(device, shader_14_coissue);
1768 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr);
1769 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
1770 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
1772 hr = IDirect3DDevice8_EndScene(device);
1773 ok(hr == D3D_OK, "IDirect3DDevice8_EndScene returned %08x\n", hr);
1775 hr = IDirect3DDevice8_SetPixelShader(device, 0);
1776 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr);
1778 /* This is the 1.4 test. The coissue doesn't change the behavior here, but keep in mind
1779 * that we swapped the values in c1 and c2 to make the other tests return some color
1781 color = getPixelColor(device, 158, 118);
1782 ok(color == 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color);
1783 color = getPixelColor(device, 162, 118);
1784 ok(color == 0x0000ffff, "pixel 162, 118 has color %08x, expected 0x0000ffff\n", color);
1785 color = getPixelColor(device, 158, 122);
1786 ok(color == 0x00ff00ff, "pixel 162, 122 has color %08x, expected 0x00ff00ff\n", color);
1787 color = getPixelColor(device, 162, 122);
1788 ok(color == 0x000000ff, "pixel 162, 122 has color %08x, expected 0x000000ff\n", color);
1790 /* 1.1 shader. coissue flag changed the semantic of cnd, c1 is always selected
1791 * (The Win7 nvidia driver always selects c2)
1793 color = getPixelColor(device, 158, 358);
1794 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
1795 "pixel 158, 358 has color %08x, expected 0x0000ff00\n", color);
1796 color = getPixelColor(device, 162, 358);
1797 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
1798 "pixel 162, 358 has color %08x, expected 0x0000ff00\n", color);
1799 color = getPixelColor(device, 158, 362);
1800 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
1801 "pixel 158, 362 has color %08x, expected 0x0000ff00\n", color);
1802 color = getPixelColor(device, 162, 362);
1803 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
1804 "pixel 162, 362 has color %08x, expected 0x0000ff00\n", color);
1806 /* 1.2 shader */
1807 color = getPixelColor(device, 478, 358);
1808 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
1809 "pixel 478, 358 has color %08x, expected 0x0000ff00\n", color);
1810 color = getPixelColor(device, 482, 358);
1811 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
1812 "pixel 482, 358 has color %08x, expected 0x0000ff00\n", color);
1813 color = getPixelColor(device, 478, 362);
1814 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
1815 "pixel 478, 362 has color %08x, expected 0x0000ff00\n", color);
1816 color = getPixelColor(device, 482, 362);
1817 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
1818 "pixel 482, 362 has color %08x, expected 0x0000ff00\n", color);
1820 /* 1.3 shader */
1821 color = getPixelColor(device, 478, 118);
1822 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
1823 "pixel 478, 118 has color %08x, expected 0x0000ff00\n", color);
1824 color = getPixelColor(device, 482, 118);
1825 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
1826 "pixel 482, 118 has color %08x, expected 0x0000ff00\n", color);
1827 color = getPixelColor(device, 478, 122);
1828 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
1829 "pixel 478, 122 has color %08x, expected 0x0000ff00\n", color);
1830 color = getPixelColor(device, 482, 122);
1831 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
1832 "pixel 482, 122 has color %08x, expected 0x0000ff00\n", color);
1834 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
1835 ok(hr == D3D_OK, "IDirect3DDevice8_Present failed with %08x\n", hr);
1837 /* Retest with the coissue flag on the alpha instruction instead. This
1838 * works "as expected". The Windows 8 testbot (WARP) seems to handle this
1839 * the same as coissue on .rgb. */
1840 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0f, 0);
1841 ok(hr == D3D_OK, "IDirect3DDevice8_Clear returned %08x\n", hr);
1843 hr = IDirect3DDevice8_BeginScene(device);
1844 ok(hr == D3D_OK, "IDirect3DDevice8_BeginScene returned %08x\n", hr);
1846 hr = IDirect3DDevice8_SetPixelShader(device, shader_11_coissue_2);
1847 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr);
1848 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
1849 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
1851 hr = IDirect3DDevice8_SetPixelShader(device, shader_12_coissue_2);
1852 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr);
1853 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
1854 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
1856 hr = IDirect3DDevice8_SetPixelShader(device, shader_13_coissue_2);
1857 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr);
1858 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
1859 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
1861 hr = IDirect3DDevice8_SetPixelShader(device, shader_14_coissue_2);
1862 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr);
1863 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
1864 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
1866 hr = IDirect3DDevice8_EndScene(device);
1867 ok(hr == D3D_OK, "IDirect3DDevice8_EndScene returned %08x\n", hr);
1869 /* 1.4 shader */
1870 color = getPixelColor(device, 158, 118);
1871 ok(color == 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color);
1872 color = getPixelColor(device, 162, 118);
1873 ok(color == 0x00000000, "pixel 162, 118 has color %08x, expected 0x00000000\n", color);
1874 color = getPixelColor(device, 158, 122);
1875 ok(color == 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color);
1876 color = getPixelColor(device, 162, 122);
1877 ok(color == 0x00000000, "pixel 162, 122 has color %08x, expected 0x00000000\n", color);
1879 /* 1.1 shader */
1880 color = getPixelColor(device, 238, 358);
1881 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
1882 "pixel 238, 358 has color %08x, expected 0x00ffffff\n", color);
1883 color = getPixelColor(device, 242, 358);
1884 ok(color_match(color, 0x00000000, 1),
1885 "pixel 242, 358 has color %08x, expected 0x00000000\n", color);
1886 color = getPixelColor(device, 238, 362);
1887 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
1888 "pixel 238, 362 has color %08x, expected 0x00ffffff\n", color);
1889 color = getPixelColor(device, 242, 362);
1890 ok(color_match(color, 0x00000000, 1),
1891 "pixel 242, 362 has color %08x, expected 0x00000000\n", color);
1893 /* 1.2 shader */
1894 color = getPixelColor(device, 558, 358);
1895 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
1896 "pixel 558, 358 has color %08x, expected 0x00ffffff\n", color);
1897 color = getPixelColor(device, 562, 358);
1898 ok(color_match(color, 0x00000000, 1),
1899 "pixel 562, 358 has color %08x, expected 0x00000000\n", color);
1900 color = getPixelColor(device, 558, 362);
1901 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
1902 "pixel 558, 362 has color %08x, expected 0x00ffffff\n", color);
1903 color = getPixelColor(device, 562, 362);
1904 ok(color_match(color, 0x00000000, 1),
1905 "pixel 562, 362 has color %08x, expected 0x00000000\n", color);
1907 /* 1.3 shader */
1908 color = getPixelColor(device, 558, 118);
1909 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
1910 "pixel 558, 118 has color %08x, expected 0x00ffffff\n", color);
1911 color = getPixelColor(device, 562, 118);
1912 ok(color_match(color, 0x00000000, 1),
1913 "pixel 562, 118 has color %08x, expected 0x00000000\n", color);
1914 color = getPixelColor(device, 558, 122);
1915 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
1916 "pixel 558, 122 has color %08x, expected 0x00ffffff\n", color);
1917 color = getPixelColor(device, 562, 122);
1918 ok(color_match(color, 0x00000000, 1),
1919 "pixel 562, 122 has color %08x, expected 0x00000000\n", color);
1921 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
1922 ok(hr == D3D_OK, "IDirect3DDevice8_Present failed with %08x\n", hr);
1924 IDirect3DDevice8_DeletePixelShader(device, shader_14_coissue_2);
1925 IDirect3DDevice8_DeletePixelShader(device, shader_13_coissue_2);
1926 IDirect3DDevice8_DeletePixelShader(device, shader_12_coissue_2);
1927 IDirect3DDevice8_DeletePixelShader(device, shader_11_coissue_2);
1928 IDirect3DDevice8_DeletePixelShader(device, shader_14_coissue);
1929 IDirect3DDevice8_DeletePixelShader(device, shader_13_coissue);
1930 IDirect3DDevice8_DeletePixelShader(device, shader_12_coissue);
1931 IDirect3DDevice8_DeletePixelShader(device, shader_11_coissue);
1932 IDirect3DDevice8_DeletePixelShader(device, shader_14);
1933 IDirect3DDevice8_DeletePixelShader(device, shader_13);
1934 IDirect3DDevice8_DeletePixelShader(device, shader_12);
1935 IDirect3DDevice8_DeletePixelShader(device, shader_11);
1936 refcount = IDirect3DDevice8_Release(device);
1937 ok(!refcount, "Device has %u references left.\n", refcount);
1938 done:
1939 IDirect3D8_Release(d3d);
1940 DestroyWindow(window);
1943 static void z_range_test(void)
1945 IDirect3DDevice8 *device;
1946 IDirect3D8 *d3d;
1947 D3DCOLOR color;
1948 ULONG refcount;
1949 D3DCAPS8 caps;
1950 DWORD shader;
1951 HWND window;
1952 HRESULT hr;
1954 static const struct
1956 struct vec3 position;
1957 DWORD diffuse;
1959 quad[] =
1961 {{-1.0f, 0.0f, 1.1f}, 0xffff0000},
1962 {{-1.0f, 1.0f, 1.1f}, 0xffff0000},
1963 {{ 1.0f, 0.0f, -1.1f}, 0xffff0000},
1964 {{ 1.0f, 1.0f, -1.1f}, 0xffff0000},
1966 quad2[] =
1968 {{-1.0f, 0.0f, 1.1f}, 0xff0000ff},
1969 {{-1.0f, 1.0f, 1.1f}, 0xff0000ff},
1970 {{ 1.0f, 0.0f, -1.1f}, 0xff0000ff},
1971 {{ 1.0f, 1.0f, -1.1f}, 0xff0000ff},
1973 static const struct
1975 struct vec4 position;
1976 DWORD diffuse;
1978 quad3[] =
1980 {{640.0f, 240.0f, -1.1f, 1.0f}, 0xffffff00},
1981 {{640.0f, 480.0f, -1.1f, 1.0f}, 0xffffff00},
1982 {{ 0.0f, 240.0f, 1.1f, 1.0f}, 0xffffff00},
1983 {{ 0.0f, 480.0f, 1.1f, 1.0f}, 0xffffff00},
1985 quad4[] =
1987 {{640.0f, 240.0f, -1.1f, 1.0f}, 0xff00ff00},
1988 {{640.0f, 480.0f, -1.1f, 1.0f}, 0xff00ff00},
1989 {{ 0.0f, 240.0f, 1.1f, 1.0f}, 0xff00ff00},
1990 {{ 0.0f, 480.0f, 1.1f, 1.0f}, 0xff00ff00},
1992 static const DWORD shader_code[] =
1994 0xfffe0101, /* vs_1_1 */
1995 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1996 0x00000001, 0xd00f0000, 0xa0e40000, /* mov oD0, c0 */
1997 0x0000ffff /* end */
1999 static const float color_const_1[] = {1.0f, 0.0f, 0.0f, 1.0f};
2000 static const float color_const_2[] = {0.0f, 0.0f, 1.0f, 1.0f};
2001 static const DWORD vertex_declaration[] =
2003 D3DVSD_STREAM(0),
2004 D3DVSD_REG(D3DVSDE_POSITION, D3DVSDT_FLOAT3),
2005 D3DVSD_END()
2008 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
2009 0, 0, 640, 480, NULL, NULL, NULL, NULL);
2010 d3d = Direct3DCreate8(D3D_SDK_VERSION);
2011 ok(!!d3d, "Failed to create a D3D object.\n");
2012 if (!(device = create_device(d3d, window, window, TRUE)))
2014 skip("Failed to create a D3D device, skipping tests.\n");
2015 goto done;
2018 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
2019 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
2021 /* Does the Present clear the depth stencil? Clear the depth buffer with some value != 0,
2022 * then call Present. Then clear the color buffer to make sure it has some defined content
2023 * after the Present with D3DSWAPEFFECT_DISCARD. After that draw a plane that is somewhere cut
2024 * by the depth value. */
2025 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.75f, 0);
2026 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
2027 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
2028 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
2029 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
2030 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
2032 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
2033 ok(SUCCEEDED(hr), "Failed to disabled lighting, hr %#x.\n", hr);
2034 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, TRUE);
2035 ok(SUCCEEDED(hr), "Failed to enable clipping, hr %#x.\n", hr);
2036 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
2037 ok(SUCCEEDED(hr), "Failed to enable z test, hr %#x.\n", hr);
2038 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
2039 ok(SUCCEEDED(hr), "Failed to disable z writes, hr %#x.\n", hr);
2040 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
2041 ok(SUCCEEDED(hr), "Failed to set z function, hr %#x.\n", hr);
2042 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
2043 ok(SUCCEEDED(hr), "Failed set FVF, hr %#x.\n", hr);
2045 hr = IDirect3DDevice8_BeginScene(device);
2046 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
2048 /* Test the untransformed vertex path */
2049 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
2050 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2051 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
2052 ok(SUCCEEDED(hr), "Failed to set z function, hr %#x.\n", hr);
2053 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
2054 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2056 /* Test the transformed vertex path */
2057 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
2058 ok(SUCCEEDED(hr), "Failed set FVF, hr %#x.\n", hr);
2060 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(quad4[0]));
2061 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2062 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
2063 ok(SUCCEEDED(hr), "Failed to set z function, hr %#x.\n", hr);
2064 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(quad3[0]));
2065 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2067 hr = IDirect3DDevice8_EndScene(device);
2068 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
2070 /* Do not test the exact corner pixels, but go pretty close to them */
2072 /* Clipped because z > 1.0 */
2073 color = getPixelColor(device, 28, 238);
2074 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2075 color = getPixelColor(device, 28, 241);
2076 if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
2077 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2078 else
2079 ok(color_match(color, 0x00ffff00, 0), "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2081 /* Not clipped, > z buffer clear value(0.75).
2083 * On the r500 driver on Windows D3DCMP_GREATER and D3DCMP_GREATEREQUAL are broken for depth
2084 * values > 0.5. The range appears to be distorted, apparently an incoming value of ~0.875 is
2085 * equal to a stored depth buffer value of 0.5. */
2086 color = getPixelColor(device, 31, 238);
2087 ok(color_match(color, 0x00ff0000, 0), "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2088 color = getPixelColor(device, 31, 241);
2089 ok(color_match(color, 0x00ffff00, 0), "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2090 color = getPixelColor(device, 100, 238);
2091 ok(color_match(color, 0x00ff0000, 0) || broken(color_match(color, 0x00ffffff, 0)),
2092 "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2093 color = getPixelColor(device, 100, 241);
2094 ok(color_match(color, 0x00ffff00, 0) || broken(color_match(color, 0x00ffffff, 0)),
2095 "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2097 /* Not clipped, < z buffer clear value */
2098 color = getPixelColor(device, 104, 238);
2099 ok(color_match(color, 0x000000ff, 0), "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2100 color = getPixelColor(device, 104, 241);
2101 ok(color_match(color, 0x0000ff00, 0), "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
2102 color = getPixelColor(device, 318, 238);
2103 ok(color_match(color, 0x000000ff, 0), "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2104 color = getPixelColor(device, 318, 241);
2105 ok(color_match(color, 0x0000ff00, 0), "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
2107 /* Clipped because z < 0.0 */
2108 color = getPixelColor(device, 321, 238);
2109 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2110 color = getPixelColor(device, 321, 241);
2111 if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
2112 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2113 else
2114 ok(color_match(color, 0x0000ff00, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2116 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
2117 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
2119 /* Test the shader path */
2120 if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1))
2122 skip("Vertex shaders not supported\n");
2123 IDirect3DDevice8_Release(device);
2124 goto done;
2126 hr = IDirect3DDevice8_CreateVertexShader(device, vertex_declaration, shader_code, &shader, 0);
2127 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
2129 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
2130 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
2132 hr = IDirect3DDevice8_SetVertexShader(device, shader);
2133 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
2135 hr = IDirect3DDevice8_BeginScene(device);
2136 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
2138 hr = IDirect3DDevice8_SetVertexShaderConstant(device, 0, color_const_1, 1);
2139 ok(SUCCEEDED(hr), "Failed to set vs constant 0, hr %#x.\n", hr);
2140 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
2141 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2143 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
2144 ok(SUCCEEDED(hr), "Failed to set z function, hr %#x.\n", hr);
2145 hr = IDirect3DDevice8_SetVertexShaderConstant(device, 0, color_const_2, 1);
2146 ok(SUCCEEDED(hr), "Failed to set vs constant 0, hr %#x.\n", hr);
2147 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
2148 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2150 hr = IDirect3DDevice8_EndScene(device);
2151 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
2153 hr = IDirect3DDevice8_SetVertexShader(device, 0);
2154 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
2156 hr = IDirect3DDevice8_DeleteVertexShader(device, shader);
2157 ok(SUCCEEDED(hr), "Failed to delete vertex shader, hr %#x.\n", hr);
2159 /* Z < 1.0 */
2160 color = getPixelColor(device, 28, 238);
2161 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2163 /* 1.0 < z < 0.75 */
2164 color = getPixelColor(device, 31, 238);
2165 ok(color_match(color, 0x00ff0000, 0), "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2166 color = getPixelColor(device, 100, 238);
2167 ok(color_match(color, 0x00ff0000, 0) || broken(color_match(color, 0x00ffffff, 0)),
2168 "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2170 /* 0.75 < z < 0.0 */
2171 color = getPixelColor(device, 104, 238);
2172 ok(color_match(color, 0x000000ff, 0), "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2173 color = getPixelColor(device, 318, 238);
2174 ok(color_match(color, 0x000000ff, 0), "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2176 /* 0.0 < z */
2177 color = getPixelColor(device, 321, 238);
2178 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2180 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
2181 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
2183 refcount = IDirect3DDevice8_Release(device);
2184 ok(!refcount, "Device has %u references left.\n", refcount);
2185 done:
2186 IDirect3D8_Release(d3d);
2187 DestroyWindow(window);
2190 static void test_scalar_instructions(void)
2192 IDirect3DDevice8 *device;
2193 IDirect3D8 *d3d;
2194 unsigned int i;
2195 D3DCOLOR color;
2196 ULONG refcount;
2197 D3DCAPS8 caps;
2198 DWORD shader;
2199 HWND window;
2200 HRESULT hr;
2202 static const struct vec3 quad[] =
2204 {-1.0f, -1.0f, 0.0f},
2205 {-1.0f, 1.0f, 0.0f},
2206 { 1.0f, -1.0f, 0.0f},
2207 { 1.0f, 1.0f, 0.0f},
2209 static const DWORD decl[] =
2211 D3DVSD_STREAM(0),
2212 D3DVSD_REG(D3DVSDE_POSITION, D3DVSDT_FLOAT3), /* dcl_position v0 */
2213 D3DVSD_CONST(0, 1), 0x3e800000, 0x3f000000, 0x3f800000, 0x40000000, /* def c0, 0.25, 0.5, 1.0, 2.0 */
2214 D3DVSD_END()
2216 static const DWORD rcp_test[] =
2218 0xfffe0101, /* vs_1_1 */
2219 0x0009fffe, 0x30303030, 0x30303030, /* Shaders have to have a minimal size. */
2220 0x30303030, 0x30303030, 0x30303030, /* Add a filler comment. Usually d3dx8's */
2221 0x30303030, 0x30303030, 0x30303030, /* version comment makes the shader big */
2222 0x00303030, /* enough to make Windows happy. */
2223 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
2224 0x00000006, 0xd00f0000, 0xa0e40000, /* rcp oD0, c0 */
2225 0x0000ffff /* END */
2227 static const DWORD rsq_test[] =
2229 0xfffe0101, /* vs_1_1 */
2230 0x0009fffe, 0x30303030, 0x30303030, /* Shaders have to have a minimal size. */
2231 0x30303030, 0x30303030, 0x30303030, /* Add a filler comment. Usually d3dx8's */
2232 0x30303030, 0x30303030, 0x30303030, /* version comment makes the shader big */
2233 0x00303030, /* enough to make Windows happy. */
2234 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
2235 0x00000007, 0xd00f0000, 0xa0e40000, /* rsq oD0, c0 */
2236 0x0000ffff /* END */
2238 static const DWORD exp_test[] =
2240 0xfffe0101, /* vs_1_1 */
2241 0x0009fffe, 0x30303030, 0x30303030, /* Shaders have to have a minimal size. */
2242 0x30303030, 0x30303030, 0x30303030, /* Add a filler comment. Usually d3dx8's */
2243 0x30303030, 0x30303030, 0x30303030, /* version comment makes the shader big */
2244 0x00303030, /* enough to make Windows happy. */
2245 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
2246 0x0000000e, 0x800f0000, 0xa0e40000, /* exp r0, c0 */
2247 0x00000006, 0xd00f0000, 0x80000000, /* rcp oD0, r0.x */
2248 0x0000ffff, /* END */
2250 static const DWORD expp_test[] =
2252 0xfffe0101, /* vs_1_1 */
2253 0x0009fffe, 0x30303030, 0x30303030, /* Shaders have to have a minimal size. */
2254 0x30303030, 0x30303030, 0x30303030, /* Add a filler comment. Usually d3dx8's */
2255 0x30303030, 0x30303030, 0x30303030, /* version comment makes the shader big */
2256 0x00303030, /* enough to make Windows happy. */
2257 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
2258 0x0000004e, 0x800f0000, 0xa0e40000, /* expp r0, c0 */
2259 0x00000006, 0xd00f0000, 0x80000000, /* rcp oD0, r0.x */
2260 0x0000ffff, /* END */
2262 static const DWORD log_test[] =
2264 0xfffe0101, /* vs_1_1 */
2265 0x0009fffe, 0x30303030, 0x30303030, /* Shaders have to have a minimal size. */
2266 0x30303030, 0x30303030, 0x30303030, /* Add a filler comment. Usually d3dx8's */
2267 0x30303030, 0x30303030, 0x30303030, /* version comment makes the shader big */
2268 0x00303030, /* enough to make Windows happy. */
2269 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
2270 0x0000000f, 0xd00f0000, 0xa0e40000, /* log oD0, c0 */
2271 0x0000ffff, /* END */
2273 static const DWORD logp_test[] =
2275 0xfffe0101, /* vs_1_1 */
2276 0x0009fffe, 0x30303030, 0x30303030, /* Shaders have to have a minimal size. */
2277 0x30303030, 0x30303030, 0x30303030, /* Add a filler comment. Usually d3dx8's */
2278 0x30303030, 0x30303030, 0x30303030, /* version comment makes the shader big */
2279 0x00303030, /* enough to make Windows happy. */
2280 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
2281 0x0000004f, 0xd00f0000, 0xa0e40000, /* logp oD0, c0 */
2282 0x0000ffff, /* END */
2284 static const struct
2286 const char *name;
2287 const DWORD *byte_code;
2288 D3DCOLOR color;
2289 /* Some drivers, including Intel HD4000 10.18.10.3345 and VMware SVGA
2290 * 3D 7.14.1.5025, use the .x component instead of the .w one. */
2291 D3DCOLOR broken_color;
2293 test_data[] =
2295 {"rcp_test", rcp_test, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x80), D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff)},
2296 {"rsq_test", rsq_test, D3DCOLOR_ARGB(0x00, 0xb4, 0xb4, 0xb4), D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff)},
2297 {"exp_test", exp_test, D3DCOLOR_ARGB(0x00, 0x40, 0x40, 0x40), D3DCOLOR_ARGB(0x00, 0xd6, 0xd6, 0xd6)},
2298 {"expp_test", expp_test, D3DCOLOR_ARGB(0x00, 0x40, 0x40, 0x40), D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff)},
2299 {"log_test", log_test, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff), D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
2300 {"logp_test", logp_test, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff), D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
2303 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
2304 0, 0, 640, 480, NULL, NULL, NULL, NULL);
2305 d3d = Direct3DCreate8(D3D_SDK_VERSION);
2306 ok(!!d3d, "Failed to create a D3D object.\n");
2307 if (!(device = create_device(d3d, window, window, TRUE)))
2309 skip("Failed to create a D3D device, skipping tests.\n");
2310 goto done;
2313 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
2314 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
2315 if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1))
2317 skip("No vs_1_1 support, skipping tests.\n");
2318 IDirect3DDevice8_Release(device);
2319 goto done;
2322 for (i = 0; i < sizeof(test_data) / sizeof(*test_data); ++i)
2324 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff336699, 0.0f, 0);
2325 ok(SUCCEEDED(hr), "%s: Failed to clear, hr %#x.\n", test_data[i].name, hr);
2327 hr = IDirect3DDevice8_CreateVertexShader(device, decl, test_data[i].byte_code, &shader, 0);
2328 ok(SUCCEEDED(hr), "%s: Failed to create vertex shader, hr %#x.\n", test_data[i].name, hr);
2329 hr = IDirect3DDevice8_SetVertexShader(device, shader);
2330 ok(SUCCEEDED(hr), "%s: Failed to set vertex shader, hr %#x.\n", test_data[i].name, hr);
2332 hr = IDirect3DDevice8_BeginScene(device);
2333 ok(SUCCEEDED(hr), "%s: Failed to begin scene, hr %#x.\n", test_data[i].name, hr);
2334 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], 3 * sizeof(float));
2335 ok(SUCCEEDED(hr), "%s: Failed to draw primitive, hr %#x.\n", test_data[i].name, hr);
2336 hr = IDirect3DDevice8_EndScene(device);
2337 ok(SUCCEEDED(hr), "%s: Failed to end scene, hr %#x.\n", test_data[i].name, hr);
2339 color = getPixelColor(device, 320, 240);
2340 ok(color_match(color, test_data[i].color, 4) || broken(color_match(color, test_data[i].broken_color, 4)),
2341 "%s: Got unexpected color 0x%08x, expected 0x%08x.\n",
2342 test_data[i].name, color, test_data[i].color);
2344 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
2345 ok(SUCCEEDED(hr), "%s: Failed to present, hr %#x.\n", test_data[i].name, hr);
2347 hr = IDirect3DDevice8_SetVertexShader(device, 0);
2348 ok(SUCCEEDED(hr), "%s: Failed to set vertex shader, hr %#x.\n", test_data[i].name, hr);
2349 hr = IDirect3DDevice8_DeleteVertexShader(device, shader);
2350 ok(SUCCEEDED(hr), "%s: Failed to delete vertex shader, hr %#x.\n", test_data[i].name, hr);
2353 refcount = IDirect3DDevice8_Release(device);
2354 ok(!refcount, "Device has %u references left.\n", refcount);
2355 done:
2356 IDirect3D8_Release(d3d);
2357 DestroyWindow(window);
2360 static void offscreen_test(void)
2362 IDirect3DSurface8 *backbuffer, *offscreen, *depthstencil;
2363 IDirect3DTexture8 *offscreenTexture;
2364 IDirect3DDevice8 *device;
2365 IDirect3D8 *d3d;
2366 D3DCOLOR color;
2367 ULONG refcount;
2368 HWND window;
2369 HRESULT hr;
2371 static const float quad[][5] =
2373 {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
2374 {-0.5f, 0.5f, 0.1f, 0.0f, 1.0f},
2375 { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
2376 { 0.5f, 0.5f, 0.1f, 1.0f, 1.0f},
2379 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
2380 0, 0, 640, 480, NULL, NULL, NULL, NULL);
2381 d3d = Direct3DCreate8(D3D_SDK_VERSION);
2382 ok(!!d3d, "Failed to create a D3D object.\n");
2383 if (!(device = create_device(d3d, window, window, TRUE)))
2385 skip("Failed to create a D3D device, skipping tests.\n");
2386 goto done;
2389 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 1.0f, 0);
2390 ok(hr == D3D_OK, "Clear failed, hr = %#08x\n", hr);
2392 hr = IDirect3DDevice8_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET,
2393 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture);
2394 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %#08x\n", hr);
2395 if (!offscreenTexture)
2397 trace("Failed to create an X8R8G8B8 offscreen texture, trying R5G6B5\n");
2398 hr = IDirect3DDevice8_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET,
2399 D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &offscreenTexture);
2400 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %#08x\n", hr);
2401 if (!offscreenTexture)
2403 skip("Cannot create an offscreen render target.\n");
2404 IDirect3DDevice8_Release(device);
2405 goto done;
2409 hr = IDirect3DDevice8_GetDepthStencilSurface(device, &depthstencil);
2410 ok(hr == D3D_OK, "IDirect3DDevice8_GetDepthStencilSurface failed, hr = %#08x\n", hr);
2412 hr = IDirect3DDevice8_GetBackBuffer(device, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
2413 ok(hr == D3D_OK, "Can't get back buffer, hr = %#08x\n", hr);
2415 hr = IDirect3DTexture8_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
2416 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %#08x\n", hr);
2418 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX1);
2419 ok(hr == D3D_OK, "SetVertexShader failed, hr = %#08x\n", hr);
2421 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
2422 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %#08x\n", hr);
2423 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
2424 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %#08x\n", hr);
2425 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MINFILTER, D3DTEXF_NONE);
2426 ok(SUCCEEDED(hr), "SetTextureStageState D3DSAMP_MINFILTER failed (%#08x)\n", hr);
2427 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MAGFILTER, D3DTEXF_NONE);
2428 ok(SUCCEEDED(hr), "SetTextureStageState D3DSAMP_MAGFILTER failed (%#08x)\n", hr);
2429 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
2430 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %08x\n", hr);
2432 hr = IDirect3DDevice8_BeginScene(device);
2433 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
2435 hr = IDirect3DDevice8_SetRenderTarget(device, offscreen, depthstencil);
2436 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
2437 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 1.0f, 0);
2438 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
2440 /* Draw without textures - Should result in a white quad. */
2441 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
2442 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2444 hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, depthstencil);
2445 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
2446 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)offscreenTexture);
2447 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
2449 /* This time with the texture .*/
2450 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
2451 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2453 hr = IDirect3DDevice8_EndScene(device);
2454 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
2456 /* Center quad - should be white */
2457 color = getPixelColor(device, 320, 240);
2458 ok(color == 0x00ffffff, "Offscreen failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2459 /* Some quad in the cleared part of the texture */
2460 color = getPixelColor(device, 170, 240);
2461 ok(color == 0x00ff00ff, "Offscreen failed: Got color 0x%08x, expected 0x00ff00ff.\n", color);
2462 /* Part of the originally cleared back buffer */
2463 color = getPixelColor(device, 10, 10);
2464 ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2465 color = getPixelColor(device, 10, 470);
2466 ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2468 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
2470 IDirect3DSurface8_Release(backbuffer);
2471 IDirect3DTexture8_Release(offscreenTexture);
2472 IDirect3DSurface8_Release(offscreen);
2473 IDirect3DSurface8_Release(depthstencil);
2474 refcount = IDirect3DDevice8_Release(device);
2475 ok(!refcount, "Device has %u references left.\n", refcount);
2476 done:
2477 IDirect3D8_Release(d3d);
2478 DestroyWindow(window);
2481 static void test_blend(void)
2483 IDirect3DSurface8 *backbuffer, *offscreen, *depthstencil;
2484 IDirect3DTexture8 *offscreenTexture;
2485 IDirect3DDevice8 *device;
2486 IDirect3D8 *d3d;
2487 D3DCOLOR color;
2488 ULONG refcount;
2489 HWND window;
2490 HRESULT hr;
2492 static const struct
2494 struct vec3 position;
2495 DWORD diffuse;
2497 quad1[] =
2499 {{-1.0f, -1.0f, 0.1f}, 0x4000ff00},
2500 {{-1.0f, 0.0f, 0.1f}, 0x4000ff00},
2501 {{ 1.0f, -1.0f, 0.1f}, 0x4000ff00},
2502 {{ 1.0f, 0.0f, 0.1f}, 0x4000ff00},
2504 quad2[] =
2506 {{-1.0f, 0.0f, 0.1f}, 0xc00000ff},
2507 {{-1.0f, 1.0f, 0.1f}, 0xc00000ff},
2508 {{ 1.0f, 0.0f, 0.1f}, 0xc00000ff},
2509 {{ 1.0f, 1.0f, 0.1f}, 0xc00000ff},
2511 static const float composite_quad[][5] =
2513 { 0.0f, -1.0f, 0.1f, 0.0f, 1.0f},
2514 { 0.0f, 1.0f, 0.1f, 0.0f, 0.0f},
2515 { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f},
2516 { 1.0f, 1.0f, 0.1f, 1.0f, 0.0f},
2519 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
2520 0, 0, 640, 480, NULL, NULL, NULL, NULL);
2521 d3d = Direct3DCreate8(D3D_SDK_VERSION);
2522 ok(!!d3d, "Failed to create a D3D object.\n");
2523 if (!(device = create_device(d3d, window, window, TRUE)))
2525 skip("Failed to create a D3D device, skipping tests.\n");
2526 goto done;
2529 /* Clear the render target with alpha = 0.5 */
2530 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x80ff0000, 1.0f, 0);
2531 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
2533 hr = IDirect3DDevice8_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET,
2534 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture);
2535 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
2537 hr = IDirect3DDevice8_GetDepthStencilSurface(device, &depthstencil);
2538 ok(SUCCEEDED(hr), "Failed to get depth/stencil buffer, hr %#x.\n", hr);
2539 hr = IDirect3DDevice8_GetBackBuffer(device, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
2540 ok(SUCCEEDED(hr), "Failed to get back buffer, hr %#x.\n", hr);
2542 hr = IDirect3DTexture8_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
2543 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %#08x\n", hr);
2545 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
2546 ok(hr == D3D_OK, "SetVertexShader failed, hr = %#08x\n", hr);
2548 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
2549 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %#08x\n", hr);
2550 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
2551 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %#08x\n", hr);
2552 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MINFILTER, D3DTEXF_NONE);
2553 ok(SUCCEEDED(hr), "SetTextureStageState D3DSAMP_MINFILTER failed (%#08x)\n", hr);
2554 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MAGFILTER, D3DTEXF_NONE);
2555 ok(SUCCEEDED(hr), "SetTextureStageState D3DSAMP_MAGFILTER failed (%#08x)\n", hr);
2556 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
2557 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %08x\n", hr);
2559 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
2560 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
2561 hr = IDirect3DDevice8_BeginScene(device);
2562 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
2564 /* Draw two quads, one with src alpha blending, one with dest alpha blending. */
2565 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
2566 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
2567 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
2568 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
2569 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
2570 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2572 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
2573 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
2574 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
2575 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
2576 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
2577 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2579 /* Switch to the offscreen buffer, and redo the testing. The offscreen
2580 * render target doesn't have an alpha channel. DESTALPHA and INVDESTALPHA
2581 * "don't work" on render targets without alpha channel, they give
2582 * essentially ZERO and ONE blend factors. */
2583 hr = IDirect3DDevice8_SetRenderTarget(device, offscreen, 0);
2584 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
2585 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
2586 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
2588 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
2589 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
2590 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
2591 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
2592 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
2593 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2595 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
2596 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
2597 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
2598 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
2599 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
2600 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2602 hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, depthstencil);
2603 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
2605 /* Render the offscreen texture onto the frame buffer to be able to
2606 * compare it regularly. Disable alpha blending for the final
2607 * composition. */
2608 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
2609 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
2610 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX1);
2611 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
2613 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *) offscreenTexture);
2614 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
2615 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, composite_quad, sizeof(float) * 5);
2616 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2618 hr = IDirect3DDevice8_EndScene(device);
2619 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
2621 color = getPixelColor(device, 160, 360);
2622 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
2623 "SRCALPHA on frame buffer returned color %08x, expected 0x00bf4000\n", color);
2625 color = getPixelColor(device, 160, 120);
2626 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x00, 0x80), 2),
2627 "DSTALPHA on frame buffer returned color %08x, expected 0x007f0080\n", color);
2629 color = getPixelColor(device, 480, 360);
2630 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
2631 "SRCALPHA on texture returned color %08x, expected 0x00bf4000\n", color);
2633 color = getPixelColor(device, 480, 120);
2634 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
2635 "DSTALPHA on texture returned color %08x, expected 0x000000ff\n", color);
2637 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
2639 IDirect3DSurface8_Release(backbuffer);
2640 IDirect3DTexture8_Release(offscreenTexture);
2641 IDirect3DSurface8_Release(offscreen);
2642 IDirect3DSurface8_Release(depthstencil);
2643 refcount = IDirect3DDevice8_Release(device);
2644 ok(!refcount, "Device has %u references left.\n", refcount);
2645 done:
2646 IDirect3D8_Release(d3d);
2647 DestroyWindow(window);
2650 static void p8_texture_test(void)
2652 IDirect3DTexture8 *texture, *texture2;
2653 IDirect3DDevice8 *device;
2654 PALETTEENTRY table[256];
2655 unsigned char *data;
2656 D3DLOCKED_RECT lr;
2657 IDirect3D8 *d3d;
2658 D3DCOLOR color;
2659 ULONG refcount;
2660 D3DCAPS8 caps;
2661 HWND window;
2662 HRESULT hr;
2663 UINT i;
2665 static const float quad[] =
2667 -1.0f, 0.0f, 0.1f, 0.0f, 0.0f,
2668 -1.0f, 1.0f, 0.1f, 0.0f, 1.0f,
2669 1.0f, 0.0f, 0.1f, 1.0f, 0.0f,
2670 1.0f, 1.0f, 0.1f, 1.0f, 1.0f,
2672 static const float quad2[] =
2674 -1.0f, -1.0f, 0.1f, 0.0f, 0.0f,
2675 -1.0f, 0.0f, 0.1f, 0.0f, 1.0f,
2676 1.0f, -1.0f, 0.1f, 1.0f, 0.0f,
2677 1.0f, 0.0f, 0.1f, 1.0f, 1.0f,
2680 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
2681 0, 0, 640, 480, NULL, NULL, NULL, NULL);
2682 d3d = Direct3DCreate8(D3D_SDK_VERSION);
2683 ok(!!d3d, "Failed to create a D3D object.\n");
2684 if (!(device = create_device(d3d, window, window, TRUE)))
2686 skip("Failed to create a D3D device, skipping tests.\n");
2687 goto done;
2690 if (IDirect3D8_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
2691 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_P8) != D3D_OK)
2693 skip("D3DFMT_P8 textures not supported.\n");
2694 IDirect3DDevice8_Release(device);
2695 goto done;
2698 hr = IDirect3DDevice8_CreateTexture(device, 1, 1, 1, 0, D3DFMT_P8, D3DPOOL_MANAGED, &texture2);
2699 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
2700 memset(&lr, 0, sizeof(lr));
2701 hr = IDirect3DTexture8_LockRect(texture2, 0, &lr, NULL, 0);
2702 ok(hr == D3D_OK, "IDirect3DTexture8_LockRect failed, hr = %08x\n", hr);
2703 data = lr.pBits;
2704 *data = 1;
2705 hr = IDirect3DTexture8_UnlockRect(texture2, 0);
2706 ok(hr == D3D_OK, "IDirect3DTexture8_UnlockRect failed, hr = %08x\n", hr);
2708 hr = IDirect3DDevice8_CreateTexture(device, 1, 1, 1, 0, D3DFMT_P8, D3DPOOL_MANAGED, &texture);
2709 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
2710 memset(&lr, 0, sizeof(lr));
2711 hr = IDirect3DTexture8_LockRect(texture, 0, &lr, NULL, 0);
2712 ok(hr == D3D_OK, "IDirect3DTexture8_LockRect failed, hr = %08x\n", hr);
2713 data = lr.pBits;
2714 *data = 1;
2715 hr = IDirect3DTexture8_UnlockRect(texture, 0);
2716 ok(hr == D3D_OK, "IDirect3DTexture8_UnlockRect failed, hr = %08x\n", hr);
2718 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff000000, 1.0f, 0);
2719 ok(hr == D3D_OK, "IDirect3DDevice8_Clear failed, hr = %08x\n", hr);
2721 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
2722 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
2723 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
2724 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
2726 /* The first part of the test should work both with and without D3DPTEXTURECAPS_ALPHAPALETTE;
2727 alpha of every entry is set to 1.0, which MS says is required when there's no
2728 D3DPTEXTURECAPS_ALPHAPALETTE capability */
2729 for (i = 0; i < 256; i++) {
2730 table[i].peRed = table[i].peGreen = table[i].peBlue = 0;
2731 table[i].peFlags = 0xff;
2733 table[1].peRed = 0xff;
2734 hr = IDirect3DDevice8_SetPaletteEntries(device, 0, table);
2735 ok(hr == D3D_OK, "IDirect3DDevice8_SetPaletteEntries failed, hr = %08x\n", hr);
2737 table[1].peRed = 0;
2738 table[1].peBlue = 0xff;
2739 hr = IDirect3DDevice8_SetPaletteEntries(device, 1, table);
2740 ok(hr == D3D_OK, "IDirect3DDevice8_SetPaletteEntries failed, hr = %08x\n", hr);
2742 hr = IDirect3DDevice8_BeginScene(device);
2743 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
2745 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
2746 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
2747 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
2748 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
2749 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX1);
2750 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
2751 hr = IDirect3DDevice8_SetCurrentTexturePalette(device, 0);
2752 ok(SUCCEEDED(hr), "Failed to set texture palette, hr %#x.\n", hr);
2753 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture2);
2754 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
2755 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
2756 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2758 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
2759 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
2760 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
2761 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2763 hr = IDirect3DDevice8_SetCurrentTexturePalette(device, 1);
2764 ok(SUCCEEDED(hr), "Failed to set texture palette, hr %#x.\n", hr);
2765 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
2766 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2768 hr = IDirect3DDevice8_EndScene(device);
2769 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
2771 color = getPixelColor(device, 32, 32);
2772 ok(color_match(color, 0x00ff0000, 0), "Got unexpected color 0x%08x.\n", color);
2773 color = getPixelColor(device, 32, 320);
2774 ok(color_match(color, 0x000000ff, 0), "Got unexpected color 0x%08x.\n", color);
2776 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
2777 ok(hr == D3D_OK, "IDirect3DDevice8_Present failed, hr = %08x\n", hr);
2779 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
2780 ok(hr == D3D_OK, "IDirect3DDevice8_Clear failed, hr = %08x\n", hr);
2782 hr = IDirect3DDevice8_BeginScene(device);
2783 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
2784 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture2);
2785 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
2786 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
2787 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2788 hr = IDirect3DDevice8_EndScene(device);
2789 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
2791 color = getPixelColor(device, 32, 32);
2792 ok(color_match(color, 0x000000ff, 0), "Got unexpected color 0x%08x.\n", color);
2794 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
2795 ok(hr == D3D_OK, "IDirect3DDevice8_Present failed, hr = %08x\n", hr);
2797 /* Test palettes with alpha */
2798 IDirect3DDevice8_GetDeviceCaps(device, &caps);
2799 if (!(caps.TextureCaps & D3DPTEXTURECAPS_ALPHAPALETTE)) {
2800 skip("no D3DPTEXTURECAPS_ALPHAPALETTE capability, tests with alpha in palette will be skipped\n");
2801 } else {
2802 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
2803 ok(hr == D3D_OK, "IDirect3DDevice8_Clear failed, hr = %08x\n", hr);
2805 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
2806 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
2808 for (i = 0; i < 256; i++) {
2809 table[i].peRed = table[i].peGreen = table[i].peBlue = 0;
2810 table[i].peFlags = 0xff;
2812 table[1].peRed = 0xff;
2813 table[1].peFlags = 0x80;
2814 hr = IDirect3DDevice8_SetPaletteEntries(device, 0, table);
2815 ok(hr == D3D_OK, "IDirect3DDevice8_SetPaletteEntries failed, hr = %08x\n", hr);
2817 table[1].peRed = 0;
2818 table[1].peBlue = 0xff;
2819 table[1].peFlags = 0x80;
2820 hr = IDirect3DDevice8_SetPaletteEntries(device, 1, table);
2821 ok(hr == D3D_OK, "IDirect3DDevice8_SetPaletteEntries failed, hr = %08x\n", hr);
2823 hr = IDirect3DDevice8_BeginScene(device);
2824 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
2826 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
2827 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
2828 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
2829 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
2830 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX1);
2831 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
2833 hr = IDirect3DDevice8_SetCurrentTexturePalette(device, 0);
2834 ok(SUCCEEDED(hr), "Failed to set texture palette, hr %#x.\n", hr);
2835 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
2836 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2838 hr = IDirect3DDevice8_SetCurrentTexturePalette(device, 1);
2839 ok(SUCCEEDED(hr), "Failed to set texture palette, hr %#x.\n", hr);
2840 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
2841 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2843 hr = IDirect3DDevice8_EndScene(device);
2844 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
2846 color = getPixelColor(device, 32, 32);
2847 ok(color_match(color, 0x00800000, 1), "Got unexpected color 0x%08x.\n", color);
2848 color = getPixelColor(device, 32, 320);
2849 ok(color_match(color, 0x00000080, 1), "Got unexpected color 0x%08x.\n", color);
2851 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
2852 ok(hr == D3D_OK, "IDirect3DDevice8_Present failed, hr = %08x\n", hr);
2855 IDirect3DTexture8_Release(texture);
2856 IDirect3DTexture8_Release(texture2);
2857 refcount = IDirect3DDevice8_Release(device);
2858 ok(!refcount, "Device has %u references left.\n", refcount);
2859 done:
2860 IDirect3D8_Release(d3d);
2861 DestroyWindow(window);
2864 static void texop_test(void)
2866 IDirect3DTexture8 *texture;
2867 D3DLOCKED_RECT locked_rect;
2868 IDirect3DDevice8 *device;
2869 IDirect3D8 *d3d;
2870 unsigned int i;
2871 D3DCOLOR color;
2872 ULONG refcount;
2873 D3DCAPS8 caps;
2874 HWND window;
2875 HRESULT hr;
2877 static const struct {
2878 float x, y, z;
2879 D3DCOLOR diffuse;
2880 float s, t;
2881 } quad[] = {
2882 {-1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00), -1.0f, -1.0f},
2883 {-1.0f, 1.0f, 0.1f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00), -1.0f, 1.0f},
2884 { 1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00), 1.0f, -1.0f},
2885 { 1.0f, 1.0f, 0.1f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00), 1.0f, 1.0f}
2888 static const struct {
2889 D3DTEXTUREOP op;
2890 const char *name;
2891 DWORD caps_flag;
2892 D3DCOLOR result;
2893 } test_data[] = {
2894 {D3DTOP_SELECTARG1, "SELECTARG1", D3DTEXOPCAPS_SELECTARG1, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
2895 {D3DTOP_SELECTARG2, "SELECTARG2", D3DTEXOPCAPS_SELECTARG2, D3DCOLOR_ARGB(0x00, 0x33, 0x33, 0x33)},
2896 {D3DTOP_MODULATE, "MODULATE", D3DTEXOPCAPS_MODULATE, D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x00)},
2897 {D3DTOP_MODULATE2X, "MODULATE2X", D3DTEXOPCAPS_MODULATE2X, D3DCOLOR_ARGB(0x00, 0x00, 0x66, 0x00)},
2898 {D3DTOP_MODULATE4X, "MODULATE4X", D3DTEXOPCAPS_MODULATE4X, D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
2899 {D3DTOP_ADD, "ADD", D3DTEXOPCAPS_ADD, D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
2901 {D3DTOP_ADDSIGNED, "ADDSIGNED", D3DTEXOPCAPS_ADDSIGNED, D3DCOLOR_ARGB(0x00, 0x00, 0xb2, 0x00)},
2902 {D3DTOP_ADDSIGNED2X, "ADDSIGNED2X", D3DTEXOPCAPS_ADDSIGNED2X, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
2904 {D3DTOP_SUBTRACT, "SUBTRACT", D3DTEXOPCAPS_SUBTRACT, D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
2905 {D3DTOP_ADDSMOOTH, "ADDSMOOTH", D3DTEXOPCAPS_ADDSMOOTH, D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
2906 {D3DTOP_BLENDDIFFUSEALPHA, "BLENDDIFFUSEALPHA", D3DTEXOPCAPS_BLENDDIFFUSEALPHA, D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
2907 {D3DTOP_BLENDTEXTUREALPHA, "BLENDTEXTUREALPHA", D3DTEXOPCAPS_BLENDTEXTUREALPHA, D3DCOLOR_ARGB(0x00, 0x14, 0xad, 0x14)},
2908 {D3DTOP_BLENDFACTORALPHA, "BLENDFACTORALPHA", D3DTEXOPCAPS_BLENDFACTORALPHA, D3DCOLOR_ARGB(0x00, 0x07, 0xe4, 0x07)},
2909 {D3DTOP_BLENDTEXTUREALPHAPM, "BLENDTEXTUREALPHAPM", D3DTEXOPCAPS_BLENDTEXTUREALPHAPM, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
2910 {D3DTOP_BLENDCURRENTALPHA, "BLENDCURRENTALPHA", D3DTEXOPCAPS_BLENDCURRENTALPHA, D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
2911 {D3DTOP_MODULATEALPHA_ADDCOLOR, "MODULATEALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x1f, 0xff, 0x1f)},
2912 {D3DTOP_MODULATECOLOR_ADDALPHA, "MODULATECOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0x99, 0xcc, 0x99)},
2913 {D3DTOP_MODULATEINVALPHA_ADDCOLOR, "MODULATEINVALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
2914 {D3DTOP_MODULATEINVCOLOR_ADDALPHA, "MODULATEINVCOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0xcc, 0x99, 0xcc)},
2915 /* BUMPENVMAP & BUMPENVMAPLUMINANCE have their own tests */
2916 {D3DTOP_DOTPRODUCT3, "DOTPRODUCT2", D3DTEXOPCAPS_DOTPRODUCT3, D3DCOLOR_ARGB(0x00, 0x99, 0x99, 0x99)},
2917 {D3DTOP_MULTIPLYADD, "MULTIPLYADD", D3DTEXOPCAPS_MULTIPLYADD, D3DCOLOR_ARGB(0x00, 0xff, 0x33, 0x00)},
2918 {D3DTOP_LERP, "LERP", D3DTEXOPCAPS_LERP, D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x33)},
2921 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
2922 0, 0, 640, 480, NULL, NULL, NULL, NULL);
2923 d3d = Direct3DCreate8(D3D_SDK_VERSION);
2924 ok(!!d3d, "Failed to create a D3D object.\n");
2925 if (!(device = create_device(d3d, window, window, TRUE)))
2927 skip("Failed to create a D3D device, skipping tests.\n");
2928 goto done;
2931 memset(&caps, 0, sizeof(caps));
2932 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
2933 ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
2935 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX0);
2936 ok(SUCCEEDED(hr), "SetVertexShader failed with 0x%08x\n", hr);
2938 hr = IDirect3DDevice8_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture);
2939 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
2940 hr = IDirect3DTexture8_LockRect(texture, 0, &locked_rect, NULL, 0);
2941 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
2942 *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x99, 0x00, 0xff, 0x00);
2943 hr = IDirect3DTexture8_UnlockRect(texture, 0);
2944 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
2945 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
2946 ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
2948 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG0, D3DTA_DIFFUSE);
2949 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
2950 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
2951 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
2952 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
2953 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
2955 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
2956 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
2958 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
2959 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
2960 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xdd333333);
2961 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
2962 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_ALPHA);
2963 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
2965 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
2966 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
2968 for (i = 0; i < sizeof(test_data) / sizeof(*test_data); ++i)
2970 if (!(caps.TextureOpCaps & test_data[i].caps_flag))
2972 skip("tex operation %s not supported\n", test_data[i].name);
2973 continue;
2976 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLOROP, test_data[i].op);
2977 ok(SUCCEEDED(hr), "SetTextureStageState (%s) failed with 0x%08x\n", test_data[i].name, hr);
2979 hr = IDirect3DDevice8_BeginScene(device);
2980 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
2982 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
2983 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
2985 hr = IDirect3DDevice8_EndScene(device);
2986 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
2988 color = getPixelColor(device, 320, 240);
2989 ok(color_match(color, test_data[i].result, 3), "Operation %s returned color 0x%08x, expected 0x%08x\n",
2990 test_data[i].name, color, test_data[i].result);
2992 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
2993 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
2995 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
2996 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
2999 IDirect3DTexture8_Release(texture);
3000 refcount = IDirect3DDevice8_Release(device);
3001 ok(!refcount, "Device has %u references left.\n", refcount);
3002 done:
3003 IDirect3D8_Release(d3d);
3004 DestroyWindow(window);
3007 /* This test tests depth clamping / clipping behaviour:
3008 * - With software vertex processing, depth values are clamped to the
3009 * minimum / maximum z value when D3DRS_CLIPPING is disabled, and clipped
3010 * when D3DRS_CLIPPING is enabled. Pretransformed vertices behave the
3011 * same as regular vertices here.
3012 * - With hardware vertex processing, D3DRS_CLIPPING seems to be ignored.
3013 * Normal vertices are always clipped. Pretransformed vertices are
3014 * clipped when D3DPMISCCAPS_CLIPTLVERTS is set, clamped when it isn't.
3015 * - The viewport's MinZ/MaxZ is irrelevant for this.
3017 static void depth_clamp_test(void)
3019 IDirect3DDevice8 *device;
3020 D3DVIEWPORT8 vp;
3021 IDirect3D8 *d3d;
3022 D3DCOLOR color;
3023 ULONG refcount;
3024 D3DCAPS8 caps;
3025 HWND window;
3026 HRESULT hr;
3028 static const struct
3030 struct vec4 position;
3031 DWORD diffuse;
3033 quad1[] =
3035 {{ 0.0f, 0.0f, 5.0f, 1.0f}, 0xff002b7f},
3036 {{640.0f, 0.0f, 5.0f, 1.0f}, 0xff002b7f},
3037 {{ 0.0f, 480.0f, 5.0f, 1.0f}, 0xff002b7f},
3038 {{640.0f, 480.0f, 5.0f, 1.0f}, 0xff002b7f},
3040 quad2[] =
3042 {{ 0.0f, 300.0f, 10.0f, 1.0f}, 0xfff9e814},
3043 {{640.0f, 300.0f, 10.0f, 1.0f}, 0xfff9e814},
3044 {{ 0.0f, 360.0f, 10.0f, 1.0f}, 0xfff9e814},
3045 {{640.0f, 360.0f, 10.0f, 1.0f}, 0xfff9e814},
3047 quad3[] =
3049 {{112.0f, 108.0f, 5.0f, 1.0f}, 0xffffffff},
3050 {{208.0f, 108.0f, 5.0f, 1.0f}, 0xffffffff},
3051 {{112.0f, 204.0f, 5.0f, 1.0f}, 0xffffffff},
3052 {{208.0f, 204.0f, 5.0f, 1.0f}, 0xffffffff},
3054 quad4[] =
3056 {{ 42.0f, 41.0f, 10.0f, 1.0f}, 0xffffffff},
3057 {{112.0f, 41.0f, 10.0f, 1.0f}, 0xffffffff},
3058 {{ 42.0f, 108.0f, 10.0f, 1.0f}, 0xffffffff},
3059 {{112.0f, 108.0f, 10.0f, 1.0f}, 0xffffffff},
3061 static const struct
3063 struct vec3 position;
3064 DWORD diffuse;
3066 quad5[] =
3068 {{-0.5f, 0.5f, 10.0f}, 0xff14f914},
3069 {{ 0.5f, 0.5f, 10.0f}, 0xff14f914},
3070 {{-0.5f, -0.5f, 10.0f}, 0xff14f914},
3071 {{ 0.5f, -0.5f, 10.0f}, 0xff14f914},
3073 quad6[] =
3075 {{-1.0f, 0.5f, 10.0f}, 0xfff91414},
3076 {{ 1.0f, 0.5f, 10.0f}, 0xfff91414},
3077 {{-1.0f, 0.25f, 10.0f}, 0xfff91414},
3078 {{ 1.0f, 0.25f, 10.0f}, 0xfff91414},
3081 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
3082 0, 0, 640, 480, NULL, NULL, NULL, NULL);
3083 d3d = Direct3DCreate8(D3D_SDK_VERSION);
3084 ok(!!d3d, "Failed to create a D3D object.\n");
3085 if (!(device = create_device(d3d, window, window, TRUE)))
3087 skip("Failed to create a D3D device, skipping tests.\n");
3088 goto done;
3091 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
3092 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
3094 vp.X = 0;
3095 vp.Y = 0;
3096 vp.Width = 640;
3097 vp.Height = 480;
3098 vp.MinZ = 0.0;
3099 vp.MaxZ = 7.5;
3101 hr = IDirect3DDevice8_SetViewport(device, &vp);
3102 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
3104 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0, 0);
3105 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
3107 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, FALSE);
3108 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3109 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3110 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3111 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
3112 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3113 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
3114 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3116 hr = IDirect3DDevice8_BeginScene(device);
3117 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
3119 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
3120 ok(SUCCEEDED(hr), "SetVertexSahder failed, hr %#x.\n", hr);
3122 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
3123 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3124 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
3125 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3127 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, TRUE);
3128 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3130 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
3131 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3132 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(*quad4));
3133 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3135 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, FALSE);
3136 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3137 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
3138 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
3140 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad5, sizeof(*quad5));
3141 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3143 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, TRUE);
3144 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3146 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad6, sizeof(*quad6));
3147 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3149 hr = IDirect3DDevice8_EndScene(device);
3150 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
3152 if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
3154 color = getPixelColor(device, 75, 75);
3155 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
3156 color = getPixelColor(device, 150, 150);
3157 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
3158 color = getPixelColor(device, 320, 240);
3159 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
3160 color = getPixelColor(device, 320, 330);
3161 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
3162 color = getPixelColor(device, 320, 330);
3163 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
3165 else
3167 color = getPixelColor(device, 75, 75);
3168 ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
3169 color = getPixelColor(device, 150, 150);
3170 ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
3171 color = getPixelColor(device, 320, 240);
3172 ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);
3173 color = getPixelColor(device, 320, 330);
3174 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
3175 color = getPixelColor(device, 320, 330);
3176 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
3179 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
3180 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3182 refcount = IDirect3DDevice8_Release(device);
3183 ok(!refcount, "Device has %u references left.\n", refcount);
3184 done:
3185 IDirect3D8_Release(d3d);
3186 DestroyWindow(window);
3189 static void depth_buffer_test(void)
3191 IDirect3DSurface8 *backbuffer, *rt1, *rt2, *rt3;
3192 IDirect3DSurface8 *depth_stencil;
3193 IDirect3DDevice8 *device;
3194 unsigned int i, j;
3195 D3DVIEWPORT8 vp;
3196 IDirect3D8 *d3d;
3197 D3DCOLOR color;
3198 ULONG refcount;
3199 HWND window;
3200 HRESULT hr;
3202 static const struct
3204 struct vec3 position;
3205 DWORD diffuse;
3207 quad1[] =
3209 {{-1.0f, 1.0f, 0.33f}, 0xff00ff00},
3210 {{ 1.0f, 1.0f, 0.33f}, 0xff00ff00},
3211 {{-1.0f, -1.0f, 0.33f}, 0xff00ff00},
3212 {{ 1.0f, -1.0f, 0.33f}, 0xff00ff00},
3214 quad2[] =
3216 {{-1.0f, 1.0f, 0.50f}, 0xffff00ff},
3217 {{ 1.0f, 1.0f, 0.50f}, 0xffff00ff},
3218 {{-1.0f, -1.0f, 0.50f}, 0xffff00ff},
3219 {{ 1.0f, -1.0f, 0.50f}, 0xffff00ff},
3221 quad3[] =
3223 {{-1.0f, 1.0f, 0.66f}, 0xffff0000},
3224 {{ 1.0f, 1.0f, 0.66f}, 0xffff0000},
3225 {{-1.0f, -1.0f, 0.66f}, 0xffff0000},
3226 {{ 1.0f, -1.0f, 0.66f}, 0xffff0000},
3228 static const DWORD expected_colors[4][4] =
3230 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
3231 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
3232 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x00ff0000},
3233 {0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
3236 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
3237 0, 0, 640, 480, NULL, NULL, NULL, NULL);
3238 d3d = Direct3DCreate8(D3D_SDK_VERSION);
3239 ok(!!d3d, "Failed to create a D3D object.\n");
3240 if (!(device = create_device(d3d, window, window, TRUE)))
3242 skip("Failed to create a D3D device, skipping tests.\n");
3243 goto done;
3246 vp.X = 0;
3247 vp.Y = 0;
3248 vp.Width = 640;
3249 vp.Height = 480;
3250 vp.MinZ = 0.0;
3251 vp.MaxZ = 1.0;
3253 hr = IDirect3DDevice8_SetViewport(device, &vp);
3254 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
3256 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3257 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3258 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
3259 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3260 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
3261 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3262 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
3263 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3264 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
3265 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
3267 hr = IDirect3DDevice8_GetDepthStencilSurface(device, &depth_stencil);
3268 ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
3269 hr = IDirect3DDevice8_GetRenderTarget(device, &backbuffer);
3270 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
3271 hr = IDirect3DDevice8_CreateRenderTarget(device, 320, 240, D3DFMT_A8R8G8B8,
3272 D3DMULTISAMPLE_NONE, FALSE, &rt1);
3273 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
3274 hr = IDirect3DDevice8_CreateRenderTarget(device, 480, 360, D3DFMT_A8R8G8B8,
3275 D3DMULTISAMPLE_NONE, FALSE, &rt2);
3276 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
3277 hr = IDirect3DDevice8_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
3278 D3DMULTISAMPLE_NONE, FALSE, &rt3);
3279 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
3281 hr = IDirect3DDevice8_SetRenderTarget(device, rt3, depth_stencil);
3282 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
3283 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0f, 0);
3284 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
3286 hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, depth_stencil);
3287 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
3288 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
3289 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
3291 hr = IDirect3DDevice8_SetRenderTarget(device, rt1, depth_stencil);
3292 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
3293 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0f, 0);
3294 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
3296 hr = IDirect3DDevice8_SetRenderTarget(device, rt2, depth_stencil);
3297 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
3298 hr = IDirect3DDevice8_BeginScene(device);
3299 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
3300 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
3301 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3302 hr = IDirect3DDevice8_EndScene(device);
3303 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
3305 hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, depth_stencil);
3306 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
3308 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
3309 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3311 hr = IDirect3DDevice8_BeginScene(device);
3312 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
3313 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
3314 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3315 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
3316 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3317 hr = IDirect3DDevice8_EndScene(device);
3318 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
3320 for (i = 0; i < 4; ++i)
3322 for (j = 0; j < 4; ++j)
3324 unsigned int x = 80 * ((2 * j) + 1);
3325 unsigned int y = 60 * ((2 * i) + 1);
3326 color = getPixelColor(device, x, y);
3327 ok(color_match(color, expected_colors[i][j], 0),
3328 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors[i][j], x, y, color);
3332 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
3333 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3335 IDirect3DSurface8_Release(depth_stencil);
3336 IDirect3DSurface8_Release(backbuffer);
3337 IDirect3DSurface8_Release(rt3);
3338 IDirect3DSurface8_Release(rt2);
3339 IDirect3DSurface8_Release(rt1);
3340 refcount = IDirect3DDevice8_Release(device);
3341 ok(!refcount, "Device has %u references left.\n", refcount);
3342 done:
3343 IDirect3D8_Release(d3d);
3344 DestroyWindow(window);
3347 /* Test that partial depth copies work the way they're supposed to. The clear
3348 * on rt2 only needs a partial copy of the onscreen depth/stencil buffer, and
3349 * the following draw should only copy back the part that was modified. */
3350 static void depth_buffer2_test(void)
3352 IDirect3DSurface8 *backbuffer, *rt1, *rt2;
3353 IDirect3DSurface8 *depth_stencil;
3354 IDirect3DDevice8 *device;
3355 unsigned int i, j;
3356 D3DVIEWPORT8 vp;
3357 IDirect3D8 *d3d;
3358 D3DCOLOR color;
3359 ULONG refcount;
3360 HWND window;
3361 HRESULT hr;
3363 static const struct
3365 struct vec3 position;
3366 DWORD diffuse;
3368 quad[] =
3370 {{-1.0f, 1.0f, 0.66f}, 0xffff0000},
3371 {{ 1.0f, 1.0f, 0.66f}, 0xffff0000},
3372 {{-1.0f, -1.0f, 0.66f}, 0xffff0000},
3373 {{ 1.0f, -1.0f, 0.66f}, 0xffff0000},
3376 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
3377 0, 0, 640, 480, NULL, NULL, NULL, NULL);
3378 d3d = Direct3DCreate8(D3D_SDK_VERSION);
3379 ok(!!d3d, "Failed to create a D3D object.\n");
3380 if (!(device = create_device(d3d, window, window, TRUE)))
3382 skip("Failed to create a D3D device, skipping tests.\n");
3383 goto done;
3386 vp.X = 0;
3387 vp.Y = 0;
3388 vp.Width = 640;
3389 vp.Height = 480;
3390 vp.MinZ = 0.0;
3391 vp.MaxZ = 1.0;
3393 hr = IDirect3DDevice8_SetViewport(device, &vp);
3394 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
3396 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3397 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3398 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
3399 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3400 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
3401 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3402 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
3403 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3404 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
3405 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
3407 hr = IDirect3DDevice8_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
3408 D3DMULTISAMPLE_NONE, FALSE, &rt1);
3409 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
3410 hr = IDirect3DDevice8_CreateRenderTarget(device, 480, 360, D3DFMT_A8R8G8B8,
3411 D3DMULTISAMPLE_NONE, FALSE, &rt2);
3412 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
3413 hr = IDirect3DDevice8_GetDepthStencilSurface(device, &depth_stencil);
3414 ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
3415 hr = IDirect3DDevice8_GetRenderTarget(device, &backbuffer);
3416 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
3418 hr = IDirect3DDevice8_SetRenderTarget(device, rt1, depth_stencil);
3419 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
3420 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
3421 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
3423 hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, depth_stencil);
3424 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
3425 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 0.5f, 0);
3426 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
3428 hr = IDirect3DDevice8_SetRenderTarget(device, rt2, depth_stencil);
3429 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
3430 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0f, 0);
3431 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
3433 hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, depth_stencil);
3434 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
3436 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
3437 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3439 hr = IDirect3DDevice8_BeginScene(device);
3440 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
3441 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
3442 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3443 hr = IDirect3DDevice8_EndScene(device);
3444 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
3446 for (i = 0; i < 4; ++i)
3448 for (j = 0; j < 4; ++j)
3450 unsigned int x = 80 * ((2 * j) + 1);
3451 unsigned int y = 60 * ((2 * i) + 1);
3452 color = getPixelColor(device, x, y);
3453 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
3454 "Expected color 0x0000ff00 %u,%u, got 0x%08x.\n", x, y, color);
3458 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
3459 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3461 IDirect3DSurface8_Release(depth_stencil);
3462 IDirect3DSurface8_Release(backbuffer);
3463 IDirect3DSurface8_Release(rt2);
3464 IDirect3DSurface8_Release(rt1);
3465 refcount = IDirect3DDevice8_Release(device);
3466 ok(!refcount, "Device has %u references left.\n", refcount);
3467 done:
3468 IDirect3D8_Release(d3d);
3469 DestroyWindow(window);
3472 static void intz_test(void)
3474 IDirect3DSurface8 *original_rt, *rt;
3475 IDirect3DTexture8 *texture;
3476 IDirect3DDevice8 *device;
3477 IDirect3DSurface8 *ds;
3478 IDirect3D8 *d3d;
3479 ULONG refcount;
3480 D3DCAPS8 caps;
3481 HWND window;
3482 HRESULT hr;
3483 DWORD ps;
3484 UINT i;
3486 static const DWORD ps_code[] =
3488 0xffff0101, /* ps_1_1 */
3489 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1.0, 0.0, 0.0, 0.0 */
3490 0x00000051, 0xa00f0001, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c1, 0.0, 1.0, 0.0, 0.0 */
3491 0x00000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c2, 0.0, 0.0, 1.0, 0.0 */
3492 0x00000042, 0xb00f0000, /* tex t0 */
3493 0x00000042, 0xb00f0001, /* tex t1 */
3494 0x00000008, 0xb0070001, 0xa0e40000, 0xb0e40001, /* dp3 t1.xyz, c0, t1 */
3495 0x00000005, 0x80070000, 0xa0e40001, 0xb0e40001, /* mul r0.xyz, c1, t1 */
3496 0x00000004, 0x80070000, 0xa0e40000, 0xb0e40000, 0x80e40000, /* mad r0.xyz, c0, t0, r0 */
3497 0x40000001, 0x80080000, 0xa0aa0002, /* +mov r0.w, c2.z */
3498 0x0000ffff, /* end */
3500 static const struct
3502 float x, y, z;
3503 float s0, t0, p0;
3504 float s1, t1, p1, q1;
3506 quad[] =
3508 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.5f},
3509 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
3510 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
3511 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.5f},
3513 half_quad_1[] =
3515 { -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.5f},
3516 { 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
3517 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
3518 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.5f},
3520 half_quad_2[] =
3522 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.5f},
3523 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
3524 { -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
3525 { 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.5f},
3527 static const struct
3529 UINT x, y;
3530 D3DCOLOR color;
3532 expected_colors[] =
3534 { 80, 100, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
3535 {240, 100, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
3536 {400, 100, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
3537 {560, 100, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
3538 { 80, 450, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
3539 {240, 450, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
3540 {400, 450, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
3541 {560, 450, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
3544 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
3545 0, 0, 640, 480, NULL, NULL, NULL, NULL);
3546 d3d = Direct3DCreate8(D3D_SDK_VERSION);
3547 ok(!!d3d, "Failed to create a D3D object.\n");
3548 if (!(device = create_device(d3d, window, window, TRUE)))
3550 skip("Failed to create a D3D device, skipping tests.\n");
3551 goto done;
3554 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
3555 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
3556 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 1))
3558 skip("No pixel shader 1.1 support, skipping INTZ test.\n");
3559 IDirect3DDevice8_Release(device);
3560 goto done;
3562 if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
3564 skip("No unconditional NP2 texture support, skipping INTZ test.\n");
3565 IDirect3DDevice8_Release(device);
3566 goto done;
3569 if (FAILED(hr = IDirect3D8_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
3570 D3DFMT_X8R8G8B8, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, MAKEFOURCC('I','N','T','Z'))))
3572 skip("No INTZ support, skipping INTZ test.\n");
3573 IDirect3DDevice8_Release(device);
3574 goto done;
3577 hr = IDirect3DDevice8_GetRenderTarget(device, &original_rt);
3578 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
3580 hr = IDirect3DDevice8_CreateTexture(device, 640, 480, 1,
3581 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture);
3582 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
3583 hr = IDirect3DDevice8_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
3584 D3DMULTISAMPLE_NONE, FALSE, &rt);
3585 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
3586 hr = IDirect3DDevice8_CreatePixelShader(device, ps_code, &ps);
3587 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
3589 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX2
3590 | D3DFVF_TEXCOORDSIZE3(0) | D3DFVF_TEXCOORDSIZE4(1));
3591 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
3592 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
3593 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3594 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
3595 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3596 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
3597 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3598 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3599 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3601 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MINFILTER, D3DTEXF_POINT);
3602 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3603 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MIPFILTER, D3DTEXF_POINT);
3604 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3605 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MAGFILTER, D3DTEXF_POINT);
3606 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3607 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
3608 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3610 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP);
3611 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3612 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP);
3613 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3614 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MAGFILTER, D3DTEXF_POINT);
3615 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3616 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MINFILTER, D3DTEXF_POINT);
3617 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3618 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MIPFILTER, D3DTEXF_POINT);
3619 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3620 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS,
3621 D3DTTFF_COUNT4 | D3DTTFF_PROJECTED);
3622 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3624 hr = IDirect3DTexture8_GetSurfaceLevel(texture, 0, &ds);
3625 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
3627 /* Render offscreen, using the INTZ texture as depth buffer */
3628 hr = IDirect3DDevice8_SetRenderTarget(device, rt, ds);
3629 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
3630 hr = IDirect3DDevice8_SetPixelShader(device, 0);
3631 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
3633 /* Setup the depth/stencil surface. */
3634 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
3635 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
3637 hr = IDirect3DDevice8_BeginScene(device);
3638 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
3639 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
3640 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3641 hr = IDirect3DDevice8_EndScene(device);
3642 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
3644 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, NULL);
3645 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
3646 IDirect3DSurface8_Release(ds);
3647 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
3648 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
3649 hr = IDirect3DDevice8_SetTexture(device, 1, (IDirect3DBaseTexture8 *)texture);
3650 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
3651 hr = IDirect3DDevice8_SetPixelShader(device, ps);
3652 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
3654 /* Read the depth values back. */
3655 hr = IDirect3DDevice8_BeginScene(device);
3656 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
3657 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
3658 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3659 hr = IDirect3DDevice8_EndScene(device);
3660 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
3662 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
3664 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
3665 ok(color_match(color, expected_colors[i].color, 1),
3666 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
3667 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
3670 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
3671 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
3673 hr = IDirect3DDevice8_SetTexture(device, 0, NULL);
3674 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
3675 hr = IDirect3DDevice8_SetTexture(device, 1, NULL);
3676 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
3677 IDirect3DTexture8_Release(texture);
3679 /* Render onscreen while using the INTZ texture as depth buffer */
3680 hr = IDirect3DDevice8_CreateTexture(device, 640, 480, 1,
3681 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture);
3682 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
3683 hr = IDirect3DTexture8_GetSurfaceLevel(texture, 0, &ds);
3684 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
3685 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, ds);
3686 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
3687 hr = IDirect3DDevice8_SetPixelShader(device, 0);
3688 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
3690 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
3691 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
3693 hr = IDirect3DDevice8_BeginScene(device);
3694 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
3695 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
3696 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3697 hr = IDirect3DDevice8_EndScene(device);
3698 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
3700 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, NULL);
3701 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
3702 IDirect3DSurface8_Release(ds);
3703 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
3704 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
3705 hr = IDirect3DDevice8_SetTexture(device, 1, (IDirect3DBaseTexture8 *)texture);
3706 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
3707 hr = IDirect3DDevice8_SetPixelShader(device, ps);
3708 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
3710 /* Read the depth values back. */
3711 hr = IDirect3DDevice8_BeginScene(device);
3712 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
3713 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
3714 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3715 hr = IDirect3DDevice8_EndScene(device);
3716 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
3718 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
3720 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
3721 ok(color_match(color, expected_colors[i].color, 1),
3722 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
3723 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
3726 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
3727 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
3729 hr = IDirect3DDevice8_SetTexture(device, 0, NULL);
3730 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
3731 hr = IDirect3DDevice8_SetTexture(device, 1, NULL);
3732 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
3733 IDirect3DTexture8_Release(texture);
3735 /* Render offscreen, then onscreen, and finally check the INTZ texture in both areas */
3736 hr = IDirect3DDevice8_CreateTexture(device, 640, 480, 1,
3737 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture);
3738 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
3739 hr = IDirect3DTexture8_GetSurfaceLevel(texture, 0, &ds);
3740 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
3741 hr = IDirect3DDevice8_SetRenderTarget(device, rt, ds);
3742 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
3743 hr = IDirect3DDevice8_SetPixelShader(device, 0);
3744 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
3746 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
3747 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
3749 hr = IDirect3DDevice8_BeginScene(device);
3750 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
3751 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, half_quad_1, sizeof(*half_quad_1));
3752 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3753 hr = IDirect3DDevice8_EndScene(device);
3754 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
3756 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, ds);
3757 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
3759 hr = IDirect3DDevice8_BeginScene(device);
3760 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
3761 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, half_quad_2, sizeof(*half_quad_2));
3762 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3763 hr = IDirect3DDevice8_EndScene(device);
3764 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
3766 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, NULL);
3767 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
3768 IDirect3DSurface8_Release(ds);
3769 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
3770 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
3771 hr = IDirect3DDevice8_SetTexture(device, 1, (IDirect3DBaseTexture8 *)texture);
3772 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
3773 hr = IDirect3DDevice8_SetPixelShader(device, ps);
3774 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
3776 /* Read the depth values back. */
3777 hr = IDirect3DDevice8_BeginScene(device);
3778 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
3779 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
3780 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3781 hr = IDirect3DDevice8_EndScene(device);
3782 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
3784 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
3786 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
3787 ok(color_match(color, expected_colors[i].color, 1),
3788 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
3789 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
3792 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
3793 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
3795 IDirect3DTexture8_Release(texture);
3796 hr = IDirect3DDevice8_DeletePixelShader(device, ps);
3797 ok(SUCCEEDED(hr), "DeletePixelShader failed, hr %#x.\n", hr);
3798 IDirect3DSurface8_Release(original_rt);
3799 IDirect3DSurface8_Release(rt);
3800 refcount = IDirect3DDevice8_Release(device);
3801 ok(!refcount, "Device has %u references left.\n", refcount);
3802 done:
3803 IDirect3D8_Release(d3d);
3804 DestroyWindow(window);
3807 static void shadow_test(void)
3809 IDirect3DSurface8 *original_rt, *rt;
3810 IDirect3DDevice8 *device;
3811 IDirect3D8 *d3d;
3812 ULONG refcount;
3813 D3DCAPS8 caps;
3814 HWND window;
3815 HRESULT hr;
3816 DWORD ps;
3817 UINT i;
3819 static const DWORD ps_code[] =
3821 0xffff0101, /* ps_1_1 */
3822 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1.0, 0.0, 0.0, 0.0 */
3823 0x00000051, 0xa00f0001, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c1, 0.0, 1.0, 0.0, 0.0 */
3824 0x00000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c2, 0.0, 0.0, 1.0, 0.0 */
3825 0x00000042, 0xb00f0000, /* tex t0 */
3826 0x00000042, 0xb00f0001, /* tex t1 */
3827 0x00000008, 0xb0070001, 0xa0e40000, 0xb0e40001, /* dp3 t1.xyz, c0, t1 */
3828 0x00000005, 0x80070000, 0xa0e40001, 0xb0e40001, /* mul r0.xyz, c1, t1 */
3829 0x00000004, 0x80070000, 0xa0e40000, 0xb0e40000, 0x80e40000, /* mad r0.xyz, c0, t0, r0 */
3830 0x40000001, 0x80080000, 0xa0aa0002, /* +mov r0.w, c2.z */
3831 0x0000ffff, /* end */
3833 static const struct
3835 D3DFORMAT format;
3836 const char *name;
3838 formats[] =
3840 {D3DFMT_D16_LOCKABLE, "D3DFMT_D16_LOCKABLE"},
3841 {D3DFMT_D32, "D3DFMT_D32"},
3842 {D3DFMT_D15S1, "D3DFMT_D15S1"},
3843 {D3DFMT_D24S8, "D3DFMT_D24S8"},
3844 {D3DFMT_D24X8, "D3DFMT_D24X8"},
3845 {D3DFMT_D24X4S4, "D3DFMT_D24X4S4"},
3846 {D3DFMT_D16, "D3DFMT_D16"},
3848 static const struct
3850 float x, y, z;
3851 float s0, t0, p0;
3852 float s1, t1, p1, q1;
3854 quad[] =
3856 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f},
3857 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f},
3858 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
3859 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f},
3861 static const struct
3863 UINT x, y;
3864 D3DCOLOR color;
3866 expected_colors[] =
3868 {400, 60, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
3869 {560, 180, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
3870 {560, 300, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
3871 {400, 420, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
3872 {240, 420, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
3873 { 80, 300, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
3874 { 80, 180, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
3875 {240, 60, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
3878 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
3879 0, 0, 640, 480, NULL, NULL, NULL, NULL);
3880 d3d = Direct3DCreate8(D3D_SDK_VERSION);
3881 ok(!!d3d, "Failed to create a D3D object.\n");
3882 if (!(device = create_device(d3d, window, window, TRUE)))
3884 skip("Failed to create a D3D device, skipping tests.\n");
3885 goto done;
3888 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
3889 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
3890 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 1))
3892 skip("No pixel shader 1.1 support, skipping shadow test.\n");
3893 IDirect3DDevice8_Release(device);
3894 goto done;
3897 hr = IDirect3DDevice8_GetRenderTarget(device, &original_rt);
3898 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
3900 hr = IDirect3DDevice8_CreateRenderTarget(device, 1024, 1024, D3DFMT_A8R8G8B8,
3901 D3DMULTISAMPLE_NONE, FALSE, &rt);
3902 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
3903 hr = IDirect3DDevice8_CreatePixelShader(device, ps_code, &ps);
3904 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
3906 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX2
3907 | D3DFVF_TEXCOORDSIZE3(0) | D3DFVF_TEXCOORDSIZE4(1));
3908 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
3909 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
3910 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3911 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
3912 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3913 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
3914 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3915 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3916 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3918 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MINFILTER, D3DTEXF_POINT);
3919 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3920 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MIPFILTER, D3DTEXF_POINT);
3921 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3922 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MAGFILTER, D3DTEXF_POINT);
3923 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3924 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
3925 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3927 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP);
3928 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3929 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP);
3930 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3931 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MAGFILTER, D3DTEXF_POINT);
3932 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3933 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MINFILTER, D3DTEXF_POINT);
3934 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3935 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MIPFILTER, D3DTEXF_POINT);
3936 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3937 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS,
3938 D3DTTFF_COUNT4 | D3DTTFF_PROJECTED);
3939 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3941 for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
3943 D3DFORMAT format = formats[i].format;
3944 IDirect3DTexture8 *texture;
3945 IDirect3DSurface8 *ds;
3946 unsigned int j;
3948 if (FAILED(IDirect3D8_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
3949 D3DFMT_X8R8G8B8, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, format)))
3950 continue;
3952 hr = IDirect3DDevice8_CreateTexture(device, 1024, 1024, 1,
3953 D3DUSAGE_DEPTHSTENCIL, format, D3DPOOL_DEFAULT, &texture);
3954 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
3956 hr = IDirect3DTexture8_GetSurfaceLevel(texture, 0, &ds);
3957 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
3959 hr = IDirect3DDevice8_SetRenderTarget(device, rt, ds);
3960 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
3962 hr = IDirect3DDevice8_SetPixelShader(device, 0);
3963 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
3965 /* Setup the depth/stencil surface. */
3966 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
3967 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
3969 hr = IDirect3DDevice8_BeginScene(device);
3970 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
3971 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
3972 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3973 hr = IDirect3DDevice8_EndScene(device);
3974 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
3976 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, NULL);
3977 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
3978 IDirect3DSurface8_Release(ds);
3980 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
3981 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
3982 hr = IDirect3DDevice8_SetTexture(device, 1, (IDirect3DBaseTexture8 *)texture);
3983 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
3985 hr = IDirect3DDevice8_SetPixelShader(device, ps);
3986 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
3988 /* Do the actual shadow mapping. */
3989 hr = IDirect3DDevice8_BeginScene(device);
3990 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
3991 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
3992 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3993 hr = IDirect3DDevice8_EndScene(device);
3994 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
3996 hr = IDirect3DDevice8_SetTexture(device, 0, NULL);
3997 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
3998 hr = IDirect3DDevice8_SetTexture(device, 1, NULL);
3999 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
4000 IDirect3DTexture8_Release(texture);
4002 for (j = 0; j < sizeof(expected_colors) / sizeof(*expected_colors); ++j)
4004 D3DCOLOR color = getPixelColor(device, expected_colors[j].x, expected_colors[j].y);
4005 ok(color_match(color, expected_colors[j].color, 0),
4006 "Expected color 0x%08x at (%u, %u) for format %s, got 0x%08x.\n",
4007 expected_colors[j].color, expected_colors[j].x, expected_colors[j].y,
4008 formats[i].name, color);
4011 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
4012 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
4015 hr = IDirect3DDevice8_DeletePixelShader(device, ps);
4016 ok(SUCCEEDED(hr), "DeletePixelShader failed, hr %#x.\n", hr);
4017 IDirect3DSurface8_Release(original_rt);
4018 IDirect3DSurface8_Release(rt);
4019 refcount = IDirect3DDevice8_Release(device);
4020 ok(!refcount, "Device has %u references left.\n", refcount);
4021 done:
4022 IDirect3D8_Release(d3d);
4023 DestroyWindow(window);
4026 static void multisample_copy_rects_test(void)
4028 IDirect3DSurface8 *ds, *ds_plain, *rt, *readback;
4029 RECT src_rect = {64, 64, 128, 128};
4030 POINT dst_point = {96, 96};
4031 D3DLOCKED_RECT locked_rect;
4032 IDirect3DDevice8 *device;
4033 IDirect3D8 *d3d;
4034 D3DCOLOR color;
4035 ULONG refcount;
4036 HWND window;
4037 HRESULT hr;
4039 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
4040 0, 0, 640, 480, NULL, NULL, NULL, NULL);
4041 d3d = Direct3DCreate8(D3D_SDK_VERSION);
4042 ok(!!d3d, "Failed to create a D3D object.\n");
4043 if (!(device = create_device(d3d, window, window, TRUE)))
4045 skip("Failed to create a D3D device, skipping tests.\n");
4046 goto done;
4049 if (FAILED(IDirect3D8_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT,
4050 D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES)))
4052 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping multisampled CopyRects test.\n");
4053 IDirect3DDevice8_Release(device);
4054 goto done;
4057 hr = IDirect3DDevice8_CreateRenderTarget(device, 256, 256, D3DFMT_A8R8G8B8,
4058 D3DMULTISAMPLE_2_SAMPLES, FALSE, &rt);
4059 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
4060 hr = IDirect3DDevice8_CreateDepthStencilSurface(device, 256, 256, D3DFMT_D24S8,
4061 D3DMULTISAMPLE_2_SAMPLES, &ds);
4062 ok(SUCCEEDED(hr), "Failed to create depth stencil surface, hr %#x.\n", hr);
4063 hr = IDirect3DDevice8_CreateDepthStencilSurface(device, 256, 256, D3DFMT_D24S8,
4064 D3DMULTISAMPLE_NONE, &ds_plain);
4065 ok(SUCCEEDED(hr), "Failed to create depth stencil surface, hr %#x.\n", hr);
4066 hr = IDirect3DDevice8_CreateImageSurface(device, 256, 256, D3DFMT_A8R8G8B8, &readback);
4067 ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
4069 hr = IDirect3DDevice8_SetRenderTarget(device, rt, ds);
4070 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
4072 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
4073 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
4075 hr = IDirect3DDevice8_CopyRects(device, rt, NULL, 0, readback, NULL);
4076 ok(SUCCEEDED(hr), "Failed to read render target back, hr %#x.\n", hr);
4078 hr = IDirect3DDevice8_CopyRects(device, ds, NULL, 0, ds_plain, NULL);
4079 ok(hr == D3DERR_INVALIDCALL, "Depth buffer copy, hr %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
4081 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4082 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
4084 hr = IDirect3DDevice8_CopyRects(device, rt, &src_rect, 1, readback, &dst_point);
4085 ok(SUCCEEDED(hr), "Failed to read render target back, hr %#x.\n", hr);
4087 hr = IDirect3DSurface8_LockRect(readback, &locked_rect, NULL, D3DLOCK_READONLY);
4088 ok(SUCCEEDED(hr), "Failed to lock readback surface, hr %#x.\n", hr);
4090 color = *(DWORD *)((BYTE *)locked_rect.pBits + 31 * locked_rect.Pitch + 31 * 4);
4091 ok(color == 0xff00ff00, "Got unexpected color 0x%08x.\n", color);
4093 color = *(DWORD *)((BYTE *)locked_rect.pBits + 127 * locked_rect.Pitch + 127 * 4);
4094 ok(color == 0xffff0000, "Got unexpected color 0x%08x.\n", color);
4096 hr = IDirect3DSurface8_UnlockRect(readback);
4097 ok(SUCCEEDED(hr), "Failed to unlock readback surface, hr %#x.\n", hr);
4099 IDirect3DSurface8_Release(readback);
4100 IDirect3DSurface8_Release(ds_plain);
4101 IDirect3DSurface8_Release(ds);
4102 IDirect3DSurface8_Release(rt);
4103 refcount = IDirect3DDevice8_Release(device);
4104 ok(!refcount, "Device has %u references left.\n", refcount);
4105 done:
4106 IDirect3D8_Release(d3d);
4107 DestroyWindow(window);
4110 static void resz_test(void)
4112 IDirect3DSurface8 *rt, *original_rt, *ds, *original_ds, *intz_ds;
4113 IDirect3DTexture8 *texture;
4114 IDirect3DDevice8 *device;
4115 IDirect3D8 *d3d;
4116 DWORD ps, value;
4117 unsigned int i;
4118 ULONG refcount;
4119 D3DCAPS8 caps;
4120 HWND window;
4121 HRESULT hr;
4123 static const DWORD ps_code[] =
4125 0xffff0101, /* ps_1_1 */
4126 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1.0, 0.0, 0.0, 0.0 */
4127 0x00000051, 0xa00f0001, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c1, 0.0, 1.0, 0.0, 0.0 */
4128 0x00000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c2, 0.0, 0.0, 1.0, 0.0 */
4129 0x00000042, 0xb00f0000, /* tex t0 */
4130 0x00000042, 0xb00f0001, /* tex t1 */
4131 0x00000008, 0xb0070001, 0xa0e40000, 0xb0e40001, /* dp3 t1.xyz, c0, t1 */
4132 0x00000005, 0x80070000, 0xa0e40001, 0xb0e40001, /* mul r0.xyz, c1, t1 */
4133 0x00000004, 0x80070000, 0xa0e40000, 0xb0e40000, 0x80e40000, /* mad r0.xyz, c0, t0, r0 */
4134 0x40000001, 0x80080000, 0xa0aa0002, /* +mov r0.w, c2.z */
4135 0x0000ffff, /* end */
4137 static const struct
4139 float x, y, z;
4140 float s0, t0, p0;
4141 float s1, t1, p1, q1;
4143 quad[] =
4145 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.5f},
4146 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
4147 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
4148 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.5f},
4150 static const struct
4152 UINT x, y;
4153 D3DCOLOR color;
4155 expected_colors[] =
4157 { 80, 100, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
4158 {240, 100, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
4159 {400, 100, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
4160 {560, 100, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
4161 { 80, 450, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
4162 {240, 450, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
4163 {400, 450, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
4164 {560, 450, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
4167 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
4168 0, 0, 640, 480, NULL, NULL, NULL, NULL);
4169 d3d = Direct3DCreate8(D3D_SDK_VERSION);
4170 ok(!!d3d, "Failed to create a D3D object.\n");
4171 if (!(device = create_device(d3d, window, window, TRUE)))
4173 skip("Failed to create a D3D device, skipping tests.\n");
4174 goto done;
4177 if (FAILED(IDirect3D8_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT,
4178 D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES)))
4180 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping RESZ test.\n");
4181 IDirect3DDevice8_Release(device);
4182 goto done;
4184 if (FAILED(IDirect3D8_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT,
4185 D3DDEVTYPE_HAL, D3DFMT_D24S8, TRUE, D3DMULTISAMPLE_2_SAMPLES)))
4187 skip("Multisampling not supported for D3DFMT_D24S8, skipping RESZ test.\n");
4188 IDirect3DDevice8_Release(device);
4189 goto done;
4191 if (FAILED(IDirect3D8_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
4192 D3DFMT_X8R8G8B8, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, MAKEFOURCC('I','N','T','Z'))))
4194 skip("No INTZ support, skipping RESZ test.\n");
4195 IDirect3DDevice8_Release(device);
4196 goto done;
4198 if (FAILED(IDirect3D8_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
4199 D3DFMT_X8R8G8B8, D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE, MAKEFOURCC('R','E','S','Z'))))
4201 skip("No RESZ support, skipping RESZ test.\n");
4202 IDirect3DDevice8_Release(device);
4203 goto done;
4206 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
4207 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
4208 if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
4210 skip("No unconditional NP2 texture support, skipping INTZ test.\n");
4211 IDirect3DDevice8_Release(device);
4212 goto done;
4215 hr = IDirect3DDevice8_GetRenderTarget(device, &original_rt);
4216 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
4217 hr = IDirect3DDevice8_GetDepthStencilSurface(device, &original_ds);
4218 ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#x.\n", hr);
4220 hr = IDirect3DDevice8_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
4221 D3DMULTISAMPLE_2_SAMPLES, FALSE, &rt);
4222 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
4223 hr = IDirect3DDevice8_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
4224 D3DMULTISAMPLE_2_SAMPLES, &ds);
4226 hr = IDirect3DDevice8_CreateTexture(device, 640, 480, 1,
4227 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture);
4228 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
4229 hr = IDirect3DTexture8_GetSurfaceLevel(texture, 0, &intz_ds);
4230 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
4232 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, intz_ds);
4233 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
4234 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
4235 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
4237 hr = IDirect3DDevice8_SetRenderTarget(device, rt, ds);
4238 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
4239 IDirect3DSurface8_Release(intz_ds);
4240 hr = IDirect3DDevice8_CreatePixelShader(device, ps_code, &ps);
4241 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
4243 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX2
4244 | D3DFVF_TEXCOORDSIZE3(0) | D3DFVF_TEXCOORDSIZE4(1));
4245 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
4246 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
4247 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
4248 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
4249 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
4250 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
4251 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
4252 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
4253 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
4255 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MINFILTER, D3DTEXF_POINT);
4256 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
4257 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MIPFILTER, D3DTEXF_POINT);
4258 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
4259 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MAGFILTER, D3DTEXF_POINT);
4260 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
4261 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
4262 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
4264 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP);
4265 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
4266 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP);
4267 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
4268 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MAGFILTER, D3DTEXF_POINT);
4269 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
4270 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MINFILTER, D3DTEXF_POINT);
4271 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
4272 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MIPFILTER, D3DTEXF_POINT);
4273 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
4274 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS,
4275 D3DTTFF_COUNT4 | D3DTTFF_PROJECTED);
4276 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
4278 /* Render offscreen (multisampled), blit the depth buffer into the INTZ texture and then check its contents. */
4279 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
4280 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
4282 hr = IDirect3DDevice8_BeginScene(device);
4283 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
4284 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
4285 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
4287 /* The destination depth texture has to be bound to sampler 0 */
4288 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
4289 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
4291 /* the ATI "spec" says you have to do a dummy draw to ensure correct commands ordering */
4292 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, FALSE);
4293 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
4294 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
4295 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
4296 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0);
4297 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
4298 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
4299 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
4300 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, TRUE);
4301 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
4302 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
4303 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
4304 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0xf);
4305 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
4307 /* The actual multisampled depth buffer resolve happens here */
4308 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
4309 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
4310 hr = IDirect3DDevice8_GetRenderState(device, D3DRS_POINTSIZE, &value);
4311 ok(SUCCEEDED(hr) && value == 0x7fa05000, "GetRenderState failed, hr %#x, value %#x.\n", hr, value);
4313 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, NULL);
4314 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
4315 hr = IDirect3DDevice8_SetTexture(device, 1, (IDirect3DBaseTexture8 *)texture);
4316 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
4317 hr = IDirect3DDevice8_SetPixelShader(device, ps);
4318 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
4320 /* Read the depth values back. */
4321 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
4322 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
4323 hr = IDirect3DDevice8_EndScene(device);
4324 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
4326 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
4328 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
4329 ok(color_match(color, expected_colors[i].color, 1),
4330 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
4331 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
4334 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
4335 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
4337 /* Test edge cases - try with no texture at all */
4338 hr = IDirect3DDevice8_SetTexture(device, 0, NULL);
4339 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
4340 hr = IDirect3DDevice8_SetTexture(device, 1, NULL);
4341 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
4342 hr = IDirect3DDevice8_SetRenderTarget(device, rt, ds);
4343 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
4345 hr = IDirect3DDevice8_BeginScene(device);
4346 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
4347 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
4348 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
4349 hr = IDirect3DDevice8_EndScene(device);
4350 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
4352 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
4353 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
4355 /* With a non-multisampled depth buffer */
4356 IDirect3DSurface8_Release(ds);
4357 IDirect3DSurface8_Release(rt);
4358 hr = IDirect3DDevice8_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
4359 D3DMULTISAMPLE_NONE, &ds);
4361 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, ds);
4362 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
4363 hr = IDirect3DDevice8_SetPixelShader(device, 0);
4364 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
4366 hr = IDirect3DDevice8_BeginScene(device);
4367 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
4368 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
4369 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
4370 hr = IDirect3DDevice8_EndScene(device);
4371 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
4373 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
4374 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
4376 hr = IDirect3DDevice8_BeginScene(device);
4377 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
4378 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, FALSE);
4379 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
4380 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
4381 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
4382 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0);
4383 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
4384 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
4385 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
4386 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, TRUE);
4387 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
4388 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
4389 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
4390 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0xf);
4391 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
4392 hr = IDirect3DDevice8_EndScene(device);
4393 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
4395 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
4396 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
4398 hr = IDirect3DDevice8_SetTexture(device, 1, (IDirect3DBaseTexture8 *)texture);
4399 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
4400 hr = IDirect3DDevice8_SetPixelShader(device, ps);
4401 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
4403 /* Read the depth values back. */
4404 hr = IDirect3DDevice8_BeginScene(device);
4405 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
4406 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
4407 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
4408 hr = IDirect3DDevice8_EndScene(device);
4409 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
4411 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
4413 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
4414 ok(color_match(color, expected_colors[i].color, 1),
4415 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
4416 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
4419 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
4420 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
4422 IDirect3DSurface8_Release(ds);
4423 IDirect3DTexture8_Release(texture);
4424 hr = IDirect3DDevice8_DeletePixelShader(device, ps);
4425 ok(SUCCEEDED(hr), "DeletePixelShader failed, hr %#x.\n", hr);
4426 IDirect3DSurface8_Release(original_ds);
4427 IDirect3DSurface8_Release(original_rt);
4429 refcount = IDirect3DDevice8_Release(device);
4430 ok(!refcount, "Device has %u references left.\n", refcount);
4431 done:
4432 IDirect3D8_Release(d3d);
4433 DestroyWindow(window);
4436 static void zenable_test(void)
4438 IDirect3DDevice8 *device;
4439 IDirect3D8 *d3d;
4440 D3DCOLOR color;
4441 ULONG refcount;
4442 D3DCAPS8 caps;
4443 HWND window;
4444 HRESULT hr;
4445 UINT x, y;
4446 UINT i, j;
4447 UINT test;
4448 IDirect3DSurface8 *ds, *rt;
4450 static const struct
4452 struct vec4 position;
4453 D3DCOLOR diffuse;
4455 tquad[] =
4457 {{ 0.0f, 480.0f, -0.5f, 1.0f}, 0xff00ff00},
4458 {{ 0.0f, 0.0f, -0.5f, 1.0f}, 0xff00ff00},
4459 {{640.0f, 480.0f, 1.5f, 1.0f}, 0xff00ff00},
4460 {{640.0f, 0.0f, 1.5f, 1.0f}, 0xff00ff00},
4463 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
4464 0, 0, 640, 480, NULL, NULL, NULL, NULL);
4465 d3d = Direct3DCreate8(D3D_SDK_VERSION);
4466 ok(!!d3d, "Failed to create a D3D object.\n");
4467 if (!(device = create_device(d3d, window, window, TRUE)))
4469 skip("Failed to create a D3D device, skipping tests.\n");
4470 goto done;
4473 hr = IDirect3DDevice8_GetDepthStencilSurface(device, &ds);
4474 ok(SUCCEEDED(hr), "Failed to get depth stencil surface, hr %#x.\n", hr);
4475 hr = IDirect3DDevice8_GetRenderTarget(device, &rt);
4476 ok(SUCCEEDED(hr), "Failed to get render target surface, hr %#x.\n", hr);
4478 for (test = 0; test < 2; ++test)
4480 /* The Windows 8 testbot (WARP) appears to clip with
4481 * ZENABLE = D3DZB_TRUE and no depth buffer set. */
4482 static const D3DCOLOR expected_broken[] =
4484 0x00ff0000, 0x0000ff00, 0x0000ff00, 0x00ff0000,
4485 0x00ff0000, 0x0000ff00, 0x0000ff00, 0x00ff0000,
4486 0x00ff0000, 0x0000ff00, 0x0000ff00, 0x00ff0000,
4487 0x00ff0000, 0x0000ff00, 0x0000ff00, 0x00ff0000,
4490 if (!test)
4492 hr = IDirect3DDevice8_SetRenderTarget(device, rt, NULL);
4493 ok(SUCCEEDED(hr), "Failed to set depth stencil surface, hr %#x.\n", hr);
4495 else
4497 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
4498 ok(SUCCEEDED(hr), "Failed to disable z-buffering, hr %#x.\n", hr);
4499 hr = IDirect3DDevice8_SetRenderTarget(device, rt, ds);
4500 ok(SUCCEEDED(hr), "Failed to set depth stencil surface, hr %#x.\n", hr);
4501 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 0.0f, 0);
4502 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
4504 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
4505 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
4507 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0f, 0);
4508 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
4509 hr = IDirect3DDevice8_BeginScene(device);
4510 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
4511 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, tquad, sizeof(*tquad));
4512 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4513 hr = IDirect3DDevice8_EndScene(device);
4514 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
4516 for (i = 0; i < 4; ++i)
4518 for (j = 0; j < 4; ++j)
4520 x = 80 * ((2 * j) + 1);
4521 y = 60 * ((2 * i) + 1);
4522 color = getPixelColor(device, x, y);
4523 ok(color_match(color, 0x0000ff00, 1)
4524 || broken(color_match(color, expected_broken[i * 4 + j], 1) && !test),
4525 "Expected color 0x0000ff00 at %u, %u, got 0x%08x.\n", x, y, color);
4529 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
4530 ok(SUCCEEDED(hr), "Failed to present backbuffer, hr %#x.\n", hr);
4533 IDirect3DSurface8_Release(ds);
4534 IDirect3DSurface8_Release(rt);
4536 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
4537 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
4539 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1)
4540 && caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
4542 static const DWORD vs_code[] =
4544 0xfffe0101, /* vs_1_1 */
4545 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4546 0x00000001, 0xd00f0000, 0x90e40000, /* mov oD0, v0 */
4547 0x0000ffff
4549 static const DWORD ps_code[] =
4551 0xffff0101, /* ps_1_1 */
4552 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
4553 0x0000ffff /* end */
4555 static const struct vec3 quad[] =
4557 {-1.0f, -1.0f, -0.5f},
4558 {-1.0f, 1.0f, -0.5f},
4559 { 1.0f, -1.0f, 1.5f},
4560 { 1.0f, 1.0f, 1.5f},
4562 static const D3DCOLOR expected[] =
4564 0x00ff0000, 0x0060df60, 0x009fdf9f, 0x00ff0000,
4565 0x00ff0000, 0x00609f60, 0x009f9f9f, 0x00ff0000,
4566 0x00ff0000, 0x00606060, 0x009f609f, 0x00ff0000,
4567 0x00ff0000, 0x00602060, 0x009f209f, 0x00ff0000,
4569 /* The Windows 8 testbot (WARP) appears to not clip z for regular
4570 * vertices either. */
4571 static const D3DCOLOR expected_broken[] =
4573 0x0020df20, 0x0060df60, 0x009fdf9f, 0x00dfdfdf,
4574 0x00209f20, 0x00609f60, 0x009f9f9f, 0x00df9fdf,
4575 0x00206020, 0x00606060, 0x009f609f, 0x00df60df,
4576 0x00202020, 0x00602060, 0x009f209f, 0x00df20df,
4578 static const DWORD decl[] =
4580 D3DVSD_STREAM(0),
4581 D3DVSD_REG(D3DVSDE_POSITION, D3DVSDT_FLOAT3),
4582 D3DVSD_END()
4584 DWORD vs, ps;
4586 hr = IDirect3DDevice8_CreateVertexShader(device, decl, vs_code, &vs, 0);
4587 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
4588 hr = IDirect3DDevice8_CreatePixelShader(device, ps_code, &ps);
4589 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
4590 hr = IDirect3DDevice8_SetVertexShader(device, vs);
4591 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
4592 hr = IDirect3DDevice8_SetPixelShader(device, ps);
4593 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
4595 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0f, 0);
4596 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
4597 hr = IDirect3DDevice8_BeginScene(device);
4598 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
4599 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
4600 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4601 hr = IDirect3DDevice8_EndScene(device);
4602 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
4604 for (i = 0; i < 4; ++i)
4606 for (j = 0; j < 4; ++j)
4608 x = 80 * ((2 * j) + 1);
4609 y = 60 * ((2 * i) + 1);
4610 color = getPixelColor(device, x, y);
4611 ok(color_match(color, expected[i * 4 + j], 1)
4612 || broken(color_match(color, expected_broken[i * 4 + j], 1)),
4613 "Expected color 0x%08x at %u, %u, got 0x%08x.\n", expected[i * 4 + j], x, y, color);
4617 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
4618 ok(SUCCEEDED(hr), "Failed to present backbuffer, hr %#x.\n", hr);
4620 hr = IDirect3DDevice8_DeletePixelShader(device, ps);
4621 ok(SUCCEEDED(hr), "Failed to delete pixel shader, hr %#x.\n", hr);
4622 hr = IDirect3DDevice8_DeleteVertexShader(device, vs);
4623 ok(SUCCEEDED(hr), "Failed to delete vertex shader, hr %#x.\n", hr);
4626 refcount = IDirect3DDevice8_Release(device);
4627 ok(!refcount, "Device has %u references left.\n", refcount);
4628 done:
4629 IDirect3D8_Release(d3d);
4630 DestroyWindow(window);
4633 static void fog_special_test(void)
4635 IDirect3DDevice8 *device;
4636 IDirect3D8 *d3d;
4637 unsigned int i;
4638 D3DCOLOR color;
4639 ULONG refcount;
4640 D3DCAPS8 caps;
4641 DWORD ps, vs;
4642 HWND window;
4643 HRESULT hr;
4644 union
4646 float f;
4647 DWORD d;
4648 } conv;
4650 static const struct
4652 struct vec3 position;
4653 D3DCOLOR diffuse;
4655 quad[] =
4657 {{ -1.0f, -1.0f, 0.0f}, 0xff00ff00},
4658 {{ -1.0f, 1.0f, 0.0f}, 0xff00ff00},
4659 {{ 1.0f, -1.0f, 1.0f}, 0xff00ff00},
4660 {{ 1.0f, 1.0f, 1.0f}, 0xff00ff00}
4662 static const struct
4664 DWORD vertexmode, tablemode;
4665 BOOL vs, ps;
4666 D3DCOLOR color_left, color_right;
4668 tests[] =
4670 {D3DFOG_LINEAR, D3DFOG_NONE, FALSE, FALSE, 0x00ff0000, 0x00ff0000},
4671 {D3DFOG_LINEAR, D3DFOG_NONE, FALSE, TRUE, 0x00ff0000, 0x00ff0000},
4672 {D3DFOG_LINEAR, D3DFOG_NONE, TRUE, FALSE, 0x00ff0000, 0x00ff0000},
4673 {D3DFOG_LINEAR, D3DFOG_NONE, TRUE, TRUE, 0x00ff0000, 0x00ff0000},
4675 {D3DFOG_NONE, D3DFOG_LINEAR, FALSE, FALSE, 0x0000ff00, 0x00ff0000},
4676 {D3DFOG_NONE, D3DFOG_LINEAR, FALSE, TRUE, 0x0000ff00, 0x00ff0000},
4677 {D3DFOG_NONE, D3DFOG_LINEAR, TRUE, FALSE, 0x0000ff00, 0x00ff0000},
4678 {D3DFOG_NONE, D3DFOG_LINEAR, TRUE, TRUE, 0x0000ff00, 0x00ff0000},
4680 static const DWORD pixel_shader_code[] =
4682 0xffff0101, /* ps.1.1 */
4683 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
4684 0x0000ffff
4686 static const DWORD vertex_decl[] =
4688 D3DVSD_STREAM(0),
4689 D3DVSD_REG(0, D3DVSDT_FLOAT3), /* position, v0 */
4690 D3DVSD_REG(1, D3DVSDT_D3DCOLOR), /* diffuse color, v1 */
4691 D3DVSD_END()
4693 static const DWORD vertex_shader_code[] =
4695 0xfffe0101, /* vs.1.1 */
4696 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4697 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
4698 0x0000ffff
4700 static const D3DMATRIX identity =
4702 1.0f, 0.0f, 0.0f, 0.0f,
4703 0.0f, 1.0f, 0.0f, 0.0f,
4704 0.0f, 0.0f, 1.0f, 0.0f,
4705 0.0f, 0.0f, 0.0f, 1.0f,
4706 }}};
4708 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
4709 0, 0, 640, 480, NULL, NULL, NULL, NULL);
4710 d3d = Direct3DCreate8(D3D_SDK_VERSION);
4711 ok(!!d3d, "Failed to create a D3D object.\n");
4712 if (!(device = create_device(d3d, window, window, TRUE)))
4714 skip("Failed to create a D3D device, skipping tests.\n");
4715 goto done;
4718 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
4719 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
4720 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
4722 hr = IDirect3DDevice8_CreateVertexShader(device, vertex_decl, vertex_shader_code, &vs, 0);
4723 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
4725 else
4727 skip("Vertex Shaders not supported, skipping some fog tests.\n");
4728 vs = 0;
4730 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
4732 hr = IDirect3DDevice8_CreatePixelShader(device, pixel_shader_code, &ps);
4733 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
4735 else
4737 skip("Pixel Shaders not supported, skipping some fog tests.\n");
4738 ps = 0;
4741 /* The table fog tests seem to depend on the projection matrix explicitly
4742 * being set to an identity matrix, even though that's the default.
4743 * (AMD Radeon HD 6310, Windows 7) */
4744 hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, &identity);
4745 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
4747 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
4748 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
4749 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
4750 ok(SUCCEEDED(hr), "Failed to enable fog, hr %#x.\n", hr);
4751 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGCOLOR, 0xffff0000);
4752 ok(SUCCEEDED(hr), "Failed to set fog color, hr %#x.\n", hr);
4754 conv.f = 0.5f;
4755 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGSTART, conv.d);
4756 ok(SUCCEEDED(hr), "Failed to set fog start, hr %#x.\n", hr);
4757 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGEND, conv.d);
4758 ok(SUCCEEDED(hr), "Failed to set fog end, hr %#x.\n", hr);
4760 for (i = 0; i < sizeof(tests) / sizeof(*tests); i++)
4762 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
4763 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
4765 if (!tests[i].vs)
4767 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
4768 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr);
4770 else if (vs)
4772 hr = IDirect3DDevice8_SetVertexShader(device, vs);
4773 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
4775 else
4777 continue;
4780 if (!tests[i].ps)
4782 hr = IDirect3DDevice8_SetPixelShader(device, 0);
4783 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
4785 else if (ps)
4787 hr = IDirect3DDevice8_SetPixelShader(device, ps);
4788 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
4790 else
4792 continue;
4795 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGVERTEXMODE, tests[i].vertexmode);
4796 ok(SUCCEEDED(hr), "Failed to set fogvertexmode, hr %#x.\n", hr);
4797 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGTABLEMODE, tests[i].tablemode);
4798 ok(SUCCEEDED(hr), "Failed to set fogtablemode, hr %#x.\n", hr);
4800 hr = IDirect3DDevice8_BeginScene(device);
4801 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
4802 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
4803 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4804 hr = IDirect3DDevice8_EndScene(device);
4805 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
4807 color = getPixelColor(device, 310, 240);
4808 ok(color_match(color, tests[i].color_left, 1),
4809 "Expected left color 0x%08x, got 0x%08x, case %u.\n", tests[i].color_left, color, i);
4810 color = getPixelColor(device, 330, 240);
4811 ok(color_match(color, tests[i].color_right, 1),
4812 "Expected right color 0x%08x, got 0x%08x, case %u.\n", tests[i].color_right, color, i);
4814 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
4815 ok(SUCCEEDED(hr), "Failed to present backbuffer, hr %#x.\n", hr);
4818 if (vs)
4819 IDirect3DDevice8_DeleteVertexShader(device, vs);
4820 if (ps)
4821 IDirect3DDevice8_DeletePixelShader(device, ps);
4822 refcount = IDirect3DDevice8_Release(device);
4823 ok(!refcount, "Device has %u references left.\n", refcount);
4824 done:
4825 IDirect3D8_Release(d3d);
4826 DestroyWindow(window);
4829 static void volume_dxt5_test(void)
4831 IDirect3DVolumeTexture8 *texture;
4832 IDirect3DDevice8 *device;
4833 D3DLOCKED_BOX box;
4834 IDirect3D8 *d3d;
4835 unsigned int i;
4836 D3DCOLOR color;
4837 ULONG refcount;
4838 HWND window;
4839 HRESULT hr;
4841 static const char texture_data[] =
4843 /* A 8x4x2 texture consisting of 4 4x4 blocks. The colors of the blocks are red, green, blue and white. */
4844 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00,
4845 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00,
4846 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00,
4847 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00
4849 static const struct
4851 struct vec3 position;
4852 struct vec3 texcrd;
4854 quads[] =
4856 {{ -1.0f, -1.0f, 0.0f}, { 0.0f, 0.0f, 0.25f}},
4857 {{ -1.0f, 1.0f, 0.0f}, { 0.0f, 1.0f, 0.25f}},
4858 {{ 0.0f, -1.0f, 1.0f}, { 1.0f, 0.0f, 0.25f}},
4859 {{ 0.0f, 1.0f, 1.0f}, { 1.0f, 1.0f, 0.25f}},
4861 {{ 0.0f, -1.0f, 0.0f}, { 0.0f, 0.0f, 0.75f}},
4862 {{ 0.0f, 1.0f, 0.0f}, { 0.0f, 1.0f, 0.75f}},
4863 {{ 1.0f, -1.0f, 1.0f}, { 1.0f, 0.0f, 0.75f}},
4864 {{ 1.0f, 1.0f, 1.0f}, { 1.0f, 1.0f, 0.75f}},
4866 static const DWORD expected_colors[] = {0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff};
4868 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
4869 0, 0, 640, 480, NULL, NULL, NULL, NULL);
4870 d3d = Direct3DCreate8(D3D_SDK_VERSION);
4871 ok(!!d3d, "Failed to create a D3D object.\n");
4872 if (!(device = create_device(d3d, window, window, TRUE)))
4874 skip("Failed to create a D3D device, skipping tests.\n");
4875 goto done;
4878 if (FAILED(IDirect3D8_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
4879 D3DFMT_X8R8G8B8, 0, D3DRTYPE_VOLUMETEXTURE, D3DFMT_DXT5)))
4881 skip("Volume DXT5 textures are not supported, skipping test.\n");
4882 IDirect3DDevice8_Release(device);
4883 goto done;
4886 hr = IDirect3DDevice8_CreateVolumeTexture(device, 8, 4, 2, 1, 0, D3DFMT_DXT5,
4887 D3DPOOL_MANAGED, &texture);
4888 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
4890 hr = IDirect3DVolumeTexture8_LockBox(texture, 0, &box, NULL, 0);
4891 ok(SUCCEEDED(hr), "Failed to lock volume texture, hr %#x.\n", hr);
4892 memcpy(box.pBits, texture_data, sizeof(texture_data));
4893 hr = IDirect3DVolumeTexture8_UnlockBox(texture, 0);
4894 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#x.\n", hr);
4896 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE3(0));
4897 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
4898 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
4899 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
4900 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
4901 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
4902 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
4903 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
4904 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
4905 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
4906 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MAGFILTER, D3DTEXF_POINT);
4907 ok(SUCCEEDED(hr), "Failed to set mag filter, hr %#x.\n", hr);
4909 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff00ff, 1.0f, 0);
4910 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
4911 hr = IDirect3DDevice8_BeginScene(device);
4912 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
4913 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads));
4914 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4915 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[4], sizeof(*quads));
4916 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4917 hr = IDirect3DDevice8_EndScene(device);
4918 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
4920 for (i = 0; i < 4; i++)
4922 color = getPixelColor(device, 80 + 160 * i, 240);
4923 ok (color_match(color, expected_colors[i], 1),
4924 "Expected color 0x%08x, got 0x%08x, case %u.\n", expected_colors[i], color, i);
4927 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
4928 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
4929 IDirect3DVolumeTexture8_Release(texture);
4930 refcount = IDirect3DDevice8_Release(device);
4931 ok(!refcount, "Device has %u references left.\n", refcount);
4932 done:
4933 IDirect3D8_Release(d3d);
4934 DestroyWindow(window);
4937 static void volume_v16u16_test(void)
4939 IDirect3DVolumeTexture8 *texture;
4940 IDirect3DDevice8 *device;
4941 D3DLOCKED_BOX box;
4942 IDirect3D8 *d3d;
4943 unsigned int i;
4944 D3DCOLOR color;
4945 ULONG refcount;
4946 D3DCAPS8 caps;
4947 DWORD shader;
4948 SHORT *texel;
4949 HWND window;
4950 HRESULT hr;
4952 static const struct
4954 struct vec3 position;
4955 struct vec3 texcrd;
4957 quads[] =
4959 {{ -1.0f, -1.0f, 0.0f}, { 0.0f, 0.0f, 0.25f}},
4960 {{ -1.0f, 1.0f, 0.0f}, { 0.0f, 1.0f, 0.25f}},
4961 {{ 0.0f, -1.0f, 1.0f}, { 1.0f, 0.0f, 0.25f}},
4962 {{ 0.0f, 1.0f, 1.0f}, { 1.0f, 1.0f, 0.25f}},
4964 {{ 0.0f, -1.0f, 0.0f}, { 0.0f, 0.0f, 0.75f}},
4965 {{ 0.0f, 1.0f, 0.0f}, { 0.0f, 1.0f, 0.75f}},
4966 {{ 1.0f, -1.0f, 1.0f}, { 1.0f, 0.0f, 0.75f}},
4967 {{ 1.0f, 1.0f, 1.0f}, { 1.0f, 1.0f, 0.75f}},
4969 static const DWORD shader_code[] =
4971 0xffff0101, /* ps_1_1 */
4972 0x00000051, 0xa00f0000, 0x3f000000, 0x3f000000, /* def c0, 0.5, 0.5, */
4973 0x3f000000, 0x3f000000, /* 0.5, 0.5 */
4974 0x00000042, 0xb00f0000, /* tex t0 */
4975 0x00000004, 0x800f0000, 0xb0e40000, 0xa0e40000, 0xa0e40000, /* mad r0, t0, c0, c0 */
4976 0x0000ffff /* end */
4979 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
4980 0, 0, 640, 480, NULL, NULL, NULL, NULL);
4981 d3d = Direct3DCreate8(D3D_SDK_VERSION);
4982 ok(!!d3d, "Failed to create a D3D object.\n");
4983 if (!(device = create_device(d3d, window, window, TRUE)))
4985 skip("Failed to create a D3D device, skipping tests.\n");
4986 goto done;
4989 if (FAILED(IDirect3D8_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
4990 D3DFMT_X8R8G8B8, 0, D3DRTYPE_VOLUMETEXTURE, D3DFMT_V16U16)))
4992 skip("Volume V16U16 textures are not supported, skipping test.\n");
4993 IDirect3DDevice8_Release(device);
4994 goto done;
4996 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
4997 ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
4998 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 1))
5000 skip("No pixel shader 1.1 support, skipping test.\n");
5001 IDirect3DDevice8_Release(device);
5002 goto done;
5005 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE3(0));
5006 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
5007 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code, &shader);
5008 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
5009 hr = IDirect3DDevice8_SetPixelShader(device, shader);
5010 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
5011 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MAGFILTER, D3DTEXF_POINT);
5012 ok(SUCCEEDED(hr), "Failed to set filter, hr %#x.\n", hr);
5014 for (i = 0; i < 2; i++)
5016 D3DPOOL pool;
5018 if (i)
5019 pool = D3DPOOL_SYSTEMMEM;
5020 else
5021 pool = D3DPOOL_MANAGED;
5023 hr = IDirect3DDevice8_CreateVolumeTexture(device, 1, 2, 2, 1, 0, D3DFMT_V16U16,
5024 pool, &texture);
5025 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
5027 hr = IDirect3DVolumeTexture8_LockBox(texture, 0, &box, NULL, 0);
5028 ok(SUCCEEDED(hr), "Failed to lock volume texture, hr %#x.\n", hr);
5030 texel = (SHORT *)((BYTE *)box.pBits + 0 * box.RowPitch + 0 * box.SlicePitch);
5031 texel[0] = 32767;
5032 texel[1] = 32767;
5033 texel = (SHORT *)((BYTE *)box.pBits + 1 * box.RowPitch + 0 * box.SlicePitch);
5034 texel[0] = -32768;
5035 texel[1] = 0;
5036 texel = (SHORT *)((BYTE *)box.pBits + 0 * box.RowPitch + 1 * box.SlicePitch);
5037 texel[0] = -16384;
5038 texel[1] = 16384;
5039 texel = (SHORT *)((BYTE *)box.pBits + 1 * box.RowPitch + 1 * box.SlicePitch);
5040 texel[0] = 0;
5041 texel[1] = 0;
5043 hr = IDirect3DVolumeTexture8_UnlockBox(texture, 0);
5044 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#x.\n", hr);
5046 if (i)
5048 IDirect3DVolumeTexture8 *texture2;
5050 hr = IDirect3DDevice8_CreateVolumeTexture(device, 1, 2, 2, 1, 0, D3DFMT_V16U16,
5051 D3DPOOL_DEFAULT, &texture2);
5052 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
5054 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)texture,
5055 (IDirect3DBaseTexture8 *)texture2);
5056 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
5058 IDirect3DVolumeTexture8_Release(texture);
5059 texture = texture2;
5062 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *) texture);
5063 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
5065 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff00ff, 1.0f, 0);
5066 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
5067 hr = IDirect3DDevice8_BeginScene(device);
5068 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5069 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads));
5070 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5071 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[4], sizeof(*quads));
5072 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5073 hr = IDirect3DDevice8_EndScene(device);
5074 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5076 color = getPixelColor(device, 120, 160);
5077 ok (color_match(color, 0x000080ff, 2),
5078 "Expected color 0x000080ff, got 0x%08x, V16U16 input -32768, 0.\n", color);
5079 color = getPixelColor(device, 120, 400);
5080 ok (color_match(color, 0x00ffffff, 2),
5081 "Expected color 0x00ffffff, got 0x%08x, V16U16 input 32767, 32767.\n", color);
5082 color = getPixelColor(device, 360, 160);
5083 ok (color_match(color, 0x007f7fff, 2),
5084 "Expected color 0x007f7fff, got 0x%08x, V16U16 input 0, 0.\n", color);
5085 color = getPixelColor(device, 360, 400);
5086 ok (color_match(color, 0x0040c0ff, 2),
5087 "Expected color 0x0040c0ff, got 0x%08x, V16U16 input -16384, 16384.\n", color);
5089 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5090 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5092 IDirect3DVolumeTexture8_Release(texture);
5095 hr = IDirect3DDevice8_DeletePixelShader(device, shader);
5096 ok(SUCCEEDED(hr), "Failed delete pixel shader, hr %#x.\n", hr);
5097 refcount = IDirect3DDevice8_Release(device);
5098 ok(!refcount, "Device has %u references left.\n", refcount);
5099 done:
5100 IDirect3D8_Release(d3d);
5101 DestroyWindow(window);
5104 static void fill_surface(IDirect3DSurface8 *surface, DWORD color, DWORD flags)
5106 D3DSURFACE_DESC desc;
5107 D3DLOCKED_RECT l;
5108 HRESULT hr;
5109 unsigned int x, y;
5110 DWORD *mem;
5112 hr = IDirect3DSurface8_GetDesc(surface, &desc);
5113 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
5114 hr = IDirect3DSurface8_LockRect(surface, &l, NULL, flags);
5115 ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
5116 if (FAILED(hr))
5117 return;
5119 for (y = 0; y < desc.Height; y++)
5121 mem = (DWORD *)((BYTE *)l.pBits + y * l.Pitch);
5122 for (x = 0; x < l.Pitch / sizeof(DWORD); x++)
5124 mem[x] = color;
5127 hr = IDirect3DSurface8_UnlockRect(surface);
5128 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
5131 static void add_dirty_rect_test_draw(IDirect3DDevice8 *device)
5133 HRESULT hr;
5134 static const struct
5136 struct vec3 position;
5137 struct vec2 texcoord;
5139 quad[] =
5141 {{-1.0f, -1.0f, 0.0f}, {0.0f, 0.0f}},
5142 {{-1.0f, 1.0f, 0.0f}, {0.0f, 1.0f}},
5143 {{ 1.0f, -1.0f, 0.0f}, {1.0f, 0.0f}},
5144 {{ 1.0f, 1.0f, 0.0f}, {1.0f, 1.0f}},
5147 hr = IDirect3DDevice8_BeginScene(device);
5148 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5149 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad, sizeof(*quad));
5150 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5151 hr = IDirect3DDevice8_EndScene(device);
5152 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5155 static void add_dirty_rect_test(void)
5157 IDirect3DSurface8 *surface_dst2, *surface_src_green, *surface_src_red, *surface_managed;
5158 IDirect3DTexture8 *tex_dst1, *tex_dst2, *tex_src_red, *tex_src_green, *tex_managed;
5159 D3DLOCKED_RECT locked_rect;
5160 IDirect3DDevice8 *device;
5161 IDirect3D8 *d3d;
5162 unsigned int i;
5163 D3DCOLOR color;
5164 ULONG refcount;
5165 DWORD *texel;
5166 HWND window;
5167 HRESULT hr;
5169 static const RECT part_rect = {96, 96, 160, 160};
5171 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
5172 0, 0, 640, 480, NULL, NULL, NULL, NULL);
5173 d3d = Direct3DCreate8(D3D_SDK_VERSION);
5174 ok(!!d3d, "Failed to create a D3D object.\n");
5175 if (!(device = create_device(d3d, window, window, TRUE)))
5177 skip("Failed to create a D3D device, skipping tests.\n");
5178 goto done;
5181 hr = IDirect3DDevice8_CreateTexture(device, 256, 256, 1, 0, D3DFMT_X8R8G8B8,
5182 D3DPOOL_DEFAULT, &tex_dst1);
5183 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
5184 hr = IDirect3DDevice8_CreateTexture(device, 256, 256, 1, 0, D3DFMT_X8R8G8B8,
5185 D3DPOOL_DEFAULT, &tex_dst2);
5186 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
5187 hr = IDirect3DDevice8_CreateTexture(device, 256, 256, 1, 0, D3DFMT_X8R8G8B8,
5188 D3DPOOL_SYSTEMMEM, &tex_src_red);
5189 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
5190 hr = IDirect3DDevice8_CreateTexture(device, 256, 256, 1, 0, D3DFMT_X8R8G8B8,
5191 D3DPOOL_SYSTEMMEM, &tex_src_green);
5192 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
5193 hr = IDirect3DDevice8_CreateTexture(device, 256, 256, 1, 0, D3DFMT_X8R8G8B8,
5194 D3DPOOL_MANAGED, &tex_managed);
5195 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
5197 hr = IDirect3DTexture8_GetSurfaceLevel(tex_dst2, 0, &surface_dst2);
5198 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
5199 hr = IDirect3DTexture8_GetSurfaceLevel(tex_src_green, 0, &surface_src_green);
5200 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
5201 hr = IDirect3DTexture8_GetSurfaceLevel(tex_src_red, 0, &surface_src_red);
5202 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
5203 hr = IDirect3DTexture8_GetSurfaceLevel(tex_managed, 0, &surface_managed);
5204 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
5206 fill_surface(surface_src_red, 0x00ff0000, 0);
5207 fill_surface(surface_src_green, 0x0000ff00, 0);
5209 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX1);
5210 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr);
5211 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
5212 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
5213 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
5214 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
5216 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_green,
5217 (IDirect3DBaseTexture8 *)tex_dst1);
5218 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
5220 /* The second UpdateTexture call writing to tex_dst2 is ignored because tex_src_green is not dirty. */
5221 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_red,
5222 (IDirect3DBaseTexture8 *)tex_dst2);
5223 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
5224 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_green,
5225 (IDirect3DBaseTexture8 *)tex_dst2);
5226 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
5228 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)tex_dst1);
5229 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
5230 add_dirty_rect_test_draw(device);
5231 color = getPixelColor(device, 320, 240);
5232 ok(color_match(color, 0x0000ff00, 1),
5233 "Expected color 0x0000ff00, got 0x%08x.\n", color);
5234 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5235 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5237 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)tex_dst2);
5238 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
5239 add_dirty_rect_test_draw(device);
5240 color = getPixelColor(device, 320, 240);
5241 todo_wine ok(color_match(color, 0x00ff0000, 1),
5242 "Expected color 0x00ff0000, got 0x%08x.\n", color);
5243 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5244 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5246 /* AddDirtyRect on the destination is ignored. */
5247 hr = IDirect3DTexture8_AddDirtyRect(tex_dst2, &part_rect);
5248 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
5249 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_green,
5250 (IDirect3DBaseTexture8 *)tex_dst2);
5251 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
5252 add_dirty_rect_test_draw(device);
5253 color = getPixelColor(device, 320, 240);
5254 todo_wine ok(color_match(color, 0x00ff0000, 1),
5255 "Expected color 0x00ff0000, got 0x%08x.\n", color);
5256 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5257 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5259 hr = IDirect3DTexture8_AddDirtyRect(tex_dst2, NULL);
5260 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
5261 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_green,
5262 (IDirect3DBaseTexture8 *)tex_dst2);
5263 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
5264 add_dirty_rect_test_draw(device);
5265 color = getPixelColor(device, 320, 240);
5266 todo_wine ok(color_match(color, 0x00ff0000, 1),
5267 "Expected color 0x00ff0000, got 0x%08x.\n", color);
5268 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5269 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5271 /* AddDirtyRect on the source makes UpdateTexture work. Partial rectangle
5272 * tracking is supported. */
5273 hr = IDirect3DTexture8_AddDirtyRect(tex_src_green, &part_rect);
5274 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
5275 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_green,
5276 (IDirect3DBaseTexture8 *)tex_dst2);
5277 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
5278 add_dirty_rect_test_draw(device);
5279 color = getPixelColor(device, 320, 240);
5280 ok(color_match(color, 0x0000ff00, 1),
5281 "Expected color 0x0000ff00, got 0x%08x.\n", color);
5282 color = getPixelColor(device, 1, 1);
5283 todo_wine ok(color_match(color, 0x00ff0000, 1),
5284 "Expected color 0x00ff0000, got 0x%08x.\n", color);
5285 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5286 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5288 hr = IDirect3DTexture8_AddDirtyRect(tex_src_green, NULL);
5289 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
5290 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_green,
5291 (IDirect3DBaseTexture8 *)tex_dst2);
5292 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
5293 add_dirty_rect_test_draw(device);
5294 color = getPixelColor(device, 1, 1);
5295 ok(color_match(color, 0x0000ff00, 1),
5296 "Expected color 0x0000ff00, got 0x%08x.\n", color);
5298 /* Locks with NO_DIRTY_UPDATE are ignored. */
5299 fill_surface(surface_src_green, 0x00000080, D3DLOCK_NO_DIRTY_UPDATE);
5300 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_green,
5301 (IDirect3DBaseTexture8 *)tex_dst2);
5302 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
5303 add_dirty_rect_test_draw(device);
5304 color = getPixelColor(device, 320, 240);
5305 todo_wine ok(color_match(color, 0x0000ff00, 1),
5306 "Expected color 0x0000ff00, got 0x%08x.\n", color);
5307 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5308 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5310 /* Readonly maps write to D3DPOOL_SYSTEMMEM, but don't record a dirty rectangle. */
5311 fill_surface(surface_src_green, 0x000000ff, D3DLOCK_READONLY);
5312 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_green,
5313 (IDirect3DBaseTexture8 *)tex_dst2);
5314 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
5315 add_dirty_rect_test_draw(device);
5316 color = getPixelColor(device, 320, 240);
5317 todo_wine ok(color_match(color, 0x0000ff00, 1),
5318 "Expected color 0x0000ff00, got 0x%08x.\n", color);
5319 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5320 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5322 hr = IDirect3DTexture8_AddDirtyRect(tex_src_green, NULL);
5323 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_green,
5324 (IDirect3DBaseTexture8 *)tex_dst2);
5325 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
5326 add_dirty_rect_test_draw(device);
5327 color = getPixelColor(device, 320, 240);
5328 ok(color_match(color, 0x000000ff, 1),
5329 "Expected color 0x000000ff, got 0x%08x.\n", color);
5330 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5331 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5333 /* Maps without either of these flags record a dirty rectangle. */
5334 fill_surface(surface_src_green, 0x00ffffff, 0);
5335 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_green,
5336 (IDirect3DBaseTexture8 *)tex_dst2);
5337 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
5338 add_dirty_rect_test_draw(device);
5339 color = getPixelColor(device, 320, 240);
5340 ok(color_match(color, 0x00ffffff, 1),
5341 "Expected color 0x00ffffff, got 0x%08x.\n", color);
5342 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5343 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5345 /* Partial LockRect works just like a partial AddDirtyRect call. */
5346 hr = IDirect3DTexture8_LockRect(tex_src_green, 0, &locked_rect, &part_rect, 0);
5347 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
5348 texel = locked_rect.pBits;
5349 for (i = 0; i < 64; i++)
5350 texel[i] = 0x00ff00ff;
5351 for (i = 1; i < 64; i++)
5352 memcpy((BYTE *)locked_rect.pBits + i * locked_rect.Pitch, locked_rect.pBits, locked_rect.Pitch);
5353 hr = IDirect3DTexture8_UnlockRect(tex_src_green, 0);
5354 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
5355 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_green,
5356 (IDirect3DBaseTexture8 *)tex_dst2);
5357 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
5358 add_dirty_rect_test_draw(device);
5359 color = getPixelColor(device, 320, 240);
5360 ok(color_match(color, 0x00ff00ff, 1),
5361 "Expected color 0x00ff00ff, got 0x%08x.\n", color);
5362 color = getPixelColor(device, 1, 1);
5363 ok(color_match(color, 0x00ffffff, 1),
5364 "Expected color 0x00ffffff, got 0x%08x.\n", color);
5365 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5366 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5368 fill_surface(surface_src_red, 0x00ff0000, 0);
5369 fill_surface(surface_src_green, 0x0000ff00, 0);
5371 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_green,
5372 (IDirect3DBaseTexture8 *)tex_dst1);
5373 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
5374 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)tex_dst1);
5375 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
5376 add_dirty_rect_test_draw(device);
5377 color = getPixelColor(device, 320, 240);
5378 ok(color_match(color, 0x0000ff00, 1),
5379 "Expected color 0x0000ff00, got 0x%08x.\n", color);
5380 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5381 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5383 /* UpdateSurface ignores the missing dirty marker. */
5384 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_red,
5385 (IDirect3DBaseTexture8 *)tex_dst2);
5386 hr = IDirect3DDevice8_CopyRects(device, surface_src_green, NULL, 0, surface_dst2, NULL);
5387 ok(SUCCEEDED(hr), "Failed to update surface, hr %#x.\n", hr);
5388 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)tex_dst2);
5389 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
5390 add_dirty_rect_test_draw(device);
5391 color = getPixelColor(device, 320, 240);
5392 ok(color_match(color, 0x0000ff00, 1),
5393 "Expected color 0x0000ff00, got 0x%08x.\n", color);
5394 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5395 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5397 fill_surface(surface_managed, 0x00ff0000, 0);
5398 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)tex_managed);
5399 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
5400 add_dirty_rect_test_draw(device);
5401 color = getPixelColor(device, 320, 240);
5402 ok(color_match(color, 0x00ff0000, 1),
5403 "Expected color 0x00ff0000, got 0x%08x.\n", color);
5404 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5405 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5407 /* Managed textures also honor D3DLOCK_NO_DIRTY_UPDATE. */
5408 fill_surface(surface_managed, 0x0000ff00, D3DLOCK_NO_DIRTY_UPDATE);
5409 add_dirty_rect_test_draw(device);
5410 color = getPixelColor(device, 320, 240);
5411 ok(color_match(color, 0x00ff0000, 1),
5412 "Expected color 0x00ff0000, got 0x%08x.\n", color);
5413 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5414 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5416 /* AddDirtyRect uploads the new contents.
5417 * Side note, not tested in the test: Partial surface updates work, and two separate
5418 * dirty rectangles are tracked individually. Tested on Nvidia Kepler, other drivers
5419 * untested. */
5420 hr = IDirect3DTexture8_AddDirtyRect(tex_managed, NULL);
5421 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
5422 add_dirty_rect_test_draw(device);
5423 color = getPixelColor(device, 320, 240);
5424 ok(color_match(color, 0x0000ff00, 1),
5425 "Expected color 0x0000ff00, got 0x%08x.\n", color);
5426 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5427 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5429 /* So does ResourceManagerDiscardBytes. */
5430 fill_surface(surface_managed, 0x000000ff, D3DLOCK_NO_DIRTY_UPDATE);
5431 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
5432 hr = IDirect3DDevice8_ResourceManagerDiscardBytes(device, 0);
5433 ok(SUCCEEDED(hr), "Failed to evict managed resources, hr %#x.\n", hr);
5434 add_dirty_rect_test_draw(device);
5435 color = getPixelColor(device, 320, 240);
5436 ok(color_match(color, 0x000000ff, 1),
5437 "Expected color 0x000000ff, got 0x%08x.\n", color);
5438 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5439 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5441 /* AddDirtyRect on a locked texture is allowed. */
5442 hr = IDirect3DTexture8_LockRect(tex_src_red, 0, &locked_rect, NULL, 0);
5443 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
5444 hr = IDirect3DTexture8_AddDirtyRect(tex_src_red, NULL);
5445 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
5446 hr = IDirect3DTexture8_UnlockRect(tex_src_red, 0);
5447 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
5449 /* Redundant AddDirtyRect calls are ok. */
5450 hr = IDirect3DTexture8_AddDirtyRect(tex_managed, NULL);
5451 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
5452 hr = IDirect3DTexture8_AddDirtyRect(tex_managed, NULL);
5453 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
5455 IDirect3DSurface8_Release(surface_dst2);
5456 IDirect3DSurface8_Release(surface_managed);
5457 IDirect3DSurface8_Release(surface_src_red);
5458 IDirect3DSurface8_Release(surface_src_green);
5459 IDirect3DTexture8_Release(tex_src_red);
5460 IDirect3DTexture8_Release(tex_src_green);
5461 IDirect3DTexture8_Release(tex_dst1);
5462 IDirect3DTexture8_Release(tex_dst2);
5463 IDirect3DTexture8_Release(tex_managed);
5464 refcount = IDirect3DDevice8_Release(device);
5465 ok(!refcount, "Device has %u references left.\n", refcount);
5466 done:
5467 IDirect3D8_Release(d3d);
5468 DestroyWindow(window);
5471 static void test_3dc_formats(void)
5473 static const char ati1n_data[] =
5475 /* A 4x4 texture with the color component at 50%. */
5476 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5478 static const char ati2n_data[] =
5480 /* A 8x4 texture consisting of 2 4x4 blocks. The first block has 50% first color component,
5481 * 0% second component. Second block is the opposite. */
5482 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5483 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5485 static const struct
5487 struct vec3 position;
5488 struct vec2 texcoord;
5490 quads[] =
5492 {{-1.0f, -1.0f, 0.0f}, {0.0f, 0.0f}},
5493 {{-1.0f, 1.0f, 0.0f}, {0.0f, 1.0f}},
5494 {{ 0.0f, -1.0f, 1.0f}, {1.0f, 0.0f}},
5495 {{ 0.0f, 1.0f, 1.0f}, {1.0f, 1.0f}},
5497 {{ 0.0f, -1.0f, 0.0f}, {0.0f, 0.0f}},
5498 {{ 0.0f, 1.0f, 0.0f}, {0.0f, 1.0f}},
5499 {{ 1.0f, -1.0f, 1.0f}, {1.0f, 0.0f}},
5500 {{ 1.0f, 1.0f, 1.0f}, {1.0f, 1.0f}},
5502 static const DWORD ati1n_fourcc = MAKEFOURCC('A','T','I','1');
5503 static const DWORD ati2n_fourcc = MAKEFOURCC('A','T','I','2');
5504 static const struct
5506 struct vec2 position;
5507 D3DCOLOR amd_r500;
5508 D3DCOLOR amd_r600;
5509 D3DCOLOR nvidia_old;
5510 D3DCOLOR nvidia_new;
5512 expected_colors[] =
5514 {{ 80, 240}, 0x007fffff, 0x003f3f3f, 0x007f7f7f, 0x007f0000},
5515 {{240, 240}, 0x007fffff, 0x003f3f3f, 0x007f7f7f, 0x007f0000},
5516 {{400, 240}, 0x00007fff, 0x00007fff, 0x00007fff, 0x00007fff},
5517 {{560, 240}, 0x007f00ff, 0x007f00ff, 0x007f00ff, 0x007f00ff},
5519 IDirect3D8 *d3d;
5520 IDirect3DDevice8 *device;
5521 IDirect3DTexture8 *ati1n_texture, *ati2n_texture;
5522 D3DCAPS8 caps;
5523 D3DLOCKED_RECT rect;
5524 D3DCOLOR color;
5525 ULONG refcount;
5526 HWND window;
5527 HRESULT hr;
5528 unsigned int i;
5530 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
5531 0, 0, 640, 480, NULL, NULL, NULL, NULL);
5532 d3d = Direct3DCreate8(D3D_SDK_VERSION);
5533 ok(!!d3d, "Failed to create a D3D object.\n");
5534 if (FAILED(IDirect3D8_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
5535 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, ati1n_fourcc)))
5537 skip("ATI1N textures are not supported, skipping test.\n");
5538 goto done;
5540 if (FAILED(IDirect3D8_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
5541 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, ati2n_fourcc)))
5543 skip("ATI2N textures are not supported, skipping test.\n");
5544 goto done;
5546 if (!(device = create_device(d3d, window, window, TRUE)))
5548 skip("Failed to create a D3D device, skipping tests.\n");
5549 goto done;
5551 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
5552 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
5553 if (!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP))
5555 skip("D3DTA_TEMP not supported, skipping tests.\n");
5556 IDirect3DDevice8_Release(device);
5557 goto done;
5560 hr = IDirect3DDevice8_CreateTexture(device, 4, 4, 1, 0, ati1n_fourcc,
5561 D3DPOOL_MANAGED, &ati1n_texture);
5562 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
5564 hr = IDirect3DTexture8_LockRect(ati1n_texture, 0, &rect, NULL, 0);
5565 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
5566 memcpy(rect.pBits, ati1n_data, sizeof(ati1n_data));
5567 hr = IDirect3DTexture8_UnlockRect(ati1n_texture, 0);
5568 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
5570 hr = IDirect3DDevice8_CreateTexture(device, 8, 4, 1, 0, ati2n_fourcc,
5571 D3DPOOL_MANAGED, &ati2n_texture);
5572 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
5574 hr = IDirect3DTexture8_LockRect(ati2n_texture, 0, &rect, NULL, 0);
5575 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
5576 memcpy(rect.pBits, ati2n_data, sizeof(ati2n_data));
5577 hr = IDirect3DTexture8_UnlockRect(ati2n_texture, 0);
5578 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
5580 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE2(0));
5581 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
5582 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BLENDTEXTUREALPHA);
5583 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
5584 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
5585 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
5586 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TEMP);
5587 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
5588 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
5589 ok(SUCCEEDED(hr), "Failed to set alpha op, hr %#x.\n", hr);
5590 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
5591 ok(SUCCEEDED(hr), "Failed to set alpha arg, hr %#x.\n", hr);
5592 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
5593 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
5594 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MAGFILTER, D3DTEXF_POINT);
5595 ok(SUCCEEDED(hr), "Failed to set mag filter, hr %#x.\n", hr);
5597 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff00ff, 1.0f, 0);
5598 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
5599 hr = IDirect3DDevice8_BeginScene(device);
5600 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5601 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)ati1n_texture);
5602 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
5603 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads));
5604 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5605 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)ati2n_texture);
5606 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
5607 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[4], sizeof(*quads));
5608 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5609 hr = IDirect3DDevice8_EndScene(device);
5610 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5612 for (i = 0; i < 4; ++i)
5614 color = getPixelColor(device, expected_colors[i].position.x, expected_colors[i].position.y);
5615 ok (color_match(color, expected_colors[i].amd_r500, 1)
5616 || color_match(color, expected_colors[i].amd_r600, 1)
5617 || color_match(color, expected_colors[i].nvidia_old, 1)
5618 || color_match(color, expected_colors[i].nvidia_new, 1),
5619 "Got unexpected color 0x%08x, case %u.\n", color, i);
5622 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5623 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5624 IDirect3DTexture8_Release(ati2n_texture);
5625 IDirect3DTexture8_Release(ati1n_texture);
5626 refcount = IDirect3DDevice8_Release(device);
5627 ok(!refcount, "Device has %u references left.\n", refcount);
5629 done:
5630 IDirect3D8_Release(d3d);
5631 DestroyWindow(window);
5634 static void test_fog_interpolation(void)
5636 HRESULT hr;
5637 IDirect3DDevice8 *device;
5638 IDirect3D8 *d3d;
5639 ULONG refcount;
5640 HWND window;
5641 D3DCOLOR color;
5642 static const struct
5644 struct vec3 position;
5645 D3DCOLOR diffuse;
5646 D3DCOLOR specular;
5648 quad[] =
5650 {{-1.0f, -1.0f, 0.0f}, 0xffff0000, 0xff000000},
5651 {{-1.0f, 1.0f, 0.0f}, 0xffff0000, 0xff000000},
5652 {{ 1.0f, -1.0f, 1.0f}, 0xffff0000, 0x00000000},
5653 {{ 1.0f, 1.0f, 1.0f}, 0xffff0000, 0x00000000},
5655 union
5657 DWORD d;
5658 float f;
5659 } conv;
5660 unsigned int i;
5661 static const struct
5663 D3DFOGMODE vfog, tfog;
5664 D3DSHADEMODE shade;
5665 D3DCOLOR middle_color;
5666 BOOL todo;
5668 tests[] =
5670 {D3DFOG_NONE, D3DFOG_NONE, D3DSHADE_FLAT, 0x00007f80, FALSE},
5671 {D3DFOG_NONE, D3DFOG_NONE, D3DSHADE_GOURAUD, 0x00007f80, FALSE},
5672 {D3DFOG_EXP, D3DFOG_NONE, D3DSHADE_FLAT, 0x00007f80, TRUE},
5673 {D3DFOG_EXP, D3DFOG_NONE, D3DSHADE_GOURAUD, 0x00007f80, TRUE},
5674 {D3DFOG_NONE, D3DFOG_EXP, D3DSHADE_FLAT, 0x0000ea15, FALSE},
5675 {D3DFOG_NONE, D3DFOG_EXP, D3DSHADE_GOURAUD, 0x0000ea15, FALSE},
5676 {D3DFOG_EXP, D3DFOG_EXP, D3DSHADE_FLAT, 0x0000ea15, FALSE},
5677 {D3DFOG_EXP, D3DFOG_EXP, D3DSHADE_GOURAUD, 0x0000ea15, FALSE},
5679 static const D3DMATRIX ident_mat =
5681 1.0f, 0.0f, 0.0f, 0.0f,
5682 0.0f, 1.0f, 0.0f, 0.0f,
5683 0.0f, 0.0f, 1.0f, 0.0f,
5684 0.0f, 0.0f, 0.0f, 1.0f
5685 }}};
5686 D3DCAPS8 caps;
5688 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
5689 0, 0, 640, 480, NULL, NULL, NULL, NULL);
5690 d3d = Direct3DCreate8(D3D_SDK_VERSION);
5691 ok(!!d3d, "Failed to create a D3D object.\n");
5693 if (!(device = create_device(d3d, window, window, TRUE)))
5695 skip("Failed to create a D3D device, skipping tests.\n");
5696 IDirect3D8_Release(d3d);
5697 DestroyWindow(window);
5698 return;
5701 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
5702 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
5703 if (!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE))
5704 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping some fog tests\n");
5706 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
5707 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr);
5708 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
5709 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
5710 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, FALSE);
5711 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
5712 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
5713 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
5714 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGCOLOR, 0x0000ff00);
5715 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
5716 conv.f = 5.0;
5717 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGDENSITY, conv.d);
5718 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
5720 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
5721 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
5722 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TFACTOR);
5723 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
5724 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x000000ff);
5725 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
5727 /* Some of the tests seem to depend on the projection matrix explicitly
5728 * being set to an identity matrix, even though that's the default.
5729 * (AMD Radeon X1600, AMD Radeon HD 6310, Windows 7). Without this,
5730 * the drivers seem to use a static z = 1.0 input for the fog equation.
5731 * The input value is independent of the actual z and w component of
5732 * the vertex position. */
5733 hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, &ident_mat);
5734 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
5736 for (i = 0; i < sizeof(tests) / sizeof(*tests); i++)
5738 if(!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE) && tests[i].tfog)
5739 continue;
5741 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00808080, 0.0f, 0);
5742 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
5744 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SHADEMODE, tests[i].shade);
5745 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
5746 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGVERTEXMODE, tests[i].vfog);
5747 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
5748 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGTABLEMODE, tests[i].tfog);
5749 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
5750 hr = IDirect3DDevice8_BeginScene(device);
5751 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5752 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
5753 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5754 hr = IDirect3DDevice8_EndScene(device);
5755 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5757 color = getPixelColor(device, 0, 240);
5758 ok(color_match(color, 0x000000ff, 2), "Got unexpected color 0x%08x, case %u.\n", color, i);
5759 color = getPixelColor(device, 320, 240);
5760 if (tests[i].todo)
5761 todo_wine ok(color_match(color, tests[i].middle_color, 2),
5762 "Got unexpected color 0x%08x, case %u.\n", color, i);
5763 else
5764 ok(color_match(color, tests[i].middle_color, 2),
5765 "Got unexpected color 0x%08x, case %u.\n", color, i);
5766 color = getPixelColor(device, 639, 240);
5767 ok(color_match(color, 0x0000fd02, 2), "Got unexpected color 0x%08x, case %u.\n", color, i);
5768 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5769 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5772 refcount = IDirect3DDevice8_Release(device);
5773 ok(!refcount, "Device has %u references left.\n", refcount);
5774 IDirect3D8_Release(d3d);
5775 DestroyWindow(window);
5778 static void test_negative_fixedfunction_fog(void)
5780 HRESULT hr;
5781 IDirect3DDevice8 *device;
5782 IDirect3D8 *d3d;
5783 ULONG refcount;
5784 HWND window;
5785 D3DCOLOR color;
5786 static const struct
5788 struct vec3 position;
5789 D3DCOLOR diffuse;
5791 quad[] =
5793 {{-1.0f, -1.0f, -0.5f}, 0xffff0000},
5794 {{-1.0f, 1.0f, -0.5f}, 0xffff0000},
5795 {{ 1.0f, -1.0f, -0.5f}, 0xffff0000},
5796 {{ 1.0f, 1.0f, -0.5f}, 0xffff0000},
5798 static const struct
5800 struct vec4 position;
5801 D3DCOLOR diffuse;
5803 tquad[] =
5805 {{ 0.0f, 0.0f, -0.5f, 1.0f}, 0xffff0000},
5806 {{640.0f, 0.0f, -0.5f, 1.0f}, 0xffff0000},
5807 {{ 0.0f, 480.0f, -0.5f, 1.0f}, 0xffff0000},
5808 {{640.0f, 480.0f, -0.5f, 1.0f}, 0xffff0000},
5810 unsigned int i;
5811 static const D3DMATRIX zero =
5813 1.0f, 0.0f, 0.0f, 0.0f,
5814 0.0f, 1.0f, 0.0f, 0.0f,
5815 0.0f, 0.0f, 0.0f, 0.0f,
5816 0.0f, 0.0f, 0.0f, 1.0f
5817 }}};
5818 /* Needed to make AMD drivers happy. Yeah, it is not supposed to
5819 * have an effect on RHW draws. */
5820 static const D3DMATRIX identity =
5822 1.0f, 0.0f, 0.0f, 0.0f,
5823 0.0f, 1.0f, 0.0f, 0.0f,
5824 0.0f, 0.0f, 1.0f, 0.0f,
5825 0.0f, 0.0f, 0.0f, 1.0f
5826 }}};
5827 static const struct
5829 DWORD pos_type;
5830 const void *quad;
5831 size_t stride;
5832 const D3DMATRIX *matrix;
5833 union
5835 float f;
5836 DWORD d;
5837 } start, end;
5838 D3DFOGMODE vfog, tfog;
5839 DWORD color, color_broken, color_broken2;
5841 tests[] =
5843 /* Run the XYZRHW tests first. Depth clamping is broken after RHW draws on the testbot.
5845 * Geforce8+ GPUs on Windows abs() table fog, everything else does not. */
5846 {D3DFVF_XYZRHW, tquad, sizeof(*tquad), &identity, { 0.0f}, {1.0f},
5847 D3DFOG_NONE, D3DFOG_LINEAR, 0x00ff0000, 0x00808000, 0x00808000},
5848 /* r200 GPUs and presumably all d3d8 and older HW clamp the fog
5849 * parameters to 0.0 and 1.0 in the table fog case. */
5850 {D3DFVF_XYZRHW, tquad, sizeof(*tquad), &identity, {-1.0f}, {0.0f},
5851 D3DFOG_NONE, D3DFOG_LINEAR, 0x00808000, 0x00ff0000, 0x0000ff00},
5852 /* test_fog_interpolation shows that vertex fog evaluates the fog
5853 * equation in the vertex pipeline. Start = -1.0 && end = 0.0 shows
5854 * that the abs happens before the fog equation is evaluated.
5856 * Vertex fog abs() behavior is the same on all GPUs. */
5857 {D3DFVF_XYZ, quad, sizeof(*quad), &zero, { 0.0f}, {1.0f},
5858 D3DFOG_LINEAR, D3DFOG_NONE, 0x00808000, 0x00808000, 0x00808000},
5859 {D3DFVF_XYZ, quad, sizeof(*quad), &zero, {-1.0f}, {0.0f},
5860 D3DFOG_LINEAR, D3DFOG_NONE, 0x0000ff00, 0x0000ff00, 0x0000ff00},
5861 {D3DFVF_XYZ, quad, sizeof(*quad), &zero, { 0.0f}, {1.0f},
5862 D3DFOG_EXP, D3DFOG_NONE, 0x009b6400, 0x009b6400, 0x009b6400},
5864 D3DCAPS8 caps;
5866 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
5867 0, 0, 640, 480, NULL, NULL, NULL, NULL);
5868 d3d = Direct3DCreate8(D3D_SDK_VERSION);
5869 ok(!!d3d, "Failed to create a D3D object.\n");
5871 if (!(device = create_device(d3d, window, window, TRUE)))
5873 skip("Failed to create a D3D device, skipping tests.\n");
5874 IDirect3D8_Release(d3d);
5875 DestroyWindow(window);
5876 return;
5879 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
5880 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
5881 if (!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE))
5882 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping some fog tests.\n");
5884 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
5885 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
5886 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
5887 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
5888 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
5889 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
5890 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGCOLOR, 0x0000ff00);
5891 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
5892 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, FALSE);
5893 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
5895 for (i = 0; i < sizeof(tests) / sizeof(*tests); i++)
5897 if (!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE) && tests[i].tfog)
5898 continue;
5900 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x000000ff, 0.0f, 0);
5901 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
5903 hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, tests[i].matrix);
5904 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
5905 hr = IDirect3DDevice8_SetVertexShader(device, tests[i].pos_type | D3DFVF_DIFFUSE);
5906 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr);
5907 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGSTART, tests[i].start.d);
5908 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
5909 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGEND, tests[i].end.d);
5910 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
5911 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGVERTEXMODE, tests[i].vfog);
5912 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
5913 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGTABLEMODE, tests[i].tfog);
5914 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
5916 hr = IDirect3DDevice8_BeginScene(device);
5917 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5918 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, tests[i].quad, tests[i].stride);
5919 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5920 hr = IDirect3DDevice8_EndScene(device);
5921 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5923 color = getPixelColor(device, 320, 240);
5924 ok(color_match(color, tests[i].color, 2) || broken(color_match(color, tests[i].color_broken, 2))
5925 || broken(color_match(color, tests[i].color_broken2, 2)),
5926 "Got unexpected color 0x%08x, case %u.\n", color, i);
5927 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5928 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5931 refcount = IDirect3DDevice8_Release(device);
5932 ok(!refcount, "Device has %u references left.\n", refcount);
5933 IDirect3D8_Release(d3d);
5934 DestroyWindow(window);
5937 static void test_table_fog_zw(void)
5939 HRESULT hr;
5940 IDirect3DDevice8 *device;
5941 IDirect3D8 *d3d;
5942 ULONG refcount;
5943 HWND window;
5944 D3DCOLOR color;
5945 D3DCAPS8 caps;
5946 static struct
5948 struct vec4 position;
5949 D3DCOLOR diffuse;
5951 quad[] =
5953 {{ 0.0f, 0.0f, 0.0f, 0.0f}, 0xffff0000},
5954 {{640.0f, 0.0f, 0.0f, 0.0f}, 0xffff0000},
5955 {{ 0.0f, 480.0f, 0.0f, 0.0f}, 0xffff0000},
5956 {{640.0f, 480.0f, 0.0f, 0.0f}, 0xffff0000},
5958 static const D3DMATRIX identity =
5960 1.0f, 0.0f, 0.0f, 0.0f,
5961 0.0f, 1.0f, 0.0f, 0.0f,
5962 0.0f, 0.0f, 1.0f, 0.0f,
5963 0.0f, 0.0f, 0.0f, 1.0f
5964 }}};
5965 static const struct
5967 float z, w;
5968 D3DZBUFFERTYPE z_test;
5969 D3DCOLOR color;
5971 tests[] =
5973 {0.7f, 0.0f, D3DZB_TRUE, 0x004cb200},
5974 {0.7f, 0.0f, D3DZB_FALSE, 0x004cb200},
5975 {0.7f, 0.3f, D3DZB_TRUE, 0x004cb200},
5976 {0.7f, 0.3f, D3DZB_FALSE, 0x004cb200},
5977 {0.7f, 3.0f, D3DZB_TRUE, 0x004cb200},
5978 {0.7f, 3.0f, D3DZB_FALSE, 0x004cb200},
5979 {0.3f, 0.0f, D3DZB_TRUE, 0x00b24c00},
5980 {0.3f, 0.0f, D3DZB_FALSE, 0x00b24c00},
5982 unsigned int i;
5984 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
5985 0, 0, 640, 480, NULL, NULL, NULL, NULL);
5986 d3d = Direct3DCreate8(D3D_SDK_VERSION);
5987 ok(!!d3d, "Failed to create a D3D object.\n");
5989 if (!(device = create_device(d3d, window, window, TRUE)))
5991 skip("Failed to create a D3D device, skipping tests.\n");
5992 IDirect3D8_Release(d3d);
5993 DestroyWindow(window);
5994 return;
5997 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
5998 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
5999 if (!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE))
6001 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping POSITIONT table fog test.\n");
6002 goto done;
6005 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6006 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6007 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
6008 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6009 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGCOLOR, 0x0000ff00);
6010 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6011 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, FALSE);
6012 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
6013 /* Work around an AMD Windows driver bug. Needs a proj matrix applied redundantly. */
6014 hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, &identity);
6015 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
6016 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
6017 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6018 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
6019 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr);
6021 for (i = 0; i < sizeof(tests) / sizeof(*tests); ++i)
6023 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
6024 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
6026 quad[0].position.z = tests[i].z;
6027 quad[1].position.z = tests[i].z;
6028 quad[2].position.z = tests[i].z;
6029 quad[3].position.z = tests[i].z;
6030 quad[0].position.w = tests[i].w;
6031 quad[1].position.w = tests[i].w;
6032 quad[2].position.w = tests[i].w;
6033 quad[3].position.w = tests[i].w;
6034 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, tests[i].z_test);
6035 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6037 hr = IDirect3DDevice8_BeginScene(device);
6038 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6039 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
6040 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6041 hr = IDirect3DDevice8_EndScene(device);
6042 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6044 color = getPixelColor(device, 320, 240);
6045 ok(color_match(color, tests[i].color, 2),
6046 "Got unexpected color 0x%08x, expected 0x%08x, case %u.\n", color, tests[i].color, i);
6047 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
6048 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
6051 done:
6052 refcount = IDirect3DDevice8_Release(device);
6053 ok(!refcount, "Device has %u references left.\n", refcount);
6054 IDirect3D8_Release(d3d);
6055 DestroyWindow(window);
6058 static void test_signed_formats(void)
6060 IDirect3DDevice8 *device;
6061 HWND window;
6062 HRESULT hr;
6063 unsigned int i, j, x, y;
6064 IDirect3DTexture8 *texture, *texture_sysmem;
6065 D3DLOCKED_RECT locked_rect;
6066 DWORD shader, shader_alpha;
6067 IDirect3D8 *d3d;
6068 D3DCOLOR color;
6069 D3DCAPS8 caps;
6070 ULONG refcount;
6072 /* See comments in the d3d9 version of this test for an
6073 * explanation of these values. */
6074 static const USHORT content_v8u8[4][4] =
6076 {0x0000, 0x7f7f, 0x8880, 0x0000},
6077 {0x0080, 0x8000, 0x7f00, 0x007f},
6078 {0x193b, 0xe8c8, 0x0808, 0xf8f8},
6079 {0x4444, 0xc0c0, 0xa066, 0x22e0},
6081 static const DWORD content_v16u16[4][4] =
6083 {0x00000000, 0x7fff7fff, 0x88008000, 0x00000000},
6084 {0x00008000, 0x80000000, 0x7fff0000, 0x00007fff},
6085 {0x19993bbb, 0xe800c800, 0x08880888, 0xf800f800},
6086 {0x44444444, 0xc000c000, 0xa0006666, 0x2222e000},
6088 static const DWORD content_q8w8v8u8[4][4] =
6090 {0x00000000, 0xff7f7f7f, 0x7f008880, 0x817f0000},
6091 {0x10000080, 0x20008000, 0x30007f00, 0x4000007f},
6092 {0x5020193b, 0x6028e8c8, 0x70020808, 0x807ff8f8},
6093 {0x90414444, 0xa000c0c0, 0x8261a066, 0x834922e0},
6095 static const DWORD content_x8l8v8u8[4][4] =
6097 {0x00000000, 0x00ff7f7f, 0x00008880, 0x00ff0000},
6098 {0x00000080, 0x00008000, 0x00007f00, 0x0000007f},
6099 {0x0041193b, 0x0051e8c8, 0x00040808, 0x00fff8f8},
6100 {0x00824444, 0x0000c0c0, 0x00c2a066, 0x009222e0},
6102 static const USHORT content_l6v5u5[4][4] =
6104 {0x0000, 0xfdef, 0x0230, 0xfc00},
6105 {0x0010, 0x0200, 0x01e0, 0x000f},
6106 {0x4067, 0x53b9, 0x0421, 0xffff},
6107 {0x8108, 0x0318, 0xc28c, 0x909c},
6109 static const struct
6111 D3DFORMAT format;
6112 const char *name;
6113 const void *content;
6114 SIZE_T pixel_size;
6115 BOOL blue, alpha;
6116 unsigned int slop, slop_broken, alpha_broken;
6118 formats[] =
6120 {D3DFMT_V8U8, "D3DFMT_V8U8", content_v8u8, sizeof(WORD), FALSE, FALSE, 1, 0, FALSE},
6121 {D3DFMT_V16U16, "D3DFMT_V16U16", content_v16u16, sizeof(DWORD), FALSE, FALSE, 1, 0, FALSE},
6122 {D3DFMT_Q8W8V8U8, "D3DFMT_Q8W8V8U8", content_q8w8v8u8, sizeof(DWORD), TRUE, TRUE, 1, 0, TRUE },
6123 {D3DFMT_X8L8V8U8, "D3DFMT_X8L8V8U8", content_x8l8v8u8, sizeof(DWORD), TRUE, FALSE, 1, 0, FALSE},
6124 {D3DFMT_L6V5U5, "D3DFMT_L6V5U5", content_l6v5u5, sizeof(WORD), TRUE, FALSE, 4, 7, FALSE},
6126 static const struct
6128 D3DPOOL pool;
6129 UINT width;
6131 tests[] =
6133 {D3DPOOL_SYSTEMMEM, 4},
6134 {D3DPOOL_SYSTEMMEM, 1},
6135 {D3DPOOL_MANAGED, 4},
6136 {D3DPOOL_MANAGED, 1},
6138 static const DWORD shader_code[] =
6140 0xffff0101, /* ps_1_1 */
6141 0x00000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, /* def c0, 0.5, 0.5, 0,5, 0,5 */
6142 0x00000042, 0xb00f0000, /* tex t0 */
6143 0x00000004, 0x800f0000, 0xb0e40000, 0xa0e40000, 0xa0e40000, /* mad r0, t0, c0, c0 */
6144 0x0000ffff /* end */
6146 static const DWORD shader_code_alpha[] =
6148 /* The idea of this shader is to replicate the alpha value in .rg, and set
6149 * blue to 1.0 iff the alpha value is < -1.0 and 0.0 otherwise. */
6150 0xffff0101, /* ps_1_1 */
6151 0x00000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, /* def c0, 0.5, 0.5, 0.5, 0.5 */
6152 0x00000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0 */
6153 0x00000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c2, 0.0, 0.0, 1.0, 0.0 */
6154 0x00000042, 0xb00f0000, /* tex t0 */
6155 0x00000004, 0x80070000, 0xb0ff0000, 0xa0e40000, 0xa0e40000, /* mad r0.rgb, t0.a, c0, c0 */
6156 0x00000003, 0x80080000, 0xb1ff0000, 0xa0e40000, /* sub r0.a, -t0.a, c0 */
6157 0x00000050, 0x80080000, 0x80ff0000, 0xa0ff0001, 0xa0ff0002, /* cnd r0.a, r0.a, c1.a, c2.a */
6158 0x00000005, 0x80070001, 0xa0e40001, 0x80e40000, /* mul r1.rgb, c1, r0 */
6159 0x00000004, 0x80070000, 0x80ff0000, 0xa0e40002, 0x80e40001, /* mad r0.rgb, r0.a, c2, r1 */
6160 0x0000ffff /* end */
6162 static const struct
6164 struct vec3 position;
6165 struct vec2 texcrd;
6167 quad[] =
6169 /* Flip the y coordinate to make the input and
6170 * output arrays easier to compare. */
6171 {{ -1.0f, -1.0f, 0.0f}, { 0.0f, 1.0f}},
6172 {{ -1.0f, 1.0f, 0.0f}, { 0.0f, 0.0f}},
6173 {{ 1.0f, -1.0f, 0.0f}, { 1.0f, 1.0f}},
6174 {{ 1.0f, 1.0f, 0.0f}, { 1.0f, 0.0f}},
6176 static const D3DCOLOR expected_alpha[4][4] =
6178 {0x00808000, 0x007f7f00, 0x00ffff00, 0x00000000},
6179 {0x00909000, 0x00a0a000, 0x00b0b000, 0x00c0c000},
6180 {0x00d0d000, 0x00e0e000, 0x00f0f000, 0x00000000},
6181 {0x00101000, 0x00202000, 0x00010100, 0x00020200},
6183 static const BOOL alpha_broken[4][4] =
6185 {FALSE, FALSE, FALSE, FALSE},
6186 {FALSE, FALSE, FALSE, FALSE},
6187 {FALSE, FALSE, FALSE, TRUE },
6188 {FALSE, FALSE, FALSE, FALSE},
6190 static const D3DCOLOR expected_colors[4][4] =
6192 {0x00808080, 0x00fefeff, 0x00010780, 0x008080ff},
6193 {0x00018080, 0x00800180, 0x0080fe80, 0x00fe8080},
6194 {0x00ba98a0, 0x004767a8, 0x00888881, 0x007878ff},
6195 {0x00c3c3c0, 0x003f3f80, 0x00e51fe1, 0x005fa2c8},
6197 D3DCOLOR expected_color;
6199 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
6200 0, 0, 640, 480, NULL, NULL, NULL, NULL);
6201 d3d = Direct3DCreate8(D3D_SDK_VERSION);
6202 ok(!!d3d, "Failed to create a D3D object.\n");
6204 if (!(device = create_device(d3d, window, window, TRUE)))
6206 skip("Failed to create a D3D device, skipping tests.\n");
6207 IDirect3D8_Release(d3d);
6208 DestroyWindow(window);
6209 return;
6212 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
6213 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
6215 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 1))
6217 skip("Pixel shaders not supported, skipping converted format test.\n");
6218 goto done;
6221 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
6222 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6223 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX1);
6224 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
6225 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code, &shader);
6226 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
6227 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code_alpha, &shader_alpha);
6228 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
6230 for (i = 0; i < sizeof(formats) / sizeof(*formats); i++)
6232 hr = IDirect3D8_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
6233 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, formats[i].format);
6234 if (FAILED(hr))
6236 skip("Format %s not supported, skipping.\n", formats[i].name);
6237 continue;
6240 for (j = 0; j < sizeof(tests) / sizeof(*tests); j++)
6242 texture_sysmem = NULL;
6243 hr = IDirect3DDevice8_CreateTexture(device, tests[j].width, 4, 1, 0,
6244 formats[i].format, tests[j].pool, &texture);
6245 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
6247 hr = IDirect3DTexture8_LockRect(texture, 0, &locked_rect, NULL, 0);
6248 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
6249 for (y = 0; y < 4; y++)
6251 memcpy((char *)locked_rect.pBits + y * locked_rect.Pitch,
6252 (char *)formats[i].content + y * 4 * formats[i].pixel_size,
6253 tests[j].width * formats[i].pixel_size);
6255 hr = IDirect3DTexture8_UnlockRect(texture, 0);
6256 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
6258 if (tests[j].pool == D3DPOOL_SYSTEMMEM)
6260 texture_sysmem = texture;
6261 hr = IDirect3DDevice8_CreateTexture(device, tests[j].width, 4, 1, 0,
6262 formats[i].format, D3DPOOL_DEFAULT, &texture);
6263 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
6265 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)texture_sysmem,
6266 (IDirect3DBaseTexture8 *)texture);
6267 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
6268 IDirect3DTexture8_Release(texture_sysmem);
6271 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
6272 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
6273 hr = IDirect3DDevice8_SetPixelShader(device, shader_alpha);
6274 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6276 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00330033, 0.0f, 0);
6277 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
6278 hr = IDirect3DDevice8_BeginScene(device);
6279 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6280 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(*quad));
6281 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6282 hr = IDirect3DDevice8_EndScene(device);
6283 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6285 for (y = 0; y < 4; y++)
6287 for (x = 0; x < tests[j].width; x++)
6289 BOOL r200_broken = formats[i].alpha_broken && alpha_broken[y][x];
6290 if (formats[i].alpha)
6291 expected_color = expected_alpha[y][x];
6292 else
6293 expected_color = 0x00ffff00;
6295 color = getPixelColor(device, 80 + 160 * x, 60 + 120 * y);
6296 ok(color_match(color, expected_color, 1) || broken(r200_broken),
6297 "Expected color 0x%08x, got 0x%08x, format %s, location %ux%u.\n",
6298 expected_color, color, formats[i].name, x, y);
6301 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
6302 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
6304 hr = IDirect3DDevice8_SetPixelShader(device, shader);
6305 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6307 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00330033, 0.0f, 0);
6308 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
6309 hr = IDirect3DDevice8_BeginScene(device);
6310 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6311 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(*quad));
6312 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6313 hr = IDirect3DDevice8_EndScene(device);
6314 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6316 for (y = 0; y < 4; y++)
6318 for (x = 0; x < tests[j].width; x++)
6320 expected_color = expected_colors[y][x];
6321 if (!formats[i].blue)
6322 expected_color |= 0x000000ff;
6324 color = getPixelColor(device, 80 + 160 * x, 60 + 120 * y);
6325 ok(color_match(color, expected_color, formats[i].slop)
6326 || broken(color_match(color, expected_color, formats[i].slop_broken)),
6327 "Expected color 0x%08x, got 0x%08x, format %s, location %ux%u.\n",
6328 expected_color, color, formats[i].name, x, y);
6331 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
6332 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
6334 IDirect3DTexture8_Release(texture);
6338 IDirect3DDevice8_DeletePixelShader(device, shader);
6339 IDirect3DDevice8_DeletePixelShader(device, shader_alpha);
6341 done:
6342 refcount = IDirect3DDevice8_Release(device);
6343 ok(!refcount, "Device has %u references left.\n", refcount);
6344 IDirect3D8_Release(d3d);
6345 DestroyWindow(window);
6348 static BOOL point_match(IDirect3DDevice8 *device, UINT x, UINT y, UINT r)
6350 D3DCOLOR color;
6352 color = D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff);
6353 if (!color_match(getPixelColor(device, x + r, y), color, 1))
6354 return FALSE;
6355 if (!color_match(getPixelColor(device, x - r, y), color, 1))
6356 return FALSE;
6357 if (!color_match(getPixelColor(device, x, y + r), color, 1))
6358 return FALSE;
6359 if (!color_match(getPixelColor(device, x, y - r), color, 1))
6360 return FALSE;
6362 ++r;
6363 color = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff);
6364 if (!color_match(getPixelColor(device, x + r, y), color, 1))
6365 return FALSE;
6366 if (!color_match(getPixelColor(device, x - r, y), color, 1))
6367 return FALSE;
6368 if (!color_match(getPixelColor(device, x, y + r), color, 1))
6369 return FALSE;
6370 if (!color_match(getPixelColor(device, x, y - r), color, 1))
6371 return FALSE;
6373 return TRUE;
6376 static void test_pointsize(void)
6378 static const float a = 0.5f, b = 0.5f, c = 0.5f;
6379 float ptsize, ptsizemax_orig, ptsizemin_orig;
6380 IDirect3DSurface8 *rt, *backbuffer, *depthstencil;
6381 IDirect3DTexture8 *tex1, *tex2;
6382 IDirect3DDevice8 *device;
6383 DWORD vs, ps;
6384 D3DLOCKED_RECT lr;
6385 IDirect3D8 *d3d;
6386 D3DCOLOR color;
6387 ULONG refcount;
6388 D3DCAPS8 caps;
6389 HWND window;
6390 HRESULT hr;
6391 unsigned int i, j;
6393 static const DWORD tex1_data[4] = {0x00ff0000, 0x00ff0000, 0x00000000, 0x00000000};
6394 static const DWORD tex2_data[4] = {0x00000000, 0x0000ff00, 0x00000000, 0x0000ff00};
6395 static const float vertices[] =
6397 64.0f, 64.0f, 0.1f,
6398 128.0f, 64.0f, 0.1f,
6399 192.0f, 64.0f, 0.1f,
6400 256.0f, 64.0f, 0.1f,
6401 320.0f, 64.0f, 0.1f,
6402 384.0f, 64.0f, 0.1f,
6403 448.0f, 64.0f, 0.1f,
6404 512.0f, 64.0f, 0.1f,
6406 static const struct
6408 float x, y, z;
6409 float point_size;
6411 vertex_pointsize = {64.0f, 64.0f, 0.1f, 48.0f},
6412 vertex_pointsize_scaled = {64.0f, 64.0f, 0.1f, 24.0f},
6413 vertex_pointsize_zero = {64.0f, 64.0f, 0.1f, 0.0f};
6414 static const DWORD decl[] =
6416 D3DVSD_STREAM(0),
6417 D3DVSD_REG(0, D3DVSDT_FLOAT3), /* position */
6418 D3DVSD_END()
6420 decl_psize[] =
6422 D3DVSD_STREAM(0),
6423 D3DVSD_REG(0, D3DVSDT_FLOAT3), /* position, v0 */
6424 D3DVSD_REG(1, D3DVSDT_FLOAT1), /* point size, v1 */
6425 D3DVSD_END()
6427 static const DWORD vshader_code[] =
6429 0xfffe0101, /* vs_1_1 */
6430 0x00000005, 0x800f0000, 0x90000000, 0xa0e40000, /* mul r0, v0.x, c0 */
6431 0x00000004, 0x800f0000, 0x90550000, 0xa0e40001, 0x80e40000, /* mad r0, v0.y, c1, r0 */
6432 0x00000004, 0x800f0000, 0x90aa0000, 0xa0e40002, 0x80e40000, /* mad r0, v0.z, c2, r0 */
6433 0x00000004, 0xc00f0000, 0x90ff0000, 0xa0e40003, 0x80e40000, /* mad oPos, v0.w, c3, r0 */
6434 0x0000ffff
6436 static const DWORD vshader_psize_code[] =
6438 0xfffe0101, /* vs_1_1 */
6439 0x00000005, 0x800f0000, 0x90000000, 0xa0e40000, /* mul r0, v0.x, c0 */
6440 0x00000004, 0x800f0000, 0x90550000, 0xa0e40001, 0x80e40000, /* mad r0, v0.y, c1, r0 */
6441 0x00000004, 0x800f0000, 0x90aa0000, 0xa0e40002, 0x80e40000, /* mad r0, v0.z, c2, r0 */
6442 0x00000004, 0xc00f0000, 0x90ff0000, 0xa0e40003, 0x80e40000, /* mad oPos, v0.w, c3, r0 */
6443 0x00000001, 0xc00f0002, 0x90000001, /* mov oPts, v1.x */
6444 0x0000ffff
6446 static const DWORD pshader_code[] =
6448 0xffff0101, /* ps_1_1 */
6449 0x00000042, 0xb00f0000, /* tex t0 */
6450 0x00000042, 0xb00f0001, /* tex t1 */
6451 0x00000002, 0x800f0000, 0xb0e40000, 0xb0e40001, /* add r0, t0, t1 */
6452 0x0000ffff
6454 static const struct test_shader
6456 DWORD version;
6457 const DWORD *code;
6459 novs = {0, NULL},
6460 vs1 = {D3DVS_VERSION(1, 1), vshader_code},
6461 vs1_psize = {D3DVS_VERSION(1, 1), vshader_psize_code},
6462 nops = {0, NULL},
6463 ps1 = {D3DPS_VERSION(1, 1), pshader_code};
6464 static const struct
6466 const DWORD *decl;
6467 const struct test_shader *vs;
6468 const struct test_shader *ps;
6469 DWORD accepted_fvf;
6470 unsigned int nonscaled_size, scaled_size;
6472 test_setups[] =
6474 {NULL, &novs, &nops, D3DFVF_XYZ, 32, 62},
6475 {decl, &vs1, &ps1, D3DFVF_XYZ, 32, 32},
6476 {NULL, &novs, &ps1, D3DFVF_XYZ, 32, 62},
6477 {decl, &vs1, &nops, D3DFVF_XYZ, 32, 32},
6478 /* {NULL, &novs, &nops, D3DFVF_XYZ | D3DFVF_PSIZE, 48, 48}, */
6479 {decl_psize, &vs1_psize, &ps1, D3DFVF_XYZ | D3DFVF_PSIZE, 48, 24},
6481 static const struct
6483 BOOL zero_size;
6484 BOOL scale;
6485 BOOL override_min;
6486 DWORD fvf;
6487 const void *vertex_data;
6488 unsigned int vertex_size;
6490 tests[] =
6492 {FALSE, FALSE, FALSE, D3DFVF_XYZ, vertices, sizeof(float) * 3},
6493 {FALSE, TRUE, FALSE, D3DFVF_XYZ, vertices, sizeof(float) * 3},
6494 {FALSE, FALSE, TRUE, D3DFVF_XYZ, vertices, sizeof(float) * 3},
6495 {TRUE, FALSE, FALSE, D3DFVF_XYZ, vertices, sizeof(float) * 3},
6496 {FALSE, FALSE, FALSE, D3DFVF_XYZ | D3DFVF_PSIZE, &vertex_pointsize, sizeof(vertex_pointsize)},
6497 {FALSE, TRUE, FALSE, D3DFVF_XYZ | D3DFVF_PSIZE, &vertex_pointsize_scaled, sizeof(vertex_pointsize_scaled)},
6498 {FALSE, FALSE, TRUE, D3DFVF_XYZ | D3DFVF_PSIZE, &vertex_pointsize, sizeof(vertex_pointsize)},
6499 {TRUE, FALSE, FALSE, D3DFVF_XYZ | D3DFVF_PSIZE, &vertex_pointsize_zero, sizeof(vertex_pointsize_zero)},
6501 /* Transforms the coordinate system [-1.0;1.0]x[1.0;-1.0] to
6502 * [0.0;0.0]x[640.0;480.0]. Z is untouched. */
6503 D3DMATRIX matrix =
6505 2.0f / 640.0f, 0.0f, 0.0f, 0.0f,
6506 0.0f, -2.0f / 480.0f, 0.0f, 0.0f,
6507 0.0f, 0.0f, 1.0f, 0.0f,
6508 -1.0f, 1.0f, 0.0f, 1.0f,
6509 }}};
6511 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
6512 0, 0, 640, 480, NULL, NULL, NULL, NULL);
6513 d3d = Direct3DCreate8(D3D_SDK_VERSION);
6514 ok(!!d3d, "Failed to create a D3D object.\n");
6515 if (!(device = create_device(d3d, window, window, TRUE)))
6517 skip("Failed to create a D3D device, skipping tests.\n");
6518 goto done;
6521 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
6522 ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
6523 if (caps.MaxPointSize < 32.0f)
6525 skip("MaxPointSize %f < 32.0, skipping.\n", caps.MaxPointSize);
6526 IDirect3DDevice8_Release(device);
6527 goto done;
6530 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
6531 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
6532 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6533 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
6534 hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, &matrix);
6535 ok(SUCCEEDED(hr), "Failed to set projection matrix, hr %#x.\n", hr);
6536 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ);
6537 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
6539 hr = IDirect3DDevice8_BeginScene(device);
6540 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6542 ptsize = 15.0f;
6543 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
6544 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6545 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
6546 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6548 ptsize = 31.0f;
6549 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
6550 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6551 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[3], sizeof(float) * 3);
6552 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6554 ptsize = 30.75f;
6555 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
6556 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6557 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[6], sizeof(float) * 3);
6558 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6560 if (caps.MaxPointSize >= 63.0f)
6562 ptsize = 63.0f;
6563 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
6564 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6565 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[9], sizeof(float) * 3);
6566 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6568 ptsize = 62.75f;
6569 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
6570 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6571 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[15], sizeof(float) * 3);
6572 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6575 ptsize = 1.0f;
6576 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
6577 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6578 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[12], sizeof(float) * 3);
6579 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6581 hr = IDirect3DDevice8_GetRenderState(device, D3DRS_POINTSIZE_MAX, (DWORD *)&ptsizemax_orig);
6582 ok(SUCCEEDED(hr), "Failed to get render state, hr %#x.\n", hr);
6583 hr = IDirect3DDevice8_GetRenderState(device, D3DRS_POINTSIZE_MIN, (DWORD *)&ptsizemin_orig);
6584 ok(SUCCEEDED(hr), "Failed to get render state, hr %#x.\n", hr);
6586 /* What happens if point scaling is disabled, and POINTSIZE_MAX < POINTSIZE? */
6587 ptsize = 15.0f;
6588 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
6589 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6590 ptsize = 1.0f;
6591 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE_MAX, *(DWORD *)&ptsize);
6592 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6593 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[18], sizeof(float) * 3);
6594 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6596 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE_MAX, *(DWORD *)&ptsizemax_orig);
6597 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6599 /* pointsize < pointsize_min < pointsize_max?
6600 * pointsize = 1.0, pointsize_min = 15.0, pointsize_max = default(usually 64.0) */
6601 ptsize = 1.0f;
6602 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
6603 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6604 ptsize = 15.0f;
6605 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE_MIN, *(DWORD *)&ptsize);
6606 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6607 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[21], sizeof(float) * 3);
6608 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6610 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE_MIN, *(DWORD *)&ptsizemin_orig);
6611 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6613 hr = IDirect3DDevice8_EndScene(device);
6614 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6616 ok(point_match(device, 64, 64, 7), "point_match(64, 64, 7) failed, expected point size 15.\n");
6617 ok(point_match(device, 128, 64, 15), "point_match(128, 64, 15) failed, expected point size 31.\n");
6618 ok(point_match(device, 192, 64, 15), "point_match(192, 64, 15) failed, expected point size 31.\n");
6620 if (caps.MaxPointSize >= 63.0f)
6622 ok(point_match(device, 256, 64, 31), "point_match(256, 64, 31) failed, expected point size 63.\n");
6623 ok(point_match(device, 384, 64, 31), "point_match(384, 64, 31) failed, expected point size 63.\n");
6626 ok(point_match(device, 320, 64, 0), "point_match(320, 64, 0) failed, expected point size 1.\n");
6627 /* ptsize = 15, ptsize_max = 1 --> point has size 1 */
6628 ok(point_match(device, 448, 64, 0), "point_match(448, 64, 0) failed, expected point size 1.\n");
6629 /* ptsize = 1, ptsize_max = default(64), ptsize_min = 15 --> point has size 15 */
6630 ok(point_match(device, 512, 64, 7), "point_match(512, 64, 7) failed, expected point size 15.\n");
6632 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
6634 /* The following code tests point sprites with two textures, to see if each texture coordinate unit
6635 * generates texture coordinates for the point(result: Yes, it does)
6637 * However, not all GL implementations support point sprites(they need GL_ARB_point_sprite), but there
6638 * is no point sprite cap bit in d3d because native d3d software emulates point sprites. Until the
6639 * SW emulation is implemented in wined3d, this test will fail on GL drivers that does not support them.
6641 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
6642 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
6644 hr = IDirect3DDevice8_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex1);
6645 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
6646 hr = IDirect3DDevice8_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex2);
6647 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
6648 memset(&lr, 0, sizeof(lr));
6649 hr = IDirect3DTexture8_LockRect(tex1, 0, &lr, NULL, 0);
6650 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
6651 memcpy(lr.pBits, tex1_data, sizeof(tex1_data));
6652 hr = IDirect3DTexture8_UnlockRect(tex1, 0);
6653 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
6654 memset(&lr, 0, sizeof(lr));
6655 hr = IDirect3DTexture8_LockRect(tex2, 0, &lr, NULL, 0);
6656 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
6657 memcpy(lr.pBits, tex2_data, sizeof(tex2_data));
6658 hr = IDirect3DTexture8_UnlockRect(tex2, 0);
6659 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
6660 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)tex1);
6661 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
6662 hr = IDirect3DDevice8_SetTexture(device, 1, (IDirect3DBaseTexture8 *)tex2);
6663 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
6664 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
6665 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
6666 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
6667 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
6668 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
6669 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
6670 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
6671 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
6672 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
6673 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
6675 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSPRITEENABLE, TRUE);
6676 ok(SUCCEEDED(hr), "Failed to enable point sprites, hr %#x.\n", hr);
6677 ptsize = 32.0f;
6678 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
6679 ok(SUCCEEDED(hr), "Failed to set point size, hr %#x.\n", hr);
6681 hr = IDirect3DDevice8_BeginScene(device);
6682 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6683 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
6684 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6685 hr = IDirect3DDevice8_EndScene(device);
6686 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6688 color = getPixelColor(device, 64 - 4, 64 - 4);
6689 ok(color == 0x00ff0000, "pSprite: Pixel (64 - 4),(64 - 4) has color 0x%08x, expected 0x00ff0000\n", color);
6690 color = getPixelColor(device, 64 - 4, 64 + 4);
6691 ok(color == 0x00000000, "pSprite: Pixel (64 - 4),(64 + 4) has color 0x%08x, expected 0x00000000\n", color);
6692 color = getPixelColor(device, 64 + 4, 64 + 4);
6693 ok(color == 0x0000ff00, "pSprite: Pixel (64 + 4),(64 + 4) has color 0x%08x, expected 0x0000ff00\n", color);
6694 color = getPixelColor(device, 64 + 4, 64 - 4);
6695 ok(color == 0x00ffff00, "pSprite: Pixel (64 + 4),(64 - 4) has color 0x%08x, expected 0x00ffff00\n", color);
6696 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
6698 U(matrix).m[0][0] = 1.0f / 64.0f;
6699 U(matrix).m[1][1] = -1.0f / 64.0f;
6700 hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, &matrix);
6701 ok(SUCCEEDED(hr), "Failed to set projection matrix, hr %#x.\n", hr);
6703 hr = IDirect3DDevice8_GetRenderTarget(device, &backbuffer);
6704 ok(SUCCEEDED(hr), "Failed to get backbuffer, hr %#x.\n", hr);
6705 hr = IDirect3DDevice8_GetDepthStencilSurface(device, &depthstencil);
6706 ok(SUCCEEDED(hr), "Failed to get depth / stencil buffer, hr %#x.\n", hr);
6708 hr = IDirect3DDevice8_CreateRenderTarget(device, 128, 128, D3DFMT_A8R8G8B8,
6709 D3DMULTISAMPLE_NONE, TRUE, &rt);
6710 ok(SUCCEEDED(hr), "Failed to create a render target, hr %#x.\n", hr);
6712 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSCALE_A, *(DWORD *)&a);
6713 ok(SUCCEEDED(hr), "Failed setting point scale attenuation coefficient, hr %#x.\n", hr);
6714 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSCALE_B, *(DWORD *)&b);
6715 ok(SUCCEEDED(hr), "Failed setting point scale attenuation coefficient, hr %#x.\n", hr);
6716 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSCALE_C, *(DWORD *)&c);
6717 ok(SUCCEEDED(hr), "Failed setting point scale attenuation coefficient, hr %#x.\n", hr);
6718 hr = IDirect3DDevice8_SetVertexShaderConstant(device, 0, &S(U(matrix))._11, 4);
6719 ok(SUCCEEDED(hr), "Failed to set vertex shader constants, hr %#x.\n", hr);
6721 if (caps.MaxPointSize < 63.0f)
6723 skip("MaxPointSize %f < 63.0, skipping some tests.\n", caps.MaxPointSize);
6724 goto cleanup;
6727 hr = IDirect3DDevice8_SetRenderTarget(device, rt, depthstencil);
6728 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
6730 for (i = 0; i < sizeof(test_setups) / sizeof(test_setups[0]); ++i)
6732 if (caps.VertexShaderVersion < test_setups[i].vs->version
6733 || caps.PixelShaderVersion < test_setups[i].ps->version)
6735 skip("Vertex / pixel shader version not supported, skipping test.\n");
6736 continue;
6738 if (test_setups[i].vs->code)
6740 hr = IDirect3DDevice8_CreateVertexShader(device, test_setups[i].decl, test_setups[i].vs->code, &vs, 0);
6741 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x (case %u).\n", hr, i);
6743 else
6745 vs = 0;
6747 if (test_setups[i].ps->code)
6749 hr = IDirect3DDevice8_CreatePixelShader(device, test_setups[i].ps->code, &ps);
6750 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x (case %u).\n", hr, i);
6752 else
6754 ps = 0;
6757 hr = IDirect3DDevice8_SetVertexShader(device, vs ? vs : test_setups[i].accepted_fvf);
6758 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
6759 hr = IDirect3DDevice8_SetPixelShader(device, ps);
6760 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6762 for (j = 0; j < sizeof(tests) / sizeof(tests[0]); ++j)
6764 unsigned int size = tests[j].override_min ? 63 : tests[j].zero_size ? 0 : tests[j].scale
6765 ? test_setups[i].scaled_size : test_setups[i].nonscaled_size;
6767 if (test_setups[i].accepted_fvf != tests[j].fvf)
6768 continue;
6770 ptsize = tests[j].zero_size ? 0.0f : 32.0f;
6771 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
6772 ok(SUCCEEDED(hr), "Failed to set pointsize, hr %#x.\n", hr);
6774 ptsize = tests[j].override_min ? 63.0f : tests[j].zero_size ? 0.0f : ptsizemin_orig;
6775 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE_MIN, *(DWORD *)&ptsize);
6776 ok(SUCCEEDED(hr), "Failed to set minimum pointsize, hr %#x.\n", hr);
6778 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSCALEENABLE, tests[j].scale);
6779 ok(SUCCEEDED(hr), "Failed setting point scale state, hr %#x.\n", hr);
6781 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
6782 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
6784 hr = IDirect3DDevice8_BeginScene(device);
6785 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6786 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1,
6787 tests[j].vertex_data, tests[j].vertex_size);
6788 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6789 hr = IDirect3DDevice8_EndScene(device);
6790 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6792 if (tests[j].zero_size)
6794 /* Technically 0 pointsize is undefined in OpenGL but in practice it seems like
6795 * it does the "useful" thing on all the drivers I tried. */
6796 /* On WARP it does draw some pixels, most of the time. */
6797 color = getPixelColor(device, 64, 64);
6798 ok(color_match(color, 0x0000ffff, 0)
6799 || broken(color_match(color, 0x00ff0000, 0))
6800 || broken(color_match(color, 0x00ffff00, 0))
6801 || broken(color_match(color, 0x00000000, 0))
6802 || broken(color_match(color, 0x0000ff00, 0)),
6803 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
6805 else
6807 color = getPixelColor(device, 64 - size / 2 + 1, 64 - size / 2 + 1);
6808 ok(color_match(color, 0x00ff0000, 0),
6809 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
6810 color = getPixelColor(device, 64 + size / 2 - 1, 64 - size / 2 + 1);
6811 ok(color_match(color, 0x00ffff00, 0),
6812 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
6813 color = getPixelColor(device, 64 - size / 2 + 1, 64 + size / 2 - 1);
6814 ok(color_match(color, 0x00000000, 0),
6815 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
6816 color = getPixelColor(device, 64 + size / 2 - 1, 64 + size / 2 - 1);
6817 ok(color_match(color, 0x0000ff00, 0),
6818 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
6820 color = getPixelColor(device, 64 - size / 2 - 1, 64 - size / 2 - 1);
6821 ok(color_match(color, 0x0000ffff, 0),
6822 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
6823 color = getPixelColor(device, 64 + size / 2 + 1, 64 - size / 2 - 1);
6824 ok(color_match(color, 0x0000ffff, 0),
6825 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
6826 color = getPixelColor(device, 64 - size / 2 - 1, 64 + size / 2 + 1);
6827 ok(color_match(color, 0x0000ffff, 0),
6828 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
6829 color = getPixelColor(device, 64 + size / 2 + 1, 64 + size / 2 + 1);
6830 ok(color_match(color, 0x0000ffff, 0),
6831 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
6834 IDirect3DDevice8_SetVertexShader(device, 0);
6835 IDirect3DDevice8_SetPixelShader(device, 0);
6836 if (vs)
6837 IDirect3DDevice8_DeleteVertexShader(device, vs);
6838 if (ps)
6839 IDirect3DDevice8_DeletePixelShader(device, ps);
6841 hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, depthstencil);
6842 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
6844 cleanup:
6845 IDirect3DSurface8_Release(backbuffer);
6846 IDirect3DSurface8_Release(depthstencil);
6847 IDirect3DSurface8_Release(rt);
6849 IDirect3DTexture8_Release(tex1);
6850 IDirect3DTexture8_Release(tex2);
6851 refcount = IDirect3DDevice8_Release(device);
6852 ok(!refcount, "Device has %u references left.\n", refcount);
6853 done:
6854 IDirect3D8_Release(d3d);
6855 DestroyWindow(window);
6858 static void test_multisample_mismatch(void)
6860 IDirect3DDevice8 *device;
6861 IDirect3D8 *d3d;
6862 HWND window;
6863 HRESULT hr;
6864 ULONG refcount;
6865 IDirect3DSurface8 *rt_multi, *ds;
6867 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
6868 0, 0, 640, 480, NULL, NULL, NULL, NULL);
6869 d3d = Direct3DCreate8(D3D_SDK_VERSION);
6870 ok(!!d3d, "Failed to create a D3D object.\n");
6871 if (FAILED(IDirect3D8_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
6872 D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES)))
6874 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping multisample mismatch test.\n");
6875 IDirect3D8_Release(d3d);
6876 return;
6879 if (!(device = create_device(d3d, window, window, TRUE)))
6881 skip("Failed to create a D3D device, skipping tests.\n");
6882 goto done;
6885 hr = IDirect3DDevice8_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
6886 D3DMULTISAMPLE_2_SAMPLES, FALSE, &rt_multi);
6887 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
6888 hr = IDirect3DDevice8_GetDepthStencilSurface(device, &ds);
6889 ok(SUCCEEDED(hr), "Failed to get original depth/stencil, hr %#x.\n", hr);
6891 hr = IDirect3DDevice8_SetRenderTarget(device, rt_multi, ds);
6892 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
6894 IDirect3DSurface8_Release(ds);
6895 IDirect3DSurface8_Release(rt_multi);
6897 refcount = IDirect3DDevice8_Release(device);
6898 ok(!refcount, "Device has %u references left.\n", refcount);
6899 done:
6900 IDirect3D8_Release(d3d);
6901 DestroyWindow(window);
6904 static void test_texcoordindex(void)
6906 static const D3DMATRIX mat =
6908 1.0f, 0.0f, 0.0f, 0.0f,
6909 0.0f, 0.0f, 0.0f, 0.0f,
6910 0.0f, 0.0f, 0.0f, 0.0f,
6911 0.0f, 0.0f, 0.0f, 0.0f,
6912 }}};
6913 static const struct
6915 struct vec3 pos;
6916 struct vec2 texcoord1;
6917 struct vec2 texcoord2;
6918 struct vec2 texcoord3;
6920 quad[] =
6922 {{-1.0f, -1.0f, 0.0f}, {0.0f, 1.0f}, {0.0f, 0.0f}, {1.0f, 1.0f}},
6923 {{-1.0f, 1.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 1.0f}, {1.0f, 0.0f}},
6924 {{ 1.0f, -1.0f, 0.0f}, {1.0f, 1.0f}, {1.0f, 0.0f}, {0.0f, 1.0f}},
6925 {{ 1.0f, 1.0f, 0.0f}, {1.0f, 0.0f}, {1.0f, 1.0f}, {0.0f, 0.0f}},
6927 IDirect3DDevice8 *device;
6928 IDirect3D8 *d3d;
6929 HWND window;
6930 HRESULT hr;
6931 IDirect3DTexture8 *texture1, *texture2;
6932 D3DLOCKED_RECT locked_rect;
6933 ULONG refcount;
6934 D3DCOLOR color;
6935 DWORD *ptr;
6937 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
6938 0, 0, 640, 480, NULL, NULL, NULL, NULL);
6939 d3d = Direct3DCreate8(D3D_SDK_VERSION);
6940 ok(!!d3d, "Failed to create a D3D object.\n");
6941 if (!(device = create_device(d3d, window, window, TRUE)))
6943 skip("Failed to create a D3D device, skipping tests.\n");
6944 IDirect3D8_Release(d3d);
6945 DestroyWindow(window);
6946 return;
6949 hr = IDirect3DDevice8_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture1);
6950 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
6951 hr = IDirect3DDevice8_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture2);
6952 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
6954 hr = IDirect3DTexture8_LockRect(texture1, 0, &locked_rect, NULL, D3DLOCK_DISCARD);
6955 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
6956 ptr = locked_rect.pBits;
6957 ptr[0] = 0xff000000;
6958 ptr[1] = 0xff00ff00;
6959 ptr[2] = 0xff0000ff;
6960 ptr[3] = 0xff00ffff;
6961 hr = IDirect3DTexture8_UnlockRect(texture1, 0);
6962 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
6964 hr = IDirect3DTexture8_LockRect(texture2, 0, &locked_rect, NULL, D3DLOCK_DISCARD);
6965 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
6966 ptr = locked_rect.pBits;
6967 ptr[0] = 0xff000000;
6968 ptr[1] = 0xff0000ff;
6969 ptr[2] = 0xffff0000;
6970 ptr[3] = 0xffff00ff;
6971 hr = IDirect3DTexture8_UnlockRect(texture2, 0);
6972 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
6974 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture1);
6975 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
6976 hr = IDirect3DDevice8_SetTexture(device, 1, (IDirect3DBaseTexture8 *)texture2);
6977 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
6978 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX3);
6979 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
6980 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6981 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
6982 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
6983 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
6984 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
6985 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
6986 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
6987 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
6988 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
6989 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
6990 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
6991 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
6992 hr = IDirect3DDevice8_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
6993 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
6995 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_TEXCOORDINDEX, 1);
6996 ok(SUCCEEDED(hr), "Failed to set texcoord index, hr %#x.\n", hr);
6997 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_TEXCOORDINDEX, 0);
6998 ok(SUCCEEDED(hr), "Failed to set texcoord index, hr %#x.\n", hr);
7000 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 1.0f, 0);
7001 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
7003 hr = IDirect3DDevice8_BeginScene(device);
7004 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7005 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
7006 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7007 hr = IDirect3DDevice8_EndScene(device);
7008 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7010 color = getPixelColor(device, 160, 120);
7011 ok(color_match(color, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color);
7012 color = getPixelColor(device, 480, 120);
7013 ok(color_match(color, 0x0000ffff, 2), "Got unexpected color 0x%08x.\n", color);
7014 color = getPixelColor(device, 160, 360);
7015 ok(color_match(color, 0x00ff0000, 2), "Got unexpected color 0x%08x.\n", color);
7016 color = getPixelColor(device, 480, 360);
7017 ok(color_match(color, 0x00ffffff, 2), "Got unexpected color 0x%08x.\n", color);
7019 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
7020 ok(SUCCEEDED(hr), "Failed to set texture transform flags, hr %#x.\n", hr);
7021 hr = IDirect3DDevice8_SetTransform(device, D3DTS_TEXTURE1, &mat);
7022 ok(SUCCEEDED(hr), "Failed to set transformation matrix, hr %#x.\n", hr);
7024 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 1.0f, 0);
7025 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
7027 hr = IDirect3DDevice8_BeginScene(device);
7028 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7029 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
7030 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7031 hr = IDirect3DDevice8_EndScene(device);
7032 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7034 color = getPixelColor(device, 160, 120);
7035 ok(color_match(color, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color);
7036 color = getPixelColor(device, 480, 120);
7037 ok(color_match(color, 0x0000ffff, 2), "Got unexpected color 0x%08x.\n", color);
7038 color = getPixelColor(device, 160, 360);
7039 ok(color_match(color, 0x00000000, 2), "Got unexpected color 0x%08x.\n", color);
7040 color = getPixelColor(device, 480, 360);
7041 ok(color_match(color, 0x0000ffff, 2), "Got unexpected color 0x%08x.\n", color);
7043 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
7044 ok(SUCCEEDED(hr), "Failed to set texture transform flags, hr %#x.\n", hr);
7045 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_TEXCOORDINDEX, 2);
7046 ok(SUCCEEDED(hr), "Failed to set texcoord index, hr %#x.\n", hr);
7048 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 1.0f, 0);
7049 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
7051 hr = IDirect3DDevice8_BeginScene(device);
7052 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7053 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
7054 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7055 hr = IDirect3DDevice8_EndScene(device);
7056 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7058 color = getPixelColor(device, 160, 120);
7059 ok(color_match(color, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color);
7060 color = getPixelColor(device, 480, 120);
7061 ok(color_match(color, 0x0000ffff, 2), "Got unexpected color 0x%08x.\n", color);
7062 color = getPixelColor(device, 160, 360);
7063 ok(color_match(color, 0x00ff00ff, 2), "Got unexpected color 0x%08x.\n", color);
7064 color = getPixelColor(device, 480, 360);
7065 ok(color_match(color, 0x00ffff00, 2), "Got unexpected color 0x%08x.\n", color);
7067 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
7068 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
7070 IDirect3DTexture8_Release(texture1);
7071 IDirect3DTexture8_Release(texture2);
7073 refcount = IDirect3DDevice8_Release(device);
7074 ok(!refcount, "Device has %u references left.\n", refcount);
7075 IDirect3D8_Release(d3d);
7076 DestroyWindow(window);
7079 static void test_vshader_input(void)
7081 DWORD swapped_twotexcrd_shader, swapped_onetexcrd_shader = 0;
7082 DWORD swapped_twotex_wrongidx_shader = 0, swapped_twotexcrd_rightorder_shader;
7083 DWORD texcoord_color_shader, color_ubyte_shader, color_color_shader, color_float_shader;
7084 DWORD color_nocolor_shader = 0;
7085 IDirect3DDevice8 *device;
7086 IDirect3D8 *d3d;
7087 ULONG refcount;
7088 D3DCAPS8 caps;
7089 DWORD color;
7090 HWND window;
7091 HRESULT hr;
7093 static const DWORD swapped_shader_code[] =
7095 0xfffe0101, /* vs_1_1 */
7096 0x00000001, 0xc00f0000, 0x90e40000, /* mov o0, v0 */
7097 0x00000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
7098 0x00000002, 0xd00f0000, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
7099 0x0000ffff /* end */
7101 static const DWORD texcoord_color_shader_code[] =
7103 0xfffe0101, /* vs_1_1 */
7104 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
7105 0x00000001, 0xd00f0000, 0x90e40007, /* mov oD0, v7 */
7106 0x0000ffff /* end */
7108 static const DWORD color_color_shader_code[] =
7110 0xfffe0101, /* vs_1_1 */
7111 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
7112 0x00000005, 0xd00f0000, 0xa0e40000, 0x90e40005, /* mul oD0, c0, v5 */
7113 0x0000ffff /* end */
7115 static const float quad1[] =
7117 -1.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7118 -1.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7119 0.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7120 0.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7122 static const float quad4[] =
7124 0.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7125 0.0f, 1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7126 1.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7127 1.0f, 1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7129 static const struct
7131 struct vec3 position;
7132 DWORD diffuse;
7134 quad1_color[] =
7136 {{-1.0f, -1.0f, 0.1f}, 0x00ff8040},
7137 {{-1.0f, 0.0f, 0.1f}, 0x00ff8040},
7138 {{ 0.0f, -1.0f, 0.1f}, 0x00ff8040},
7139 {{ 0.0f, 0.0f, 0.1f}, 0x00ff8040},
7141 quad2_color[] =
7143 {{ 0.0f, -1.0f, 0.1f}, 0x00ff8040},
7144 {{ 0.0f, 0.0f, 0.1f}, 0x00ff8040},
7145 {{ 1.0f, -1.0f, 0.1f}, 0x00ff8040},
7146 {{ 1.0f, 0.0f, 0.1f}, 0x00ff8040},
7148 quad3_color[] =
7150 {{-1.0f, 0.0f, 0.1f}, 0x00ff8040},
7151 {{-1.0f, 1.0f, 0.1f}, 0x00ff8040},
7152 {{ 0.0f, 0.0f, 0.1f}, 0x00ff8040},
7153 {{ 0.0f, 1.0f, 0.1f}, 0x00ff8040},
7155 static const float quad4_color[] =
7157 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 0.0f, 0.0f,
7158 0.0f, 1.0f, 0.1f, 1.0f, 1.0f, 0.0f, 0.0f,
7159 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 0.0f, 1.0f,
7160 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 0.0f, 1.0f,
7162 static const DWORD decl_twotexcrd[] =
7164 D3DVSD_STREAM(0),
7165 D3DVSD_REG(0, D3DVSDT_FLOAT3), /* position */
7166 D3DVSD_REG(1, D3DVSDT_FLOAT4), /* texcoord0 */
7167 D3DVSD_REG(2, D3DVSDT_FLOAT4), /* texcoord1 */
7168 D3DVSD_END()
7170 static const DWORD decl_twotexcrd_rightorder[] =
7172 D3DVSD_STREAM(0),
7173 D3DVSD_REG(0, D3DVSDT_FLOAT3), /* position */
7174 D3DVSD_REG(2, D3DVSDT_FLOAT4), /* texcoord0 */
7175 D3DVSD_REG(1, D3DVSDT_FLOAT4), /* texcoord1 */
7176 D3DVSD_END()
7178 static const DWORD decl_onetexcrd[] =
7180 D3DVSD_STREAM(0),
7181 D3DVSD_REG(0, D3DVSDT_FLOAT3), /* position */
7182 D3DVSD_REG(1, D3DVSDT_FLOAT4), /* texcoord0 */
7183 D3DVSD_END()
7185 static const DWORD decl_twotexcrd_wrongidx[] =
7187 D3DVSD_STREAM(0),
7188 D3DVSD_REG(0, D3DVSDT_FLOAT3), /* position */
7189 D3DVSD_REG(2, D3DVSDT_FLOAT4), /* texcoord1 */
7190 D3DVSD_REG(3, D3DVSDT_FLOAT4), /* texcoord2 */
7191 D3DVSD_END()
7193 static const DWORD decl_texcoord_color[] =
7195 D3DVSD_STREAM(0),
7196 D3DVSD_REG(0, D3DVSDT_FLOAT3), /* position */
7197 D3DVSD_REG(7, D3DVSDT_D3DCOLOR), /* texcoord0 */
7198 D3DVSD_END()
7200 static const DWORD decl_color_color[] =
7202 D3DVSD_STREAM(0),
7203 D3DVSD_REG(0, D3DVSDT_FLOAT3), /* position */
7204 D3DVSD_REG(5, D3DVSDT_D3DCOLOR), /* diffuse */
7205 D3DVSD_END()
7207 static const DWORD decl_color_ubyte[] =
7209 D3DVSD_STREAM(0),
7210 D3DVSD_REG(0, D3DVSDT_FLOAT3),
7211 D3DVSD_REG(5, D3DVSDT_UBYTE4),
7212 D3DVSD_END()
7214 static const DWORD decl_color_float[] =
7216 D3DVSD_STREAM(0),
7217 D3DVSD_REG(0, D3DVSDT_FLOAT3),
7218 D3DVSD_REG(5, D3DVSDT_FLOAT4),
7219 D3DVSD_END()
7221 static const DWORD decl_nocolor[] =
7223 D3DVSD_STREAM(0),
7224 D3DVSD_REG(0, D3DVSDT_FLOAT3),
7225 D3DVSD_END()
7227 static const float normalize[4] = {1.0f / 256.0f, 1.0f / 256.0f, 1.0f / 256.0f, 1.0f / 256.0f};
7228 static const float no_normalize[4] = {1.0f, 1.0f, 1.0f, 1.0f};
7230 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
7231 0, 0, 640, 480, NULL, NULL, NULL, NULL);
7232 d3d = Direct3DCreate8(D3D_SDK_VERSION);
7233 ok(!!d3d, "Failed to create a D3D object.\n");
7234 if (!(device = create_device(d3d, window, window, TRUE)))
7236 skip("Failed to create a D3D device, skipping tests.\n");
7237 goto done;
7240 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
7241 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
7242 if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1))
7244 skip("No vs_1_1 support, skipping tests.\n");
7245 IDirect3DDevice8_Release(device);
7246 goto done;
7249 hr = IDirect3DDevice8_CreateVertexShader(device, decl_twotexcrd, swapped_shader_code, &swapped_twotexcrd_shader, 0);
7250 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
7251 hr = IDirect3DDevice8_CreateVertexShader(device, decl_onetexcrd, swapped_shader_code, &swapped_onetexcrd_shader, 0);
7252 todo_wine ok(hr == D3DERR_INVALIDCALL, "Unexpected error while creating vertex shader, hr %#x.\n", hr);
7253 hr = IDirect3DDevice8_CreateVertexShader(device, decl_twotexcrd_wrongidx, swapped_shader_code, &swapped_twotex_wrongidx_shader, 0);
7254 todo_wine ok(hr == D3DERR_INVALIDCALL, "Unexpected error while creating vertex shader, hr %#x.\n", hr);
7255 hr = IDirect3DDevice8_CreateVertexShader(device, decl_twotexcrd_rightorder, swapped_shader_code, &swapped_twotexcrd_rightorder_shader, 0);
7256 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
7258 hr = IDirect3DDevice8_CreateVertexShader(device, decl_texcoord_color, texcoord_color_shader_code, &texcoord_color_shader, 0);
7259 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
7260 hr = IDirect3DDevice8_CreateVertexShader(device, decl_color_ubyte, color_color_shader_code, &color_ubyte_shader, 0);
7261 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
7262 hr = IDirect3DDevice8_CreateVertexShader(device, decl_color_color, color_color_shader_code, &color_color_shader, 0);
7263 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
7264 hr = IDirect3DDevice8_CreateVertexShader(device, decl_color_float, color_color_shader_code, &color_float_shader, 0);
7265 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
7266 hr = IDirect3DDevice8_CreateVertexShader(device, decl_nocolor, color_color_shader_code, &color_nocolor_shader, 0);
7267 todo_wine ok(hr == D3DERR_INVALIDCALL, "Unexpected error while creating vertex shader, hr %#x.\n", hr);
7269 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 1.0f, 0);
7270 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
7272 hr = IDirect3DDevice8_BeginScene(device);
7273 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7275 hr = IDirect3DDevice8_SetVertexShader(device, swapped_twotexcrd_shader);
7276 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
7278 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 11);
7279 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7281 hr = IDirect3DDevice8_SetVertexShader(device, swapped_twotexcrd_rightorder_shader);
7282 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
7283 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 11);
7284 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7286 hr = IDirect3DDevice8_EndScene(device);
7287 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7289 color = getPixelColor(device, 160, 360);
7290 ok(color_match(color, 0x00ffff80, 1), "Got unexpected color 0x%08x for quad 1 (2crd).\n", color);
7291 color = getPixelColor(device, 480, 160);
7292 ok(color == 0x00000000, "Got unexpected color 0x%08x for quad 4 (2crd-rightorder).\n", color);
7294 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
7295 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
7297 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
7298 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
7300 hr = IDirect3DDevice8_BeginScene(device);
7301 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7303 hr = IDirect3DDevice8_SetVertexShader(device, texcoord_color_shader);
7304 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
7305 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1_color, sizeof(quad1_color[0]));
7306 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7308 hr = IDirect3DDevice8_SetVertexShader(device, color_ubyte_shader);
7309 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
7311 hr = IDirect3DDevice8_SetVertexShaderConstant(device, 0, normalize, 1);
7312 ok(SUCCEEDED(hr), "Failed to set vertex shader constant, hr %#x.\n", hr);
7313 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_color, sizeof(quad2_color[0]));
7314 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7316 hr = IDirect3DDevice8_SetVertexShaderConstant(device, 0, no_normalize, 1);
7317 ok(SUCCEEDED(hr), "Failed to set vertex shader constant, hr %#x.\n", hr);
7318 hr = IDirect3DDevice8_SetVertexShader(device, color_color_shader);
7319 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
7320 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3_color, sizeof(quad3_color[0]));
7321 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7323 hr = IDirect3DDevice8_SetVertexShader(device, color_float_shader);
7324 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
7325 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4_color, sizeof(float) * 7);
7326 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7328 hr = IDirect3DDevice8_EndScene(device);
7329 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7331 IDirect3DDevice8_SetVertexShader(device, 0);
7333 color = getPixelColor(device, 160, 360);
7334 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
7335 "Input test: Quad 1(color-texcoord) returned color 0x%08x, expected 0x00ff8040\n", color);
7336 color = getPixelColor(device, 480, 360);
7337 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x40, 0x80, 0xff), 1),
7338 "Input test: Quad 2(color-ubyte) returned color 0x%08x, expected 0x004080ff\n", color);
7339 color = getPixelColor(device, 160, 120);
7340 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
7341 "Input test: Quad 3(color-color) returned color 0x%08x, expected 0x00ff8040\n", color);
7342 color = getPixelColor(device, 480, 160);
7343 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 1),
7344 "Input test: Quad 4(color-float) returned color 0x%08x, expected 0x00ffff00\n", color);
7346 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
7347 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
7349 IDirect3DDevice8_DeleteVertexShader(device, swapped_twotexcrd_shader);
7350 IDirect3DDevice8_DeleteVertexShader(device, swapped_onetexcrd_shader);
7351 IDirect3DDevice8_DeleteVertexShader(device, swapped_twotex_wrongidx_shader);
7352 IDirect3DDevice8_DeleteVertexShader(device, swapped_twotexcrd_rightorder_shader);
7353 IDirect3DDevice8_DeleteVertexShader(device, texcoord_color_shader);
7354 IDirect3DDevice8_DeleteVertexShader(device, color_ubyte_shader);
7355 IDirect3DDevice8_DeleteVertexShader(device, color_color_shader);
7356 IDirect3DDevice8_DeleteVertexShader(device, color_float_shader);
7357 IDirect3DDevice8_DeleteVertexShader(device, color_nocolor_shader);
7359 refcount = IDirect3DDevice8_Release(device);
7360 ok(!refcount, "Device has %u references left.\n", refcount);
7361 done:
7362 IDirect3D8_Release(d3d);
7363 DestroyWindow(window);
7366 static void test_fixed_function_fvf(void)
7368 IDirect3DDevice8 *device;
7369 DWORD color;
7370 IDirect3D8 *d3d;
7371 ULONG refcount;
7372 D3DCAPS8 caps;
7373 HWND window;
7374 HRESULT hr;
7376 static const struct
7378 struct vec3 position;
7379 DWORD diffuse;
7381 quad1[] =
7383 {{-1.0f, -1.0f, 0.1f}, 0x00ffff00},
7384 {{-1.0f, 0.0f, 0.1f}, 0x00ffff00},
7385 {{ 0.0f, -1.0f, 0.1f}, 0x00ffff00},
7386 {{ 0.0f, 0.0f, 0.1f}, 0x00ffff00},
7388 static const struct vec3 quad2[] =
7390 {-1.0f, -1.0f, 0.1f},
7391 {-1.0f, 0.0f, 0.1f},
7392 { 0.0f, -1.0f, 0.1f},
7393 { 0.0f, 0.0f, 0.1f},
7395 static const struct
7397 struct vec4 position;
7398 DWORD diffuse;
7400 quad_transformed[] =
7402 {{ 90.0f, 110.0f, 0.1f, 2.0f}, 0x00ffff00},
7403 {{570.0f, 110.0f, 0.1f, 2.0f}, 0x00ffff00},
7404 {{ 90.0f, 300.0f, 0.1f, 2.0f}, 0x00ffff00},
7405 {{570.0f, 300.0f, 0.1f, 2.0f}, 0x00ffff00},
7408 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
7409 0, 0, 640, 480, NULL, NULL, NULL, NULL);
7410 d3d = Direct3DCreate8(D3D_SDK_VERSION);
7411 ok(!!d3d, "Failed to create a D3D object.\n");
7412 if (!(device = create_device(d3d, window, window, TRUE)))
7414 skip("Failed to create a D3D device, skipping tests.\n");
7415 goto done;
7418 memset(&caps, 0, sizeof(caps));
7419 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
7420 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
7422 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
7423 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
7425 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
7426 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
7428 hr = IDirect3DDevice8_BeginScene(device);
7429 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7431 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
7432 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
7433 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
7434 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7436 hr = IDirect3DDevice8_EndScene(device);
7437 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7439 color = getPixelColor(device, 160, 360);
7440 ok(color == 0x00ffff00,
7441 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7442 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
7444 /* Test with no diffuse color attribute. */
7445 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7446 ok(SUCCEEDED(hr), "IDirect3DDevice8_Clear failed with %08x\n", hr);
7448 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ);
7449 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
7450 hr = IDirect3DDevice8_BeginScene(device);
7451 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7452 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad2, sizeof(quad2[0]));
7453 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7454 hr = IDirect3DDevice8_EndScene(device);
7455 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7457 color = getPixelColor(device, 160, 360);
7458 ok(color == 0x00ffffff, "Got unexpected color 0x%08x in the no diffuse attribute test.\n", color);
7459 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
7461 /* Test what happens with specular lighting enabled and no specular color attribute. */
7462 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
7463 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
7464 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SPECULARENABLE, TRUE);
7465 ok(SUCCEEDED(hr), "Failed to enable specular lighting, hr %#x.\n", hr);
7466 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
7467 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
7468 hr = IDirect3DDevice8_BeginScene(device);
7469 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7471 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad1, sizeof(quad1[0]));
7472 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7474 hr = IDirect3DDevice8_EndScene(device);
7475 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7476 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SPECULARENABLE, FALSE);
7477 ok(SUCCEEDED(hr), "Failed to disable specular lighting, hr %#x.\n", hr);
7479 color = getPixelColor(device, 160, 360);
7480 ok(color == 0x00ffff00, "Got unexpected color 0x%08x in the no specular attribute test.\n", color);
7482 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
7484 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
7485 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
7487 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7488 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
7490 hr = IDirect3DDevice8_BeginScene(device);
7491 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7492 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad_transformed, sizeof(quad_transformed[0]));
7493 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7494 hr = IDirect3DDevice8_EndScene(device);
7495 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7497 color = getPixelColor(device, 88, 108);
7498 ok(color == 0x000000ff,
7499 "pixel 88/108 has color %08x, expected 0x000000ff\n", color);
7500 color = getPixelColor(device, 92, 108);
7501 ok(color == 0x000000ff,
7502 "pixel 92/108 has color %08x, expected 0x000000ff\n", color);
7503 color = getPixelColor(device, 88, 112);
7504 ok(color == 0x000000ff,
7505 "pixel 88/112 has color %08x, expected 0x000000ff\n", color);
7506 color = getPixelColor(device, 92, 112);
7507 ok(color == 0x00ffff00,
7508 "pixel 92/112 has color %08x, expected 0x00ffff00\n", color);
7510 color = getPixelColor(device, 568, 108);
7511 ok(color == 0x000000ff,
7512 "pixel 568/108 has color %08x, expected 0x000000ff\n", color);
7513 color = getPixelColor(device, 572, 108);
7514 ok(color == 0x000000ff,
7515 "pixel 572/108 has color %08x, expected 0x000000ff\n", color);
7516 color = getPixelColor(device, 568, 112);
7517 ok(color == 0x00ffff00,
7518 "pixel 568/112 has color %08x, expected 0x00ffff00\n", color);
7519 color = getPixelColor(device, 572, 112);
7520 ok(color == 0x000000ff,
7521 "pixel 572/112 has color %08x, expected 0x000000ff\n", color);
7523 color = getPixelColor(device, 88, 298);
7524 ok(color == 0x000000ff,
7525 "pixel 88/298 has color %08x, expected 0x000000ff\n", color);
7526 color = getPixelColor(device, 92, 298);
7527 ok(color == 0x00ffff00,
7528 "pixel 92/298 has color %08x, expected 0x00ffff00\n", color);
7529 color = getPixelColor(device, 88, 302);
7530 ok(color == 0x000000ff,
7531 "pixel 88/302 has color %08x, expected 0x000000ff\n", color);
7532 color = getPixelColor(device, 92, 302);
7533 ok(color == 0x000000ff,
7534 "pixel 92/302 has color %08x, expected 0x000000ff\n", color);
7536 color = getPixelColor(device, 568, 298);
7537 ok(color == 0x00ffff00,
7538 "pixel 568/298 has color %08x, expected 0x00ffff00\n", color);
7539 color = getPixelColor(device, 572, 298);
7540 ok(color == 0x000000ff,
7541 "pixel 572/298 has color %08x, expected 0x000000ff\n", color);
7542 color = getPixelColor(device, 568, 302);
7543 ok(color == 0x000000ff,
7544 "pixel 568/302 has color %08x, expected 0x000000ff\n", color);
7545 color = getPixelColor(device, 572, 302);
7546 ok(color == 0x000000ff,
7547 "pixel 572/302 has color %08x, expected 0x000000ff\n", color);
7549 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
7551 refcount = IDirect3DDevice8_Release(device);
7552 ok(!refcount, "Device has %u references left.\n", refcount);
7553 done:
7554 IDirect3D8_Release(d3d);
7555 DestroyWindow(window);
7558 START_TEST(visual)
7560 D3DADAPTER_IDENTIFIER8 identifier;
7561 IDirect3D8 *d3d;
7562 HRESULT hr;
7564 if (!(d3d = Direct3DCreate8(D3D_SDK_VERSION)))
7566 skip("Failed to create D3D8 object.\n");
7567 return;
7570 memset(&identifier, 0, sizeof(identifier));
7571 hr = IDirect3D8_GetAdapterIdentifier(d3d, D3DADAPTER_DEFAULT, 0, &identifier);
7572 ok(SUCCEEDED(hr), "Failed to get adapter identifier, hr %#x.\n", hr);
7573 trace("Driver string: \"%s\"\n", identifier.Driver);
7574 trace("Description string: \"%s\"\n", identifier.Description);
7575 /* Only Windows XP's default VGA driver should have an empty description */
7576 ok(identifier.Description[0] || broken(!strcmp(identifier.Driver, "vga.dll")), "Empty driver description.\n");
7577 trace("Driver version %d.%d.%d.%d\n",
7578 HIWORD(U(identifier.DriverVersion).HighPart), LOWORD(U(identifier.DriverVersion).HighPart),
7579 HIWORD(U(identifier.DriverVersion).LowPart), LOWORD(U(identifier.DriverVersion).LowPart));
7581 IDirect3D8_Release(d3d);
7583 test_sanity();
7584 depth_clamp_test();
7585 lighting_test();
7586 test_specular_lighting();
7587 clear_test();
7588 fog_test();
7589 z_range_test();
7590 offscreen_test();
7591 test_blend();
7592 test_scalar_instructions();
7593 fog_with_shader_test();
7594 cnd_test();
7595 p8_texture_test();
7596 texop_test();
7597 depth_buffer_test();
7598 depth_buffer2_test();
7599 intz_test();
7600 shadow_test();
7601 multisample_copy_rects_test();
7602 zenable_test();
7603 resz_test();
7604 fog_special_test();
7605 volume_dxt5_test();
7606 volume_v16u16_test();
7607 add_dirty_rect_test();
7608 test_3dc_formats();
7609 test_fog_interpolation();
7610 test_negative_fixedfunction_fog();
7611 test_table_fog_zw();
7612 test_signed_formats();
7613 test_pointsize();
7614 test_multisample_mismatch();
7615 test_texcoordindex();
7616 test_vshader_input();
7617 test_fixed_function_fvf();