d3d8/tests: Add helpers to avoid multiple readbacks of the render target surface.
[wine.git] / dlls / d3d8 / tests / visual.c
blob772fd968dc10f928e95068c3f4cee80a21cdcf20
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 struct surface_readback
57 IDirect3DSurface8 *surface;
58 D3DLOCKED_RECT locked_rect;
61 static void get_rt_readback(IDirect3DSurface8 *surface, struct surface_readback *rb)
63 IDirect3DDevice8 *device;
64 IDirect3DTexture8 *tex = NULL;
65 HRESULT hr;
67 memset(rb, 0, sizeof(*rb));
68 IDirect3DSurface8_GetDevice(surface, &device);
69 hr = IDirect3DDevice8_CreateTexture(device, 640, 480, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &tex);
70 if (FAILED(hr) || !tex)
72 trace("Can't create an offscreen plain surface to read the render target data, hr %#x.\n", hr);
73 goto error;
75 hr = IDirect3DTexture8_GetSurfaceLevel(tex, 0, &rb->surface);
76 if (FAILED(hr))
78 trace("Can't get surface from texture, hr %#x.\n", hr);
79 goto error;
81 hr = IDirect3DDevice8_CopyRects(device, surface, NULL, 0, rb->surface, NULL);
82 if (FAILED(hr))
84 trace("Can't read the render target, hr %#x.\n", hr);
85 goto error;
87 hr = IDirect3DSurface8_LockRect(rb->surface, &rb->locked_rect, NULL, D3DLOCK_READONLY);
88 if (FAILED(hr))
90 trace("Can't lock the offscreen surface, hr %#x.\n", hr);
91 goto error;
93 IDirect3DTexture8_Release(tex);
94 IDirect3DDevice8_Release(device);
95 return;
97 error:
98 if (rb->surface)
99 IDirect3DSurface8_Release(rb->surface);
100 rb->surface = NULL;
101 if (tex)
102 IDirect3DTexture8_Release(tex);
103 IDirect3DDevice8_Release(device);
106 static DWORD get_readback_color(struct surface_readback *rb, unsigned int x, unsigned int y)
108 return rb->locked_rect.pBits
109 ? ((DWORD *)rb->locked_rect.pBits)[y * rb->locked_rect.Pitch / sizeof(DWORD) + x] : 0xdeadbeef;
112 static void release_surface_readback(struct surface_readback *rb)
114 HRESULT hr;
116 if (!rb->surface)
117 return;
118 if (rb->locked_rect.pBits && FAILED(hr = IDirect3DSurface8_UnlockRect(rb->surface)))
119 trace("Can't unlock the offscreen surface, hr %#x.\n", hr);
120 IDirect3DSurface8_Release(rb->surface);
123 static DWORD getPixelColor(IDirect3DDevice8 *device, UINT x, UINT y)
125 DWORD ret;
126 IDirect3DSurface8 *rt;
127 struct surface_readback rb;
128 HRESULT hr;
130 hr = IDirect3DDevice8_GetRenderTarget(device, &rt);
131 if (FAILED(hr))
133 trace("Can't get the render target, hr %#x.\n", hr);
134 return 0xdeadbeef;
137 get_rt_readback(rt, &rb);
138 /* Remove the X channel for now. DirectX and OpenGL have different ideas how to treat it apparently, and it isn't
139 * really important for these tests
141 ret = get_readback_color(&rb, x, y) & 0x00ffffff;
142 release_surface_readback(&rb);
144 IDirect3DSurface8_Release(rt);
145 return ret;
148 static D3DCOLOR get_surface_color(IDirect3DSurface8 *surface, UINT x, UINT y)
150 DWORD color;
151 HRESULT hr;
152 D3DSURFACE_DESC desc;
153 RECT rectToLock = {x, y, x+1, y+1};
154 D3DLOCKED_RECT lockedRect;
156 hr = IDirect3DSurface8_GetDesc(surface, &desc);
157 ok(SUCCEEDED(hr), "Failed to get surface description, hr=%#x.\n", hr);
159 hr = IDirect3DSurface8_LockRect(surface, &lockedRect, &rectToLock, D3DLOCK_READONLY);
160 ok(SUCCEEDED(hr), "Failed to lock surface, hr=%#x.\n", hr);
162 switch(desc.Format)
164 case D3DFMT_A8R8G8B8:
165 color = ((D3DCOLOR *)lockedRect.pBits)[0];
166 break;
168 default:
169 trace("Error: unknown surface format: %u.\n", desc.Format);
170 color = 0xdeadbeef;
171 break;
174 hr = IDirect3DSurface8_UnlockRect(surface);
175 ok(SUCCEEDED(hr), "Failed to unlock surface, hr=%#x.\n", hr);
177 return color;
180 static IDirect3DDevice8 *create_device(IDirect3D8 *d3d, HWND device_window, HWND focus_window, BOOL windowed)
182 D3DPRESENT_PARAMETERS present_parameters = {0};
183 IDirect3DDevice8 *device;
185 present_parameters.Windowed = windowed;
186 present_parameters.hDeviceWindow = device_window;
187 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
188 present_parameters.BackBufferWidth = 640;
189 present_parameters.BackBufferHeight = 480;
190 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
191 present_parameters.EnableAutoDepthStencil = TRUE;
192 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
194 if (SUCCEEDED(IDirect3D8_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, focus_window,
195 D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device)))
196 return device;
198 return NULL;
201 static void test_sanity(void)
203 IDirect3DDevice8 *device;
204 IDirect3D8 *d3d;
205 D3DCOLOR color;
206 ULONG refcount;
207 HWND window;
208 HRESULT hr;
210 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
211 0, 0, 640, 480, NULL, NULL, NULL, NULL);
212 d3d = Direct3DCreate8(D3D_SDK_VERSION);
213 ok(!!d3d, "Failed to create a D3D object.\n");
214 if (!(device = create_device(d3d, window, window, TRUE)))
216 skip("Failed to create a D3D device, skipping tests.\n");
217 goto done;
220 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 1.0f, 0);
221 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
222 color = getPixelColor(device, 1, 1);
223 ok(color == 0x00ff0000, "Got unexpected color 0x%08x.\n", color);
225 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
226 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
228 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ddee, 1.0f, 0);
229 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
230 color = getPixelColor(device, 639, 479);
231 ok(color == 0x0000ddee, "Got unexpected color 0x%08x.\n", color);
233 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
234 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
236 refcount = IDirect3DDevice8_Release(device);
237 ok(!refcount, "Device has %u references left.\n", refcount);
238 done:
239 IDirect3D8_Release(d3d);
240 DestroyWindow(window);
243 static void lighting_test(void)
245 DWORD nfvf = D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_NORMAL;
246 DWORD fvf = D3DFVF_XYZ | D3DFVF_DIFFUSE;
247 IDirect3DDevice8 *device;
248 IDirect3D8 *d3d;
249 D3DCOLOR color;
250 ULONG refcount;
251 HWND window;
252 HRESULT hr;
253 unsigned int i;
255 static const struct
257 struct vec3 position;
258 DWORD diffuse;
260 unlitquad[] =
262 {{-1.0f, -1.0f, 0.1f}, 0xffff0000},
263 {{-1.0f, 0.0f, 0.1f}, 0xffff0000},
264 {{ 0.0f, 0.0f, 0.1f}, 0xffff0000},
265 {{ 0.0f, -1.0f, 0.1f}, 0xffff0000},
267 litquad[] =
269 {{-1.0f, 0.0f, 0.1f}, 0xff00ff00},
270 {{-1.0f, 1.0f, 0.1f}, 0xff00ff00},
271 {{ 0.0f, 1.0f, 0.1f}, 0xff00ff00},
272 {{ 0.0f, 0.0f, 0.1f}, 0xff00ff00},
274 static const struct
276 struct vec3 position;
277 struct vec3 normal;
278 DWORD diffuse;
280 unlitnquad[] =
282 {{0.0f, -1.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xff0000ff},
283 {{0.0f, 0.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xff0000ff},
284 {{1.0f, 0.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xff0000ff},
285 {{1.0f, -1.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xff0000ff},
287 litnquad[] =
289 {{0.0f, 0.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xffffff00},
290 {{0.0f, 1.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xffffff00},
291 {{1.0f, 1.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xffffff00},
292 {{1.0f, 0.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xffffff00},
294 nquad[] =
296 {{-1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
297 {{-1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
298 {{ 1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
299 {{ 1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
301 rotatedquad[] =
303 {{-10.0f, -11.0f, 11.0f}, {-1.0f, 0.0f, 0.0f}, 0xff0000ff},
304 {{-10.0f, -9.0f, 11.0f}, {-1.0f, 0.0f, 0.0f}, 0xff0000ff},
305 {{-10.0f, -9.0f, 9.0f}, {-1.0f, 0.0f, 0.0f}, 0xff0000ff},
306 {{-10.0f, -11.0f, 9.0f}, {-1.0f, 0.0f, 0.0f}, 0xff0000ff},
308 translatedquad[] =
310 {{-11.0f, -11.0f, -10.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
311 {{-11.0f, -9.0f, -10.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
312 {{ -9.0f, -9.0f, -10.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
313 {{ -9.0f, -11.0f, -10.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
315 static const WORD indices[] = {0, 1, 2, 2, 3, 0};
316 static const D3DMATRIX mat =
318 1.0f, 0.0f, 0.0f, 0.0f,
319 0.0f, 1.0f, 0.0f, 0.0f,
320 0.0f, 0.0f, 1.0f, 0.0f,
321 0.0f, 0.0f, 0.0f, 1.0f,
322 }}},
323 mat_singular =
325 1.0f, 0.0f, 1.0f, 0.0f,
326 0.0f, 1.0f, 0.0f, 0.0f,
327 1.0f, 0.0f, 1.0f, 0.0f,
328 0.0f, 0.0f, 0.5f, 1.0f,
329 }}},
330 mat_transf =
332 0.0f, 0.0f, 1.0f, 0.0f,
333 0.0f, 1.0f, 0.0f, 0.0f,
334 -1.0f, 0.0f, 0.0f, 0.0f,
335 10.f, 10.0f, 10.0f, 1.0f,
336 }}},
337 mat_nonaffine =
339 1.0f, 0.0f, 0.0f, 0.0f,
340 0.0f, 1.0f, 0.0f, 0.0f,
341 0.0f, 0.0f, 1.0f, -1.0f,
342 10.f, 10.0f, 10.0f, 0.0f,
343 }}};
344 static const struct
346 const D3DMATRIX *world_matrix;
347 const void *quad;
348 unsigned int size;
349 DWORD expected;
350 const char *message;
352 tests[] =
354 {&mat, nquad, sizeof(nquad[0]), 0x000000ff, "Lit quad with light"},
355 {&mat_singular, nquad, sizeof(nquad[0]), 0x000000ff, "Lit quad with singular world matrix"},
356 {&mat_transf, rotatedquad, sizeof(rotatedquad[0]), 0x000000ff, "Lit quad with transformation matrix"},
357 {&mat_nonaffine, translatedquad, sizeof(translatedquad[0]), 0x00000000, "Lit quad with non-affine matrix"},
360 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
361 0, 0, 640, 480, NULL, NULL, NULL, NULL);
362 d3d = Direct3DCreate8(D3D_SDK_VERSION);
363 ok(!!d3d, "Failed to create a D3D object.\n");
364 if (!(device = create_device(d3d, window, window, TRUE)))
366 skip("Failed to create a D3D device, skipping tests.\n");
367 goto done;
370 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
371 ok(hr == D3D_OK, "IDirect3DDevice8_Clear failed with %#08x\n", hr);
373 hr = IDirect3DDevice8_SetTransform(device, D3DTS_WORLDMATRIX(0), &mat);
374 ok(hr == D3D_OK, "IDirect3DDevice8_SetTransform returned %#08x\n", hr);
375 hr = IDirect3DDevice8_SetTransform(device, D3DTS_VIEW, &mat);
376 ok(hr == D3D_OK, "IDirect3DDevice8_SetTransform returned %#08x\n", hr);
377 hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, &mat);
378 ok(hr == D3D_OK, "IDirect3DDevice8_SetTransform returned %#08x\n", hr);
379 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, FALSE);
380 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %#08x\n", hr);
381 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, FALSE);
382 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %#08x\n", hr);
383 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
384 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %#08x\n", hr);
385 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
386 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %#08x\n", hr);
387 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
388 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed with %#08x\n", hr);
390 hr = IDirect3DDevice8_SetVertexShader(device, fvf);
391 ok(hr == D3D_OK, "IDirect3DDevice8_SetVertexShader returned %#08x\n", hr);
393 hr = IDirect3DDevice8_BeginScene(device);
394 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
396 /* No lights are defined... That means, lit vertices should be entirely black. */
397 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
398 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
399 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
400 2, indices, D3DFMT_INDEX16, unlitquad, sizeof(unlitquad[0]));
401 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
403 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, TRUE);
404 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
405 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
406 2, indices, D3DFMT_INDEX16, litquad, sizeof(litquad[0]));
407 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
409 hr = IDirect3DDevice8_SetVertexShader(device, nfvf);
410 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
412 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
413 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
414 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
415 2, indices, D3DFMT_INDEX16, unlitnquad, sizeof(unlitnquad[0]));
416 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
418 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, TRUE);
419 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
420 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
421 2, indices, D3DFMT_INDEX16, litnquad, sizeof(litnquad[0]));
422 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
424 hr = IDirect3DDevice8_EndScene(device);
425 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
427 color = getPixelColor(device, 160, 360); /* Lower left quad - unlit without normals */
428 ok(color == 0x00ff0000, "Unlit quad without normals has color 0x%08x, expected 0x00ff0000.\n", color);
429 color = getPixelColor(device, 160, 120); /* Upper left quad - lit without normals */
430 ok(color == 0x00000000, "Lit quad without normals has color 0x%08x, expected 0x00000000.\n", color);
431 color = getPixelColor(device, 480, 360); /* Lower right quad - unlit with normals */
432 ok(color == 0x000000ff, "Unlit quad with normals has color 0x%08x, expected 0x000000ff.\n", color);
433 color = getPixelColor(device, 480, 120); /* Upper right quad - lit with normals */
434 ok(color == 0x00000000, "Lit quad with normals has color 0x%08x, expected 0x00000000.\n", color);
436 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
438 hr = IDirect3DDevice8_LightEnable(device, 0, TRUE);
439 ok(SUCCEEDED(hr), "Failed to enable light 0, hr %#x.\n", hr);
441 for (i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i)
443 hr = IDirect3DDevice8_SetTransform(device, D3DTS_WORLD, tests[i].world_matrix);
444 ok(SUCCEEDED(hr), "Failed to set world transform, hr %#x.\n", hr);
446 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
447 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
449 hr = IDirect3DDevice8_BeginScene(device);
450 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
452 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
453 2, indices, D3DFMT_INDEX16, tests[i].quad, tests[i].size);
454 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
456 hr = IDirect3DDevice8_EndScene(device);
457 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
459 color = getPixelColor(device, 320, 240);
460 ok(color == tests[i].expected, "%s has color 0x%08x.\n", tests[i].message, color);
463 refcount = IDirect3DDevice8_Release(device);
464 ok(!refcount, "Device has %u references left.\n", refcount);
465 done:
466 IDirect3D8_Release(d3d);
467 DestroyWindow(window);
470 static void test_specular_lighting(void)
472 static const unsigned int vertices_side = 5;
473 const unsigned int indices_count = (vertices_side - 1) * (vertices_side - 1) * 2 * 3;
474 static const DWORD fvf = D3DFVF_XYZ | D3DFVF_NORMAL;
475 static const D3DMATRIX mat =
477 1.0f, 0.0f, 0.0f, 0.0f,
478 0.0f, 1.0f, 0.0f, 0.0f,
479 0.0f, 0.0f, 1.0f, 0.0f,
480 0.0f, 0.0f, 0.0f, 1.0f,
481 }}};
482 static const D3DLIGHT8 directional =
484 D3DLIGHT_DIRECTIONAL,
485 {0.0f, 0.0f, 0.0f, 0.0f},
486 {1.0f, 1.0f, 1.0f, 0.0f},
487 {0.0f, 0.0f, 0.0f, 0.0f},
488 {0.0f, 0.0f, 0.0f},
489 {0.0f, 0.0f, 1.0f},
491 point =
493 D3DLIGHT_POINT,
494 {0.0f, 0.0f, 0.0f, 0.0f},
495 {1.0f, 1.0f, 1.0f, 0.0f},
496 {0.0f, 0.0f, 0.0f, 0.0f},
497 {0.0f, 0.0f, 0.0f},
498 {0.0f, 0.0f, 0.0f},
499 100.0f,
500 0.0f,
501 0.0f, 0.0f, 1.0f,
503 spot =
505 D3DLIGHT_SPOT,
506 {0.0f, 0.0f, 0.0f, 0.0f},
507 {1.0f, 1.0f, 1.0f, 0.0f},
508 {0.0f, 0.0f, 0.0f, 0.0f},
509 {0.0f, 0.0f, 0.0f},
510 {0.0f, 0.0f, 1.0f},
511 100.0f,
512 1.0f,
513 0.0f, 0.0f, 1.0f,
514 M_PI / 12.0f, M_PI / 3.0f
516 /* The chosen range value makes the test fail when using a manhattan
517 * distance metric vs the correct euclidean distance. */
518 point_range =
520 D3DLIGHT_POINT,
521 {0.0f, 0.0f, 0.0f, 0.0f},
522 {1.0f, 1.0f, 1.0f, 0.0f},
523 {0.0f, 0.0f, 0.0f, 0.0f},
524 {0.0f, 0.0f, 0.0f},
525 {0.0f, 0.0f, 0.0f},
526 1.2f,
527 0.0f,
528 0.0f, 0.0f, 1.0f,
530 static const struct expected_color
532 unsigned int x, y;
533 D3DCOLOR color;
535 expected_directional[] =
537 {160, 120, 0x00ffffff},
538 {320, 120, 0x00ffffff},
539 {480, 120, 0x00ffffff},
540 {160, 240, 0x00ffffff},
541 {320, 240, 0x00ffffff},
542 {480, 240, 0x00ffffff},
543 {160, 360, 0x00ffffff},
544 {320, 360, 0x00ffffff},
545 {480, 360, 0x00ffffff},
547 expected_directional_local[] =
549 {160, 120, 0x003c3c3c},
550 {320, 120, 0x00717171},
551 {480, 120, 0x003c3c3c},
552 {160, 240, 0x00717171},
553 {320, 240, 0x00ffffff},
554 {480, 240, 0x00717171},
555 {160, 360, 0x003c3c3c},
556 {320, 360, 0x00717171},
557 {480, 360, 0x003c3c3c},
559 expected_point[] =
561 {160, 120, 0x00282828},
562 {320, 120, 0x005a5a5a},
563 {480, 120, 0x00282828},
564 {160, 240, 0x005a5a5a},
565 {320, 240, 0x00ffffff},
566 {480, 240, 0x005a5a5a},
567 {160, 360, 0x00282828},
568 {320, 360, 0x005a5a5a},
569 {480, 360, 0x00282828},
571 expected_point_local[] =
573 {160, 120, 0x00000000},
574 {320, 120, 0x00070707},
575 {480, 120, 0x00000000},
576 {160, 240, 0x00070707},
577 {320, 240, 0x00ffffff},
578 {480, 240, 0x00070707},
579 {160, 360, 0x00000000},
580 {320, 360, 0x00070707},
581 {480, 360, 0x00000000},
583 expected_spot[] =
585 {160, 120, 0x00000000},
586 {320, 120, 0x00141414},
587 {480, 120, 0x00000000},
588 {160, 240, 0x00141414},
589 {320, 240, 0x00ffffff},
590 {480, 240, 0x00141414},
591 {160, 360, 0x00000000},
592 {320, 360, 0x00141414},
593 {480, 360, 0x00000000},
595 expected_spot_local[] =
597 {160, 120, 0x00000000},
598 {320, 120, 0x00020202},
599 {480, 120, 0x00000000},
600 {160, 240, 0x00020202},
601 {320, 240, 0x00ffffff},
602 {480, 240, 0x00020202},
603 {160, 360, 0x00000000},
604 {320, 360, 0x00020202},
605 {480, 360, 0x00000000},
607 expected_point_range[] =
609 {160, 120, 0x00000000},
610 {320, 120, 0x005a5a5a},
611 {480, 120, 0x00000000},
612 {160, 240, 0x005a5a5a},
613 {320, 240, 0x00ffffff},
614 {480, 240, 0x005a5a5a},
615 {160, 360, 0x00000000},
616 {320, 360, 0x005a5a5a},
617 {480, 360, 0x00000000},
619 static const struct
621 const D3DLIGHT8 *light;
622 BOOL local_viewer;
623 const struct expected_color *expected;
624 unsigned int expected_count;
626 tests[] =
628 {&directional, FALSE, expected_directional,
629 sizeof(expected_directional) / sizeof(expected_directional[0])},
630 {&directional, TRUE, expected_directional_local,
631 sizeof(expected_directional_local) / sizeof(expected_directional_local[0])},
632 {&point, FALSE, expected_point,
633 sizeof(expected_point) / sizeof(expected_point[0])},
634 {&point, TRUE, expected_point_local,
635 sizeof(expected_point_local) / sizeof(expected_point_local[0])},
636 {&spot, FALSE, expected_spot,
637 sizeof(expected_spot) / sizeof(expected_spot[0])},
638 {&spot, TRUE, expected_spot_local,
639 sizeof(expected_spot_local) / sizeof(expected_spot_local[0])},
640 {&point_range, FALSE, expected_point_range,
641 sizeof(expected_point_range) / sizeof(expected_point_range[0])},
643 IDirect3DDevice8 *device;
644 D3DMATERIAL8 material;
645 IDirect3D8 *d3d;
646 D3DCOLOR color;
647 ULONG refcount;
648 HWND window;
649 HRESULT hr;
650 unsigned int i, j, x, y;
651 struct
653 struct vec3 position;
654 struct vec3 normal;
655 } *quad;
656 WORD *indices;
658 quad = HeapAlloc(GetProcessHeap(), 0, vertices_side * vertices_side * sizeof(*quad));
659 indices = HeapAlloc(GetProcessHeap(), 0, indices_count * sizeof(*indices));
660 for (i = 0, y = 0; y < vertices_side; ++y)
662 for (x = 0; x < vertices_side; ++x)
664 quad[i].position.x = x * 2.0f / (vertices_side - 1) - 1.0f;
665 quad[i].position.y = y * 2.0f / (vertices_side - 1) - 1.0f;
666 quad[i].position.z = 1.0f;
667 quad[i].normal.x = 0.0f;
668 quad[i].normal.y = 0.0f;
669 quad[i++].normal.z = -1.0f;
672 for (i = 0, y = 0; y < (vertices_side - 1); ++y)
674 for (x = 0; x < (vertices_side - 1); ++x)
676 indices[i++] = y * vertices_side + x + 1;
677 indices[i++] = y * vertices_side + x;
678 indices[i++] = (y + 1) * vertices_side + x;
679 indices[i++] = y * vertices_side + x + 1;
680 indices[i++] = (y + 1) * vertices_side + x;
681 indices[i++] = (y + 1) * vertices_side + x + 1;
685 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
686 0, 0, 640, 480, NULL, NULL, NULL, NULL);
687 d3d = Direct3DCreate8(D3D_SDK_VERSION);
688 ok(!!d3d, "Failed to create a D3D object.\n");
689 if (!(device = create_device(d3d, window, window, TRUE)))
691 skip("Failed to create a D3D device, skipping tests.\n");
692 goto done;
695 hr = IDirect3DDevice8_SetTransform(device, D3DTS_WORLD, &mat);
696 ok(SUCCEEDED(hr), "Failed to set world transform, hr %#x.\n", hr);
697 hr = IDirect3DDevice8_SetTransform(device, D3DTS_VIEW, &mat);
698 ok(SUCCEEDED(hr), "Failed to set view transform, hr %#x.\n", hr);
699 hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, &mat);
700 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
701 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, FALSE);
702 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#x.\n", hr);
703 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, FALSE);
704 ok(SUCCEEDED(hr), "Failed to disable z test, hr %#x.\n", hr);
705 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
706 ok(SUCCEEDED(hr), "Failed to disable fog, hr %#x.\n", hr);
708 hr = IDirect3DDevice8_SetVertexShader(device, fvf);
709 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
711 memset(&material, 0, sizeof(material));
712 material.Specular.r = 1.0f;
713 material.Specular.g = 1.0f;
714 material.Specular.b = 1.0f;
715 material.Specular.a = 1.0f;
716 material.Power = 30.0f;
717 hr = IDirect3DDevice8_SetMaterial(device, &material);
718 ok(SUCCEEDED(hr), "Failed to set material, hr %#x.\n", hr);
720 hr = IDirect3DDevice8_LightEnable(device, 0, TRUE);
721 ok(SUCCEEDED(hr), "Failed to enable light 0, hr %#x.\n", hr);
722 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SPECULARENABLE, TRUE);
723 ok(SUCCEEDED(hr), "Failed to enable specular lighting, hr %#x.\n", hr);
725 for (i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i)
727 hr = IDirect3DDevice8_SetLight(device, 0, tests[i].light);
728 ok(SUCCEEDED(hr), "Failed to set light parameters, hr %#x.\n", hr);
730 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LOCALVIEWER, tests[i].local_viewer);
731 ok(SUCCEEDED(hr), "Failed to set local viewer state, hr %#x.\n", hr);
733 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
734 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
736 hr = IDirect3DDevice8_BeginScene(device);
737 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
739 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST,
740 0, vertices_side * vertices_side, indices_count / 3, indices,
741 D3DFMT_INDEX16, quad, sizeof(quad[0]));
742 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
744 hr = IDirect3DDevice8_EndScene(device);
745 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
747 for (j = 0; j < tests[i].expected_count; ++j)
749 color = getPixelColor(device, tests[i].expected[j].x, tests[i].expected[j].y);
750 ok(color_match(color, tests[i].expected[j].color, 1),
751 "Expected color 0x%08x at location (%u, %u), got 0x%08x, case %u.\n",
752 tests[i].expected[j].color, tests[i].expected[j].x,
753 tests[i].expected[j].y, color, i);
757 refcount = IDirect3DDevice8_Release(device);
758 ok(!refcount, "Device has %u references left.\n", refcount);
759 done:
760 IDirect3D8_Release(d3d);
761 DestroyWindow(window);
762 HeapFree(GetProcessHeap(), 0, indices);
763 HeapFree(GetProcessHeap(), 0, quad);
766 static void clear_test(void)
768 /* Tests the correctness of clearing parameters */
769 D3DRECT rect_negneg, rect[2];
770 IDirect3DDevice8 *device;
771 IDirect3D8 *d3d;
772 D3DCOLOR color;
773 ULONG refcount;
774 HWND window;
775 HRESULT hr;
777 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
778 0, 0, 640, 480, NULL, NULL, NULL, NULL);
779 d3d = Direct3DCreate8(D3D_SDK_VERSION);
780 ok(!!d3d, "Failed to create a D3D object.\n");
781 if (!(device = create_device(d3d, window, window, TRUE)))
783 skip("Failed to create a D3D device, skipping tests.\n");
784 goto done;
787 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
788 ok(hr == D3D_OK, "IDirect3DDevice8_Clear failed with %#08x\n", hr);
790 /* Positive x, negative y */
791 rect[0].x1 = 0;
792 rect[0].y1 = 480;
793 rect[0].x2 = 320;
794 rect[0].y2 = 240;
796 /* Positive x, positive y */
797 rect[1].x1 = 0;
798 rect[1].y1 = 0;
799 rect[1].x2 = 320;
800 rect[1].y2 = 240;
801 /* Clear 2 rectangles with one call. Shows that a positive value is returned, but the negative rectangle
802 * is ignored, the positive is still cleared afterwards
804 hr = IDirect3DDevice8_Clear(device, 2, rect, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
805 ok(hr == D3D_OK, "IDirect3DDevice8_Clear failed with %#08x\n", hr);
807 /* negative x, negative y */
808 rect_negneg.x1 = 640;
809 rect_negneg.y1 = 240;
810 rect_negneg.x2 = 320;
811 rect_negneg.y2 = 0;
812 hr = IDirect3DDevice8_Clear(device, 1, &rect_negneg, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
813 ok(hr == D3D_OK, "IDirect3DDevice8_Clear failed with %#08x\n", hr);
815 color = getPixelColor(device, 160, 360); /* lower left quad */
816 ok(color == 0x00ffffff, "Clear rectangle 3(pos, neg) has color %08x\n", color);
817 color = getPixelColor(device, 160, 120); /* upper left quad */
818 ok(color == 0x00ff0000, "Clear rectangle 1(pos, pos) has color %08x\n", color);
819 color = getPixelColor(device, 480, 360); /* lower right quad */
820 ok(color == 0x00ffffff, "Clear rectangle 4(NULL) has color %08x\n", color);
821 color = getPixelColor(device, 480, 120); /* upper right quad */
822 ok(color == 0x00ffffff, "Clear rectangle 4(neg, neg) has color %08x\n", color);
824 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
826 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
827 ok(SUCCEEDED(hr), "IDirect3DDevice8_Clear failed with %#08x\n", hr);
829 rect[0].x1 = 0;
830 rect[0].y1 = 0;
831 rect[0].x2 = 640;
832 rect[0].y2 = 480;
833 hr = IDirect3DDevice8_Clear(device, 0, rect, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
834 ok(SUCCEEDED(hr), "IDirect3DDevice8_Clear failed with %#08x\n", hr);
836 color = getPixelColor(device, 320, 240);
837 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff), 1),
838 "Clear with count = 0, rect != NULL has color %#08x\n", color);
840 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
842 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
843 ok(SUCCEEDED(hr), "IDirect3DDevice8_Clear failed with %#08x\n", hr);
844 hr = IDirect3DDevice8_Clear(device, 1, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
845 ok(SUCCEEDED(hr), "IDirect3DDevice8_Clear failed with %#08x\n", hr);
847 color = getPixelColor(device, 320, 240);
848 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
849 "Clear with count = 1, rect = NULL has color %#08x\n", color);
851 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
853 refcount = IDirect3DDevice8_Release(device);
854 ok(!refcount, "Device has %u references left.\n", refcount);
855 done:
856 IDirect3D8_Release(d3d);
857 DestroyWindow(window);
860 static void fog_test(void)
862 float start = 0.0f, end = 1.0f;
863 IDirect3DDevice8 *device;
864 IDirect3D8 *d3d;
865 D3DCOLOR color;
866 ULONG refcount;
867 D3DCAPS8 caps;
868 HWND window;
869 HRESULT hr;
871 /* Gets full z based fog with linear fog, no fog with specular color. */
872 static const struct
874 float x, y, z;
875 D3DCOLOR diffuse;
876 D3DCOLOR specular;
878 untransformed_1[] =
880 {-1.0f, -1.0f, 0.1f, 0xffff0000, 0xff000000},
881 {-1.0f, 0.0f, 0.1f, 0xffff0000, 0xff000000},
882 { 0.0f, 0.0f, 0.1f, 0xffff0000, 0xff000000},
883 { 0.0f, -1.0f, 0.1f, 0xffff0000, 0xff000000},
885 /* Ok, I am too lazy to deal with transform matrices. */
886 untransformed_2[] =
888 {-1.0f, 0.0f, 1.0f, 0xffff0000, 0xff000000},
889 {-1.0f, 1.0f, 1.0f, 0xffff0000, 0xff000000},
890 { 0.0f, 1.0f, 1.0f, 0xffff0000, 0xff000000},
891 { 0.0f, 0.0f, 1.0f, 0xffff0000, 0xff000000},
893 far_quad1[] =
895 {-1.0f, -1.0f, 0.5f, 0xffff0000, 0xff000000},
896 {-1.0f, 0.0f, 0.5f, 0xffff0000, 0xff000000},
897 { 0.0f, 0.0f, 0.5f, 0xffff0000, 0xff000000},
898 { 0.0f, -1.0f, 0.5f, 0xffff0000, 0xff000000},
900 far_quad2[] =
902 {-1.0f, 0.0f, 1.5f, 0xffff0000, 0xff000000},
903 {-1.0f, 1.0f, 1.5f, 0xffff0000, 0xff000000},
904 { 0.0f, 1.0f, 1.5f, 0xffff0000, 0xff000000},
905 { 0.0f, 0.0f, 1.5f, 0xffff0000, 0xff000000},
908 /* Untransformed ones. Give them a different diffuse color to make the
909 * test look nicer. It also makes making sure that they are drawn
910 * correctly easier. */
911 static const struct
913 float x, y, z, rhw;
914 D3DCOLOR diffuse;
915 D3DCOLOR specular;
917 transformed_1[] =
919 {320.0f, 0.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
920 {640.0f, 0.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
921 {640.0f, 240.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
922 {320.0f, 240.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
924 transformed_2[] =
926 {320.0f, 240.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
927 {640.0f, 240.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
928 {640.0f, 480.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
929 {320.0f, 480.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
931 static const D3DMATRIX ident_mat =
933 1.0f, 0.0f, 0.0f, 0.0f,
934 0.0f, 1.0f, 0.0f, 0.0f,
935 0.0f, 0.0f, 1.0f, 0.0f,
936 0.0f, 0.0f, 0.0f, 1.0f,
937 }}};
938 static const D3DMATRIX world_mat1 =
940 1.0f, 0.0f, 0.0f, 0.0f,
941 0.0f, 1.0f, 0.0f, 0.0f,
942 0.0f, 0.0f, 1.0f, 0.0f,
943 0.0f, 0.0f, -0.5f, 1.0f,
944 }}};
945 static const D3DMATRIX world_mat2 =
947 1.0f, 0.0f, 0.0f, 0.0f,
948 0.0f, 1.0f, 0.0f, 0.0f,
949 0.0f, 0.0f, 1.0f, 0.0f,
950 0.0f, 0.0f, 1.0f, 1.0f,
951 }}};
952 static const D3DMATRIX proj_mat =
954 1.0f, 0.0f, 0.0f, 0.0f,
955 0.0f, 1.0f, 0.0f, 0.0f,
956 0.0f, 0.0f, 1.0f, 0.0f,
957 0.0f, 0.0f, -1.0f, 1.0f,
958 }}};
959 static const WORD Indices[] = {0, 1, 2, 2, 3, 0};
961 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
962 0, 0, 640, 480, NULL, NULL, NULL, NULL);
963 d3d = Direct3DCreate8(D3D_SDK_VERSION);
964 ok(!!d3d, "Failed to create a D3D object.\n");
965 if (!(device = create_device(d3d, window, window, TRUE)))
967 skip("Failed to create a D3D device, skipping tests.\n");
968 goto done;
971 memset(&caps, 0, sizeof(caps));
972 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
973 ok(hr == D3D_OK, "IDirect3DDevice8_GetDeviceCaps returned %08x\n", hr);
974 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
975 ok(hr == D3D_OK, "IDirect3DDevice8_Clear returned %#08x\n", hr);
977 /* Setup initial states: No lighting, fog on, fog color */
978 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, FALSE);
979 ok(SUCCEEDED(hr), "Failed to disable D3DRS_ZENABLE, hr %#x.\n", hr);
980 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
981 ok(hr == D3D_OK, "Turning off lighting returned %#08x\n", hr);
982 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
983 ok(hr == D3D_OK, "Turning on fog calculations returned %#08x\n", hr);
984 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
985 ok(hr == D3D_OK, "Setting fog color returned %#08x\n", hr);
986 /* Some of the tests seem to depend on the projection matrix explicitly
987 * being set to an identity matrix, even though that's the default.
988 * (AMD Radeon HD 6310, Windows 7) */
989 hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, &ident_mat);
990 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
992 /* First test: Both table fog and vertex fog off */
993 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
994 ok(hr == D3D_OK, "Turning off table fog returned %#08x\n", hr);
995 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
996 ok(hr == D3D_OK, "Turning off vertex fog returned %#08x\n", hr);
998 /* Start = 0, end = 1. Should be default, but set them */
999 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1000 ok(hr == D3D_OK, "Setting fog start returned %#08x\n", hr);
1001 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1002 ok(hr == D3D_OK, "Setting fog start returned %#08x\n", hr);
1004 hr = IDirect3DDevice8_BeginScene(device);
1005 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
1007 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1008 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
1009 /* Untransformed, vertex fog = NONE, table fog = NONE:
1010 * Read the fog weighting from the specular color. */
1011 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1012 2 /* PrimCount */, Indices, D3DFMT_INDEX16, untransformed_1, sizeof(untransformed_1[0]));
1013 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1015 /* This makes it use the Z value. */
1016 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1017 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
1018 /* Untransformed, vertex fog != none (or table fog != none):
1019 * Use the Z value as input into the equation. */
1020 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1021 2 /* PrimCount */, Indices, D3DFMT_INDEX16, untransformed_2, sizeof(untransformed_2[0]));
1022 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1024 /* Transformed vertices. */
1025 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1026 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
1027 /* Transformed, vertex fog != NONE, pixel fog == NONE:
1028 * Use specular color alpha component. */
1029 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1030 2 /* PrimCount */, Indices, D3DFMT_INDEX16, transformed_1, sizeof(transformed_1[0]));
1031 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1033 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
1034 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
1035 /* Transformed, table fog != none, vertex anything:
1036 * Use Z value as input to the fog equation. */
1037 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1038 2 /* PrimCount */, Indices, D3DFMT_INDEX16, transformed_2, sizeof(transformed_2[0]));
1039 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1041 hr = IDirect3DDevice8_EndScene(device);
1042 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
1044 color = getPixelColor(device, 160, 360);
1045 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xFF, 0x00, 0x00), 1),
1046 "Untransformed vertex with no table or vertex fog has color %08x\n", color);
1047 color = getPixelColor(device, 160, 120);
1048 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xFF, 0x00), 1),
1049 "Untransformed vertex with linear vertex fog has color %08x\n", color);
1050 color = getPixelColor(device, 480, 120);
1051 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xFF, 0xFF, 0x00), 1),
1052 "Transformed vertex with linear vertex fog has color %08x\n", color);
1053 color = getPixelColor(device, 480, 360);
1054 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xFF, 0x00), 1),
1055 "Transformed vertex with linear table fog has color %08x\n", color);
1057 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
1059 if (caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)
1061 /* A simple fog + non-identity world matrix test */
1062 hr = IDirect3DDevice8_SetTransform(device, D3DTS_WORLDMATRIX(0), &world_mat1);
1063 ok(hr == D3D_OK, "IDirect3DDevice8_SetTransform returned %#08x\n", hr);
1065 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
1066 ok(hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %#08x\n", hr);
1067 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
1068 ok(hr == D3D_OK, "Turning off vertex fog returned %#08x\n", hr);
1070 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1071 ok(hr == D3D_OK, "IDirect3DDevice8_Clear returned %#08x\n", hr);
1073 hr = IDirect3DDevice8_BeginScene(device);
1074 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
1075 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1076 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
1077 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
1078 2, Indices, D3DFMT_INDEX16, far_quad1, sizeof(far_quad1[0]));
1079 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1080 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
1081 2, Indices, D3DFMT_INDEX16, far_quad2, sizeof(far_quad2[0]));
1082 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1083 hr = IDirect3DDevice8_EndScene(device);
1084 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
1086 color = getPixelColor(device, 160, 360);
1087 ok(color_match(color, 0x00ff0000, 4), "Unfogged quad has color %08x\n", color);
1088 color = getPixelColor(device, 160, 120);
1089 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
1090 "Fogged out quad has color %08x\n", color);
1092 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
1094 /* Test fog behavior with an orthogonal (but not identity) projection matrix */
1095 hr = IDirect3DDevice8_SetTransform(device, D3DTS_WORLDMATRIX(0), &world_mat2);
1096 ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
1097 hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, &proj_mat);
1098 ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
1100 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1101 ok(hr == D3D_OK, "Clear returned %#08x\n", hr);
1103 hr = IDirect3DDevice8_BeginScene(device);
1104 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
1105 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1106 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
1107 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
1108 2, Indices, D3DFMT_INDEX16, untransformed_1, sizeof(untransformed_1[0]));
1109 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1110 hr = IDirect3DDevice8_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
1111 2, Indices, D3DFMT_INDEX16, untransformed_2, sizeof(untransformed_2[0]));
1112 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1113 hr = IDirect3DDevice8_EndScene(device);
1114 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
1116 color = getPixelColor(device, 160, 360);
1117 ok(color_match(color, 0x00e51900, 4), "Partially fogged quad has color %08x\n", color);
1118 color = getPixelColor(device, 160, 120);
1119 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
1120 "Fogged out quad has color %08x\n", color);
1122 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
1124 else
1126 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping some fog tests\n");
1129 refcount = IDirect3DDevice8_Release(device);
1130 ok(!refcount, "Device has %u references left.\n", refcount);
1131 done:
1132 IDirect3D8_Release(d3d);
1133 DestroyWindow(window);
1136 /* This tests fog in combination with shaders.
1137 * What's tested: linear fog (vertex and table) with pixel shader
1138 * linear table fog with non foggy vertex shader
1139 * vertex fog with foggy vertex shader, non-linear
1140 * fog with shader, non-linear fog with foggy shader,
1141 * linear table fog with foggy shader */
1142 static void fog_with_shader_test(void)
1144 /* Fill the null-shader entry with the FVF (SetVertexShader is "overloaded" on d3d8...) */
1145 DWORD vertex_shader[3] = {D3DFVF_XYZ | D3DFVF_DIFFUSE, 0, 0};
1146 DWORD pixel_shader[2] = {0, 0};
1147 IDirect3DDevice8 *device;
1148 unsigned int i, j;
1149 IDirect3D8 *d3d;
1150 D3DCOLOR color;
1151 ULONG refcount;
1152 D3DCAPS8 caps;
1153 HWND window;
1154 HRESULT hr;
1155 union
1157 float f;
1158 DWORD i;
1159 } start, end;
1161 /* Basic vertex shader without fog computation ("non foggy") */
1162 static const DWORD vertex_shader_code1[] =
1164 0xfffe0100, /* vs.1.0 */
1165 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1166 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
1167 0x0000ffff
1169 /* Basic vertex shader with reversed fog computation ("foggy") */
1170 static const DWORD vertex_shader_code2[] =
1172 0xfffe0100, /* vs.1.0 */
1173 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1174 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
1175 0x00000002, 0x800f0000, 0x90aa0000, 0xa0aa0000, /* add r0, v0.z, c0.z */
1176 0x00000005, 0xc00f0001, 0x80000000, 0xa0000000, /* mul oFog, r0.x, c0.x */
1177 0x0000ffff
1179 /* Basic pixel shader */
1180 static const DWORD pixel_shader_code[] =
1182 0xffff0101, /* ps_1_1 */
1183 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
1184 0x0000ffff
1186 static struct
1188 struct vec3 position;
1189 DWORD diffuse;
1191 quad[] =
1193 {{-1.0f, -1.0f, 0.0f}, 0xffff0000},
1194 {{-1.0f, 1.0f, 0.0f}, 0xffff0000},
1195 {{ 1.0f, -1.0f, 0.0f}, 0xffff0000},
1196 {{ 1.0f, 1.0f, 0.0f}, 0xffff0000},
1198 static const DWORD decl[] =
1200 D3DVSD_STREAM(0),
1201 D3DVSD_REG(0, D3DVSDT_FLOAT3), /* position, v0 */
1202 D3DVSD_REG(1, D3DVSDT_D3DCOLOR), /* diffuse color, v1 */
1203 D3DVSD_END()
1205 static const float vs_constant[4] = {-1.25f, 0.0f, -0.9f, 0.0f};
1206 /* This reference data was collected on a nVidia GeForce 7600GS
1207 * driver version 84.19 DirectX version 9.0c on Windows XP */
1208 static const struct test_data_t
1210 int vshader;
1211 int pshader;
1212 D3DFOGMODE vfog;
1213 D3DFOGMODE tfog;
1214 BOOL uninitialized_reg;
1215 unsigned int color[11];
1217 test_data[] =
1219 /* Only pixel shader */
1220 {0, 1, D3DFOG_NONE, D3DFOG_LINEAR, FALSE,
1221 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1222 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1223 {0, 1, D3DFOG_EXP, D3DFOG_LINEAR, FALSE,
1224 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1225 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1226 {0, 1, D3DFOG_EXP2, D3DFOG_LINEAR, FALSE,
1227 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1228 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1229 {0, 1, D3DFOG_LINEAR, D3DFOG_NONE, FALSE,
1230 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1231 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1232 {0, 1, D3DFOG_LINEAR, D3DFOG_LINEAR, FALSE,
1233 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1234 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1236 /* Vertex shader */
1237 {1, 0, D3DFOG_NONE, D3DFOG_NONE, TRUE,
1238 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1239 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1240 {1, 0, D3DFOG_NONE, D3DFOG_LINEAR, FALSE,
1241 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1242 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1243 {1, 0, D3DFOG_EXP, D3DFOG_LINEAR, FALSE,
1244 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1245 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1247 {1, 0, D3DFOG_EXP2, D3DFOG_LINEAR, FALSE,
1248 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1249 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1250 {1, 0, D3DFOG_LINEAR, D3DFOG_LINEAR, FALSE,
1251 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1252 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1254 /* Vertex shader and pixel shader */
1255 /* The next 4 tests would read the fog coord output, but it isn't available.
1256 * The result is a fully fogged quad, no matter what the Z coord is. */
1257 {1, 1, D3DFOG_NONE, D3DFOG_NONE, TRUE,
1258 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1259 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1260 {1, 1, D3DFOG_LINEAR, D3DFOG_NONE, TRUE,
1261 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1262 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1263 {1, 1, D3DFOG_EXP, D3DFOG_NONE, TRUE,
1264 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1265 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1266 {1, 1, D3DFOG_EXP2, D3DFOG_NONE, TRUE,
1267 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
1268 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
1270 /* These use the Z coordinate with linear table fog */
1271 {1, 1, D3DFOG_NONE, D3DFOG_LINEAR, FALSE,
1272 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1273 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1274 {1, 1, D3DFOG_EXP, D3DFOG_LINEAR, FALSE,
1275 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1276 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1277 {1, 1, D3DFOG_EXP2, D3DFOG_LINEAR, FALSE,
1278 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1279 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1280 {1, 1, D3DFOG_LINEAR, D3DFOG_LINEAR, FALSE,
1281 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1282 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1284 /* Non-linear table fog without fog coord */
1285 {1, 1, D3DFOG_NONE, D3DFOG_EXP, FALSE,
1286 {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
1287 0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
1288 {1, 1, D3DFOG_NONE, D3DFOG_EXP2, FALSE,
1289 {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
1290 0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
1292 /* These tests fail on older Nvidia drivers */
1293 /* Foggy vertex shader */
1294 {2, 0, D3DFOG_NONE, D3DFOG_NONE, FALSE,
1295 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1296 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1297 {2, 0, D3DFOG_EXP, D3DFOG_NONE, FALSE,
1298 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1299 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1300 {2, 0, D3DFOG_EXP2, D3DFOG_NONE, FALSE,
1301 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1302 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1303 {2, 0, D3DFOG_LINEAR, D3DFOG_NONE, FALSE,
1304 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1305 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1307 /* Foggy vertex shader and pixel shader. First 4 tests with vertex fog,
1308 * all using the fixed fog-coord linear fog */
1309 {2, 1, D3DFOG_NONE, D3DFOG_NONE, FALSE,
1310 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1311 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1312 {2, 1, D3DFOG_EXP, D3DFOG_NONE, FALSE,
1313 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1314 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1315 {2, 1, D3DFOG_EXP2, D3DFOG_NONE, FALSE,
1316 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1317 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1318 {2, 1, D3DFOG_LINEAR, D3DFOG_NONE, FALSE,
1319 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
1320 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
1322 /* These use table fog. Here the shader-provided fog coordinate is
1323 * ignored and the z coordinate used instead */
1324 {2, 1, D3DFOG_NONE, D3DFOG_EXP, FALSE,
1325 {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
1326 0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
1327 {2, 1, D3DFOG_NONE, D3DFOG_EXP2, FALSE,
1328 {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
1329 0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
1330 {2, 1, D3DFOG_NONE, D3DFOG_LINEAR, FALSE,
1331 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
1332 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
1334 static const D3DMATRIX identity =
1336 1.0f, 0.0f, 0.0f, 0.0f,
1337 0.0f, 1.0f, 0.0f, 0.0f,
1338 0.0f, 0.0f, 1.0f, 0.0f,
1339 0.0f, 0.0f, 0.0f, 1.0f,
1340 }}};
1342 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
1343 0, 0, 640, 480, NULL, NULL, NULL, NULL);
1344 d3d = Direct3DCreate8(D3D_SDK_VERSION);
1345 ok(!!d3d, "Failed to create a D3D object.\n");
1346 if (!(device = create_device(d3d, window, window, TRUE)))
1348 skip("Failed to create a D3D device, skipping tests.\n");
1349 goto done;
1352 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
1353 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
1354 if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1) || caps.PixelShaderVersion < D3DPS_VERSION(1, 1))
1356 skip("No vs_1_1 / ps_1_1 support, skipping tests.\n");
1357 IDirect3DDevice8_Release(device);
1358 goto done;
1361 /* NOTE: changing these values will not affect the tests with foggy vertex
1362 * shader, as the values are hardcoded in the shader constant. */
1363 start.f = 0.1f;
1364 end.f = 0.9f;
1366 /* Some of the tests seem to depend on the projection matrix explicitly
1367 * being set to an identity matrix, even though that's the default.
1368 * (AMD Radeon HD 6310, Windows 7) */
1369 hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, &identity);
1370 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
1372 hr = IDirect3DDevice8_CreateVertexShader(device, decl, vertex_shader_code1, &vertex_shader[1], 0);
1373 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1374 hr = IDirect3DDevice8_CreateVertexShader(device, decl, vertex_shader_code2, &vertex_shader[2], 0);
1375 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1376 hr = IDirect3DDevice8_CreatePixelShader(device, pixel_shader_code, &pixel_shader[1]);
1377 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
1379 /* Set shader constant value */
1380 hr = IDirect3DDevice8_SetVertexShader(device, vertex_shader[2]);
1381 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1382 hr = IDirect3DDevice8_SetVertexShaderConstant(device, 0, vs_constant, 1);
1383 ok(hr == D3D_OK, "Setting vertex shader constant failed (%08x)\n", hr);
1385 /* Setup initial states: No lighting, fog on, fog color */
1386 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1387 ok(hr == D3D_OK, "Turning off lighting failed (%08x)\n", hr);
1388 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
1389 ok(hr == D3D_OK, "Turning on fog calculations failed (%08x)\n", hr);
1390 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGCOLOR, 0xFF00FF00 /* A nice green */);
1391 ok(hr == D3D_OK, "Setting fog color failed (%08x)\n", hr);
1393 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1394 ok(hr == D3D_OK, "Turning off table fog failed (%08x)\n", hr);
1395 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
1396 ok(hr == D3D_OK, "Turning off vertex fog failed (%08x)\n", hr);
1398 /* Use fogtart = 0.1 and end = 0.9 to test behavior outside the fog transition phase, too */
1399 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGSTART, start.i);
1400 ok(hr == D3D_OK, "Setting fog start failed (%08x)\n", hr);
1401 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGEND, end.i);
1402 ok(hr == D3D_OK, "Setting fog end failed (%08x)\n", hr);
1404 for (i = 0; i < sizeof(test_data)/sizeof(test_data[0]); ++i)
1406 hr = IDirect3DDevice8_SetVertexShader(device, vertex_shader[test_data[i].vshader]);
1407 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1408 hr = IDirect3DDevice8_SetPixelShader(device, pixel_shader[test_data[i].pshader]);
1409 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
1410 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGVERTEXMODE, test_data[i].vfog);
1411 ok( hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1412 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGTABLEMODE, test_data[i].tfog);
1413 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR failed (%08x)\n", hr);
1415 for(j = 0; j < 11; ++j)
1417 /* Don't use the whole zrange to prevent rounding errors */
1418 quad[0].position.z = 0.001f + j / 10.02f;
1419 quad[1].position.z = 0.001f + j / 10.02f;
1420 quad[2].position.z = 0.001f + j / 10.02f;
1421 quad[3].position.z = 0.001f + j / 10.02f;
1423 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff00ff, 1.0f, 0);
1424 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
1426 hr = IDirect3DDevice8_BeginScene(device);
1427 ok( hr == D3D_OK, "BeginScene returned failed (%08x)\n", hr);
1429 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
1430 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
1432 hr = IDirect3DDevice8_EndScene(device);
1433 ok(hr == D3D_OK, "EndScene failed (%08x)\n", hr);
1435 /* As the red and green component are the result of blending use 5% tolerance on the expected value */
1436 color = getPixelColor(device, 128, 240);
1437 ok(color_match(color, test_data[i].color[j], 13) || broken(test_data[i].uninitialized_reg),
1438 "fog vs%i ps%i fvm%i ftm%i %d: got color %08x, expected %08x +-5%%\n",
1439 test_data[i].vshader, test_data[i].pshader,
1440 test_data[i].vfog, test_data[i].tfog, j, color, test_data[i].color[j]);
1443 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
1445 IDirect3DDevice8_DeleteVertexShader(device, vertex_shader[1]);
1446 IDirect3DDevice8_DeleteVertexShader(device, vertex_shader[2]);
1447 IDirect3DDevice8_DeleteVertexShader(device, pixel_shader[1]);
1448 refcount = IDirect3DDevice8_Release(device);
1449 ok(!refcount, "Device has %u references left.\n", refcount);
1450 done:
1451 IDirect3D8_Release(d3d);
1452 DestroyWindow(window);
1455 static void cnd_test(void)
1457 DWORD shader_11_coissue_2, shader_12_coissue_2, shader_13_coissue_2, shader_14_coissue_2;
1458 DWORD shader_11_coissue, shader_12_coissue, shader_13_coissue, shader_14_coissue;
1459 DWORD shader_11, shader_12, shader_13, shader_14;
1460 IDirect3DDevice8 *device;
1461 IDirect3D8 *d3d;
1462 ULONG refcount;
1463 D3DCAPS8 caps;
1464 DWORD color;
1465 HWND window;
1466 HRESULT hr;
1468 /* ps 1.x shaders are rather picky with writemasks and source swizzles.
1469 * The dp3 is used to copy r0.r to all components of r1, then copy r1.a to
1470 * r0.a. Essentially it does a mov r0.a, r0.r, which isn't allowed as-is
1471 * in 1.x pixel shaders. */
1472 static const DWORD shader_code_11[] =
1474 0xffff0101, /* ps_1_1 */
1475 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
1476 0x00000040, 0xb00f0000, /* texcoord t0 */
1477 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
1478 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3 r1, r0, c0 */
1479 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
1480 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
1481 0x0000ffff /* end */
1483 static const DWORD shader_code_12[] =
1485 0xffff0102, /* ps_1_2 */
1486 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
1487 0x00000040, 0xb00f0000, /* texcoord t0 */
1488 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
1489 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3 r1, r0, c0 */
1490 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
1491 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
1492 0x0000ffff /* end */
1494 static const DWORD shader_code_13[] =
1496 0xffff0103, /* ps_1_3 */
1497 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
1498 0x00000040, 0xb00f0000, /* texcoord t0 */
1499 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
1500 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3, r1, r0, c0 */
1501 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
1502 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
1503 0x0000ffff /* end */
1505 static const DWORD shader_code_14[] =
1507 0xffff0104, /* ps_1_3 */
1508 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
1509 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0, t0 */
1510 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
1511 0x00000050, 0x800f0000, 0x80e40000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0, c1, c2 */
1512 0x0000ffff /* end */
1515 /* Special fun: The coissue flag on cnd: Apparently cnd always selects the 2nd source,
1516 * as if the src0 comparison against 0.5 always evaluates to true. The coissue flag isn't
1517 * set by the compiler, it was added manually after compilation. Note that the COISSUE
1518 * flag on a color(.xyz) operation is only allowed after an alpha operation. DirectX doesn't
1519 * have proper docs, but GL_ATI_fragment_shader explains the pairing of color and alpha ops
1520 * well enough.
1522 * The shader attempts to test the range [-1;1] against coissued cnd, which is a bit tricky.
1523 * The input from t0 is [0;1]. 0.5 is subtracted, then we have to multiply with 2. Since
1524 * constants are clamped to [-1;1], a 2.0 is constructed by adding c0.r(=1.0) to c0.r into r1.r,
1525 * then r1(2.0, 0.0, 0.0, 0.0) is passed to dp3(explained above).
1527 static const DWORD shader_code_11_coissue[] =
1529 0xffff0101, /* ps_1_1 */
1530 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
1531 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
1532 0x00000040, 0xb00f0000, /* texcoord t0 */
1533 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
1534 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
1535 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
1536 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
1537 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
1538 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.xyz, r0.a, c1, c2*/
1539 0x0000ffff /* end */
1541 static const DWORD shader_code_11_coissue_2[] =
1543 0xffff0101, /* ps_1_1 */
1544 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
1545 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
1546 0x00000040, 0xb00f0000, /* texcoord t0 */
1547 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
1548 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
1549 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
1550 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
1551 0x00000001, 0x800f0000, 0x80e40001, /* mov r0, r1 */
1552 0x00000001, 0x80070000, 0x80ff0001, /* mov r0.xyz, r1.a */
1553 0x40000050, 0x80080000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.a, r0.a, c1, c2 */
1554 0x00000001, 0x80070000, 0x80ff0000, /* mov r0.xyz, r0.a */
1555 0x0000ffff /* end */
1557 static const DWORD shader_code_12_coissue[] =
1559 0xffff0102, /* ps_1_2 */
1560 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
1561 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
1562 0x00000040, 0xb00f0000, /* texcoord t0 */
1563 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
1564 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
1565 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
1566 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
1567 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
1568 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.xyz, r0.a, c1, c2*/
1569 0x0000ffff /* end */
1571 static const DWORD shader_code_12_coissue_2[] =
1573 0xffff0102, /* ps_1_2 */
1574 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
1575 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
1576 0x00000040, 0xb00f0000, /* texcoord t0 */
1577 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
1578 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
1579 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
1580 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
1581 0x00000001, 0x800f0000, 0x80e40001, /* mov r0, r1 */
1582 0x00000001, 0x80070000, 0x80ff0001, /* mov r0.xyz, r1.a */
1583 0x40000050, 0x80080000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.a, r0.a, c1, c2 */
1584 0x00000001, 0x80070000, 0x80ff0000, /* mov r0.xyz, r0.a */
1585 0x0000ffff /* end */
1587 static const DWORD shader_code_13_coissue[] =
1589 0xffff0103, /* ps_1_3 */
1590 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
1591 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
1592 0x00000040, 0xb00f0000, /* texcoord t0 */
1593 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
1594 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
1595 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
1596 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
1597 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
1598 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.xyz, r0.a, c1, c2*/
1599 0x0000ffff /* end */
1601 static const DWORD shader_code_13_coissue_2[] =
1603 0xffff0103, /* ps_1_3 */
1604 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
1605 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
1606 0x00000040, 0xb00f0000, /* texcoord t0 */
1607 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
1608 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
1609 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
1610 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
1611 0x00000001, 0x800f0000, 0x80e40001, /* mov r0, r1 */
1612 0x00000001, 0x80070000, 0x80ff0001, /* mov r0.xyz, r1.a */
1613 0x40000050, 0x80080000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.a, r0.a, c1, c2 */
1614 0x00000001, 0x80070000, 0x80ff0000, /* mov r0.xyz, r0.a */
1615 0x0000ffff /* end */
1617 /* ps_1_4 does not have a different cnd behavior, just pass the [0;1]
1618 * texcrd result to cnd, it will compare against 0.5. */
1619 static const DWORD shader_code_14_coissue[] =
1621 0xffff0104, /* ps_1_4 */
1622 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
1623 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0.xyz, t0 */
1624 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
1625 0x40000050, 0x80070000, 0x80e40000, 0xa0e40001, 0xa0e40002, /* +cnd r0.xyz, r0, c1, c2 */
1626 0x0000ffff /* end */
1628 static const DWORD shader_code_14_coissue_2[] =
1630 0xffff0104, /* ps_1_4 */
1631 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
1632 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0.xyz, t0 */
1633 0x00000001, 0x80080000, 0x80000000, /* mov r0.a, r0.x */
1634 0x00000001, 0x80070001, 0xa0ff0000, /* mov r1.xyz, c0.a */
1635 0x40000050, 0x80080001, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r1.a, r0.a, c1, c2 */
1636 0x00000001, 0x80070000, 0x80ff0001, /* mov r0.xyz, r1.a */
1637 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
1638 0x0000ffff /* end */
1640 static const float quad1[] =
1642 -1.0f, -1.0f, 0.1f, 0.0f, 0.0f, 1.0f,
1643 -1.0f, 0.0f, 0.1f, 0.0f, 1.0f, 0.0f,
1644 0.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f,
1645 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 0.0f
1647 static const float quad2[] =
1649 0.0f, -1.0f, 0.1f, 0.0f, 0.0f, 1.0f,
1650 0.0f, 0.0f, 0.1f, 0.0f, 1.0f, 0.0f,
1651 1.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f,
1652 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 0.0f
1654 static const float quad3[] =
1656 0.0f, 0.0f, 0.1f, 0.0f, 0.0f, 1.0f,
1657 0.0f, 1.0f, 0.1f, 0.0f, 1.0f, 0.0f,
1658 1.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f,
1659 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 0.0f
1661 static const float quad4[] =
1663 -1.0f, 0.0f, 0.1f, 0.0f, 0.0f, 1.0f,
1664 -1.0f, 1.0f, 0.1f, 0.0f, 1.0f, 0.0f,
1665 0.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f,
1666 0.0f, 1.0f, 0.1f, 1.0f, 1.0f, 0.0f
1668 static const float test_data_c1[4] = {0.0f, 0.0f, 0.0f, 0.0f};
1669 static const float test_data_c2[4] = {1.0f, 1.0f, 1.0f, 1.0f};
1670 static const float test_data_c1_coi[4] = {0.0f, 1.0f, 0.0f, 0.0f};
1671 static const float test_data_c2_coi[4] = {1.0f, 0.0f, 1.0f, 1.0f};
1673 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
1674 0, 0, 640, 480, NULL, NULL, NULL, NULL);
1675 d3d = Direct3DCreate8(D3D_SDK_VERSION);
1676 ok(!!d3d, "Failed to create a D3D object.\n");
1677 if (!(device = create_device(d3d, window, window, TRUE)))
1679 skip("Failed to create a D3D device, skipping tests.\n");
1680 goto done;
1683 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
1684 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
1685 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 4))
1687 skip("No ps_1_4 support, skipping tests.\n");
1688 IDirect3DDevice8_Release(device);
1689 goto done;
1692 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
1693 ok(hr == D3D_OK, "IDirect3DDevice8_Clear returned %08x\n", hr);
1695 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code_11, &shader_11);
1696 ok(hr == D3D_OK, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr);
1697 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code_12, &shader_12);
1698 ok(hr == D3D_OK, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr);
1699 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code_13, &shader_13);
1700 ok(hr == D3D_OK, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr);
1701 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code_14, &shader_14);
1702 ok(hr == D3D_OK, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr);
1703 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code_11_coissue, &shader_11_coissue);
1704 ok(hr == D3D_OK, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr);
1705 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code_12_coissue, &shader_12_coissue);
1706 ok(hr == D3D_OK, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr);
1707 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code_13_coissue, &shader_13_coissue);
1708 ok(hr == D3D_OK, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr);
1709 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code_14_coissue, &shader_14_coissue);
1710 ok(hr == D3D_OK, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr);
1711 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code_11_coissue_2, &shader_11_coissue_2);
1712 ok(hr == D3D_OK, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr);
1713 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code_12_coissue_2, &shader_12_coissue_2);
1714 ok(hr == D3D_OK, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr);
1715 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code_13_coissue_2, &shader_13_coissue_2);
1716 ok(hr == D3D_OK, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr);
1717 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code_14_coissue_2, &shader_14_coissue_2);
1718 ok(hr == D3D_OK, "IDirect3DDevice8_CreatePixelShader returned %08x\n", hr);
1720 hr = IDirect3DDevice8_SetPixelShaderConstant(device, 1, test_data_c1, 1);
1721 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShaderConstant returned %08x\n", hr);
1722 hr = IDirect3DDevice8_SetPixelShaderConstant(device, 2, test_data_c2, 1);
1723 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShaderConstant returned %08x\n", hr);
1724 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX1);
1725 ok(hr == D3D_OK, "IDirect3DDevice8_SetVertexShader returned %#08x\n", hr);
1727 hr = IDirect3DDevice8_BeginScene(device);
1728 ok(hr == D3D_OK, "IDirect3DDevice8_BeginScene returned %08x\n", hr);
1730 hr = IDirect3DDevice8_SetPixelShader(device, shader_11);
1731 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr);
1732 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
1733 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
1735 hr = IDirect3DDevice8_SetPixelShader(device, shader_12);
1736 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr);
1737 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
1738 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
1740 hr = IDirect3DDevice8_SetPixelShader(device, shader_13);
1741 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr);
1742 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
1743 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
1745 hr = IDirect3DDevice8_SetPixelShader(device, shader_14);
1746 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr);
1747 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
1748 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
1750 hr = IDirect3DDevice8_EndScene(device);
1751 ok(hr == D3D_OK, "IDirect3DDevice8_EndScene returned %08x\n", hr);
1753 hr = IDirect3DDevice8_SetPixelShader(device, 0);
1754 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr);
1756 /* This is the 1.4 test. Each component(r, g, b) is tested separately against 0.5 */
1757 color = getPixelColor(device, 158, 118);
1758 ok(color == 0x00ff00ff, "pixel 158, 118 has color %08x, expected 0x00ff00ff\n", color);
1759 color = getPixelColor(device, 162, 118);
1760 ok(color == 0x000000ff, "pixel 162, 118 has color %08x, expected 0x000000ff\n", color);
1761 color = getPixelColor(device, 158, 122);
1762 ok(color == 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color);
1763 color = getPixelColor(device, 162, 122);
1764 ok(color == 0x0000ffff, "pixel 162, 122 has color %08x, expected 0x0000ffff\n", color);
1766 /* 1.1 shader. All 3 components get set, based on the .w comparison */
1767 color = getPixelColor(device, 158, 358);
1768 ok(color == 0x00ffffff, "pixel 158, 358 has color %08x, expected 0x00ffffff\n", color);
1769 color = getPixelColor(device, 162, 358);
1770 ok(color_match(color, 0x00000000, 1),
1771 "pixel 162, 358 has color %08x, expected 0x00000000\n", color);
1772 color = getPixelColor(device, 158, 362);
1773 ok(color == 0x00ffffff, "pixel 158, 362 has color %08x, expected 0x00ffffff\n", color);
1774 color = getPixelColor(device, 162, 362);
1775 ok(color_match(color, 0x00000000, 1),
1776 "pixel 162, 362 has color %08x, expected 0x00000000\n", color);
1778 /* 1.2 shader */
1779 color = getPixelColor(device, 478, 358);
1780 ok(color == 0x00ffffff, "pixel 478, 358 has color %08x, expected 0x00ffffff\n", color);
1781 color = getPixelColor(device, 482, 358);
1782 ok(color_match(color, 0x00000000, 1),
1783 "pixel 482, 358 has color %08x, expected 0x00000000\n", color);
1784 color = getPixelColor(device, 478, 362);
1785 ok(color == 0x00ffffff, "pixel 478, 362 has color %08x, expected 0x00ffffff\n", color);
1786 color = getPixelColor(device, 482, 362);
1787 ok(color_match(color, 0x00000000, 1),
1788 "pixel 482, 362 has color %08x, expected 0x00000000\n", color);
1790 /* 1.3 shader */
1791 color = getPixelColor(device, 478, 118);
1792 ok(color == 0x00ffffff, "pixel 478, 118 has color %08x, expected 0x00ffffff\n", color);
1793 color = getPixelColor(device, 482, 118);
1794 ok(color_match(color, 0x00000000, 1),
1795 "pixel 482, 118 has color %08x, expected 0x00000000\n", color);
1796 color = getPixelColor(device, 478, 122);
1797 ok(color == 0x00ffffff, "pixel 478, 122 has color %08x, expected 0x00ffffff\n", color);
1798 color = getPixelColor(device, 482, 122);
1799 ok(color_match(color, 0x00000000, 1),
1800 "pixel 482, 122 has color %08x, expected 0x00000000\n", color);
1802 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
1803 ok(hr == D3D_OK, "IDirect3DDevice8_Present failed with %08x\n", hr);
1805 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0f, 0);
1806 ok(hr == D3D_OK, "IDirect3DDevice8_Clear returned %08x\n", hr);
1807 hr = IDirect3DDevice8_SetPixelShaderConstant(device, 1, test_data_c1_coi, 1);
1808 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShaderConstant returned %08x\n", hr);
1809 hr = IDirect3DDevice8_SetPixelShaderConstant(device, 2, test_data_c2_coi, 1);
1810 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShaderConstant returned %08x\n", hr);
1812 hr = IDirect3DDevice8_BeginScene(device);
1813 ok(hr == D3D_OK, "IDirect3DDevice8_BeginScene returned %08x\n", hr);
1815 hr = IDirect3DDevice8_SetPixelShader(device, shader_11_coissue);
1816 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr);
1817 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
1818 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
1820 hr = IDirect3DDevice8_SetPixelShader(device, shader_12_coissue);
1821 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr);
1822 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
1823 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
1825 hr = IDirect3DDevice8_SetPixelShader(device, shader_13_coissue);
1826 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr);
1827 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
1828 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
1830 hr = IDirect3DDevice8_SetPixelShader(device, shader_14_coissue);
1831 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr);
1832 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
1833 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
1835 hr = IDirect3DDevice8_EndScene(device);
1836 ok(hr == D3D_OK, "IDirect3DDevice8_EndScene returned %08x\n", hr);
1838 hr = IDirect3DDevice8_SetPixelShader(device, 0);
1839 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr);
1841 /* This is the 1.4 test. The coissue doesn't change the behavior here, but keep in mind
1842 * that we swapped the values in c1 and c2 to make the other tests return some color
1844 color = getPixelColor(device, 158, 118);
1845 ok(color == 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color);
1846 color = getPixelColor(device, 162, 118);
1847 ok(color == 0x0000ffff, "pixel 162, 118 has color %08x, expected 0x0000ffff\n", color);
1848 color = getPixelColor(device, 158, 122);
1849 ok(color == 0x00ff00ff, "pixel 162, 122 has color %08x, expected 0x00ff00ff\n", color);
1850 color = getPixelColor(device, 162, 122);
1851 ok(color == 0x000000ff, "pixel 162, 122 has color %08x, expected 0x000000ff\n", color);
1853 /* 1.1 shader. coissue flag changed the semantic of cnd, c1 is always selected
1854 * (The Win7 nvidia driver always selects c2)
1856 color = getPixelColor(device, 158, 358);
1857 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
1858 "pixel 158, 358 has color %08x, expected 0x0000ff00\n", color);
1859 color = getPixelColor(device, 162, 358);
1860 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
1861 "pixel 162, 358 has color %08x, expected 0x0000ff00\n", color);
1862 color = getPixelColor(device, 158, 362);
1863 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
1864 "pixel 158, 362 has color %08x, expected 0x0000ff00\n", color);
1865 color = getPixelColor(device, 162, 362);
1866 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
1867 "pixel 162, 362 has color %08x, expected 0x0000ff00\n", color);
1869 /* 1.2 shader */
1870 color = getPixelColor(device, 478, 358);
1871 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
1872 "pixel 478, 358 has color %08x, expected 0x0000ff00\n", color);
1873 color = getPixelColor(device, 482, 358);
1874 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
1875 "pixel 482, 358 has color %08x, expected 0x0000ff00\n", color);
1876 color = getPixelColor(device, 478, 362);
1877 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
1878 "pixel 478, 362 has color %08x, expected 0x0000ff00\n", color);
1879 color = getPixelColor(device, 482, 362);
1880 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
1881 "pixel 482, 362 has color %08x, expected 0x0000ff00\n", color);
1883 /* 1.3 shader */
1884 color = getPixelColor(device, 478, 118);
1885 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
1886 "pixel 478, 118 has color %08x, expected 0x0000ff00\n", color);
1887 color = getPixelColor(device, 482, 118);
1888 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
1889 "pixel 482, 118 has color %08x, expected 0x0000ff00\n", color);
1890 color = getPixelColor(device, 478, 122);
1891 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
1892 "pixel 478, 122 has color %08x, expected 0x0000ff00\n", color);
1893 color = getPixelColor(device, 482, 122);
1894 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
1895 "pixel 482, 122 has color %08x, expected 0x0000ff00\n", color);
1897 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
1898 ok(hr == D3D_OK, "IDirect3DDevice8_Present failed with %08x\n", hr);
1900 /* Retest with the coissue flag on the alpha instruction instead. This
1901 * works "as expected". The Windows 8 testbot (WARP) seems to handle this
1902 * the same as coissue on .rgb. */
1903 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0f, 0);
1904 ok(hr == D3D_OK, "IDirect3DDevice8_Clear returned %08x\n", hr);
1906 hr = IDirect3DDevice8_BeginScene(device);
1907 ok(hr == D3D_OK, "IDirect3DDevice8_BeginScene returned %08x\n", hr);
1909 hr = IDirect3DDevice8_SetPixelShader(device, shader_11_coissue_2);
1910 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr);
1911 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
1912 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
1914 hr = IDirect3DDevice8_SetPixelShader(device, shader_12_coissue_2);
1915 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr);
1916 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
1917 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
1919 hr = IDirect3DDevice8_SetPixelShader(device, shader_13_coissue_2);
1920 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr);
1921 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
1922 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
1924 hr = IDirect3DDevice8_SetPixelShader(device, shader_14_coissue_2);
1925 ok(hr == D3D_OK, "IDirect3DDevice8_SetPixelShader returned %08x\n", hr);
1926 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
1927 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
1929 hr = IDirect3DDevice8_EndScene(device);
1930 ok(hr == D3D_OK, "IDirect3DDevice8_EndScene returned %08x\n", hr);
1932 /* 1.4 shader */
1933 color = getPixelColor(device, 158, 118);
1934 ok(color == 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color);
1935 color = getPixelColor(device, 162, 118);
1936 ok(color == 0x00000000, "pixel 162, 118 has color %08x, expected 0x00000000\n", color);
1937 color = getPixelColor(device, 158, 122);
1938 ok(color == 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color);
1939 color = getPixelColor(device, 162, 122);
1940 ok(color == 0x00000000, "pixel 162, 122 has color %08x, expected 0x00000000\n", color);
1942 /* 1.1 shader */
1943 color = getPixelColor(device, 238, 358);
1944 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
1945 "pixel 238, 358 has color %08x, expected 0x00ffffff\n", color);
1946 color = getPixelColor(device, 242, 358);
1947 ok(color_match(color, 0x00000000, 1),
1948 "pixel 242, 358 has color %08x, expected 0x00000000\n", color);
1949 color = getPixelColor(device, 238, 362);
1950 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
1951 "pixel 238, 362 has color %08x, expected 0x00ffffff\n", color);
1952 color = getPixelColor(device, 242, 362);
1953 ok(color_match(color, 0x00000000, 1),
1954 "pixel 242, 362 has color %08x, expected 0x00000000\n", color);
1956 /* 1.2 shader */
1957 color = getPixelColor(device, 558, 358);
1958 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
1959 "pixel 558, 358 has color %08x, expected 0x00ffffff\n", color);
1960 color = getPixelColor(device, 562, 358);
1961 ok(color_match(color, 0x00000000, 1),
1962 "pixel 562, 358 has color %08x, expected 0x00000000\n", color);
1963 color = getPixelColor(device, 558, 362);
1964 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
1965 "pixel 558, 362 has color %08x, expected 0x00ffffff\n", color);
1966 color = getPixelColor(device, 562, 362);
1967 ok(color_match(color, 0x00000000, 1),
1968 "pixel 562, 362 has color %08x, expected 0x00000000\n", color);
1970 /* 1.3 shader */
1971 color = getPixelColor(device, 558, 118);
1972 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
1973 "pixel 558, 118 has color %08x, expected 0x00ffffff\n", color);
1974 color = getPixelColor(device, 562, 118);
1975 ok(color_match(color, 0x00000000, 1),
1976 "pixel 562, 118 has color %08x, expected 0x00000000\n", color);
1977 color = getPixelColor(device, 558, 122);
1978 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
1979 "pixel 558, 122 has color %08x, expected 0x00ffffff\n", color);
1980 color = getPixelColor(device, 562, 122);
1981 ok(color_match(color, 0x00000000, 1),
1982 "pixel 562, 122 has color %08x, expected 0x00000000\n", color);
1984 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
1985 ok(hr == D3D_OK, "IDirect3DDevice8_Present failed with %08x\n", hr);
1987 IDirect3DDevice8_DeletePixelShader(device, shader_14_coissue_2);
1988 IDirect3DDevice8_DeletePixelShader(device, shader_13_coissue_2);
1989 IDirect3DDevice8_DeletePixelShader(device, shader_12_coissue_2);
1990 IDirect3DDevice8_DeletePixelShader(device, shader_11_coissue_2);
1991 IDirect3DDevice8_DeletePixelShader(device, shader_14_coissue);
1992 IDirect3DDevice8_DeletePixelShader(device, shader_13_coissue);
1993 IDirect3DDevice8_DeletePixelShader(device, shader_12_coissue);
1994 IDirect3DDevice8_DeletePixelShader(device, shader_11_coissue);
1995 IDirect3DDevice8_DeletePixelShader(device, shader_14);
1996 IDirect3DDevice8_DeletePixelShader(device, shader_13);
1997 IDirect3DDevice8_DeletePixelShader(device, shader_12);
1998 IDirect3DDevice8_DeletePixelShader(device, shader_11);
1999 refcount = IDirect3DDevice8_Release(device);
2000 ok(!refcount, "Device has %u references left.\n", refcount);
2001 done:
2002 IDirect3D8_Release(d3d);
2003 DestroyWindow(window);
2006 static void z_range_test(void)
2008 IDirect3DDevice8 *device;
2009 IDirect3D8 *d3d;
2010 D3DCOLOR color;
2011 ULONG refcount;
2012 D3DCAPS8 caps;
2013 DWORD shader;
2014 HWND window;
2015 HRESULT hr;
2017 static const struct
2019 struct vec3 position;
2020 DWORD diffuse;
2022 quad[] =
2024 {{-1.0f, 0.0f, 1.1f}, 0xffff0000},
2025 {{-1.0f, 1.0f, 1.1f}, 0xffff0000},
2026 {{ 1.0f, 0.0f, -1.1f}, 0xffff0000},
2027 {{ 1.0f, 1.0f, -1.1f}, 0xffff0000},
2029 quad2[] =
2031 {{-1.0f, 0.0f, 1.1f}, 0xff0000ff},
2032 {{-1.0f, 1.0f, 1.1f}, 0xff0000ff},
2033 {{ 1.0f, 0.0f, -1.1f}, 0xff0000ff},
2034 {{ 1.0f, 1.0f, -1.1f}, 0xff0000ff},
2036 static const struct
2038 struct vec4 position;
2039 DWORD diffuse;
2041 quad3[] =
2043 {{640.0f, 240.0f, -1.1f, 1.0f}, 0xffffff00},
2044 {{640.0f, 480.0f, -1.1f, 1.0f}, 0xffffff00},
2045 {{ 0.0f, 240.0f, 1.1f, 1.0f}, 0xffffff00},
2046 {{ 0.0f, 480.0f, 1.1f, 1.0f}, 0xffffff00},
2048 quad4[] =
2050 {{640.0f, 240.0f, -1.1f, 1.0f}, 0xff00ff00},
2051 {{640.0f, 480.0f, -1.1f, 1.0f}, 0xff00ff00},
2052 {{ 0.0f, 240.0f, 1.1f, 1.0f}, 0xff00ff00},
2053 {{ 0.0f, 480.0f, 1.1f, 1.0f}, 0xff00ff00},
2055 static const DWORD shader_code[] =
2057 0xfffe0101, /* vs_1_1 */
2058 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
2059 0x00000001, 0xd00f0000, 0xa0e40000, /* mov oD0, c0 */
2060 0x0000ffff /* end */
2062 static const float color_const_1[] = {1.0f, 0.0f, 0.0f, 1.0f};
2063 static const float color_const_2[] = {0.0f, 0.0f, 1.0f, 1.0f};
2064 static const DWORD vertex_declaration[] =
2066 D3DVSD_STREAM(0),
2067 D3DVSD_REG(D3DVSDE_POSITION, D3DVSDT_FLOAT3),
2068 D3DVSD_END()
2071 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
2072 0, 0, 640, 480, NULL, NULL, NULL, NULL);
2073 d3d = Direct3DCreate8(D3D_SDK_VERSION);
2074 ok(!!d3d, "Failed to create a D3D object.\n");
2075 if (!(device = create_device(d3d, window, window, TRUE)))
2077 skip("Failed to create a D3D device, skipping tests.\n");
2078 goto done;
2081 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
2082 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
2084 /* Does the Present clear the depth stencil? Clear the depth buffer with some value != 0,
2085 * then call Present. Then clear the color buffer to make sure it has some defined content
2086 * after the Present with D3DSWAPEFFECT_DISCARD. After that draw a plane that is somewhere cut
2087 * by the depth value. */
2088 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.75f, 0);
2089 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
2090 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
2091 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
2092 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
2093 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
2095 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
2096 ok(SUCCEEDED(hr), "Failed to disabled lighting, hr %#x.\n", hr);
2097 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, TRUE);
2098 ok(SUCCEEDED(hr), "Failed to enable clipping, hr %#x.\n", hr);
2099 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
2100 ok(SUCCEEDED(hr), "Failed to enable z test, hr %#x.\n", hr);
2101 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
2102 ok(SUCCEEDED(hr), "Failed to disable z writes, hr %#x.\n", hr);
2103 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
2104 ok(SUCCEEDED(hr), "Failed to set z function, hr %#x.\n", hr);
2105 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
2106 ok(SUCCEEDED(hr), "Failed set FVF, hr %#x.\n", hr);
2108 hr = IDirect3DDevice8_BeginScene(device);
2109 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
2111 /* Test the untransformed vertex path */
2112 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
2113 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2114 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
2115 ok(SUCCEEDED(hr), "Failed to set z function, hr %#x.\n", hr);
2116 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
2117 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2119 /* Test the transformed vertex path */
2120 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
2121 ok(SUCCEEDED(hr), "Failed set FVF, hr %#x.\n", hr);
2123 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(quad4[0]));
2124 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2125 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
2126 ok(SUCCEEDED(hr), "Failed to set z function, hr %#x.\n", hr);
2127 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(quad3[0]));
2128 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2130 hr = IDirect3DDevice8_EndScene(device);
2131 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
2133 /* Do not test the exact corner pixels, but go pretty close to them */
2135 /* Clipped because z > 1.0 */
2136 color = getPixelColor(device, 28, 238);
2137 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2138 color = getPixelColor(device, 28, 241);
2139 if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
2140 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2141 else
2142 ok(color_match(color, 0x00ffff00, 0), "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2144 /* Not clipped, > z buffer clear value(0.75).
2146 * On the r500 driver on Windows D3DCMP_GREATER and D3DCMP_GREATEREQUAL are broken for depth
2147 * values > 0.5. The range appears to be distorted, apparently an incoming value of ~0.875 is
2148 * equal to a stored depth buffer value of 0.5. */
2149 color = getPixelColor(device, 31, 238);
2150 ok(color_match(color, 0x00ff0000, 0), "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2151 color = getPixelColor(device, 31, 241);
2152 ok(color_match(color, 0x00ffff00, 0), "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2153 color = getPixelColor(device, 100, 238);
2154 ok(color_match(color, 0x00ff0000, 0) || broken(color_match(color, 0x00ffffff, 0)),
2155 "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2156 color = getPixelColor(device, 100, 241);
2157 ok(color_match(color, 0x00ffff00, 0) || broken(color_match(color, 0x00ffffff, 0)),
2158 "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
2160 /* Not clipped, < z buffer clear value */
2161 color = getPixelColor(device, 104, 238);
2162 ok(color_match(color, 0x000000ff, 0), "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2163 color = getPixelColor(device, 104, 241);
2164 ok(color_match(color, 0x0000ff00, 0), "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
2165 color = getPixelColor(device, 318, 238);
2166 ok(color_match(color, 0x000000ff, 0), "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2167 color = getPixelColor(device, 318, 241);
2168 ok(color_match(color, 0x0000ff00, 0), "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
2170 /* Clipped because z < 0.0 */
2171 color = getPixelColor(device, 321, 238);
2172 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2173 color = getPixelColor(device, 321, 241);
2174 if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
2175 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2176 else
2177 ok(color_match(color, 0x0000ff00, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2179 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
2180 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
2182 /* Test the shader path */
2183 if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1))
2185 skip("Vertex shaders not supported\n");
2186 IDirect3DDevice8_Release(device);
2187 goto done;
2189 hr = IDirect3DDevice8_CreateVertexShader(device, vertex_declaration, shader_code, &shader, 0);
2190 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
2192 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
2193 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
2195 hr = IDirect3DDevice8_SetVertexShader(device, shader);
2196 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
2198 hr = IDirect3DDevice8_BeginScene(device);
2199 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
2201 hr = IDirect3DDevice8_SetVertexShaderConstant(device, 0, color_const_1, 1);
2202 ok(SUCCEEDED(hr), "Failed to set vs constant 0, hr %#x.\n", hr);
2203 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
2204 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2206 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
2207 ok(SUCCEEDED(hr), "Failed to set z function, hr %#x.\n", hr);
2208 hr = IDirect3DDevice8_SetVertexShaderConstant(device, 0, color_const_2, 1);
2209 ok(SUCCEEDED(hr), "Failed to set vs constant 0, hr %#x.\n", hr);
2210 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
2211 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2213 hr = IDirect3DDevice8_EndScene(device);
2214 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
2216 hr = IDirect3DDevice8_SetVertexShader(device, 0);
2217 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
2219 hr = IDirect3DDevice8_DeleteVertexShader(device, shader);
2220 ok(SUCCEEDED(hr), "Failed to delete vertex shader, hr %#x.\n", hr);
2222 /* Z < 1.0 */
2223 color = getPixelColor(device, 28, 238);
2224 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2226 /* 1.0 < z < 0.75 */
2227 color = getPixelColor(device, 31, 238);
2228 ok(color_match(color, 0x00ff0000, 0), "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2229 color = getPixelColor(device, 100, 238);
2230 ok(color_match(color, 0x00ff0000, 0) || broken(color_match(color, 0x00ffffff, 0)),
2231 "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2233 /* 0.75 < z < 0.0 */
2234 color = getPixelColor(device, 104, 238);
2235 ok(color_match(color, 0x000000ff, 0), "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2236 color = getPixelColor(device, 318, 238);
2237 ok(color_match(color, 0x000000ff, 0), "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
2239 /* 0.0 < z */
2240 color = getPixelColor(device, 321, 238);
2241 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2243 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
2244 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
2246 refcount = IDirect3DDevice8_Release(device);
2247 ok(!refcount, "Device has %u references left.\n", refcount);
2248 done:
2249 IDirect3D8_Release(d3d);
2250 DestroyWindow(window);
2253 static void test_scalar_instructions(void)
2255 IDirect3DDevice8 *device;
2256 IDirect3D8 *d3d;
2257 unsigned int i;
2258 D3DCOLOR color;
2259 ULONG refcount;
2260 D3DCAPS8 caps;
2261 DWORD shader;
2262 HWND window;
2263 HRESULT hr;
2265 static const struct vec3 quad[] =
2267 {-1.0f, -1.0f, 0.0f},
2268 {-1.0f, 1.0f, 0.0f},
2269 { 1.0f, -1.0f, 0.0f},
2270 { 1.0f, 1.0f, 0.0f},
2272 static const DWORD decl[] =
2274 D3DVSD_STREAM(0),
2275 D3DVSD_REG(D3DVSDE_POSITION, D3DVSDT_FLOAT3), /* dcl_position v0 */
2276 D3DVSD_CONST(0, 1), 0x3e800000, 0x3f000000, 0x3f800000, 0x40000000, /* def c0, 0.25, 0.5, 1.0, 2.0 */
2277 D3DVSD_END()
2279 static const DWORD rcp_test[] =
2281 0xfffe0101, /* vs_1_1 */
2282 0x0009fffe, 0x30303030, 0x30303030, /* Shaders have to have a minimal size. */
2283 0x30303030, 0x30303030, 0x30303030, /* Add a filler comment. Usually d3dx8's */
2284 0x30303030, 0x30303030, 0x30303030, /* version comment makes the shader big */
2285 0x00303030, /* enough to make Windows happy. */
2286 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
2287 0x00000006, 0xd00f0000, 0xa0e40000, /* rcp oD0, c0 */
2288 0x0000ffff /* END */
2290 static const DWORD rsq_test[] =
2292 0xfffe0101, /* vs_1_1 */
2293 0x0009fffe, 0x30303030, 0x30303030, /* Shaders have to have a minimal size. */
2294 0x30303030, 0x30303030, 0x30303030, /* Add a filler comment. Usually d3dx8's */
2295 0x30303030, 0x30303030, 0x30303030, /* version comment makes the shader big */
2296 0x00303030, /* enough to make Windows happy. */
2297 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
2298 0x00000007, 0xd00f0000, 0xa0e40000, /* rsq oD0, c0 */
2299 0x0000ffff /* END */
2301 static const DWORD exp_test[] =
2303 0xfffe0101, /* vs_1_1 */
2304 0x0009fffe, 0x30303030, 0x30303030, /* Shaders have to have a minimal size. */
2305 0x30303030, 0x30303030, 0x30303030, /* Add a filler comment. Usually d3dx8's */
2306 0x30303030, 0x30303030, 0x30303030, /* version comment makes the shader big */
2307 0x00303030, /* enough to make Windows happy. */
2308 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
2309 0x0000000e, 0x800f0000, 0xa0e40000, /* exp r0, c0 */
2310 0x00000006, 0xd00f0000, 0x80000000, /* rcp oD0, r0.x */
2311 0x0000ffff, /* END */
2313 static const DWORD expp_test[] =
2315 0xfffe0101, /* vs_1_1 */
2316 0x0009fffe, 0x30303030, 0x30303030, /* Shaders have to have a minimal size. */
2317 0x30303030, 0x30303030, 0x30303030, /* Add a filler comment. Usually d3dx8's */
2318 0x30303030, 0x30303030, 0x30303030, /* version comment makes the shader big */
2319 0x00303030, /* enough to make Windows happy. */
2320 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
2321 0x0000004e, 0x800f0000, 0xa0e40000, /* expp r0, c0 */
2322 0x00000006, 0xd00f0000, 0x80000000, /* rcp oD0, r0.x */
2323 0x0000ffff, /* END */
2325 static const DWORD log_test[] =
2327 0xfffe0101, /* vs_1_1 */
2328 0x0009fffe, 0x30303030, 0x30303030, /* Shaders have to have a minimal size. */
2329 0x30303030, 0x30303030, 0x30303030, /* Add a filler comment. Usually d3dx8's */
2330 0x30303030, 0x30303030, 0x30303030, /* version comment makes the shader big */
2331 0x00303030, /* enough to make Windows happy. */
2332 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
2333 0x0000000f, 0xd00f0000, 0xa0e40000, /* log oD0, c0 */
2334 0x0000ffff, /* END */
2336 static const DWORD logp_test[] =
2338 0xfffe0101, /* vs_1_1 */
2339 0x0009fffe, 0x30303030, 0x30303030, /* Shaders have to have a minimal size. */
2340 0x30303030, 0x30303030, 0x30303030, /* Add a filler comment. Usually d3dx8's */
2341 0x30303030, 0x30303030, 0x30303030, /* version comment makes the shader big */
2342 0x00303030, /* enough to make Windows happy. */
2343 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
2344 0x0000004f, 0xd00f0000, 0xa0e40000, /* logp oD0, c0 */
2345 0x0000ffff, /* END */
2347 static const struct
2349 const char *name;
2350 const DWORD *byte_code;
2351 D3DCOLOR color;
2352 /* Some drivers, including Intel HD4000 10.18.10.3345 and VMware SVGA
2353 * 3D 7.14.1.5025, use the .x component instead of the .w one. */
2354 D3DCOLOR broken_color;
2356 test_data[] =
2358 {"rcp_test", rcp_test, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x80), D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff)},
2359 {"rsq_test", rsq_test, D3DCOLOR_ARGB(0x00, 0xb4, 0xb4, 0xb4), D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff)},
2360 {"exp_test", exp_test, D3DCOLOR_ARGB(0x00, 0x40, 0x40, 0x40), D3DCOLOR_ARGB(0x00, 0xd6, 0xd6, 0xd6)},
2361 {"expp_test", expp_test, D3DCOLOR_ARGB(0x00, 0x40, 0x40, 0x40), D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff)},
2362 {"log_test", log_test, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff), D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
2363 {"logp_test", logp_test, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff), D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
2366 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
2367 0, 0, 640, 480, NULL, NULL, NULL, NULL);
2368 d3d = Direct3DCreate8(D3D_SDK_VERSION);
2369 ok(!!d3d, "Failed to create a D3D object.\n");
2370 if (!(device = create_device(d3d, window, window, TRUE)))
2372 skip("Failed to create a D3D device, skipping tests.\n");
2373 goto done;
2376 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
2377 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
2378 if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1))
2380 skip("No vs_1_1 support, skipping tests.\n");
2381 IDirect3DDevice8_Release(device);
2382 goto done;
2385 for (i = 0; i < sizeof(test_data) / sizeof(*test_data); ++i)
2387 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff336699, 0.0f, 0);
2388 ok(SUCCEEDED(hr), "%s: Failed to clear, hr %#x.\n", test_data[i].name, hr);
2390 hr = IDirect3DDevice8_CreateVertexShader(device, decl, test_data[i].byte_code, &shader, 0);
2391 ok(SUCCEEDED(hr), "%s: Failed to create vertex shader, hr %#x.\n", test_data[i].name, hr);
2392 hr = IDirect3DDevice8_SetVertexShader(device, shader);
2393 ok(SUCCEEDED(hr), "%s: Failed to set vertex shader, hr %#x.\n", test_data[i].name, hr);
2395 hr = IDirect3DDevice8_BeginScene(device);
2396 ok(SUCCEEDED(hr), "%s: Failed to begin scene, hr %#x.\n", test_data[i].name, hr);
2397 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], 3 * sizeof(float));
2398 ok(SUCCEEDED(hr), "%s: Failed to draw primitive, hr %#x.\n", test_data[i].name, hr);
2399 hr = IDirect3DDevice8_EndScene(device);
2400 ok(SUCCEEDED(hr), "%s: Failed to end scene, hr %#x.\n", test_data[i].name, hr);
2402 color = getPixelColor(device, 320, 240);
2403 ok(color_match(color, test_data[i].color, 4) || broken(color_match(color, test_data[i].broken_color, 4)),
2404 "%s: Got unexpected color 0x%08x, expected 0x%08x.\n",
2405 test_data[i].name, color, test_data[i].color);
2407 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
2408 ok(SUCCEEDED(hr), "%s: Failed to present, hr %#x.\n", test_data[i].name, hr);
2410 hr = IDirect3DDevice8_SetVertexShader(device, 0);
2411 ok(SUCCEEDED(hr), "%s: Failed to set vertex shader, hr %#x.\n", test_data[i].name, hr);
2412 hr = IDirect3DDevice8_DeleteVertexShader(device, shader);
2413 ok(SUCCEEDED(hr), "%s: Failed to delete vertex shader, hr %#x.\n", test_data[i].name, hr);
2416 refcount = IDirect3DDevice8_Release(device);
2417 ok(!refcount, "Device has %u references left.\n", refcount);
2418 done:
2419 IDirect3D8_Release(d3d);
2420 DestroyWindow(window);
2423 static void offscreen_test(void)
2425 IDirect3DSurface8 *backbuffer, *offscreen, *depthstencil;
2426 IDirect3DTexture8 *offscreenTexture;
2427 IDirect3DDevice8 *device;
2428 IDirect3D8 *d3d;
2429 D3DCOLOR color;
2430 ULONG refcount;
2431 HWND window;
2432 HRESULT hr;
2434 static const float quad[][5] =
2436 {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
2437 {-0.5f, 0.5f, 0.1f, 0.0f, 1.0f},
2438 { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
2439 { 0.5f, 0.5f, 0.1f, 1.0f, 1.0f},
2442 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
2443 0, 0, 640, 480, NULL, NULL, NULL, NULL);
2444 d3d = Direct3DCreate8(D3D_SDK_VERSION);
2445 ok(!!d3d, "Failed to create a D3D object.\n");
2446 if (!(device = create_device(d3d, window, window, TRUE)))
2448 skip("Failed to create a D3D device, skipping tests.\n");
2449 goto done;
2452 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 1.0f, 0);
2453 ok(hr == D3D_OK, "Clear failed, hr = %#08x\n", hr);
2455 hr = IDirect3DDevice8_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET,
2456 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture);
2457 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %#08x\n", hr);
2458 if (!offscreenTexture)
2460 trace("Failed to create an X8R8G8B8 offscreen texture, trying R5G6B5\n");
2461 hr = IDirect3DDevice8_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET,
2462 D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &offscreenTexture);
2463 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %#08x\n", hr);
2464 if (!offscreenTexture)
2466 skip("Cannot create an offscreen render target.\n");
2467 IDirect3DDevice8_Release(device);
2468 goto done;
2472 hr = IDirect3DDevice8_GetDepthStencilSurface(device, &depthstencil);
2473 ok(hr == D3D_OK, "IDirect3DDevice8_GetDepthStencilSurface failed, hr = %#08x\n", hr);
2475 hr = IDirect3DDevice8_GetBackBuffer(device, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
2476 ok(hr == D3D_OK, "Can't get back buffer, hr = %#08x\n", hr);
2478 hr = IDirect3DTexture8_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
2479 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %#08x\n", hr);
2481 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX1);
2482 ok(hr == D3D_OK, "SetVertexShader failed, hr = %#08x\n", hr);
2484 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
2485 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %#08x\n", hr);
2486 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
2487 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %#08x\n", hr);
2488 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MINFILTER, D3DTEXF_NONE);
2489 ok(SUCCEEDED(hr), "SetTextureStageState D3DSAMP_MINFILTER failed (%#08x)\n", hr);
2490 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MAGFILTER, D3DTEXF_NONE);
2491 ok(SUCCEEDED(hr), "SetTextureStageState D3DSAMP_MAGFILTER failed (%#08x)\n", hr);
2492 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
2493 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %08x\n", hr);
2495 hr = IDirect3DDevice8_BeginScene(device);
2496 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
2498 hr = IDirect3DDevice8_SetRenderTarget(device, offscreen, depthstencil);
2499 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
2500 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 1.0f, 0);
2501 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
2503 /* Draw without textures - Should result in a white quad. */
2504 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
2505 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2507 hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, depthstencil);
2508 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
2509 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)offscreenTexture);
2510 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
2512 /* This time with the texture .*/
2513 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
2514 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2516 hr = IDirect3DDevice8_EndScene(device);
2517 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
2519 /* Center quad - should be white */
2520 color = getPixelColor(device, 320, 240);
2521 ok(color == 0x00ffffff, "Offscreen failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2522 /* Some quad in the cleared part of the texture */
2523 color = getPixelColor(device, 170, 240);
2524 ok(color == 0x00ff00ff, "Offscreen failed: Got color 0x%08x, expected 0x00ff00ff.\n", color);
2525 /* Part of the originally cleared back buffer */
2526 color = getPixelColor(device, 10, 10);
2527 ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2528 color = getPixelColor(device, 10, 470);
2529 ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2531 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
2533 IDirect3DSurface8_Release(backbuffer);
2534 IDirect3DTexture8_Release(offscreenTexture);
2535 IDirect3DSurface8_Release(offscreen);
2536 IDirect3DSurface8_Release(depthstencil);
2537 refcount = IDirect3DDevice8_Release(device);
2538 ok(!refcount, "Device has %u references left.\n", refcount);
2539 done:
2540 IDirect3D8_Release(d3d);
2541 DestroyWindow(window);
2544 static void test_blend(void)
2546 IDirect3DSurface8 *backbuffer, *offscreen, *depthstencil;
2547 IDirect3DTexture8 *offscreenTexture;
2548 IDirect3DDevice8 *device;
2549 IDirect3D8 *d3d;
2550 D3DCOLOR color;
2551 ULONG refcount;
2552 HWND window;
2553 HRESULT hr;
2555 static const struct
2557 struct vec3 position;
2558 DWORD diffuse;
2560 quad1[] =
2562 {{-1.0f, -1.0f, 0.1f}, 0x4000ff00},
2563 {{-1.0f, 0.0f, 0.1f}, 0x4000ff00},
2564 {{ 1.0f, -1.0f, 0.1f}, 0x4000ff00},
2565 {{ 1.0f, 0.0f, 0.1f}, 0x4000ff00},
2567 quad2[] =
2569 {{-1.0f, 0.0f, 0.1f}, 0xc00000ff},
2570 {{-1.0f, 1.0f, 0.1f}, 0xc00000ff},
2571 {{ 1.0f, 0.0f, 0.1f}, 0xc00000ff},
2572 {{ 1.0f, 1.0f, 0.1f}, 0xc00000ff},
2574 static const float composite_quad[][5] =
2576 { 0.0f, -1.0f, 0.1f, 0.0f, 1.0f},
2577 { 0.0f, 1.0f, 0.1f, 0.0f, 0.0f},
2578 { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f},
2579 { 1.0f, 1.0f, 0.1f, 1.0f, 0.0f},
2582 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
2583 0, 0, 640, 480, NULL, NULL, NULL, NULL);
2584 d3d = Direct3DCreate8(D3D_SDK_VERSION);
2585 ok(!!d3d, "Failed to create a D3D object.\n");
2586 if (!(device = create_device(d3d, window, window, TRUE)))
2588 skip("Failed to create a D3D device, skipping tests.\n");
2589 goto done;
2592 /* Clear the render target with alpha = 0.5 */
2593 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x80ff0000, 1.0f, 0);
2594 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
2596 hr = IDirect3DDevice8_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET,
2597 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture);
2598 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
2600 hr = IDirect3DDevice8_GetDepthStencilSurface(device, &depthstencil);
2601 ok(SUCCEEDED(hr), "Failed to get depth/stencil buffer, hr %#x.\n", hr);
2602 hr = IDirect3DDevice8_GetBackBuffer(device, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
2603 ok(SUCCEEDED(hr), "Failed to get back buffer, hr %#x.\n", hr);
2605 hr = IDirect3DTexture8_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
2606 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %#08x\n", hr);
2608 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
2609 ok(hr == D3D_OK, "SetVertexShader failed, hr = %#08x\n", hr);
2611 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
2612 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %#08x\n", hr);
2613 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
2614 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %#08x\n", hr);
2615 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MINFILTER, D3DTEXF_NONE);
2616 ok(SUCCEEDED(hr), "SetTextureStageState D3DSAMP_MINFILTER failed (%#08x)\n", hr);
2617 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MAGFILTER, D3DTEXF_NONE);
2618 ok(SUCCEEDED(hr), "SetTextureStageState D3DSAMP_MAGFILTER failed (%#08x)\n", hr);
2619 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
2620 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState returned %08x\n", hr);
2622 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
2623 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
2624 hr = IDirect3DDevice8_BeginScene(device);
2625 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
2627 /* Draw two quads, one with src alpha blending, one with dest alpha blending. */
2628 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
2629 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
2630 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
2631 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
2632 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
2633 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2635 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
2636 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
2637 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
2638 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
2639 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
2640 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2642 /* Switch to the offscreen buffer, and redo the testing. The offscreen
2643 * render target doesn't have an alpha channel. DESTALPHA and INVDESTALPHA
2644 * "don't work" on render targets without alpha channel, they give
2645 * essentially ZERO and ONE blend factors. */
2646 hr = IDirect3DDevice8_SetRenderTarget(device, offscreen, 0);
2647 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
2648 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x80ff0000, 0.0, 0);
2649 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
2651 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
2652 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
2653 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
2654 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
2655 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
2656 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2658 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
2659 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
2660 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
2661 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
2662 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
2663 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2665 hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, depthstencil);
2666 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
2668 /* Render the offscreen texture onto the frame buffer to be able to
2669 * compare it regularly. Disable alpha blending for the final
2670 * composition. */
2671 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
2672 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
2673 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX1);
2674 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
2676 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *) offscreenTexture);
2677 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
2678 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, composite_quad, sizeof(float) * 5);
2679 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2681 hr = IDirect3DDevice8_EndScene(device);
2682 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
2684 color = getPixelColor(device, 160, 360);
2685 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
2686 "SRCALPHA on frame buffer returned color %08x, expected 0x00bf4000\n", color);
2688 color = getPixelColor(device, 160, 120);
2689 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x00, 0x80), 2),
2690 "DSTALPHA on frame buffer returned color %08x, expected 0x007f0080\n", color);
2692 color = getPixelColor(device, 480, 360);
2693 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
2694 "SRCALPHA on texture returned color %08x, expected 0x00bf4000\n", color);
2696 color = getPixelColor(device, 480, 120);
2697 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
2698 "DSTALPHA on texture returned color %08x, expected 0x000000ff\n", color);
2700 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
2702 IDirect3DSurface8_Release(backbuffer);
2703 IDirect3DTexture8_Release(offscreenTexture);
2704 IDirect3DSurface8_Release(offscreen);
2705 IDirect3DSurface8_Release(depthstencil);
2706 refcount = IDirect3DDevice8_Release(device);
2707 ok(!refcount, "Device has %u references left.\n", refcount);
2708 done:
2709 IDirect3D8_Release(d3d);
2710 DestroyWindow(window);
2713 static void p8_texture_test(void)
2715 IDirect3DTexture8 *texture, *texture2;
2716 IDirect3DDevice8 *device;
2717 PALETTEENTRY table[256];
2718 unsigned char *data;
2719 D3DLOCKED_RECT lr;
2720 IDirect3D8 *d3d;
2721 D3DCOLOR color;
2722 ULONG refcount;
2723 D3DCAPS8 caps;
2724 HWND window;
2725 HRESULT hr;
2726 UINT i;
2728 static const float quad[] =
2730 -1.0f, 0.0f, 0.1f, 0.0f, 0.0f,
2731 -1.0f, 1.0f, 0.1f, 0.0f, 1.0f,
2732 1.0f, 0.0f, 0.1f, 1.0f, 0.0f,
2733 1.0f, 1.0f, 0.1f, 1.0f, 1.0f,
2735 static const float quad2[] =
2737 -1.0f, -1.0f, 0.1f, 0.0f, 0.0f,
2738 -1.0f, 0.0f, 0.1f, 0.0f, 1.0f,
2739 1.0f, -1.0f, 0.1f, 1.0f, 0.0f,
2740 1.0f, 0.0f, 0.1f, 1.0f, 1.0f,
2743 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
2744 0, 0, 640, 480, NULL, NULL, NULL, NULL);
2745 d3d = Direct3DCreate8(D3D_SDK_VERSION);
2746 ok(!!d3d, "Failed to create a D3D object.\n");
2747 if (!(device = create_device(d3d, window, window, TRUE)))
2749 skip("Failed to create a D3D device, skipping tests.\n");
2750 goto done;
2753 if (IDirect3D8_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
2754 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_P8) != D3D_OK)
2756 skip("D3DFMT_P8 textures not supported.\n");
2757 IDirect3DDevice8_Release(device);
2758 goto done;
2761 hr = IDirect3DDevice8_CreateTexture(device, 1, 1, 1, 0, D3DFMT_P8, D3DPOOL_MANAGED, &texture2);
2762 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
2763 memset(&lr, 0, sizeof(lr));
2764 hr = IDirect3DTexture8_LockRect(texture2, 0, &lr, NULL, 0);
2765 ok(hr == D3D_OK, "IDirect3DTexture8_LockRect failed, hr = %08x\n", hr);
2766 data = lr.pBits;
2767 *data = 1;
2768 hr = IDirect3DTexture8_UnlockRect(texture2, 0);
2769 ok(hr == D3D_OK, "IDirect3DTexture8_UnlockRect failed, hr = %08x\n", hr);
2771 hr = IDirect3DDevice8_CreateTexture(device, 1, 1, 1, 0, D3DFMT_P8, D3DPOOL_MANAGED, &texture);
2772 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
2773 memset(&lr, 0, sizeof(lr));
2774 hr = IDirect3DTexture8_LockRect(texture, 0, &lr, NULL, 0);
2775 ok(hr == D3D_OK, "IDirect3DTexture8_LockRect failed, hr = %08x\n", hr);
2776 data = lr.pBits;
2777 *data = 1;
2778 hr = IDirect3DTexture8_UnlockRect(texture, 0);
2779 ok(hr == D3D_OK, "IDirect3DTexture8_UnlockRect failed, hr = %08x\n", hr);
2781 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff000000, 1.0f, 0);
2782 ok(hr == D3D_OK, "IDirect3DDevice8_Clear failed, hr = %08x\n", hr);
2784 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
2785 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
2786 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
2787 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
2789 /* The first part of the test should work both with and without D3DPTEXTURECAPS_ALPHAPALETTE;
2790 alpha of every entry is set to 1.0, which MS says is required when there's no
2791 D3DPTEXTURECAPS_ALPHAPALETTE capability */
2792 for (i = 0; i < 256; i++) {
2793 table[i].peRed = table[i].peGreen = table[i].peBlue = 0;
2794 table[i].peFlags = 0xff;
2796 table[1].peRed = 0xff;
2797 hr = IDirect3DDevice8_SetPaletteEntries(device, 0, table);
2798 ok(hr == D3D_OK, "IDirect3DDevice8_SetPaletteEntries failed, hr = %08x\n", hr);
2800 table[1].peRed = 0;
2801 table[1].peBlue = 0xff;
2802 hr = IDirect3DDevice8_SetPaletteEntries(device, 1, table);
2803 ok(hr == D3D_OK, "IDirect3DDevice8_SetPaletteEntries failed, hr = %08x\n", hr);
2805 hr = IDirect3DDevice8_BeginScene(device);
2806 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
2808 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
2809 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
2810 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
2811 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
2812 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX1);
2813 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
2814 hr = IDirect3DDevice8_SetCurrentTexturePalette(device, 0);
2815 ok(SUCCEEDED(hr), "Failed to set texture palette, hr %#x.\n", hr);
2816 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture2);
2817 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
2818 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
2819 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2821 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
2822 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
2823 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
2824 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2826 hr = IDirect3DDevice8_SetCurrentTexturePalette(device, 1);
2827 ok(SUCCEEDED(hr), "Failed to set texture palette, hr %#x.\n", hr);
2828 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
2829 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2831 hr = IDirect3DDevice8_EndScene(device);
2832 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
2834 color = getPixelColor(device, 32, 32);
2835 ok(color_match(color, 0x00ff0000, 0), "Got unexpected color 0x%08x.\n", color);
2836 color = getPixelColor(device, 32, 320);
2837 ok(color_match(color, 0x000000ff, 0), "Got unexpected color 0x%08x.\n", color);
2839 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
2840 ok(hr == D3D_OK, "IDirect3DDevice8_Present failed, hr = %08x\n", hr);
2842 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
2843 ok(hr == D3D_OK, "IDirect3DDevice8_Clear failed, hr = %08x\n", hr);
2845 hr = IDirect3DDevice8_BeginScene(device);
2846 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
2847 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture2);
2848 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
2849 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
2850 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2851 hr = IDirect3DDevice8_EndScene(device);
2852 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
2854 color = getPixelColor(device, 32, 32);
2855 ok(color_match(color, 0x000000ff, 0), "Got unexpected color 0x%08x.\n", color);
2857 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
2858 ok(hr == D3D_OK, "IDirect3DDevice8_Present failed, hr = %08x\n", hr);
2860 /* Test palettes with alpha */
2861 IDirect3DDevice8_GetDeviceCaps(device, &caps);
2862 if (!(caps.TextureCaps & D3DPTEXTURECAPS_ALPHAPALETTE)) {
2863 skip("no D3DPTEXTURECAPS_ALPHAPALETTE capability, tests with alpha in palette will be skipped\n");
2864 } else {
2865 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
2866 ok(hr == D3D_OK, "IDirect3DDevice8_Clear failed, hr = %08x\n", hr);
2868 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
2869 ok(hr == D3D_OK, "IDirect3DDevice8_SetRenderState failed, hr = %08x\n", hr);
2871 for (i = 0; i < 256; i++) {
2872 table[i].peRed = table[i].peGreen = table[i].peBlue = 0;
2873 table[i].peFlags = 0xff;
2875 table[1].peRed = 0xff;
2876 table[1].peFlags = 0x80;
2877 hr = IDirect3DDevice8_SetPaletteEntries(device, 0, table);
2878 ok(hr == D3D_OK, "IDirect3DDevice8_SetPaletteEntries failed, hr = %08x\n", hr);
2880 table[1].peRed = 0;
2881 table[1].peBlue = 0xff;
2882 table[1].peFlags = 0x80;
2883 hr = IDirect3DDevice8_SetPaletteEntries(device, 1, table);
2884 ok(hr == D3D_OK, "IDirect3DDevice8_SetPaletteEntries failed, hr = %08x\n", hr);
2886 hr = IDirect3DDevice8_BeginScene(device);
2887 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
2889 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
2890 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
2891 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
2892 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
2893 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX1);
2894 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
2896 hr = IDirect3DDevice8_SetCurrentTexturePalette(device, 0);
2897 ok(SUCCEEDED(hr), "Failed to set texture palette, hr %#x.\n", hr);
2898 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
2899 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2901 hr = IDirect3DDevice8_SetCurrentTexturePalette(device, 1);
2902 ok(SUCCEEDED(hr), "Failed to set texture palette, hr %#x.\n", hr);
2903 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
2904 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2906 hr = IDirect3DDevice8_EndScene(device);
2907 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
2909 color = getPixelColor(device, 32, 32);
2910 ok(color_match(color, 0x00800000, 1), "Got unexpected color 0x%08x.\n", color);
2911 color = getPixelColor(device, 32, 320);
2912 ok(color_match(color, 0x00000080, 1), "Got unexpected color 0x%08x.\n", color);
2914 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
2915 ok(hr == D3D_OK, "IDirect3DDevice8_Present failed, hr = %08x\n", hr);
2918 IDirect3DTexture8_Release(texture);
2919 IDirect3DTexture8_Release(texture2);
2920 refcount = IDirect3DDevice8_Release(device);
2921 ok(!refcount, "Device has %u references left.\n", refcount);
2922 done:
2923 IDirect3D8_Release(d3d);
2924 DestroyWindow(window);
2927 static void texop_test(void)
2929 IDirect3DTexture8 *texture;
2930 D3DLOCKED_RECT locked_rect;
2931 IDirect3DDevice8 *device;
2932 IDirect3D8 *d3d;
2933 unsigned int i;
2934 D3DCOLOR color;
2935 ULONG refcount;
2936 D3DCAPS8 caps;
2937 HWND window;
2938 HRESULT hr;
2940 static const struct {
2941 float x, y, z;
2942 D3DCOLOR diffuse;
2943 float s, t;
2944 } quad[] = {
2945 {-1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00), -1.0f, -1.0f},
2946 {-1.0f, 1.0f, 0.1f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00), -1.0f, 1.0f},
2947 { 1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00), 1.0f, -1.0f},
2948 { 1.0f, 1.0f, 0.1f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00), 1.0f, 1.0f}
2951 static const struct {
2952 D3DTEXTUREOP op;
2953 const char *name;
2954 DWORD caps_flag;
2955 D3DCOLOR result;
2956 } test_data[] = {
2957 {D3DTOP_SELECTARG1, "SELECTARG1", D3DTEXOPCAPS_SELECTARG1, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
2958 {D3DTOP_SELECTARG2, "SELECTARG2", D3DTEXOPCAPS_SELECTARG2, D3DCOLOR_ARGB(0x00, 0x33, 0x33, 0x33)},
2959 {D3DTOP_MODULATE, "MODULATE", D3DTEXOPCAPS_MODULATE, D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x00)},
2960 {D3DTOP_MODULATE2X, "MODULATE2X", D3DTEXOPCAPS_MODULATE2X, D3DCOLOR_ARGB(0x00, 0x00, 0x66, 0x00)},
2961 {D3DTOP_MODULATE4X, "MODULATE4X", D3DTEXOPCAPS_MODULATE4X, D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
2962 {D3DTOP_ADD, "ADD", D3DTEXOPCAPS_ADD, D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
2964 {D3DTOP_ADDSIGNED, "ADDSIGNED", D3DTEXOPCAPS_ADDSIGNED, D3DCOLOR_ARGB(0x00, 0x00, 0xb2, 0x00)},
2965 {D3DTOP_ADDSIGNED2X, "ADDSIGNED2X", D3DTEXOPCAPS_ADDSIGNED2X, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
2967 {D3DTOP_SUBTRACT, "SUBTRACT", D3DTEXOPCAPS_SUBTRACT, D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
2968 {D3DTOP_ADDSMOOTH, "ADDSMOOTH", D3DTEXOPCAPS_ADDSMOOTH, D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
2969 {D3DTOP_BLENDDIFFUSEALPHA, "BLENDDIFFUSEALPHA", D3DTEXOPCAPS_BLENDDIFFUSEALPHA, D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
2970 {D3DTOP_BLENDTEXTUREALPHA, "BLENDTEXTUREALPHA", D3DTEXOPCAPS_BLENDTEXTUREALPHA, D3DCOLOR_ARGB(0x00, 0x14, 0xad, 0x14)},
2971 {D3DTOP_BLENDFACTORALPHA, "BLENDFACTORALPHA", D3DTEXOPCAPS_BLENDFACTORALPHA, D3DCOLOR_ARGB(0x00, 0x07, 0xe4, 0x07)},
2972 {D3DTOP_BLENDTEXTUREALPHAPM, "BLENDTEXTUREALPHAPM", D3DTEXOPCAPS_BLENDTEXTUREALPHAPM, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
2973 {D3DTOP_BLENDCURRENTALPHA, "BLENDCURRENTALPHA", D3DTEXOPCAPS_BLENDCURRENTALPHA, D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
2974 {D3DTOP_MODULATEALPHA_ADDCOLOR, "MODULATEALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x1f, 0xff, 0x1f)},
2975 {D3DTOP_MODULATECOLOR_ADDALPHA, "MODULATECOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0x99, 0xcc, 0x99)},
2976 {D3DTOP_MODULATEINVALPHA_ADDCOLOR, "MODULATEINVALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
2977 {D3DTOP_MODULATEINVCOLOR_ADDALPHA, "MODULATEINVCOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0xcc, 0x99, 0xcc)},
2978 /* BUMPENVMAP & BUMPENVMAPLUMINANCE have their own tests */
2979 {D3DTOP_DOTPRODUCT3, "DOTPRODUCT2", D3DTEXOPCAPS_DOTPRODUCT3, D3DCOLOR_ARGB(0x00, 0x99, 0x99, 0x99)},
2980 {D3DTOP_MULTIPLYADD, "MULTIPLYADD", D3DTEXOPCAPS_MULTIPLYADD, D3DCOLOR_ARGB(0x00, 0xff, 0x33, 0x00)},
2981 {D3DTOP_LERP, "LERP", D3DTEXOPCAPS_LERP, D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x33)},
2984 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
2985 0, 0, 640, 480, NULL, NULL, NULL, NULL);
2986 d3d = Direct3DCreate8(D3D_SDK_VERSION);
2987 ok(!!d3d, "Failed to create a D3D object.\n");
2988 if (!(device = create_device(d3d, window, window, TRUE)))
2990 skip("Failed to create a D3D device, skipping tests.\n");
2991 goto done;
2994 memset(&caps, 0, sizeof(caps));
2995 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
2996 ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
2998 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX0);
2999 ok(SUCCEEDED(hr), "SetVertexShader failed with 0x%08x\n", hr);
3001 hr = IDirect3DDevice8_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture);
3002 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
3003 hr = IDirect3DTexture8_LockRect(texture, 0, &locked_rect, NULL, 0);
3004 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
3005 *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x99, 0x00, 0xff, 0x00);
3006 hr = IDirect3DTexture8_UnlockRect(texture, 0);
3007 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
3008 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
3009 ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
3011 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG0, D3DTA_DIFFUSE);
3012 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
3013 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
3014 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
3015 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
3016 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
3018 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
3019 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
3021 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3022 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
3023 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xdd333333);
3024 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
3025 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_ALPHA);
3026 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
3028 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
3029 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
3031 for (i = 0; i < sizeof(test_data) / sizeof(*test_data); ++i)
3033 if (!(caps.TextureOpCaps & test_data[i].caps_flag))
3035 skip("tex operation %s not supported\n", test_data[i].name);
3036 continue;
3039 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLOROP, test_data[i].op);
3040 ok(SUCCEEDED(hr), "SetTextureStageState (%s) failed with 0x%08x\n", test_data[i].name, hr);
3042 hr = IDirect3DDevice8_BeginScene(device);
3043 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
3045 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
3046 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
3048 hr = IDirect3DDevice8_EndScene(device);
3049 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
3051 color = getPixelColor(device, 320, 240);
3052 ok(color_match(color, test_data[i].result, 3), "Operation %s returned color 0x%08x, expected 0x%08x\n",
3053 test_data[i].name, color, test_data[i].result);
3055 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
3056 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
3058 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
3059 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
3062 IDirect3DTexture8_Release(texture);
3063 refcount = IDirect3DDevice8_Release(device);
3064 ok(!refcount, "Device has %u references left.\n", refcount);
3065 done:
3066 IDirect3D8_Release(d3d);
3067 DestroyWindow(window);
3070 /* This test tests depth clamping / clipping behaviour:
3071 * - With software vertex processing, depth values are clamped to the
3072 * minimum / maximum z value when D3DRS_CLIPPING is disabled, and clipped
3073 * when D3DRS_CLIPPING is enabled. Pretransformed vertices behave the
3074 * same as regular vertices here.
3075 * - With hardware vertex processing, D3DRS_CLIPPING seems to be ignored.
3076 * Normal vertices are always clipped. Pretransformed vertices are
3077 * clipped when D3DPMISCCAPS_CLIPTLVERTS is set, clamped when it isn't.
3078 * - The viewport's MinZ/MaxZ is irrelevant for this.
3080 static void depth_clamp_test(void)
3082 IDirect3DDevice8 *device;
3083 D3DVIEWPORT8 vp;
3084 IDirect3D8 *d3d;
3085 D3DCOLOR color;
3086 ULONG refcount;
3087 D3DCAPS8 caps;
3088 HWND window;
3089 HRESULT hr;
3091 static const struct
3093 struct vec4 position;
3094 DWORD diffuse;
3096 quad1[] =
3098 {{ 0.0f, 0.0f, 5.0f, 1.0f}, 0xff002b7f},
3099 {{640.0f, 0.0f, 5.0f, 1.0f}, 0xff002b7f},
3100 {{ 0.0f, 480.0f, 5.0f, 1.0f}, 0xff002b7f},
3101 {{640.0f, 480.0f, 5.0f, 1.0f}, 0xff002b7f},
3103 quad2[] =
3105 {{ 0.0f, 300.0f, 10.0f, 1.0f}, 0xfff9e814},
3106 {{640.0f, 300.0f, 10.0f, 1.0f}, 0xfff9e814},
3107 {{ 0.0f, 360.0f, 10.0f, 1.0f}, 0xfff9e814},
3108 {{640.0f, 360.0f, 10.0f, 1.0f}, 0xfff9e814},
3110 quad3[] =
3112 {{112.0f, 108.0f, 5.0f, 1.0f}, 0xffffffff},
3113 {{208.0f, 108.0f, 5.0f, 1.0f}, 0xffffffff},
3114 {{112.0f, 204.0f, 5.0f, 1.0f}, 0xffffffff},
3115 {{208.0f, 204.0f, 5.0f, 1.0f}, 0xffffffff},
3117 quad4[] =
3119 {{ 42.0f, 41.0f, 10.0f, 1.0f}, 0xffffffff},
3120 {{112.0f, 41.0f, 10.0f, 1.0f}, 0xffffffff},
3121 {{ 42.0f, 108.0f, 10.0f, 1.0f}, 0xffffffff},
3122 {{112.0f, 108.0f, 10.0f, 1.0f}, 0xffffffff},
3124 static const struct
3126 struct vec3 position;
3127 DWORD diffuse;
3129 quad5[] =
3131 {{-0.5f, 0.5f, 10.0f}, 0xff14f914},
3132 {{ 0.5f, 0.5f, 10.0f}, 0xff14f914},
3133 {{-0.5f, -0.5f, 10.0f}, 0xff14f914},
3134 {{ 0.5f, -0.5f, 10.0f}, 0xff14f914},
3136 quad6[] =
3138 {{-1.0f, 0.5f, 10.0f}, 0xfff91414},
3139 {{ 1.0f, 0.5f, 10.0f}, 0xfff91414},
3140 {{-1.0f, 0.25f, 10.0f}, 0xfff91414},
3141 {{ 1.0f, 0.25f, 10.0f}, 0xfff91414},
3144 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
3145 0, 0, 640, 480, NULL, NULL, NULL, NULL);
3146 d3d = Direct3DCreate8(D3D_SDK_VERSION);
3147 ok(!!d3d, "Failed to create a D3D object.\n");
3148 if (!(device = create_device(d3d, window, window, TRUE)))
3150 skip("Failed to create a D3D device, skipping tests.\n");
3151 goto done;
3154 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
3155 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
3157 vp.X = 0;
3158 vp.Y = 0;
3159 vp.Width = 640;
3160 vp.Height = 480;
3161 vp.MinZ = 0.0;
3162 vp.MaxZ = 7.5;
3164 hr = IDirect3DDevice8_SetViewport(device, &vp);
3165 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
3167 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0, 0);
3168 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
3170 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, FALSE);
3171 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3172 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3173 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3174 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
3175 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3176 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
3177 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3179 hr = IDirect3DDevice8_BeginScene(device);
3180 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
3182 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
3183 ok(SUCCEEDED(hr), "SetVertexSahder failed, hr %#x.\n", hr);
3185 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
3186 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3187 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
3188 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3190 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, TRUE);
3191 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3193 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
3194 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3195 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(*quad4));
3196 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3198 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, FALSE);
3199 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3200 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
3201 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
3203 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad5, sizeof(*quad5));
3204 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3206 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, TRUE);
3207 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3209 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad6, sizeof(*quad6));
3210 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3212 hr = IDirect3DDevice8_EndScene(device);
3213 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
3215 if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
3217 color = getPixelColor(device, 75, 75);
3218 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
3219 color = getPixelColor(device, 150, 150);
3220 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
3221 color = getPixelColor(device, 320, 240);
3222 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
3223 color = getPixelColor(device, 320, 330);
3224 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
3225 color = getPixelColor(device, 320, 330);
3226 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
3228 else
3230 color = getPixelColor(device, 75, 75);
3231 ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
3232 color = getPixelColor(device, 150, 150);
3233 ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
3234 color = getPixelColor(device, 320, 240);
3235 ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);
3236 color = getPixelColor(device, 320, 330);
3237 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
3238 color = getPixelColor(device, 320, 330);
3239 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
3242 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
3243 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3245 refcount = IDirect3DDevice8_Release(device);
3246 ok(!refcount, "Device has %u references left.\n", refcount);
3247 done:
3248 IDirect3D8_Release(d3d);
3249 DestroyWindow(window);
3252 static void depth_buffer_test(void)
3254 IDirect3DSurface8 *backbuffer, *rt1, *rt2, *rt3;
3255 IDirect3DSurface8 *depth_stencil;
3256 IDirect3DDevice8 *device;
3257 unsigned int i, j;
3258 D3DVIEWPORT8 vp;
3259 IDirect3D8 *d3d;
3260 D3DCOLOR color;
3261 ULONG refcount;
3262 HWND window;
3263 HRESULT hr;
3265 static const struct
3267 struct vec3 position;
3268 DWORD diffuse;
3270 quad1[] =
3272 {{-1.0f, 1.0f, 0.33f}, 0xff00ff00},
3273 {{ 1.0f, 1.0f, 0.33f}, 0xff00ff00},
3274 {{-1.0f, -1.0f, 0.33f}, 0xff00ff00},
3275 {{ 1.0f, -1.0f, 0.33f}, 0xff00ff00},
3277 quad2[] =
3279 {{-1.0f, 1.0f, 0.50f}, 0xffff00ff},
3280 {{ 1.0f, 1.0f, 0.50f}, 0xffff00ff},
3281 {{-1.0f, -1.0f, 0.50f}, 0xffff00ff},
3282 {{ 1.0f, -1.0f, 0.50f}, 0xffff00ff},
3284 quad3[] =
3286 {{-1.0f, 1.0f, 0.66f}, 0xffff0000},
3287 {{ 1.0f, 1.0f, 0.66f}, 0xffff0000},
3288 {{-1.0f, -1.0f, 0.66f}, 0xffff0000},
3289 {{ 1.0f, -1.0f, 0.66f}, 0xffff0000},
3291 static const DWORD expected_colors[4][4] =
3293 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
3294 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
3295 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x00ff0000},
3296 {0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
3299 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
3300 0, 0, 640, 480, NULL, NULL, NULL, NULL);
3301 d3d = Direct3DCreate8(D3D_SDK_VERSION);
3302 ok(!!d3d, "Failed to create a D3D object.\n");
3303 if (!(device = create_device(d3d, window, window, TRUE)))
3305 skip("Failed to create a D3D device, skipping tests.\n");
3306 goto done;
3309 vp.X = 0;
3310 vp.Y = 0;
3311 vp.Width = 640;
3312 vp.Height = 480;
3313 vp.MinZ = 0.0;
3314 vp.MaxZ = 1.0;
3316 hr = IDirect3DDevice8_SetViewport(device, &vp);
3317 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
3319 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3320 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3321 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
3322 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3323 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
3324 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3325 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
3326 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3327 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
3328 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
3330 hr = IDirect3DDevice8_GetDepthStencilSurface(device, &depth_stencil);
3331 ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
3332 hr = IDirect3DDevice8_GetRenderTarget(device, &backbuffer);
3333 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
3334 hr = IDirect3DDevice8_CreateRenderTarget(device, 320, 240, D3DFMT_A8R8G8B8,
3335 D3DMULTISAMPLE_NONE, FALSE, &rt1);
3336 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
3337 hr = IDirect3DDevice8_CreateRenderTarget(device, 480, 360, D3DFMT_A8R8G8B8,
3338 D3DMULTISAMPLE_NONE, FALSE, &rt2);
3339 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
3340 hr = IDirect3DDevice8_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
3341 D3DMULTISAMPLE_NONE, FALSE, &rt3);
3342 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
3344 hr = IDirect3DDevice8_SetRenderTarget(device, rt3, depth_stencil);
3345 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
3346 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0f, 0);
3347 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
3349 hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, depth_stencil);
3350 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
3351 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
3352 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
3354 hr = IDirect3DDevice8_SetRenderTarget(device, rt1, depth_stencil);
3355 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
3356 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0f, 0);
3357 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
3359 hr = IDirect3DDevice8_SetRenderTarget(device, rt2, depth_stencil);
3360 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
3361 hr = IDirect3DDevice8_BeginScene(device);
3362 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
3363 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
3364 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3365 hr = IDirect3DDevice8_EndScene(device);
3366 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
3368 hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, depth_stencil);
3369 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
3371 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
3372 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3374 hr = IDirect3DDevice8_BeginScene(device);
3375 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
3376 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
3377 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3378 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
3379 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3380 hr = IDirect3DDevice8_EndScene(device);
3381 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
3383 for (i = 0; i < 4; ++i)
3385 for (j = 0; j < 4; ++j)
3387 unsigned int x = 80 * ((2 * j) + 1);
3388 unsigned int y = 60 * ((2 * i) + 1);
3389 color = getPixelColor(device, x, y);
3390 ok(color_match(color, expected_colors[i][j], 0),
3391 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors[i][j], x, y, color);
3395 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
3396 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3398 IDirect3DSurface8_Release(depth_stencil);
3399 IDirect3DSurface8_Release(backbuffer);
3400 IDirect3DSurface8_Release(rt3);
3401 IDirect3DSurface8_Release(rt2);
3402 IDirect3DSurface8_Release(rt1);
3403 refcount = IDirect3DDevice8_Release(device);
3404 ok(!refcount, "Device has %u references left.\n", refcount);
3405 done:
3406 IDirect3D8_Release(d3d);
3407 DestroyWindow(window);
3410 /* Test that partial depth copies work the way they're supposed to. The clear
3411 * on rt2 only needs a partial copy of the onscreen depth/stencil buffer, and
3412 * the following draw should only copy back the part that was modified. */
3413 static void depth_buffer2_test(void)
3415 IDirect3DSurface8 *backbuffer, *rt1, *rt2;
3416 IDirect3DSurface8 *depth_stencil;
3417 IDirect3DDevice8 *device;
3418 unsigned int i, j;
3419 D3DVIEWPORT8 vp;
3420 IDirect3D8 *d3d;
3421 D3DCOLOR color;
3422 ULONG refcount;
3423 HWND window;
3424 HRESULT hr;
3426 static const struct
3428 struct vec3 position;
3429 DWORD diffuse;
3431 quad[] =
3433 {{-1.0f, 1.0f, 0.66f}, 0xffff0000},
3434 {{ 1.0f, 1.0f, 0.66f}, 0xffff0000},
3435 {{-1.0f, -1.0f, 0.66f}, 0xffff0000},
3436 {{ 1.0f, -1.0f, 0.66f}, 0xffff0000},
3439 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
3440 0, 0, 640, 480, NULL, NULL, NULL, NULL);
3441 d3d = Direct3DCreate8(D3D_SDK_VERSION);
3442 ok(!!d3d, "Failed to create a D3D object.\n");
3443 if (!(device = create_device(d3d, window, window, TRUE)))
3445 skip("Failed to create a D3D device, skipping tests.\n");
3446 goto done;
3449 vp.X = 0;
3450 vp.Y = 0;
3451 vp.Width = 640;
3452 vp.Height = 480;
3453 vp.MinZ = 0.0;
3454 vp.MaxZ = 1.0;
3456 hr = IDirect3DDevice8_SetViewport(device, &vp);
3457 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
3459 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3460 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3461 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
3462 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3463 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
3464 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3465 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
3466 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3467 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
3468 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
3470 hr = IDirect3DDevice8_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
3471 D3DMULTISAMPLE_NONE, FALSE, &rt1);
3472 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
3473 hr = IDirect3DDevice8_CreateRenderTarget(device, 480, 360, D3DFMT_A8R8G8B8,
3474 D3DMULTISAMPLE_NONE, FALSE, &rt2);
3475 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
3476 hr = IDirect3DDevice8_GetDepthStencilSurface(device, &depth_stencil);
3477 ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
3478 hr = IDirect3DDevice8_GetRenderTarget(device, &backbuffer);
3479 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
3481 hr = IDirect3DDevice8_SetRenderTarget(device, rt1, depth_stencil);
3482 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
3483 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
3484 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
3486 hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, depth_stencil);
3487 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
3488 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 0.5f, 0);
3489 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
3491 hr = IDirect3DDevice8_SetRenderTarget(device, rt2, depth_stencil);
3492 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
3493 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0f, 0);
3494 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
3496 hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, depth_stencil);
3497 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
3499 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
3500 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3502 hr = IDirect3DDevice8_BeginScene(device);
3503 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
3504 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
3505 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3506 hr = IDirect3DDevice8_EndScene(device);
3507 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
3509 for (i = 0; i < 4; ++i)
3511 for (j = 0; j < 4; ++j)
3513 unsigned int x = 80 * ((2 * j) + 1);
3514 unsigned int y = 60 * ((2 * i) + 1);
3515 color = getPixelColor(device, x, y);
3516 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
3517 "Expected color 0x0000ff00 %u,%u, got 0x%08x.\n", x, y, color);
3521 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
3522 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3524 IDirect3DSurface8_Release(depth_stencil);
3525 IDirect3DSurface8_Release(backbuffer);
3526 IDirect3DSurface8_Release(rt2);
3527 IDirect3DSurface8_Release(rt1);
3528 refcount = IDirect3DDevice8_Release(device);
3529 ok(!refcount, "Device has %u references left.\n", refcount);
3530 done:
3531 IDirect3D8_Release(d3d);
3532 DestroyWindow(window);
3535 static void intz_test(void)
3537 IDirect3DSurface8 *original_rt, *rt;
3538 IDirect3DTexture8 *texture;
3539 IDirect3DDevice8 *device;
3540 IDirect3DSurface8 *ds;
3541 IDirect3D8 *d3d;
3542 ULONG refcount;
3543 D3DCAPS8 caps;
3544 HWND window;
3545 HRESULT hr;
3546 DWORD ps;
3547 UINT i;
3549 static const DWORD ps_code[] =
3551 0xffff0101, /* ps_1_1 */
3552 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1.0, 0.0, 0.0, 0.0 */
3553 0x00000051, 0xa00f0001, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c1, 0.0, 1.0, 0.0, 0.0 */
3554 0x00000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c2, 0.0, 0.0, 1.0, 0.0 */
3555 0x00000042, 0xb00f0000, /* tex t0 */
3556 0x00000042, 0xb00f0001, /* tex t1 */
3557 0x00000008, 0xb0070001, 0xa0e40000, 0xb0e40001, /* dp3 t1.xyz, c0, t1 */
3558 0x00000005, 0x80070000, 0xa0e40001, 0xb0e40001, /* mul r0.xyz, c1, t1 */
3559 0x00000004, 0x80070000, 0xa0e40000, 0xb0e40000, 0x80e40000, /* mad r0.xyz, c0, t0, r0 */
3560 0x40000001, 0x80080000, 0xa0aa0002, /* +mov r0.w, c2.z */
3561 0x0000ffff, /* end */
3563 static const struct
3565 float x, y, z;
3566 float s0, t0, p0;
3567 float s1, t1, p1, q1;
3569 quad[] =
3571 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.5f},
3572 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
3573 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
3574 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.5f},
3576 half_quad_1[] =
3578 { -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.5f},
3579 { 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
3580 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
3581 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.5f},
3583 half_quad_2[] =
3585 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.5f},
3586 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
3587 { -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
3588 { 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.5f},
3590 static const struct
3592 UINT x, y;
3593 D3DCOLOR color;
3595 expected_colors[] =
3597 { 80, 100, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
3598 {240, 100, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
3599 {400, 100, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
3600 {560, 100, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
3601 { 80, 450, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
3602 {240, 450, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
3603 {400, 450, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
3604 {560, 450, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
3607 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
3608 0, 0, 640, 480, NULL, NULL, NULL, NULL);
3609 d3d = Direct3DCreate8(D3D_SDK_VERSION);
3610 ok(!!d3d, "Failed to create a D3D object.\n");
3611 if (!(device = create_device(d3d, window, window, TRUE)))
3613 skip("Failed to create a D3D device, skipping tests.\n");
3614 goto done;
3617 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
3618 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
3619 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 1))
3621 skip("No pixel shader 1.1 support, skipping INTZ test.\n");
3622 IDirect3DDevice8_Release(device);
3623 goto done;
3625 if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
3627 skip("No unconditional NP2 texture support, skipping INTZ test.\n");
3628 IDirect3DDevice8_Release(device);
3629 goto done;
3632 if (FAILED(hr = IDirect3D8_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
3633 D3DFMT_X8R8G8B8, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, MAKEFOURCC('I','N','T','Z'))))
3635 skip("No INTZ support, skipping INTZ test.\n");
3636 IDirect3DDevice8_Release(device);
3637 goto done;
3640 hr = IDirect3DDevice8_GetRenderTarget(device, &original_rt);
3641 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
3643 hr = IDirect3DDevice8_CreateTexture(device, 640, 480, 1,
3644 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture);
3645 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
3646 hr = IDirect3DDevice8_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
3647 D3DMULTISAMPLE_NONE, FALSE, &rt);
3648 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
3649 hr = IDirect3DDevice8_CreatePixelShader(device, ps_code, &ps);
3650 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
3652 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX2
3653 | D3DFVF_TEXCOORDSIZE3(0) | D3DFVF_TEXCOORDSIZE4(1));
3654 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
3655 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
3656 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3657 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
3658 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3659 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
3660 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3661 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3662 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3664 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MINFILTER, D3DTEXF_POINT);
3665 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3666 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MIPFILTER, D3DTEXF_POINT);
3667 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3668 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MAGFILTER, D3DTEXF_POINT);
3669 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3670 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
3671 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3673 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP);
3674 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3675 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP);
3676 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3677 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MAGFILTER, D3DTEXF_POINT);
3678 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3679 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MINFILTER, D3DTEXF_POINT);
3680 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3681 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MIPFILTER, D3DTEXF_POINT);
3682 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3683 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS,
3684 D3DTTFF_COUNT4 | D3DTTFF_PROJECTED);
3685 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3687 hr = IDirect3DTexture8_GetSurfaceLevel(texture, 0, &ds);
3688 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
3690 /* Render offscreen, using the INTZ texture as depth buffer */
3691 hr = IDirect3DDevice8_SetRenderTarget(device, rt, ds);
3692 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
3693 hr = IDirect3DDevice8_SetPixelShader(device, 0);
3694 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
3696 /* Setup the depth/stencil surface. */
3697 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
3698 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
3700 hr = IDirect3DDevice8_BeginScene(device);
3701 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
3702 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
3703 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3704 hr = IDirect3DDevice8_EndScene(device);
3705 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
3707 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, NULL);
3708 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
3709 IDirect3DSurface8_Release(ds);
3710 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
3711 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
3712 hr = IDirect3DDevice8_SetTexture(device, 1, (IDirect3DBaseTexture8 *)texture);
3713 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
3714 hr = IDirect3DDevice8_SetPixelShader(device, ps);
3715 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
3717 /* Read the depth values back. */
3718 hr = IDirect3DDevice8_BeginScene(device);
3719 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
3720 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
3721 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3722 hr = IDirect3DDevice8_EndScene(device);
3723 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
3725 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
3727 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
3728 ok(color_match(color, expected_colors[i].color, 1),
3729 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
3730 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
3733 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
3734 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
3736 hr = IDirect3DDevice8_SetTexture(device, 0, NULL);
3737 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
3738 hr = IDirect3DDevice8_SetTexture(device, 1, NULL);
3739 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
3740 IDirect3DTexture8_Release(texture);
3742 /* Render onscreen while using the INTZ texture as depth buffer */
3743 hr = IDirect3DDevice8_CreateTexture(device, 640, 480, 1,
3744 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture);
3745 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
3746 hr = IDirect3DTexture8_GetSurfaceLevel(texture, 0, &ds);
3747 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
3748 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, ds);
3749 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
3750 hr = IDirect3DDevice8_SetPixelShader(device, 0);
3751 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
3753 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
3754 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
3756 hr = IDirect3DDevice8_BeginScene(device);
3757 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
3758 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
3759 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3760 hr = IDirect3DDevice8_EndScene(device);
3761 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
3763 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, NULL);
3764 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
3765 IDirect3DSurface8_Release(ds);
3766 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
3767 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
3768 hr = IDirect3DDevice8_SetTexture(device, 1, (IDirect3DBaseTexture8 *)texture);
3769 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
3770 hr = IDirect3DDevice8_SetPixelShader(device, ps);
3771 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
3773 /* Read the depth values back. */
3774 hr = IDirect3DDevice8_BeginScene(device);
3775 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
3776 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
3777 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3778 hr = IDirect3DDevice8_EndScene(device);
3779 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
3781 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
3783 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
3784 ok(color_match(color, expected_colors[i].color, 1),
3785 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
3786 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
3789 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
3790 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
3792 hr = IDirect3DDevice8_SetTexture(device, 0, NULL);
3793 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
3794 hr = IDirect3DDevice8_SetTexture(device, 1, NULL);
3795 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
3796 IDirect3DTexture8_Release(texture);
3798 /* Render offscreen, then onscreen, and finally check the INTZ texture in both areas */
3799 hr = IDirect3DDevice8_CreateTexture(device, 640, 480, 1,
3800 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture);
3801 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
3802 hr = IDirect3DTexture8_GetSurfaceLevel(texture, 0, &ds);
3803 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
3804 hr = IDirect3DDevice8_SetRenderTarget(device, rt, ds);
3805 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
3806 hr = IDirect3DDevice8_SetPixelShader(device, 0);
3807 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
3809 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
3810 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
3812 hr = IDirect3DDevice8_BeginScene(device);
3813 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
3814 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, half_quad_1, sizeof(*half_quad_1));
3815 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3816 hr = IDirect3DDevice8_EndScene(device);
3817 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
3819 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, ds);
3820 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
3822 hr = IDirect3DDevice8_BeginScene(device);
3823 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
3824 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, half_quad_2, sizeof(*half_quad_2));
3825 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3826 hr = IDirect3DDevice8_EndScene(device);
3827 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
3829 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, NULL);
3830 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
3831 IDirect3DSurface8_Release(ds);
3832 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
3833 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
3834 hr = IDirect3DDevice8_SetTexture(device, 1, (IDirect3DBaseTexture8 *)texture);
3835 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
3836 hr = IDirect3DDevice8_SetPixelShader(device, ps);
3837 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
3839 /* Read the depth values back. */
3840 hr = IDirect3DDevice8_BeginScene(device);
3841 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
3842 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
3843 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
3844 hr = IDirect3DDevice8_EndScene(device);
3845 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
3847 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
3849 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
3850 ok(color_match(color, expected_colors[i].color, 1),
3851 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
3852 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
3855 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
3856 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
3858 IDirect3DTexture8_Release(texture);
3859 hr = IDirect3DDevice8_DeletePixelShader(device, ps);
3860 ok(SUCCEEDED(hr), "DeletePixelShader failed, hr %#x.\n", hr);
3861 IDirect3DSurface8_Release(original_rt);
3862 IDirect3DSurface8_Release(rt);
3863 refcount = IDirect3DDevice8_Release(device);
3864 ok(!refcount, "Device has %u references left.\n", refcount);
3865 done:
3866 IDirect3D8_Release(d3d);
3867 DestroyWindow(window);
3870 static void shadow_test(void)
3872 IDirect3DSurface8 *original_rt, *rt;
3873 IDirect3DDevice8 *device;
3874 IDirect3D8 *d3d;
3875 ULONG refcount;
3876 D3DCAPS8 caps;
3877 HWND window;
3878 HRESULT hr;
3879 DWORD ps;
3880 UINT i;
3882 static const DWORD ps_code[] =
3884 0xffff0101, /* ps_1_1 */
3885 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1.0, 0.0, 0.0, 0.0 */
3886 0x00000051, 0xa00f0001, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c1, 0.0, 1.0, 0.0, 0.0 */
3887 0x00000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c2, 0.0, 0.0, 1.0, 0.0 */
3888 0x00000042, 0xb00f0000, /* tex t0 */
3889 0x00000042, 0xb00f0001, /* tex t1 */
3890 0x00000008, 0xb0070001, 0xa0e40000, 0xb0e40001, /* dp3 t1.xyz, c0, t1 */
3891 0x00000005, 0x80070000, 0xa0e40001, 0xb0e40001, /* mul r0.xyz, c1, t1 */
3892 0x00000004, 0x80070000, 0xa0e40000, 0xb0e40000, 0x80e40000, /* mad r0.xyz, c0, t0, r0 */
3893 0x40000001, 0x80080000, 0xa0aa0002, /* +mov r0.w, c2.z */
3894 0x0000ffff, /* end */
3896 static const struct
3898 D3DFORMAT format;
3899 const char *name;
3901 formats[] =
3903 {D3DFMT_D16_LOCKABLE, "D3DFMT_D16_LOCKABLE"},
3904 {D3DFMT_D32, "D3DFMT_D32"},
3905 {D3DFMT_D15S1, "D3DFMT_D15S1"},
3906 {D3DFMT_D24S8, "D3DFMT_D24S8"},
3907 {D3DFMT_D24X8, "D3DFMT_D24X8"},
3908 {D3DFMT_D24X4S4, "D3DFMT_D24X4S4"},
3909 {D3DFMT_D16, "D3DFMT_D16"},
3911 static const struct
3913 float x, y, z;
3914 float s0, t0, p0;
3915 float s1, t1, p1, q1;
3917 quad[] =
3919 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f},
3920 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f},
3921 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
3922 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f},
3924 static const struct
3926 UINT x, y;
3927 D3DCOLOR color;
3929 expected_colors[] =
3931 {400, 60, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
3932 {560, 180, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
3933 {560, 300, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
3934 {400, 420, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
3935 {240, 420, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
3936 { 80, 300, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
3937 { 80, 180, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
3938 {240, 60, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00)},
3941 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
3942 0, 0, 640, 480, NULL, NULL, NULL, NULL);
3943 d3d = Direct3DCreate8(D3D_SDK_VERSION);
3944 ok(!!d3d, "Failed to create a D3D object.\n");
3945 if (!(device = create_device(d3d, window, window, TRUE)))
3947 skip("Failed to create a D3D device, skipping tests.\n");
3948 goto done;
3951 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
3952 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
3953 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 1))
3955 skip("No pixel shader 1.1 support, skipping shadow test.\n");
3956 IDirect3DDevice8_Release(device);
3957 goto done;
3960 hr = IDirect3DDevice8_GetRenderTarget(device, &original_rt);
3961 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
3963 hr = IDirect3DDevice8_CreateRenderTarget(device, 1024, 1024, D3DFMT_A8R8G8B8,
3964 D3DMULTISAMPLE_NONE, FALSE, &rt);
3965 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
3966 hr = IDirect3DDevice8_CreatePixelShader(device, ps_code, &ps);
3967 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
3969 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX2
3970 | D3DFVF_TEXCOORDSIZE3(0) | D3DFVF_TEXCOORDSIZE4(1));
3971 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
3972 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
3973 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3974 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
3975 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3976 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
3977 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3978 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3979 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
3981 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MINFILTER, D3DTEXF_POINT);
3982 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3983 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MIPFILTER, D3DTEXF_POINT);
3984 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3985 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MAGFILTER, D3DTEXF_POINT);
3986 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3987 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
3988 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3990 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP);
3991 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3992 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP);
3993 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3994 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MAGFILTER, D3DTEXF_POINT);
3995 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3996 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MINFILTER, D3DTEXF_POINT);
3997 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
3998 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MIPFILTER, D3DTEXF_POINT);
3999 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
4000 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS,
4001 D3DTTFF_COUNT4 | D3DTTFF_PROJECTED);
4002 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
4004 for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
4006 D3DFORMAT format = formats[i].format;
4007 IDirect3DTexture8 *texture;
4008 IDirect3DSurface8 *ds;
4009 unsigned int j;
4011 if (FAILED(IDirect3D8_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
4012 D3DFMT_X8R8G8B8, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, format)))
4013 continue;
4015 hr = IDirect3DDevice8_CreateTexture(device, 1024, 1024, 1,
4016 D3DUSAGE_DEPTHSTENCIL, format, D3DPOOL_DEFAULT, &texture);
4017 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
4019 hr = IDirect3DTexture8_GetSurfaceLevel(texture, 0, &ds);
4020 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
4022 hr = IDirect3DDevice8_SetRenderTarget(device, rt, ds);
4023 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
4025 hr = IDirect3DDevice8_SetPixelShader(device, 0);
4026 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
4028 /* Setup the depth/stencil surface. */
4029 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
4030 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
4032 hr = IDirect3DDevice8_BeginScene(device);
4033 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
4034 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
4035 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
4036 hr = IDirect3DDevice8_EndScene(device);
4037 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
4039 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, NULL);
4040 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
4041 IDirect3DSurface8_Release(ds);
4043 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
4044 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
4045 hr = IDirect3DDevice8_SetTexture(device, 1, (IDirect3DBaseTexture8 *)texture);
4046 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
4048 hr = IDirect3DDevice8_SetPixelShader(device, ps);
4049 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
4051 /* Do the actual shadow mapping. */
4052 hr = IDirect3DDevice8_BeginScene(device);
4053 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
4054 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
4055 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
4056 hr = IDirect3DDevice8_EndScene(device);
4057 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
4059 hr = IDirect3DDevice8_SetTexture(device, 0, NULL);
4060 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
4061 hr = IDirect3DDevice8_SetTexture(device, 1, NULL);
4062 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
4063 IDirect3DTexture8_Release(texture);
4065 for (j = 0; j < sizeof(expected_colors) / sizeof(*expected_colors); ++j)
4067 D3DCOLOR color = getPixelColor(device, expected_colors[j].x, expected_colors[j].y);
4068 ok(color_match(color, expected_colors[j].color, 0),
4069 "Expected color 0x%08x at (%u, %u) for format %s, got 0x%08x.\n",
4070 expected_colors[j].color, expected_colors[j].x, expected_colors[j].y,
4071 formats[i].name, color);
4074 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
4075 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
4078 hr = IDirect3DDevice8_DeletePixelShader(device, ps);
4079 ok(SUCCEEDED(hr), "DeletePixelShader failed, hr %#x.\n", hr);
4080 IDirect3DSurface8_Release(original_rt);
4081 IDirect3DSurface8_Release(rt);
4082 refcount = IDirect3DDevice8_Release(device);
4083 ok(!refcount, "Device has %u references left.\n", refcount);
4084 done:
4085 IDirect3D8_Release(d3d);
4086 DestroyWindow(window);
4089 static void multisample_copy_rects_test(void)
4091 IDirect3DSurface8 *ds, *ds_plain, *rt, *readback;
4092 RECT src_rect = {64, 64, 128, 128};
4093 POINT dst_point = {96, 96};
4094 D3DLOCKED_RECT locked_rect;
4095 IDirect3DDevice8 *device;
4096 IDirect3D8 *d3d;
4097 D3DCOLOR color;
4098 ULONG refcount;
4099 HWND window;
4100 HRESULT hr;
4102 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
4103 0, 0, 640, 480, NULL, NULL, NULL, NULL);
4104 d3d = Direct3DCreate8(D3D_SDK_VERSION);
4105 ok(!!d3d, "Failed to create a D3D object.\n");
4106 if (!(device = create_device(d3d, window, window, TRUE)))
4108 skip("Failed to create a D3D device, skipping tests.\n");
4109 goto done;
4112 if (FAILED(IDirect3D8_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT,
4113 D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES)))
4115 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping multisampled CopyRects test.\n");
4116 IDirect3DDevice8_Release(device);
4117 goto done;
4120 hr = IDirect3DDevice8_CreateRenderTarget(device, 256, 256, D3DFMT_A8R8G8B8,
4121 D3DMULTISAMPLE_2_SAMPLES, FALSE, &rt);
4122 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
4123 hr = IDirect3DDevice8_CreateDepthStencilSurface(device, 256, 256, D3DFMT_D24S8,
4124 D3DMULTISAMPLE_2_SAMPLES, &ds);
4125 ok(SUCCEEDED(hr), "Failed to create depth stencil surface, hr %#x.\n", hr);
4126 hr = IDirect3DDevice8_CreateDepthStencilSurface(device, 256, 256, D3DFMT_D24S8,
4127 D3DMULTISAMPLE_NONE, &ds_plain);
4128 ok(SUCCEEDED(hr), "Failed to create depth stencil surface, hr %#x.\n", hr);
4129 hr = IDirect3DDevice8_CreateImageSurface(device, 256, 256, D3DFMT_A8R8G8B8, &readback);
4130 ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
4132 hr = IDirect3DDevice8_SetRenderTarget(device, rt, ds);
4133 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
4135 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
4136 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
4138 hr = IDirect3DDevice8_CopyRects(device, rt, NULL, 0, readback, NULL);
4139 ok(SUCCEEDED(hr), "Failed to read render target back, hr %#x.\n", hr);
4141 hr = IDirect3DDevice8_CopyRects(device, ds, NULL, 0, ds_plain, NULL);
4142 ok(hr == D3DERR_INVALIDCALL, "Depth buffer copy, hr %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
4144 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
4145 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
4147 hr = IDirect3DDevice8_CopyRects(device, rt, &src_rect, 1, readback, &dst_point);
4148 ok(SUCCEEDED(hr), "Failed to read render target back, hr %#x.\n", hr);
4150 hr = IDirect3DSurface8_LockRect(readback, &locked_rect, NULL, D3DLOCK_READONLY);
4151 ok(SUCCEEDED(hr), "Failed to lock readback surface, hr %#x.\n", hr);
4153 color = *(DWORD *)((BYTE *)locked_rect.pBits + 31 * locked_rect.Pitch + 31 * 4);
4154 ok(color == 0xff00ff00, "Got unexpected color 0x%08x.\n", color);
4156 color = *(DWORD *)((BYTE *)locked_rect.pBits + 127 * locked_rect.Pitch + 127 * 4);
4157 ok(color == 0xffff0000, "Got unexpected color 0x%08x.\n", color);
4159 hr = IDirect3DSurface8_UnlockRect(readback);
4160 ok(SUCCEEDED(hr), "Failed to unlock readback surface, hr %#x.\n", hr);
4162 IDirect3DSurface8_Release(readback);
4163 IDirect3DSurface8_Release(ds_plain);
4164 IDirect3DSurface8_Release(ds);
4165 IDirect3DSurface8_Release(rt);
4166 refcount = IDirect3DDevice8_Release(device);
4167 ok(!refcount, "Device has %u references left.\n", refcount);
4168 done:
4169 IDirect3D8_Release(d3d);
4170 DestroyWindow(window);
4173 static void resz_test(void)
4175 IDirect3DSurface8 *rt, *original_rt, *ds, *original_ds, *intz_ds;
4176 IDirect3DTexture8 *texture;
4177 IDirect3DDevice8 *device;
4178 IDirect3D8 *d3d;
4179 DWORD ps, value;
4180 unsigned int i;
4181 ULONG refcount;
4182 D3DCAPS8 caps;
4183 HWND window;
4184 HRESULT hr;
4186 static const DWORD ps_code[] =
4188 0xffff0101, /* ps_1_1 */
4189 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1.0, 0.0, 0.0, 0.0 */
4190 0x00000051, 0xa00f0001, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c1, 0.0, 1.0, 0.0, 0.0 */
4191 0x00000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c2, 0.0, 0.0, 1.0, 0.0 */
4192 0x00000042, 0xb00f0000, /* tex t0 */
4193 0x00000042, 0xb00f0001, /* tex t1 */
4194 0x00000008, 0xb0070001, 0xa0e40000, 0xb0e40001, /* dp3 t1.xyz, c0, t1 */
4195 0x00000005, 0x80070000, 0xa0e40001, 0xb0e40001, /* mul r0.xyz, c1, t1 */
4196 0x00000004, 0x80070000, 0xa0e40000, 0xb0e40000, 0x80e40000, /* mad r0.xyz, c0, t0, r0 */
4197 0x40000001, 0x80080000, 0xa0aa0002, /* +mov r0.w, c2.z */
4198 0x0000ffff, /* end */
4200 static const struct
4202 float x, y, z;
4203 float s0, t0, p0;
4204 float s1, t1, p1, q1;
4206 quad[] =
4208 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.5f},
4209 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
4210 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
4211 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.5f},
4213 static const struct
4215 UINT x, y;
4216 D3DCOLOR color;
4218 expected_colors[] =
4220 { 80, 100, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
4221 {240, 100, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
4222 {400, 100, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
4223 {560, 100, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
4224 { 80, 450, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
4225 {240, 450, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
4226 {400, 450, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
4227 {560, 450, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
4230 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
4231 0, 0, 640, 480, NULL, NULL, NULL, NULL);
4232 d3d = Direct3DCreate8(D3D_SDK_VERSION);
4233 ok(!!d3d, "Failed to create a D3D object.\n");
4234 if (!(device = create_device(d3d, window, window, TRUE)))
4236 skip("Failed to create a D3D device, skipping tests.\n");
4237 goto done;
4240 if (FAILED(IDirect3D8_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT,
4241 D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES)))
4243 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping RESZ test.\n");
4244 IDirect3DDevice8_Release(device);
4245 goto done;
4247 if (FAILED(IDirect3D8_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT,
4248 D3DDEVTYPE_HAL, D3DFMT_D24S8, TRUE, D3DMULTISAMPLE_2_SAMPLES)))
4250 skip("Multisampling not supported for D3DFMT_D24S8, skipping RESZ test.\n");
4251 IDirect3DDevice8_Release(device);
4252 goto done;
4254 if (FAILED(IDirect3D8_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
4255 D3DFMT_X8R8G8B8, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, MAKEFOURCC('I','N','T','Z'))))
4257 skip("No INTZ support, skipping RESZ test.\n");
4258 IDirect3DDevice8_Release(device);
4259 goto done;
4261 if (FAILED(IDirect3D8_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
4262 D3DFMT_X8R8G8B8, D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE, MAKEFOURCC('R','E','S','Z'))))
4264 skip("No RESZ support, skipping RESZ test.\n");
4265 IDirect3DDevice8_Release(device);
4266 goto done;
4269 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
4270 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
4271 if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
4273 skip("No unconditional NP2 texture support, skipping INTZ test.\n");
4274 IDirect3DDevice8_Release(device);
4275 goto done;
4278 hr = IDirect3DDevice8_GetRenderTarget(device, &original_rt);
4279 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
4280 hr = IDirect3DDevice8_GetDepthStencilSurface(device, &original_ds);
4281 ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#x.\n", hr);
4283 hr = IDirect3DDevice8_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
4284 D3DMULTISAMPLE_2_SAMPLES, FALSE, &rt);
4285 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
4286 hr = IDirect3DDevice8_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
4287 D3DMULTISAMPLE_2_SAMPLES, &ds);
4289 hr = IDirect3DDevice8_CreateTexture(device, 640, 480, 1,
4290 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture);
4291 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
4292 hr = IDirect3DTexture8_GetSurfaceLevel(texture, 0, &intz_ds);
4293 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
4295 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, intz_ds);
4296 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
4297 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
4298 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
4300 hr = IDirect3DDevice8_SetRenderTarget(device, rt, ds);
4301 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
4302 IDirect3DSurface8_Release(intz_ds);
4303 hr = IDirect3DDevice8_CreatePixelShader(device, ps_code, &ps);
4304 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
4306 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX2
4307 | D3DFVF_TEXCOORDSIZE3(0) | D3DFVF_TEXCOORDSIZE4(1));
4308 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
4309 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
4310 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
4311 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
4312 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
4313 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
4314 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
4315 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
4316 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
4318 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MINFILTER, D3DTEXF_POINT);
4319 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
4320 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MIPFILTER, D3DTEXF_POINT);
4321 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
4322 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MAGFILTER, D3DTEXF_POINT);
4323 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
4324 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
4325 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
4327 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP);
4328 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
4329 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP);
4330 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
4331 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MAGFILTER, D3DTEXF_POINT);
4332 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
4333 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MINFILTER, D3DTEXF_POINT);
4334 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
4335 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_MIPFILTER, D3DTEXF_POINT);
4336 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
4337 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS,
4338 D3DTTFF_COUNT4 | D3DTTFF_PROJECTED);
4339 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
4341 /* Render offscreen (multisampled), blit the depth buffer into the INTZ texture and then check its contents. */
4342 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
4343 ok(SUCCEEDED(hr), "Failed to clear 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);
4350 /* The destination depth texture has to be bound to sampler 0 */
4351 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
4352 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
4354 /* the ATI "spec" says you have to do a dummy draw to ensure correct commands ordering */
4355 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, FALSE);
4356 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
4357 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
4358 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
4359 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0);
4360 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
4361 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
4362 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
4363 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, TRUE);
4364 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
4365 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
4366 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
4367 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0xf);
4368 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
4370 /* The actual multisampled depth buffer resolve happens here */
4371 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
4372 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
4373 hr = IDirect3DDevice8_GetRenderState(device, D3DRS_POINTSIZE, &value);
4374 ok(SUCCEEDED(hr) && value == 0x7fa05000, "GetRenderState failed, hr %#x, value %#x.\n", hr, value);
4376 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, NULL);
4377 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
4378 hr = IDirect3DDevice8_SetTexture(device, 1, (IDirect3DBaseTexture8 *)texture);
4379 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
4380 hr = IDirect3DDevice8_SetPixelShader(device, ps);
4381 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
4383 /* Read the depth values back. */
4384 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
4385 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
4386 hr = IDirect3DDevice8_EndScene(device);
4387 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
4389 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
4391 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
4392 ok(color_match(color, expected_colors[i].color, 1),
4393 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
4394 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
4397 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
4398 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
4400 /* Test edge cases - try with no texture at all */
4401 hr = IDirect3DDevice8_SetTexture(device, 0, NULL);
4402 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
4403 hr = IDirect3DDevice8_SetTexture(device, 1, NULL);
4404 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
4405 hr = IDirect3DDevice8_SetRenderTarget(device, rt, ds);
4406 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
4408 hr = IDirect3DDevice8_BeginScene(device);
4409 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
4410 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
4411 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
4412 hr = IDirect3DDevice8_EndScene(device);
4413 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
4415 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
4416 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
4418 /* With a non-multisampled depth buffer */
4419 IDirect3DSurface8_Release(ds);
4420 IDirect3DSurface8_Release(rt);
4421 hr = IDirect3DDevice8_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
4422 D3DMULTISAMPLE_NONE, &ds);
4424 hr = IDirect3DDevice8_SetRenderTarget(device, original_rt, ds);
4425 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
4426 hr = IDirect3DDevice8_SetPixelShader(device, 0);
4427 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
4429 hr = IDirect3DDevice8_BeginScene(device);
4430 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
4431 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
4432 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
4433 hr = IDirect3DDevice8_EndScene(device);
4434 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
4436 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
4437 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
4439 hr = IDirect3DDevice8_BeginScene(device);
4440 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
4441 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, FALSE);
4442 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
4443 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
4444 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
4445 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0);
4446 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
4447 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
4448 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
4449 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, TRUE);
4450 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
4451 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
4452 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
4453 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0xf);
4454 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
4455 hr = IDirect3DDevice8_EndScene(device);
4456 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
4458 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
4459 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
4461 hr = IDirect3DDevice8_SetTexture(device, 1, (IDirect3DBaseTexture8 *)texture);
4462 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
4463 hr = IDirect3DDevice8_SetPixelShader(device, ps);
4464 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
4466 /* Read the depth values back. */
4467 hr = IDirect3DDevice8_BeginScene(device);
4468 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
4469 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
4470 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
4471 hr = IDirect3DDevice8_EndScene(device);
4472 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
4474 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
4476 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
4477 ok(color_match(color, expected_colors[i].color, 1),
4478 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
4479 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
4482 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
4483 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
4485 IDirect3DSurface8_Release(ds);
4486 IDirect3DTexture8_Release(texture);
4487 hr = IDirect3DDevice8_DeletePixelShader(device, ps);
4488 ok(SUCCEEDED(hr), "DeletePixelShader failed, hr %#x.\n", hr);
4489 IDirect3DSurface8_Release(original_ds);
4490 IDirect3DSurface8_Release(original_rt);
4492 refcount = IDirect3DDevice8_Release(device);
4493 ok(!refcount, "Device has %u references left.\n", refcount);
4494 done:
4495 IDirect3D8_Release(d3d);
4496 DestroyWindow(window);
4499 static void zenable_test(void)
4501 IDirect3DDevice8 *device;
4502 IDirect3D8 *d3d;
4503 D3DCOLOR color;
4504 ULONG refcount;
4505 D3DCAPS8 caps;
4506 HWND window;
4507 HRESULT hr;
4508 UINT x, y;
4509 UINT i, j;
4510 UINT test;
4511 IDirect3DSurface8 *ds, *rt;
4513 static const struct
4515 struct vec4 position;
4516 D3DCOLOR diffuse;
4518 tquad[] =
4520 {{ 0.0f, 480.0f, -0.5f, 1.0f}, 0xff00ff00},
4521 {{ 0.0f, 0.0f, -0.5f, 1.0f}, 0xff00ff00},
4522 {{640.0f, 480.0f, 1.5f, 1.0f}, 0xff00ff00},
4523 {{640.0f, 0.0f, 1.5f, 1.0f}, 0xff00ff00},
4526 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
4527 0, 0, 640, 480, NULL, NULL, NULL, NULL);
4528 d3d = Direct3DCreate8(D3D_SDK_VERSION);
4529 ok(!!d3d, "Failed to create a D3D object.\n");
4530 if (!(device = create_device(d3d, window, window, TRUE)))
4532 skip("Failed to create a D3D device, skipping tests.\n");
4533 goto done;
4536 hr = IDirect3DDevice8_GetDepthStencilSurface(device, &ds);
4537 ok(SUCCEEDED(hr), "Failed to get depth stencil surface, hr %#x.\n", hr);
4538 hr = IDirect3DDevice8_GetRenderTarget(device, &rt);
4539 ok(SUCCEEDED(hr), "Failed to get render target surface, hr %#x.\n", hr);
4541 for (test = 0; test < 2; ++test)
4543 /* The Windows 8 testbot (WARP) appears to clip with
4544 * ZENABLE = D3DZB_TRUE and no depth buffer set. */
4545 static const D3DCOLOR expected_broken[] =
4547 0x00ff0000, 0x0000ff00, 0x0000ff00, 0x00ff0000,
4548 0x00ff0000, 0x0000ff00, 0x0000ff00, 0x00ff0000,
4549 0x00ff0000, 0x0000ff00, 0x0000ff00, 0x00ff0000,
4550 0x00ff0000, 0x0000ff00, 0x0000ff00, 0x00ff0000,
4553 if (!test)
4555 hr = IDirect3DDevice8_SetRenderTarget(device, rt, NULL);
4556 ok(SUCCEEDED(hr), "Failed to set depth stencil surface, hr %#x.\n", hr);
4558 else
4560 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
4561 ok(SUCCEEDED(hr), "Failed to disable z-buffering, hr %#x.\n", hr);
4562 hr = IDirect3DDevice8_SetRenderTarget(device, rt, ds);
4563 ok(SUCCEEDED(hr), "Failed to set depth stencil surface, hr %#x.\n", hr);
4564 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 0.0f, 0);
4565 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
4567 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
4568 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
4570 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0f, 0);
4571 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
4572 hr = IDirect3DDevice8_BeginScene(device);
4573 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
4574 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, tquad, sizeof(*tquad));
4575 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4576 hr = IDirect3DDevice8_EndScene(device);
4577 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
4579 for (i = 0; i < 4; ++i)
4581 for (j = 0; j < 4; ++j)
4583 x = 80 * ((2 * j) + 1);
4584 y = 60 * ((2 * i) + 1);
4585 color = getPixelColor(device, x, y);
4586 ok(color_match(color, 0x0000ff00, 1)
4587 || broken(color_match(color, expected_broken[i * 4 + j], 1) && !test),
4588 "Expected color 0x0000ff00 at %u, %u, got 0x%08x.\n", x, y, color);
4592 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
4593 ok(SUCCEEDED(hr), "Failed to present backbuffer, hr %#x.\n", hr);
4596 IDirect3DSurface8_Release(ds);
4597 IDirect3DSurface8_Release(rt);
4599 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
4600 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
4602 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1)
4603 && caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
4605 static const DWORD vs_code[] =
4607 0xfffe0101, /* vs_1_1 */
4608 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4609 0x00000001, 0xd00f0000, 0x90e40000, /* mov oD0, v0 */
4610 0x0000ffff
4612 static const DWORD ps_code[] =
4614 0xffff0101, /* ps_1_1 */
4615 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
4616 0x0000ffff /* end */
4618 static const struct vec3 quad[] =
4620 {-1.0f, -1.0f, -0.5f},
4621 {-1.0f, 1.0f, -0.5f},
4622 { 1.0f, -1.0f, 1.5f},
4623 { 1.0f, 1.0f, 1.5f},
4625 static const D3DCOLOR expected[] =
4627 0x00ff0000, 0x0060df60, 0x009fdf9f, 0x00ff0000,
4628 0x00ff0000, 0x00609f60, 0x009f9f9f, 0x00ff0000,
4629 0x00ff0000, 0x00606060, 0x009f609f, 0x00ff0000,
4630 0x00ff0000, 0x00602060, 0x009f209f, 0x00ff0000,
4632 /* The Windows 8 testbot (WARP) appears to not clip z for regular
4633 * vertices either. */
4634 static const D3DCOLOR expected_broken[] =
4636 0x0020df20, 0x0060df60, 0x009fdf9f, 0x00dfdfdf,
4637 0x00209f20, 0x00609f60, 0x009f9f9f, 0x00df9fdf,
4638 0x00206020, 0x00606060, 0x009f609f, 0x00df60df,
4639 0x00202020, 0x00602060, 0x009f209f, 0x00df20df,
4641 static const DWORD decl[] =
4643 D3DVSD_STREAM(0),
4644 D3DVSD_REG(D3DVSDE_POSITION, D3DVSDT_FLOAT3),
4645 D3DVSD_END()
4647 DWORD vs, ps;
4649 hr = IDirect3DDevice8_CreateVertexShader(device, decl, vs_code, &vs, 0);
4650 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
4651 hr = IDirect3DDevice8_CreatePixelShader(device, ps_code, &ps);
4652 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
4653 hr = IDirect3DDevice8_SetVertexShader(device, vs);
4654 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
4655 hr = IDirect3DDevice8_SetPixelShader(device, ps);
4656 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
4658 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0f, 0);
4659 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
4660 hr = IDirect3DDevice8_BeginScene(device);
4661 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
4662 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
4663 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4664 hr = IDirect3DDevice8_EndScene(device);
4665 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
4667 for (i = 0; i < 4; ++i)
4669 for (j = 0; j < 4; ++j)
4671 x = 80 * ((2 * j) + 1);
4672 y = 60 * ((2 * i) + 1);
4673 color = getPixelColor(device, x, y);
4674 ok(color_match(color, expected[i * 4 + j], 1)
4675 || broken(color_match(color, expected_broken[i * 4 + j], 1)),
4676 "Expected color 0x%08x at %u, %u, got 0x%08x.\n", expected[i * 4 + j], x, y, color);
4680 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
4681 ok(SUCCEEDED(hr), "Failed to present backbuffer, hr %#x.\n", hr);
4683 hr = IDirect3DDevice8_DeletePixelShader(device, ps);
4684 ok(SUCCEEDED(hr), "Failed to delete pixel shader, hr %#x.\n", hr);
4685 hr = IDirect3DDevice8_DeleteVertexShader(device, vs);
4686 ok(SUCCEEDED(hr), "Failed to delete vertex shader, hr %#x.\n", hr);
4689 refcount = IDirect3DDevice8_Release(device);
4690 ok(!refcount, "Device has %u references left.\n", refcount);
4691 done:
4692 IDirect3D8_Release(d3d);
4693 DestroyWindow(window);
4696 static void fog_special_test(void)
4698 IDirect3DDevice8 *device;
4699 IDirect3D8 *d3d;
4700 unsigned int i;
4701 D3DCOLOR color;
4702 ULONG refcount;
4703 D3DCAPS8 caps;
4704 DWORD ps, vs;
4705 HWND window;
4706 HRESULT hr;
4707 union
4709 float f;
4710 DWORD d;
4711 } conv;
4713 static const struct
4715 struct vec3 position;
4716 D3DCOLOR diffuse;
4718 quad[] =
4720 {{ -1.0f, -1.0f, 0.0f}, 0xff00ff00},
4721 {{ -1.0f, 1.0f, 0.0f}, 0xff00ff00},
4722 {{ 1.0f, -1.0f, 1.0f}, 0xff00ff00},
4723 {{ 1.0f, 1.0f, 1.0f}, 0xff00ff00}
4725 static const struct
4727 DWORD vertexmode, tablemode;
4728 BOOL vs, ps;
4729 D3DCOLOR color_left, color_right;
4731 tests[] =
4733 {D3DFOG_LINEAR, D3DFOG_NONE, FALSE, FALSE, 0x00ff0000, 0x00ff0000},
4734 {D3DFOG_LINEAR, D3DFOG_NONE, FALSE, TRUE, 0x00ff0000, 0x00ff0000},
4735 {D3DFOG_LINEAR, D3DFOG_NONE, TRUE, FALSE, 0x00ff0000, 0x00ff0000},
4736 {D3DFOG_LINEAR, D3DFOG_NONE, TRUE, TRUE, 0x00ff0000, 0x00ff0000},
4738 {D3DFOG_NONE, D3DFOG_LINEAR, FALSE, FALSE, 0x0000ff00, 0x00ff0000},
4739 {D3DFOG_NONE, D3DFOG_LINEAR, FALSE, TRUE, 0x0000ff00, 0x00ff0000},
4740 {D3DFOG_NONE, D3DFOG_LINEAR, TRUE, FALSE, 0x0000ff00, 0x00ff0000},
4741 {D3DFOG_NONE, D3DFOG_LINEAR, TRUE, TRUE, 0x0000ff00, 0x00ff0000},
4743 static const DWORD pixel_shader_code[] =
4745 0xffff0101, /* ps.1.1 */
4746 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
4747 0x0000ffff
4749 static const DWORD vertex_decl[] =
4751 D3DVSD_STREAM(0),
4752 D3DVSD_REG(0, D3DVSDT_FLOAT3), /* position, v0 */
4753 D3DVSD_REG(1, D3DVSDT_D3DCOLOR), /* diffuse color, v1 */
4754 D3DVSD_END()
4756 static const DWORD vertex_shader_code[] =
4758 0xfffe0101, /* vs.1.1 */
4759 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4760 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
4761 0x0000ffff
4763 static const D3DMATRIX identity =
4765 1.0f, 0.0f, 0.0f, 0.0f,
4766 0.0f, 1.0f, 0.0f, 0.0f,
4767 0.0f, 0.0f, 1.0f, 0.0f,
4768 0.0f, 0.0f, 0.0f, 1.0f,
4769 }}};
4771 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
4772 0, 0, 640, 480, NULL, NULL, NULL, NULL);
4773 d3d = Direct3DCreate8(D3D_SDK_VERSION);
4774 ok(!!d3d, "Failed to create a D3D object.\n");
4775 if (!(device = create_device(d3d, window, window, TRUE)))
4777 skip("Failed to create a D3D device, skipping tests.\n");
4778 goto done;
4781 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
4782 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
4783 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
4785 hr = IDirect3DDevice8_CreateVertexShader(device, vertex_decl, vertex_shader_code, &vs, 0);
4786 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
4788 else
4790 skip("Vertex Shaders not supported, skipping some fog tests.\n");
4791 vs = 0;
4793 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
4795 hr = IDirect3DDevice8_CreatePixelShader(device, pixel_shader_code, &ps);
4796 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
4798 else
4800 skip("Pixel Shaders not supported, skipping some fog tests.\n");
4801 ps = 0;
4804 /* The table fog tests seem to depend on the projection matrix explicitly
4805 * being set to an identity matrix, even though that's the default.
4806 * (AMD Radeon HD 6310, Windows 7) */
4807 hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, &identity);
4808 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
4810 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
4811 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
4812 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
4813 ok(SUCCEEDED(hr), "Failed to enable fog, hr %#x.\n", hr);
4814 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGCOLOR, 0xffff0000);
4815 ok(SUCCEEDED(hr), "Failed to set fog color, hr %#x.\n", hr);
4817 conv.f = 0.5f;
4818 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGSTART, conv.d);
4819 ok(SUCCEEDED(hr), "Failed to set fog start, hr %#x.\n", hr);
4820 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGEND, conv.d);
4821 ok(SUCCEEDED(hr), "Failed to set fog end, hr %#x.\n", hr);
4823 for (i = 0; i < sizeof(tests) / sizeof(*tests); i++)
4825 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
4826 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
4828 if (!tests[i].vs)
4830 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
4831 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr);
4833 else if (vs)
4835 hr = IDirect3DDevice8_SetVertexShader(device, vs);
4836 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
4838 else
4840 continue;
4843 if (!tests[i].ps)
4845 hr = IDirect3DDevice8_SetPixelShader(device, 0);
4846 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
4848 else if (ps)
4850 hr = IDirect3DDevice8_SetPixelShader(device, ps);
4851 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
4853 else
4855 continue;
4858 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGVERTEXMODE, tests[i].vertexmode);
4859 ok(SUCCEEDED(hr), "Failed to set fogvertexmode, hr %#x.\n", hr);
4860 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGTABLEMODE, tests[i].tablemode);
4861 ok(SUCCEEDED(hr), "Failed to set fogtablemode, hr %#x.\n", hr);
4863 hr = IDirect3DDevice8_BeginScene(device);
4864 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
4865 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
4866 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4867 hr = IDirect3DDevice8_EndScene(device);
4868 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
4870 color = getPixelColor(device, 310, 240);
4871 ok(color_match(color, tests[i].color_left, 1),
4872 "Expected left color 0x%08x, got 0x%08x, case %u.\n", tests[i].color_left, color, i);
4873 color = getPixelColor(device, 330, 240);
4874 ok(color_match(color, tests[i].color_right, 1),
4875 "Expected right color 0x%08x, got 0x%08x, case %u.\n", tests[i].color_right, color, i);
4877 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
4878 ok(SUCCEEDED(hr), "Failed to present backbuffer, hr %#x.\n", hr);
4881 if (vs)
4882 IDirect3DDevice8_DeleteVertexShader(device, vs);
4883 if (ps)
4884 IDirect3DDevice8_DeletePixelShader(device, ps);
4885 refcount = IDirect3DDevice8_Release(device);
4886 ok(!refcount, "Device has %u references left.\n", refcount);
4887 done:
4888 IDirect3D8_Release(d3d);
4889 DestroyWindow(window);
4892 static void volume_dxt5_test(void)
4894 IDirect3DVolumeTexture8 *texture;
4895 IDirect3DDevice8 *device;
4896 D3DLOCKED_BOX box;
4897 IDirect3D8 *d3d;
4898 unsigned int i;
4899 D3DCOLOR color;
4900 ULONG refcount;
4901 HWND window;
4902 HRESULT hr;
4904 static const char texture_data[] =
4906 /* A 8x4x2 texture consisting of 4 4x4 blocks. The colors of the blocks are red, green, blue and white. */
4907 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00,
4908 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00,
4909 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00,
4910 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00
4912 static const struct
4914 struct vec3 position;
4915 struct vec3 texcrd;
4917 quads[] =
4919 {{ -1.0f, -1.0f, 0.0f}, { 0.0f, 0.0f, 0.25f}},
4920 {{ -1.0f, 1.0f, 0.0f}, { 0.0f, 1.0f, 0.25f}},
4921 {{ 0.0f, -1.0f, 1.0f}, { 1.0f, 0.0f, 0.25f}},
4922 {{ 0.0f, 1.0f, 1.0f}, { 1.0f, 1.0f, 0.25f}},
4924 {{ 0.0f, -1.0f, 0.0f}, { 0.0f, 0.0f, 0.75f}},
4925 {{ 0.0f, 1.0f, 0.0f}, { 0.0f, 1.0f, 0.75f}},
4926 {{ 1.0f, -1.0f, 1.0f}, { 1.0f, 0.0f, 0.75f}},
4927 {{ 1.0f, 1.0f, 1.0f}, { 1.0f, 1.0f, 0.75f}},
4929 static const DWORD expected_colors[] = {0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff};
4931 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
4932 0, 0, 640, 480, NULL, NULL, NULL, NULL);
4933 d3d = Direct3DCreate8(D3D_SDK_VERSION);
4934 ok(!!d3d, "Failed to create a D3D object.\n");
4935 if (!(device = create_device(d3d, window, window, TRUE)))
4937 skip("Failed to create a D3D device, skipping tests.\n");
4938 goto done;
4941 if (FAILED(IDirect3D8_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
4942 D3DFMT_X8R8G8B8, 0, D3DRTYPE_VOLUMETEXTURE, D3DFMT_DXT5)))
4944 skip("Volume DXT5 textures are not supported, skipping test.\n");
4945 IDirect3DDevice8_Release(device);
4946 goto done;
4949 hr = IDirect3DDevice8_CreateVolumeTexture(device, 8, 4, 2, 1, 0, D3DFMT_DXT5,
4950 D3DPOOL_MANAGED, &texture);
4951 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
4953 hr = IDirect3DVolumeTexture8_LockBox(texture, 0, &box, NULL, 0);
4954 ok(SUCCEEDED(hr), "Failed to lock volume texture, hr %#x.\n", hr);
4955 memcpy(box.pBits, texture_data, sizeof(texture_data));
4956 hr = IDirect3DVolumeTexture8_UnlockBox(texture, 0);
4957 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#x.\n", hr);
4959 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE3(0));
4960 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
4961 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
4962 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
4963 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
4964 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
4965 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
4966 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
4967 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
4968 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
4969 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MAGFILTER, D3DTEXF_POINT);
4970 ok(SUCCEEDED(hr), "Failed to set mag filter, hr %#x.\n", hr);
4972 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff00ff, 1.0f, 0);
4973 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
4974 hr = IDirect3DDevice8_BeginScene(device);
4975 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
4976 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads));
4977 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4978 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[4], sizeof(*quads));
4979 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4980 hr = IDirect3DDevice8_EndScene(device);
4981 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
4983 for (i = 0; i < 4; i++)
4985 color = getPixelColor(device, 80 + 160 * i, 240);
4986 ok (color_match(color, expected_colors[i], 1),
4987 "Expected color 0x%08x, got 0x%08x, case %u.\n", expected_colors[i], color, i);
4990 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
4991 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
4992 IDirect3DVolumeTexture8_Release(texture);
4993 refcount = IDirect3DDevice8_Release(device);
4994 ok(!refcount, "Device has %u references left.\n", refcount);
4995 done:
4996 IDirect3D8_Release(d3d);
4997 DestroyWindow(window);
5000 static void volume_v16u16_test(void)
5002 IDirect3DVolumeTexture8 *texture;
5003 IDirect3DDevice8 *device;
5004 D3DLOCKED_BOX box;
5005 IDirect3D8 *d3d;
5006 unsigned int i;
5007 D3DCOLOR color;
5008 ULONG refcount;
5009 D3DCAPS8 caps;
5010 DWORD shader;
5011 SHORT *texel;
5012 HWND window;
5013 HRESULT hr;
5015 static const struct
5017 struct vec3 position;
5018 struct vec3 texcrd;
5020 quads[] =
5022 {{ -1.0f, -1.0f, 0.0f}, { 0.0f, 0.0f, 0.25f}},
5023 {{ -1.0f, 1.0f, 0.0f}, { 0.0f, 1.0f, 0.25f}},
5024 {{ 0.0f, -1.0f, 1.0f}, { 1.0f, 0.0f, 0.25f}},
5025 {{ 0.0f, 1.0f, 1.0f}, { 1.0f, 1.0f, 0.25f}},
5027 {{ 0.0f, -1.0f, 0.0f}, { 0.0f, 0.0f, 0.75f}},
5028 {{ 0.0f, 1.0f, 0.0f}, { 0.0f, 1.0f, 0.75f}},
5029 {{ 1.0f, -1.0f, 1.0f}, { 1.0f, 0.0f, 0.75f}},
5030 {{ 1.0f, 1.0f, 1.0f}, { 1.0f, 1.0f, 0.75f}},
5032 static const DWORD shader_code[] =
5034 0xffff0101, /* ps_1_1 */
5035 0x00000051, 0xa00f0000, 0x3f000000, 0x3f000000, /* def c0, 0.5, 0.5, */
5036 0x3f000000, 0x3f000000, /* 0.5, 0.5 */
5037 0x00000042, 0xb00f0000, /* tex t0 */
5038 0x00000004, 0x800f0000, 0xb0e40000, 0xa0e40000, 0xa0e40000, /* mad r0, t0, c0, c0 */
5039 0x0000ffff /* end */
5042 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
5043 0, 0, 640, 480, NULL, NULL, NULL, NULL);
5044 d3d = Direct3DCreate8(D3D_SDK_VERSION);
5045 ok(!!d3d, "Failed to create a D3D object.\n");
5046 if (!(device = create_device(d3d, window, window, TRUE)))
5048 skip("Failed to create a D3D device, skipping tests.\n");
5049 goto done;
5052 if (FAILED(IDirect3D8_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
5053 D3DFMT_X8R8G8B8, 0, D3DRTYPE_VOLUMETEXTURE, D3DFMT_V16U16)))
5055 skip("Volume V16U16 textures are not supported, skipping test.\n");
5056 IDirect3DDevice8_Release(device);
5057 goto done;
5059 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
5060 ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
5061 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 1))
5063 skip("No pixel shader 1.1 support, skipping test.\n");
5064 IDirect3DDevice8_Release(device);
5065 goto done;
5068 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE3(0));
5069 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
5070 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code, &shader);
5071 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
5072 hr = IDirect3DDevice8_SetPixelShader(device, shader);
5073 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
5074 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MAGFILTER, D3DTEXF_POINT);
5075 ok(SUCCEEDED(hr), "Failed to set filter, hr %#x.\n", hr);
5077 for (i = 0; i < 2; i++)
5079 D3DPOOL pool;
5081 if (i)
5082 pool = D3DPOOL_SYSTEMMEM;
5083 else
5084 pool = D3DPOOL_MANAGED;
5086 hr = IDirect3DDevice8_CreateVolumeTexture(device, 1, 2, 2, 1, 0, D3DFMT_V16U16,
5087 pool, &texture);
5088 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
5090 hr = IDirect3DVolumeTexture8_LockBox(texture, 0, &box, NULL, 0);
5091 ok(SUCCEEDED(hr), "Failed to lock volume texture, hr %#x.\n", hr);
5093 texel = (SHORT *)((BYTE *)box.pBits + 0 * box.RowPitch + 0 * box.SlicePitch);
5094 texel[0] = 32767;
5095 texel[1] = 32767;
5096 texel = (SHORT *)((BYTE *)box.pBits + 1 * box.RowPitch + 0 * box.SlicePitch);
5097 texel[0] = -32768;
5098 texel[1] = 0;
5099 texel = (SHORT *)((BYTE *)box.pBits + 0 * box.RowPitch + 1 * box.SlicePitch);
5100 texel[0] = -16384;
5101 texel[1] = 16384;
5102 texel = (SHORT *)((BYTE *)box.pBits + 1 * box.RowPitch + 1 * box.SlicePitch);
5103 texel[0] = 0;
5104 texel[1] = 0;
5106 hr = IDirect3DVolumeTexture8_UnlockBox(texture, 0);
5107 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#x.\n", hr);
5109 if (i)
5111 IDirect3DVolumeTexture8 *texture2;
5113 hr = IDirect3DDevice8_CreateVolumeTexture(device, 1, 2, 2, 1, 0, D3DFMT_V16U16,
5114 D3DPOOL_DEFAULT, &texture2);
5115 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
5117 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)texture,
5118 (IDirect3DBaseTexture8 *)texture2);
5119 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
5121 IDirect3DVolumeTexture8_Release(texture);
5122 texture = texture2;
5125 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *) texture);
5126 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
5128 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff00ff, 1.0f, 0);
5129 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
5130 hr = IDirect3DDevice8_BeginScene(device);
5131 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5132 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads));
5133 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5134 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[4], sizeof(*quads));
5135 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5136 hr = IDirect3DDevice8_EndScene(device);
5137 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5139 color = getPixelColor(device, 120, 160);
5140 ok (color_match(color, 0x000080ff, 2),
5141 "Expected color 0x000080ff, got 0x%08x, V16U16 input -32768, 0.\n", color);
5142 color = getPixelColor(device, 120, 400);
5143 ok (color_match(color, 0x00ffffff, 2),
5144 "Expected color 0x00ffffff, got 0x%08x, V16U16 input 32767, 32767.\n", color);
5145 color = getPixelColor(device, 360, 160);
5146 ok (color_match(color, 0x007f7fff, 2),
5147 "Expected color 0x007f7fff, got 0x%08x, V16U16 input 0, 0.\n", color);
5148 color = getPixelColor(device, 360, 400);
5149 ok (color_match(color, 0x0040c0ff, 2),
5150 "Expected color 0x0040c0ff, got 0x%08x, V16U16 input -16384, 16384.\n", color);
5152 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5153 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5155 IDirect3DVolumeTexture8_Release(texture);
5158 hr = IDirect3DDevice8_DeletePixelShader(device, shader);
5159 ok(SUCCEEDED(hr), "Failed delete pixel shader, hr %#x.\n", hr);
5160 refcount = IDirect3DDevice8_Release(device);
5161 ok(!refcount, "Device has %u references left.\n", refcount);
5162 done:
5163 IDirect3D8_Release(d3d);
5164 DestroyWindow(window);
5167 static void fill_surface(IDirect3DSurface8 *surface, DWORD color, DWORD flags)
5169 D3DSURFACE_DESC desc;
5170 D3DLOCKED_RECT l;
5171 HRESULT hr;
5172 unsigned int x, y;
5173 DWORD *mem;
5175 hr = IDirect3DSurface8_GetDesc(surface, &desc);
5176 ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr);
5177 hr = IDirect3DSurface8_LockRect(surface, &l, NULL, flags);
5178 ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
5179 if (FAILED(hr))
5180 return;
5182 for (y = 0; y < desc.Height; y++)
5184 mem = (DWORD *)((BYTE *)l.pBits + y * l.Pitch);
5185 for (x = 0; x < l.Pitch / sizeof(DWORD); x++)
5187 mem[x] = color;
5190 hr = IDirect3DSurface8_UnlockRect(surface);
5191 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
5194 static void add_dirty_rect_test_draw(IDirect3DDevice8 *device)
5196 HRESULT hr;
5197 static const struct
5199 struct vec3 position;
5200 struct vec2 texcoord;
5202 quad[] =
5204 {{-1.0f, -1.0f, 0.0f}, {0.0f, 0.0f}},
5205 {{-1.0f, 1.0f, 0.0f}, {0.0f, 1.0f}},
5206 {{ 1.0f, -1.0f, 0.0f}, {1.0f, 0.0f}},
5207 {{ 1.0f, 1.0f, 0.0f}, {1.0f, 1.0f}},
5210 hr = IDirect3DDevice8_BeginScene(device);
5211 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5212 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad, sizeof(*quad));
5213 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5214 hr = IDirect3DDevice8_EndScene(device);
5215 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5218 static void add_dirty_rect_test(void)
5220 IDirect3DSurface8 *surface_dst2, *surface_src_green, *surface_src_red, *surface_managed;
5221 IDirect3DTexture8 *tex_dst1, *tex_dst2, *tex_src_red, *tex_src_green, *tex_managed;
5222 D3DLOCKED_RECT locked_rect;
5223 IDirect3DDevice8 *device;
5224 IDirect3D8 *d3d;
5225 unsigned int i;
5226 D3DCOLOR color;
5227 ULONG refcount;
5228 DWORD *texel;
5229 HWND window;
5230 HRESULT hr;
5232 static const RECT part_rect = {96, 96, 160, 160};
5234 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
5235 0, 0, 640, 480, NULL, NULL, NULL, NULL);
5236 d3d = Direct3DCreate8(D3D_SDK_VERSION);
5237 ok(!!d3d, "Failed to create a D3D object.\n");
5238 if (!(device = create_device(d3d, window, window, TRUE)))
5240 skip("Failed to create a D3D device, skipping tests.\n");
5241 goto done;
5244 hr = IDirect3DDevice8_CreateTexture(device, 256, 256, 1, 0, D3DFMT_X8R8G8B8,
5245 D3DPOOL_DEFAULT, &tex_dst1);
5246 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
5247 hr = IDirect3DDevice8_CreateTexture(device, 256, 256, 1, 0, D3DFMT_X8R8G8B8,
5248 D3DPOOL_DEFAULT, &tex_dst2);
5249 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
5250 hr = IDirect3DDevice8_CreateTexture(device, 256, 256, 1, 0, D3DFMT_X8R8G8B8,
5251 D3DPOOL_SYSTEMMEM, &tex_src_red);
5252 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
5253 hr = IDirect3DDevice8_CreateTexture(device, 256, 256, 1, 0, D3DFMT_X8R8G8B8,
5254 D3DPOOL_SYSTEMMEM, &tex_src_green);
5255 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
5256 hr = IDirect3DDevice8_CreateTexture(device, 256, 256, 1, 0, D3DFMT_X8R8G8B8,
5257 D3DPOOL_MANAGED, &tex_managed);
5258 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
5260 hr = IDirect3DTexture8_GetSurfaceLevel(tex_dst2, 0, &surface_dst2);
5261 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
5262 hr = IDirect3DTexture8_GetSurfaceLevel(tex_src_green, 0, &surface_src_green);
5263 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
5264 hr = IDirect3DTexture8_GetSurfaceLevel(tex_src_red, 0, &surface_src_red);
5265 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
5266 hr = IDirect3DTexture8_GetSurfaceLevel(tex_managed, 0, &surface_managed);
5267 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
5269 fill_surface(surface_src_red, 0x00ff0000, 0);
5270 fill_surface(surface_src_green, 0x0000ff00, 0);
5272 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX1);
5273 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr);
5274 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
5275 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
5276 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
5277 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
5279 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_green,
5280 (IDirect3DBaseTexture8 *)tex_dst1);
5281 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
5283 /* The second UpdateTexture call writing to tex_dst2 is ignored because tex_src_green is not dirty. */
5284 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_red,
5285 (IDirect3DBaseTexture8 *)tex_dst2);
5286 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
5287 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_green,
5288 (IDirect3DBaseTexture8 *)tex_dst2);
5289 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
5291 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)tex_dst1);
5292 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
5293 add_dirty_rect_test_draw(device);
5294 color = getPixelColor(device, 320, 240);
5295 ok(color_match(color, 0x0000ff00, 1),
5296 "Expected color 0x0000ff00, got 0x%08x.\n", color);
5297 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5298 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5300 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)tex_dst2);
5301 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
5302 add_dirty_rect_test_draw(device);
5303 color = getPixelColor(device, 320, 240);
5304 todo_wine ok(color_match(color, 0x00ff0000, 1),
5305 "Expected color 0x00ff0000, got 0x%08x.\n", color);
5306 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5307 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5309 /* AddDirtyRect on the destination is ignored. */
5310 hr = IDirect3DTexture8_AddDirtyRect(tex_dst2, &part_rect);
5311 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
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, 0x00ff0000, 1),
5318 "Expected color 0x00ff0000, 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_dst2, NULL);
5323 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
5324 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_green,
5325 (IDirect3DBaseTexture8 *)tex_dst2);
5326 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
5327 add_dirty_rect_test_draw(device);
5328 color = getPixelColor(device, 320, 240);
5329 todo_wine ok(color_match(color, 0x00ff0000, 1),
5330 "Expected color 0x00ff0000, got 0x%08x.\n", color);
5331 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5332 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5334 /* AddDirtyRect on the source makes UpdateTexture work. Partial rectangle
5335 * tracking is supported. */
5336 hr = IDirect3DTexture8_AddDirtyRect(tex_src_green, &part_rect);
5337 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
5338 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_green,
5339 (IDirect3DBaseTexture8 *)tex_dst2);
5340 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
5341 add_dirty_rect_test_draw(device);
5342 color = getPixelColor(device, 320, 240);
5343 ok(color_match(color, 0x0000ff00, 1),
5344 "Expected color 0x0000ff00, got 0x%08x.\n", color);
5345 color = getPixelColor(device, 1, 1);
5346 todo_wine ok(color_match(color, 0x00ff0000, 1),
5347 "Expected color 0x00ff0000, got 0x%08x.\n", color);
5348 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5349 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5351 hr = IDirect3DTexture8_AddDirtyRect(tex_src_green, NULL);
5352 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
5353 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_green,
5354 (IDirect3DBaseTexture8 *)tex_dst2);
5355 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
5356 add_dirty_rect_test_draw(device);
5357 color = getPixelColor(device, 1, 1);
5358 ok(color_match(color, 0x0000ff00, 1),
5359 "Expected color 0x0000ff00, got 0x%08x.\n", color);
5361 /* Locks with NO_DIRTY_UPDATE are ignored. */
5362 fill_surface(surface_src_green, 0x00000080, D3DLOCK_NO_DIRTY_UPDATE);
5363 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_green,
5364 (IDirect3DBaseTexture8 *)tex_dst2);
5365 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
5366 add_dirty_rect_test_draw(device);
5367 color = getPixelColor(device, 320, 240);
5368 todo_wine ok(color_match(color, 0x0000ff00, 1),
5369 "Expected color 0x0000ff00, got 0x%08x.\n", color);
5370 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5371 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5373 /* Readonly maps write to D3DPOOL_SYSTEMMEM, but don't record a dirty rectangle. */
5374 fill_surface(surface_src_green, 0x000000ff, D3DLOCK_READONLY);
5375 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_green,
5376 (IDirect3DBaseTexture8 *)tex_dst2);
5377 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
5378 add_dirty_rect_test_draw(device);
5379 color = getPixelColor(device, 320, 240);
5380 todo_wine ok(color_match(color, 0x0000ff00, 1),
5381 "Expected color 0x0000ff00, got 0x%08x.\n", color);
5382 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5383 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5385 hr = IDirect3DTexture8_AddDirtyRect(tex_src_green, NULL);
5386 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_green,
5387 (IDirect3DBaseTexture8 *)tex_dst2);
5388 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
5389 add_dirty_rect_test_draw(device);
5390 color = getPixelColor(device, 320, 240);
5391 ok(color_match(color, 0x000000ff, 1),
5392 "Expected color 0x000000ff, got 0x%08x.\n", color);
5393 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5394 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5396 /* Maps without either of these flags record a dirty rectangle. */
5397 fill_surface(surface_src_green, 0x00ffffff, 0);
5398 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_green,
5399 (IDirect3DBaseTexture8 *)tex_dst2);
5400 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
5401 add_dirty_rect_test_draw(device);
5402 color = getPixelColor(device, 320, 240);
5403 ok(color_match(color, 0x00ffffff, 1),
5404 "Expected color 0x00ffffff, got 0x%08x.\n", color);
5405 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5406 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5408 /* Partial LockRect works just like a partial AddDirtyRect call. */
5409 hr = IDirect3DTexture8_LockRect(tex_src_green, 0, &locked_rect, &part_rect, 0);
5410 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
5411 texel = locked_rect.pBits;
5412 for (i = 0; i < 64; i++)
5413 texel[i] = 0x00ff00ff;
5414 for (i = 1; i < 64; i++)
5415 memcpy((BYTE *)locked_rect.pBits + i * locked_rect.Pitch, locked_rect.pBits, locked_rect.Pitch);
5416 hr = IDirect3DTexture8_UnlockRect(tex_src_green, 0);
5417 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
5418 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_green,
5419 (IDirect3DBaseTexture8 *)tex_dst2);
5420 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
5421 add_dirty_rect_test_draw(device);
5422 color = getPixelColor(device, 320, 240);
5423 ok(color_match(color, 0x00ff00ff, 1),
5424 "Expected color 0x00ff00ff, got 0x%08x.\n", color);
5425 color = getPixelColor(device, 1, 1);
5426 ok(color_match(color, 0x00ffffff, 1),
5427 "Expected color 0x00ffffff, got 0x%08x.\n", color);
5428 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5429 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5431 fill_surface(surface_src_red, 0x00ff0000, 0);
5432 fill_surface(surface_src_green, 0x0000ff00, 0);
5434 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_green,
5435 (IDirect3DBaseTexture8 *)tex_dst1);
5436 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
5437 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)tex_dst1);
5438 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
5439 add_dirty_rect_test_draw(device);
5440 color = getPixelColor(device, 320, 240);
5441 ok(color_match(color, 0x0000ff00, 1),
5442 "Expected color 0x0000ff00, got 0x%08x.\n", color);
5443 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5444 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5446 /* UpdateSurface ignores the missing dirty marker. */
5447 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)tex_src_red,
5448 (IDirect3DBaseTexture8 *)tex_dst2);
5449 hr = IDirect3DDevice8_CopyRects(device, surface_src_green, NULL, 0, surface_dst2, NULL);
5450 ok(SUCCEEDED(hr), "Failed to update surface, hr %#x.\n", hr);
5451 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)tex_dst2);
5452 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
5453 add_dirty_rect_test_draw(device);
5454 color = getPixelColor(device, 320, 240);
5455 ok(color_match(color, 0x0000ff00, 1),
5456 "Expected color 0x0000ff00, got 0x%08x.\n", color);
5457 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5458 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5460 fill_surface(surface_managed, 0x00ff0000, 0);
5461 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)tex_managed);
5462 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
5463 add_dirty_rect_test_draw(device);
5464 color = getPixelColor(device, 320, 240);
5465 ok(color_match(color, 0x00ff0000, 1),
5466 "Expected color 0x00ff0000, got 0x%08x.\n", color);
5467 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5468 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5470 /* Managed textures also honor D3DLOCK_NO_DIRTY_UPDATE. */
5471 fill_surface(surface_managed, 0x0000ff00, D3DLOCK_NO_DIRTY_UPDATE);
5472 add_dirty_rect_test_draw(device);
5473 color = getPixelColor(device, 320, 240);
5474 ok(color_match(color, 0x00ff0000, 1),
5475 "Expected color 0x00ff0000, got 0x%08x.\n", color);
5476 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5477 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5479 /* AddDirtyRect uploads the new contents.
5480 * Side note, not tested in the test: Partial surface updates work, and two separate
5481 * dirty rectangles are tracked individually. Tested on Nvidia Kepler, other drivers
5482 * untested. */
5483 hr = IDirect3DTexture8_AddDirtyRect(tex_managed, NULL);
5484 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
5485 add_dirty_rect_test_draw(device);
5486 color = getPixelColor(device, 320, 240);
5487 ok(color_match(color, 0x0000ff00, 1),
5488 "Expected color 0x0000ff00, got 0x%08x.\n", color);
5489 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5490 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5492 /* So does ResourceManagerDiscardBytes. */
5493 fill_surface(surface_managed, 0x000000ff, D3DLOCK_NO_DIRTY_UPDATE);
5494 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
5495 hr = IDirect3DDevice8_ResourceManagerDiscardBytes(device, 0);
5496 ok(SUCCEEDED(hr), "Failed to evict managed resources, hr %#x.\n", hr);
5497 add_dirty_rect_test_draw(device);
5498 color = getPixelColor(device, 320, 240);
5499 ok(color_match(color, 0x000000ff, 1),
5500 "Expected color 0x000000ff, got 0x%08x.\n", color);
5501 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5502 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5504 /* AddDirtyRect on a locked texture is allowed. */
5505 hr = IDirect3DTexture8_LockRect(tex_src_red, 0, &locked_rect, NULL, 0);
5506 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
5507 hr = IDirect3DTexture8_AddDirtyRect(tex_src_red, NULL);
5508 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
5509 hr = IDirect3DTexture8_UnlockRect(tex_src_red, 0);
5510 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
5512 /* Redundant AddDirtyRect calls are ok. */
5513 hr = IDirect3DTexture8_AddDirtyRect(tex_managed, NULL);
5514 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
5515 hr = IDirect3DTexture8_AddDirtyRect(tex_managed, NULL);
5516 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
5518 IDirect3DSurface8_Release(surface_dst2);
5519 IDirect3DSurface8_Release(surface_managed);
5520 IDirect3DSurface8_Release(surface_src_red);
5521 IDirect3DSurface8_Release(surface_src_green);
5522 IDirect3DTexture8_Release(tex_src_red);
5523 IDirect3DTexture8_Release(tex_src_green);
5524 IDirect3DTexture8_Release(tex_dst1);
5525 IDirect3DTexture8_Release(tex_dst2);
5526 IDirect3DTexture8_Release(tex_managed);
5527 refcount = IDirect3DDevice8_Release(device);
5528 ok(!refcount, "Device has %u references left.\n", refcount);
5529 done:
5530 IDirect3D8_Release(d3d);
5531 DestroyWindow(window);
5534 static void test_3dc_formats(void)
5536 static const char ati1n_data[] =
5538 /* A 4x4 texture with the color component at 50%. */
5539 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5541 static const char ati2n_data[] =
5543 /* A 8x4 texture consisting of 2 4x4 blocks. The first block has 50% first color component,
5544 * 0% second component. Second block is the opposite. */
5545 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5546 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5548 static const struct
5550 struct vec3 position;
5551 struct vec2 texcoord;
5553 quads[] =
5555 {{-1.0f, -1.0f, 0.0f}, {0.0f, 0.0f}},
5556 {{-1.0f, 1.0f, 0.0f}, {0.0f, 1.0f}},
5557 {{ 0.0f, -1.0f, 1.0f}, {1.0f, 0.0f}},
5558 {{ 0.0f, 1.0f, 1.0f}, {1.0f, 1.0f}},
5560 {{ 0.0f, -1.0f, 0.0f}, {0.0f, 0.0f}},
5561 {{ 0.0f, 1.0f, 0.0f}, {0.0f, 1.0f}},
5562 {{ 1.0f, -1.0f, 1.0f}, {1.0f, 0.0f}},
5563 {{ 1.0f, 1.0f, 1.0f}, {1.0f, 1.0f}},
5565 static const DWORD ati1n_fourcc = MAKEFOURCC('A','T','I','1');
5566 static const DWORD ati2n_fourcc = MAKEFOURCC('A','T','I','2');
5567 static const struct
5569 struct vec2 position;
5570 D3DCOLOR amd_r500;
5571 D3DCOLOR amd_r600;
5572 D3DCOLOR nvidia_old;
5573 D3DCOLOR nvidia_new;
5575 expected_colors[] =
5577 {{ 80, 240}, 0x007fffff, 0x003f3f3f, 0x007f7f7f, 0x007f0000},
5578 {{240, 240}, 0x007fffff, 0x003f3f3f, 0x007f7f7f, 0x007f0000},
5579 {{400, 240}, 0x00007fff, 0x00007fff, 0x00007fff, 0x00007fff},
5580 {{560, 240}, 0x007f00ff, 0x007f00ff, 0x007f00ff, 0x007f00ff},
5582 IDirect3D8 *d3d;
5583 IDirect3DDevice8 *device;
5584 IDirect3DTexture8 *ati1n_texture, *ati2n_texture;
5585 D3DCAPS8 caps;
5586 D3DLOCKED_RECT rect;
5587 D3DCOLOR color;
5588 ULONG refcount;
5589 HWND window;
5590 HRESULT hr;
5591 unsigned int i;
5593 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
5594 0, 0, 640, 480, NULL, NULL, NULL, NULL);
5595 d3d = Direct3DCreate8(D3D_SDK_VERSION);
5596 ok(!!d3d, "Failed to create a D3D object.\n");
5597 if (FAILED(IDirect3D8_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
5598 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, ati1n_fourcc)))
5600 skip("ATI1N textures are not supported, skipping test.\n");
5601 goto done;
5603 if (FAILED(IDirect3D8_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
5604 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, ati2n_fourcc)))
5606 skip("ATI2N textures are not supported, skipping test.\n");
5607 goto done;
5609 if (!(device = create_device(d3d, window, window, TRUE)))
5611 skip("Failed to create a D3D device, skipping tests.\n");
5612 goto done;
5614 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
5615 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
5616 if (!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP))
5618 skip("D3DTA_TEMP not supported, skipping tests.\n");
5619 IDirect3DDevice8_Release(device);
5620 goto done;
5623 hr = IDirect3DDevice8_CreateTexture(device, 4, 4, 1, 0, ati1n_fourcc,
5624 D3DPOOL_MANAGED, &ati1n_texture);
5625 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
5627 hr = IDirect3DTexture8_LockRect(ati1n_texture, 0, &rect, NULL, 0);
5628 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
5629 memcpy(rect.pBits, ati1n_data, sizeof(ati1n_data));
5630 hr = IDirect3DTexture8_UnlockRect(ati1n_texture, 0);
5631 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
5633 hr = IDirect3DDevice8_CreateTexture(device, 8, 4, 1, 0, ati2n_fourcc,
5634 D3DPOOL_MANAGED, &ati2n_texture);
5635 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
5637 hr = IDirect3DTexture8_LockRect(ati2n_texture, 0, &rect, NULL, 0);
5638 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
5639 memcpy(rect.pBits, ati2n_data, sizeof(ati2n_data));
5640 hr = IDirect3DTexture8_UnlockRect(ati2n_texture, 0);
5641 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
5643 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE2(0));
5644 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
5645 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BLENDTEXTUREALPHA);
5646 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
5647 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
5648 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
5649 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TEMP);
5650 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
5651 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
5652 ok(SUCCEEDED(hr), "Failed to set alpha op, hr %#x.\n", hr);
5653 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
5654 ok(SUCCEEDED(hr), "Failed to set alpha arg, hr %#x.\n", hr);
5655 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
5656 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
5657 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MAGFILTER, D3DTEXF_POINT);
5658 ok(SUCCEEDED(hr), "Failed to set mag filter, hr %#x.\n", hr);
5660 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff00ff, 1.0f, 0);
5661 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
5662 hr = IDirect3DDevice8_BeginScene(device);
5663 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5664 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)ati1n_texture);
5665 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
5666 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads));
5667 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5668 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)ati2n_texture);
5669 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
5670 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[4], sizeof(*quads));
5671 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5672 hr = IDirect3DDevice8_EndScene(device);
5673 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5675 for (i = 0; i < 4; ++i)
5677 color = getPixelColor(device, expected_colors[i].position.x, expected_colors[i].position.y);
5678 ok (color_match(color, expected_colors[i].amd_r500, 1)
5679 || color_match(color, expected_colors[i].amd_r600, 1)
5680 || color_match(color, expected_colors[i].nvidia_old, 1)
5681 || color_match(color, expected_colors[i].nvidia_new, 1),
5682 "Got unexpected color 0x%08x, case %u.\n", color, i);
5685 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5686 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5687 IDirect3DTexture8_Release(ati2n_texture);
5688 IDirect3DTexture8_Release(ati1n_texture);
5689 refcount = IDirect3DDevice8_Release(device);
5690 ok(!refcount, "Device has %u references left.\n", refcount);
5692 done:
5693 IDirect3D8_Release(d3d);
5694 DestroyWindow(window);
5697 static void test_fog_interpolation(void)
5699 HRESULT hr;
5700 IDirect3DDevice8 *device;
5701 IDirect3D8 *d3d;
5702 ULONG refcount;
5703 HWND window;
5704 D3DCOLOR color;
5705 static const struct
5707 struct vec3 position;
5708 D3DCOLOR diffuse;
5709 D3DCOLOR specular;
5711 quad[] =
5713 {{-1.0f, -1.0f, 0.0f}, 0xffff0000, 0xff000000},
5714 {{-1.0f, 1.0f, 0.0f}, 0xffff0000, 0xff000000},
5715 {{ 1.0f, -1.0f, 1.0f}, 0xffff0000, 0x00000000},
5716 {{ 1.0f, 1.0f, 1.0f}, 0xffff0000, 0x00000000},
5718 union
5720 DWORD d;
5721 float f;
5722 } conv;
5723 unsigned int i;
5724 static const struct
5726 D3DFOGMODE vfog, tfog;
5727 D3DSHADEMODE shade;
5728 D3DCOLOR middle_color;
5729 BOOL todo;
5731 tests[] =
5733 {D3DFOG_NONE, D3DFOG_NONE, D3DSHADE_FLAT, 0x00007f80, FALSE},
5734 {D3DFOG_NONE, D3DFOG_NONE, D3DSHADE_GOURAUD, 0x00007f80, FALSE},
5735 {D3DFOG_EXP, D3DFOG_NONE, D3DSHADE_FLAT, 0x00007f80, TRUE},
5736 {D3DFOG_EXP, D3DFOG_NONE, D3DSHADE_GOURAUD, 0x00007f80, TRUE},
5737 {D3DFOG_NONE, D3DFOG_EXP, D3DSHADE_FLAT, 0x0000ea15, FALSE},
5738 {D3DFOG_NONE, D3DFOG_EXP, D3DSHADE_GOURAUD, 0x0000ea15, FALSE},
5739 {D3DFOG_EXP, D3DFOG_EXP, D3DSHADE_FLAT, 0x0000ea15, FALSE},
5740 {D3DFOG_EXP, D3DFOG_EXP, D3DSHADE_GOURAUD, 0x0000ea15, FALSE},
5742 static const D3DMATRIX ident_mat =
5744 1.0f, 0.0f, 0.0f, 0.0f,
5745 0.0f, 1.0f, 0.0f, 0.0f,
5746 0.0f, 0.0f, 1.0f, 0.0f,
5747 0.0f, 0.0f, 0.0f, 1.0f
5748 }}};
5749 D3DCAPS8 caps;
5751 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
5752 0, 0, 640, 480, NULL, NULL, NULL, NULL);
5753 d3d = Direct3DCreate8(D3D_SDK_VERSION);
5754 ok(!!d3d, "Failed to create a D3D object.\n");
5756 if (!(device = create_device(d3d, window, window, TRUE)))
5758 skip("Failed to create a D3D device, skipping tests.\n");
5759 IDirect3D8_Release(d3d);
5760 DestroyWindow(window);
5761 return;
5764 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
5765 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
5766 if (!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE))
5767 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping some fog tests\n");
5769 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
5770 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr);
5771 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
5772 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
5773 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, FALSE);
5774 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
5775 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
5776 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
5777 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGCOLOR, 0x0000ff00);
5778 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
5779 conv.f = 5.0;
5780 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGDENSITY, conv.d);
5781 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
5783 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
5784 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
5785 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TFACTOR);
5786 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
5787 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x000000ff);
5788 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
5790 /* Some of the tests seem to depend on the projection matrix explicitly
5791 * being set to an identity matrix, even though that's the default.
5792 * (AMD Radeon X1600, AMD Radeon HD 6310, Windows 7). Without this,
5793 * the drivers seem to use a static z = 1.0 input for the fog equation.
5794 * The input value is independent of the actual z and w component of
5795 * the vertex position. */
5796 hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, &ident_mat);
5797 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
5799 for (i = 0; i < sizeof(tests) / sizeof(*tests); i++)
5801 if(!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE) && tests[i].tfog)
5802 continue;
5804 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00808080, 0.0f, 0);
5805 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
5807 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SHADEMODE, tests[i].shade);
5808 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
5809 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGVERTEXMODE, tests[i].vfog);
5810 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
5811 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGTABLEMODE, tests[i].tfog);
5812 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
5813 hr = IDirect3DDevice8_BeginScene(device);
5814 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5815 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
5816 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5817 hr = IDirect3DDevice8_EndScene(device);
5818 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5820 color = getPixelColor(device, 0, 240);
5821 ok(color_match(color, 0x000000ff, 2), "Got unexpected color 0x%08x, case %u.\n", color, i);
5822 color = getPixelColor(device, 320, 240);
5823 if (tests[i].todo)
5824 todo_wine ok(color_match(color, tests[i].middle_color, 2),
5825 "Got unexpected color 0x%08x, case %u.\n", color, i);
5826 else
5827 ok(color_match(color, tests[i].middle_color, 2),
5828 "Got unexpected color 0x%08x, case %u.\n", color, i);
5829 color = getPixelColor(device, 639, 240);
5830 ok(color_match(color, 0x0000fd02, 2), "Got unexpected color 0x%08x, case %u.\n", color, i);
5831 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5832 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5835 refcount = IDirect3DDevice8_Release(device);
5836 ok(!refcount, "Device has %u references left.\n", refcount);
5837 IDirect3D8_Release(d3d);
5838 DestroyWindow(window);
5841 static void test_negative_fixedfunction_fog(void)
5843 HRESULT hr;
5844 IDirect3DDevice8 *device;
5845 IDirect3D8 *d3d;
5846 ULONG refcount;
5847 HWND window;
5848 D3DCOLOR color;
5849 static const struct
5851 struct vec3 position;
5852 D3DCOLOR diffuse;
5854 quad[] =
5856 {{-1.0f, -1.0f, -0.5f}, 0xffff0000},
5857 {{-1.0f, 1.0f, -0.5f}, 0xffff0000},
5858 {{ 1.0f, -1.0f, -0.5f}, 0xffff0000},
5859 {{ 1.0f, 1.0f, -0.5f}, 0xffff0000},
5861 static const struct
5863 struct vec4 position;
5864 D3DCOLOR diffuse;
5866 tquad[] =
5868 {{ 0.0f, 0.0f, -0.5f, 1.0f}, 0xffff0000},
5869 {{640.0f, 0.0f, -0.5f, 1.0f}, 0xffff0000},
5870 {{ 0.0f, 480.0f, -0.5f, 1.0f}, 0xffff0000},
5871 {{640.0f, 480.0f, -0.5f, 1.0f}, 0xffff0000},
5873 unsigned int i;
5874 static const D3DMATRIX zero =
5876 1.0f, 0.0f, 0.0f, 0.0f,
5877 0.0f, 1.0f, 0.0f, 0.0f,
5878 0.0f, 0.0f, 0.0f, 0.0f,
5879 0.0f, 0.0f, 0.0f, 1.0f
5880 }}};
5881 /* Needed to make AMD drivers happy. Yeah, it is not supposed to
5882 * have an effect on RHW draws. */
5883 static const D3DMATRIX identity =
5885 1.0f, 0.0f, 0.0f, 0.0f,
5886 0.0f, 1.0f, 0.0f, 0.0f,
5887 0.0f, 0.0f, 1.0f, 0.0f,
5888 0.0f, 0.0f, 0.0f, 1.0f
5889 }}};
5890 static const struct
5892 DWORD pos_type;
5893 const void *quad;
5894 size_t stride;
5895 const D3DMATRIX *matrix;
5896 union
5898 float f;
5899 DWORD d;
5900 } start, end;
5901 D3DFOGMODE vfog, tfog;
5902 DWORD color, color_broken, color_broken2;
5904 tests[] =
5906 /* Run the XYZRHW tests first. Depth clamping is broken after RHW draws on the testbot.
5908 * Geforce8+ GPUs on Windows abs() table fog, everything else does not. */
5909 {D3DFVF_XYZRHW, tquad, sizeof(*tquad), &identity, { 0.0f}, {1.0f},
5910 D3DFOG_NONE, D3DFOG_LINEAR, 0x00ff0000, 0x00808000, 0x00808000},
5911 /* r200 GPUs and presumably all d3d8 and older HW clamp the fog
5912 * parameters to 0.0 and 1.0 in the table fog case. */
5913 {D3DFVF_XYZRHW, tquad, sizeof(*tquad), &identity, {-1.0f}, {0.0f},
5914 D3DFOG_NONE, D3DFOG_LINEAR, 0x00808000, 0x00ff0000, 0x0000ff00},
5915 /* test_fog_interpolation shows that vertex fog evaluates the fog
5916 * equation in the vertex pipeline. Start = -1.0 && end = 0.0 shows
5917 * that the abs happens before the fog equation is evaluated.
5919 * Vertex fog abs() behavior is the same on all GPUs. */
5920 {D3DFVF_XYZ, quad, sizeof(*quad), &zero, { 0.0f}, {1.0f},
5921 D3DFOG_LINEAR, D3DFOG_NONE, 0x00808000, 0x00808000, 0x00808000},
5922 {D3DFVF_XYZ, quad, sizeof(*quad), &zero, {-1.0f}, {0.0f},
5923 D3DFOG_LINEAR, D3DFOG_NONE, 0x0000ff00, 0x0000ff00, 0x0000ff00},
5924 {D3DFVF_XYZ, quad, sizeof(*quad), &zero, { 0.0f}, {1.0f},
5925 D3DFOG_EXP, D3DFOG_NONE, 0x009b6400, 0x009b6400, 0x009b6400},
5927 D3DCAPS8 caps;
5929 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
5930 0, 0, 640, 480, NULL, NULL, NULL, NULL);
5931 d3d = Direct3DCreate8(D3D_SDK_VERSION);
5932 ok(!!d3d, "Failed to create a D3D object.\n");
5934 if (!(device = create_device(d3d, window, window, TRUE)))
5936 skip("Failed to create a D3D device, skipping tests.\n");
5937 IDirect3D8_Release(d3d);
5938 DestroyWindow(window);
5939 return;
5942 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
5943 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
5944 if (!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE))
5945 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping some fog tests.\n");
5947 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
5948 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
5949 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
5950 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
5951 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
5952 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
5953 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGCOLOR, 0x0000ff00);
5954 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
5955 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, FALSE);
5956 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
5958 for (i = 0; i < sizeof(tests) / sizeof(*tests); i++)
5960 if (!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE) && tests[i].tfog)
5961 continue;
5963 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x000000ff, 0.0f, 0);
5964 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
5966 hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, tests[i].matrix);
5967 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
5968 hr = IDirect3DDevice8_SetVertexShader(device, tests[i].pos_type | D3DFVF_DIFFUSE);
5969 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr);
5970 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGSTART, tests[i].start.d);
5971 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
5972 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGEND, tests[i].end.d);
5973 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
5974 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGVERTEXMODE, tests[i].vfog);
5975 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
5976 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGTABLEMODE, tests[i].tfog);
5977 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
5979 hr = IDirect3DDevice8_BeginScene(device);
5980 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5981 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, tests[i].quad, tests[i].stride);
5982 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5983 hr = IDirect3DDevice8_EndScene(device);
5984 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5986 color = getPixelColor(device, 320, 240);
5987 ok(color_match(color, tests[i].color, 2) || broken(color_match(color, tests[i].color_broken, 2))
5988 || broken(color_match(color, tests[i].color_broken2, 2)),
5989 "Got unexpected color 0x%08x, case %u.\n", color, i);
5990 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
5991 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
5994 refcount = IDirect3DDevice8_Release(device);
5995 ok(!refcount, "Device has %u references left.\n", refcount);
5996 IDirect3D8_Release(d3d);
5997 DestroyWindow(window);
6000 static void test_table_fog_zw(void)
6002 HRESULT hr;
6003 IDirect3DDevice8 *device;
6004 IDirect3D8 *d3d;
6005 ULONG refcount;
6006 HWND window;
6007 D3DCOLOR color;
6008 D3DCAPS8 caps;
6009 static struct
6011 struct vec4 position;
6012 D3DCOLOR diffuse;
6014 quad[] =
6016 {{ 0.0f, 0.0f, 0.0f, 0.0f}, 0xffff0000},
6017 {{640.0f, 0.0f, 0.0f, 0.0f}, 0xffff0000},
6018 {{ 0.0f, 480.0f, 0.0f, 0.0f}, 0xffff0000},
6019 {{640.0f, 480.0f, 0.0f, 0.0f}, 0xffff0000},
6021 static const D3DMATRIX identity =
6023 1.0f, 0.0f, 0.0f, 0.0f,
6024 0.0f, 1.0f, 0.0f, 0.0f,
6025 0.0f, 0.0f, 1.0f, 0.0f,
6026 0.0f, 0.0f, 0.0f, 1.0f
6027 }}};
6028 static const struct
6030 float z, w;
6031 D3DZBUFFERTYPE z_test;
6032 D3DCOLOR color;
6034 tests[] =
6036 {0.7f, 0.0f, D3DZB_TRUE, 0x004cb200},
6037 {0.7f, 0.0f, D3DZB_FALSE, 0x004cb200},
6038 {0.7f, 0.3f, D3DZB_TRUE, 0x004cb200},
6039 {0.7f, 0.3f, D3DZB_FALSE, 0x004cb200},
6040 {0.7f, 3.0f, D3DZB_TRUE, 0x004cb200},
6041 {0.7f, 3.0f, D3DZB_FALSE, 0x004cb200},
6042 {0.3f, 0.0f, D3DZB_TRUE, 0x00b24c00},
6043 {0.3f, 0.0f, D3DZB_FALSE, 0x00b24c00},
6045 unsigned int i;
6047 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
6048 0, 0, 640, 480, NULL, NULL, NULL, NULL);
6049 d3d = Direct3DCreate8(D3D_SDK_VERSION);
6050 ok(!!d3d, "Failed to create a D3D object.\n");
6052 if (!(device = create_device(d3d, window, window, TRUE)))
6054 skip("Failed to create a D3D device, skipping tests.\n");
6055 IDirect3D8_Release(d3d);
6056 DestroyWindow(window);
6057 return;
6060 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
6061 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
6062 if (!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE))
6064 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping POSITIONT table fog test.\n");
6065 goto done;
6068 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6069 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6070 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
6071 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6072 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGCOLOR, 0x0000ff00);
6073 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6074 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_CLIPPING, FALSE);
6075 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
6076 /* Work around an AMD Windows driver bug. Needs a proj matrix applied redundantly. */
6077 hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, &identity);
6078 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
6079 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
6080 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6081 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
6082 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr);
6084 for (i = 0; i < sizeof(tests) / sizeof(*tests); ++i)
6086 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
6087 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
6089 quad[0].position.z = tests[i].z;
6090 quad[1].position.z = tests[i].z;
6091 quad[2].position.z = tests[i].z;
6092 quad[3].position.z = tests[i].z;
6093 quad[0].position.w = tests[i].w;
6094 quad[1].position.w = tests[i].w;
6095 quad[2].position.w = tests[i].w;
6096 quad[3].position.w = tests[i].w;
6097 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, tests[i].z_test);
6098 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6100 hr = IDirect3DDevice8_BeginScene(device);
6101 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6102 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
6103 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6104 hr = IDirect3DDevice8_EndScene(device);
6105 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6107 color = getPixelColor(device, 320, 240);
6108 ok(color_match(color, tests[i].color, 2),
6109 "Got unexpected color 0x%08x, expected 0x%08x, case %u.\n", color, tests[i].color, i);
6110 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
6111 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
6114 done:
6115 refcount = IDirect3DDevice8_Release(device);
6116 ok(!refcount, "Device has %u references left.\n", refcount);
6117 IDirect3D8_Release(d3d);
6118 DestroyWindow(window);
6121 static void test_signed_formats(void)
6123 IDirect3DDevice8 *device;
6124 HWND window;
6125 HRESULT hr;
6126 unsigned int i, j, x, y;
6127 IDirect3DTexture8 *texture, *texture_sysmem;
6128 D3DLOCKED_RECT locked_rect;
6129 DWORD shader, shader_alpha;
6130 IDirect3D8 *d3d;
6131 D3DCOLOR color;
6132 D3DCAPS8 caps;
6133 ULONG refcount;
6135 /* See comments in the d3d9 version of this test for an
6136 * explanation of these values. */
6137 static const USHORT content_v8u8[4][4] =
6139 {0x0000, 0x7f7f, 0x8880, 0x0000},
6140 {0x0080, 0x8000, 0x7f00, 0x007f},
6141 {0x193b, 0xe8c8, 0x0808, 0xf8f8},
6142 {0x4444, 0xc0c0, 0xa066, 0x22e0},
6144 static const DWORD content_v16u16[4][4] =
6146 {0x00000000, 0x7fff7fff, 0x88008000, 0x00000000},
6147 {0x00008000, 0x80000000, 0x7fff0000, 0x00007fff},
6148 {0x19993bbb, 0xe800c800, 0x08880888, 0xf800f800},
6149 {0x44444444, 0xc000c000, 0xa0006666, 0x2222e000},
6151 static const DWORD content_q8w8v8u8[4][4] =
6153 {0x00000000, 0xff7f7f7f, 0x7f008880, 0x817f0000},
6154 {0x10000080, 0x20008000, 0x30007f00, 0x4000007f},
6155 {0x5020193b, 0x6028e8c8, 0x70020808, 0x807ff8f8},
6156 {0x90414444, 0xa000c0c0, 0x8261a066, 0x834922e0},
6158 static const DWORD content_x8l8v8u8[4][4] =
6160 {0x00000000, 0x00ff7f7f, 0x00008880, 0x00ff0000},
6161 {0x00000080, 0x00008000, 0x00007f00, 0x0000007f},
6162 {0x0041193b, 0x0051e8c8, 0x00040808, 0x00fff8f8},
6163 {0x00824444, 0x0000c0c0, 0x00c2a066, 0x009222e0},
6165 static const USHORT content_l6v5u5[4][4] =
6167 {0x0000, 0xfdef, 0x0230, 0xfc00},
6168 {0x0010, 0x0200, 0x01e0, 0x000f},
6169 {0x4067, 0x53b9, 0x0421, 0xffff},
6170 {0x8108, 0x0318, 0xc28c, 0x909c},
6172 static const struct
6174 D3DFORMAT format;
6175 const char *name;
6176 const void *content;
6177 SIZE_T pixel_size;
6178 BOOL blue, alpha;
6179 unsigned int slop, slop_broken, alpha_broken;
6181 formats[] =
6183 {D3DFMT_V8U8, "D3DFMT_V8U8", content_v8u8, sizeof(WORD), FALSE, FALSE, 1, 0, FALSE},
6184 {D3DFMT_V16U16, "D3DFMT_V16U16", content_v16u16, sizeof(DWORD), FALSE, FALSE, 1, 0, FALSE},
6185 {D3DFMT_Q8W8V8U8, "D3DFMT_Q8W8V8U8", content_q8w8v8u8, sizeof(DWORD), TRUE, TRUE, 1, 0, TRUE },
6186 {D3DFMT_X8L8V8U8, "D3DFMT_X8L8V8U8", content_x8l8v8u8, sizeof(DWORD), TRUE, FALSE, 1, 0, FALSE},
6187 {D3DFMT_L6V5U5, "D3DFMT_L6V5U5", content_l6v5u5, sizeof(WORD), TRUE, FALSE, 4, 7, FALSE},
6189 static const struct
6191 D3DPOOL pool;
6192 UINT width;
6194 tests[] =
6196 {D3DPOOL_SYSTEMMEM, 4},
6197 {D3DPOOL_SYSTEMMEM, 1},
6198 {D3DPOOL_MANAGED, 4},
6199 {D3DPOOL_MANAGED, 1},
6201 static const DWORD shader_code[] =
6203 0xffff0101, /* ps_1_1 */
6204 0x00000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, /* def c0, 0.5, 0.5, 0,5, 0,5 */
6205 0x00000042, 0xb00f0000, /* tex t0 */
6206 0x00000004, 0x800f0000, 0xb0e40000, 0xa0e40000, 0xa0e40000, /* mad r0, t0, c0, c0 */
6207 0x0000ffff /* end */
6209 static const DWORD shader_code_alpha[] =
6211 /* The idea of this shader is to replicate the alpha value in .rg, and set
6212 * blue to 1.0 iff the alpha value is < -1.0 and 0.0 otherwise. */
6213 0xffff0101, /* ps_1_1 */
6214 0x00000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, /* def c0, 0.5, 0.5, 0.5, 0.5 */
6215 0x00000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0 */
6216 0x00000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c2, 0.0, 0.0, 1.0, 0.0 */
6217 0x00000042, 0xb00f0000, /* tex t0 */
6218 0x00000004, 0x80070000, 0xb0ff0000, 0xa0e40000, 0xa0e40000, /* mad r0.rgb, t0.a, c0, c0 */
6219 0x00000003, 0x80080000, 0xb1ff0000, 0xa0e40000, /* sub r0.a, -t0.a, c0 */
6220 0x00000050, 0x80080000, 0x80ff0000, 0xa0ff0001, 0xa0ff0002, /* cnd r0.a, r0.a, c1.a, c2.a */
6221 0x00000005, 0x80070001, 0xa0e40001, 0x80e40000, /* mul r1.rgb, c1, r0 */
6222 0x00000004, 0x80070000, 0x80ff0000, 0xa0e40002, 0x80e40001, /* mad r0.rgb, r0.a, c2, r1 */
6223 0x0000ffff /* end */
6225 static const struct
6227 struct vec3 position;
6228 struct vec2 texcrd;
6230 quad[] =
6232 /* Flip the y coordinate to make the input and
6233 * output arrays easier to compare. */
6234 {{ -1.0f, -1.0f, 0.0f}, { 0.0f, 1.0f}},
6235 {{ -1.0f, 1.0f, 0.0f}, { 0.0f, 0.0f}},
6236 {{ 1.0f, -1.0f, 0.0f}, { 1.0f, 1.0f}},
6237 {{ 1.0f, 1.0f, 0.0f}, { 1.0f, 0.0f}},
6239 static const D3DCOLOR expected_alpha[4][4] =
6241 {0x00808000, 0x007f7f00, 0x00ffff00, 0x00000000},
6242 {0x00909000, 0x00a0a000, 0x00b0b000, 0x00c0c000},
6243 {0x00d0d000, 0x00e0e000, 0x00f0f000, 0x00000000},
6244 {0x00101000, 0x00202000, 0x00010100, 0x00020200},
6246 static const BOOL alpha_broken[4][4] =
6248 {FALSE, FALSE, FALSE, FALSE},
6249 {FALSE, FALSE, FALSE, FALSE},
6250 {FALSE, FALSE, FALSE, TRUE },
6251 {FALSE, FALSE, FALSE, FALSE},
6253 static const D3DCOLOR expected_colors[4][4] =
6255 {0x00808080, 0x00fefeff, 0x00010780, 0x008080ff},
6256 {0x00018080, 0x00800180, 0x0080fe80, 0x00fe8080},
6257 {0x00ba98a0, 0x004767a8, 0x00888881, 0x007878ff},
6258 {0x00c3c3c0, 0x003f3f80, 0x00e51fe1, 0x005fa2c8},
6260 D3DCOLOR expected_color;
6262 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
6263 0, 0, 640, 480, NULL, NULL, NULL, NULL);
6264 d3d = Direct3DCreate8(D3D_SDK_VERSION);
6265 ok(!!d3d, "Failed to create a D3D object.\n");
6267 if (!(device = create_device(d3d, window, window, TRUE)))
6269 skip("Failed to create a D3D device, skipping tests.\n");
6270 IDirect3D8_Release(d3d);
6271 DestroyWindow(window);
6272 return;
6275 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
6276 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
6278 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 1))
6280 skip("Pixel shaders not supported, skipping converted format test.\n");
6281 goto done;
6284 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
6285 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6286 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX1);
6287 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
6288 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code, &shader);
6289 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
6290 hr = IDirect3DDevice8_CreatePixelShader(device, shader_code_alpha, &shader_alpha);
6291 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
6293 for (i = 0; i < sizeof(formats) / sizeof(*formats); i++)
6295 hr = IDirect3D8_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
6296 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, formats[i].format);
6297 if (FAILED(hr))
6299 skip("Format %s not supported, skipping.\n", formats[i].name);
6300 continue;
6303 for (j = 0; j < sizeof(tests) / sizeof(*tests); j++)
6305 texture_sysmem = NULL;
6306 hr = IDirect3DDevice8_CreateTexture(device, tests[j].width, 4, 1, 0,
6307 formats[i].format, tests[j].pool, &texture);
6308 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
6310 hr = IDirect3DTexture8_LockRect(texture, 0, &locked_rect, NULL, 0);
6311 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
6312 for (y = 0; y < 4; y++)
6314 memcpy((char *)locked_rect.pBits + y * locked_rect.Pitch,
6315 (char *)formats[i].content + y * 4 * formats[i].pixel_size,
6316 tests[j].width * formats[i].pixel_size);
6318 hr = IDirect3DTexture8_UnlockRect(texture, 0);
6319 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
6321 if (tests[j].pool == D3DPOOL_SYSTEMMEM)
6323 texture_sysmem = texture;
6324 hr = IDirect3DDevice8_CreateTexture(device, tests[j].width, 4, 1, 0,
6325 formats[i].format, D3DPOOL_DEFAULT, &texture);
6326 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
6328 hr = IDirect3DDevice8_UpdateTexture(device, (IDirect3DBaseTexture8 *)texture_sysmem,
6329 (IDirect3DBaseTexture8 *)texture);
6330 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
6331 IDirect3DTexture8_Release(texture_sysmem);
6334 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture);
6335 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
6336 hr = IDirect3DDevice8_SetPixelShader(device, shader_alpha);
6337 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6339 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00330033, 0.0f, 0);
6340 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
6341 hr = IDirect3DDevice8_BeginScene(device);
6342 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6343 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(*quad));
6344 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6345 hr = IDirect3DDevice8_EndScene(device);
6346 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6348 for (y = 0; y < 4; y++)
6350 for (x = 0; x < tests[j].width; x++)
6352 BOOL r200_broken = formats[i].alpha_broken && alpha_broken[y][x];
6353 if (formats[i].alpha)
6354 expected_color = expected_alpha[y][x];
6355 else
6356 expected_color = 0x00ffff00;
6358 color = getPixelColor(device, 80 + 160 * x, 60 + 120 * y);
6359 ok(color_match(color, expected_color, 1) || broken(r200_broken),
6360 "Expected color 0x%08x, got 0x%08x, format %s, location %ux%u.\n",
6361 expected_color, color, formats[i].name, x, y);
6364 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
6365 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
6367 hr = IDirect3DDevice8_SetPixelShader(device, shader);
6368 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6370 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00330033, 0.0f, 0);
6371 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
6372 hr = IDirect3DDevice8_BeginScene(device);
6373 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6374 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(*quad));
6375 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6376 hr = IDirect3DDevice8_EndScene(device);
6377 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6379 for (y = 0; y < 4; y++)
6381 for (x = 0; x < tests[j].width; x++)
6383 expected_color = expected_colors[y][x];
6384 if (!formats[i].blue)
6385 expected_color |= 0x000000ff;
6387 color = getPixelColor(device, 80 + 160 * x, 60 + 120 * y);
6388 ok(color_match(color, expected_color, formats[i].slop)
6389 || broken(color_match(color, expected_color, formats[i].slop_broken)),
6390 "Expected color 0x%08x, got 0x%08x, format %s, location %ux%u.\n",
6391 expected_color, color, formats[i].name, x, y);
6394 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
6395 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
6397 IDirect3DTexture8_Release(texture);
6401 IDirect3DDevice8_DeletePixelShader(device, shader);
6402 IDirect3DDevice8_DeletePixelShader(device, shader_alpha);
6404 done:
6405 refcount = IDirect3DDevice8_Release(device);
6406 ok(!refcount, "Device has %u references left.\n", refcount);
6407 IDirect3D8_Release(d3d);
6408 DestroyWindow(window);
6411 static void test_updatetexture(void)
6413 IDirect3DDevice8 *device;
6414 IDirect3D8 *d3d;
6415 HWND window;
6416 HRESULT hr;
6417 IDirect3DBaseTexture8 *src, *dst;
6418 unsigned int t, i, f, l, x, y, z;
6419 D3DLOCKED_RECT locked_rect;
6420 D3DLOCKED_BOX locked_box;
6421 ULONG refcount;
6422 D3DCAPS8 caps;
6423 D3DCOLOR color;
6424 BOOL ati2n_supported, do_visual_test;
6425 static const struct
6427 struct vec3 pos;
6428 struct vec2 texcoord;
6430 quad[] =
6432 {{-1.0f, -1.0f, 0.0f}, {0.0f, 1.0f}},
6433 {{-1.0f, 1.0f, 0.0f}, {0.0f, 0.0f}},
6434 {{ 1.0f, -1.0f, 0.0f}, {1.0f, 1.0f}},
6435 {{ 1.0f, 1.0f, 0.0f}, {1.0f, 0.0f}},
6437 static const struct
6439 struct vec3 pos;
6440 struct vec3 texcoord;
6442 quad_cube_tex[] =
6444 {{-1.0f, -1.0f, 0.0f}, {1.0f, -0.5f, 0.5f}},
6445 {{-1.0f, 1.0f, 0.0f}, {1.0f, 0.5f, 0.5f}},
6446 {{ 1.0f, -1.0f, 0.0f}, {1.0f, -0.5f, -0.5f}},
6447 {{ 1.0f, 1.0f, 0.0f}, {1.0f, 0.5f, -0.5f}},
6449 static const struct
6451 UINT src_width, src_height;
6452 UINT dst_width, dst_height;
6453 UINT src_levels, dst_levels;
6454 D3DFORMAT src_format, dst_format;
6455 BOOL broken;
6457 tests[] =
6459 {8, 8, 8, 8, 0, 0, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 0 */
6460 {8, 8, 8, 8, 4, 4, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 1 */
6461 {8, 8, 8, 8, 2, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 2 */
6462 {8, 8, 8, 8, 1, 1, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 3 */
6463 {8, 8, 8, 8, 4, 0, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 4 */
6464 {8, 8, 2, 2, 4, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 5 */
6465 /* The WARP renderer doesn't handle these cases correctly. */
6466 {8, 8, 8, 8, 4, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, TRUE}, /* 6 */
6467 {8, 8, 4, 4, 4, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, TRUE}, /* 7 */
6468 /* Not clear what happens here on Windows, it doesn't make much sense
6469 * though (on Nvidia it seems to upload the 4x4 surface into the 7x7
6470 * one or something like that). */
6471 /* {8, 8, 7, 7, 4, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, */
6472 {8, 8, 8, 8, 1, 4, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 8 */
6473 {4, 4, 8, 8, 1, 1, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 9 */
6474 /* This one causes weird behavior on Windows (it probably writes out
6475 * of the texture memory). */
6476 /* {8, 8, 4, 4, 1, 1, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, */
6477 {8, 4, 4, 2, 4, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 10 */
6478 {8, 4, 2, 4, 4, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 11 */
6479 {8, 8, 8, 8, 4, 4, D3DFMT_A8R8G8B8, D3DFMT_X8R8G8B8, FALSE}, /* 12 */
6480 {8, 8, 8, 8, 4, 4, D3DFMT_X8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 13 */
6481 /* The data is converted correctly on AMD, on Nvidia nothing happens
6482 * (it draws a black quad). */
6483 {8, 8, 8, 8, 4, 4, D3DFMT_A8R8G8B8, D3DFMT_R5G6B5, TRUE}, /* 14 */
6484 /* This one doesn't seem to give the expected results on AMD. */
6485 /* {8, 8, 8, 8, 4, 4, D3DFMT_A8R8G8B8, D3DFMT_Q8W8V8U8, FALSE}, */
6486 {8, 8, 8, 8, 4, 4, MAKEFOURCC('A','T','I','2'), MAKEFOURCC('A','T','I','2'), FALSE}, /* 15 */
6487 {8, 8, 8, 8, 4, 2, MAKEFOURCC('A','T','I','2'), MAKEFOURCC('A','T','I','2'), FALSE}, /* 16 */
6488 {8, 8, 2, 2, 4, 2, MAKEFOURCC('A','T','I','2'), MAKEFOURCC('A','T','I','2'), FALSE}, /* 17 */
6490 static const struct
6492 D3DRESOURCETYPE type;
6493 DWORD fvf;
6494 const void *quad;
6495 unsigned int vertex_size;
6496 DWORD cap;
6497 const char *name;
6499 texture_types[] =
6501 {D3DRTYPE_TEXTURE, D3DFVF_XYZ | D3DFVF_TEX1,
6502 quad, sizeof(*quad), D3DPTEXTURECAPS_MIPMAP, "2D mipmapped"},
6504 {D3DRTYPE_CUBETEXTURE, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE3(0),
6505 quad_cube_tex, sizeof(*quad_cube_tex), D3DPTEXTURECAPS_CUBEMAP, "Cube"},
6507 {D3DRTYPE_VOLUMETEXTURE, D3DFVF_XYZ | D3DFVF_TEX1,
6508 quad, sizeof(*quad), D3DPTEXTURECAPS_VOLUMEMAP, "Volume"}
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 IDirect3D8_Release(d3d);
6519 DestroyWindow(window);
6520 return;
6523 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
6524 ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
6526 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR);
6527 ok(SUCCEEDED(hr), "Failed to set texture filtering state, hr %#x.\n", hr);
6528 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP);
6529 ok(SUCCEEDED(hr), "Failed to set texture filtering state, hr %#x.\n", hr);
6530 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP);
6531 ok(SUCCEEDED(hr), "Failed to set texture filtering state, hr %#x.\n", hr);
6532 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_ADDRESSW, D3DTADDRESS_CLAMP);
6533 ok(SUCCEEDED(hr), "Failed to set texture filtering state, hr %#x.\n", hr);
6534 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6535 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6536 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
6537 ok(hr == D3D_OK, "Failed to set texture stage state, hr %#x.\n", hr);
6538 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
6539 ok(hr == D3D_OK, "Failed to set texture stage state, hr %#x.\n", hr);
6541 for (t = 0; t < sizeof(texture_types) / sizeof(*texture_types); ++t)
6543 if (!(caps.TextureCaps & texture_types[t].cap))
6545 skip("%s textures not supported, skipping some tests.\n", texture_types[t].name);
6546 continue;
6549 if (FAILED(IDirect3D8_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
6550 D3DFMT_X8R8G8B8, 0, texture_types[t].type, MAKEFOURCC('A','T','I','2'))))
6552 skip("%s ATI2N textures are not supported, skipping some tests.\n", texture_types[t].name);
6553 ati2n_supported = FALSE;
6555 else
6557 ati2n_supported = TRUE;
6560 hr = IDirect3DDevice8_SetVertexShader(device, texture_types[t].fvf);
6561 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
6563 for (i = 0; i < sizeof(tests) / sizeof(*tests); ++i)
6565 if (tests[i].src_format == MAKEFOURCC('A','T','I','2') && !ati2n_supported)
6566 continue;
6568 switch (texture_types[t].type)
6570 case D3DRTYPE_TEXTURE:
6571 hr = IDirect3DDevice8_CreateTexture(device,
6572 tests[i].src_width, tests[i].src_height,
6573 tests[i].src_levels, 0, tests[i].src_format, D3DPOOL_SYSTEMMEM,
6574 (IDirect3DTexture8 **)&src);
6575 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x, case %u, %u.\n", hr, t, i);
6576 hr = IDirect3DDevice8_CreateTexture(device,
6577 tests[i].dst_width, tests[i].dst_height,
6578 tests[i].dst_levels, 0, tests[i].dst_format, D3DPOOL_DEFAULT,
6579 (IDirect3DTexture8 **)&dst);
6580 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x, case %u, %u.\n", hr, t, i);
6581 break;
6582 case D3DRTYPE_CUBETEXTURE:
6583 hr = IDirect3DDevice8_CreateCubeTexture(device,
6584 tests[i].src_width,
6585 tests[i].src_levels, 0, tests[i].src_format, D3DPOOL_SYSTEMMEM,
6586 (IDirect3DCubeTexture8 **)&src);
6587 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x, case %u, %u.\n", hr, t, i);
6588 hr = IDirect3DDevice8_CreateCubeTexture(device,
6589 tests[i].dst_width,
6590 tests[i].dst_levels, 0, tests[i].dst_format, D3DPOOL_DEFAULT,
6591 (IDirect3DCubeTexture8 **)&dst);
6592 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x, case %u, %u.\n", hr, t, i);
6593 break;
6594 case D3DRTYPE_VOLUMETEXTURE:
6595 hr = IDirect3DDevice8_CreateVolumeTexture(device,
6596 tests[i].src_width, tests[i].src_height, tests[i].src_width,
6597 tests[i].src_levels, 0, tests[i].src_format, D3DPOOL_SYSTEMMEM,
6598 (IDirect3DVolumeTexture8 **)&src);
6599 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x, case %u, %u.\n", hr, t, i);
6600 hr = IDirect3DDevice8_CreateVolumeTexture(device,
6601 tests[i].dst_width, tests[i].dst_height, tests[i].dst_width,
6602 tests[i].dst_levels, 0, tests[i].dst_format, D3DPOOL_DEFAULT,
6603 (IDirect3DVolumeTexture8 **)&dst);
6604 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x, case %u, %u.\n", hr, t, i);
6605 break;
6606 default:
6607 trace("Unexpected resource type.\n");
6610 /* Skip the visual part of the test for ATI2N (laziness) and cases that
6611 * give a different (and unlikely to be useful) result. */
6612 do_visual_test = (tests[i].src_format == D3DFMT_A8R8G8B8 || tests[i].src_format == D3DFMT_X8R8G8B8)
6613 && tests[i].src_levels != 0
6614 && tests[i].src_width >= tests[i].dst_width && tests[i].src_height >= tests[i].dst_height
6615 && !(tests[i].src_width > tests[i].src_height && tests[i].dst_width < tests[i].dst_height);
6617 if (do_visual_test)
6619 DWORD *ptr = NULL;
6620 unsigned int width, height, depth, row_pitch = 0, slice_pitch = 0;
6622 for (f = 0; f < (texture_types[t].type == D3DRTYPE_CUBETEXTURE ? 6 : 1); ++f)
6624 width = tests[i].src_width;
6625 height = texture_types[t].type != D3DRTYPE_CUBETEXTURE ? tests[i].src_height : tests[i].src_width;
6626 depth = texture_types[t].type == D3DRTYPE_VOLUMETEXTURE ? width : 1;
6628 for (l = 0; l < tests[i].src_levels; ++l)
6630 switch (texture_types[t].type)
6632 case D3DRTYPE_TEXTURE:
6633 hr = IDirect3DTexture8_LockRect((IDirect3DTexture8 *)src,
6634 l, &locked_rect, NULL, 0);
6635 ptr = locked_rect.pBits;
6636 row_pitch = locked_rect.Pitch / sizeof(*ptr);
6637 break;
6638 case D3DRTYPE_CUBETEXTURE:
6639 hr = IDirect3DCubeTexture8_LockRect((IDirect3DCubeTexture8 *)src,
6640 f, l, &locked_rect, NULL, 0);
6641 ptr = locked_rect.pBits;
6642 row_pitch = locked_rect.Pitch / sizeof(*ptr);
6643 break;
6644 case D3DRTYPE_VOLUMETEXTURE:
6645 hr = IDirect3DVolumeTexture8_LockBox((IDirect3DVolumeTexture8 *)src,
6646 l, &locked_box, NULL, 0);
6647 ptr = locked_box.pBits;
6648 row_pitch = locked_box.RowPitch / sizeof(*ptr);
6649 slice_pitch = locked_box.SlicePitch / sizeof(*ptr);
6650 break;
6651 default:
6652 trace("Unexpected resource type.\n");
6654 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
6656 for (z = 0; z < depth; ++z)
6658 for (y = 0; y < height; ++y)
6660 for (x = 0; x < width; ++x)
6662 ptr[z * slice_pitch + y * row_pitch + x] = 0xff000000
6663 | (DWORD)(x / (width - 1.0f) * 255.0f) << 16
6664 | (DWORD)(y / (height - 1.0f) * 255.0f) << 8;
6669 switch (texture_types[t].type)
6671 case D3DRTYPE_TEXTURE:
6672 hr = IDirect3DTexture8_UnlockRect((IDirect3DTexture8 *)src, l);
6673 break;
6674 case D3DRTYPE_CUBETEXTURE:
6675 hr = IDirect3DCubeTexture8_UnlockRect((IDirect3DCubeTexture8 *)src, f, l);
6676 break;
6677 case D3DRTYPE_VOLUMETEXTURE:
6678 hr = IDirect3DVolumeTexture8_UnlockBox((IDirect3DVolumeTexture8 *)src, l);
6679 break;
6680 default:
6681 trace("Unexpected resource type.\n");
6683 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
6685 width >>= 1;
6686 if (!width)
6687 width = 1;
6688 height >>= 1;
6689 if (!height)
6690 height = 1;
6691 depth >>= 1;
6692 if (!depth)
6693 depth = 1;
6698 hr = IDirect3DDevice8_UpdateTexture(device, src, dst);
6699 if (FAILED(hr))
6701 todo_wine ok(SUCCEEDED(hr), "Failed to update texture, hr %#x, case %u, %u.\n", hr, t, i);
6702 IDirect3DBaseTexture8_Release(src);
6703 IDirect3DBaseTexture8_Release(dst);
6704 continue;
6706 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x, case %u, %u.\n", hr, t, i);
6708 if (do_visual_test)
6710 hr = IDirect3DDevice8_SetTexture(device, 0, dst);
6711 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
6713 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 1.0f, 0);
6714 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
6716 hr = IDirect3DDevice8_BeginScene(device);
6717 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6718 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,
6719 texture_types[t].quad, texture_types[t].vertex_size);
6720 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6721 hr = IDirect3DDevice8_EndScene(device);
6722 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6724 color = getPixelColor(device, 320, 240);
6725 ok (color_match(color, 0x007f7f00, 2) || broken(tests[i].broken)
6726 || broken(color == 0x00adbeef), /* WARP device often just breaks down. */
6727 "Got unexpected color 0x%08x, case %u, %u.\n", color, t, i);
6730 IDirect3DBaseTexture8_Release(src);
6731 IDirect3DBaseTexture8_Release(dst);
6735 refcount = IDirect3DDevice8_Release(device);
6736 ok(!refcount, "Device has %u references left.\n", refcount);
6737 IDirect3D8_Release(d3d);
6738 DestroyWindow(window);
6741 static BOOL point_match(IDirect3DDevice8 *device, UINT x, UINT y, UINT r)
6743 D3DCOLOR color;
6745 color = D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff);
6746 if (!color_match(getPixelColor(device, x + r, y), color, 1))
6747 return FALSE;
6748 if (!color_match(getPixelColor(device, x - r, y), color, 1))
6749 return FALSE;
6750 if (!color_match(getPixelColor(device, x, y + r), color, 1))
6751 return FALSE;
6752 if (!color_match(getPixelColor(device, x, y - r), color, 1))
6753 return FALSE;
6755 ++r;
6756 color = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff);
6757 if (!color_match(getPixelColor(device, x + r, y), color, 1))
6758 return FALSE;
6759 if (!color_match(getPixelColor(device, x - r, y), color, 1))
6760 return FALSE;
6761 if (!color_match(getPixelColor(device, x, y + r), color, 1))
6762 return FALSE;
6763 if (!color_match(getPixelColor(device, x, y - r), color, 1))
6764 return FALSE;
6766 return TRUE;
6769 static void test_pointsize(void)
6771 static const float a = 0.5f, b = 0.5f, c = 0.5f;
6772 float ptsize, ptsizemax_orig, ptsizemin_orig;
6773 IDirect3DSurface8 *rt, *backbuffer, *depthstencil;
6774 IDirect3DTexture8 *tex1, *tex2;
6775 IDirect3DDevice8 *device;
6776 DWORD vs, ps;
6777 D3DLOCKED_RECT lr;
6778 IDirect3D8 *d3d;
6779 D3DCOLOR color;
6780 ULONG refcount;
6781 D3DCAPS8 caps;
6782 HWND window;
6783 HRESULT hr;
6784 unsigned int i, j;
6786 static const DWORD tex1_data[4] = {0x00ff0000, 0x00ff0000, 0x00000000, 0x00000000};
6787 static const DWORD tex2_data[4] = {0x00000000, 0x0000ff00, 0x00000000, 0x0000ff00};
6788 static const float vertices[] =
6790 64.0f, 64.0f, 0.1f,
6791 128.0f, 64.0f, 0.1f,
6792 192.0f, 64.0f, 0.1f,
6793 256.0f, 64.0f, 0.1f,
6794 320.0f, 64.0f, 0.1f,
6795 384.0f, 64.0f, 0.1f,
6796 448.0f, 64.0f, 0.1f,
6797 512.0f, 64.0f, 0.1f,
6799 static const struct
6801 float x, y, z;
6802 float point_size;
6804 vertex_pointsize = {64.0f, 64.0f, 0.1f, 48.0f},
6805 vertex_pointsize_scaled = {64.0f, 64.0f, 0.1f, 24.0f},
6806 vertex_pointsize_zero = {64.0f, 64.0f, 0.1f, 0.0f};
6807 static const DWORD decl[] =
6809 D3DVSD_STREAM(0),
6810 D3DVSD_REG(0, D3DVSDT_FLOAT3), /* position */
6811 D3DVSD_END()
6813 decl_psize[] =
6815 D3DVSD_STREAM(0),
6816 D3DVSD_REG(0, D3DVSDT_FLOAT3), /* position, v0 */
6817 D3DVSD_REG(1, D3DVSDT_FLOAT1), /* point size, v1 */
6818 D3DVSD_END()
6820 static const DWORD vshader_code[] =
6822 0xfffe0101, /* vs_1_1 */
6823 0x00000005, 0x800f0000, 0x90000000, 0xa0e40000, /* mul r0, v0.x, c0 */
6824 0x00000004, 0x800f0000, 0x90550000, 0xa0e40001, 0x80e40000, /* mad r0, v0.y, c1, r0 */
6825 0x00000004, 0x800f0000, 0x90aa0000, 0xa0e40002, 0x80e40000, /* mad r0, v0.z, c2, r0 */
6826 0x00000004, 0xc00f0000, 0x90ff0000, 0xa0e40003, 0x80e40000, /* mad oPos, v0.w, c3, r0 */
6827 0x0000ffff
6829 static const DWORD vshader_psize_code[] =
6831 0xfffe0101, /* vs_1_1 */
6832 0x00000005, 0x800f0000, 0x90000000, 0xa0e40000, /* mul r0, v0.x, c0 */
6833 0x00000004, 0x800f0000, 0x90550000, 0xa0e40001, 0x80e40000, /* mad r0, v0.y, c1, r0 */
6834 0x00000004, 0x800f0000, 0x90aa0000, 0xa0e40002, 0x80e40000, /* mad r0, v0.z, c2, r0 */
6835 0x00000004, 0xc00f0000, 0x90ff0000, 0xa0e40003, 0x80e40000, /* mad oPos, v0.w, c3, r0 */
6836 0x00000001, 0xc00f0002, 0x90000001, /* mov oPts, v1.x */
6837 0x0000ffff
6839 static const DWORD pshader_code[] =
6841 0xffff0101, /* ps_1_1 */
6842 0x00000042, 0xb00f0000, /* tex t0 */
6843 0x00000042, 0xb00f0001, /* tex t1 */
6844 0x00000002, 0x800f0000, 0xb0e40000, 0xb0e40001, /* add r0, t0, t1 */
6845 0x0000ffff
6847 static const struct test_shader
6849 DWORD version;
6850 const DWORD *code;
6852 novs = {0, NULL},
6853 vs1 = {D3DVS_VERSION(1, 1), vshader_code},
6854 vs1_psize = {D3DVS_VERSION(1, 1), vshader_psize_code},
6855 nops = {0, NULL},
6856 ps1 = {D3DPS_VERSION(1, 1), pshader_code};
6857 static const struct
6859 const DWORD *decl;
6860 const struct test_shader *vs;
6861 const struct test_shader *ps;
6862 DWORD accepted_fvf;
6863 unsigned int nonscaled_size, scaled_size;
6865 test_setups[] =
6867 {NULL, &novs, &nops, D3DFVF_XYZ, 32, 62},
6868 {decl, &vs1, &ps1, D3DFVF_XYZ, 32, 32},
6869 {NULL, &novs, &ps1, D3DFVF_XYZ, 32, 62},
6870 {decl, &vs1, &nops, D3DFVF_XYZ, 32, 32},
6871 {NULL, &novs, &nops, D3DFVF_XYZ | D3DFVF_PSIZE, 48, 48},
6872 {decl_psize, &vs1_psize, &ps1, D3DFVF_XYZ | D3DFVF_PSIZE, 48, 24},
6874 static const struct
6876 BOOL zero_size;
6877 BOOL scale;
6878 BOOL override_min;
6879 DWORD fvf;
6880 const void *vertex_data;
6881 unsigned int vertex_size;
6883 tests[] =
6885 {FALSE, FALSE, FALSE, D3DFVF_XYZ, vertices, sizeof(float) * 3},
6886 {FALSE, TRUE, FALSE, D3DFVF_XYZ, vertices, sizeof(float) * 3},
6887 {FALSE, FALSE, TRUE, D3DFVF_XYZ, vertices, sizeof(float) * 3},
6888 {TRUE, FALSE, FALSE, D3DFVF_XYZ, vertices, sizeof(float) * 3},
6889 {FALSE, FALSE, FALSE, D3DFVF_XYZ | D3DFVF_PSIZE, &vertex_pointsize, sizeof(vertex_pointsize)},
6890 {FALSE, TRUE, FALSE, D3DFVF_XYZ | D3DFVF_PSIZE, &vertex_pointsize_scaled, sizeof(vertex_pointsize_scaled)},
6891 {FALSE, FALSE, TRUE, D3DFVF_XYZ | D3DFVF_PSIZE, &vertex_pointsize, sizeof(vertex_pointsize)},
6892 {TRUE, FALSE, FALSE, D3DFVF_XYZ | D3DFVF_PSIZE, &vertex_pointsize_zero, sizeof(vertex_pointsize_zero)},
6894 /* Transforms the coordinate system [-1.0;1.0]x[1.0;-1.0] to
6895 * [0.0;0.0]x[640.0;480.0]. Z is untouched. */
6896 D3DMATRIX matrix =
6898 2.0f / 640.0f, 0.0f, 0.0f, 0.0f,
6899 0.0f, -2.0f / 480.0f, 0.0f, 0.0f,
6900 0.0f, 0.0f, 1.0f, 0.0f,
6901 -1.0f, 1.0f, 0.0f, 1.0f,
6902 }}};
6904 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
6905 0, 0, 640, 480, NULL, NULL, NULL, NULL);
6906 d3d = Direct3DCreate8(D3D_SDK_VERSION);
6907 ok(!!d3d, "Failed to create a D3D object.\n");
6908 if (!(device = create_device(d3d, window, window, TRUE)))
6910 skip("Failed to create a D3D device, skipping tests.\n");
6911 goto done;
6914 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
6915 ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
6916 if (caps.MaxPointSize < 32.0f)
6918 skip("MaxPointSize %f < 32.0, skipping.\n", caps.MaxPointSize);
6919 IDirect3DDevice8_Release(device);
6920 goto done;
6923 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
6924 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
6925 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
6926 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
6927 hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, &matrix);
6928 ok(SUCCEEDED(hr), "Failed to set projection matrix, hr %#x.\n", hr);
6929 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ);
6930 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
6932 hr = IDirect3DDevice8_BeginScene(device);
6933 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6935 ptsize = 15.0f;
6936 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
6937 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6938 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
6939 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6941 ptsize = 31.0f;
6942 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
6943 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6944 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[3], sizeof(float) * 3);
6945 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6947 ptsize = 30.75f;
6948 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
6949 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6950 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[6], sizeof(float) * 3);
6951 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6953 if (caps.MaxPointSize >= 63.0f)
6955 ptsize = 63.0f;
6956 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
6957 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6958 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[9], sizeof(float) * 3);
6959 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6961 ptsize = 62.75f;
6962 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
6963 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6964 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[15], sizeof(float) * 3);
6965 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6968 ptsize = 1.0f;
6969 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
6970 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6971 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[12], sizeof(float) * 3);
6972 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6974 hr = IDirect3DDevice8_GetRenderState(device, D3DRS_POINTSIZE_MAX, (DWORD *)&ptsizemax_orig);
6975 ok(SUCCEEDED(hr), "Failed to get render state, hr %#x.\n", hr);
6976 hr = IDirect3DDevice8_GetRenderState(device, D3DRS_POINTSIZE_MIN, (DWORD *)&ptsizemin_orig);
6977 ok(SUCCEEDED(hr), "Failed to get render state, hr %#x.\n", hr);
6979 /* What happens if point scaling is disabled, and POINTSIZE_MAX < POINTSIZE? */
6980 ptsize = 15.0f;
6981 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
6982 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6983 ptsize = 1.0f;
6984 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE_MAX, *(DWORD *)&ptsize);
6985 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6986 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[18], sizeof(float) * 3);
6987 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6989 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE_MAX, *(DWORD *)&ptsizemax_orig);
6990 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6992 /* pointsize < pointsize_min < pointsize_max?
6993 * pointsize = 1.0, pointsize_min = 15.0, pointsize_max = default(usually 64.0) */
6994 ptsize = 1.0f;
6995 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
6996 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
6997 ptsize = 15.0f;
6998 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE_MIN, *(DWORD *)&ptsize);
6999 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
7000 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[21], sizeof(float) * 3);
7001 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7003 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE_MIN, *(DWORD *)&ptsizemin_orig);
7004 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
7006 hr = IDirect3DDevice8_EndScene(device);
7007 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7009 ok(point_match(device, 64, 64, 7), "point_match(64, 64, 7) failed, expected point size 15.\n");
7010 ok(point_match(device, 128, 64, 15), "point_match(128, 64, 15) failed, expected point size 31.\n");
7011 ok(point_match(device, 192, 64, 15), "point_match(192, 64, 15) failed, expected point size 31.\n");
7013 if (caps.MaxPointSize >= 63.0f)
7015 ok(point_match(device, 256, 64, 31), "point_match(256, 64, 31) failed, expected point size 63.\n");
7016 ok(point_match(device, 384, 64, 31), "point_match(384, 64, 31) failed, expected point size 63.\n");
7019 ok(point_match(device, 320, 64, 0), "point_match(320, 64, 0) failed, expected point size 1.\n");
7020 /* ptsize = 15, ptsize_max = 1 --> point has size 1 */
7021 ok(point_match(device, 448, 64, 0), "point_match(448, 64, 0) failed, expected point size 1.\n");
7022 /* ptsize = 1, ptsize_max = default(64), ptsize_min = 15 --> point has size 15 */
7023 ok(point_match(device, 512, 64, 7), "point_match(512, 64, 7) failed, expected point size 15.\n");
7025 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
7027 /* The following code tests point sprites with two textures, to see if each texture coordinate unit
7028 * generates texture coordinates for the point(result: Yes, it does)
7030 * However, not all GL implementations support point sprites(they need GL_ARB_point_sprite), but there
7031 * is no point sprite cap bit in d3d because native d3d software emulates point sprites. Until the
7032 * SW emulation is implemented in wined3d, this test will fail on GL drivers that does not support them.
7034 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
7035 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
7037 hr = IDirect3DDevice8_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex1);
7038 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
7039 hr = IDirect3DDevice8_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex2);
7040 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
7041 memset(&lr, 0, sizeof(lr));
7042 hr = IDirect3DTexture8_LockRect(tex1, 0, &lr, NULL, 0);
7043 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
7044 memcpy(lr.pBits, tex1_data, sizeof(tex1_data));
7045 hr = IDirect3DTexture8_UnlockRect(tex1, 0);
7046 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
7047 memset(&lr, 0, sizeof(lr));
7048 hr = IDirect3DTexture8_LockRect(tex2, 0, &lr, NULL, 0);
7049 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
7050 memcpy(lr.pBits, tex2_data, sizeof(tex2_data));
7051 hr = IDirect3DTexture8_UnlockRect(tex2, 0);
7052 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
7053 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)tex1);
7054 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
7055 hr = IDirect3DDevice8_SetTexture(device, 1, (IDirect3DBaseTexture8 *)tex2);
7056 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
7057 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7058 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
7059 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7060 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
7061 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
7062 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
7063 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7064 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
7065 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
7066 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
7068 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSPRITEENABLE, TRUE);
7069 ok(SUCCEEDED(hr), "Failed to enable point sprites, hr %#x.\n", hr);
7070 ptsize = 32.0f;
7071 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
7072 ok(SUCCEEDED(hr), "Failed to set point size, hr %#x.\n", hr);
7074 hr = IDirect3DDevice8_BeginScene(device);
7075 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7076 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
7077 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7078 hr = IDirect3DDevice8_EndScene(device);
7079 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7081 color = getPixelColor(device, 64 - 4, 64 - 4);
7082 ok(color == 0x00ff0000, "pSprite: Pixel (64 - 4),(64 - 4) has color 0x%08x, expected 0x00ff0000\n", color);
7083 color = getPixelColor(device, 64 - 4, 64 + 4);
7084 ok(color == 0x00000000, "pSprite: Pixel (64 - 4),(64 + 4) has color 0x%08x, expected 0x00000000\n", color);
7085 color = getPixelColor(device, 64 + 4, 64 + 4);
7086 ok(color == 0x0000ff00, "pSprite: Pixel (64 + 4),(64 + 4) has color 0x%08x, expected 0x0000ff00\n", color);
7087 color = getPixelColor(device, 64 + 4, 64 - 4);
7088 ok(color == 0x00ffff00, "pSprite: Pixel (64 + 4),(64 - 4) has color 0x%08x, expected 0x00ffff00\n", color);
7089 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
7091 U(matrix).m[0][0] = 1.0f / 64.0f;
7092 U(matrix).m[1][1] = -1.0f / 64.0f;
7093 hr = IDirect3DDevice8_SetTransform(device, D3DTS_PROJECTION, &matrix);
7094 ok(SUCCEEDED(hr), "Failed to set projection matrix, hr %#x.\n", hr);
7096 hr = IDirect3DDevice8_GetRenderTarget(device, &backbuffer);
7097 ok(SUCCEEDED(hr), "Failed to get backbuffer, hr %#x.\n", hr);
7098 hr = IDirect3DDevice8_GetDepthStencilSurface(device, &depthstencil);
7099 ok(SUCCEEDED(hr), "Failed to get depth / stencil buffer, hr %#x.\n", hr);
7101 hr = IDirect3DDevice8_CreateRenderTarget(device, 128, 128, D3DFMT_A8R8G8B8,
7102 D3DMULTISAMPLE_NONE, TRUE, &rt);
7103 ok(SUCCEEDED(hr), "Failed to create a render target, hr %#x.\n", hr);
7105 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSCALE_A, *(DWORD *)&a);
7106 ok(SUCCEEDED(hr), "Failed setting point scale attenuation coefficient, hr %#x.\n", hr);
7107 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSCALE_B, *(DWORD *)&b);
7108 ok(SUCCEEDED(hr), "Failed setting point scale attenuation coefficient, hr %#x.\n", hr);
7109 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSCALE_C, *(DWORD *)&c);
7110 ok(SUCCEEDED(hr), "Failed setting point scale attenuation coefficient, hr %#x.\n", hr);
7111 hr = IDirect3DDevice8_SetVertexShaderConstant(device, 0, &S(U(matrix))._11, 4);
7112 ok(SUCCEEDED(hr), "Failed to set vertex shader constants, hr %#x.\n", hr);
7114 if (caps.MaxPointSize < 63.0f)
7116 skip("MaxPointSize %f < 63.0, skipping some tests.\n", caps.MaxPointSize);
7117 goto cleanup;
7120 hr = IDirect3DDevice8_SetRenderTarget(device, rt, depthstencil);
7121 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
7123 for (i = 0; i < sizeof(test_setups) / sizeof(test_setups[0]); ++i)
7125 if (caps.VertexShaderVersion < test_setups[i].vs->version
7126 || caps.PixelShaderVersion < test_setups[i].ps->version)
7128 skip("Vertex / pixel shader version not supported, skipping test.\n");
7129 continue;
7131 if (test_setups[i].vs->code)
7133 hr = IDirect3DDevice8_CreateVertexShader(device, test_setups[i].decl, test_setups[i].vs->code, &vs, 0);
7134 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x (case %u).\n", hr, i);
7136 else
7138 vs = 0;
7140 if (test_setups[i].ps->code)
7142 hr = IDirect3DDevice8_CreatePixelShader(device, test_setups[i].ps->code, &ps);
7143 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x (case %u).\n", hr, i);
7145 else
7147 ps = 0;
7150 hr = IDirect3DDevice8_SetVertexShader(device, vs ? vs : test_setups[i].accepted_fvf);
7151 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
7152 hr = IDirect3DDevice8_SetPixelShader(device, ps);
7153 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
7155 for (j = 0; j < sizeof(tests) / sizeof(tests[0]); ++j)
7157 unsigned int size = tests[j].override_min ? 63 : tests[j].zero_size ? 0 : tests[j].scale
7158 ? test_setups[i].scaled_size : test_setups[i].nonscaled_size;
7160 if (test_setups[i].accepted_fvf != tests[j].fvf)
7161 continue;
7163 ptsize = tests[j].zero_size ? 0.0f : 32.0f;
7164 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
7165 ok(SUCCEEDED(hr), "Failed to set pointsize, hr %#x.\n", hr);
7167 ptsize = tests[j].override_min ? 63.0f : tests[j].zero_size ? 0.0f : ptsizemin_orig;
7168 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSIZE_MIN, *(DWORD *)&ptsize);
7169 ok(SUCCEEDED(hr), "Failed to set minimum pointsize, hr %#x.\n", hr);
7171 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_POINTSCALEENABLE, tests[j].scale);
7172 ok(SUCCEEDED(hr), "Failed setting point scale state, hr %#x.\n", hr);
7174 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
7175 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
7177 hr = IDirect3DDevice8_BeginScene(device);
7178 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7179 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1,
7180 tests[j].vertex_data, tests[j].vertex_size);
7181 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7182 hr = IDirect3DDevice8_EndScene(device);
7183 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7185 if (tests[j].zero_size)
7187 /* Technically 0 pointsize is undefined in OpenGL but in practice it seems like
7188 * it does the "useful" thing on all the drivers I tried. */
7189 /* On WARP it does draw some pixels, most of the time. */
7190 color = getPixelColor(device, 64, 64);
7191 ok(color_match(color, 0x0000ffff, 0)
7192 || broken(color_match(color, 0x00ff0000, 0))
7193 || broken(color_match(color, 0x00ffff00, 0))
7194 || broken(color_match(color, 0x00000000, 0))
7195 || broken(color_match(color, 0x0000ff00, 0)),
7196 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
7198 else
7200 color = getPixelColor(device, 64 - size / 2 + 1, 64 - size / 2 + 1);
7201 ok(color_match(color, 0x00ff0000, 0),
7202 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
7203 color = getPixelColor(device, 64 + size / 2 - 1, 64 - size / 2 + 1);
7204 ok(color_match(color, 0x00ffff00, 0),
7205 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
7206 color = getPixelColor(device, 64 - size / 2 + 1, 64 + size / 2 - 1);
7207 ok(color_match(color, 0x00000000, 0),
7208 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
7209 color = getPixelColor(device, 64 + size / 2 - 1, 64 + size / 2 - 1);
7210 ok(color_match(color, 0x0000ff00, 0),
7211 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
7213 color = getPixelColor(device, 64 - size / 2 - 1, 64 - size / 2 - 1);
7214 ok(color_match(color, 0x0000ffff, 0),
7215 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
7216 color = getPixelColor(device, 64 + size / 2 + 1, 64 - size / 2 - 1);
7217 ok(color_match(color, 0x0000ffff, 0),
7218 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
7219 color = getPixelColor(device, 64 - size / 2 - 1, 64 + size / 2 + 1);
7220 ok(color_match(color, 0x0000ffff, 0),
7221 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
7222 color = getPixelColor(device, 64 + size / 2 + 1, 64 + size / 2 + 1);
7223 ok(color_match(color, 0x0000ffff, 0),
7224 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
7227 IDirect3DDevice8_SetVertexShader(device, 0);
7228 IDirect3DDevice8_SetPixelShader(device, 0);
7229 if (vs)
7230 IDirect3DDevice8_DeleteVertexShader(device, vs);
7231 if (ps)
7232 IDirect3DDevice8_DeletePixelShader(device, ps);
7234 hr = IDirect3DDevice8_SetRenderTarget(device, backbuffer, depthstencil);
7235 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
7237 cleanup:
7238 IDirect3DSurface8_Release(backbuffer);
7239 IDirect3DSurface8_Release(depthstencil);
7240 IDirect3DSurface8_Release(rt);
7242 IDirect3DTexture8_Release(tex1);
7243 IDirect3DTexture8_Release(tex2);
7244 refcount = IDirect3DDevice8_Release(device);
7245 ok(!refcount, "Device has %u references left.\n", refcount);
7246 done:
7247 IDirect3D8_Release(d3d);
7248 DestroyWindow(window);
7251 static void test_multisample_mismatch(void)
7253 IDirect3DDevice8 *device;
7254 IDirect3D8 *d3d;
7255 HWND window;
7256 HRESULT hr;
7257 ULONG refcount;
7258 IDirect3DSurface8 *rt_multi, *ds;
7260 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
7261 0, 0, 640, 480, NULL, NULL, NULL, NULL);
7262 d3d = Direct3DCreate8(D3D_SDK_VERSION);
7263 ok(!!d3d, "Failed to create a D3D object.\n");
7264 if (FAILED(IDirect3D8_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
7265 D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES)))
7267 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping multisample mismatch test.\n");
7268 IDirect3D8_Release(d3d);
7269 return;
7272 if (!(device = create_device(d3d, window, window, TRUE)))
7274 skip("Failed to create a D3D device, skipping tests.\n");
7275 goto done;
7278 hr = IDirect3DDevice8_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
7279 D3DMULTISAMPLE_2_SAMPLES, FALSE, &rt_multi);
7280 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
7281 hr = IDirect3DDevice8_GetDepthStencilSurface(device, &ds);
7282 ok(SUCCEEDED(hr), "Failed to get original depth/stencil, hr %#x.\n", hr);
7284 hr = IDirect3DDevice8_SetRenderTarget(device, rt_multi, ds);
7285 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
7287 IDirect3DSurface8_Release(ds);
7288 IDirect3DSurface8_Release(rt_multi);
7290 refcount = IDirect3DDevice8_Release(device);
7291 ok(!refcount, "Device has %u references left.\n", refcount);
7292 done:
7293 IDirect3D8_Release(d3d);
7294 DestroyWindow(window);
7297 static void test_texcoordindex(void)
7299 static const D3DMATRIX mat =
7301 1.0f, 0.0f, 0.0f, 0.0f,
7302 0.0f, 0.0f, 0.0f, 0.0f,
7303 0.0f, 0.0f, 0.0f, 0.0f,
7304 0.0f, 0.0f, 0.0f, 0.0f,
7305 }}};
7306 static const struct
7308 struct vec3 pos;
7309 struct vec2 texcoord1;
7310 struct vec2 texcoord2;
7311 struct vec2 texcoord3;
7313 quad[] =
7315 {{-1.0f, -1.0f, 0.0f}, {0.0f, 1.0f}, {0.0f, 0.0f}, {1.0f, 1.0f}},
7316 {{-1.0f, 1.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 1.0f}, {1.0f, 0.0f}},
7317 {{ 1.0f, -1.0f, 0.0f}, {1.0f, 1.0f}, {1.0f, 0.0f}, {0.0f, 1.0f}},
7318 {{ 1.0f, 1.0f, 0.0f}, {1.0f, 0.0f}, {1.0f, 1.0f}, {0.0f, 0.0f}},
7320 IDirect3DDevice8 *device;
7321 IDirect3D8 *d3d;
7322 HWND window;
7323 HRESULT hr;
7324 IDirect3DTexture8 *texture1, *texture2;
7325 D3DLOCKED_RECT locked_rect;
7326 ULONG refcount;
7327 D3DCOLOR color;
7328 DWORD *ptr;
7330 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
7331 0, 0, 640, 480, NULL, NULL, NULL, NULL);
7332 d3d = Direct3DCreate8(D3D_SDK_VERSION);
7333 ok(!!d3d, "Failed to create a D3D object.\n");
7334 if (!(device = create_device(d3d, window, window, TRUE)))
7336 skip("Failed to create a D3D device, skipping tests.\n");
7337 IDirect3D8_Release(d3d);
7338 DestroyWindow(window);
7339 return;
7342 hr = IDirect3DDevice8_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture1);
7343 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
7344 hr = IDirect3DDevice8_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture2);
7345 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
7347 hr = IDirect3DTexture8_LockRect(texture1, 0, &locked_rect, NULL, D3DLOCK_DISCARD);
7348 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
7349 ptr = locked_rect.pBits;
7350 ptr[0] = 0xff000000;
7351 ptr[1] = 0xff00ff00;
7352 ptr[2] = 0xff0000ff;
7353 ptr[3] = 0xff00ffff;
7354 hr = IDirect3DTexture8_UnlockRect(texture1, 0);
7355 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
7357 hr = IDirect3DTexture8_LockRect(texture2, 0, &locked_rect, NULL, D3DLOCK_DISCARD);
7358 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
7359 ptr = locked_rect.pBits;
7360 ptr[0] = 0xff000000;
7361 ptr[1] = 0xff0000ff;
7362 ptr[2] = 0xffff0000;
7363 ptr[3] = 0xffff00ff;
7364 hr = IDirect3DTexture8_UnlockRect(texture2, 0);
7365 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
7367 hr = IDirect3DDevice8_SetTexture(device, 0, (IDirect3DBaseTexture8 *)texture1);
7368 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
7369 hr = IDirect3DDevice8_SetTexture(device, 1, (IDirect3DBaseTexture8 *)texture2);
7370 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
7371 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_TEX3);
7372 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
7373 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
7374 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
7375 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
7376 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
7377 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7378 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
7379 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
7380 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
7381 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
7382 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
7383 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
7384 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
7385 hr = IDirect3DDevice8_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
7386 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
7388 hr = IDirect3DDevice8_SetTextureStageState(device, 0, D3DTSS_TEXCOORDINDEX, 1);
7389 ok(SUCCEEDED(hr), "Failed to set texcoord index, hr %#x.\n", hr);
7390 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_TEXCOORDINDEX, 0);
7391 ok(SUCCEEDED(hr), "Failed to set texcoord index, hr %#x.\n", hr);
7393 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 1.0f, 0);
7394 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
7396 hr = IDirect3DDevice8_BeginScene(device);
7397 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7398 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
7399 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7400 hr = IDirect3DDevice8_EndScene(device);
7401 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7403 color = getPixelColor(device, 160, 120);
7404 ok(color_match(color, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color);
7405 color = getPixelColor(device, 480, 120);
7406 ok(color_match(color, 0x0000ffff, 2), "Got unexpected color 0x%08x.\n", color);
7407 color = getPixelColor(device, 160, 360);
7408 ok(color_match(color, 0x00ff0000, 2), "Got unexpected color 0x%08x.\n", color);
7409 color = getPixelColor(device, 480, 360);
7410 ok(color_match(color, 0x00ffffff, 2), "Got unexpected color 0x%08x.\n", color);
7412 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
7413 ok(SUCCEEDED(hr), "Failed to set texture transform flags, hr %#x.\n", hr);
7414 hr = IDirect3DDevice8_SetTransform(device, D3DTS_TEXTURE1, &mat);
7415 ok(SUCCEEDED(hr), "Failed to set transformation matrix, hr %#x.\n", hr);
7417 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 1.0f, 0);
7418 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
7420 hr = IDirect3DDevice8_BeginScene(device);
7421 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7422 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
7423 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7424 hr = IDirect3DDevice8_EndScene(device);
7425 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7427 color = getPixelColor(device, 160, 120);
7428 ok(color_match(color, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color);
7429 color = getPixelColor(device, 480, 120);
7430 ok(color_match(color, 0x0000ffff, 2), "Got unexpected color 0x%08x.\n", color);
7431 color = getPixelColor(device, 160, 360);
7432 ok(color_match(color, 0x00000000, 2), "Got unexpected color 0x%08x.\n", color);
7433 color = getPixelColor(device, 480, 360);
7434 ok(color_match(color, 0x0000ffff, 2), "Got unexpected color 0x%08x.\n", color);
7436 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
7437 ok(SUCCEEDED(hr), "Failed to set texture transform flags, hr %#x.\n", hr);
7438 hr = IDirect3DDevice8_SetTextureStageState(device, 1, D3DTSS_TEXCOORDINDEX, 2);
7439 ok(SUCCEEDED(hr), "Failed to set texcoord index, hr %#x.\n", hr);
7441 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 1.0f, 0);
7442 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
7444 hr = IDirect3DDevice8_BeginScene(device);
7445 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7446 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
7447 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7448 hr = IDirect3DDevice8_EndScene(device);
7449 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7451 color = getPixelColor(device, 160, 120);
7452 ok(color_match(color, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color);
7453 color = getPixelColor(device, 480, 120);
7454 ok(color_match(color, 0x0000ffff, 2), "Got unexpected color 0x%08x.\n", color);
7455 color = getPixelColor(device, 160, 360);
7456 ok(color_match(color, 0x00ff00ff, 2), "Got unexpected color 0x%08x.\n", color);
7457 color = getPixelColor(device, 480, 360);
7458 ok(color_match(color, 0x00ffff00, 2), "Got unexpected color 0x%08x.\n", color);
7460 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
7461 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
7463 IDirect3DTexture8_Release(texture1);
7464 IDirect3DTexture8_Release(texture2);
7466 refcount = IDirect3DDevice8_Release(device);
7467 ok(!refcount, "Device has %u references left.\n", refcount);
7468 IDirect3D8_Release(d3d);
7469 DestroyWindow(window);
7472 static void test_vshader_input(void)
7474 DWORD swapped_twotexcrd_shader, swapped_onetexcrd_shader = 0;
7475 DWORD swapped_twotex_wrongidx_shader = 0, swapped_twotexcrd_rightorder_shader;
7476 DWORD texcoord_color_shader, color_ubyte_shader, color_color_shader, color_float_shader;
7477 DWORD color_nocolor_shader = 0;
7478 IDirect3DDevice8 *device;
7479 IDirect3D8 *d3d;
7480 ULONG refcount;
7481 D3DCAPS8 caps;
7482 DWORD color;
7483 HWND window;
7484 HRESULT hr;
7486 static const DWORD swapped_shader_code[] =
7488 0xfffe0101, /* vs_1_1 */
7489 0x00000001, 0xc00f0000, 0x90e40000, /* mov o0, v0 */
7490 0x00000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
7491 0x00000002, 0xd00f0000, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
7492 0x0000ffff /* end */
7494 static const DWORD texcoord_color_shader_code[] =
7496 0xfffe0101, /* vs_1_1 */
7497 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
7498 0x00000001, 0xd00f0000, 0x90e40007, /* mov oD0, v7 */
7499 0x0000ffff /* end */
7501 static const DWORD color_color_shader_code[] =
7503 0xfffe0101, /* vs_1_1 */
7504 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
7505 0x00000005, 0xd00f0000, 0xa0e40000, 0x90e40005, /* mul oD0, c0, v5 */
7506 0x0000ffff /* end */
7508 static const float quad1[] =
7510 -1.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7511 -1.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7512 0.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7513 0.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7515 static const float quad4[] =
7517 0.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7518 0.0f, 1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7519 1.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7520 1.0f, 1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7522 static const struct
7524 struct vec3 position;
7525 DWORD diffuse;
7527 quad1_color[] =
7529 {{-1.0f, -1.0f, 0.1f}, 0x00ff8040},
7530 {{-1.0f, 0.0f, 0.1f}, 0x00ff8040},
7531 {{ 0.0f, -1.0f, 0.1f}, 0x00ff8040},
7532 {{ 0.0f, 0.0f, 0.1f}, 0x00ff8040},
7534 quad2_color[] =
7536 {{ 0.0f, -1.0f, 0.1f}, 0x00ff8040},
7537 {{ 0.0f, 0.0f, 0.1f}, 0x00ff8040},
7538 {{ 1.0f, -1.0f, 0.1f}, 0x00ff8040},
7539 {{ 1.0f, 0.0f, 0.1f}, 0x00ff8040},
7541 quad3_color[] =
7543 {{-1.0f, 0.0f, 0.1f}, 0x00ff8040},
7544 {{-1.0f, 1.0f, 0.1f}, 0x00ff8040},
7545 {{ 0.0f, 0.0f, 0.1f}, 0x00ff8040},
7546 {{ 0.0f, 1.0f, 0.1f}, 0x00ff8040},
7548 static const float quad4_color[] =
7550 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 0.0f, 0.0f,
7551 0.0f, 1.0f, 0.1f, 1.0f, 1.0f, 0.0f, 0.0f,
7552 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 0.0f, 1.0f,
7553 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 0.0f, 1.0f,
7555 static const DWORD decl_twotexcrd[] =
7557 D3DVSD_STREAM(0),
7558 D3DVSD_REG(0, D3DVSDT_FLOAT3), /* position */
7559 D3DVSD_REG(1, D3DVSDT_FLOAT4), /* texcoord0 */
7560 D3DVSD_REG(2, D3DVSDT_FLOAT4), /* texcoord1 */
7561 D3DVSD_END()
7563 static const DWORD decl_twotexcrd_rightorder[] =
7565 D3DVSD_STREAM(0),
7566 D3DVSD_REG(0, D3DVSDT_FLOAT3), /* position */
7567 D3DVSD_REG(2, D3DVSDT_FLOAT4), /* texcoord0 */
7568 D3DVSD_REG(1, D3DVSDT_FLOAT4), /* texcoord1 */
7569 D3DVSD_END()
7571 static const DWORD decl_onetexcrd[] =
7573 D3DVSD_STREAM(0),
7574 D3DVSD_REG(0, D3DVSDT_FLOAT3), /* position */
7575 D3DVSD_REG(1, D3DVSDT_FLOAT4), /* texcoord0 */
7576 D3DVSD_END()
7578 static const DWORD decl_twotexcrd_wrongidx[] =
7580 D3DVSD_STREAM(0),
7581 D3DVSD_REG(0, D3DVSDT_FLOAT3), /* position */
7582 D3DVSD_REG(2, D3DVSDT_FLOAT4), /* texcoord1 */
7583 D3DVSD_REG(3, D3DVSDT_FLOAT4), /* texcoord2 */
7584 D3DVSD_END()
7586 static const DWORD decl_texcoord_color[] =
7588 D3DVSD_STREAM(0),
7589 D3DVSD_REG(0, D3DVSDT_FLOAT3), /* position */
7590 D3DVSD_REG(7, D3DVSDT_D3DCOLOR), /* texcoord0 */
7591 D3DVSD_END()
7593 static const DWORD decl_color_color[] =
7595 D3DVSD_STREAM(0),
7596 D3DVSD_REG(0, D3DVSDT_FLOAT3), /* position */
7597 D3DVSD_REG(5, D3DVSDT_D3DCOLOR), /* diffuse */
7598 D3DVSD_END()
7600 static const DWORD decl_color_ubyte[] =
7602 D3DVSD_STREAM(0),
7603 D3DVSD_REG(0, D3DVSDT_FLOAT3),
7604 D3DVSD_REG(5, D3DVSDT_UBYTE4),
7605 D3DVSD_END()
7607 static const DWORD decl_color_float[] =
7609 D3DVSD_STREAM(0),
7610 D3DVSD_REG(0, D3DVSDT_FLOAT3),
7611 D3DVSD_REG(5, D3DVSDT_FLOAT4),
7612 D3DVSD_END()
7614 static const DWORD decl_nocolor[] =
7616 D3DVSD_STREAM(0),
7617 D3DVSD_REG(0, D3DVSDT_FLOAT3),
7618 D3DVSD_END()
7620 static const float normalize[4] = {1.0f / 256.0f, 1.0f / 256.0f, 1.0f / 256.0f, 1.0f / 256.0f};
7621 static const float no_normalize[4] = {1.0f, 1.0f, 1.0f, 1.0f};
7623 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
7624 0, 0, 640, 480, NULL, NULL, NULL, NULL);
7625 d3d = Direct3DCreate8(D3D_SDK_VERSION);
7626 ok(!!d3d, "Failed to create a D3D object.\n");
7627 if (!(device = create_device(d3d, window, window, TRUE)))
7629 skip("Failed to create a D3D device, skipping tests.\n");
7630 goto done;
7633 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
7634 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
7635 if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1))
7637 skip("No vs_1_1 support, skipping tests.\n");
7638 IDirect3DDevice8_Release(device);
7639 goto done;
7642 hr = IDirect3DDevice8_CreateVertexShader(device, decl_twotexcrd, swapped_shader_code, &swapped_twotexcrd_shader, 0);
7643 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
7644 hr = IDirect3DDevice8_CreateVertexShader(device, decl_onetexcrd, swapped_shader_code, &swapped_onetexcrd_shader, 0);
7645 todo_wine ok(hr == D3DERR_INVALIDCALL, "Unexpected error while creating vertex shader, hr %#x.\n", hr);
7646 hr = IDirect3DDevice8_CreateVertexShader(device, decl_twotexcrd_wrongidx, swapped_shader_code, &swapped_twotex_wrongidx_shader, 0);
7647 todo_wine ok(hr == D3DERR_INVALIDCALL, "Unexpected error while creating vertex shader, hr %#x.\n", hr);
7648 hr = IDirect3DDevice8_CreateVertexShader(device, decl_twotexcrd_rightorder, swapped_shader_code, &swapped_twotexcrd_rightorder_shader, 0);
7649 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
7651 hr = IDirect3DDevice8_CreateVertexShader(device, decl_texcoord_color, texcoord_color_shader_code, &texcoord_color_shader, 0);
7652 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
7653 hr = IDirect3DDevice8_CreateVertexShader(device, decl_color_ubyte, color_color_shader_code, &color_ubyte_shader, 0);
7654 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
7655 hr = IDirect3DDevice8_CreateVertexShader(device, decl_color_color, color_color_shader_code, &color_color_shader, 0);
7656 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
7657 hr = IDirect3DDevice8_CreateVertexShader(device, decl_color_float, color_color_shader_code, &color_float_shader, 0);
7658 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
7659 hr = IDirect3DDevice8_CreateVertexShader(device, decl_nocolor, color_color_shader_code, &color_nocolor_shader, 0);
7660 todo_wine ok(hr == D3DERR_INVALIDCALL, "Unexpected error while creating vertex shader, hr %#x.\n", hr);
7662 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 1.0f, 0);
7663 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
7665 hr = IDirect3DDevice8_BeginScene(device);
7666 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7668 hr = IDirect3DDevice8_SetVertexShader(device, swapped_twotexcrd_shader);
7669 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
7671 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 11);
7672 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7674 hr = IDirect3DDevice8_SetVertexShader(device, swapped_twotexcrd_rightorder_shader);
7675 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
7676 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 11);
7677 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7679 hr = IDirect3DDevice8_EndScene(device);
7680 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7682 color = getPixelColor(device, 160, 360);
7683 ok(color_match(color, 0x00ffff80, 1), "Got unexpected color 0x%08x for quad 1 (2crd).\n", color);
7684 color = getPixelColor(device, 480, 160);
7685 ok(color == 0x00000000, "Got unexpected color 0x%08x for quad 4 (2crd-rightorder).\n", color);
7687 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
7688 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
7690 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
7691 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
7693 hr = IDirect3DDevice8_BeginScene(device);
7694 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7696 hr = IDirect3DDevice8_SetVertexShader(device, texcoord_color_shader);
7697 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
7698 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1_color, sizeof(quad1_color[0]));
7699 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7701 hr = IDirect3DDevice8_SetVertexShader(device, color_ubyte_shader);
7702 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
7704 hr = IDirect3DDevice8_SetVertexShaderConstant(device, 0, normalize, 1);
7705 ok(SUCCEEDED(hr), "Failed to set vertex shader constant, hr %#x.\n", hr);
7706 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_color, sizeof(quad2_color[0]));
7707 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7709 hr = IDirect3DDevice8_SetVertexShaderConstant(device, 0, no_normalize, 1);
7710 ok(SUCCEEDED(hr), "Failed to set vertex shader constant, hr %#x.\n", hr);
7711 hr = IDirect3DDevice8_SetVertexShader(device, color_color_shader);
7712 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
7713 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3_color, sizeof(quad3_color[0]));
7714 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7716 hr = IDirect3DDevice8_SetVertexShader(device, color_float_shader);
7717 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
7718 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4_color, sizeof(float) * 7);
7719 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7721 hr = IDirect3DDevice8_EndScene(device);
7722 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7724 IDirect3DDevice8_SetVertexShader(device, 0);
7726 color = getPixelColor(device, 160, 360);
7727 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
7728 "Input test: Quad 1(color-texcoord) returned color 0x%08x, expected 0x00ff8040\n", color);
7729 color = getPixelColor(device, 480, 360);
7730 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x40, 0x80, 0xff), 1),
7731 "Input test: Quad 2(color-ubyte) returned color 0x%08x, expected 0x004080ff\n", color);
7732 color = getPixelColor(device, 160, 120);
7733 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
7734 "Input test: Quad 3(color-color) returned color 0x%08x, expected 0x00ff8040\n", color);
7735 color = getPixelColor(device, 480, 160);
7736 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 1),
7737 "Input test: Quad 4(color-float) returned color 0x%08x, expected 0x00ffff00\n", color);
7739 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
7740 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
7742 IDirect3DDevice8_DeleteVertexShader(device, swapped_twotexcrd_shader);
7743 IDirect3DDevice8_DeleteVertexShader(device, swapped_onetexcrd_shader);
7744 IDirect3DDevice8_DeleteVertexShader(device, swapped_twotex_wrongidx_shader);
7745 IDirect3DDevice8_DeleteVertexShader(device, swapped_twotexcrd_rightorder_shader);
7746 IDirect3DDevice8_DeleteVertexShader(device, texcoord_color_shader);
7747 IDirect3DDevice8_DeleteVertexShader(device, color_ubyte_shader);
7748 IDirect3DDevice8_DeleteVertexShader(device, color_color_shader);
7749 IDirect3DDevice8_DeleteVertexShader(device, color_float_shader);
7750 IDirect3DDevice8_DeleteVertexShader(device, color_nocolor_shader);
7752 refcount = IDirect3DDevice8_Release(device);
7753 ok(!refcount, "Device has %u references left.\n", refcount);
7754 done:
7755 IDirect3D8_Release(d3d);
7756 DestroyWindow(window);
7759 static void test_fixed_function_fvf(void)
7761 IDirect3DDevice8 *device;
7762 DWORD color;
7763 IDirect3D8 *d3d;
7764 ULONG refcount;
7765 D3DCAPS8 caps;
7766 HWND window;
7767 HRESULT hr;
7769 static const struct
7771 struct vec3 position;
7772 DWORD diffuse;
7774 quad1[] =
7776 {{-1.0f, -1.0f, 0.1f}, 0x00ffff00},
7777 {{-1.0f, 0.0f, 0.1f}, 0x00ffff00},
7778 {{ 0.0f, -1.0f, 0.1f}, 0x00ffff00},
7779 {{ 0.0f, 0.0f, 0.1f}, 0x00ffff00},
7781 static const struct vec3 quad2[] =
7783 {-1.0f, -1.0f, 0.1f},
7784 {-1.0f, 0.0f, 0.1f},
7785 { 0.0f, -1.0f, 0.1f},
7786 { 0.0f, 0.0f, 0.1f},
7788 static const struct
7790 struct vec4 position;
7791 DWORD diffuse;
7793 quad_transformed[] =
7795 {{ 90.0f, 110.0f, 0.1f, 2.0f}, 0x00ffff00},
7796 {{570.0f, 110.0f, 0.1f, 2.0f}, 0x00ffff00},
7797 {{ 90.0f, 300.0f, 0.1f, 2.0f}, 0x00ffff00},
7798 {{570.0f, 300.0f, 0.1f, 2.0f}, 0x00ffff00},
7801 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
7802 0, 0, 640, 480, NULL, NULL, NULL, NULL);
7803 d3d = Direct3DCreate8(D3D_SDK_VERSION);
7804 ok(!!d3d, "Failed to create a D3D object.\n");
7805 if (!(device = create_device(d3d, window, window, TRUE)))
7807 skip("Failed to create a D3D device, skipping tests.\n");
7808 goto done;
7811 memset(&caps, 0, sizeof(caps));
7812 hr = IDirect3DDevice8_GetDeviceCaps(device, &caps);
7813 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
7815 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
7816 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
7818 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_LIGHTING, FALSE);
7819 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
7821 hr = IDirect3DDevice8_BeginScene(device);
7822 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7824 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
7825 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
7826 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
7827 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7829 hr = IDirect3DDevice8_EndScene(device);
7830 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7832 color = getPixelColor(device, 160, 360);
7833 ok(color == 0x00ffff00,
7834 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
7835 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
7837 /* Test with no diffuse color attribute. */
7838 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7839 ok(SUCCEEDED(hr), "IDirect3DDevice8_Clear failed with %08x\n", hr);
7841 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ);
7842 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
7843 hr = IDirect3DDevice8_BeginScene(device);
7844 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7845 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad2, sizeof(quad2[0]));
7846 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7847 hr = IDirect3DDevice8_EndScene(device);
7848 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7850 color = getPixelColor(device, 160, 360);
7851 ok(color == 0x00ffffff, "Got unexpected color 0x%08x in the no diffuse attribute test.\n", color);
7852 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
7854 /* Test what happens with specular lighting enabled and no specular color attribute. */
7855 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
7856 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
7857 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SPECULARENABLE, TRUE);
7858 ok(SUCCEEDED(hr), "Failed to enable specular lighting, hr %#x.\n", hr);
7859 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
7860 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
7861 hr = IDirect3DDevice8_BeginScene(device);
7862 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7864 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad1, sizeof(quad1[0]));
7865 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7867 hr = IDirect3DDevice8_EndScene(device);
7868 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7869 hr = IDirect3DDevice8_SetRenderState(device, D3DRS_SPECULARENABLE, FALSE);
7870 ok(SUCCEEDED(hr), "Failed to disable specular lighting, hr %#x.\n", hr);
7872 color = getPixelColor(device, 160, 360);
7873 ok(color == 0x00ffff00, "Got unexpected color 0x%08x in the no specular attribute test.\n", color);
7875 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
7877 hr = IDirect3DDevice8_SetVertexShader(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
7878 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
7880 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
7881 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
7883 hr = IDirect3DDevice8_BeginScene(device);
7884 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7885 hr = IDirect3DDevice8_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad_transformed, sizeof(quad_transformed[0]));
7886 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7887 hr = IDirect3DDevice8_EndScene(device);
7888 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7890 color = getPixelColor(device, 88, 108);
7891 ok(color == 0x000000ff,
7892 "pixel 88/108 has color %08x, expected 0x000000ff\n", color);
7893 color = getPixelColor(device, 92, 108);
7894 ok(color == 0x000000ff,
7895 "pixel 92/108 has color %08x, expected 0x000000ff\n", color);
7896 color = getPixelColor(device, 88, 112);
7897 ok(color == 0x000000ff,
7898 "pixel 88/112 has color %08x, expected 0x000000ff\n", color);
7899 color = getPixelColor(device, 92, 112);
7900 ok(color == 0x00ffff00,
7901 "pixel 92/112 has color %08x, expected 0x00ffff00\n", color);
7903 color = getPixelColor(device, 568, 108);
7904 ok(color == 0x000000ff,
7905 "pixel 568/108 has color %08x, expected 0x000000ff\n", color);
7906 color = getPixelColor(device, 572, 108);
7907 ok(color == 0x000000ff,
7908 "pixel 572/108 has color %08x, expected 0x000000ff\n", color);
7909 color = getPixelColor(device, 568, 112);
7910 ok(color == 0x00ffff00,
7911 "pixel 568/112 has color %08x, expected 0x00ffff00\n", color);
7912 color = getPixelColor(device, 572, 112);
7913 ok(color == 0x000000ff,
7914 "pixel 572/112 has color %08x, expected 0x000000ff\n", color);
7916 color = getPixelColor(device, 88, 298);
7917 ok(color == 0x000000ff,
7918 "pixel 88/298 has color %08x, expected 0x000000ff\n", color);
7919 color = getPixelColor(device, 92, 298);
7920 ok(color == 0x00ffff00,
7921 "pixel 92/298 has color %08x, expected 0x00ffff00\n", color);
7922 color = getPixelColor(device, 88, 302);
7923 ok(color == 0x000000ff,
7924 "pixel 88/302 has color %08x, expected 0x000000ff\n", color);
7925 color = getPixelColor(device, 92, 302);
7926 ok(color == 0x000000ff,
7927 "pixel 92/302 has color %08x, expected 0x000000ff\n", color);
7929 color = getPixelColor(device, 568, 298);
7930 ok(color == 0x00ffff00,
7931 "pixel 568/298 has color %08x, expected 0x00ffff00\n", color);
7932 color = getPixelColor(device, 572, 298);
7933 ok(color == 0x000000ff,
7934 "pixel 572/298 has color %08x, expected 0x000000ff\n", color);
7935 color = getPixelColor(device, 568, 302);
7936 ok(color == 0x000000ff,
7937 "pixel 568/302 has color %08x, expected 0x000000ff\n", color);
7938 color = getPixelColor(device, 572, 302);
7939 ok(color == 0x000000ff,
7940 "pixel 572/302 has color %08x, expected 0x000000ff\n", color);
7942 IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
7944 refcount = IDirect3DDevice8_Release(device);
7945 ok(!refcount, "Device has %u references left.\n", refcount);
7946 done:
7947 IDirect3D8_Release(d3d);
7948 DestroyWindow(window);
7951 static void test_flip(void)
7953 IDirect3DDevice8 *device;
7954 IDirect3D8 *d3d;
7955 ULONG refcount;
7956 HWND window;
7957 HRESULT hr;
7958 IDirect3DSurface8 *back_buffers[3], *test_surface;
7959 unsigned int i;
7960 D3DCOLOR color;
7961 D3DPRESENT_PARAMETERS present_parameters = {0};
7963 window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW,
7964 0, 0, 640, 480, NULL, NULL, NULL, NULL);
7965 d3d = Direct3DCreate8(D3D_SDK_VERSION);
7966 ok(!!d3d, "Failed to create a D3D object.\n");
7968 present_parameters.BackBufferWidth = 640;
7969 present_parameters.BackBufferHeight = 480;
7970 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
7971 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
7972 present_parameters.hDeviceWindow = window;
7973 present_parameters.Windowed = TRUE;
7974 present_parameters.BackBufferCount = 3;
7975 present_parameters.Flags = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER;
7976 hr = IDirect3D8_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
7977 window, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device);
7978 if (!device)
7980 skip("Failed to create a D3D device, skipping tests.\n");
7981 IDirect3D8_Release(d3d);
7982 DestroyWindow(window);
7983 return;
7986 for (i = 0; i < sizeof(back_buffers) / sizeof(*back_buffers); ++i)
7988 hr = IDirect3DDevice8_GetBackBuffer(device, i, D3DBACKBUFFER_TYPE_MONO, &back_buffers[i]);
7989 ok(SUCCEEDED(hr), "Failed to get back buffer, hr %#x.\n", hr);
7991 hr = IDirect3DDevice8_GetRenderTarget(device, &test_surface);
7992 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
7993 ok(test_surface == back_buffers[0], "Expected render target %p, got %p.\n", back_buffers[0], test_surface);
7994 IDirect3DSurface8_Release(test_surface);
7997 hr = IDirect3DDevice8_SetRenderTarget(device, back_buffers[0], NULL);
7998 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
7999 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0f, 0);
8000 ok(SUCCEEDED(hr), "Failed to clear, hr %#x\n", hr);
8002 hr = IDirect3DDevice8_SetRenderTarget(device, back_buffers[1], NULL);
8003 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
8004 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0f, 0);
8005 ok(SUCCEEDED(hr), "Failed to clear, hr %#x\n", hr);
8007 hr = IDirect3DDevice8_SetRenderTarget(device, back_buffers[2], NULL);
8008 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
8009 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0f, 0);
8010 ok(SUCCEEDED(hr), "Failed to clear, hr %#x\n", hr);
8012 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
8013 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
8015 /* Render target is unmodified. */
8016 hr = IDirect3DDevice8_GetRenderTarget(device, &test_surface);
8017 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
8018 ok(test_surface == back_buffers[2], "Expected render target %p, got %p.\n", back_buffers[2], test_surface);
8019 IDirect3DSurface8_Release(test_surface);
8021 /* Backbuffer surface pointers are unmodified */
8022 for (i = 0; i < sizeof(back_buffers) / sizeof(*back_buffers); ++i)
8024 hr = IDirect3DDevice8_GetBackBuffer(device, i, D3DBACKBUFFER_TYPE_MONO, &test_surface);
8025 ok(SUCCEEDED(hr), "Failed to get back buffer, hr %#x.\n", hr);
8026 ok(test_surface == back_buffers[i], "Expected back buffer %u = %p, got %p.\n",
8027 i, back_buffers[i], test_surface);
8028 IDirect3DSurface8_Release(test_surface);
8031 /* Contents were changed. */
8032 color = get_surface_color(back_buffers[0], 1, 1);
8033 todo_wine ok(color == 0xff00ff00, "Got unexpected color 0x%08x.\n", color);
8034 color = get_surface_color(back_buffers[1], 1, 1);
8035 todo_wine ok(color == 0xff0000ff, "Got unexpected color 0x%08x.\n", color);
8037 hr = IDirect3DDevice8_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff808080, 0.0f, 0);
8038 ok(SUCCEEDED(hr), "Failed to clear, hr %#x\n", hr);
8040 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
8041 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
8043 color = get_surface_color(back_buffers[0], 1, 1);
8044 todo_wine ok(color == 0xff0000ff, "Got unexpected color 0x%08x.\n", color);
8045 color = get_surface_color(back_buffers[1], 1, 1);
8046 todo_wine ok(color == 0xff808080, "Got unexpected color 0x%08x.\n", color);
8048 hr = IDirect3DDevice8_Present(device, NULL, NULL, NULL, NULL);
8049 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
8051 color = get_surface_color(back_buffers[0], 1, 1);
8052 todo_wine ok(color == 0xff808080, "Got unexpected color 0x%08x.\n", color);
8054 for (i = 0; i < sizeof(back_buffers) / sizeof(*back_buffers); ++i)
8055 IDirect3DSurface8_Release(back_buffers[i]);
8057 refcount = IDirect3DDevice8_Release(device);
8058 ok(!refcount, "Device has %u references left.\n", refcount);
8059 IDirect3D8_Release(d3d);
8060 DestroyWindow(window);
8063 START_TEST(visual)
8065 D3DADAPTER_IDENTIFIER8 identifier;
8066 IDirect3D8 *d3d;
8067 HRESULT hr;
8069 if (!(d3d = Direct3DCreate8(D3D_SDK_VERSION)))
8071 skip("Failed to create D3D8 object.\n");
8072 return;
8075 memset(&identifier, 0, sizeof(identifier));
8076 hr = IDirect3D8_GetAdapterIdentifier(d3d, D3DADAPTER_DEFAULT, 0, &identifier);
8077 ok(SUCCEEDED(hr), "Failed to get adapter identifier, hr %#x.\n", hr);
8078 trace("Driver string: \"%s\"\n", identifier.Driver);
8079 trace("Description string: \"%s\"\n", identifier.Description);
8080 /* Only Windows XP's default VGA driver should have an empty description */
8081 ok(identifier.Description[0] || broken(!strcmp(identifier.Driver, "vga.dll")), "Empty driver description.\n");
8082 trace("Driver version %d.%d.%d.%d\n",
8083 HIWORD(U(identifier.DriverVersion).HighPart), LOWORD(U(identifier.DriverVersion).HighPart),
8084 HIWORD(U(identifier.DriverVersion).LowPart), LOWORD(U(identifier.DriverVersion).LowPart));
8086 IDirect3D8_Release(d3d);
8088 test_sanity();
8089 depth_clamp_test();
8090 lighting_test();
8091 test_specular_lighting();
8092 clear_test();
8093 fog_test();
8094 z_range_test();
8095 offscreen_test();
8096 test_blend();
8097 test_scalar_instructions();
8098 fog_with_shader_test();
8099 cnd_test();
8100 p8_texture_test();
8101 texop_test();
8102 depth_buffer_test();
8103 depth_buffer2_test();
8104 intz_test();
8105 shadow_test();
8106 multisample_copy_rects_test();
8107 zenable_test();
8108 resz_test();
8109 fog_special_test();
8110 volume_dxt5_test();
8111 volume_v16u16_test();
8112 add_dirty_rect_test();
8113 test_3dc_formats();
8114 test_fog_interpolation();
8115 test_negative_fixedfunction_fog();
8116 test_table_fog_zw();
8117 test_signed_formats();
8118 test_updatetexture();
8119 test_pointsize();
8120 test_multisample_mismatch();
8121 test_texcoordindex();
8122 test_vshader_input();
8123 test_fixed_function_fvf();
8124 test_flip();