d3d11/tests: Test creating SM4 shaders on feature level 9.
[wine.git] / dlls / d3d9 / tests / visual.c
blobf531dc5e655752765b971910c8bd2abb1f73c100
1 /*
2 * Copyright 2005, 2007-2008 Henri Verbeet
3 * Copyright (C) 2007-2013 Stefan Dösinger(for CodeWeavers)
4 * Copyright (C) 2008 Jason Green(for TransGaming)
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 /* This test framework allows limited testing of rendering results. Things are rendered, shown on
22 * the framebuffer, read back from there and compared to expected colors.
24 * However, neither d3d nor opengl is guaranteed to be pixel exact, and thus the capability of this test
25 * is rather limited. As a general guideline for adding tests, do not rely on corner pixels. Draw a big enough
26 * area which shows specific behavior(like a quad on the whole screen), and try to get resulting colors with
27 * all bits set or unset in all channels(like pure red, green, blue, white, black). Hopefully everything that
28 * causes visible results in games can be tested in a way that does not depend on pixel exactness
31 #include <math.h>
33 #define COBJMACROS
34 #include <d3d9.h>
35 #include "wine/test.h"
37 struct vec2
39 float x, y;
42 struct vec3
44 float x, y, z;
47 struct vec4
49 float x, y, z, w;
52 static HWND create_window(void)
54 WNDCLASSA wc = {0};
55 HWND ret;
56 wc.lpfnWndProc = DefWindowProcA;
57 wc.lpszClassName = "d3d9_test_wc";
58 RegisterClassA(&wc);
60 ret = CreateWindowA("d3d9_test_wc", "d3d9_test", WS_SYSMENU | WS_POPUP,
61 0, 0, 640, 480, 0, 0, 0, 0);
62 ShowWindow(ret, SW_SHOW);
63 return ret;
66 static BOOL color_match(D3DCOLOR c1, D3DCOLOR c2, BYTE max_diff)
68 if (abs((int)(c1 & 0xff) - (int)(c2 & 0xff)) > max_diff) return FALSE;
69 c1 >>= 8; c2 >>= 8;
70 if (abs((int)(c1 & 0xff) - (int)(c2 & 0xff)) > max_diff) return FALSE;
71 c1 >>= 8; c2 >>= 8;
72 if (abs((int)(c1 & 0xff) - (int)(c2 & 0xff)) > max_diff) return FALSE;
73 c1 >>= 8; c2 >>= 8;
74 if (abs((int)(c1 & 0xff) - (int)(c2 & 0xff)) > max_diff) return FALSE;
75 return TRUE;
78 static BOOL adapter_is_warp(const D3DADAPTER_IDENTIFIER9 *identifier)
80 return !strcmp(identifier->Driver, "d3d10warp.dll");
83 /* Locks a given surface and returns the color at (x,y). It's the caller's
84 * responsibility to only pass in lockable surfaces and valid x,y coordinates */
85 static DWORD getPixelColorFromSurface(IDirect3DSurface9 *surface, UINT x, UINT y)
87 DWORD color;
88 HRESULT hr;
89 D3DSURFACE_DESC desc;
90 RECT rectToLock = {x, y, x+1, y+1};
91 D3DLOCKED_RECT lockedRect;
93 hr = IDirect3DSurface9_GetDesc(surface, &desc);
94 if(FAILED(hr)) /* This is not a test */
96 trace("Can't get the surface description, hr=%08x\n", hr);
97 return 0xdeadbeef;
100 hr = IDirect3DSurface9_LockRect(surface, &lockedRect, &rectToLock, D3DLOCK_READONLY);
101 if(FAILED(hr)) /* This is not a test */
103 trace("Can't lock the surface, hr=%08x\n", hr);
104 return 0xdeadbeef;
106 switch(desc.Format) {
107 case D3DFMT_A8R8G8B8:
109 color = ((DWORD *) lockedRect.pBits)[0];
110 break;
112 default:
113 trace("Error: unknown surface format: %d\n", desc.Format);
114 color = 0xdeadbeef;
115 break;
117 hr = IDirect3DSurface9_UnlockRect(surface);
118 if(FAILED(hr))
120 trace("Can't unlock the surface, hr=%08x\n", hr);
122 return color;
125 struct surface_readback
127 IDirect3DSurface9 *surface;
128 D3DLOCKED_RECT locked_rect;
131 static void get_rt_readback(IDirect3DSurface9 *surface, struct surface_readback *rb)
133 IDirect3DDevice9 *device;
134 HRESULT hr;
136 memset(rb, 0, sizeof(*rb));
137 IDirect3DSurface9_GetDevice(surface, &device);
138 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 640, 480,
139 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &rb->surface, NULL);
140 if (FAILED(hr) || !rb->surface)
142 trace("Can't create an offscreen plain surface to read the render target data, hr %#x.\n", hr);
143 goto error;
146 hr = IDirect3DDevice9_GetRenderTargetData(device, surface, rb->surface);
147 if (FAILED(hr))
149 trace("Can't read the render target data, hr %#x.\n", hr);
150 goto error;
153 hr = IDirect3DSurface9_LockRect(rb->surface, &rb->locked_rect, NULL, D3DLOCK_READONLY);
154 if (FAILED(hr))
156 trace("Can't lock the offscreen surface, hr %#x.\n", hr);
157 goto error;
159 IDirect3DDevice9_Release(device);
161 return;
163 error:
164 if (rb->surface)
165 IDirect3DSurface9_Release(rb->surface);
166 rb->surface = NULL;
167 IDirect3DDevice9_Release(device);
170 static DWORD get_readback_color(struct surface_readback *rb, unsigned int x, unsigned int y)
172 return rb->locked_rect.pBits
173 ? ((DWORD *)rb->locked_rect.pBits)[y * rb->locked_rect.Pitch / sizeof(DWORD) + x] : 0xdeadbeef;
176 static void release_surface_readback(struct surface_readback *rb)
178 HRESULT hr;
180 if (!rb->surface)
181 return;
182 if (rb->locked_rect.pBits && FAILED(hr = IDirect3DSurface9_UnlockRect(rb->surface)))
183 trace("Can't unlock the offscreen surface, hr %#x.\n", hr);
184 IDirect3DSurface9_Release(rb->surface);
187 static DWORD getPixelColor(IDirect3DDevice9 *device, UINT x, UINT y)
189 DWORD ret;
190 IDirect3DSurface9 *rt;
191 struct surface_readback rb;
192 HRESULT hr;
194 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &rt);
195 if(FAILED(hr))
197 trace("Can't get the render target, hr %#x.\n", hr);
198 return 0xdeadbeed;
201 get_rt_readback(rt, &rb);
202 /* Remove the X channel for now. DirectX and OpenGL have different ideas how to treat it apparently, and it isn't
203 * really important for these tests
205 ret = get_readback_color(&rb, x, y) & 0x00ffffff;
206 release_surface_readback(&rb);
208 IDirect3DSurface9_Release(rt);
209 return ret;
212 static IDirect3DDevice9 *create_device(IDirect3D9 *d3d, HWND device_window, HWND focus_window, BOOL windowed)
214 D3DPRESENT_PARAMETERS present_parameters = {0};
215 IDirect3DDevice9 *device;
217 present_parameters.Windowed = windowed;
218 present_parameters.hDeviceWindow = device_window;
219 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
220 present_parameters.BackBufferWidth = 640;
221 present_parameters.BackBufferHeight = 480;
222 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
223 present_parameters.EnableAutoDepthStencil = TRUE;
224 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
226 if (SUCCEEDED(IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, focus_window,
227 D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device)))
228 return device;
230 return NULL;
233 static void cleanup_device(IDirect3DDevice9 *device)
235 if (device)
237 D3DPRESENT_PARAMETERS present_parameters;
238 IDirect3DSwapChain9 *swapchain;
239 ULONG ref;
241 IDirect3DDevice9_GetSwapChain(device, 0, &swapchain);
242 IDirect3DSwapChain9_GetPresentParameters(swapchain, &present_parameters);
243 IDirect3DSwapChain9_Release(swapchain);
244 ref = IDirect3DDevice9_Release(device);
245 ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
246 DestroyWindow(present_parameters.hDeviceWindow);
250 static void test_sanity(void)
252 IDirect3DDevice9 *device;
253 IDirect3D9 *d3d;
254 D3DCOLOR color;
255 ULONG refcount;
256 HWND window;
257 HRESULT hr;
259 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
260 0, 0, 640, 480, NULL, NULL, NULL, NULL);
261 d3d = Direct3DCreate9(D3D_SDK_VERSION);
262 ok(!!d3d, "Failed to create a D3D object.\n");
263 if (!(device = create_device(d3d, window, window, TRUE)))
265 skip("Failed to create a D3D device, skipping tests.\n");
266 goto done;
269 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 1.0f, 0);
270 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
271 color = getPixelColor(device, 1, 1);
272 ok(color == 0x00ff0000, "Got unexpected color 0x%08x.\n", color);
274 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
275 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
277 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ddee, 0.0, 0);
278 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
279 color = getPixelColor(device, 639, 479);
280 ok(color == 0x0000ddee, "Got unexpected color 0x%08x.\n", color);
282 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
283 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
285 refcount = IDirect3DDevice9_Release(device);
286 ok(!refcount, "Device has %u references left.\n", refcount);
287 done:
288 IDirect3D9_Release(d3d);
289 DestroyWindow(window);
292 static void lighting_test(void)
294 DWORD nfvf = D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_NORMAL;
295 DWORD fvf = D3DFVF_XYZ | D3DFVF_DIFFUSE;
296 IDirect3DDevice9 *device;
297 D3DMATERIAL9 material;
298 IDirect3D9 *d3d;
299 D3DCOLOR color;
300 ULONG refcount;
301 HWND window;
302 HRESULT hr;
303 unsigned int i;
305 static const D3DMATRIX mat =
307 1.0f, 0.0f, 0.0f, 0.0f,
308 0.0f, 1.0f, 0.0f, 0.0f,
309 0.0f, 0.0f, 1.0f, 0.0f,
310 0.0f, 0.0f, 0.0f, 1.0f,
311 }}},
312 mat_singular =
314 1.0f, 0.0f, 1.0f, 0.0f,
315 0.0f, 1.0f, 0.0f, 0.0f,
316 1.0f, 0.0f, 1.0f, 0.0f,
317 0.0f, 0.0f, 0.5f, 1.0f,
318 }}},
319 mat_transf =
321 0.0f, 0.0f, 1.0f, 0.0f,
322 0.0f, 1.0f, 0.0f, 0.0f,
323 -1.0f, 0.0f, 0.0f, 0.0f,
324 10.f, 10.0f, 10.0f, 1.0f,
325 }}},
326 mat_nonaffine =
328 1.0f, 0.0f, 0.0f, 0.0f,
329 0.0f, 1.0f, 0.0f, 0.0f,
330 0.0f, 0.0f, 1.0f, -1.0f,
331 10.f, 10.0f, 10.0f, 0.0f,
332 }}};
333 static const struct
335 struct vec3 position;
336 DWORD diffuse;
338 unlitquad[] =
340 {{-1.0f, -1.0f, 0.1f}, 0xffff0000},
341 {{-1.0f, 0.0f, 0.1f}, 0xffff0000},
342 {{ 0.0f, 0.0f, 0.1f}, 0xffff0000},
343 {{ 0.0f, -1.0f, 0.1f}, 0xffff0000},
345 litquad[] =
347 {{-1.0f, 0.0f, 0.1f}, 0xff00ff00},
348 {{-1.0f, 1.0f, 0.1f}, 0xff00ff00},
349 {{ 0.0f, 1.0f, 0.1f}, 0xff00ff00},
350 {{ 0.0f, 0.0f, 0.1f}, 0xff00ff00},
352 lighting_test[] =
354 {{-1.0f, -1.0f, 0.1f}, 0x8000ff00},
355 {{ 1.0f, -1.0f, 0.1f}, 0x80000000},
356 {{-1.0f, 1.0f, 0.1f}, 0x8000ff00},
357 {{ 1.0f, 1.0f, 0.1f}, 0x80000000},
359 static const struct
361 struct vec3 position;
362 struct vec3 normal;
363 DWORD diffuse;
365 unlitnquad[] =
367 {{0.0f, -1.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xff0000ff},
368 {{0.0f, 0.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xff0000ff},
369 {{1.0f, 0.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xff0000ff},
370 {{1.0f, -1.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xff0000ff},
372 litnquad[] =
374 {{0.0f, 0.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xffffff00},
375 {{0.0f, 1.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xffffff00},
376 {{1.0f, 1.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xffffff00},
377 {{1.0f, 0.0f, 0.1f}, {1.0f, 1.0f, 1.0f}, 0xffffff00},
379 nquad[] =
381 {{-1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
382 {{-1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
383 {{ 1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
384 {{ 1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
386 rotatedquad[] =
388 {{-10.0f, -11.0f, 11.0f}, {-1.0f, 0.0f, 0.0f}, 0xff0000ff},
389 {{-10.0f, -9.0f, 11.0f}, {-1.0f, 0.0f, 0.0f}, 0xff0000ff},
390 {{-10.0f, -9.0f, 9.0f}, {-1.0f, 0.0f, 0.0f}, 0xff0000ff},
391 {{-10.0f, -11.0f, 9.0f}, {-1.0f, 0.0f, 0.0f}, 0xff0000ff},
393 translatedquad[] =
395 {{-11.0f, -11.0f, -10.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
396 {{-11.0f, -9.0f, -10.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
397 {{ -9.0f, -9.0f, -10.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
398 {{ -9.0f, -11.0f, -10.0f}, {0.0f, 0.0f, -1.0f}, 0xff0000ff},
400 static const WORD indices[] = {0, 1, 2, 2, 3, 0};
401 static const struct
403 const D3DMATRIX *world_matrix;
404 const void *quad;
405 unsigned int size;
406 DWORD expected;
407 const char *message;
409 tests[] =
411 {&mat, nquad, sizeof(nquad[0]), 0x000000ff, "Lit quad with light"},
412 {&mat_singular, nquad, sizeof(nquad[0]), 0x000000ff, "Lit quad with singular world matrix"},
413 {&mat_transf, rotatedquad, sizeof(rotatedquad[0]), 0x000000ff, "Lit quad with transformation matrix"},
414 {&mat_nonaffine, translatedquad, sizeof(translatedquad[0]), 0x00000000, "Lit quad with non-affine matrix"},
417 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
418 0, 0, 640, 480, NULL, NULL, NULL, NULL);
419 d3d = Direct3DCreate9(D3D_SDK_VERSION);
420 ok(!!d3d, "Failed to create a D3D object.\n");
421 if (!(device = create_device(d3d, window, window, TRUE)))
423 skip("Failed to create a D3D device, skipping tests.\n");
424 goto done;
427 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
428 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
430 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), &mat);
431 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
432 hr = IDirect3DDevice9_SetTransform(device, D3DTS_VIEW, &mat);
433 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
434 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &mat);
435 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
436 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
437 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
438 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
439 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
440 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
441 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
442 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
443 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
444 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
445 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
447 hr = IDirect3DDevice9_SetFVF(device, fvf);
448 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
450 hr = IDirect3DDevice9_BeginScene(device);
451 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
453 /* No lights are defined... That means, lit vertices should be entirely black */
454 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
455 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
456 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
457 2, indices, D3DFMT_INDEX16, unlitquad, sizeof(unlitquad[0]));
458 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
460 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
461 ok(SUCCEEDED(hr), "Failed to enable lighting, hr %#x.\n", hr);
462 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
463 2, indices, D3DFMT_INDEX16, litquad, sizeof(litquad[0]));
464 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
466 hr = IDirect3DDevice9_SetFVF(device, nfvf);
467 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
469 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
470 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
471 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
472 2, indices, D3DFMT_INDEX16, unlitnquad, sizeof(unlitnquad[0]));
473 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
475 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, TRUE);
476 ok(SUCCEEDED(hr), "Failed to enable lighting, hr %#x.\n", hr);
477 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
478 2, indices, D3DFMT_INDEX16, litnquad, sizeof(litnquad[0]));
479 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
481 hr = IDirect3DDevice9_EndScene(device);
482 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
484 color = getPixelColor(device, 160, 360); /* Lower left quad - unlit without normals */
485 ok(color == 0x00ff0000, "Unlit quad without normals has color 0x%08x, expected 0x00ff0000.\n", color);
486 color = getPixelColor(device, 160, 120); /* Upper left quad - lit without normals */
487 ok(color == 0x00000000, "Lit quad without normals has color 0x%08x, expected 0x00000000.\n", color);
488 color = getPixelColor(device, 480, 360); /* Lower left quad - unlit with normals */
489 ok(color == 0x000000ff, "Unlit quad with normals has color 0x%08x, expected 0x000000ff.\n", color);
490 color = getPixelColor(device, 480, 120); /* Upper left quad - lit with normals */
491 ok(color == 0x00000000, "Lit quad with normals has color 0x%08x, expected 0x00000000.\n", color);
493 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
495 hr = IDirect3DDevice9_LightEnable(device, 0, TRUE);
496 ok(SUCCEEDED(hr), "Failed to enable light 0, hr %#x.\n", hr);
498 for (i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i)
500 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLD, tests[i].world_matrix);
501 ok(SUCCEEDED(hr), "Failed to set world transform, hr %#x.\n", hr);
503 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
504 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
506 hr = IDirect3DDevice9_BeginScene(device);
507 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
509 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
510 2, indices, D3DFMT_INDEX16, tests[i].quad, tests[i].size);
511 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
513 hr = IDirect3DDevice9_EndScene(device);
514 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
516 color = getPixelColor(device, 320, 240);
517 ok(color == tests[i].expected, "%s has color 0x%08x.\n", tests[i].message, color);
520 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLD, &mat);
521 ok(SUCCEEDED(hr), "Failed to set world transform, hr %#x.\n", hr);
522 hr = IDirect3DDevice9_LightEnable(device, 0, FALSE);
523 ok(SUCCEEDED(hr), "Failed to disable light 0, hr %#x.\n", hr);
525 memset(&material, 0, sizeof(material));
526 material.Diffuse.r = 0.0;
527 material.Diffuse.g = 0.0;
528 material.Diffuse.b = 0.0;
529 material.Diffuse.a = 1.0;
530 material.Ambient.r = 0.0;
531 material.Ambient.g = 0.0;
532 material.Ambient.b = 0.0;
533 material.Ambient.a = 0.0;
534 material.Specular.r = 0.0;
535 material.Specular.g = 0.0;
536 material.Specular.b = 0.0;
537 material.Specular.a = 0.0;
538 material.Emissive.r = 0.0;
539 material.Emissive.g = 0.0;
540 material.Emissive.b = 0.0;
541 material.Emissive.a = 0.0;
542 material.Power = 0.0;
543 hr = IDirect3DDevice9_SetMaterial(device, &material);
544 ok(hr == D3D_OK, "IDirect3DDevice9_SetMaterial returned %08x\n", hr);
546 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_MATERIAL);
547 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
548 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARMATERIALSOURCE, D3DMCS_MATERIAL);
549 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
551 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
552 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
553 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
554 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState returned %08x\n", hr);
556 hr = IDirect3DDevice9_BeginScene(device);
557 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
559 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
560 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
561 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, lighting_test, sizeof(lighting_test[0]));
562 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
564 hr = IDirect3DDevice9_EndScene(device);
565 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
567 color = getPixelColor(device, 320, 240);
568 ok(color == 0x00ffffff, "Lit vertex alpha test returned color %08x, expected 0x00ffffff\n", color);
569 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
571 refcount = IDirect3DDevice9_Release(device);
572 ok(!refcount, "Device has %u references left.\n", refcount);
573 done:
574 IDirect3D9_Release(d3d);
575 DestroyWindow(window);
578 static void test_specular_lighting(void)
580 static const unsigned int vertices_side = 5;
581 const unsigned int indices_count = (vertices_side - 1) * (vertices_side - 1) * 2 * 3;
582 static const DWORD fvf = D3DFVF_XYZ | D3DFVF_NORMAL;
583 static const D3DMATRIX mat =
585 1.0f, 0.0f, 0.0f, 0.0f,
586 0.0f, 1.0f, 0.0f, 0.0f,
587 0.0f, 0.0f, 1.0f, 0.0f,
588 0.0f, 0.0f, 0.0f, 1.0f,
589 }}};
590 static const D3DLIGHT9 directional =
592 D3DLIGHT_DIRECTIONAL,
593 {0.0f, 0.0f, 0.0f, 0.0f},
594 {1.0f, 1.0f, 1.0f, 0.0f},
595 {0.0f, 0.0f, 0.0f, 0.0f},
596 {0.0f, 0.0f, 0.0f},
597 {0.0f, 0.0f, 1.0f},
599 point =
601 D3DLIGHT_POINT,
602 {0.0f, 0.0f, 0.0f, 0.0f},
603 {1.0f, 1.0f, 1.0f, 0.0f},
604 {0.0f, 0.0f, 0.0f, 0.0f},
605 {0.0f, 0.0f, 0.0f},
606 {0.0f, 0.0f, 0.0f},
607 100.0f,
608 0.0f,
609 0.0f, 0.0f, 1.0f,
611 spot =
613 D3DLIGHT_SPOT,
614 {0.0f, 0.0f, 0.0f, 0.0f},
615 {1.0f, 1.0f, 1.0f, 0.0f},
616 {0.0f, 0.0f, 0.0f, 0.0f},
617 {0.0f, 0.0f, 0.0f},
618 {0.0f, 0.0f, 1.0f},
619 100.0f,
620 1.0f,
621 0.0f, 0.0f, 1.0f,
622 M_PI / 12.0f, M_PI / 3.0f
624 /* The chosen range value makes the test fail when using a manhattan
625 * distance metric vs the correct euclidean distance. */
626 point_range =
628 D3DLIGHT_POINT,
629 {0.0f, 0.0f, 0.0f, 0.0f},
630 {1.0f, 1.0f, 1.0f, 0.0f},
631 {0.0f, 0.0f, 0.0f, 0.0f},
632 {0.0f, 0.0f, 0.0f},
633 {0.0f, 0.0f, 0.0f},
634 1.2f,
635 0.0f,
636 0.0f, 0.0f, 1.0f,
638 static const struct expected_color
640 unsigned int x, y;
641 D3DCOLOR color;
643 expected_directional[] =
645 {160, 120, 0x00ffffff},
646 {320, 120, 0x00ffffff},
647 {480, 120, 0x00ffffff},
648 {160, 240, 0x00ffffff},
649 {320, 240, 0x00ffffff},
650 {480, 240, 0x00ffffff},
651 {160, 360, 0x00ffffff},
652 {320, 360, 0x00ffffff},
653 {480, 360, 0x00ffffff},
655 expected_directional_local[] =
657 {160, 120, 0x003c3c3c},
658 {320, 120, 0x00717171},
659 {480, 120, 0x003c3c3c},
660 {160, 240, 0x00717171},
661 {320, 240, 0x00ffffff},
662 {480, 240, 0x00717171},
663 {160, 360, 0x003c3c3c},
664 {320, 360, 0x00717171},
665 {480, 360, 0x003c3c3c},
667 expected_point[] =
669 {160, 120, 0x00282828},
670 {320, 120, 0x005a5a5a},
671 {480, 120, 0x00282828},
672 {160, 240, 0x005a5a5a},
673 {320, 240, 0x00ffffff},
674 {480, 240, 0x005a5a5a},
675 {160, 360, 0x00282828},
676 {320, 360, 0x005a5a5a},
677 {480, 360, 0x00282828},
679 expected_point_local[] =
681 {160, 120, 0x00000000},
682 {320, 120, 0x00070707},
683 {480, 120, 0x00000000},
684 {160, 240, 0x00070707},
685 {320, 240, 0x00ffffff},
686 {480, 240, 0x00070707},
687 {160, 360, 0x00000000},
688 {320, 360, 0x00070707},
689 {480, 360, 0x00000000},
691 expected_spot[] =
693 {160, 120, 0x00000000},
694 {320, 120, 0x00141414},
695 {480, 120, 0x00000000},
696 {160, 240, 0x00141414},
697 {320, 240, 0x00ffffff},
698 {480, 240, 0x00141414},
699 {160, 360, 0x00000000},
700 {320, 360, 0x00141414},
701 {480, 360, 0x00000000},
703 expected_spot_local[] =
705 {160, 120, 0x00000000},
706 {320, 120, 0x00020202},
707 {480, 120, 0x00000000},
708 {160, 240, 0x00020202},
709 {320, 240, 0x00ffffff},
710 {480, 240, 0x00020202},
711 {160, 360, 0x00000000},
712 {320, 360, 0x00020202},
713 {480, 360, 0x00000000},
715 expected_point_range[] =
717 {160, 120, 0x00000000},
718 {320, 120, 0x005a5a5a},
719 {480, 120, 0x00000000},
720 {160, 240, 0x005a5a5a},
721 {320, 240, 0x00ffffff},
722 {480, 240, 0x005a5a5a},
723 {160, 360, 0x00000000},
724 {320, 360, 0x005a5a5a},
725 {480, 360, 0x00000000},
727 static const struct
729 const D3DLIGHT9 *light;
730 BOOL local_viewer;
731 const struct expected_color *expected;
732 unsigned int expected_count;
734 tests[] =
736 {&directional, FALSE, expected_directional,
737 sizeof(expected_directional) / sizeof(expected_directional[0])},
738 {&directional, TRUE, expected_directional_local,
739 sizeof(expected_directional_local) / sizeof(expected_directional_local[0])},
740 {&point, FALSE, expected_point,
741 sizeof(expected_point) / sizeof(expected_point[0])},
742 {&point, TRUE, expected_point_local,
743 sizeof(expected_point_local) / sizeof(expected_point_local[0])},
744 {&spot, FALSE, expected_spot,
745 sizeof(expected_spot) / sizeof(expected_spot[0])},
746 {&spot, TRUE, expected_spot_local,
747 sizeof(expected_spot_local) / sizeof(expected_spot_local[0])},
748 {&point_range, FALSE, expected_point_range,
749 sizeof(expected_point_range) / sizeof(expected_point_range[0])},
751 IDirect3DDevice9 *device;
752 D3DMATERIAL9 material;
753 IDirect3D9 *d3d;
754 D3DCOLOR color;
755 ULONG refcount;
756 HWND window;
757 HRESULT hr;
758 unsigned int i, j, x, y;
759 struct
761 struct vec3 position;
762 struct vec3 normal;
763 } *quad;
764 WORD *indices;
766 quad = HeapAlloc(GetProcessHeap(), 0, vertices_side * vertices_side * sizeof(*quad));
767 indices = HeapAlloc(GetProcessHeap(), 0, indices_count * sizeof(*indices));
768 for (i = 0, y = 0; y < vertices_side; ++y)
770 for (x = 0; x < vertices_side; ++x)
772 quad[i].position.x = x * 2.0f / (vertices_side - 1) - 1.0f;
773 quad[i].position.y = y * 2.0f / (vertices_side - 1) - 1.0f;
774 quad[i].position.z = 1.0f;
775 quad[i].normal.x = 0.0f;
776 quad[i].normal.y = 0.0f;
777 quad[i++].normal.z = -1.0f;
780 for (i = 0, y = 0; y < (vertices_side - 1); ++y)
782 for (x = 0; x < (vertices_side - 1); ++x)
784 indices[i++] = y * vertices_side + x + 1;
785 indices[i++] = y * vertices_side + x;
786 indices[i++] = (y + 1) * vertices_side + x;
787 indices[i++] = y * vertices_side + x + 1;
788 indices[i++] = (y + 1) * vertices_side + x;
789 indices[i++] = (y + 1) * vertices_side + x + 1;
793 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
794 0, 0, 640, 480, NULL, NULL, NULL, NULL);
795 d3d = Direct3DCreate9(D3D_SDK_VERSION);
796 ok(!!d3d, "Failed to create a D3D object.\n");
797 if (!(device = create_device(d3d, window, window, TRUE)))
799 skip("Failed to create a D3D device, skipping tests.\n");
800 goto done;
803 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLD, &mat);
804 ok(SUCCEEDED(hr), "Failed to set world transform, hr %#x.\n", hr);
805 hr = IDirect3DDevice9_SetTransform(device, D3DTS_VIEW, &mat);
806 ok(SUCCEEDED(hr), "Failed to set view transform, hr %#x.\n", hr);
807 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &mat);
808 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
809 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
810 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#x.\n", hr);
811 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
812 ok(SUCCEEDED(hr), "Failed to disable z test, hr %#x.\n", hr);
813 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
814 ok(SUCCEEDED(hr), "Failed to disable fog, hr %#x.\n", hr);
816 hr = IDirect3DDevice9_SetFVF(device, fvf);
817 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
819 memset(&material, 0, sizeof(material));
820 material.Specular.r = 1.0f;
821 material.Specular.g = 1.0f;
822 material.Specular.b = 1.0f;
823 material.Specular.a = 1.0f;
824 material.Power = 30.0f;
825 hr = IDirect3DDevice9_SetMaterial(device, &material);
826 ok(SUCCEEDED(hr), "Failed to set material, hr %#x.\n", hr);
828 hr = IDirect3DDevice9_LightEnable(device, 0, TRUE);
829 ok(SUCCEEDED(hr), "Failed to enable light 0, hr %#x.\n", hr);
830 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARENABLE, TRUE);
831 ok(SUCCEEDED(hr), "Failed to enable specular lighting, hr %#x.\n", hr);
833 for (i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i)
835 hr = IDirect3DDevice9_SetLight(device, 0, tests[i].light);
836 ok(SUCCEEDED(hr), "Failed to set light parameters, hr %#x.\n", hr);
838 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LOCALVIEWER, tests[i].local_viewer);
839 ok(SUCCEEDED(hr), "Failed to set local viewer state, hr %#x.\n", hr);
841 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
842 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
844 hr = IDirect3DDevice9_BeginScene(device);
845 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
847 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST,
848 0, vertices_side * vertices_side, indices_count / 3, indices,
849 D3DFMT_INDEX16, quad, sizeof(quad[0]));
850 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
852 hr = IDirect3DDevice9_EndScene(device);
853 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
855 for (j = 0; j < tests[i].expected_count; ++j)
857 color = getPixelColor(device, tests[i].expected[j].x, tests[i].expected[j].y);
858 ok(color_match(color, tests[i].expected[j].color, 1),
859 "Expected color 0x%08x at location (%u, %u), got 0x%08x, case %u.\n",
860 tests[i].expected[j].color, tests[i].expected[j].x,
861 tests[i].expected[j].y, color, i);
865 refcount = IDirect3DDevice9_Release(device);
866 ok(!refcount, "Device has %u references left.\n", refcount);
867 done:
868 IDirect3D9_Release(d3d);
869 DestroyWindow(window);
870 HeapFree(GetProcessHeap(), 0, indices);
871 HeapFree(GetProcessHeap(), 0, quad);
874 static void clear_test(void)
876 static const D3DMATRIX mat =
878 1.0f, 0.0f, 0.0f, 0.0f,
879 0.0f, 1.0f, 0.0f, 0.0f,
880 0.0f, 0.0f, 1.0f, 0.0f,
881 0.0f, 0.0f, 0.0f, 1.0f,
882 }}};
883 static const struct
885 struct vec3 position;
886 DWORD diffuse;
888 quad[] =
890 {{-1.0f, -1.0f, 0.1f}, 0xff7f7f7f},
891 {{ 1.0f, -1.0f, 0.1f}, 0xff7f7f7f},
892 {{-1.0f, 1.0f, 0.1f}, 0xff7f7f7f},
893 {{ 1.0f, 1.0f, 0.1f}, 0xff7f7f7f},
895 IDirect3DSurface9 *surface0, *surface1, *backbuffer;
896 IDirect3DTexture9 *texture;
897 HRESULT hr;
898 D3DRECT rect[2];
899 D3DRECT rect_negneg;
900 DWORD color;
901 D3DVIEWPORT9 old_vp, vp;
902 RECT scissor;
903 DWORD oldColorWrite;
904 BOOL invalid_clear_failed = FALSE;
905 IDirect3DDevice9 *device;
906 IDirect3D9 *d3d;
907 ULONG refcount;
908 HWND window;
910 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
911 0, 0, 640, 480, NULL, NULL, NULL, NULL);
912 d3d = Direct3DCreate9(D3D_SDK_VERSION);
913 ok(!!d3d, "Failed to create a D3D object.\n");
914 if (!(device = create_device(d3d, window, window, TRUE)))
916 skip("Failed to create a D3D device, skipping tests.\n");
917 goto done;
920 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
921 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
923 /* Positive x, negative y */
924 rect[0].x1 = 0;
925 rect[0].y1 = 480;
926 rect[0].x2 = 320;
927 rect[0].y2 = 240;
929 /* Positive x, positive y */
930 rect[1].x1 = 0;
931 rect[1].y1 = 0;
932 rect[1].x2 = 320;
933 rect[1].y2 = 240;
934 /* Clear 2 rectangles with one call. The refrast returns an error in this case, every real driver tested so far
935 * returns D3D_OK, but ignores the rectangle silently
937 hr = IDirect3DDevice9_Clear(device, 2, rect, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
938 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %08x\n", hr);
939 if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
941 /* negative x, negative y */
942 rect_negneg.x1 = 640;
943 rect_negneg.y1 = 240;
944 rect_negneg.x2 = 320;
945 rect_negneg.y2 = 0;
946 hr = IDirect3DDevice9_Clear(device, 1, &rect_negneg, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
947 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %08x\n", hr);
948 if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
950 color = getPixelColor(device, 160, 360); /* lower left quad */
951 ok(color == 0x00ffffff, "Clear rectangle 3(pos, neg) has color %08x\n", color);
952 color = getPixelColor(device, 160, 120); /* upper left quad */
953 if(invalid_clear_failed) {
954 /* If the negative rectangle was refused, the other rectangles in the list shouldn't be cleared either */
955 ok(color == 0x00ffffff, "Clear rectangle 1(pos, pos) has color %08x\n", color);
956 } else {
957 /* If the negative rectangle was dropped silently, the correct ones are cleared */
958 ok(color == 0x00ff0000, "Clear rectangle 1(pos, pos) has color %08x\n", color);
960 color = getPixelColor(device, 480, 360); /* lower right quad */
961 ok(color == 0x00ffffff, "Clear rectangle 4(NULL) has color %08x\n", color);
962 color = getPixelColor(device, 480, 120); /* upper right quad */
963 ok(color == 0x00ffffff, "Clear rectangle 4(neg, neg) has color %08x\n", color);
965 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
967 /* Hack to work around a nvidia windows driver bug. The clear below is supposed to
968 * clear the red quad in the top left part of the render target. For some reason it
969 * doesn't work if the clear color is 0xffffffff on some versions of the Nvidia Windows
970 * driver(tested on 8.17.12.5896, Win7). A clear with a different color works around
971 * this bug and fixes the clear with the white color. Even 0xfeffffff works, but let's
972 * pick some obvious value
974 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xdeadbabe, 0.0, 0);
975 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
977 /* Test how the viewport affects clears */
978 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
979 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
980 hr = IDirect3DDevice9_GetViewport(device, &old_vp);
981 ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
983 vp.X = 160;
984 vp.Y = 120;
985 vp.Width = 160;
986 vp.Height = 120;
987 vp.MinZ = 0.0;
988 vp.MaxZ = 1.0;
989 hr = IDirect3DDevice9_SetViewport(device, &vp);
990 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
991 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
992 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
994 vp.X = 320;
995 vp.Y = 240;
996 vp.Width = 320;
997 vp.Height = 240;
998 vp.MinZ = 0.0;
999 vp.MaxZ = 1.0;
1000 hr = IDirect3DDevice9_SetViewport(device, &vp);
1001 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
1002 rect[0].x1 = 160;
1003 rect[0].y1 = 120;
1004 rect[0].x2 = 480;
1005 rect[0].y2 = 360;
1006 hr = IDirect3DDevice9_Clear(device, 1, &rect[0], D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
1007 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
1009 hr = IDirect3DDevice9_SetViewport(device, &old_vp);
1010 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
1012 color = getPixelColor(device, 158, 118);
1013 ok(color == 0x00ffffff, "(158,118) has color %08x\n", color);
1014 color = getPixelColor(device, 162, 118);
1015 ok(color == 0x00ffffff, "(162,118) has color %08x\n", color);
1016 color = getPixelColor(device, 158, 122);
1017 ok(color == 0x00ffffff, "(158,122) has color %08x\n", color);
1018 color = getPixelColor(device, 162, 122);
1019 ok(color == 0x000000ff, "(162,122) has color %08x\n", color);
1021 color = getPixelColor(device, 318, 238);
1022 ok(color == 0x000000ff, "(318,238) has color %08x\n", color);
1023 color = getPixelColor(device, 322, 238);
1024 ok(color == 0x00ffffff, "(322,328) has color %08x\n", color);
1025 color = getPixelColor(device, 318, 242);
1026 ok(color == 0x00ffffff, "(318,242) has color %08x\n", color);
1027 color = getPixelColor(device, 322, 242);
1028 ok(color == 0x0000ff00, "(322,242) has color %08x\n", color);
1030 color = getPixelColor(device, 478, 358);
1031 ok(color == 0x0000ff00, "(478,358 has color %08x\n", color);
1032 color = getPixelColor(device, 482, 358);
1033 ok(color == 0x00ffffff, "(482,358) has color %08x\n", color);
1034 color = getPixelColor(device, 478, 362);
1035 ok(color == 0x00ffffff, "(478,362) has color %08x\n", color);
1036 color = getPixelColor(device, 482, 362);
1037 ok(color == 0x00ffffff, "(482,362) has color %08x\n", color);
1039 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1041 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
1042 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
1044 scissor.left = 160;
1045 scissor.right = 480;
1046 scissor.top = 120;
1047 scissor.bottom = 360;
1048 hr = IDirect3DDevice9_SetScissorRect(device, &scissor);
1049 ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
1050 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, TRUE);
1051 ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
1053 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
1054 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
1055 hr = IDirect3DDevice9_Clear(device, 1, &rect[1], D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1056 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
1058 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
1059 ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
1061 color = getPixelColor(device, 158, 118);
1062 ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
1063 color = getPixelColor(device, 162, 118);
1064 ok(color == 0x00ffffff, "Pixel 162/118 has color %08x\n", color);
1065 color = getPixelColor(device, 158, 122);
1066 ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
1067 color = getPixelColor(device, 162, 122);
1068 ok(color == 0x00ff0000, "Pixel 162/122 has color %08x\n", color);
1070 color = getPixelColor(device, 158, 358);
1071 ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
1072 color = getPixelColor(device, 162, 358);
1073 ok(color == 0x0000ff00, "Pixel 162/358 has color %08x\n", color);
1074 color = getPixelColor(device, 158, 358);
1075 ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
1076 color = getPixelColor(device, 162, 362);
1077 ok(color == 0x00ffffff, "Pixel 162/362 has color %08x\n", color);
1079 color = getPixelColor(device, 478, 118);
1080 ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
1081 color = getPixelColor(device, 478, 122);
1082 ok(color == 0x0000ff00, "Pixel 162/118 has color %08x\n", color);
1083 color = getPixelColor(device, 482, 122);
1084 ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
1085 color = getPixelColor(device, 482, 358);
1086 ok(color == 0x00ffffff, "Pixel 162/122 has color %08x\n", color);
1088 color = getPixelColor(device, 478, 358);
1089 ok(color == 0x0000ff00, "Pixel 478/358 has color %08x\n", color);
1090 color = getPixelColor(device, 478, 362);
1091 ok(color == 0x00ffffff, "Pixel 478/118 has color %08x\n", color);
1092 color = getPixelColor(device, 482, 358);
1093 ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
1094 color = getPixelColor(device, 482, 362);
1095 ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
1097 color = getPixelColor(device, 318, 238);
1098 ok(color == 0x00ff0000, "Pixel 318/238 has color %08x\n", color);
1099 color = getPixelColor(device, 318, 242);
1100 ok(color == 0x0000ff00, "Pixel 318/242 has color %08x\n", color);
1101 color = getPixelColor(device, 322, 238);
1102 ok(color == 0x0000ff00, "Pixel 322/238 has color %08x\n", color);
1103 color = getPixelColor(device, 322, 242);
1104 ok(color == 0x0000ff00, "Pixel 322/242 has color %08x\n", color);
1106 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1108 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_COLORWRITEENABLE, &oldColorWrite);
1109 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
1110 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED);
1111 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
1113 /* Same nvidia windows driver trouble with white clears as earlier in the same test */
1114 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xdeadbeef, 0.0, 0);
1115 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
1117 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
1118 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
1120 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, oldColorWrite);
1121 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
1123 /* Colorwriteenable does not affect the clear */
1124 color = getPixelColor(device, 320, 240);
1125 ok(color == 0x00ffffff, "Color write protected clear returned color %08x\n", color);
1127 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1129 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ffffff, 0.0, 0);
1130 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with %08x\n", hr);
1132 rect[0].x1 = 0;
1133 rect[0].y1 = 0;
1134 rect[0].x2 = 640;
1135 rect[0].y2 = 480;
1136 hr = IDirect3DDevice9_Clear(device, 0, rect, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
1137 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with %08x\n", hr);
1139 color = getPixelColor(device, 320, 240);
1140 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff), 1),
1141 "Clear with count = 0, rect != NULL has color %08x\n", color);
1143 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1145 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
1146 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with %08x\n", hr);
1147 hr = IDirect3DDevice9_Clear(device, 1, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
1148 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with %08x\n", hr);
1150 color = getPixelColor(device, 320, 240);
1151 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
1152 "Clear with count = 1, rect = NULL has color %08x\n", color);
1154 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1156 /* Test D3DRS_SRGBWRITEENABLE interactions with clears. */
1157 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x7f7f7f7f, 0.0, 0);
1158 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
1160 color = getPixelColor(device, 320, 240);
1161 ok(color_match(color, 0x007f7f7f, 1), "Clear has color %08x.\n", color);
1163 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, TRUE);
1164 ok(SUCCEEDED(hr), "Failed to enable sRGB write, hr %#x.\n", hr);
1166 /* Draw something to make sure the SRGBWRITEENABLE setting is applied. */
1167 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLD, &mat);
1168 ok(SUCCEEDED(hr), "Failed to set world matrix, hr %#x.\n", hr);
1169 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
1170 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#x.\n", hr);
1171 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
1172 ok(SUCCEEDED(hr), "Failed to disable z test, hr %#x.\n", hr);
1173 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
1174 ok(SUCCEEDED(hr), "Failed to disable fog, hr %#x.\n", hr);
1175 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
1176 ok(SUCCEEDED(hr), "Failed to disable stencil test, hr %#x.\n", hr);
1177 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
1178 ok(SUCCEEDED(hr), "Failed to disable culling, hr %#x.\n", hr);
1179 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1180 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
1181 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
1182 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
1183 hr = IDirect3DDevice9_BeginScene(device);
1184 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
1185 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad));
1186 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1187 hr = IDirect3DDevice9_EndScene(device);
1188 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
1190 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x7f7f7f7f, 0.0, 0);
1191 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
1193 color = getPixelColor(device, 320, 240);
1194 ok(color_match(color, 0x00bbbbbb, 1), "Clear has color %08x.\n", color);
1196 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, FALSE);
1197 ok(SUCCEEDED(hr), "Failed to disable sRGB write, hr %#x.\n", hr);
1199 /* Switching to a new render target seems to be enough to make Windows pick
1200 * up on the changed render state. */
1201 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 2, D3DUSAGE_RENDERTARGET,
1202 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
1203 ok(SUCCEEDED(hr), "Failed to create the offscreen render target, hr %#x.\n", hr);
1204 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
1205 ok(SUCCEEDED(hr), "Failed to get backbuffer, hr %#x.\n", hr);
1206 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface0);
1207 ok(SUCCEEDED(hr), "Failed to get offscreen surface, hr %#x.\n", hr);
1208 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface0);
1209 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
1211 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x7f7f7f7f, 0.0, 0);
1212 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
1214 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1215 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
1217 hr = IDirect3DDevice9_StretchRect(device, surface0, NULL, backbuffer, NULL, D3DTEXF_NONE);
1218 ok(SUCCEEDED(hr), "Failed to blit surface, hr %#x.\n", hr);
1220 color = getPixelColor(device, 64, 64);
1221 ok(color_match(color, 0x007f7f7f, 1), "Clear has color %08x.\n", color);
1223 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, TRUE);
1224 ok(SUCCEEDED(hr), "Failed to enable sRGB write, hr %#x.\n", hr);
1226 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface0);
1227 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
1229 hr = IDirect3DDevice9_BeginScene(device);
1230 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
1231 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad));
1232 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1233 hr = IDirect3DDevice9_EndScene(device);
1234 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
1236 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x7f7f7f7f, 0.0, 0);
1237 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
1239 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1240 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
1242 hr = IDirect3DDevice9_StretchRect(device, surface0, NULL, backbuffer, NULL, D3DTEXF_NONE);
1243 ok(SUCCEEDED(hr), "Failed to blit surface, hr %#x.\n", hr);
1245 color = getPixelColor(device, 320, 240);
1246 ok(color_match(color, 0x00bbbbbb, 1), "Clear has color %08x.\n", color);
1248 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, FALSE);
1249 ok(SUCCEEDED(hr), "Failed to disable sRGB write, hr %#x.\n", hr);
1250 /* Switching to another surface of the same texture is also enough to make
1251 * the setting "stick". */
1252 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 1, &surface1);
1253 ok(SUCCEEDED(hr), "Failed to get offscreen surface, hr %#x.\n", hr);
1254 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface1);
1255 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
1257 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x7f7f7f7f, 0.0, 0);
1258 ok(SUCCEEDED(hr), "Failed to clear, hr %#x\n", hr);
1260 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
1261 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
1263 hr = IDirect3DDevice9_StretchRect(device, surface1, NULL, backbuffer, NULL, D3DTEXF_NONE);
1264 ok(SUCCEEDED(hr), "Failed to blit surface, hr %#x.\n", hr);
1266 color = getPixelColor(device, 320, 240);
1267 ok(color_match(color, 0x007f7f7f, 1), "Clear has color %08x.\n", color);
1269 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1271 IDirect3DSurface9_Release(surface1);
1272 IDirect3DSurface9_Release(surface0);
1273 IDirect3DSurface9_Release(backbuffer);
1274 IDirect3DTexture9_Release(texture);
1275 refcount = IDirect3DDevice9_Release(device);
1276 ok(!refcount, "Device has %u references left.\n", refcount);
1277 done:
1278 IDirect3D9_Release(d3d);
1279 DestroyWindow(window);
1282 static void color_fill_test(void)
1284 IDirect3DSurface9 *surface;
1285 IDirect3DTexture9 *texture;
1286 D3DCOLOR fill_color, color;
1287 DWORD fill_a, expected_a;
1288 IDirect3DDevice9 *device;
1289 IDirect3D9 *d3d;
1290 ULONG refcount;
1291 HWND window;
1292 HRESULT hr;
1293 static const struct
1295 D3DPOOL pool;
1296 DWORD usage;
1297 HRESULT hr;
1299 resource_types[] =
1301 {D3DPOOL_DEFAULT, 0, D3DERR_INVALIDCALL},
1302 {D3DPOOL_DEFAULT, D3DUSAGE_DYNAMIC, D3DERR_INVALIDCALL},
1303 {D3DPOOL_DEFAULT, D3DUSAGE_RENDERTARGET, D3D_OK},
1304 {D3DPOOL_SYSTEMMEM, 0, D3DERR_INVALIDCALL},
1305 {D3DPOOL_MANAGED, 0, D3DERR_INVALIDCALL},
1306 {D3DPOOL_SCRATCH, 0, D3DERR_INVALIDCALL},
1308 static const struct
1310 D3DFORMAT format;
1311 const char *name;
1312 enum
1314 CHECK_FILL_VALUE = 0x1,
1315 TODO_FILL_RETURN = 0x2,
1316 BLOCKS = 0x4,
1317 } flags;
1318 DWORD fill_value;
1320 formats[] =
1322 {D3DFMT_A8R8G8B8, "D3DFMT_A8R8G8B8", CHECK_FILL_VALUE, 0xdeadbeef},
1323 /* D3DFMT_X8R8G8B8 either set X = A or X = 0, depending on the driver. */
1324 {D3DFMT_R5G6B5, "D3DFMT_R5G6B5", CHECK_FILL_VALUE, 0xadfdadfd},
1325 {D3DFMT_G16R16, "D3DFMT_G16R16", CHECK_FILL_VALUE, 0xbebeadad},
1326 /* Real hardware reliably fills the surface with the blue channel but
1327 * the testbot fills it with 0x00. Wine incorrectly uses the alpha
1328 * channel. Don't bother checking the result because P8 surfaces are
1329 * essentially useless in d3d9. */
1330 {D3DFMT_P8, "D3DFMT_P8", 0, 0xefefefef},
1331 /* Windows drivers produce different results for these formats.
1332 * No driver produces a YUV value that matches the input RGB
1333 * value, and no driver produces a proper DXT compression block.
1335 * Even the clear value 0 does not reliably produce a fill value
1336 * that will return vec4(0.0, 0.0, 0.0, 0.0) when sampled.
1338 * The YUV tests are disabled because they produce a driver-dependent
1339 * result on Wine.
1340 * {D3DFMT_YUY2, "D3DFMT_YUY2", BLOCKS, 0},
1341 * {D3DFMT_UYVY, "D3DFMT_UYVY", BLOCKS, 0}, */
1342 {D3DFMT_DXT1, "D3DFMT_DXT1", BLOCKS | TODO_FILL_RETURN, 0},
1343 /* Vendor-specific formats like ATI2N are a non-issue here since they're not
1344 * supported as offscreen plain surfaces and do not support D3DUSAGE_RENDERTARGET
1345 * when created as texture. */
1347 unsigned int i;
1348 D3DLOCKED_RECT locked_rect;
1349 DWORD *surface_data;
1350 static const RECT rect = {4, 4, 8, 8}, rect2 = {5, 5, 7, 7};
1352 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
1353 0, 0, 640, 480, NULL, NULL, NULL, NULL);
1354 d3d = Direct3DCreate9(D3D_SDK_VERSION);
1355 ok(!!d3d, "Failed to create a D3D object.\n");
1356 if (!(device = create_device(d3d, window, window, TRUE)))
1358 skip("Failed to create a D3D device, skipping tests.\n");
1359 goto done;
1362 /* Test ColorFill on a the backbuffer (should pass) */
1363 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &surface);
1364 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
1366 fill_color = 0x112233;
1367 hr = IDirect3DDevice9_ColorFill(device, surface, NULL, fill_color);
1368 ok(SUCCEEDED(hr), "Color fill failed, hr %#x.\n", hr);
1370 color = getPixelColor(device, 0, 0);
1371 ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
1373 IDirect3DSurface9_Release(surface);
1375 /* Test ColorFill on a render target surface (should pass) */
1376 hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_A8R8G8B8,
1377 D3DMULTISAMPLE_NONE, 0, TRUE, &surface, NULL );
1378 ok(hr == D3D_OK, "Unable to create render target surface, hr = %08x\n", hr);
1380 fill_color = 0x445566;
1381 hr = IDirect3DDevice9_ColorFill(device, surface, NULL, fill_color);
1382 ok(SUCCEEDED(hr), "Color fill failed, hr %#x.\n", hr);
1384 color = getPixelColorFromSurface(surface, 0, 0);
1385 ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
1387 IDirect3DSurface9_Release(surface);
1389 /* Test ColorFill on an offscreen plain surface in D3DPOOL_DEFAULT (should pass) */
1390 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
1391 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surface, NULL);
1392 ok(hr == D3D_OK, "Unable to create offscreen plain surface, hr = %08x\n", hr);
1394 fill_color = 0x778899;
1395 hr = IDirect3DDevice9_ColorFill(device, surface, NULL, fill_color);
1396 ok(SUCCEEDED(hr), "Color fill failed, hr %#x.\n", hr);
1398 color = getPixelColorFromSurface(surface, 0, 0);
1399 ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
1401 IDirect3DSurface9_Release(surface);
1403 /* Try ColorFill on an offscreen surface in sysmem (should fail) */
1404 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
1405 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surface, NULL);
1406 ok(hr == D3D_OK, "Unable to create offscreen plain surface, hr = %08x\n", hr);
1408 hr = IDirect3DDevice9_ColorFill(device, surface, NULL, 0);
1409 ok(hr == D3DERR_INVALIDCALL, "ColorFill on offscreen sysmem surface failed with hr = %08x\n", hr);
1411 IDirect3DSurface9_Release(surface);
1413 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 32, 32, D3DFMT_D16,
1414 D3DMULTISAMPLE_NONE, 0, TRUE, &surface, NULL);
1415 ok(SUCCEEDED(hr), "Failed to create depth stencil surface, hr = %08x.\n", hr);
1417 hr = IDirect3DDevice9_ColorFill(device, surface, NULL, 0);
1418 ok(hr == D3DERR_INVALIDCALL, "ColorFill on a depth stencil surface returned hr = %08x.\n", hr);
1420 IDirect3DSurface9_Release(surface);
1422 for (i = 0; i < sizeof(resource_types) / sizeof(resource_types[0]); i++)
1424 texture = NULL;
1425 hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, resource_types[i].usage,
1426 D3DFMT_A8R8G8B8, resource_types[i].pool, &texture, NULL);
1427 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x, i=%u.\n", hr, i);
1428 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
1429 ok(SUCCEEDED(hr), "Failed to get surface, hr %#x, i=%u.\n", hr, i);
1431 hr = IDirect3DDevice9_ColorFill(device, surface, NULL, fill_color);
1432 ok(hr == resource_types[i].hr, "Got unexpected hr %#x, expected %#x, i=%u.\n",
1433 hr, resource_types[i].hr, i);
1435 IDirect3DSurface9_Release(surface);
1436 IDirect3DTexture9_Release(texture);
1439 for (i = 0; i < sizeof(formats) / sizeof(formats[0]); i++)
1441 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
1442 D3DFMT_X8R8G8B8, 0, D3DRTYPE_SURFACE, formats[i].format) != D3D_OK)
1444 skip("Offscreenplain %s surfaces not supported, skipping colorfill test\n", formats[i].name);
1445 continue;
1448 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
1449 formats[i].format, D3DPOOL_DEFAULT, &surface, NULL);
1450 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x, fmt=%s.\n", hr, formats[i].name);
1452 hr = IDirect3DDevice9_ColorFill(device, surface, NULL, 0xdeadbeef);
1453 todo_wine_if (formats[i].flags & TODO_FILL_RETURN)
1454 ok(SUCCEEDED(hr), "Failed to color fill, hr %#x, fmt=%s.\n", hr, formats[i].name);
1456 hr = IDirect3DDevice9_ColorFill(device, surface, &rect, 0xdeadbeef);
1457 todo_wine_if (formats[i].flags & TODO_FILL_RETURN)
1458 ok(SUCCEEDED(hr), "Failed to color fill, hr %#x, fmt=%s.\n", hr, formats[i].name);
1460 if (SUCCEEDED(hr))
1462 hr = IDirect3DDevice9_ColorFill(device, surface, &rect2, 0xdeadbeef);
1463 if (formats[i].flags & BLOCKS)
1464 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x, fmt=%s.\n", hr, formats[i].name);
1465 else
1466 ok(SUCCEEDED(hr), "Failed to color fill, hr %#x, fmt=%s.\n", hr, formats[i].name);
1469 if (formats[i].flags & CHECK_FILL_VALUE)
1471 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, D3DLOCK_READONLY);
1472 ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x, fmt=%s.\n", hr, formats[i].name);
1473 surface_data = locked_rect.pBits;
1474 fill_a = (surface_data[0] & 0xff000000) >> 24;
1475 expected_a = (formats[i].fill_value & 0xff000000) >> 24;
1476 /* Windows drivers disagree on how to promote the 8 bit per channel
1477 * input argument to 16 bit for D3DFMT_G16R16. */
1478 ok(color_match(surface_data[0], formats[i].fill_value, 2) &&
1479 abs((expected_a) - (fill_a)) < 3,
1480 "Expected clear value 0x%08x, got 0x%08x, fmt=%s.\n",
1481 formats[i].fill_value, surface_data[0], formats[i].name);
1482 hr = IDirect3DSurface9_UnlockRect(surface);
1483 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x, fmt=%s.\n", hr, formats[i].name);
1486 IDirect3DSurface9_Release(surface);
1489 refcount = IDirect3DDevice9_Release(device);
1490 ok(!refcount, "Device has %u references left.\n", refcount);
1491 done:
1492 IDirect3D9_Release(d3d);
1493 DestroyWindow(window);
1497 * c7 mova ARGB mov ARGB
1498 * -2.4 -2 0x00ffff00 -3 0x00ff0000
1499 * -1.6 -2 0x00ffff00 -2 0x00ffff00
1500 * -0.4 0 0x0000ffff -1 0x0000ff00
1501 * 0.4 0 0x0000ffff 0 0x0000ffff
1502 * 1.6 2 0x00ff00ff 1 0x000000ff
1503 * 2.4 2 0x00ff00ff 2 0x00ff00ff
1505 static void test_mova(void)
1507 IDirect3DVertexDeclaration9 *vertex_declaration;
1508 IDirect3DVertexShader9 *mova_shader;
1509 IDirect3DVertexShader9 *mov_shader;
1510 IDirect3DDevice9 *device;
1511 unsigned int i, j;
1512 IDirect3D9 *d3d;
1513 ULONG refcount;
1514 D3DCAPS9 caps;
1515 HWND window;
1516 HRESULT hr;
1518 static const DWORD mova_test[] =
1520 0xfffe0200, /* vs_2_0 */
1521 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
1522 0x05000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
1523 0x05000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0 */
1524 0x05000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0 */
1525 0x05000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0 */
1526 0x05000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0 */
1527 0x05000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0 */
1528 0x05000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0 */
1529 0x0200002e, 0xb0010000, 0xa0000007, /* mova a0.x, c7.x */
1530 0x03000001, 0xd00f0000, 0xa0e42003, 0xb0000000, /* mov oD0, c[a0.x + 3] */
1531 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1532 0x0000ffff /* END */
1534 static const DWORD mov_test[] =
1536 0xfffe0101, /* vs_1_1 */
1537 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
1538 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
1539 0x00000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0 */
1540 0x00000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0 */
1541 0x00000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0 */
1542 0x00000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0 */
1543 0x00000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0 */
1544 0x00000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0 */
1545 0x00000001, 0xb0010000, 0xa0000007, /* mov a0.x, c7.x */
1546 0x00000001, 0xd00f0000, 0xa0e42003, /* mov oD0, c[a0.x + 3] */
1547 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1548 0x0000ffff /* END */
1550 static const struct
1552 float in[4];
1553 DWORD out;
1555 test_data[2][6] =
1558 {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff0000},
1559 {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
1560 {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ff00},
1561 {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
1562 {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x000000ff},
1563 {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
1566 {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
1567 {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
1568 {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
1569 {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
1570 {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff},
1571 {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
1574 static const struct vec3 quad[] =
1576 {-1.0f, -1.0f, 0.0f},
1577 {-1.0f, 1.0f, 0.0f},
1578 { 1.0f, -1.0f, 0.0f},
1579 { 1.0f, 1.0f, 0.0f},
1581 static const D3DVERTEXELEMENT9 decl_elements[] =
1583 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1584 D3DDECL_END()
1587 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
1588 0, 0, 640, 480, NULL, NULL, NULL, NULL);
1589 d3d = Direct3DCreate9(D3D_SDK_VERSION);
1590 ok(!!d3d, "Failed to create a D3D object.\n");
1591 if (!(device = create_device(d3d, window, window, TRUE)))
1593 skip("Failed to create a D3D device, skipping tests.\n");
1594 goto done;
1597 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
1598 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
1599 if (caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
1601 skip("No vs_2_0 support, skipping tests.\n");
1602 IDirect3DDevice9_Release(device);
1603 goto done;
1606 hr = IDirect3DDevice9_CreateVertexShader(device, mova_test, &mova_shader);
1607 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1608 hr = IDirect3DDevice9_CreateVertexShader(device, mov_test, &mov_shader);
1609 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1610 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1611 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
1612 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1613 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1615 hr = IDirect3DDevice9_SetVertexShader(device, mov_shader);
1616 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1617 for (j = 0; j < sizeof(test_data) / sizeof(*test_data); ++j)
1619 for (i = 0; i < sizeof(*test_data) / sizeof(**test_data); ++i)
1621 DWORD color;
1623 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, test_data[j][i].in, 1);
1624 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
1626 hr = IDirect3DDevice9_BeginScene(device);
1627 ok(SUCCEEDED(hr), "BeginScene failed (%08x)\n", hr);
1629 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
1630 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
1632 hr = IDirect3DDevice9_EndScene(device);
1633 ok(SUCCEEDED(hr), "EndScene failed (%08x)\n", hr);
1635 color = getPixelColor(device, 320, 240);
1636 ok(color == test_data[j][i].out, "Expected color %08x, got %08x (for input %f, instruction %s)\n",
1637 test_data[j][i].out, color, test_data[j][i].in[0], j == 0 ? "mov" : "mova");
1639 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1640 ok(SUCCEEDED(hr), "Present failed (%08x)\n", hr);
1642 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1643 ok(SUCCEEDED(hr), "Clear failed (%08x)\n", hr);
1645 hr = IDirect3DDevice9_SetVertexShader(device, mova_shader);
1646 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1649 IDirect3DVertexDeclaration9_Release(vertex_declaration);
1650 IDirect3DVertexShader9_Release(mova_shader);
1651 IDirect3DVertexShader9_Release(mov_shader);
1652 refcount = IDirect3DDevice9_Release(device);
1653 ok(!refcount, "Device has %u references left.\n", refcount);
1654 done:
1655 IDirect3D9_Release(d3d);
1656 DestroyWindow(window);
1659 static void fog_test(void)
1661 float start = 0.0f, end = 1.0f;
1662 IDirect3DDevice9 *device;
1663 IDirect3D9 *d3d;
1664 D3DCOLOR color;
1665 ULONG refcount;
1666 D3DCAPS9 caps;
1667 HWND window;
1668 HRESULT hr;
1669 int i;
1671 /* Gets full z based fog with linear fog, no fog with specular color. */
1672 static const struct
1674 float x, y, z;
1675 D3DCOLOR diffuse;
1676 D3DCOLOR specular;
1678 untransformed_1[] =
1680 {-1.0f, -1.0f, 0.1f, 0xffff0000, 0xff000000},
1681 {-1.0f, 0.0f, 0.1f, 0xffff0000, 0xff000000},
1682 { 0.0f, 0.0f, 0.1f, 0xffff0000, 0xff000000},
1683 { 0.0f, -1.0f, 0.1f, 0xffff0000, 0xff000000},
1685 /* Ok, I am too lazy to deal with transform matrices. */
1686 untransformed_2[] =
1688 {-1.0f, 0.0f, 1.0f, 0xffff0000, 0xff000000},
1689 {-1.0f, 1.0f, 1.0f, 0xffff0000, 0xff000000},
1690 { 0.0f, 1.0f, 1.0f, 0xffff0000, 0xff000000},
1691 { 0.0f, 0.0f, 1.0f, 0xffff0000, 0xff000000},
1693 untransformed_3[] =
1695 {-1.0f, -1.0f, 0.5f, 0xffff0000, 0xff000000},
1696 {-1.0f, 1.0f, 0.5f, 0xffff0000, 0xff000000},
1697 { 1.0f, -1.0f, 0.5f, 0xffff0000, 0xff000000},
1698 { 1.0f, 1.0f, 0.5f, 0xffff0000, 0xff000000},
1700 far_quad1[] =
1702 {-1.0f, -1.0f, 0.5f, 0xffff0000, 0xff000000},
1703 {-1.0f, 0.0f, 0.5f, 0xffff0000, 0xff000000},
1704 { 0.0f, 0.0f, 0.5f, 0xffff0000, 0xff000000},
1705 { 0.0f, -1.0f, 0.5f, 0xffff0000, 0xff000000},
1707 far_quad2[] =
1709 {-1.0f, 0.0f, 1.5f, 0xffff0000, 0xff000000},
1710 {-1.0f, 1.0f, 1.5f, 0xffff0000, 0xff000000},
1711 { 0.0f, 1.0f, 1.5f, 0xffff0000, 0xff000000},
1712 { 0.0f, 0.0f, 1.5f, 0xffff0000, 0xff000000},
1714 /* Untransformed ones. Give them a different diffuse color to make the
1715 * test look nicer. It also makes making sure that they are drawn
1716 * correctly easier. */
1717 static const struct
1719 float x, y, z, rhw;
1720 D3DCOLOR diffuse;
1721 D3DCOLOR specular;
1723 transformed_1[] =
1725 {320.0f, 0.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
1726 {640.0f, 0.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
1727 {640.0f, 240.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
1728 {320.0f, 240.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
1730 transformed_2[] =
1732 {320.0f, 240.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
1733 {640.0f, 240.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
1734 {640.0f, 480.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
1735 {320.0f, 480.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
1737 static const struct
1739 struct vec3 position;
1740 DWORD diffuse;
1742 rev_fog_quads[] =
1744 {{-1.0f, -1.0f, 0.1f}, 0x000000ff},
1745 {{-1.0f, 0.0f, 0.1f}, 0x000000ff},
1746 {{ 0.0f, 0.0f, 0.1f}, 0x000000ff},
1747 {{ 0.0f, -1.0f, 0.1f}, 0x000000ff},
1749 {{ 0.0f, -1.0f, 0.9f}, 0x000000ff},
1750 {{ 0.0f, 0.0f, 0.9f}, 0x000000ff},
1751 {{ 1.0f, 0.0f, 0.9f}, 0x000000ff},
1752 {{ 1.0f, -1.0f, 0.9f}, 0x000000ff},
1754 {{ 0.0f, 0.0f, 0.4f}, 0x000000ff},
1755 {{ 0.0f, 1.0f, 0.4f}, 0x000000ff},
1756 {{ 1.0f, 1.0f, 0.4f}, 0x000000ff},
1757 {{ 1.0f, 0.0f, 0.4f}, 0x000000ff},
1759 {{-1.0f, 0.0f, 0.7f}, 0x000000ff},
1760 {{-1.0f, 1.0f, 0.7f}, 0x000000ff},
1761 {{ 0.0f, 1.0f, 0.7f}, 0x000000ff},
1762 {{ 0.0f, 0.0f, 0.7f}, 0x000000ff},
1764 static const D3DMATRIX ident_mat =
1766 1.0f, 0.0f, 0.0f, 0.0f,
1767 0.0f, 1.0f, 0.0f, 0.0f,
1768 0.0f, 0.0f, 1.0f, 0.0f,
1769 0.0f, 0.0f, 0.0f, 1.0f
1770 }}};
1771 static const D3DMATRIX world_mat1 =
1773 1.0f, 0.0f, 0.0f, 0.0f,
1774 0.0f, 1.0f, 0.0f, 0.0f,
1775 0.0f, 0.0f, 1.0f, 0.0f,
1776 0.0f, 0.0f, -0.5f, 1.0f
1777 }}};
1778 static const D3DMATRIX world_mat2 =
1780 1.0f, 0.0f, 0.0f, 0.0f,
1781 0.0f, 1.0f, 0.0f, 0.0f,
1782 0.0f, 0.0f, 1.0f, 0.0f,
1783 0.0f, 0.0f, 1.0f, 1.0f
1784 }}};
1785 static const D3DMATRIX proj_mat =
1787 1.0f, 0.0f, 0.0f, 0.0f,
1788 0.0f, 1.0f, 0.0f, 0.0f,
1789 0.0f, 0.0f, 1.0f, 0.0f,
1790 0.0f, 0.0f, -1.0f, 1.0f
1791 }}};
1792 static const WORD Indices[] = {0, 1, 2, 2, 3, 0};
1793 static const WORD Indices2[] =
1795 0, 1, 2, 2, 3, 0,
1796 4, 5, 6, 6, 7, 4,
1797 8, 9, 10, 10, 11, 8,
1798 12, 13, 14, 14, 15, 12,
1801 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
1802 0, 0, 640, 480, NULL, NULL, NULL, NULL);
1803 d3d = Direct3DCreate9(D3D_SDK_VERSION);
1804 ok(!!d3d, "Failed to create a D3D object.\n");
1805 if (!(device = create_device(d3d, window, window, TRUE)))
1807 skip("Failed to create a D3D device, skipping tests.\n");
1808 goto done;
1811 memset(&caps, 0, sizeof(caps));
1812 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
1813 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
1814 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1815 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1817 /* Setup initial states: No lighting, fog on, fog color */
1818 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
1819 ok(SUCCEEDED(hr), "Failed to disable D3DRS_ZENABLE, hr %#x.\n", hr);
1820 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1821 ok(hr == D3D_OK, "Turning off lighting returned %08x\n", hr);
1822 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
1823 ok(hr == D3D_OK, "Turning on fog calculations returned %08x\n", hr);
1824 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xff00ff00 /* A nice green */);
1825 ok(hr == D3D_OK, "Setting fog color returned %#08x\n", hr);
1826 /* Some of the tests seem to depend on the projection matrix explicitly
1827 * being set to an identity matrix, even though that's the default.
1828 * (AMD Radeon HD 6310, Windows 7) */
1829 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &ident_mat);
1830 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
1832 /* First test: Both table fog and vertex fog off */
1833 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1834 ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
1835 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
1836 ok(hr == D3D_OK, "Turning off vertex fog returned %08x\n", hr);
1838 /* Start = 0, end = 1. Should be default, but set them */
1839 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1840 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1841 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1842 ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1844 hr = IDirect3DDevice9_BeginScene(device);
1845 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
1847 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1848 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
1850 /* Untransformed, vertex fog = NONE, table fog = NONE:
1851 * Read the fog weighting from the specular color. */
1852 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1853 2 /* PrimCount */, Indices, D3DFMT_INDEX16, untransformed_1, sizeof(untransformed_1[0]));
1854 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1856 /* That makes it use the Z value */
1857 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1858 ok(SUCCEEDED(hr), "Failed to set D3DFOG_LINEAR fog vertex mode, hr %#x.\n", hr);
1859 /* Untransformed, vertex fog != none (or table fog != none):
1860 * Use the Z value as input into the equation. */
1861 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1862 2 /* PrimCount */, Indices, D3DFMT_INDEX16, untransformed_2, sizeof(untransformed_2[0]));
1863 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1865 /* transformed verts */
1866 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1867 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
1868 /* Transformed, vertex fog != NONE, pixel fog == NONE:
1869 * Use specular color alpha component. */
1870 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1871 2 /* PrimCount */, Indices, D3DFMT_INDEX16, transformed_1, sizeof(transformed_1[0]));
1872 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1874 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
1875 ok(SUCCEEDED(hr), "Failed to set D3DFOG_LINEAR fog table mode, hr %#x.\n", hr);
1876 /* Transformed, table fog != none, vertex anything:
1877 * Use Z value as input to the fog equation. */
1878 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1879 2 /* PrimCount */, Indices, D3DFMT_INDEX16, transformed_2, sizeof(transformed_2[0]));
1880 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1882 hr = IDirect3DDevice9_EndScene(device);
1883 ok(hr == D3D_OK, "EndScene returned %08x\n", hr);
1885 color = getPixelColor(device, 160, 360);
1886 ok(color == 0x00ff0000, "Untransformed vertex with no table or vertex fog has color %08x\n", color);
1887 color = getPixelColor(device, 160, 120);
1888 ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with linear vertex fog has color %08x\n", color);
1889 color = getPixelColor(device, 480, 120);
1890 ok(color == 0x00ffff00, "Transformed vertex with linear vertex fog has color %08x\n", color);
1891 if(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)
1893 color = getPixelColor(device, 480, 360);
1894 ok(color_match(color, 0x0000ff00, 1), "Transformed vertex with linear table fog has color %08x\n", color);
1896 else
1898 /* Without fog table support the vertex fog is still applied, even though table fog is turned on.
1899 * The settings above result in no fogging with vertex fog
1901 color = getPixelColor(device, 480, 120);
1902 ok(color == 0x00ffff00, "Transformed vertex with linear vertex fog has color %08x\n", color);
1903 trace("Info: Table fog not supported by this device\n");
1905 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1907 /* Now test the special case fogstart == fogend */
1908 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
1909 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1911 hr = IDirect3DDevice9_BeginScene(device);
1912 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
1914 start = 512;
1915 end = 512;
1916 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *)&start));
1917 ok(SUCCEEDED(hr), "Failed to set fog start, hr %#x.\n", hr);
1918 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *)&end));
1919 ok(SUCCEEDED(hr), "Failed to set fog end, hr %#x.\n", hr);
1921 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1922 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
1923 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1924 ok(SUCCEEDED(hr), "Failed to set D3DFOG_LINEAR fog vertex mode, hr %#x.\n", hr);
1925 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1926 ok(SUCCEEDED(hr), "Failed to set D3DFOG_NONE fog table mode, hr %#x.\n", hr);
1928 /* Untransformed vertex, z coord = 0.1, fogstart = 512, fogend = 512.
1929 * Would result in a completely fog-free primitive because start > zcoord,
1930 * but because start == end, the primitive is fully covered by fog. The
1931 * same happens to the 2nd untransformed quad with z = 1.0. The third
1932 * transformed quad remains unfogged because the fogcoords are read from
1933 * the specular color and has fixed fogstart and fogend. */
1934 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1935 2 /* PrimCount */, Indices, D3DFMT_INDEX16, untransformed_1, sizeof(untransformed_1[0]));
1936 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1937 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1938 2 /* PrimCount */, Indices, D3DFMT_INDEX16, untransformed_2, sizeof(untransformed_2[0]));
1939 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1941 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1942 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
1943 /* Transformed, vertex fog != NONE, pixel fog == NONE:
1944 * Use specular color alpha component. */
1945 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1946 2 /* PrimCount */, Indices, D3DFMT_INDEX16, transformed_1, sizeof(transformed_1[0]));
1947 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1949 hr = IDirect3DDevice9_EndScene(device);
1950 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
1952 color = getPixelColor(device, 160, 360);
1953 ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with vertex fog and z = 0.1 has color %08x\n", color);
1954 color = getPixelColor(device, 160, 120);
1955 ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with vertex fog and z = 1.0 has color %08x\n", color);
1956 color = getPixelColor(device, 480, 120);
1957 ok(color == 0x00ffff00, "Transformed vertex with linear vertex fog has color %08x\n", color);
1958 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1960 /* Test "reversed" fog without shaders. With shaders this fails on a few Windows D3D implementations,
1961 * but without shaders it seems to work everywhere
1963 end = 0.2;
1964 start = 0.8;
1965 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1966 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1967 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1968 ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1969 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
1970 ok( hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
1972 /* Test reversed fog without shaders. ATI cards have problems with reversed fog and shaders, so
1973 * it doesn't seem very important for games. ATI cards also have problems with reversed table fog,
1974 * so skip this for now
1976 for(i = 0; i < 1 /*2 - Table fog test disabled, fails on ATI */; i++) {
1977 const char *mode = (i ? "table" : "vertex");
1978 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1979 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1980 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, i == 0 ? D3DFOG_LINEAR : D3DFOG_NONE);
1981 ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1982 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, i == 0 ? D3DFOG_NONE : D3DFOG_LINEAR);
1983 ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1984 hr = IDirect3DDevice9_BeginScene(device);
1985 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
1986 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 16 /* NumVerts */,
1987 8 /* PrimCount */, Indices2, D3DFMT_INDEX16, rev_fog_quads, sizeof(rev_fog_quads[0]));
1988 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1989 hr = IDirect3DDevice9_EndScene(device);
1990 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
1992 color = getPixelColor(device, 160, 360);
1993 ok(color_match(color, 0x0000ff00, 1),
1994 "Reversed %s fog: z=0.1 has color 0x%08x, expected 0x0000ff00 or 0x0000fe00\n", mode, color);
1996 color = getPixelColor(device, 160, 120);
1997 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x2b, 0xd4), 2),
1998 "Reversed %s fog: z=0.7 has color 0x%08x\n", mode, color);
2000 color = getPixelColor(device, 480, 120);
2001 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xaa, 0x55), 2),
2002 "Reversed %s fog: z=0.4 has color 0x%08x\n", mode, color);
2004 color = getPixelColor(device, 480, 360);
2005 ok(color == 0x000000ff, "Reversed %s fog: z=0.9 has color 0x%08x, expected 0x000000ff\n", mode, color);
2007 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2009 if(!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)) {
2010 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping reversed table fog test\n");
2011 break;
2015 if (caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)
2017 /* A simple fog + non-identity world matrix test */
2018 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), &world_mat1);
2019 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %#08x\n", hr);
2021 start = 0.0;
2022 end = 1.0;
2023 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *)&start));
2024 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
2025 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *)&end));
2026 ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
2027 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
2028 ok(hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %#08x\n", hr);
2029 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
2030 ok(hr == D3D_OK, "Turning off vertex fog returned %#08x\n", hr);
2032 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
2033 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %#08x\n", hr);
2035 hr = IDirect3DDevice9_BeginScene(device);
2036 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
2038 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
2039 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
2041 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
2042 2, Indices, D3DFMT_INDEX16, far_quad1, sizeof(far_quad1[0]));
2043 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2044 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
2045 2, Indices, D3DFMT_INDEX16, far_quad2, sizeof(far_quad2[0]));
2046 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2048 hr = IDirect3DDevice9_EndScene(device);
2049 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
2051 color = getPixelColor(device, 160, 360);
2052 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00), 4),
2053 "Unfogged quad has color %08x\n", color);
2054 color = getPixelColor(device, 160, 120);
2055 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
2056 "Fogged out quad has color %08x\n", color);
2058 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2060 /* Test fog behavior with an orthogonal (but non-identity) projection matrix */
2061 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), &world_mat2);
2062 ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
2063 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &proj_mat);
2064 ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
2066 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
2067 ok(hr == D3D_OK, "Clear returned %#08x\n", hr);
2069 hr = IDirect3DDevice9_BeginScene(device);
2070 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
2072 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
2073 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
2075 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
2076 2, Indices, D3DFMT_INDEX16, untransformed_1, sizeof(untransformed_1[0]));
2077 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2078 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
2079 2, Indices, D3DFMT_INDEX16, untransformed_2, sizeof(untransformed_2[0]));
2080 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2082 hr = IDirect3DDevice9_EndScene(device);
2083 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
2085 color = getPixelColor(device, 160, 360);
2086 ok(color_match(color, 0x00e51900, 4), "Partially fogged quad has color %08x\n", color);
2087 color = getPixelColor(device, 160, 120);
2088 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
2089 "Fogged out quad has color %08x\n", color);
2091 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2093 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), &ident_mat);
2094 ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
2095 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &ident_mat);
2096 ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
2098 else
2100 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping some fog tests\n");
2103 /* Test RANGEFOG vs FOGTABLEMODE */
2104 if ((caps.RasterCaps & (D3DPRASTERCAPS_FOGTABLE | D3DPRASTERCAPS_FOGRANGE)) ==
2105 (D3DPRASTERCAPS_FOGTABLE | D3DPRASTERCAPS_FOGRANGE))
2107 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
2108 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed, hr %#x.\n", hr);
2109 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
2110 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed, hr %#x.\n", hr);
2112 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_RANGEFOGENABLE, TRUE);
2113 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
2115 /* z=0.5, x = +/- 1.0, y = +/- 1.0. In case of z fog the fog coordinate is
2116 * 0.5. With range fog it is sqrt(x*x + y*y + z*z) = 1.5 for all vertices.
2117 * Note that the fog coordinate is interpolated linearly across the vertices,
2118 * so the different eye distance at the screen center should not matter. */
2119 start = 0.75f;
2120 end = 0.75001f;
2121 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
2122 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
2123 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
2124 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
2126 /* Table fog: Range fog is not used */
2127 hr = IDirect3DDevice9_BeginScene(device);
2128 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
2130 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
2131 ok(SUCCEEDED(hr), "Failed to set D3DFOG_LINEAR fog table mode, hr %#x.\n", hr);
2132 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,
2133 untransformed_3, sizeof(*untransformed_3));
2134 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2136 hr = IDirect3DDevice9_EndScene(device);
2137 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
2139 color = getPixelColor(device, 10, 10);
2140 ok(color == 0x00ff0000, "Rangefog with table fog returned color 0x%08x\n", color);
2141 color = getPixelColor(device, 630, 10);
2142 ok(color == 0x00ff0000, "Rangefog with table fog returned color 0x%08x\n", color);
2143 color = getPixelColor(device, 10, 470);
2144 ok(color == 0x00ff0000, "Rangefog with table fog returned color 0x%08x\n", color);
2145 color = getPixelColor(device, 630, 470);
2146 ok(color == 0x00ff0000, "Rangefog with table fog returned color 0x%08x\n", color);
2148 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2149 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed, hr %#x.\n", hr);
2151 /* Vertex fog: Rangefog is used */
2152 hr = IDirect3DDevice9_BeginScene(device);
2153 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
2155 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
2156 ok(SUCCEEDED(hr), "Failed to set D3DFOG_NONE fog table mode, hr %#x.\n", hr);
2157 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
2158 ok(SUCCEEDED(hr), "Failed to set D3DFOG_LINEAR fog vertex mode, hr %#x.\n", hr);
2159 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,
2160 untransformed_3, sizeof(*untransformed_3));
2161 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2163 hr = IDirect3DDevice9_EndScene(device);
2164 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
2166 color = getPixelColor(device, 10, 10);
2167 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
2168 "Rangefog with vertex fog returned color 0x%08x\n", color);
2169 color = getPixelColor(device, 630, 10);
2170 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
2171 "Rangefog with vertex fog returned color 0x%08x\n", color);
2172 color = getPixelColor(device, 10, 470);
2173 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
2174 "Rangefog with vertex fog returned color 0x%08x\n", color);
2175 color = getPixelColor(device, 630, 470);
2176 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
2177 "Rangefog with vertex fog returned color 0x%08x\n", color);
2179 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2180 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed, hr %#x.\n", hr);
2182 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_RANGEFOGENABLE, FALSE);
2183 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
2185 else
2187 skip("Range fog or table fog not supported, skipping range fog tests\n");
2190 refcount = IDirect3DDevice9_Release(device);
2191 ok(!refcount, "Device has %u references left.\n", refcount);
2192 done:
2193 IDirect3D9_Release(d3d);
2194 DestroyWindow(window);
2197 /* This test verifies the behaviour of cube maps wrt. texture wrapping.
2198 * D3D cube map wrapping always behaves like GL_CLAMP_TO_EDGE,
2199 * regardless of the actual addressing mode set. The way this test works is
2200 * that we sample in one of the corners of the cubemap with filtering enabled,
2201 * and check the interpolated color. There are essentially two reasonable
2202 * things an implementation can do: Either pick one of the faces and
2203 * interpolate the edge texel with itself (i.e., clamp within the face), or
2204 * interpolate between the edge texels of the three involved faces. It should
2205 * never involve the border color or the other side (texcoord wrapping) of a
2206 * face in the interpolation. */
2207 static void test_cube_wrap(void)
2209 IDirect3DVertexDeclaration9 *vertex_declaration;
2210 IDirect3DSurface9 *face_surface, *surface;
2211 IDirect3DCubeTexture9 *texture;
2212 D3DLOCKED_RECT locked_rect;
2213 IDirect3DDevice9 *device;
2214 unsigned int x, y, face;
2215 IDirect3D9 *d3d;
2216 ULONG refcount;
2217 D3DCAPS9 caps;
2218 HWND window;
2219 HRESULT hr;
2221 static const float quad[][6] =
2223 {-1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
2224 {-1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
2225 { 1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
2226 { 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
2228 static const D3DVERTEXELEMENT9 decl_elements[] =
2230 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2231 {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
2232 D3DDECL_END()
2234 static const struct
2236 D3DTEXTUREADDRESS mode;
2237 const char *name;
2239 address_modes[] =
2241 {D3DTADDRESS_WRAP, "D3DTADDRESS_WRAP"},
2242 {D3DTADDRESS_MIRROR, "D3DTADDRESS_MIRROR"},
2243 {D3DTADDRESS_CLAMP, "D3DTADDRESS_CLAMP"},
2244 {D3DTADDRESS_BORDER, "D3DTADDRESS_BORDER"},
2245 {D3DTADDRESS_MIRRORONCE, "D3DTADDRESS_MIRRORONCE"},
2248 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
2249 0, 0, 640, 480, NULL, NULL, NULL, NULL);
2250 d3d = Direct3DCreate9(D3D_SDK_VERSION);
2251 ok(!!d3d, "Failed to create a D3D object.\n");
2252 if (!(device = create_device(d3d, window, window, TRUE)))
2254 skip("Failed to create a D3D device, skipping tests.\n");
2255 goto done;
2258 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
2259 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
2260 if (!(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP))
2262 skip("No cube texture support, skipping tests.\n");
2263 IDirect3DDevice9_Release(device);
2264 goto done;
2267 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
2268 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
2269 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
2270 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
2272 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
2273 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surface, NULL);
2274 ok(SUCCEEDED(hr), "CreateOffscreenPlainSurface failed (0x%08x)\n", hr);
2276 hr = IDirect3DDevice9_CreateCubeTexture(device, 128, 1, 0, D3DFMT_A8R8G8B8,
2277 D3DPOOL_DEFAULT, &texture, NULL);
2278 ok(SUCCEEDED(hr), "CreateCubeTexture failed (0x%08x)\n", hr);
2280 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
2281 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2283 for (y = 0; y < 128; ++y)
2285 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
2286 for (x = 0; x < 64; ++x)
2288 *ptr++ = 0xff0000ff;
2290 for (x = 64; x < 128; ++x)
2292 *ptr++ = 0xffff0000;
2296 hr = IDirect3DSurface9_UnlockRect(surface);
2297 ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
2299 hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, 0, 0, &face_surface);
2300 ok(SUCCEEDED(hr), "GetCubeMapSurface failed (0x%08x)\n", hr);
2302 hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
2303 ok(SUCCEEDED(hr), "UpdateSurface failed (0x%08x)\n", hr);
2305 IDirect3DSurface9_Release(face_surface);
2307 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
2308 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2310 for (y = 0; y < 128; ++y)
2312 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
2313 for (x = 0; x < 64; ++x)
2315 *ptr++ = 0xffff0000;
2317 for (x = 64; x < 128; ++x)
2319 *ptr++ = 0xff0000ff;
2323 hr = IDirect3DSurface9_UnlockRect(surface);
2324 ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
2326 /* Create cube faces */
2327 for (face = 1; face < 6; ++face)
2329 hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, face, 0, &face_surface);
2330 ok(SUCCEEDED(hr), "GetCubeMapSurface failed (0x%08x)\n", hr);
2332 hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
2333 ok(SUCCEEDED(hr), "UpdateSurface failed (0x%08x)\n", hr);
2335 IDirect3DSurface9_Release(face_surface);
2338 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
2339 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
2341 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
2342 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
2343 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
2344 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
2345 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_BORDERCOLOR, 0xff00ff00);
2346 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_BORDERCOLOR failed (0x%08x)\n", hr);
2348 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
2349 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2351 for (x = 0; x < (sizeof(address_modes) / sizeof(*address_modes)); ++x)
2353 DWORD color;
2355 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, address_modes[x].mode);
2356 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU (%s) failed (0x%08x)\n", address_modes[x].name, hr);
2357 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, address_modes[x].mode);
2358 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV (%s) failed (0x%08x)\n", address_modes[x].name, hr);
2360 hr = IDirect3DDevice9_BeginScene(device);
2361 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
2363 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
2364 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
2366 hr = IDirect3DDevice9_EndScene(device);
2367 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
2369 color = getPixelColor(device, 320, 240);
2370 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
2371 "Got color 0x%08x for addressing mode %s, expected 0x000000ff.\n",
2372 color, address_modes[x].name);
2374 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2375 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2377 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
2378 ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
2381 IDirect3DVertexDeclaration9_Release(vertex_declaration);
2382 IDirect3DCubeTexture9_Release(texture);
2383 IDirect3DSurface9_Release(surface);
2384 refcount = IDirect3DDevice9_Release(device);
2385 ok(!refcount, "Device has %u references left.\n", refcount);
2386 done:
2387 IDirect3D9_Release(d3d);
2388 DestroyWindow(window);
2391 static void offscreen_test(void)
2393 IDirect3DSurface9 *backbuffer, *offscreen;
2394 IDirect3DTexture9 *offscreenTexture;
2395 IDirect3DDevice9 *device;
2396 IDirect3D9 *d3d;
2397 D3DCOLOR color;
2398 ULONG refcount;
2399 HWND window;
2400 HRESULT hr;
2402 static const float quad[][5] =
2404 {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
2405 {-0.5f, 0.5f, 0.1f, 0.0f, 1.0f},
2406 { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
2407 { 0.5f, 0.5f, 0.1f, 1.0f, 1.0f},
2410 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
2411 0, 0, 640, 480, NULL, NULL, NULL, NULL);
2412 d3d = Direct3DCreate9(D3D_SDK_VERSION);
2413 ok(!!d3d, "Failed to create a D3D object.\n");
2414 if (!(device = create_device(d3d, window, window, TRUE)))
2416 skip("Failed to create a D3D device, skipping tests.\n");
2417 goto done;
2420 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 1.0f, 0);
2421 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
2423 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET,
2424 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
2425 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
2426 if (!offscreenTexture)
2428 trace("Failed to create an X8R8G8B8 offscreen texture, trying R5G6B5.\n");
2429 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET,
2430 D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
2431 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
2432 if (!offscreenTexture)
2434 skip("Cannot create an offscreen render target.\n");
2435 IDirect3DDevice9_Release(device);
2436 goto done;
2440 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
2441 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
2443 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
2444 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
2446 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
2447 ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
2449 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
2450 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
2451 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
2452 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
2453 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
2454 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
2455 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
2456 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
2457 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
2458 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2460 hr = IDirect3DDevice9_BeginScene(device);
2461 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
2463 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
2464 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
2465 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 1.0f, 0);
2466 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
2468 /* Draw without textures - Should result in a white quad. */
2469 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
2470 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2472 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
2473 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
2474 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)offscreenTexture);
2475 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
2477 /* This time with the texture. */
2478 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
2479 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2481 hr = IDirect3DDevice9_EndScene(device);
2482 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
2484 /* Center quad - should be white */
2485 color = getPixelColor(device, 320, 240);
2486 ok(color == 0x00ffffff, "Offscreen failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2487 /* Some quad in the cleared part of the texture */
2488 color = getPixelColor(device, 170, 240);
2489 ok(color == 0x00ff00ff, "Offscreen failed: Got color 0x%08x, expected 0x00ff00ff.\n", color);
2490 /* Part of the originally cleared back buffer */
2491 color = getPixelColor(device, 10, 10);
2492 ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2493 color = getPixelColor(device, 10, 470);
2494 ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2496 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2498 IDirect3DSurface9_Release(backbuffer);
2499 IDirect3DTexture9_Release(offscreenTexture);
2500 IDirect3DSurface9_Release(offscreen);
2501 refcount = IDirect3DDevice9_Release(device);
2502 ok(!refcount, "Device has %u references left.\n", refcount);
2503 done:
2504 IDirect3D9_Release(d3d);
2505 DestroyWindow(window);
2508 /* This test tests fog in combination with shaders.
2509 * What's tested: linear fog (vertex and table) with pixel shader
2510 * linear table fog with non foggy vertex shader
2511 * vertex fog with foggy vertex shader, non-linear
2512 * fog with shader, non-linear fog with foggy shader,
2513 * linear table fog with foggy shader */
2514 static void fog_with_shader_test(void)
2516 IDirect3DVertexShader9 *vertex_shader[4] = {NULL, NULL, NULL, NULL};
2517 IDirect3DPixelShader9 *pixel_shader[3] = {NULL, NULL, NULL};
2518 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
2519 IDirect3DDevice9 *device;
2520 unsigned int i, j;
2521 IDirect3D9 *d3d;
2522 ULONG refcount;
2523 D3DCAPS9 caps;
2524 DWORD color;
2525 HWND window;
2526 HRESULT hr;
2527 union
2529 float f;
2530 DWORD i;
2531 } start, end;
2533 /* basic vertex shader without fog computation ("non foggy") */
2534 static const DWORD vertex_shader_code1[] =
2536 0xfffe0101, /* vs_1_1 */
2537 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
2538 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
2539 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
2540 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
2541 0x0000ffff
2543 /* basic vertex shader with reversed fog computation ("foggy") */
2544 static const DWORD vertex_shader_code2[] =
2546 0xfffe0101, /* vs_1_1 */
2547 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
2548 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
2549 0x00000051, 0xa00f0000, 0xbfa00000, 0x00000000, 0xbf666666, 0x00000000, /* def c0, -1.25, 0.0, -0.9, 0.0 */
2550 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
2551 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
2552 0x00000002, 0x800f0000, 0x90aa0000, 0xa0aa0000, /* add r0, v0.z, c0.z */
2553 0x00000005, 0xc00f0001, 0x80000000, 0xa0000000, /* mul oFog, r0.x, c0.x */
2554 0x0000ffff
2556 /* basic vertex shader with reversed fog computation ("foggy"), vs_2_0 */
2557 static const DWORD vertex_shader_code3[] =
2559 0xfffe0200, /* vs_2_0 */
2560 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
2561 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
2562 0x05000051, 0xa00f0000, 0xbfa00000, 0x00000000, 0xbf666666, 0x00000000, /* def c0, -1.25, 0.0, -0.9, 0.0 */
2563 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
2564 0x02000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
2565 0x03000002, 0x800f0000, 0x90aa0000, 0xa0aa0000, /* add r0, v0.z, c0.z */
2566 0x03000005, 0xc00f0001, 0x80000000, 0xa0000000, /* mul oFog, r0.x, c0.x */
2567 0x0000ffff
2569 /* basic pixel shader */
2570 static const DWORD pixel_shader_code[] =
2572 0xffff0101, /* ps_1_1 */
2573 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
2574 0x0000ffff
2576 static const DWORD pixel_shader_code2[] =
2578 0xffff0200, /* ps_2_0 */
2579 0x0200001f, 0x80000000, 0x900f0000, /* dcl v0 */
2580 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
2581 0x0000ffff
2583 struct
2585 struct vec3 position;
2586 DWORD diffuse;
2588 quad[] =
2590 {{-1.0f, -1.0f, 0.0f}, 0xffff0000},
2591 {{-1.0f, 1.0f, 0.0f}, 0xffff0000},
2592 {{ 1.0f, -1.0f, 0.0f}, 0xffff0000},
2593 {{ 1.0f, 1.0f, 0.0f}, 0xffff0000},
2595 static const D3DVERTEXELEMENT9 decl_elements[] =
2597 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2598 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
2599 D3DDECL_END()
2601 /* This reference data was collected on a nVidia GeForce 7600GS driver
2602 * version 84.19 DirectX version 9.0c on Windows XP. */
2603 static const struct test_data_t
2605 int vshader;
2606 int pshader;
2607 D3DFOGMODE vfog;
2608 D3DFOGMODE tfog;
2609 unsigned int color[11];
2611 test_data[] =
2613 /* only pixel shader: */
2614 {0, 1, D3DFOG_NONE, D3DFOG_LINEAR,
2615 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2616 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2617 {0, 1, D3DFOG_EXP, D3DFOG_LINEAR,
2618 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2619 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2620 {0, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
2621 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2622 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2623 {0, 1, D3DFOG_LINEAR, D3DFOG_NONE,
2624 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2625 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2626 {0, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
2627 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2628 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2630 /* vertex shader */
2631 {1, 0, D3DFOG_NONE, D3DFOG_NONE,
2632 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
2633 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
2634 {1, 0, D3DFOG_NONE, D3DFOG_LINEAR,
2635 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2636 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2637 {1, 0, D3DFOG_EXP, D3DFOG_LINEAR,
2638 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2639 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2641 {1, 0, D3DFOG_EXP2, D3DFOG_LINEAR,
2642 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2643 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2644 {1, 0, D3DFOG_LINEAR, D3DFOG_LINEAR,
2645 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2646 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2648 /* vertex shader and pixel shader */
2649 /* The next 4 tests would read the fog coord output, but it isn't available.
2650 * The result is a fully fogged quad, no matter what the Z coord is. This is on
2651 * a geforce 7400, 97.52 driver, Windows Vista, but probably hardware dependent.
2652 * These tests should be disabled if some other hardware behaves differently
2654 {1, 1, D3DFOG_NONE, D3DFOG_NONE,
2655 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
2656 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
2657 {1, 1, D3DFOG_LINEAR, D3DFOG_NONE,
2658 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
2659 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
2660 {1, 1, D3DFOG_EXP, D3DFOG_NONE,
2661 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
2662 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
2663 {1, 1, D3DFOG_EXP2, D3DFOG_NONE,
2664 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
2665 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
2667 /* These use the Z coordinate with linear table fog */
2668 {1, 1, D3DFOG_NONE, D3DFOG_LINEAR,
2669 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2670 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2671 {1, 1, D3DFOG_EXP, D3DFOG_LINEAR,
2672 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2673 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2674 {1, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
2675 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2676 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2677 {1, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
2678 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2679 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2681 /* Non-linear table fog without fog coord */
2682 {1, 1, D3DFOG_NONE, D3DFOG_EXP,
2683 {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
2684 0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
2685 {1, 1, D3DFOG_NONE, D3DFOG_EXP2,
2686 {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
2687 0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
2689 /* These tests fail on older Nvidia drivers */
2690 /* foggy vertex shader */
2691 {2, 0, D3DFOG_NONE, D3DFOG_NONE,
2692 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2693 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2694 {2, 0, D3DFOG_EXP, D3DFOG_NONE,
2695 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2696 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2697 {2, 0, D3DFOG_EXP2, D3DFOG_NONE,
2698 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2699 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2700 {2, 0, D3DFOG_LINEAR, D3DFOG_NONE,
2701 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2702 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2704 {3, 0, D3DFOG_NONE, D3DFOG_NONE,
2705 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2706 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2707 {3, 0, D3DFOG_EXP, D3DFOG_NONE,
2708 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2709 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2710 {3, 0, D3DFOG_EXP2, D3DFOG_NONE,
2711 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2712 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2713 {3, 0, D3DFOG_LINEAR, D3DFOG_NONE,
2714 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2715 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2717 /* foggy vertex shader and pixel shader. First 4 tests with vertex fog,
2718 * all using the fixed fog-coord linear fog
2720 /* vs_1_1 with ps_1_1 */
2721 {2, 1, D3DFOG_NONE, D3DFOG_NONE,
2722 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2723 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2724 {2, 1, D3DFOG_EXP, D3DFOG_NONE,
2725 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2726 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2727 {2, 1, D3DFOG_EXP2, D3DFOG_NONE,
2728 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2729 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2730 {2, 1, D3DFOG_LINEAR, D3DFOG_NONE,
2731 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2732 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2734 /* vs_2_0 with ps_1_1 */
2735 {3, 1, D3DFOG_NONE, D3DFOG_NONE,
2736 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2737 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2738 {3, 1, D3DFOG_EXP, D3DFOG_NONE,
2739 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2740 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2741 {3, 1, D3DFOG_EXP2, D3DFOG_NONE,
2742 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2743 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2744 {3, 1, D3DFOG_LINEAR, D3DFOG_NONE,
2745 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2746 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2748 /* vs_1_1 with ps_2_0 */
2749 {2, 2, D3DFOG_NONE, D3DFOG_NONE,
2750 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2751 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2752 {2, 2, D3DFOG_EXP, D3DFOG_NONE,
2753 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2754 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2755 {2, 2, D3DFOG_EXP2, D3DFOG_NONE,
2756 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2757 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2758 {2, 2, D3DFOG_LINEAR, D3DFOG_NONE,
2759 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2760 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2762 /* vs_2_0 with ps_2_0 */
2763 {3, 2, D3DFOG_NONE, D3DFOG_NONE,
2764 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2765 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2766 {3, 2, D3DFOG_EXP, D3DFOG_NONE,
2767 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2768 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2769 {3, 2, D3DFOG_EXP2, D3DFOG_NONE,
2770 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2771 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2772 {3, 2, D3DFOG_LINEAR, D3DFOG_NONE,
2773 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2774 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2776 /* These use table fog. Here the shader-provided fog coordinate is
2777 * ignored and the z coordinate used instead
2779 {2, 1, D3DFOG_NONE, D3DFOG_EXP,
2780 {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
2781 0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
2782 {2, 1, D3DFOG_NONE, D3DFOG_EXP2,
2783 {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
2784 0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
2785 {2, 1, D3DFOG_NONE, D3DFOG_LINEAR,
2786 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2787 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2789 static const D3DMATRIX identity =
2791 1.0f, 0.0f, 0.0f, 0.0f,
2792 0.0f, 1.0f, 0.0f, 0.0f,
2793 0.0f, 0.0f, 1.0f, 0.0f,
2794 0.0f, 0.0f, 0.0f, 1.0f,
2795 }}};
2797 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
2798 0, 0, 640, 480, NULL, NULL, NULL, NULL);
2799 d3d = Direct3DCreate9(D3D_SDK_VERSION);
2800 ok(!!d3d, "Failed to create a D3D object.\n");
2801 if (!(device = create_device(d3d, window, window, TRUE)))
2803 skip("Failed to create a D3D device, skipping tests.\n");
2804 goto done;
2807 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
2808 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
2809 if (caps.VertexShaderVersion < D3DVS_VERSION(2, 0) || caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
2811 skip("No shader model 2 support, skipping tests.\n");
2812 IDirect3DDevice9_Release(device);
2813 goto done;
2816 /* NOTE: Changing these values will not affect the tests with foggy vertex
2817 * shader, as the values are hardcoded in the shader. */
2818 start.f = 0.1f;
2819 end.f = 0.9f;
2821 /* Some of the tests seem to depend on the projection matrix explicitly
2822 * being set to an identity matrix, even though that's the default.
2823 * (AMD Radeon HD 6310, Windows 7) */
2824 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &identity);
2825 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
2827 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code1, &vertex_shader[1]);
2828 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
2829 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code2, &vertex_shader[2]);
2830 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
2831 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code3, &vertex_shader[3]);
2832 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
2833 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader[1]);
2834 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
2835 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code2, &pixel_shader[2]);
2836 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
2837 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
2838 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
2840 /* Setup initial states: No lighting, fog on, fog color */
2841 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
2842 ok(hr == D3D_OK, "Turning off lighting failed (%08x)\n", hr);
2843 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
2844 ok(hr == D3D_OK, "Turning on fog calculations failed (%08x)\n", hr);
2845 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xff00ff00 /* A nice green */);
2846 ok(hr == D3D_OK, "Setting fog color failed (%08x)\n", hr);
2847 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
2848 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
2850 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
2851 ok(hr == D3D_OK, "Turning off table fog failed (%08x)\n", hr);
2852 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
2853 ok(hr == D3D_OK, "Turning off vertex fog failed (%08x)\n", hr);
2855 /* Use fogtart = 0.1 and end = 0.9 to test behavior outside the fog transition phase, too*/
2856 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, start.i);
2857 ok(hr == D3D_OK, "Setting fog start failed (%08x)\n", hr);
2858 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, end.i);
2859 ok(hr == D3D_OK, "Setting fog end failed (%08x)\n", hr);
2861 for (i = 0; i < sizeof(test_data)/sizeof(test_data[0]); i++)
2863 hr = IDirect3DDevice9_SetVertexShader(device, vertex_shader[test_data[i].vshader]);
2864 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
2865 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader[test_data[i].pshader]);
2866 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
2867 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, test_data[i].vfog);
2868 ok( hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR failed (%08x)\n", hr);
2869 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, test_data[i].tfog);
2870 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR failed (%08x)\n", hr);
2872 for(j=0; j < 11; j++)
2874 /* Don't use the whole zrange to prevent rounding errors */
2875 quad[0].position.z = 0.001f + (float)j / 10.02f;
2876 quad[1].position.z = 0.001f + (float)j / 10.02f;
2877 quad[2].position.z = 0.001f + (float)j / 10.02f;
2878 quad[3].position.z = 0.001f + (float)j / 10.02f;
2880 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff00ff, 1.0f, 0);
2881 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
2883 hr = IDirect3DDevice9_BeginScene(device);
2884 ok( hr == D3D_OK, "BeginScene returned failed (%08x)\n", hr);
2886 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
2887 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2889 hr = IDirect3DDevice9_EndScene(device);
2890 ok(hr == D3D_OK, "EndScene failed (%08x)\n", hr);
2892 /* As the red and green component are the result of blending use 5% tolerance on the expected value */
2893 color = getPixelColor(device, 128, 240);
2894 ok(color_match(color, test_data[i].color[j], 13),
2895 "fog vs%i ps%i fvm%i ftm%i %d: got color %08x, expected %08x +-5%%\n",
2896 test_data[i].vshader, test_data[i].pshader, test_data[i].vfog, test_data[i].tfog, j, color, test_data[i].color[j]);
2899 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2901 IDirect3DVertexShader9_Release(vertex_shader[1]);
2902 IDirect3DVertexShader9_Release(vertex_shader[2]);
2903 IDirect3DVertexShader9_Release(vertex_shader[3]);
2904 IDirect3DPixelShader9_Release(pixel_shader[1]);
2905 IDirect3DPixelShader9_Release(pixel_shader[2]);
2906 IDirect3DVertexDeclaration9_Release(vertex_declaration);
2907 refcount = IDirect3DDevice9_Release(device);
2908 ok(!refcount, "Device has %u references left.\n", refcount);
2909 done:
2910 IDirect3D9_Release(d3d);
2911 DestroyWindow(window);
2914 static void generate_bumpmap_textures(IDirect3DDevice9 *device) {
2915 unsigned int i, x, y;
2916 HRESULT hr;
2917 IDirect3DTexture9 *texture[2] = {NULL, NULL};
2918 D3DLOCKED_RECT locked_rect;
2920 /* Generate the textures */
2921 for(i=0; i<2; i++)
2923 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, 0, i?D3DFMT_A8R8G8B8:D3DFMT_V8U8,
2924 D3DPOOL_MANAGED, &texture[i], NULL);
2925 ok(SUCCEEDED(hr), "CreateTexture failed (0x%08x)\n", hr);
2927 hr = IDirect3DTexture9_LockRect(texture[i], 0, &locked_rect, NULL, 0);
2928 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2929 for (y = 0; y < 128; ++y)
2931 if(i)
2932 { /* Set up black texture with 2x2 texel white spot in the middle */
2933 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
2934 for (x = 0; x < 128; ++x)
2936 *ptr++ = D3DCOLOR_ARGB(0xff, x * 2, y * 2, 0);
2939 else
2940 { /* Set up a displacement map which points away from the center parallel to the closest axis.
2941 * (if multiplied with bumpenvmat)
2943 WORD *ptr = (WORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
2944 for (x = 0; x < 128; ++x)
2946 if(abs(x-64)>abs(y-64))
2948 if(x < 64)
2949 *ptr++ = 0xc000;
2950 else
2951 *ptr++ = 0x4000;
2953 else
2955 if(y < 64)
2956 *ptr++ = 0x0040;
2957 else
2958 *ptr++ = 0x00c0;
2963 hr = IDirect3DTexture9_UnlockRect(texture[i], 0);
2964 ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
2966 hr = IDirect3DDevice9_SetTexture(device, i, (IDirect3DBaseTexture9 *)texture[i]);
2967 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
2969 /* Disable texture filtering */
2970 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MINFILTER, D3DTEXF_POINT);
2971 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
2972 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
2973 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
2975 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2976 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU failed (0x%08x)\n", hr);
2977 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2978 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV failed (0x%08x)\n", hr);
2982 /* Test the behavior of the texbem instruction with normal 2D and projective
2983 * 2D textures. */
2984 static void texbem_test(void)
2986 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
2987 /* Use asymmetric matrix to test loading. */
2988 float bumpenvmat[4] = {0.0f, 0.5f, -0.5f, 0.0f};
2989 IDirect3DPixelShader9 *pixel_shader = NULL;
2990 IDirect3DTexture9 *texture1, *texture2;
2991 IDirect3DTexture9 *texture = NULL;
2992 D3DLOCKED_RECT locked_rect;
2993 IDirect3DDevice9 *device;
2994 IDirect3D9 *d3d;
2995 ULONG refcount;
2996 D3DCAPS9 caps;
2997 DWORD color;
2998 HWND window;
2999 HRESULT hr;
3000 int i;
3002 static const DWORD pixel_shader_code[] =
3004 0xffff0101, /* ps_1_1*/
3005 0x00000042, 0xb00f0000, /* tex t0*/
3006 0x00000043, 0xb00f0001, 0xb0e40000, /* texbem t1, t0*/
3007 0x00000001, 0x800f0000, 0xb0e40001, /* mov r0, t1*/
3008 0x0000ffff
3010 static const DWORD double_texbem_code[] =
3012 0xffff0103, /* ps_1_3 */
3013 0x00000042, 0xb00f0000, /* tex t0 */
3014 0x00000043, 0xb00f0001, 0xb0e40000, /* texbem t1, t0 */
3015 0x00000042, 0xb00f0002, /* tex t2 */
3016 0x00000043, 0xb00f0003, 0xb0e40002, /* texbem t3, t2 */
3017 0x00000002, 0x800f0000, 0xb0e40001, 0xb0e40003, /* add r0, t1, t3 */
3018 0x0000ffff /* end */
3020 static const float quad[][7] =
3022 {-1.0f, -1.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
3023 {-1.0f, 1.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
3024 { 1.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
3025 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
3027 static const float quad_proj[][9] =
3029 {-1.0f, -1.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 128.0f},
3030 {-1.0f, 1.0f, 0.1f, 0.0f, 1.0f, 0.0f, 128.0f, 0.0f, 128.0f},
3031 { 1.0f, -1.0f, 0.1f, 1.0f, 0.0f, 128.0f, 0.0f, 0.0f, 128.0f},
3032 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 128.0f, 128.0f, 0.0f, 128.0f},
3034 static const float double_quad[] =
3036 -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.5f, 0.5f, 0.0f, 0.0f, 0.5f, 0.5f,
3037 -1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.5f, 0.5f, 0.0f, 0.0f, 0.5f, 0.5f,
3038 1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.5f, 0.5f, 0.0f, 0.0f, 0.5f, 0.5f,
3039 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.5f, 0.5f, 0.0f, 0.0f, 0.5f, 0.5f,
3041 static const D3DVERTEXELEMENT9 decl_elements[][4] =
3044 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3045 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3046 {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
3047 D3DDECL_END()
3050 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
3051 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
3052 {0, 20, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
3053 D3DDECL_END()
3057 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
3058 0, 0, 640, 480, NULL, NULL, NULL, NULL);
3059 d3d = Direct3DCreate9(D3D_SDK_VERSION);
3060 ok(!!d3d, "Failed to create a D3D object.\n");
3061 if (!(device = create_device(d3d, window, window, TRUE)))
3063 skip("Failed to create a D3D device, skipping tests.\n");
3064 goto done;
3067 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
3068 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
3069 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 1))
3071 skip("No ps_1_1 support, skipping tests.\n");
3072 IDirect3DDevice9_Release(device);
3073 goto done;
3076 generate_bumpmap_textures(device);
3078 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
3079 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
3080 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
3081 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
3082 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
3084 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
3085 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
3087 for(i=0; i<2; i++)
3089 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
3090 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
3092 if(i)
3094 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4|D3DTTFF_PROJECTED);
3095 ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
3098 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements[i], &vertex_declaration);
3099 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
3100 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
3101 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
3103 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader);
3104 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
3105 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
3106 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
3108 hr = IDirect3DDevice9_BeginScene(device);
3109 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
3111 if(!i)
3112 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
3113 else
3114 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad_proj[0], sizeof(quad_proj[0]));
3115 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
3117 hr = IDirect3DDevice9_EndScene(device);
3118 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
3120 /* The Window 8 testbot (WARP) seems to use the transposed
3121 * D3DTSS_BUMPENVMAT matrix. */
3122 color = getPixelColor(device, 160, 240);
3123 ok(color_match(color, 0x007e8000, 4) || broken(color_match(color, 0x00007e00, 4)),
3124 "Got unexpected color 0x%08x.\n", color);
3125 color = getPixelColor(device, 480, 240);
3126 ok(color_match(color, 0x007e8000, 4) || broken(color_match(color, 0x00fe7e00, 4)),
3127 "Got unexpected color 0x%08x.\n", color);
3128 color = getPixelColor(device, 320, 120);
3129 ok(color_match(color, 0x007e8000, 4) || broken(color_match(color, 0x0080fe00, 4)),
3130 "Got unexpected color 0x%08x.\n", color);
3131 color = getPixelColor(device, 320, 360);
3132 ok(color_match(color, 0x007e8000, 4) || broken(color_match(color, 0x00800000, 4)),
3133 "Got unexpected color 0x%08x.\n", color);
3135 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3136 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3138 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
3139 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
3140 IDirect3DPixelShader9_Release(pixel_shader);
3142 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
3143 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
3144 IDirect3DVertexDeclaration9_Release(vertex_declaration);
3147 /* clean up */
3148 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
3149 ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
3151 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3152 ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
3154 for(i=0; i<2; i++)
3156 hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
3157 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
3158 IDirect3DTexture9_Release(texture); /* For the GetTexture */
3159 hr = IDirect3DDevice9_SetTexture(device, i, NULL);
3160 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
3161 IDirect3DTexture9_Release(texture);
3164 /* Test double texbem */
3165 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture, NULL);
3166 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
3167 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture1, NULL);
3168 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
3169 hr = IDirect3DDevice9_CreateTexture(device, 8, 8, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture2, NULL);
3170 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
3171 hr = IDirect3DDevice9_CreatePixelShader(device, double_texbem_code, &pixel_shader);
3172 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
3174 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
3175 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
3176 ((signed char *) locked_rect.pBits)[0] = (-1.0 / 8.0) * 127;
3177 ((signed char *) locked_rect.pBits)[1] = ( 1.0 / 8.0) * 127;
3179 hr = IDirect3DTexture9_UnlockRect(texture, 0);
3180 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
3182 hr = IDirect3DTexture9_LockRect(texture1, 0, &locked_rect, NULL, 0);
3183 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
3184 ((signed char *) locked_rect.pBits)[0] = (-2.0 / 8.0) * 127;
3185 ((signed char *) locked_rect.pBits)[1] = (-4.0 / 8.0) * 127;
3186 hr = IDirect3DTexture9_UnlockRect(texture1, 0);
3187 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
3190 /* Some data without any meaning, just to have an 8x8 array to see which element is picked */
3191 #define tex 0x00ff0000
3192 #define tex1 0x0000ff00
3193 #define origin 0x000000ff
3194 static const DWORD pixel_data[] = {
3195 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
3196 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
3197 0x000000ff, tex1 , 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
3198 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
3199 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, origin, 0x000000ff, tex , 0x000000ff,
3200 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
3201 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
3202 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
3204 #undef tex1
3205 #undef tex2
3206 #undef origin
3208 hr = IDirect3DTexture9_LockRect(texture2, 0, &locked_rect, NULL, 0);
3209 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
3210 for(i = 0; i < 8; i++) {
3211 memcpy(((char *) locked_rect.pBits) + i * locked_rect.Pitch, pixel_data + 8 * i, 8 * sizeof(DWORD));
3213 hr = IDirect3DTexture9_UnlockRect(texture2, 0);
3214 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
3217 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3218 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
3219 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) texture2);
3220 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
3221 hr = IDirect3DDevice9_SetTexture(device, 2, (IDirect3DBaseTexture9 *) texture1);
3222 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
3223 hr = IDirect3DDevice9_SetTexture(device, 3, (IDirect3DBaseTexture9 *) texture2);
3224 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
3225 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
3226 ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
3227 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX4);
3228 ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
3230 bumpenvmat[0] =-1.0; bumpenvmat[2] = 2.0;
3231 bumpenvmat[1] = 0.0; bumpenvmat[3] = 0.0;
3232 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
3233 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
3234 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
3235 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
3236 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
3237 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
3238 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
3239 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
3241 bumpenvmat[0] = 1.5; bumpenvmat[2] = 0.0;
3242 bumpenvmat[1] = 0.0; bumpenvmat[3] = 0.5;
3243 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
3244 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
3245 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
3246 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
3247 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
3248 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
3249 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
3250 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
3252 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
3253 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
3254 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
3255 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
3256 hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
3257 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
3258 hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
3259 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
3260 hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
3261 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
3262 hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
3263 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
3264 hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
3265 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
3266 hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
3267 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
3269 hr = IDirect3DDevice9_BeginScene(device);
3270 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
3271 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, double_quad, sizeof(float) * 11);
3272 ok(SUCCEEDED(hr), "Failed to draw primitive, hr %#x.\n", hr);
3273 hr = IDirect3DDevice9_EndScene(device);
3274 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
3275 /* The Window 8 testbot (WARP) seems to use the transposed
3276 * D3DTSS_BUMPENVMAT matrix. */
3277 color = getPixelColor(device, 320, 240);
3278 ok(color_match(color, 0x00ffff00, 1) || broken(color_match(color, 0x0000ffff, 1)),
3279 "Got unexpected color 0x%08x.\n", color);
3281 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3282 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3284 IDirect3DPixelShader9_Release(pixel_shader);
3285 IDirect3DTexture9_Release(texture);
3286 IDirect3DTexture9_Release(texture1);
3287 IDirect3DTexture9_Release(texture2);
3288 refcount = IDirect3DDevice9_Release(device);
3289 ok(!refcount, "Device has %u references left.\n", refcount);
3290 done:
3291 IDirect3D9_Release(d3d);
3292 DestroyWindow(window);
3295 static void z_range_test(void)
3297 IDirect3DVertexShader9 *shader;
3298 IDirect3DDevice9 *device;
3299 IDirect3D9 *d3d;
3300 ULONG refcount;
3301 D3DCAPS9 caps;
3302 DWORD color;
3303 HWND window;
3304 HRESULT hr;
3306 static const struct
3308 struct vec3 position;
3309 DWORD diffuse;
3311 quad[] =
3313 {{-1.0f, 0.0f, 1.1f}, 0xffff0000},
3314 {{-1.0f, 1.0f, 1.1f}, 0xffff0000},
3315 {{ 1.0f, 0.0f, -1.1f}, 0xffff0000},
3316 {{ 1.0f, 1.0f, -1.1f}, 0xffff0000},
3318 quad2[] =
3320 {{-1.0f, 0.0f, 1.1f}, 0xff0000ff},
3321 {{-1.0f, 1.0f, 1.1f}, 0xff0000ff},
3322 {{ 1.0f, 0.0f, -1.1f}, 0xff0000ff},
3323 {{ 1.0f, 1.0f, -1.1f}, 0xff0000ff},
3325 static const struct
3327 struct vec4 position;
3328 DWORD diffuse;
3330 quad3[] =
3332 {{640.0f, 240.0f, -1.1f, 1.0f}, 0xffffff00},
3333 {{640.0f, 480.0f, -1.1f, 1.0f}, 0xffffff00},
3334 {{ 0.0f, 240.0f, 1.1f, 1.0f}, 0xffffff00},
3335 {{ 0.0f, 480.0f, 1.1f, 1.0f}, 0xffffff00},
3337 quad4[] =
3339 {{640.0f, 240.0f, -1.1f, 1.0f}, 0xff00ff00},
3340 {{640.0f, 480.0f, -1.1f, 1.0f}, 0xff00ff00},
3341 {{ 0.0f, 240.0f, 1.1f, 1.0f}, 0xff00ff00},
3342 {{ 0.0f, 480.0f, 1.1f, 1.0f}, 0xff00ff00},
3344 static const DWORD shader_code[] =
3346 0xfffe0101, /* vs_1_1 */
3347 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
3348 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
3349 0x00000001, 0xd00f0000, 0xa0e40000, /* mov oD0, c0 */
3350 0x0000ffff /* end */
3352 static const float color_const_1[] = {1.0f, 0.0f, 0.0f, 1.0f};
3353 static const float color_const_2[] = {0.0f, 0.0f, 1.0f, 1.0f};
3355 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
3356 0, 0, 640, 480, NULL, NULL, NULL, NULL);
3357 d3d = Direct3DCreate9(D3D_SDK_VERSION);
3358 ok(!!d3d, "Failed to create a D3D object.\n");
3359 if (!(device = create_device(d3d, window, window, TRUE)))
3361 skip("Failed to create a D3D device, skipping tests.\n");
3362 goto done;
3365 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
3366 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
3368 /* Does the Present clear the depth stencil? Clear the depth buffer with some value != 0,
3369 * then call Present. Then clear the color buffer to make sure it has some defined content
3370 * after the Present with D3DSWAPEFFECT_DISCARD. After that draw a plane that is somewhere cut
3371 * by the depth value. */
3372 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.75f, 0);
3373 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
3374 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3375 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
3376 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
3377 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
3379 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3380 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
3381 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
3382 ok(SUCCEEDED(hr), "Failed to enable clipping, hr %#x.\n", hr);
3383 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
3384 ok(SUCCEEDED(hr), "Failed to enable z test, hr %#x.\n", hr);
3385 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
3386 ok(SUCCEEDED(hr), "Failed to disable z writes, hr %#x.\n", hr);
3387 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
3388 ok(SUCCEEDED(hr), "Failed to set z function, hr %#x.\n", hr);
3389 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
3390 ok(SUCCEEDED(hr), "Failed set FVF, hr %#x.\n", hr);
3392 hr = IDirect3DDevice9_BeginScene(device);
3393 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
3395 /* Test the untransformed vertex path */
3396 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
3397 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
3398 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
3399 ok(SUCCEEDED(hr), "Failed to set z function, hr %#x.\n", hr);
3400 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
3401 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
3403 /* Test the transformed vertex path */
3404 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
3405 ok(SUCCEEDED(hr), "Failed set FVF, hr %#x.\n", hr);
3407 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(quad4[0]));
3408 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
3409 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
3410 ok(SUCCEEDED(hr), "Failed to set z function, hr %#x.\n", hr);
3411 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(quad3[0]));
3412 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
3414 hr = IDirect3DDevice9_EndScene(device);
3415 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
3417 /* Do not test the exact corner pixels, but go pretty close to them */
3419 /* Clipped because z > 1.0 */
3420 color = getPixelColor(device, 28, 238);
3421 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
3422 color = getPixelColor(device, 28, 241);
3423 if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
3424 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
3425 else
3426 ok(color_match(color, 0x00ffff00, 0), "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
3428 /* Not clipped, > z buffer clear value(0.75).
3430 * On the r500 driver on Windows D3DCMP_GREATER and D3DCMP_GREATEREQUAL are broken for depth
3431 * values > 0.5. The range appears to be distorted, apparently an incoming value of ~0.875 is
3432 * equal to a stored depth buffer value of 0.5. */
3433 color = getPixelColor(device, 31, 238);
3434 ok(color_match(color, 0x00ff0000, 0), "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
3435 color = getPixelColor(device, 31, 241);
3436 ok(color_match(color, 0x00ffff00, 0), "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
3437 color = getPixelColor(device, 100, 238);
3438 ok(color_match(color, 0x00ff0000, 0) || broken(color_match(color, 0x00ffffff, 0)),
3439 "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
3440 color = getPixelColor(device, 100, 241);
3441 ok(color_match(color, 0x00ffff00, 0) || broken(color_match(color, 0x00ffffff, 0)),
3442 "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
3444 /* Not clipped, < z buffer clear value */
3445 color = getPixelColor(device, 104, 238);
3446 ok(color_match(color, 0x000000ff, 0), "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
3447 color = getPixelColor(device, 104, 241);
3448 ok(color_match(color, 0x0000ff00, 0), "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
3449 color = getPixelColor(device, 318, 238);
3450 ok(color_match(color, 0x000000ff, 0), "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
3451 color = getPixelColor(device, 318, 241);
3452 ok(color_match(color, 0x0000ff00, 0), "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
3454 /* Clipped because z < 0.0 */
3455 color = getPixelColor(device, 321, 238);
3456 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
3457 color = getPixelColor(device, 321, 241);
3458 if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
3459 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
3460 else
3461 ok(color_match(color, 0x0000ff00, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
3463 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3464 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
3466 /* Test the shader path */
3467 if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1))
3469 skip("Vertex shaders not supported, skipping tests.\n");
3470 IDirect3DDevice9_Release(device);
3471 goto done;
3473 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
3474 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
3476 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
3477 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
3479 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
3480 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
3481 hr = IDirect3DDevice9_SetVertexShader(device, shader);
3482 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
3484 hr = IDirect3DDevice9_BeginScene(device);
3485 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
3487 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, color_const_1, 1);
3488 ok(SUCCEEDED(hr), "Failed to set vs constant 0, hr %#x.\n", hr);
3489 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
3490 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
3492 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
3493 ok(SUCCEEDED(hr), "Failed to set z function, hr %#x.\n", hr);
3494 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, color_const_2, 1);
3495 ok(SUCCEEDED(hr), "Failed to set vs constant 0, hr %#x.\n", hr);
3496 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
3497 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
3499 hr = IDirect3DDevice9_EndScene(device);
3500 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
3502 IDirect3DVertexShader9_Release(shader);
3504 /* Z < 1.0 */
3505 color = getPixelColor(device, 28, 238);
3506 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
3508 /* 1.0 < z < 0.75 */
3509 color = getPixelColor(device, 31, 238);
3510 ok(color_match(color, 0x00ff0000, 0), "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
3511 color = getPixelColor(device, 100, 238);
3512 ok(color_match(color, 0x00ff0000, 0) || broken(color_match(color, 0x00ffffff, 0)),
3513 "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
3515 /* 0.75 < z < 0.0 */
3516 color = getPixelColor(device, 104, 238);
3517 ok(color_match(color, 0x000000ff, 0), "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
3518 color = getPixelColor(device, 318, 238);
3519 ok(color_match(color, 0x000000ff, 0), "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
3521 /* 0.0 < z */
3522 color = getPixelColor(device, 321, 238);
3523 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
3525 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3526 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
3528 refcount = IDirect3DDevice9_Release(device);
3529 ok(!refcount, "Device has %u references left.\n", refcount);
3530 done:
3531 IDirect3D9_Release(d3d);
3532 DestroyWindow(window);
3535 static void fill_surface(IDirect3DSurface9 *surface, DWORD color, DWORD flags)
3537 D3DSURFACE_DESC desc;
3538 D3DLOCKED_RECT l;
3539 HRESULT hr;
3540 unsigned int x, y;
3541 DWORD *mem;
3543 memset(&desc, 0, sizeof(desc));
3544 memset(&l, 0, sizeof(l));
3545 hr = IDirect3DSurface9_GetDesc(surface, &desc);
3546 ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %08x\n", hr);
3547 hr = IDirect3DSurface9_LockRect(surface, &l, NULL, flags);
3548 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed with %08x\n", hr);
3549 if(FAILED(hr)) return;
3551 for(y = 0; y < desc.Height; y++)
3553 mem = (DWORD *) ((BYTE *) l.pBits + y * l.Pitch);
3554 for(x = 0; x < l.Pitch / sizeof(DWORD); x++)
3556 mem[x] = color;
3559 hr = IDirect3DSurface9_UnlockRect(surface);
3560 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed with %08x\n", hr);
3563 static void stretchrect_test(void)
3565 IDirect3DSurface9 *surf_tex_rt32, *surf_tex_rt64, *surf_tex_rt_dest64, *surf_tex_rt_dest640_480;
3566 IDirect3DSurface9 *surf_offscreen32, *surf_offscreen64, *surf_offscreen_dest64;
3567 IDirect3DTexture9 *tex_rt32, *tex_rt64, *tex_rt_dest64, *tex_rt_dest640_480;
3568 IDirect3DSurface9 *surf_tex32, *surf_tex64, *surf_tex_dest64;
3569 IDirect3DSurface9 *surf_rt32, *surf_rt64, *surf_rt_dest64;
3570 IDirect3DTexture9 *tex32, *tex64, *tex_dest64;
3571 IDirect3DSurface9 *surf_temp32, *surf_temp64;
3572 IDirect3DSurface9 *backbuffer;
3573 IDirect3DDevice9 *device;
3574 IDirect3D9 *d3d;
3575 D3DCOLOR color;
3576 ULONG refcount;
3577 HWND window;
3578 HRESULT hr;
3580 static const RECT src_rect = {0, 0, 640, 480};
3581 static const RECT src_rect_flipy = {0, 480, 640, 0};
3582 static const RECT dst_rect = {0, 0, 640, 480};
3583 static const RECT dst_rect_flipy = {0, 480, 640, 0};
3584 static const RECT src_rect64 = {0, 0, 64, 64};
3585 static const RECT src_rect64_flipy = {0, 64, 64, 0};
3586 static const RECT dst_rect64 = {0, 0, 64, 64};
3587 static const RECT dst_rect64_flipy = {0, 64, 64, 0};
3589 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
3590 0, 0, 640, 480, NULL, NULL, NULL, NULL);
3591 d3d = Direct3DCreate9(D3D_SDK_VERSION);
3592 ok(!!d3d, "Failed to create a D3D object.\n");
3593 if (!(device = create_device(d3d, window, window, TRUE)))
3595 skip("Failed to create a D3D device, skipping tests.\n");
3596 goto done;
3599 /* Create our temporary surfaces in system memory. */
3600 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
3601 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp32, NULL);
3602 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
3603 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64,
3604 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp64, NULL);
3605 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
3607 /* Create offscreen plain surfaces in D3DPOOL_DEFAULT. */
3608 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
3609 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen32, NULL);
3610 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
3611 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64,
3612 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen64, NULL);
3613 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
3614 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64,
3615 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen_dest64, NULL);
3616 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
3618 /* Create render target surfaces. */
3619 hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32,
3620 D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt32, NULL );
3621 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
3622 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64,
3623 D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt64, NULL );
3624 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
3625 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64,
3626 D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt_dest64, NULL );
3627 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
3628 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
3629 ok(SUCCEEDED(hr), "Failed to get back buffer, hr %#x.\n", hr);
3631 /* Create render target textures. */
3632 hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, D3DUSAGE_RENDERTARGET,
3633 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt32, NULL);
3634 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
3635 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET,
3636 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt64, NULL);
3637 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
3638 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET,
3639 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt_dest64, NULL);
3640 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
3641 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1, D3DUSAGE_RENDERTARGET,
3642 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt_dest640_480, NULL);
3643 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
3644 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt32, 0, &surf_tex_rt32);
3645 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
3646 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt64, 0, &surf_tex_rt64);
3647 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
3648 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt_dest64, 0, &surf_tex_rt_dest64);
3649 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
3650 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt_dest640_480, 0, &surf_tex_rt_dest640_480);
3651 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
3653 /* Create regular textures in D3DPOOL_DEFAULT. */
3654 hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex32, NULL);
3655 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
3656 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex64, NULL);
3657 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
3658 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_dest64, NULL);
3659 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
3660 hr = IDirect3DTexture9_GetSurfaceLevel(tex32, 0, &surf_tex32);
3661 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
3662 hr = IDirect3DTexture9_GetSurfaceLevel(tex64, 0, &surf_tex64);
3663 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
3664 hr = IDirect3DTexture9_GetSurfaceLevel(tex_dest64, 0, &surf_tex_dest64);
3665 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
3667 /**********************************************************************
3668 * Tests for when the source parameter is an offscreen plain surface. *
3669 **********************************************************************/
3671 /* Fill the offscreen 64x64 surface with green. */
3672 fill_surface(surf_offscreen64, 0xff00ff00, 0);
3674 /* offscreenplain ==> offscreenplain, same size. */
3675 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_offscreen_dest64, NULL, D3DTEXF_NONE);
3676 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3677 color = getPixelColorFromSurface(surf_offscreen_dest64, 32, 32);
3678 ok(color == 0xff00ff00, "Got unexpected color 0x%08x.\n", color);
3679 /* Blit without scaling. */
3680 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64,
3681 surf_offscreen_dest64, &dst_rect64, D3DTEXF_NONE);
3682 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3683 /* Flipping in y-direction through src_rect, no scaling (not allowed). */
3684 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy,
3685 surf_offscreen_dest64, &dst_rect64, D3DTEXF_NONE);
3686 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3687 /* Flipping in y-direction through dst_rect, no scaling (not allowed). */
3688 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64,
3689 surf_offscreen_dest64, &dst_rect64_flipy, D3DTEXF_NONE);
3690 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3692 /* offscreenplain ==> rendertarget texture, same size. */
3693 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_rt_dest64, NULL, D3DTEXF_NONE);
3694 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3695 /* We can't lock rendertarget textures, so copy to our temp surface first. */
3696 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3697 ok(SUCCEEDED(hr), "Failed to get render target data, hr %#x.\n", hr);
3698 color = getPixelColorFromSurface(surf_temp64, 32, 32);
3699 ok(color == 0xff00ff00, "Got unexpected color 0x%08x.\n", color);
3700 /* Blit without scaling. */
3701 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64,
3702 surf_tex_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3703 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3704 /* Flipping in y-direction through src_rect, no scaling (not allowed). */
3705 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy,
3706 surf_tex_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3707 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3708 /* Flipping in y-direction through dst_rect, no scaling (not allowed). */
3709 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64,
3710 surf_tex_rt_dest64, &dst_rect64_flipy, D3DTEXF_NONE);
3711 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3713 /* offscreenplain ==> rendertarget surface, same size. */
3714 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_rt_dest64, NULL, D3DTEXF_NONE);
3715 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3716 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
3717 ok(color == 0xff00ff00, "Got unexpected color 0x%08x.\n", color);
3718 /* Blit without scaling. */
3719 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64,
3720 surf_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3721 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3722 /* Flipping in y-direction through src_rect, no scaling (not allowed). */
3723 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy,
3724 surf_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3725 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3726 /* Flipping in y-direction through dst_rect, no scaling (not allowed). */
3727 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64,
3728 surf_rt_dest64, &dst_rect64_flipy, D3DTEXF_NONE);
3729 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3731 /* offscreenplain ==> texture, same size (should fail). */
3732 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_dest64, NULL, D3DTEXF_NONE);
3733 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3735 /* Fill the smaller offscreen surface with red. */
3736 fill_surface(surf_offscreen32, 0xffff0000, 0);
3738 /* offscreenplain ==> offscreenplain, scaling (should fail). */
3739 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_offscreen64, NULL, D3DTEXF_NONE);
3740 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3742 /* offscreenplain ==> rendertarget texture, scaling. */
3743 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_rt_dest64, NULL, D3DTEXF_NONE);
3744 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3745 /* We can't lock rendertarget textures, so copy to our temp surface first. */
3746 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3747 ok(SUCCEEDED(hr), "Failed to get render target data, hr %#x.\n", hr);
3748 color = getPixelColorFromSurface(surf_temp64, 48, 48);
3749 ok(color == 0xffff0000, "Got unexpected color 0x%08x.\n", color);
3751 /* offscreenplain ==> rendertarget surface, scaling. */
3752 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_rt_dest64, NULL, D3DTEXF_NONE);
3753 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3754 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
3755 ok(color == 0xffff0000, "Got unexpected color 0x%08x.\n", color);
3757 /* offscreenplain ==> texture, scaling (should fail). */
3758 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_dest64, NULL, D3DTEXF_NONE);
3759 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3761 /*************************************************************
3762 * Tests for when the source parameter is a regular texture. *
3763 *************************************************************/
3765 /* Fill the surface of the regular texture with blue. */
3766 /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT. */
3767 fill_surface(surf_temp64, 0xff0000ff, 0);
3768 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex64, NULL);
3769 ok(SUCCEEDED(hr), "Failed to update surface, hr %#x.\n", hr);
3771 /* texture ==> offscreenplain, same size. */
3772 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_offscreen64, NULL, D3DTEXF_NONE);
3773 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3775 /* texture ==> rendertarget texture, same size. */
3776 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_rt_dest64, NULL, D3DTEXF_NONE);
3777 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3778 /* We can't lock rendertarget textures, so copy to our temp surface first. */
3779 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3780 ok(SUCCEEDED(hr), "Failed to get render target data, hr %#x.\n", hr);
3781 color = getPixelColorFromSurface(surf_temp64, 32, 32);
3782 ok(color == 0xff0000ff, "Got unexpected color 0x%08x.\n", color);
3783 /* Blit without scaling. */
3784 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64,
3785 surf_tex_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3786 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3787 /* Flipping in y-direction through src_rect, no scaling (not allowed). */
3788 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64_flipy,
3789 surf_tex_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3790 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3791 /* Flipping in y-direction through dst_rect, no scaling (not allowed). */
3792 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64,
3793 surf_tex_rt_dest64, &dst_rect64_flipy, D3DTEXF_NONE);
3794 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3796 /* texture ==> rendertarget surface, same size. */
3797 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_rt_dest64, NULL, D3DTEXF_NONE);
3798 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3799 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
3800 ok(color == 0xff0000ff, "Got unexpected color 0x%08x.\n", color);
3801 /* Blit without scaling. */
3802 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64,
3803 surf_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3804 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3805 /* Flipping in y-direction through src_rect, no scaling (not allowed). */
3806 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64_flipy,
3807 surf_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3808 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3809 /* Flipping in y-direction through dst_rect, no scaling (not allowed). */
3810 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64,
3811 surf_rt_dest64, &dst_rect64_flipy, D3DTEXF_NONE);
3812 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3814 /* texture ==> texture, same size (should fail). */
3815 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_dest64, NULL, D3DTEXF_NONE);
3816 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3818 /* Fill the surface of the smaller regular texture with red. */
3819 /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT. */
3820 fill_surface(surf_temp32, 0xffff0000, 0);
3821 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex32, NULL);
3822 ok(SUCCEEDED(hr), "Failed to update surface, hr %#x.\n", hr);
3824 /* texture ==> offscreenplain, scaling (should fail). */
3825 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_offscreen64, NULL, D3DTEXF_NONE);
3826 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3828 /* texture ==> rendertarget texture, scaling. */
3829 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_rt_dest64, NULL, D3DTEXF_NONE);
3830 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3831 /* We can't lock rendertarget textures, so copy to our temp surface first. */
3832 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3833 ok(SUCCEEDED(hr), "Failed to get render target data, hr %#x.\n", hr);
3834 color = getPixelColorFromSurface(surf_temp64, 48, 48);
3835 ok(color == 0xffff0000, "Got unexpected color 0x%08x.\n", color);
3837 /* texture ==> rendertarget surface, scaling. */
3838 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_rt_dest64, NULL, D3DTEXF_NONE);
3839 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3840 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
3841 ok(color == 0xffff0000, "Got unexpected color 0x%08x.\n", color);
3843 /* texture ==> texture, scaling (should fail). */
3844 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_dest64, NULL, D3DTEXF_NONE);
3845 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3847 /******************************************************************
3848 * Tests for when the source parameter is a rendertarget texture. *
3849 ******************************************************************/
3851 /* Fill the surface of the rendertarget texture with white. */
3852 /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT. */
3853 fill_surface(surf_temp64, 0xffffffff, 0);
3854 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex_rt64, NULL);
3855 ok(SUCCEEDED(hr), "Failed to update surface, hr %#x.\n", hr);
3857 /* rendertarget texture ==> offscreenplain, same size. */
3858 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_offscreen64, NULL, D3DTEXF_NONE);
3859 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3861 /* rendertarget texture ==> rendertarget texture, same size. */
3862 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_rt_dest64, NULL, D3DTEXF_NONE);
3863 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3864 /* We can't lock rendertarget textures, so copy to our temp surface first. */
3865 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3866 ok(SUCCEEDED(hr), "Failed to get render target data, hr %#x.\n", hr);
3867 color = getPixelColorFromSurface(surf_temp64, 32, 32);
3868 ok(color == 0xffffffff, "Got unexpected color 0x%08x.\n", color);
3869 /* Blit without scaling. */
3870 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64,
3871 surf_tex_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3872 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3873 /* Flipping in y-direction through src_rect, no scaling (not allowed). */
3874 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64_flipy,
3875 surf_tex_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3876 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3877 /* Flipping in y-direction through dst_rect, no scaling (not allowed). */
3878 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64,
3879 surf_tex_rt_dest64, &dst_rect64_flipy, D3DTEXF_NONE);
3880 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3882 /* rendertarget texture ==> rendertarget surface, same size. */
3883 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_rt_dest64, NULL, D3DTEXF_NONE);
3884 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3885 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
3886 ok(color == 0xffffffff, "Got unexpected color 0x%08x.\n", color);
3887 /* Blit without scaling. */
3888 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64,
3889 surf_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3890 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3891 /* Flipping in y-direction through src_rect, no scaling (not allowed). */
3892 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64_flipy,
3893 surf_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3894 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3895 /* Flipping in y-direction through dst_rect, no scaling (not allowed). */
3896 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64,
3897 surf_rt_dest64, &dst_rect64_flipy, D3DTEXF_NONE);
3898 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3900 /* rendertarget texture ==> texture, same size (should fail). */
3901 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_dest64, NULL, D3DTEXF_NONE);
3902 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3904 /* Fill the surface of the smaller rendertarget texture with red. */
3905 /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT. */
3906 fill_surface(surf_temp32, 0xffff0000, 0);
3907 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex_rt32, NULL);
3908 ok(SUCCEEDED(hr), "Failed to update surface, hr %#x.\n", hr);
3910 /* rendertarget texture ==> offscreenplain, scaling (should fail). */
3911 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_offscreen64, NULL, D3DTEXF_NONE);
3912 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3914 /* rendertarget texture ==> rendertarget texture, scaling. */
3915 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_rt_dest64, NULL, D3DTEXF_NONE);
3916 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3917 /* We can't lock rendertarget textures, so copy to our temp surface first. */
3918 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3919 ok(SUCCEEDED(hr), "Failed to get render target data, hr %#x.\n", hr);
3920 color = getPixelColorFromSurface(surf_temp64, 48, 48);
3921 ok(color == 0xffff0000, "Got unexpected color 0x%08x.\n", color);
3923 /* rendertarget texture ==> rendertarget surface, scaling. */
3924 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_rt_dest64, NULL, D3DTEXF_NONE);
3925 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3926 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
3927 ok(color == 0xffff0000, "Got unexpected color 0x%08x.\n", color);
3929 /* rendertarget texture ==> texture, scaling (should fail). */
3930 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_dest64, NULL, D3DTEXF_NONE);
3931 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3933 /******************************************************************
3934 * Tests for when the source parameter is a rendertarget surface. *
3935 ******************************************************************/
3937 /* Fill the surface of the rendertarget surface with black. */
3938 fill_surface(surf_rt64, 0xff000000, 0);
3940 /* rendertarget texture ==> offscreenplain, same size. */
3941 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_offscreen64, NULL, D3DTEXF_NONE);
3942 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3944 /* rendertarget surface ==> rendertarget texture, same size. */
3945 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_rt_dest64, NULL, D3DTEXF_NONE);
3946 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3947 /* We can't lock rendertarget textures, so copy to our temp surface first. */
3948 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3949 ok(SUCCEEDED(hr), "Failed to get render target data, hr %#x.\n", hr);
3950 color = getPixelColorFromSurface(surf_temp64, 32, 32);
3951 ok(color == 0xff000000, "Got unexpected color 0x%08x.\n", color);
3952 /* Blit without scaling. */
3953 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64,
3954 surf_tex_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3955 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3956 /* Flipping in y-direction through src_rect, no scaling (not allowed). */
3957 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64_flipy,
3958 surf_tex_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3959 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3960 /* Flipping in y-direction through dst_rect, no scaling (not allowed). */
3961 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64,
3962 surf_tex_rt_dest64, &dst_rect64_flipy, D3DTEXF_NONE);
3963 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3965 /* rendertarget surface ==> rendertarget surface, same size. */
3966 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_rt_dest64, NULL, D3DTEXF_NONE);
3967 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3968 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
3969 ok(color == 0xff000000, "Got unexpected color 0x%08x.\n", color);
3970 /* Blit without scaling. */
3971 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64,
3972 surf_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3973 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3974 /* Flipping in y-direction through src_rect, no scaling (not allowed). */
3975 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64_flipy,
3976 surf_rt_dest64, &dst_rect64_flipy, D3DTEXF_NONE);
3977 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3978 /* Flipping in y-direction through dst_rect, no scaling (not allowed). */
3979 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64,
3980 surf_rt_dest64, &dst_rect64_flipy, D3DTEXF_NONE);
3981 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3983 /* rendertarget surface ==> texture, same size (should fail). */
3984 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_dest64, NULL, D3DTEXF_NONE);
3985 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3987 /* Fill the surface of the smaller rendertarget texture with red. */
3988 fill_surface(surf_rt32, 0xffff0000, 0);
3990 /* rendertarget surface ==> offscreenplain, scaling (should fail). */
3991 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_offscreen64, NULL, D3DTEXF_NONE);
3992 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3994 /* rendertarget surface ==> rendertarget texture, scaling. */
3995 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_rt_dest64, NULL, D3DTEXF_NONE);
3996 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3997 /* We can't lock rendertarget textures, so copy to our temp surface first. */
3998 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3999 ok(SUCCEEDED(hr), "Failed to get render target data, hr %#x.\n", hr);
4000 color = getPixelColorFromSurface(surf_temp64, 48, 48);
4001 ok(color == 0xffff0000, "Got unexpected color 0x%08x.\n", color);
4003 /* rendertarget surface ==> rendertarget surface, scaling. */
4004 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_rt_dest64, NULL, D3DTEXF_NONE);
4005 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4006 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
4007 ok(color == 0xffff0000, "Got unexpected color 0x%08x.\n", color);
4009 /* rendertarget surface ==> texture, scaling (should fail). */
4010 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_dest64, NULL, D3DTEXF_NONE);
4011 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4013 /* backbuffer ==> surface tests (no scaling). */
4014 /* Blit with NULL rectangles. */
4015 hr = IDirect3DDevice9_StretchRect(device, backbuffer, NULL, surf_tex_rt_dest640_480, NULL, D3DTEXF_NONE);
4016 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4017 /* Blit without scaling. */
4018 hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect,
4019 surf_tex_rt_dest640_480, &dst_rect, D3DTEXF_NONE);
4020 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
4021 /* Flipping in y-direction through src_rect, no scaling (not allowed). */
4022 hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect_flipy,
4023 surf_tex_rt_dest640_480, &dst_rect, D3DTEXF_NONE);
4024 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4025 /* Flipping in y-direction through dst_rect, no scaling (not allowed). */
4026 hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect,
4027 surf_tex_rt_dest640_480, &dst_rect_flipy, D3DTEXF_NONE);
4028 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
4030 /* TODO: Test format conversions. */
4032 IDirect3DSurface9_Release(backbuffer);
4033 IDirect3DSurface9_Release(surf_rt32);
4034 IDirect3DSurface9_Release(surf_rt64);
4035 IDirect3DSurface9_Release(surf_rt_dest64);
4036 IDirect3DSurface9_Release(surf_temp32);
4037 IDirect3DSurface9_Release(surf_temp64);
4038 IDirect3DSurface9_Release(surf_offscreen32);
4039 IDirect3DSurface9_Release(surf_offscreen64);
4040 IDirect3DSurface9_Release(surf_offscreen_dest64);
4041 IDirect3DSurface9_Release(surf_tex_rt32);
4042 IDirect3DTexture9_Release(tex_rt32);
4043 IDirect3DSurface9_Release(surf_tex_rt64);
4044 IDirect3DTexture9_Release(tex_rt64);
4045 IDirect3DSurface9_Release(surf_tex_rt_dest64);
4046 IDirect3DTexture9_Release(tex_rt_dest64);
4047 IDirect3DSurface9_Release(surf_tex_rt_dest640_480);
4048 IDirect3DTexture9_Release(tex_rt_dest640_480);
4049 IDirect3DSurface9_Release(surf_tex32);
4050 IDirect3DTexture9_Release(tex32);
4051 IDirect3DSurface9_Release(surf_tex64);
4052 IDirect3DTexture9_Release(tex64);
4053 IDirect3DSurface9_Release(surf_tex_dest64);
4054 IDirect3DTexture9_Release(tex_dest64);
4055 refcount = IDirect3DDevice9_Release(device);
4056 ok(!refcount, "Device has %u references left.\n", refcount);
4057 done:
4058 IDirect3D9_Release(d3d);
4059 DestroyWindow(window);
4062 static void maxmip_test(void)
4064 IDirect3DTexture9 *texture;
4065 IDirect3DSurface9 *surface;
4066 IDirect3DDevice9 *device;
4067 IDirect3D9 *d3d;
4068 D3DCOLOR color;
4069 ULONG refcount;
4070 D3DCAPS9 caps;
4071 HWND window;
4072 HRESULT hr;
4073 DWORD ret;
4075 static const struct
4077 struct
4079 float x, y, z;
4080 float s, t;
4082 v[4];
4084 quads[] =
4087 {-1.0, -1.0, 0.0, 0.0, 0.0},
4088 {-1.0, 0.0, 0.0, 0.0, 1.0},
4089 { 0.0, -1.0, 0.0, 1.0, 0.0},
4090 { 0.0, 0.0, 0.0, 1.0, 1.0},
4093 { 0.0, -1.0, 0.0, 0.0, 0.0},
4094 { 0.0, 0.0, 0.0, 0.0, 1.0},
4095 { 1.0, -1.0, 0.0, 1.0, 0.0},
4096 { 1.0, 0.0, 0.0, 1.0, 1.0},
4099 { 0.0, 0.0, 0.0, 0.0, 0.0},
4100 { 0.0, 1.0, 0.0, 0.0, 1.0},
4101 { 1.0, 0.0, 0.0, 1.0, 0.0},
4102 { 1.0, 1.0, 0.0, 1.0, 1.0},
4105 {-1.0, 0.0, 0.0, 0.0, 0.0},
4106 {-1.0, 1.0, 0.0, 0.0, 1.0},
4107 { 0.0, 0.0, 0.0, 1.0, 0.0},
4108 { 0.0, 1.0, 0.0, 1.0, 1.0},
4112 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
4113 0, 0, 640, 480, NULL, NULL, NULL, NULL);
4114 d3d = Direct3DCreate9(D3D_SDK_VERSION);
4115 ok(!!d3d, "Failed to create a D3D object.\n");
4116 if (!(device = create_device(d3d, window, window, TRUE)))
4118 skip("Failed to create a D3D device, skipping tests.\n");
4119 goto done;
4122 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
4123 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
4124 if (!(caps.TextureCaps & D3DPTEXTURECAPS_MIPMAP))
4126 skip("No mipmap support, skipping tests.\n");
4127 IDirect3DDevice9_Release(device);
4128 goto done;
4131 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 3, 0,
4132 D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
4133 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
4135 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
4136 ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
4137 fill_surface(surface, 0xffff0000, 0);
4138 IDirect3DSurface9_Release(surface);
4139 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 1, &surface);
4140 ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
4141 fill_surface(surface, 0xff00ff00, 0);
4142 IDirect3DSurface9_Release(surface);
4143 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 2, &surface);
4144 ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
4145 fill_surface(surface, 0xff0000ff, 0);
4146 IDirect3DSurface9_Release(surface);
4148 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4149 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
4150 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4151 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4153 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
4154 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
4155 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
4156 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
4158 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
4159 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4161 hr = IDirect3DDevice9_BeginScene(device);
4162 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
4164 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
4165 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4166 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads->v));
4167 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4169 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
4170 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4171 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[1], sizeof(*quads->v));
4172 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4174 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
4175 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4176 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[2], sizeof(*quads->v));
4177 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4179 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
4180 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4181 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[3], sizeof(*quads->v));
4182 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4184 hr = IDirect3DDevice9_EndScene(device);
4185 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
4187 /* With mipmapping disabled, the max mip level is ignored, only level 0 is used */
4188 color = getPixelColor(device, 160, 360);
4189 ok(color == 0x00ff0000, "MaxMip 0, no mipfilter has color 0x%08x.\n", color);
4190 color = getPixelColor(device, 480, 360);
4191 ok(color == 0x00ff0000, "MaxMip 1, no mipfilter has color 0x%08x.\n", color);
4192 color = getPixelColor(device, 480, 120);
4193 ok(color == 0x00ff0000, "MaxMip 2, no mipfilter has color 0x%08x.\n", color);
4194 color = getPixelColor(device, 160, 120);
4195 ok(color == 0x00ff0000, "MaxMip 3, no mipfilter has color 0x%08x.\n", color);
4196 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4197 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
4199 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
4200 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
4202 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
4203 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4205 hr = IDirect3DDevice9_BeginScene(device);
4206 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
4208 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
4209 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4210 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads->v));
4211 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4213 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
4214 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4215 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[1], sizeof(*quads->v));
4216 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4218 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
4219 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4220 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[2], sizeof(*quads->v));
4221 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4223 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
4224 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4225 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[3], sizeof(*quads->v));
4226 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4228 hr = IDirect3DDevice9_EndScene(device);
4229 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
4231 /* Max Mip level 0-2 sample from the specified texture level, Max Mip
4232 * level 3 (> levels in texture) samples from the highest level in the
4233 * texture (level 2). */
4234 color = getPixelColor(device, 160, 360);
4235 ok(color == 0x00ff0000, "MaxMip 0, point mipfilter has color 0x%08x.\n", color);
4236 color = getPixelColor(device, 480, 360);
4237 ok(color == 0x0000ff00, "MaxMip 1, point mipfilter has color 0x%08x.\n", color);
4238 color = getPixelColor(device, 480, 120);
4239 ok(color == 0x000000ff, "MaxMip 2, point mipfilter has color 0x%08x.\n", color);
4240 color = getPixelColor(device, 160, 120);
4241 ok(color == 0x000000ff, "MaxMip 3, point mipfilter has color 0x%08x.\n", color);
4242 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4243 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
4245 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
4246 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4248 hr = IDirect3DDevice9_BeginScene(device);
4249 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
4251 /* Mipmapping OFF, LOD level smaller than MAXMIPLEVEL. LOD level limits */
4252 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
4253 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4254 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
4255 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4256 ret = IDirect3DTexture9_SetLOD(texture, 1);
4257 ok(ret == 0, "Got unexpected LOD %u.\n", ret);
4258 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads->v));
4259 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4261 /* Mipmapping ON, LOD level smaller than max mip level. LOD level limits */
4262 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
4263 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4264 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
4265 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4266 ret = IDirect3DTexture9_SetLOD(texture, 2);
4267 ok(ret == 1, "Got unexpected LOD %u.\n", ret);
4268 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[1], sizeof(*quads->v));
4269 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4271 /* Mipmapping ON, LOD level bigger than max mip level. MAXMIPLEVEL limits */
4272 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
4273 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4274 ret = IDirect3DTexture9_SetLOD(texture, 1);
4275 ok(ret == 2, "Got unexpected LOD %u.\n", ret);
4276 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[2], sizeof(*quads->v));
4277 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4279 /* Mipmapping OFF, LOD level bigger than max mip level. LOD level limits */
4280 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
4281 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4282 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
4283 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4284 ret = IDirect3DTexture9_SetLOD(texture, 1);
4285 ok(ret == 1, "Got unexpected LOD %u.\n", ret);
4286 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[3], sizeof(*quads->v));
4287 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4289 hr = IDirect3DDevice9_EndScene(device);
4290 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
4292 /* Max Mip level 0-2 sample from the specified texture level, Max Mip
4293 * level 3 (> levels in texture) samples from the highest level in the
4294 * texture (level 2). */
4295 color = getPixelColor(device, 160, 360);
4296 ok(color == 0x0000ff00, "MaxMip 0, LOD 1, none mipfilter has color 0x%08x.\n", color);
4297 color = getPixelColor(device, 480, 360);
4298 ok(color == 0x000000ff, "MaxMip 1, LOD 2, point mipfilter has color 0x%08x.\n", color);
4299 color = getPixelColor(device, 480, 120);
4300 ok(color == 0x000000ff, "MaxMip 2, LOD 1, point mipfilter has color 0x%08x.\n", color);
4301 color = getPixelColor(device, 160, 120);
4302 ok(color == 0x0000ff00, "MaxMip 2, LOD 1, none mipfilter has color 0x%08x.\n", color);
4304 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4305 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
4307 IDirect3DTexture9_Release(texture);
4308 refcount = IDirect3DDevice9_Release(device);
4309 ok(!refcount, "Device has %u references left.\n", refcount);
4310 done:
4311 IDirect3D9_Release(d3d);
4312 DestroyWindow(window);
4315 static void release_buffer_test(void)
4317 IDirect3DVertexBuffer9 *vb;
4318 IDirect3DIndexBuffer9 *ib;
4319 IDirect3DDevice9 *device;
4320 IDirect3D9 *d3d;
4321 D3DCOLOR color;
4322 ULONG refcount;
4323 HWND window;
4324 HRESULT hr;
4325 BYTE *data;
4326 LONG ref;
4328 static const short indices[] = {3, 4, 5};
4329 static const struct
4331 struct vec3 position;
4332 DWORD diffuse;
4334 quad[] =
4336 {{-1.0f, -1.0f, 0.1f}, 0xffff0000},
4337 {{-1.0f, 1.0f, 0.1f}, 0xffff0000},
4338 {{ 1.0f, 1.0f, 0.1f}, 0xffff0000},
4340 {{-1.0f, -1.0f, 0.1f}, 0xff00ff00},
4341 {{-1.0f, 1.0f, 0.1f}, 0xff00ff00},
4342 {{ 1.0f, 1.0f, 0.1f}, 0xff00ff00},
4345 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
4346 0, 0, 640, 480, NULL, NULL, NULL, NULL);
4347 d3d = Direct3DCreate9(D3D_SDK_VERSION);
4348 ok(!!d3d, "Failed to create a D3D object.\n");
4349 if (!(device = create_device(d3d, window, window, TRUE)))
4351 skip("Failed to create a D3D device, skipping tests.\n");
4352 goto done;
4355 /* Index and vertex buffers should always be creatable */
4356 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0,
4357 D3DFVF_XYZ | D3DFVF_DIFFUSE, D3DPOOL_MANAGED, &vb, NULL);
4358 ok(SUCCEEDED(hr), "Failed to create vertex buffer, hr %#x.\n", hr);
4359 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
4360 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
4361 memcpy(data, quad, sizeof(quad));
4362 hr = IDirect3DVertexBuffer9_Unlock(vb);
4363 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
4365 hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0,
4366 D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
4367 ok(SUCCEEDED(hr), "Failed to create index buffer, hr %#x.\n", hr);
4368 hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
4369 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
4370 memcpy(data, indices, sizeof(indices));
4371 hr = IDirect3DIndexBuffer9_Unlock(ib);
4372 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
4374 hr = IDirect3DDevice9_SetIndices(device, ib);
4375 ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
4376 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad[0]));
4377 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
4378 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
4379 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4380 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
4381 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
4383 /* Now destroy the bound index buffer and draw again */
4384 ref = IDirect3DIndexBuffer9_Release(ib);
4385 ok(ref == 0, "Index Buffer reference count is %08d\n", ref);
4387 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
4388 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
4390 hr = IDirect3DDevice9_BeginScene(device);
4391 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
4392 /* Deliberately using minvertexindex = 0 and numVertices = 6 to prevent
4393 * D3D from making assumptions about the indices or vertices. */
4394 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 3, 3, 0, 1);
4395 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4396 hr = IDirect3DDevice9_EndScene(device);
4397 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
4399 color = getPixelColor(device, 160, 120);
4400 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1), "Got unexpected color 0x%08x.\n", color);
4401 color = getPixelColor(device, 480, 360);
4402 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1), "Got unexpected color 0x%08x.\n", color);
4404 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4405 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4407 /* Index buffer was already destroyed as part of the test */
4408 IDirect3DVertexBuffer9_Release(vb);
4409 refcount = IDirect3DDevice9_Release(device);
4410 ok(!refcount, "Device has %u references left.\n", refcount);
4411 done:
4412 IDirect3D9_Release(d3d);
4413 DestroyWindow(window);
4416 static void float_texture_test(void)
4418 IDirect3DTexture9 *texture;
4419 IDirect3DDevice9 *device;
4420 D3DLOCKED_RECT lr;
4421 IDirect3D9 *d3d;
4422 ULONG refcount;
4423 float *data;
4424 DWORD color;
4425 HWND window;
4426 HRESULT hr;
4428 static const float quad[] =
4430 -1.0f, -1.0f, 0.1f, 0.0f, 0.0f,
4431 -1.0f, 1.0f, 0.1f, 0.0f, 1.0f,
4432 1.0f, -1.0f, 0.1f, 1.0f, 0.0f,
4433 1.0f, 1.0f, 0.1f, 1.0f, 1.0f,
4436 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
4437 0, 0, 640, 480, NULL, NULL, NULL, NULL);
4438 d3d = Direct3DCreate9(D3D_SDK_VERSION);
4439 ok(!!d3d, "Failed to create a D3D object.\n");
4440 if (!(device = create_device(d3d, window, window, TRUE)))
4442 skip("Failed to create a D3D device, skipping tests.\n");
4443 goto done;
4446 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
4447 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_R32F) != D3D_OK)
4449 skip("D3DFMT_R32F textures not supported\n");
4450 IDirect3DDevice9_Release(device);
4451 goto done;
4454 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_R32F, D3DPOOL_MANAGED, &texture, NULL);
4455 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
4457 memset(&lr, 0, sizeof(lr));
4458 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
4459 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
4460 data = lr.pBits;
4461 *data = 0.0;
4462 hr = IDirect3DTexture9_UnlockRect(texture, 0);
4463 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
4465 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
4466 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
4467 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
4468 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
4470 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
4471 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
4473 hr = IDirect3DDevice9_BeginScene(device);
4474 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
4475 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4476 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
4477 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4478 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4479 hr = IDirect3DDevice9_EndScene(device);
4480 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
4482 color = getPixelColor(device, 240, 320);
4483 ok(color == 0x0000ffff, "R32F with value 0.0 has color %08x, expected 0x0000ffff\n", color);
4485 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4486 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4488 IDirect3DTexture9_Release(texture);
4489 refcount = IDirect3DDevice9_Release(device);
4490 ok(!refcount, "Device has %u references left.\n", refcount);
4491 done:
4492 IDirect3D9_Release(d3d);
4493 DestroyWindow(window);
4496 static void g16r16_texture_test(void)
4498 IDirect3DTexture9 *texture;
4499 IDirect3DDevice9 *device;
4500 D3DLOCKED_RECT lr;
4501 IDirect3D9 *d3d;
4502 ULONG refcount;
4503 DWORD *data;
4504 DWORD color;
4505 HWND window;
4506 HRESULT hr;
4508 static const float quad[] =
4510 -1.0f, -1.0f, 0.1f, 0.0f, 0.0f,
4511 -1.0f, 1.0f, 0.1f, 0.0f, 1.0f,
4512 1.0f, -1.0f, 0.1f, 1.0f, 0.0f,
4513 1.0f, 1.0f, 0.1f, 1.0f, 1.0f,
4516 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
4517 0, 0, 640, 480, NULL, NULL, NULL, NULL);
4518 d3d = Direct3DCreate9(D3D_SDK_VERSION);
4519 ok(!!d3d, "Failed to create a D3D object.\n");
4520 if (!(device = create_device(d3d, window, window, TRUE)))
4522 skip("Failed to create a D3D device, skipping tests.\n");
4523 goto done;
4526 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
4527 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_G16R16) != D3D_OK)
4529 skip("D3DFMT_G16R16 textures not supported\n");
4530 IDirect3DDevice9_Release(device);
4531 goto done;
4534 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_G16R16, D3DPOOL_MANAGED, &texture, NULL);
4535 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
4537 memset(&lr, 0, sizeof(lr));
4538 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
4539 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
4540 data = lr.pBits;
4541 *data = 0x0f00f000;
4542 hr = IDirect3DTexture9_UnlockRect(texture, 0);
4543 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
4545 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
4546 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
4547 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
4548 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
4550 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
4551 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
4553 hr = IDirect3DDevice9_BeginScene(device);
4554 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
4555 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4556 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
4557 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4558 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4559 hr = IDirect3DDevice9_EndScene(device);
4560 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
4562 color = getPixelColor(device, 240, 320);
4563 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xf0, 0x0f, 0xff), 1),
4564 "D3DFMT_G16R16 with value 0x00ffff00 has color %08x, expected 0x00f00fff\n", color);
4566 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4567 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4569 IDirect3DTexture9_Release(texture);
4570 refcount = IDirect3DDevice9_Release(device);
4571 ok(!refcount, "Device has %u references left.\n", refcount);
4572 done:
4573 IDirect3D9_Release(d3d);
4574 DestroyWindow(window);
4577 static void check_rect(IDirect3DDevice9 *device, RECT r, const char *message)
4579 LONG x_coords[2][2] =
4581 {r.left - 1, r.left + 1},
4582 {r.right + 1, r.right - 1},
4584 LONG y_coords[2][2] =
4586 {r.top - 1, r.top + 1},
4587 {r.bottom + 1, r.bottom - 1}
4589 unsigned int i, j, x_side, y_side;
4591 for (i = 0; i < 2; ++i)
4593 for (j = 0; j < 2; ++j)
4595 for (x_side = 0; x_side < 2; ++x_side)
4597 for (y_side = 0; y_side < 2; ++y_side)
4599 unsigned int x = x_coords[i][x_side], y = y_coords[j][y_side];
4600 DWORD color;
4601 DWORD expected = (x_side == 1 && y_side == 1) ? 0x00ffffff : 0;
4603 color = getPixelColor(device, x, y);
4604 ok(color == expected, "%s: Pixel (%d, %d) has color %08x, expected %08x\n",
4605 message, x, y, color, expected);
4612 struct projected_textures_test_run
4614 const char *message;
4615 DWORD flags;
4616 IDirect3DVertexDeclaration9 *decl;
4617 BOOL vs, ps;
4618 RECT rect;
4621 static void projected_textures_test(IDirect3DDevice9 *device,
4622 struct projected_textures_test_run tests[4])
4624 unsigned int i;
4626 static const DWORD vertex_shader[] =
4628 0xfffe0101, /* vs_1_1 */
4629 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4630 0x0000001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
4631 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4632 0x00000001, 0xe00f0000, 0x90e40001, /* mov oT0, v1 */
4633 0x0000ffff /* end */
4635 static const DWORD pixel_shader[] =
4637 0xffff0103, /* ps_1_3 */
4638 0x00000042, 0xb00f0000, /* tex t0 */
4639 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
4640 0x0000ffff /* end */
4642 IDirect3DVertexShader9 *vs = NULL;
4643 IDirect3DPixelShader9 *ps = NULL;
4644 IDirect3D9 *d3d;
4645 D3DCAPS9 caps;
4646 HRESULT hr;
4648 IDirect3DDevice9_GetDirect3D(device, &d3d);
4649 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
4650 ok(SUCCEEDED(hr), "GetDeviceCaps failed (%08x)\n", hr);
4651 IDirect3D9_Release(d3d);
4653 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
4655 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader, &vs);
4656 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
4658 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 3))
4660 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader, &ps);
4661 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
4664 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0f, 0);
4665 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4667 hr = IDirect3DDevice9_BeginScene(device);
4668 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
4670 for (i = 0; i < 4; ++i)
4672 DWORD value = 0xdeadbeef;
4673 static const float proj_quads[] =
4675 -1.0f, -1.0f, 0.1f, 0.0f, 0.0f, 4.0f, 6.0f,
4676 -1.0f, 0.0f, 0.1f, 0.0f, 4.0f, 4.0f, 6.0f,
4677 0.0f, -1.0f, 0.1f, 4.0f, 0.0f, 4.0f, 6.0f,
4678 0.0f, 0.0f, 0.1f, 4.0f, 4.0f, 4.0f, 6.0f,
4680 0.0f, -1.0f, 0.1f, 0.0f, 0.0f, 4.0f, 6.0f,
4681 0.0f, 0.0f, 0.1f, 0.0f, 4.0f, 4.0f, 6.0f,
4682 1.0f, -1.0f, 0.1f, 4.0f, 0.0f, 4.0f, 6.0f,
4683 1.0f, 0.0f, 0.1f, 4.0f, 4.0f, 4.0f, 6.0f,
4685 -1.0f, 0.0f, 0.1f, 0.0f, 0.0f, 4.0f, 6.0f,
4686 -1.0f, 1.0f, 0.1f, 0.0f, 4.0f, 4.0f, 6.0f,
4687 0.0f, 0.0f, 0.1f, 4.0f, 0.0f, 4.0f, 6.0f,
4688 0.0f, 1.0f, 0.1f, 4.0f, 4.0f, 4.0f, 6.0f,
4690 0.0f, 0.0f, 0.1f, 0.0f, 0.0f, 4.0f, 6.0f,
4691 0.0f, 1.0f, 0.1f, 0.0f, 4.0f, 4.0f, 6.0f,
4692 1.0f, 0.0f, 0.1f, 4.0f, 0.0f, 4.0f, 6.0f,
4693 1.0f, 1.0f, 0.1f, 4.0f, 4.0f, 4.0f, 6.0f,
4696 if (tests[i].vs)
4698 if (!vs)
4700 skip("Vertex shaders not supported, skipping\n");
4701 continue;
4703 hr = IDirect3DDevice9_SetVertexShader(device, vs);
4705 else
4706 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
4707 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
4708 if (tests[i].ps)
4710 if (!ps)
4712 skip("Pixel shaders not supported, skipping\n");
4713 continue;
4715 hr = IDirect3DDevice9_SetPixelShader(device, ps);
4717 else
4718 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4719 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
4721 hr = IDirect3DDevice9_SetVertexDeclaration(device, tests[i].decl);
4722 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4724 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, tests[i].flags);
4725 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4726 hr = IDirect3DDevice9_GetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, &value);
4727 ok(SUCCEEDED(hr) && value == tests[i].flags,
4728 "GetTextureStageState returned: hr %08x, value %08x.\n", hr, value);
4730 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,
4731 &proj_quads[i * 4 * 7], 7 * sizeof(float));
4732 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4735 hr = IDirect3DDevice9_EndScene(device);
4736 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
4738 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
4739 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4740 if (vs) IDirect3DVertexShader9_Release(vs);
4741 if (ps) IDirect3DPixelShader9_Release(ps);
4743 for (i = 0; i < 4; ++i)
4745 if ((!tests[i].vs || vs) && (!tests[i].ps || ps))
4746 check_rect(device, tests[i].rect, tests[i].message);
4749 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4750 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4753 static void texture_transform_flags_test(void)
4755 HRESULT hr;
4756 IDirect3D9 *d3d;
4757 D3DFORMAT fmt = D3DFMT_X8R8G8B8;
4758 D3DCAPS9 caps;
4759 IDirect3DTexture9 *texture = NULL;
4760 IDirect3DVolumeTexture9 *volume = NULL;
4761 IDirect3DDevice9 *device;
4762 unsigned int x, y, z;
4763 D3DLOCKED_RECT lr;
4764 D3DLOCKED_BOX lb;
4765 D3DCOLOR color;
4766 ULONG refcount;
4767 HWND window;
4768 UINT w, h;
4769 IDirect3DVertexDeclaration9 *decl, *decl2, *decl3, *decl4;
4771 static const D3DVERTEXELEMENT9 decl_elements[] = {
4772 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4773 {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
4774 D3DDECL_END()
4776 static const D3DVERTEXELEMENT9 decl_elements2[] = {
4777 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4778 {0, 12, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
4779 D3DDECL_END()
4781 static const D3DVERTEXELEMENT9 decl_elements3[] = {
4782 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4783 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
4784 D3DDECL_END()
4786 static const D3DVERTEXELEMENT9 decl_elements4[] = {
4787 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4788 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
4789 D3DDECL_END()
4791 static const unsigned char proj_texdata[] = {0x00, 0x00, 0x00, 0x00,
4792 0x00, 0xff, 0x00, 0x00,
4793 0x00, 0x00, 0x00, 0x00,
4794 0x00, 0x00, 0x00, 0x00};
4795 static const D3DMATRIX identity =
4797 1.0f, 0.0f, 0.0f, 0.0f,
4798 0.0f, 1.0f, 0.0f, 0.0f,
4799 0.0f, 0.0f, 1.0f, 0.0f,
4800 0.0f, 0.0f, 0.0f, 1.0f,
4801 }}};
4803 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
4804 0, 0, 640, 480, NULL, NULL, NULL, NULL);
4805 d3d = Direct3DCreate9(D3D_SDK_VERSION);
4806 ok(!!d3d, "Failed to create a D3D object.\n");
4807 if (!(device = create_device(d3d, window, window, TRUE)))
4809 skip("Failed to create a D3D device, skipping tests.\n");
4810 goto done;
4813 memset(&lr, 0, sizeof(lr));
4814 memset(&lb, 0, sizeof(lb));
4815 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
4816 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16) == D3D_OK)
4817 fmt = D3DFMT_A16B16G16R16;
4819 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
4820 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
4821 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
4822 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
4823 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements3, &decl3);
4824 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
4825 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements4, &decl4);
4826 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
4827 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
4828 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_SRGBTEXTURE) returned %08x\n", hr);
4829 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
4830 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MAGFILTER) returned %08x\n", hr);
4831 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
4832 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MINFILTER) returned %08x\n", hr);
4833 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
4834 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MIPFILTER) returned %08x\n", hr);
4835 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
4836 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSU) returned %08x\n", hr);
4837 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
4838 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSV) returned %08x\n", hr);
4839 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSW, D3DTADDRESS_CLAMP);
4840 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSW) returned %08x\n", hr);
4841 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
4842 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState(D3DTSS_COLOROP) returned %08x\n", hr);
4843 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
4844 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState(D3DTSS_COLORARG1) returned %08x\n", hr);
4845 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
4846 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState(D3DRS_LIGHTING) returned %08x\n", hr);
4847 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
4848 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4850 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
4851 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
4852 w = min(1024, caps.MaxTextureWidth);
4853 h = min(1024, caps.MaxTextureHeight);
4854 hr = IDirect3DDevice9_CreateTexture(device, w, h, 1,
4855 0, fmt, D3DPOOL_MANAGED, &texture, NULL);
4856 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
4857 if (!texture)
4859 skip("Failed to create the test texture.\n");
4860 IDirect3DDevice9_Release(device);
4861 goto done;
4864 /* Unfortunately there is no easy way to set up a texture coordinate passthrough
4865 * in d3d fixed function pipeline, so create a texture that has a gradient from 0.0 to
4866 * 1.0 in red and green for the x and y coords
4868 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
4869 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %08x\n", hr);
4870 for(y = 0; y < h; y++) {
4871 for(x = 0; x < w; x++) {
4872 double r_f = (double) y / (double) h;
4873 double g_f = (double) x / (double) w;
4874 if(fmt == D3DFMT_A16B16G16R16) {
4875 unsigned short r, g;
4876 unsigned short *dst = (unsigned short *) (((char *) lr.pBits) + y * lr.Pitch + x * 8);
4877 r = (unsigned short) (r_f * 65536.0);
4878 g = (unsigned short) (g_f * 65536.0);
4879 dst[0] = r;
4880 dst[1] = g;
4881 dst[2] = 0;
4882 dst[3] = 65535;
4883 } else {
4884 unsigned char *dst = ((unsigned char *) lr.pBits) + y * lr.Pitch + x * 4;
4885 unsigned char r = (unsigned char) (r_f * 255.0);
4886 unsigned char g = (unsigned char) (g_f * 255.0);
4887 dst[0] = 0;
4888 dst[1] = g;
4889 dst[2] = r;
4890 dst[3] = 255;
4894 hr = IDirect3DTexture9_UnlockRect(texture, 0);
4895 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %08x\n", hr);
4896 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4897 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4899 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4900 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4901 hr = IDirect3DDevice9_BeginScene(device);
4902 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
4903 if(SUCCEEDED(hr))
4905 static const float quad1[] =
4907 -1.0f, -1.0f, 0.1f, 1.0f, 1.0f,
4908 -1.0f, 0.0f, 0.1f, 1.0f, 1.0f,
4909 0.0f, -1.0f, 0.1f, 1.0f, 1.0f,
4910 0.0f, 0.0f, 0.1f, 1.0f, 1.0f,
4912 static const float quad2[] =
4914 -1.0f, 0.0f, 0.1f, 1.0f, 1.0f,
4915 -1.0f, 1.0f, 0.1f, 1.0f, 1.0f,
4916 0.0f, 0.0f, 0.1f, 1.0f, 1.0f,
4917 0.0f, 1.0f, 0.1f, 1.0f, 1.0f,
4919 static const float quad3[] =
4921 0.0f, 0.0f, 0.1f, 0.5f, 0.5f,
4922 0.0f, 1.0f, 0.1f, 0.5f, 0.5f,
4923 1.0f, 0.0f, 0.1f, 0.5f, 0.5f,
4924 1.0f, 1.0f, 0.1f, 0.5f, 0.5f,
4926 static const float quad4[] =
4928 320.0f, 480.0f, 0.1f, 1.0f, 0.0f, 1.0f,
4929 320.0f, 240.0f, 0.1f, 1.0f, 0.0f, 1.0f,
4930 640.0f, 480.0f, 0.1f, 1.0f, 0.0f, 1.0f,
4931 640.0f, 240.0f, 0.1f, 1.0f, 0.0f, 1.0f,
4933 D3DMATRIX mat =
4935 0.0f, 0.0f, 0.0f, 0.0f,
4936 0.0f, 0.0f, 0.0f, 0.0f,
4937 0.0f, 0.0f, 0.0f, 0.0f,
4938 0.0f, 0.0f, 0.0f, 0.0f,
4939 }}};
4941 /* What happens with the texture matrix if D3DTSS_TEXTURETRANSFORMFLAGS is disabled? */
4942 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &mat);
4943 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4944 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
4945 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4947 /* What happens with transforms enabled? */
4948 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
4949 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4950 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
4951 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4953 /* What happens if 4 coords are used, but only 2 given ?*/
4954 U(mat).m[2][0] = 1.0f;
4955 U(mat).m[3][1] = 1.0f;
4956 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &mat);
4957 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4958 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
4959 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4960 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
4961 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4963 /* What happens with transformed geometry? This setup lead to 0/0 coords with untransformed
4964 * geometry. If the same applies to transformed vertices, the quad will be black, otherwise red,
4965 * due to the coords in the vertices. (turns out red, indeed)
4967 memset(&mat, 0, sizeof(mat));
4968 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &mat);
4969 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4970 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_TEX1);
4971 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4972 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
4973 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4974 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
4975 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4977 hr = IDirect3DDevice9_EndScene(device);
4978 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
4980 color = getPixelColor(device, 160, 360);
4981 ok(color_match(color, 0x00ffff00, 1), "quad 1 has color %08x, expected 0x00ffff00\n", color);
4982 color = getPixelColor(device, 160, 120);
4983 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
4984 color = getPixelColor(device, 480, 120);
4985 ok(color_match(color, 0x0000ff00, 1), "quad 3 has color %08x, expected 0x0000ff00\n", color);
4986 color = getPixelColor(device, 480, 360);
4987 ok(color_match(color, 0x00ff0000, 1), "quad 4 has color %08x, expected 0x00ff0000\n", color);
4988 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4989 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4991 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
4992 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4994 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4995 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4996 hr = IDirect3DDevice9_BeginScene(device);
4997 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
4998 if(SUCCEEDED(hr))
5000 static const float quad1[] =
5002 -1.0f, -1.0f, 0.1f, 0.8f, 0.2f,
5003 -1.0f, 0.0f, 0.1f, 0.8f, 0.2f,
5004 0.0f, -1.0f, 0.1f, 0.8f, 0.2f,
5005 0.0f, 0.0f, 0.1f, 0.8f, 0.2f,
5007 static const float quad2[] =
5009 -1.0f, 0.0f, 0.1f, 0.5f, 1.0f,
5010 -1.0f, 1.0f, 0.1f, 0.5f, 1.0f,
5011 0.0f, 0.0f, 0.1f, 0.5f, 1.0f,
5012 0.0f, 1.0f, 0.1f, 0.5f, 1.0f,
5014 static const float quad3[] =
5016 0.0f, 0.0f, 0.1f, 0.5f, 1.0f,
5017 0.0f, 1.0f, 0.1f, 0.5f, 1.0f,
5018 1.0f, 0.0f, 0.1f, 0.5f, 1.0f,
5019 1.0f, 1.0f, 0.1f, 0.5f, 1.0f,
5021 static const float quad4[] =
5023 0.0f, -1.0f, 0.1f, 0.8f, 0.2f,
5024 0.0f, 0.0f, 0.1f, 0.8f, 0.2f,
5025 1.0f, -1.0f, 0.1f, 0.8f, 0.2f,
5026 1.0f, 0.0f, 0.1f, 0.8f, 0.2f,
5028 D3DMATRIX mat =
5030 0.0f, 0.0f, 0.0f, 0.0f,
5031 0.0f, 0.0f, 0.0f, 0.0f,
5032 0.0f, 1.0f, 0.0f, 0.0f,
5033 0.0f, 0.0f, 0.0f, 0.0f,
5034 }}};
5036 /* What happens to the default 1 in the 3rd coordinate if it is disabled? */
5037 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &mat);
5038 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
5039 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
5040 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
5042 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
5043 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
5045 /* D3DTFF_COUNT1 does not work on Nvidia drivers. It behaves like D3DTTFF_DISABLE. On ATI drivers
5046 * it behaves like COUNT2 because normal textures require 2 coords. */
5047 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
5048 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
5049 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 5 * sizeof(float));
5050 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
5052 /* Just to be sure, the same as quad2 above */
5053 memset(&mat, 0, sizeof(mat));
5054 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &mat);
5055 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
5056 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
5057 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
5058 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
5059 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
5061 /* Now, what happens to the 2nd coordinate(that is disabled in the matrix) if it is not
5062 * used? And what happens to the first? */
5063 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
5064 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
5065 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
5066 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
5068 hr = IDirect3DDevice9_EndScene(device);
5069 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
5071 color = getPixelColor(device, 160, 360);
5072 ok(color_match(color, 0x00ff0000, 1), "quad 1 has color %08x, expected 0x00ff0000\n", color);
5073 color = getPixelColor(device, 160, 120);
5074 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
5075 color = getPixelColor(device, 480, 120);
5076 ok(color_match(color, 0x00ff8000, 1) || color == 0x00000000,
5077 "quad 3 has color %08x, expected 0x00ff8000\n", color);
5078 color = getPixelColor(device, 480, 360);
5079 ok(color_match(color, 0x0033cc00, 1) || color_match(color, 0x00ff0000, 1),
5080 "quad 4 has color %08x, expected 0x0033cc00\n", color);
5081 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5082 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5084 IDirect3DTexture9_Release(texture);
5086 /* Test projected textures, without any fancy matrices */
5087 hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, 0, D3DFMT_L8, D3DPOOL_MANAGED, &texture, NULL);
5088 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
5089 if (SUCCEEDED(hr))
5091 struct projected_textures_test_run projected_tests_1[4] =
5094 "D3DTTFF_COUNT4 | D3DTTFF_PROJECTED - bottom left",
5095 D3DTTFF_COUNT4 | D3DTTFF_PROJECTED,
5096 decl3,
5097 FALSE, TRUE,
5098 {120, 300, 240, 390},
5101 "D3DTTFF_COUNT3 | D3DTTFF_PROJECTED - bottom right",
5102 D3DTTFF_COUNT3 | D3DTTFF_PROJECTED,
5103 decl3,
5104 FALSE, TRUE,
5105 {400, 360, 480, 420},
5107 /* Try with some invalid values */
5109 "0xffffffff (draws like COUNT4 | PROJECTED) - top left",
5110 0xffffffff,
5111 decl3,
5112 FALSE, TRUE,
5113 {120, 60, 240, 150}
5116 "D3DTTFF_COUNT3 | D3DTTFF_PROJECTED (draws non-projected) - top right",
5117 D3DTTFF_COUNT3 | D3DTTFF_PROJECTED,
5118 decl4,
5119 FALSE, TRUE,
5120 {340, 210, 360, 225},
5123 struct projected_textures_test_run projected_tests_2[4] =
5126 "D3DTTFF_PROJECTED (like COUNT4 | PROJECTED, texcoord has 4 components) - bottom left",
5127 D3DTTFF_PROJECTED,
5128 decl3,
5129 FALSE, TRUE,
5130 {120, 300, 240, 390},
5133 "D3DTTFF_PROJECTED (like COUNT3 | PROJECTED, texcoord has only 3 components) - bottom right",
5134 D3DTTFF_PROJECTED,
5135 decl,
5136 FALSE, TRUE,
5137 {400, 360, 480, 420},
5140 "0xffffffff (like COUNT3 | PROJECTED, texcoord has only 3 components) - top left",
5141 0xffffffff,
5142 decl,
5143 FALSE, TRUE,
5144 {80, 120, 160, 180},
5147 "D3DTTFF_COUNT1 (draws non-projected) - top right",
5148 D3DTTFF_COUNT1,
5149 decl4,
5150 FALSE, TRUE,
5151 {340, 210, 360, 225},
5154 struct projected_textures_test_run projected_tests_3[4] =
5157 "D3DTTFF_COUNT3 | D3DTTFF_PROJECTED (like COUNT4 | PROJECTED) - bottom left",
5158 D3DTTFF_PROJECTED,
5159 decl3,
5160 TRUE, FALSE,
5161 {120, 300, 240, 390},
5164 "D3DTTFF_COUNT3 | D3DTTFF_PROJECTED (like COUNT4 | PROJECTED) - bottom right",
5165 D3DTTFF_COUNT3 | D3DTTFF_PROJECTED,
5166 decl3,
5167 TRUE, TRUE,
5168 {440, 300, 560, 390},
5171 "0xffffffff (like COUNT4 | PROJECTED) - top left",
5172 0xffffffff,
5173 decl3,
5174 TRUE, TRUE,
5175 {120, 60, 240, 150},
5178 "D3DTTFF_PROJECTED (like COUNT4 | PROJECTED) - top right",
5179 D3DTTFF_PROJECTED,
5180 decl3,
5181 FALSE, FALSE,
5182 {440, 60, 560, 150},
5186 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &identity);
5187 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
5189 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
5190 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
5191 for(x = 0; x < 4; x++) {
5192 memcpy(((BYTE *) lr.pBits) + lr.Pitch * x, proj_texdata + 4 * x, 4 * sizeof(proj_texdata[0]));
5194 hr = IDirect3DTexture9_UnlockRect(texture, 0);
5195 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
5196 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
5197 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
5199 projected_textures_test(device, projected_tests_1);
5200 projected_textures_test(device, projected_tests_2);
5201 projected_textures_test(device, projected_tests_3);
5203 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
5204 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
5205 IDirect3DTexture9_Release(texture);
5208 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
5209 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5210 /* Use a smaller volume texture than the biggest possible size for memory and performance reasons
5211 * Thus watch out if sampling from texels between 0 and 1.
5213 hr = IDirect3DDevice9_CreateVolumeTexture(device, 32, 32, 32, 1, 0, fmt, D3DPOOL_MANAGED, &volume, 0);
5214 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
5215 "IDirect3DDevice9_CreateVolumeTexture failed with %08x\n", hr);
5216 if(!volume) {
5217 skip("Failed to create a volume texture\n");
5218 goto out;
5221 hr = IDirect3DVolumeTexture9_LockBox(volume, 0, &lb, NULL, 0);
5222 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_LockBox failed with %08x\n", hr);
5223 for(z = 0; z < 32; z++) {
5224 for(y = 0; y < 32; y++) {
5225 for(x = 0; x < 32; x++) {
5226 char size = (fmt == D3DFMT_A16B16G16R16 ? 8 : 4);
5227 void *mem = ((char *) lb.pBits) + y * lb.RowPitch + z * lb.SlicePitch + x * size;
5228 float r_f = (float) x / 31.0;
5229 float g_f = (float) y / 31.0;
5230 float b_f = (float) z / 31.0;
5232 if(fmt == D3DFMT_A16B16G16R16) {
5233 unsigned short *mem_s = mem;
5234 mem_s[0] = r_f * 65535.0;
5235 mem_s[1] = g_f * 65535.0;
5236 mem_s[2] = b_f * 65535.0;
5237 mem_s[3] = 65535;
5238 } else {
5239 unsigned char *mem_c = mem;
5240 mem_c[0] = b_f * 255.0;
5241 mem_c[1] = g_f * 255.0;
5242 mem_c[2] = r_f * 255.0;
5243 mem_c[3] = 255;
5248 hr = IDirect3DVolumeTexture9_UnlockBox(volume, 0);
5249 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
5251 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) volume);
5252 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
5254 hr = IDirect3DDevice9_BeginScene(device);
5255 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
5256 if(SUCCEEDED(hr))
5258 static const float quad1[] =
5260 -1.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5261 -1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5262 0.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5263 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5265 static const float quad2[] =
5267 -1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5268 -1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5269 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5270 0.0f, 1.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5272 static const float quad3[] =
5274 0.0f, 0.0f, 0.1f, 0.0f, 0.0f,
5275 0.0f, 1.0f, 0.1f, 0.0f, 0.0f,
5276 1.0f, 0.0f, 0.1f, 0.0f, 0.0f,
5277 1.0f, 1.0f, 0.1f, 0.0f, 0.0f,
5279 static const float quad4[] =
5281 0.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5282 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5283 1.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5284 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5286 D3DMATRIX mat =
5288 1.0f, 0.0f, 0.0f, 0.0f,
5289 0.0f, 0.0f, 1.0f, 0.0f,
5290 0.0f, 1.0f, 0.0f, 0.0f,
5291 0.0f, 0.0f, 0.0f, 1.0f,
5292 }}};
5293 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
5294 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
5296 /* Draw a quad with all 3 coords enabled. Nothing fancy. v and w are swapped, but have the same
5297 * values
5299 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &mat);
5300 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
5301 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
5302 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
5303 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
5304 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5306 /* Now disable the w coordinate. Does that change the input, or the output. The coordinates
5307 * are swapped by the matrix. If it changes the input, the v coord will be missing(green),
5308 * otherwise the w will be missing(blue).
5309 * turns out that on nvidia cards the blue color is missing, so it is an output modification.
5310 * On ATI cards the COUNT2 is ignored, and it behaves in the same way as COUNT3. */
5311 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
5312 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
5313 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
5314 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5316 /* default values? Set up the identity matrix, pass in 2 vertex coords, and enable 3 */
5317 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &identity);
5318 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
5319 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
5320 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
5321 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
5322 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
5323 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
5324 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5326 /* D3DTTFF_COUNT1. Set a NULL matrix, and count1, pass in all values as 1.0. Nvidia has count1 ==
5327 * disable. ATI extends it up to the amount of values needed for the volume texture
5329 memset(&mat, 0, sizeof(mat));
5330 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &mat);
5331 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
5332 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
5333 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
5334 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
5335 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
5336 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
5337 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5339 hr = IDirect3DDevice9_EndScene(device);
5340 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
5343 color = getPixelColor(device, 160, 360);
5344 ok(color == 0x00ffffff, "quad 1 has color %08x, expected 0x00ffffff\n", color);
5345 color = getPixelColor(device, 160, 120);
5346 ok(color == 0x00ffff00 /* NV*/ || color == 0x00ffffff /* ATI */,
5347 "quad 2 has color %08x, expected 0x00ffff00\n", color);
5348 color = getPixelColor(device, 480, 120);
5349 ok(color == 0x000000ff, "quad 3 has color %08x, expected 0x000000ff\n", color);
5350 color = getPixelColor(device, 480, 360);
5351 ok(color == 0x00ffffff || color == 0x0000ff00, "quad 4 has color %08x, expected 0x00ffffff\n", color);
5353 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5354 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5356 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff303030, 0.0, 0);
5357 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5358 hr = IDirect3DDevice9_BeginScene(device);
5359 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
5360 if(SUCCEEDED(hr))
5362 static const float quad1[] =
5364 -1.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5365 -1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5366 0.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5367 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5369 static const float quad2[] =
5371 -1.0f, 0.0f, 0.1f,
5372 -1.0f, 1.0f, 0.1f,
5373 0.0f, 0.0f, 0.1f,
5374 0.0f, 1.0f, 0.1f,
5376 static const float quad3[] =
5378 0.0f, 0.0f, 0.1f, 1.0f,
5379 0.0f, 1.0f, 0.1f, 1.0f,
5380 1.0f, 0.0f, 0.1f, 1.0f,
5381 1.0f, 1.0f, 0.1f, 1.0f,
5383 static const D3DMATRIX mat =
5385 0.0f, 0.0f, 0.0f, 0.0f,
5386 0.0f, 0.0f, 0.0f, 0.0f,
5387 0.0f, 0.0f, 0.0f, 0.0f,
5388 0.0f, 1.0f, 0.0f, 0.0f,
5389 }}};
5390 static const D3DMATRIX mat2 =
5392 0.0f, 0.0f, 0.0f, 1.0f,
5393 1.0f, 0.0f, 0.0f, 0.0f,
5394 0.0f, 1.0f, 0.0f, 0.0f,
5395 0.0f, 0.0f, 1.0f, 0.0f,
5396 }}};
5397 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
5398 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
5400 /* Default values? 4 coords used, 3 passed. What happens to the 4th?
5401 * Use COUNT3 because newer Nvidia drivers return black when there are more (output) coords
5402 * than being used by the texture(volume tex -> 3). Again, as shown in earlier test the COUNTx
5403 * affects the post-transformation output, so COUNT3 plus the matrix above is OK for testing the
5404 * 4th *input* coordinate.
5406 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &mat);
5407 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
5408 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
5409 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
5410 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
5411 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5413 /* None passed */
5414 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &identity);
5415 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
5416 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5417 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
5418 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
5419 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5421 /* 4 used, 1 passed */
5422 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
5423 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
5424 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &mat2);
5425 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
5426 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 4 * sizeof(float));
5427 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5429 hr = IDirect3DDevice9_EndScene(device);
5430 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
5432 color = getPixelColor(device, 160, 360);
5433 ok(color == 0x0000ff00, "quad 1 has color %08x, expected 0x0000ff00\n", color);
5434 color = getPixelColor(device, 160, 120);
5435 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x00000000\n", color);
5436 color = getPixelColor(device, 480, 120);
5437 ok(color == 0x00ff0000, "quad 3 has color %08x, expected 0x00ff0000\n", color);
5438 /* Quad4: unused */
5440 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5441 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5443 IDirect3DVolumeTexture9_Release(volume);
5445 out:
5446 IDirect3DVertexDeclaration9_Release(decl);
5447 IDirect3DVertexDeclaration9_Release(decl2);
5448 IDirect3DVertexDeclaration9_Release(decl3);
5449 IDirect3DVertexDeclaration9_Release(decl4);
5450 refcount = IDirect3DDevice9_Release(device);
5451 ok(!refcount, "Device has %u references left.\n", refcount);
5452 done:
5453 IDirect3D9_Release(d3d);
5454 DestroyWindow(window);
5457 static void texdepth_test(void)
5459 IDirect3DPixelShader9 *shader;
5460 IDirect3DDevice9 *device;
5461 IDirect3D9 *d3d;
5462 ULONG refcount;
5463 D3DCAPS9 caps;
5464 DWORD color;
5465 HWND window;
5466 HRESULT hr;
5468 static const float texdepth_test_data1[] = { 0.25f, 2.0f, 0.0f, 0.0f};
5469 static const float texdepth_test_data2[] = { 0.25f, 0.5f, 0.0f, 0.0f};
5470 static const float texdepth_test_data3[] = {-1.00f, 0.1f, 0.0f, 0.0f};
5471 static const float texdepth_test_data4[] = {-0.25f, -0.5f, 0.0f, 0.0f};
5472 static const float texdepth_test_data5[] = { 1.00f, -0.1f, 0.0f, 0.0f};
5473 static const float texdepth_test_data6[] = { 1.00f, 0.5f, 0.0f, 0.0f};
5474 static const float texdepth_test_data7[] = { 0.50f, 0.0f, 0.0f, 0.0f};
5475 static const DWORD shader_code[] =
5477 0xffff0104, /* ps_1_4 */
5478 0x00000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c1, 0, 0, 1, 1 */
5479 0x00000001, 0x800f0005, 0xa0e40000, /* mov r5, c0 */
5480 0x0000fffd, /* phase */
5481 0x00000057, 0x800f0005, /* texdepth r5 */
5482 0x00000001, 0x800f0000, 0xa0e40001, /* mov r0, c1 */
5483 0x0000ffff /* end */
5485 static const float vertex[] =
5487 -1.0f, -1.0f, 0.0f,
5488 -1.0f, 1.0f, 0.0f,
5489 1.0f, -1.0f, 1.0f,
5490 1.0f, 1.0f, 1.0f,
5493 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
5494 0, 0, 640, 480, NULL, NULL, NULL, NULL);
5495 d3d = Direct3DCreate9(D3D_SDK_VERSION);
5496 ok(!!d3d, "Failed to create a D3D object.\n");
5497 if (!(device = create_device(d3d, window, window, TRUE)))
5499 skip("Failed to create a D3D device, skipping tests.\n");
5500 goto done;
5503 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
5504 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
5505 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 4))
5507 skip("No ps_1_4 support, skipping tests.\n");
5508 IDirect3DDevice9_Release(device);
5509 goto done;
5512 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
5513 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5515 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffff00, 0.0, 0);
5516 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5517 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
5518 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
5519 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
5520 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
5521 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
5522 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
5523 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
5524 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
5525 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5526 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF returned %#x.\n", hr);
5528 /* Fill the depth buffer with a gradient */
5529 hr = IDirect3DDevice9_BeginScene(device);
5530 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5531 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
5532 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5533 hr = IDirect3DDevice9_EndScene(device);
5534 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5536 /* Now perform the actual tests. Same geometry, but with the shader */
5537 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
5538 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
5539 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
5540 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
5541 hr = IDirect3DDevice9_SetPixelShader(device, shader);
5542 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
5544 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data1, 1);
5545 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5546 hr = IDirect3DDevice9_BeginScene(device);
5547 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5548 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
5549 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5550 hr = IDirect3DDevice9_EndScene(device);
5551 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5553 color = getPixelColor(device, 158, 240);
5554 ok(color == 0x000000ff, "Pixel 158(25%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
5555 color = getPixelColor(device, 162, 240);
5556 ok(color == 0x00ffffff, "Pixel 158(25%% + 2 pixel) has color %08x, expected 0x00ffffff\n", color);
5558 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5559 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5561 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
5562 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
5564 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data2, 1);
5565 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5566 hr = IDirect3DDevice9_BeginScene(device);
5567 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5568 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
5569 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5570 hr = IDirect3DDevice9_EndScene(device);
5571 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5573 color = getPixelColor(device, 318, 240);
5574 ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
5575 color = getPixelColor(device, 322, 240);
5576 ok(color == 0x00ffff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
5578 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5579 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5581 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
5582 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
5584 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data3, 1);
5585 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5586 hr = IDirect3DDevice9_BeginScene(device);
5587 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5588 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
5589 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5590 hr = IDirect3DDevice9_EndScene(device);
5591 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5593 color = getPixelColor(device, 1, 240);
5594 ok(color == 0x00ff0000, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ff0000\n", color);
5596 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5597 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5599 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
5600 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
5602 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data4, 1);
5603 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5604 hr = IDirect3DDevice9_BeginScene(device);
5605 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5606 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
5607 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5608 hr = IDirect3DDevice9_EndScene(device);
5609 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5611 color = getPixelColor(device, 318, 240);
5612 ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
5613 color = getPixelColor(device, 322, 240);
5614 ok(color == 0x0000ff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x0000ff00\n", color);
5616 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5617 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5619 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
5620 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
5622 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data5, 1);
5623 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5624 hr = IDirect3DDevice9_BeginScene(device);
5625 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5626 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
5627 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5628 hr = IDirect3DDevice9_EndScene(device);
5629 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5631 color = getPixelColor(device, 1, 240);
5632 ok(color == 0x00ffff00, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
5634 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5635 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5637 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
5638 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
5640 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data6, 1);
5641 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5642 hr = IDirect3DDevice9_BeginScene(device);
5643 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5644 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
5645 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5646 hr = IDirect3DDevice9_EndScene(device);
5647 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5649 color = getPixelColor(device, 638, 240);
5650 ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
5652 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5653 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5655 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
5656 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
5658 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data7, 1);
5659 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5660 hr = IDirect3DDevice9_BeginScene(device);
5661 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5662 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
5663 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5664 hr = IDirect3DDevice9_EndScene(device);
5665 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5667 color = getPixelColor(device, 638, 240);
5668 ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
5670 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5671 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5673 IDirect3DPixelShader9_Release(shader);
5674 refcount = IDirect3DDevice9_Release(device);
5675 ok(!refcount, "Device has %u references left.\n", refcount);
5676 done:
5677 IDirect3D9_Release(d3d);
5678 DestroyWindow(window);
5681 static void texkill_test(void)
5683 IDirect3DPixelShader9 *shader;
5684 IDirect3DDevice9 *device;
5685 IDirect3D9 *d3d;
5686 ULONG refcount;
5687 D3DCAPS9 caps;
5688 DWORD color;
5689 HWND window;
5690 HRESULT hr;
5692 static const float vertex[] =
5694 /* bottom top right left */
5695 -1.0f, -1.0f, 1.0f, -0.1f, 0.9f, 0.9f, -0.1f,
5696 -1.0f, 1.0f, 1.0f, -0.1f, 0.9f, -0.1f, 0.9f,
5697 1.0f, -1.0f, 0.0f, 0.9f, -0.1f, 0.9f, -0.1f,
5698 1.0f, 1.0f, 0.0f, 0.9f, -0.1f, -0.1f, 0.9f,
5700 static const DWORD shader_code_11[] =
5702 0xffff0101, /* ps_1_1 */
5703 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
5704 0x00000041, 0xb00f0000, /* texkill t0 */
5705 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5706 0x0000ffff /* end */
5708 static const DWORD shader_code_20[] =
5710 0xffff0200, /* ps_2_0 */
5711 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
5712 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c0, 0.0, 0.0, 1.0, 1.0 */
5713 0x01000041, 0xb00f0000, /* texkill t0 */
5714 0x02000001, 0x800f0800, 0xa0e40000, /* mov oC0, c0 */
5715 0x0000ffff /* end */
5718 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
5719 0, 0, 640, 480, NULL, NULL, NULL, NULL);
5720 d3d = Direct3DCreate9(D3D_SDK_VERSION);
5721 ok(!!d3d, "Failed to create a D3D object.\n");
5722 if (!(device = create_device(d3d, window, window, TRUE)))
5724 skip("Failed to create a D3D device, skipping tests.\n");
5725 goto done;
5728 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
5729 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
5730 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 1))
5732 skip("No ps_1_1 support, skipping tests.\n");
5733 IDirect3DDevice9_Release(device);
5734 goto done;
5737 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
5738 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5739 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader);
5740 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5742 hr = IDirect3DDevice9_SetPixelShader(device, shader);
5743 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5744 hr = IDirect3DDevice9_BeginScene(device);
5745 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5746 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEXCOORDSIZE4(0) | D3DFVF_TEX1);
5747 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
5748 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
5749 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5750 hr = IDirect3DDevice9_EndScene(device);
5751 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5753 color = getPixelColor(device, 63, 46);
5754 ok(color == 0x0000ff00, "Pixel 63/46 has color %08x, expected 0x0000ff00\n", color);
5755 color = getPixelColor(device, 66, 46);
5756 ok(color == 0x0000ff00, "Pixel 66/64 has color %08x, expected 0x0000ff00\n", color);
5757 color = getPixelColor(device, 63, 49);
5758 ok(color == 0x0000ff00, "Pixel 63/49 has color %08x, expected 0x0000ff00\n", color);
5759 color = getPixelColor(device, 66, 49);
5760 ok(color == 0x00ff0000, "Pixel 66/49 has color %08x, expected 0x00ff0000\n", color);
5762 color = getPixelColor(device, 578, 46);
5763 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
5764 color = getPixelColor(device, 575, 46);
5765 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
5766 color = getPixelColor(device, 578, 49);
5767 ok(color == 0x0000ff00, "Pixel 578/49 has color %08x, expected 0x0000ff00\n", color);
5768 color = getPixelColor(device, 575, 49);
5769 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
5771 color = getPixelColor(device, 63, 430);
5772 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
5773 color = getPixelColor(device, 63, 433);
5774 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
5775 color = getPixelColor(device, 66, 433);
5776 ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
5777 color = getPixelColor(device, 66, 430);
5778 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
5780 color = getPixelColor(device, 578, 430);
5781 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
5782 color = getPixelColor(device, 578, 433);
5783 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
5784 color = getPixelColor(device, 575, 433);
5785 ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
5786 color = getPixelColor(device, 575, 430);
5787 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
5789 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5790 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5792 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5793 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5794 IDirect3DPixelShader9_Release(shader);
5796 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
5797 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5798 if (FAILED(IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader)))
5800 skip("Failed to create 2.0 test shader, most likely not supported.\n");
5801 IDirect3DDevice9_Release(device);
5802 goto done;
5805 hr = IDirect3DDevice9_SetPixelShader(device, shader);
5806 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5807 hr = IDirect3DDevice9_BeginScene(device);
5808 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5809 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
5810 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5811 hr = IDirect3DDevice9_EndScene(device);
5812 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5814 color = getPixelColor(device, 63, 46);
5815 ok(color == 0x00ffff00, "Pixel 63/46 has color %08x, expected 0x00ffff00\n", color);
5816 color = getPixelColor(device, 66, 46);
5817 ok(color == 0x00ffff00, "Pixel 66/64 has color %08x, expected 0x00ffff00\n", color);
5818 color = getPixelColor(device, 63, 49);
5819 ok(color == 0x00ffff00, "Pixel 63/49 has color %08x, expected 0x00ffff00\n", color);
5820 color = getPixelColor(device, 66, 49);
5821 ok(color == 0x000000ff, "Pixel 66/49 has color %08x, expected 0x000000ff\n", color);
5823 color = getPixelColor(device, 578, 46);
5824 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
5825 color = getPixelColor(device, 575, 46);
5826 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
5827 color = getPixelColor(device, 578, 49);
5828 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
5829 color = getPixelColor(device, 575, 49);
5830 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
5832 color = getPixelColor(device, 63, 430);
5833 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
5834 color = getPixelColor(device, 63, 433);
5835 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
5836 color = getPixelColor(device, 66, 433);
5837 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
5838 color = getPixelColor(device, 66, 430);
5839 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
5841 color = getPixelColor(device, 578, 430);
5842 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
5843 color = getPixelColor(device, 578, 433);
5844 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
5845 color = getPixelColor(device, 575, 433);
5846 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
5847 color = getPixelColor(device, 575, 430);
5848 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
5850 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5851 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5853 IDirect3DPixelShader9_Release(shader);
5854 refcount = IDirect3DDevice9_Release(device);
5855 ok(!refcount, "Device has %u references left.\n", refcount);
5856 done:
5857 IDirect3D9_Release(d3d);
5858 DestroyWindow(window);
5861 static void autogen_mipmap_test(void)
5863 IDirect3DTexture9 *texture = NULL;
5864 IDirect3DSurface9 *surface;
5865 IDirect3DDevice9 *device;
5866 unsigned int x, y;
5867 D3DLOCKED_RECT lr;
5868 IDirect3D9 *d3d;
5869 D3DCOLOR color;
5870 ULONG refcount;
5871 HWND window;
5872 HRESULT hr;
5874 static const RECT r1 = {256, 256, 512, 512};
5875 static const RECT r2 = {512, 256, 768, 512};
5876 static const RECT r3 = {256, 512, 512, 768};
5877 static const RECT r4 = {512, 512, 768, 768};
5878 static const float quad[] =
5880 -0.5f, -0.5f, 0.1f, 0.0f, 0.0f,
5881 -0.5f, 0.5f, 0.1f, 0.0f, 1.0f,
5882 0.5f, -0.5f, 0.1f, 1.0f, 0.0f,
5883 0.5f, 0.5f, 0.1f, 1.0f, 1.0f,
5886 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
5887 0, 0, 640, 480, NULL, NULL, NULL, NULL);
5888 d3d = Direct3DCreate9(D3D_SDK_VERSION);
5889 ok(!!d3d, "Failed to create a D3D object.\n");
5890 if (!(device = create_device(d3d, window, window, TRUE)))
5892 skip("Failed to create a D3D device, skipping tests.\n");
5893 goto done;
5896 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
5897 D3DFMT_X8R8G8B8, D3DUSAGE_AUTOGENMIPMAP, D3DRTYPE_TEXTURE, D3DFMT_X8R8G8B8) != D3D_OK)
5899 skip("No autogenmipmap support.\n");
5900 IDirect3DDevice9_Release(device);
5901 goto done;
5904 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffff00, 1.0f, 0);
5905 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5907 /* Make the mipmap big, so that a smaller mipmap is used
5909 hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 0, D3DUSAGE_AUTOGENMIPMAP,
5910 D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, 0);
5911 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
5913 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
5914 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel returned %08x\n", hr);
5915 memset(&lr, 0, sizeof(lr));
5916 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
5917 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect returned %08x\n", hr);
5918 for(y = 0; y < 1024; y++) {
5919 for(x = 0; x < 1024; x++) {
5920 DWORD *dst = (DWORD *) (((BYTE *) lr.pBits) + y * lr.Pitch + x * 4);
5921 POINT pt;
5923 pt.x = x;
5924 pt.y = y;
5925 if(PtInRect(&r1, pt)) {
5926 *dst = 0xffff0000;
5927 } else if(PtInRect(&r2, pt)) {
5928 *dst = 0xff00ff00;
5929 } else if(PtInRect(&r3, pt)) {
5930 *dst = 0xff0000ff;
5931 } else if(PtInRect(&r4, pt)) {
5932 *dst = 0xff000000;
5933 } else {
5934 *dst = 0xffffffff;
5938 hr = IDirect3DSurface9_UnlockRect(surface);
5939 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect returned %08x\n", hr);
5940 IDirect3DSurface9_Release(surface);
5942 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
5943 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
5944 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
5945 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
5946 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
5947 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
5949 hr = IDirect3DDevice9_BeginScene(device);
5950 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5951 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
5952 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
5953 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
5954 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5955 hr = IDirect3DDevice9_EndScene(device);
5956 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5957 IDirect3DTexture9_Release(texture);
5959 color = getPixelColor(device, 200, 200);
5960 ok(color == 0x00ffffff, "pixel 200/200 has color %08x, expected 0x00ffffff\n", color);
5961 color = getPixelColor(device, 280, 200);
5962 ok(color == 0x000000ff, "pixel 280/200 has color %08x, expected 0x000000ff\n", color);
5963 color = getPixelColor(device, 360, 200);
5964 ok(color == 0x00000000, "pixel 360/200 has color %08x, expected 0x00000000\n", color);
5965 color = getPixelColor(device, 440, 200);
5966 ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
5967 color = getPixelColor(device, 200, 270);
5968 ok(color == 0x00ffffff, "pixel 200/270 has color %08x, expected 0x00ffffff\n", color);
5969 color = getPixelColor(device, 280, 270);
5970 ok(color == 0x00ff0000, "pixel 280/270 has color %08x, expected 0x00ff0000\n", color);
5971 color = getPixelColor(device, 360, 270);
5972 ok(color == 0x0000ff00, "pixel 360/270 has color %08x, expected 0x0000ff00\n", color);
5973 color = getPixelColor(device, 440, 270);
5974 ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
5975 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5976 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5978 refcount = IDirect3DDevice9_Release(device);
5979 ok(!refcount, "Device has %u references left.\n", refcount);
5980 done:
5981 IDirect3D9_Release(d3d);
5982 DestroyWindow(window);
5985 static void test_constant_clamp_vs(void)
5987 IDirect3DVertexShader9 *shader_11, *shader_11_2, *shader_20, *shader_20_2;
5988 IDirect3DVertexDeclaration9 *decl;
5989 IDirect3DDevice9 *device;
5990 IDirect3D9 *d3d;
5991 D3DCOLOR color;
5992 ULONG refcount;
5993 D3DCAPS9 caps;
5994 HWND window;
5995 HRESULT hr;
5997 static const DWORD shader_code_11[] =
5999 0xfffe0101, /* vs_1_1 */
6000 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6001 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
6002 0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
6003 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6004 0x0000ffff /* end */
6006 static const DWORD shader_code_11_2[] =
6008 0xfffe0101, /* vs_1_1 */
6009 0x00000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000, /* dcl ... */
6010 0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* dcl ... */
6011 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6012 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
6013 0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
6014 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6015 0x0000ffff /* end */
6017 static const DWORD shader_code_20[] =
6019 0xfffe0200, /* vs_2_0 */
6020 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6021 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
6022 0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
6023 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6024 0x0000ffff /* end */
6026 static const DWORD shader_code_20_2[] =
6028 0xfffe0200, /* vs_2_0 */
6029 0x05000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000,
6030 0x05000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000,
6031 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6032 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
6033 0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
6034 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
6035 0x0000ffff /* end */
6037 static const D3DVERTEXELEMENT9 decl_elements[] =
6039 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
6040 D3DDECL_END()
6042 static const float quad1[] =
6044 -1.0f, -1.0f, 0.1f,
6045 -1.0f, 0.0f, 0.1f,
6046 0.0f, -1.0f, 0.1f,
6047 0.0f, 0.0f, 0.1f,
6049 static const float quad2[] =
6051 0.0f, -1.0f, 0.1f,
6052 0.0f, 0.0f, 0.1f,
6053 1.0f, -1.0f, 0.1f,
6054 1.0f, 0.0f, 0.1f,
6056 static const float quad3[] =
6058 0.0f, 0.0f, 0.1f,
6059 0.0f, 1.0f, 0.1f,
6060 1.0f, 0.0f, 0.1f,
6061 1.0f, 1.0f, 0.1f,
6063 static const float quad4[] =
6065 -1.0f, 0.0f, 0.1f,
6066 -1.0f, 1.0f, 0.1f,
6067 0.0f, 0.0f, 0.1f,
6068 0.0f, 1.0f, 0.1f,
6070 static const float test_data_c1[4] = { 1.25f, -0.50f, -1.50f, 1.0f};
6071 static const float test_data_c2[4] = {-0.50f, 1.25f, 2.00f, 1.0f};
6073 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
6074 0, 0, 640, 480, NULL, NULL, NULL, NULL);
6075 d3d = Direct3DCreate9(D3D_SDK_VERSION);
6076 ok(!!d3d, "Failed to create a D3D object.\n");
6077 if (!(device = create_device(d3d, window, window, TRUE)))
6079 skip("Failed to create a D3D device, skipping tests.\n");
6080 goto done;
6083 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6084 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
6085 if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1))
6087 skip("No vs_1_1 support, skipping tests.\n");
6088 IDirect3DDevice9_Release(device);
6089 goto done;
6092 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
6093 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6095 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11, &shader_11);
6096 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6097 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11_2, &shader_11_2);
6098 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
6099 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20, &shader_20);
6100 if(FAILED(hr)) shader_20 = NULL;
6101 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20_2, &shader_20_2);
6102 if(FAILED(hr)) shader_20_2 = NULL;
6103 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
6104 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
6106 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, test_data_c1, 1);
6107 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
6108 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, test_data_c2, 1);
6109 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
6110 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
6111 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
6113 hr = IDirect3DDevice9_BeginScene(device);
6114 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6116 hr = IDirect3DDevice9_SetVertexShader(device, shader_11);
6117 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
6118 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
6119 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6121 hr = IDirect3DDevice9_SetVertexShader(device, shader_11_2);
6122 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
6123 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
6124 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6126 if (shader_20)
6128 hr = IDirect3DDevice9_SetVertexShader(device, shader_20);
6129 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
6130 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
6131 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6134 if (shader_20_2)
6136 hr = IDirect3DDevice9_SetVertexShader(device, shader_20_2);
6137 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
6138 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
6139 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6142 hr = IDirect3DDevice9_EndScene(device);
6143 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6145 color = getPixelColor(device, 160, 360);
6146 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
6147 "quad 1 has color %08x, expected 0x00bfbf80\n", color);
6148 color = getPixelColor(device, 480, 360);
6149 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
6150 "quad 2 has color %08x, expected 0x00bfbf80\n", color);
6151 if(shader_20) {
6152 color = getPixelColor(device, 480, 120);
6153 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
6154 "quad 3 has color %08x, expected 0x00bfbf80\n", color);
6156 if(shader_20_2) {
6157 color = getPixelColor(device, 160, 120);
6158 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
6159 "quad 4 has color %08x, expected 0x00bfbf80\n", color);
6161 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6162 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6164 IDirect3DVertexDeclaration9_Release(decl);
6165 if(shader_20_2) IDirect3DVertexShader9_Release(shader_20_2);
6166 if(shader_20) IDirect3DVertexShader9_Release(shader_20);
6167 IDirect3DVertexShader9_Release(shader_11_2);
6168 IDirect3DVertexShader9_Release(shader_11);
6169 refcount = IDirect3DDevice9_Release(device);
6170 ok(!refcount, "Device has %u references left.\n", refcount);
6171 done:
6172 IDirect3D9_Release(d3d);
6173 DestroyWindow(window);
6176 static void constant_clamp_ps_test(void)
6178 IDirect3DPixelShader9 *shader_11, *shader_12, *shader_14, *shader_20;
6179 IDirect3DDevice9 *device;
6180 IDirect3D9 *d3d;
6181 ULONG refcount;
6182 D3DCAPS9 caps;
6183 DWORD color;
6184 HWND window;
6185 HRESULT hr;
6187 static const DWORD shader_code_11[] =
6189 0xffff0101, /* ps_1_1 */
6190 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
6191 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
6192 0x0000ffff /* end */
6194 static const DWORD shader_code_12[] =
6196 0xffff0102, /* ps_1_2 */
6197 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
6198 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
6199 0x0000ffff /* end */
6201 /* Skip 1.3 shaders because we have only 4 quads (ok, could make them
6202 * smaller if needed). 1.2 and 1.4 shaders behave the same, so it's
6203 * unlikely that 1.3 shaders are different. During development of this
6204 * test, 1.3 shaders were verified too. */
6205 static const DWORD shader_code_14[] =
6207 0xffff0104, /* ps_1_4 */
6208 /* Try to make one constant local. It gets clamped too, although the
6209 * binary contains the bigger numbers. */
6210 0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* def c2, -0.5, 1.25, 2, 1 */
6211 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
6212 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
6213 0x0000ffff /* end */
6215 static const DWORD shader_code_20[] =
6217 0xffff0200, /* ps_2_0 */
6218 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
6219 0x03000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
6220 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
6221 0x0000ffff /* end */
6223 static const float quad1[] =
6225 -1.0f, -1.0f, 0.1f,
6226 -1.0f, 0.0f, 0.1f,
6227 0.0f, -1.0f, 0.1f,
6228 0.0f, 0.0f, 0.1f,
6230 static const float quad2[] =
6232 0.0f, -1.0f, 0.1f,
6233 0.0f, 0.0f, 0.1f,
6234 1.0f, -1.0f, 0.1f,
6235 1.0f, 0.0f, 0.1f,
6237 static const float quad3[] =
6239 0.0f, 0.0f, 0.1f,
6240 0.0f, 1.0f, 0.1f,
6241 1.0f, 0.0f, 0.1f,
6242 1.0f, 1.0f, 0.1f,
6244 static const float quad4[] =
6246 -1.0f, 0.0f, 0.1f,
6247 -1.0f, 1.0f, 0.1f,
6248 0.0f, 0.0f, 0.1f,
6249 0.0f, 1.0f, 0.1f,
6251 static const float test_data_c1[4] = { 1.25f, -0.50f, -1.50f, 1.0f};
6252 static const float test_data_c2[4] = {-0.50f, 1.25f, 2.00f, 1.0f};
6254 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
6255 0, 0, 640, 480, NULL, NULL, NULL, NULL);
6256 d3d = Direct3DCreate9(D3D_SDK_VERSION);
6257 ok(!!d3d, "Failed to create a D3D object.\n");
6258 if (!(device = create_device(d3d, window, window, TRUE)))
6260 skip("Failed to create a D3D device, skipping tests.\n");
6261 goto done;
6264 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6265 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
6266 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 4))
6268 skip("No ps_1_4 support, skipping tests.\n");
6269 IDirect3DDevice9_Release(device);
6270 goto done;
6273 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
6274 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6276 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
6277 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6278 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
6279 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6280 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
6281 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6282 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader_20);
6283 if(FAILED(hr)) shader_20 = NULL;
6285 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
6286 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
6287 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
6288 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
6289 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6290 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
6292 hr = IDirect3DDevice9_BeginScene(device);
6293 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6295 hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
6296 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6297 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
6298 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6300 hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
6301 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6302 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
6303 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6305 hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
6306 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6307 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
6308 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6310 if (shader_20)
6312 hr = IDirect3DDevice9_SetPixelShader(device, shader_20);
6313 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6314 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
6315 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6318 hr = IDirect3DDevice9_EndScene(device);
6319 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6321 color = getPixelColor(device, 160, 360);
6322 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
6323 "quad 1 has color %08x, expected 0x00808000\n", color);
6324 color = getPixelColor(device, 480, 360);
6325 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
6326 "quad 2 has color %08x, expected 0x00808000\n", color);
6327 color = getPixelColor(device, 480, 120);
6328 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
6329 "quad 3 has color %08x, expected 0x00808000\n", color);
6330 if(shader_20) {
6331 color = getPixelColor(device, 160, 120);
6332 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
6333 "quad 4 has color %08x, expected 0x00bfbf80\n", color);
6335 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6336 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6338 if(shader_20) IDirect3DPixelShader9_Release(shader_20);
6339 IDirect3DPixelShader9_Release(shader_14);
6340 IDirect3DPixelShader9_Release(shader_12);
6341 IDirect3DPixelShader9_Release(shader_11);
6342 refcount = IDirect3DDevice9_Release(device);
6343 ok(!refcount, "Device has %u references left.\n", refcount);
6344 done:
6345 IDirect3D9_Release(d3d);
6346 DestroyWindow(window);
6349 static void dp2add_ps_test(void)
6351 IDirect3DPixelShader9 *shader_dp2add_sat;
6352 IDirect3DPixelShader9 *shader_dp2add;
6353 IDirect3DDevice9 *device;
6354 IDirect3D9 *d3d;
6355 ULONG refcount;
6356 D3DCAPS9 caps;
6357 DWORD color;
6358 HWND window;
6359 HRESULT hr;
6361 /* DP2ADD is defined as: (src0.r * src1.r) + (src0.g * src1.g) + src2.
6362 * One D3D restriction of all shader instructions except SINCOS is that no more than 2
6363 * source tokens can be constants. So, for this exercise, we move contents of c0 to
6364 * r0 first.
6365 * The result here for the r,g,b components should be roughly 0.5:
6366 * (0.5 * 0.5) + (0.5 * 0.5) + 0.0 = 0.5 */
6367 static const DWORD shader_code_dp2add[] = {
6368 0xffff0200, /* ps_2_0 */
6369 0x05000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f800000, 0x00000000, /* def c0, 0.5, 0.5, 1.0, 0 */
6371 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
6372 0x0400005a, 0x80070000, 0x80000000, 0x80000000, 0x80ff0000, /* dp2add r0.rgb, r0, r0, r0.a */
6374 0x02000001, 0x80080000, 0xa0aa0000, /* mov r0.a, c0.b */
6375 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
6376 0x0000ffff /* end */
6379 /* Test the _sat modifier, too. Result here should be:
6380 * DP2: (-0.5 * -0.5) + (-0.5 * -0.5) + 2.0 = 2.5
6381 * _SAT: ==> 1.0
6382 * ADD: (1.0 + -0.5) = 0.5
6384 static const DWORD shader_code_dp2add_sat[] = {
6385 0xffff0200, /* ps_2_0 */
6386 0x05000051, 0xa00f0000, 0xbf000000, 0xbf000000, 0x3f800000, 0x40000000, /* def c0, -0.5, -0.5, 1.0, 2.0 */
6388 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
6389 0x0400005a, 0x80170000, 0x80000000, 0x80000000, 0x80ff0000, /* dp2add_sat r0.rgb, r0, r0, r0.a */
6390 0x03000002, 0x80070000, 0x80e40000, 0xa0000000, /* add r0.rgb, r0, c0.r */
6392 0x02000001, 0x80080000, 0xa0aa0000, /* mov r0.a, c0.b */
6393 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
6394 0x0000ffff /* end */
6396 static const float quad[] =
6398 -1.0f, -1.0f, 0.1f,
6399 -1.0f, 1.0f, 0.1f,
6400 1.0f, -1.0f, 0.1f,
6401 1.0f, 1.0f, 0.1f,
6404 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
6405 0, 0, 640, 480, NULL, NULL, NULL, NULL);
6406 d3d = Direct3DCreate9(D3D_SDK_VERSION);
6407 ok(!!d3d, "Failed to create a D3D object.\n");
6408 if (!(device = create_device(d3d, window, window, TRUE)))
6410 skip("Failed to create a D3D device, skipping tests.\n");
6411 goto done;
6414 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6415 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
6416 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
6418 skip("No ps_2_0 support, skipping tests.\n");
6419 IDirect3DDevice9_Release(device);
6420 goto done;
6423 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff000000, 1.0f, 0);
6424 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6426 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add, &shader_dp2add);
6427 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6429 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add_sat, &shader_dp2add_sat);
6430 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6432 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6433 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
6435 hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add);
6436 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
6437 hr = IDirect3DDevice9_BeginScene(device);
6438 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6439 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
6440 ok(SUCCEEDED(hr), "Failed to draw primitive, hr %#x.\n", hr);
6441 hr = IDirect3DDevice9_EndScene(device);
6442 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6444 color = getPixelColor(device, 360, 240);
6445 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x7f, 0x7f), 1), "Got unexpected color 0x%08x.\n", color);
6447 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6448 ok(SUCCEEDED(hr), "Failed to present frame, hr %#x.\n", hr);
6449 IDirect3DPixelShader9_Release(shader_dp2add);
6451 hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add_sat);
6452 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
6453 hr = IDirect3DDevice9_BeginScene(device);
6454 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6455 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
6456 ok(SUCCEEDED(hr), "Failed to draw primitive, hr %#x.\n", hr);
6457 hr = IDirect3DDevice9_EndScene(device);
6458 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6460 color = getPixelColor(device, 360, 240);
6461 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x7f, 0x7f), 1), "Got unexpected color 0x%08x.\n", color);
6463 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6464 ok(SUCCEEDED(hr), "Failed to present frame, hr %#x.\n", hr);
6465 IDirect3DPixelShader9_Release(shader_dp2add_sat);
6467 refcount = IDirect3DDevice9_Release(device);
6468 ok(!refcount, "Device has %u references left.\n", refcount);
6469 done:
6470 IDirect3D9_Release(d3d);
6471 DestroyWindow(window);
6474 static void cnd_test(void)
6476 IDirect3DPixelShader9 *shader_11_coissue_2, *shader_12_coissue_2, *shader_13_coissue_2, *shader_14_coissue_2;
6477 IDirect3DPixelShader9 *shader_11_coissue, *shader_12_coissue, *shader_13_coissue, *shader_14_coissue;
6478 IDirect3DPixelShader9 *shader_11, *shader_12, *shader_13, *shader_14;
6479 IDirect3DDevice9 *device;
6480 IDirect3D9 *d3d;
6481 ULONG refcount;
6482 D3DCAPS9 caps;
6483 HWND window;
6484 DWORD color;
6485 HRESULT hr;
6487 /* ps 1.x shaders are rather picky with writemasks and source swizzles.
6488 * The dp3 is used to copy r0.r to all components of r1, then copy r1.a to
6489 * r0.a. Essentially it does a mov r0.a, r0.r, which isn't allowed as-is
6490 * in 1.x pixel shaders. */
6491 static const DWORD shader_code_11[] =
6493 0xffff0101, /* ps_1_1 */
6494 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
6495 0x00000040, 0xb00f0000, /* texcoord t0 */
6496 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, ???(t0) */
6497 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3 r1, r0, c0 */
6498 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
6499 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
6500 0x0000ffff /* end */
6502 static const DWORD shader_code_12[] =
6504 0xffff0102, /* ps_1_2 */
6505 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
6506 0x00000040, 0xb00f0000, /* texcoord t0 */
6507 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
6508 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3 r1, r0, c0 */
6509 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
6510 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
6511 0x0000ffff /* end */
6513 static const DWORD shader_code_13[] =
6515 0xffff0103, /* ps_1_3 */
6516 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
6517 0x00000040, 0xb00f0000, /* texcoord t0 */
6518 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
6519 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3, r1, r0, c0 */
6520 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
6521 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
6522 0x0000ffff /* end */
6524 static const DWORD shader_code_14[] =
6526 0xffff0104, /* ps_1_3 */
6527 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
6528 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0, t0 */
6529 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
6530 0x00000050, 0x800f0000, 0x80e40000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0, c1, c2 */
6531 0x0000ffff /* end */
6534 /* Special fun: The coissue flag on cnd: Apparently cnd always selects the 2nd source,
6535 * as if the src0 comparison against 0.5 always evaluates to true. The coissue flag isn't
6536 * set by the compiler, it was added manually after compilation. Note that the COISSUE
6537 * flag on a color(.xyz) operation is only allowed after an alpha operation. DirectX doesn't
6538 * have proper docs, but GL_ATI_fragment_shader explains the pairing of color and alpha ops
6539 * well enough.
6541 * The shader attempts to test the range [-1;1] against coissued cnd, which is a bit tricky.
6542 * The input from t0 is [0;1]. 0.5 is subtracted, then we have to multiply with 2. Since
6543 * constants are clamped to [-1;1], a 2.0 is constructed by adding c0.r(=1.0) to c0.r into r1.r,
6544 * then r1(2.0, 0.0, 0.0, 0.0) is passed to dp3(explained above).
6546 static const DWORD shader_code_11_coissue[] =
6548 0xffff0101, /* ps_1_1 */
6549 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
6550 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
6551 0x00000040, 0xb00f0000, /* texcoord t0 */
6552 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
6553 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
6554 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
6555 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
6556 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
6557 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.xyz, r0.a, c1, c2*/
6558 0x0000ffff /* end */
6560 static const DWORD shader_code_11_coissue_2[] =
6562 0xffff0101, /* ps_1_1 */
6563 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
6564 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
6565 0x00000040, 0xb00f0000, /* texcoord t0 */
6566 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
6567 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
6568 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
6569 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
6570 0x00000001, 0x800f0000, 0x80e40001, /* mov r0, r1 */
6571 0x00000001, 0x80070000, 0x80ff0001, /* mov r0.xyz, r1.a */
6572 0x40000050, 0x80080000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.a, r0.a, c1, c2 */
6573 0x00000001, 0x80070000, 0x80ff0000, /* mov r0.xyz, r0.a */
6574 0x0000ffff /* end */
6576 static const DWORD shader_code_12_coissue[] =
6578 0xffff0102, /* ps_1_2 */
6579 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
6580 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
6581 0x00000040, 0xb00f0000, /* texcoord t0 */
6582 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
6583 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
6584 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
6585 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
6586 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
6587 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.xyz, r0.a, c1, c2*/
6588 0x0000ffff /* end */
6590 static const DWORD shader_code_12_coissue_2[] =
6592 0xffff0102, /* ps_1_2 */
6593 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
6594 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
6595 0x00000040, 0xb00f0000, /* texcoord t0 */
6596 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
6597 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
6598 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
6599 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
6600 0x00000001, 0x800f0000, 0x80e40001, /* mov r0, r1 */
6601 0x00000001, 0x80070000, 0x80ff0001, /* mov r0.xyz, r1.a */
6602 0x40000050, 0x80080000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.a, r0.a, c1, c2 */
6603 0x00000001, 0x80070000, 0x80ff0000, /* mov r0.xyz, r0.a */
6604 0x0000ffff /* end */
6606 static const DWORD shader_code_13_coissue[] =
6608 0xffff0103, /* ps_1_3 */
6609 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
6610 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
6611 0x00000040, 0xb00f0000, /* texcoord t0 */
6612 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
6613 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
6614 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
6615 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
6616 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
6617 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.xyz, r0.a, c1, c2*/
6618 0x0000ffff /* end */
6620 static const DWORD shader_code_13_coissue_2[] =
6622 0xffff0103, /* ps_1_3 */
6623 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
6624 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
6625 0x00000040, 0xb00f0000, /* texcoord t0 */
6626 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
6627 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
6628 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
6629 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
6630 0x00000001, 0x800f0000, 0x80e40001, /* mov r0, r1 */
6631 0x00000001, 0x80070000, 0x80ff0001, /* mov r0.xyz, r1.a */
6632 0x40000050, 0x80080000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.a, r0.a, c1, c2 */
6633 0x00000001, 0x80070000, 0x80ff0000, /* mov r0.xyz, r0.a */
6634 0x0000ffff /* end */
6636 /* ps_1_4 does not have a different cnd behavior, just pass the [0;1]
6637 * texcrd result to cnd, it will compare against 0.5. */
6638 static const DWORD shader_code_14_coissue[] =
6640 0xffff0104, /* ps_1_4 */
6641 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
6642 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0.xyz, t0 */
6643 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
6644 0x40000050, 0x80070000, 0x80e40000, 0xa0e40001, 0xa0e40002, /* +cnd r0.xyz, r0, c1, c2 */
6645 0x0000ffff /* end */
6647 static const DWORD shader_code_14_coissue_2[] =
6649 0xffff0104, /* ps_1_4 */
6650 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
6651 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0.xyz, t0 */
6652 0x00000001, 0x80080000, 0x80000000, /* mov r0.a, r0.x */
6653 0x00000001, 0x80070001, 0xa0ff0000, /* mov r1.xyz, c0.a */
6654 0x40000050, 0x80080001, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r1.a, r0.a, c1, c2 */
6655 0x00000001, 0x80070000, 0x80ff0001, /* mov r0.xyz, r1.a */
6656 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
6657 0x0000ffff /* end */
6659 static const float quad1[] =
6661 -1.0f, -1.0f, 0.1f, 0.0f, 0.0f, 1.0f,
6662 -1.0f, 0.0f, 0.1f, 0.0f, 1.0f, 0.0f,
6663 0.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f,
6664 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 0.0f,
6666 static const float quad2[] =
6668 0.0f, -1.0f, 0.1f, 0.0f, 0.0f, 1.0f,
6669 0.0f, 0.0f, 0.1f, 0.0f, 1.0f, 0.0f,
6670 1.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f,
6671 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 0.0f,
6673 static const float quad3[] =
6675 0.0f, 0.0f, 0.1f, 0.0f, 0.0f, 1.0f,
6676 0.0f, 1.0f, 0.1f, 0.0f, 1.0f, 0.0f,
6677 1.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f,
6678 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 0.0f,
6680 static const float quad4[] =
6682 -1.0f, 0.0f, 0.1f, 0.0f, 0.0f, 1.0f,
6683 -1.0f, 1.0f, 0.1f, 0.0f, 1.0f, 0.0f,
6684 0.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f,
6685 0.0f, 1.0f, 0.1f, 1.0f, 1.0f, 0.0f,
6687 static const float test_data_c1[4] = {0.0f, 0.0f, 0.0f, 0.0f};
6688 static const float test_data_c2[4] = {1.0f, 1.0f, 1.0f, 1.0f};
6689 static const float test_data_c1_coi[4] = {0.0f, 1.0f, 0.0f, 0.0f};
6690 static const float test_data_c2_coi[4] = {1.0f, 0.0f, 1.0f, 1.0f};
6692 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
6693 0, 0, 640, 480, NULL, NULL, NULL, NULL);
6694 d3d = Direct3DCreate9(D3D_SDK_VERSION);
6695 ok(!!d3d, "Failed to create a D3D object.\n");
6696 if (!(device = create_device(d3d, window, window, TRUE)))
6698 skip("Failed to create a D3D device, skipping tests.\n");
6699 goto done;
6702 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6703 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
6704 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 4))
6706 skip("No ps_1_4 support, skipping tests.\n");
6707 IDirect3DDevice9_Release(device);
6708 goto done;
6711 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
6712 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6714 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
6715 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6716 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
6717 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6718 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13, &shader_13);
6719 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6720 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
6721 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6722 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11_coissue, &shader_11_coissue);
6723 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6724 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12_coissue, &shader_12_coissue);
6725 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6726 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13_coissue, &shader_13_coissue);
6727 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6728 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14_coissue, &shader_14_coissue);
6729 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6730 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11_coissue_2, &shader_11_coissue_2);
6731 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6732 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12_coissue_2, &shader_12_coissue_2);
6733 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6734 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13_coissue_2, &shader_13_coissue_2);
6735 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6736 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14_coissue_2, &shader_14_coissue_2);
6737 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6739 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
6740 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
6741 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
6742 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
6743 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6744 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
6746 hr = IDirect3DDevice9_BeginScene(device);
6747 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6749 hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
6750 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6751 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
6752 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6754 hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
6755 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6756 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
6757 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6759 hr = IDirect3DDevice9_SetPixelShader(device, shader_13);
6760 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6761 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
6762 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6764 hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
6765 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6766 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
6767 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6769 hr = IDirect3DDevice9_EndScene(device);
6770 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6772 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
6773 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6775 /* This is the 1.4 test. Each component(r, g, b) is tested separately against 0.5 */
6776 color = getPixelColor(device, 158, 118);
6777 ok(color == 0x00ff00ff, "pixel 158, 118 has color %08x, expected 0x00ff00ff\n", color);
6778 color = getPixelColor(device, 162, 118);
6779 ok(color == 0x000000ff, "pixel 162, 118 has color %08x, expected 0x000000ff\n", color);
6780 color = getPixelColor(device, 158, 122);
6781 ok(color == 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color);
6782 color = getPixelColor(device, 162, 122);
6783 ok(color == 0x0000ffff, "pixel 162, 122 has color %08x, expected 0x0000ffff\n", color);
6785 /* 1.1 shader. All 3 components get set, based on the .w comparison */
6786 color = getPixelColor(device, 158, 358);
6787 ok(color == 0x00ffffff, "pixel 158, 358 has color %08x, expected 0x00ffffff\n", color);
6788 color = getPixelColor(device, 162, 358);
6789 ok(color_match(color, 0x00000000, 1), "pixel 162, 358 has color 0x%08x, expected 0x00000000.\n", color);
6790 color = getPixelColor(device, 158, 362);
6791 ok(color == 0x00ffffff, "pixel 158, 362 has color %08x, expected 0x00ffffff\n", color);
6792 color = getPixelColor(device, 162, 362);
6793 ok(color_match(color, 0x00000000, 1), "pixel 162, 362 has color 0x%08x, expected 0x00000000.\n", color);
6795 /* 1.2 shader */
6796 color = getPixelColor(device, 478, 358);
6797 ok(color == 0x00ffffff, "pixel 478, 358 has color %08x, expected 0x00ffffff\n", color);
6798 color = getPixelColor(device, 482, 358);
6799 ok(color_match(color, 0x00000000, 1), "pixel 482, 358 has color 0x%08x, expected 0x00000000.\n", color);
6800 color = getPixelColor(device, 478, 362);
6801 ok(color == 0x00ffffff, "pixel 478, 362 has color %08x, expected 0x00ffffff\n", color);
6802 color = getPixelColor(device, 482, 362);
6803 ok(color_match(color, 0x00000000, 1), "pixel 482, 362 has color 0x%08x, expected 0x00000000.\n", color);
6805 /* 1.3 shader */
6806 color = getPixelColor(device, 478, 118);
6807 ok(color == 0x00ffffff, "pixel 478, 118 has color %08x, expected 0x00ffffff\n", color);
6808 color = getPixelColor(device, 482, 118);
6809 ok(color_match(color, 0x00000000, 1), "pixel 482, 118 has color 0x%08x, expected 0x00000000.\n", color);
6810 color = getPixelColor(device, 478, 122);
6811 ok(color == 0x00ffffff, "pixel 478, 122 has color %08x, expected 0x00ffffff\n", color);
6812 color = getPixelColor(device, 482, 122);
6813 ok(color_match(color, 0x00000000, 1), "pixel 482, 122 has color 0x%08x, expected 0x00000000.\n", color);
6815 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6816 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6818 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
6819 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6820 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1_coi, 1);
6821 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
6822 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2_coi, 1);
6823 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
6825 hr = IDirect3DDevice9_BeginScene(device);
6826 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6828 hr = IDirect3DDevice9_SetPixelShader(device, shader_11_coissue);
6829 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6830 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
6831 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6833 hr = IDirect3DDevice9_SetPixelShader(device, shader_12_coissue);
6834 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6835 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
6836 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6838 hr = IDirect3DDevice9_SetPixelShader(device, shader_13_coissue);
6839 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6840 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
6841 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6843 hr = IDirect3DDevice9_SetPixelShader(device, shader_14_coissue);
6844 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6845 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
6846 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6848 hr = IDirect3DDevice9_EndScene(device);
6849 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6851 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
6852 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6854 /* This is the 1.4 test. The coissue doesn't change the behavior here, but keep in mind
6855 * that we swapped the values in c1 and c2 to make the other tests return some color
6857 color = getPixelColor(device, 158, 118);
6858 ok(color == 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color);
6859 color = getPixelColor(device, 162, 118);
6860 ok(color == 0x0000ffff, "pixel 162, 118 has color %08x, expected 0x0000ffff\n", color);
6861 color = getPixelColor(device, 158, 122);
6862 ok(color == 0x00ff00ff, "pixel 162, 122 has color %08x, expected 0x00ff00ff\n", color);
6863 color = getPixelColor(device, 162, 122);
6864 ok(color == 0x000000ff, "pixel 162, 122 has color %08x, expected 0x000000ff\n", color);
6866 /* 1.1 shader. coissue flag changed the semantic of cnd, c1 is always selected
6867 * (The Win7 nvidia driver always selects c2)
6869 color = getPixelColor(device, 158, 358);
6870 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6871 "pixel 158, 358 has color %08x, expected 0x0000ff00\n", color);
6872 color = getPixelColor(device, 162, 358);
6873 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6874 "pixel 162, 358 has color %08x, expected 0x0000ff00\n", color);
6875 color = getPixelColor(device, 158, 362);
6876 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6877 "pixel 158, 362 has color %08x, expected 0x0000ff00\n", color);
6878 color = getPixelColor(device, 162, 362);
6879 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6880 "pixel 162, 362 has color %08x, expected 0x0000ff00\n", color);
6882 /* 1.2 shader */
6883 color = getPixelColor(device, 478, 358);
6884 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6885 "pixel 478, 358 has color %08x, expected 0x0000ff00\n", color);
6886 color = getPixelColor(device, 482, 358);
6887 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6888 "pixel 482, 358 has color %08x, expected 0x0000ff00\n", color);
6889 color = getPixelColor(device, 478, 362);
6890 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6891 "pixel 478, 362 has color %08x, expected 0x0000ff00\n", color);
6892 color = getPixelColor(device, 482, 362);
6893 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6894 "pixel 482, 362 has color %08x, expected 0x0000ff00\n", color);
6896 /* 1.3 shader */
6897 color = getPixelColor(device, 478, 118);
6898 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6899 "pixel 478, 118 has color %08x, expected 0x0000ff00\n", color);
6900 color = getPixelColor(device, 482, 118);
6901 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6902 "pixel 482, 118 has color %08x, expected 0x0000ff00\n", color);
6903 color = getPixelColor(device, 478, 122);
6904 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6905 "pixel 478, 122 has color %08x, expected 0x0000ff00\n", color);
6906 color = getPixelColor(device, 482, 122);
6907 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6908 "pixel 482, 122 has color %08x, expected 0x0000ff00\n", color);
6910 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6911 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6913 /* Retest with the coissue flag on the alpha instruction instead. This
6914 * works "as expected". The Windows 8 testbot (WARP) seems to handle this
6915 * the same as coissue on .rgb. */
6916 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
6917 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6919 hr = IDirect3DDevice9_BeginScene(device);
6920 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6922 hr = IDirect3DDevice9_SetPixelShader(device, shader_11_coissue_2);
6923 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6924 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
6925 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6927 hr = IDirect3DDevice9_SetPixelShader(device, shader_12_coissue_2);
6928 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6929 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
6930 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6932 hr = IDirect3DDevice9_SetPixelShader(device, shader_13_coissue_2);
6933 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6934 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
6935 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6937 hr = IDirect3DDevice9_SetPixelShader(device, shader_14_coissue_2);
6938 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6939 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
6940 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6942 hr = IDirect3DDevice9_EndScene(device);
6943 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6945 /* 1.4 shader */
6946 color = getPixelColor(device, 158, 118);
6947 ok(color == 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color);
6948 color = getPixelColor(device, 162, 118);
6949 ok(color == 0x00000000, "pixel 162, 118 has color %08x, expected 0x00000000\n", color);
6950 color = getPixelColor(device, 158, 122);
6951 ok(color == 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color);
6952 color = getPixelColor(device, 162, 122);
6953 ok(color == 0x00000000, "pixel 162, 122 has color %08x, expected 0x00000000\n", color);
6955 /* 1.1 shader */
6956 color = getPixelColor(device, 238, 358);
6957 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
6958 "pixel 238, 358 has color %08x, expected 0x00ffffff\n", color);
6959 color = getPixelColor(device, 242, 358);
6960 ok(color_match(color, 0x00000000, 1),
6961 "pixel 242, 358 has color %08x, expected 0x00000000\n", color);
6962 color = getPixelColor(device, 238, 362);
6963 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
6964 "pixel 238, 362 has color %08x, expected 0x00ffffff\n", color);
6965 color = getPixelColor(device, 242, 362);
6966 ok(color_match(color, 0x00000000, 1),
6967 "pixel 242, 362 has color %08x, expected 0x00000000\n", color);
6969 /* 1.2 shader */
6970 color = getPixelColor(device, 558, 358);
6971 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
6972 "pixel 558, 358 has color %08x, expected 0x00ffffff\n", color);
6973 color = getPixelColor(device, 562, 358);
6974 ok(color_match(color, 0x00000000, 1),
6975 "pixel 562, 358 has color %08x, expected 0x00000000\n", color);
6976 color = getPixelColor(device, 558, 362);
6977 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
6978 "pixel 558, 362 has color %08x, expected 0x00ffffff\n", color);
6979 color = getPixelColor(device, 562, 362);
6980 ok(color_match(color, 0x00000000, 1),
6981 "pixel 562, 362 has color %08x, expected 0x00000000\n", color);
6983 /* 1.3 shader */
6984 color = getPixelColor(device, 558, 118);
6985 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
6986 "pixel 558, 118 has color %08x, expected 0x00ffffff\n", color);
6987 color = getPixelColor(device, 562, 118);
6988 ok(color_match(color, 0x00000000, 1),
6989 "pixel 562, 118 has color %08x, expected 0x00000000\n", color);
6990 color = getPixelColor(device, 558, 122);
6991 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
6992 "pixel 558, 122 has color %08x, expected 0x00ffffff\n", color);
6993 color = getPixelColor(device, 562, 122);
6994 ok(color_match(color, 0x00000000, 1),
6995 "pixel 562, 122 has color %08x, expected 0x00000000\n", color);
6997 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6998 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
7000 IDirect3DPixelShader9_Release(shader_14_coissue_2);
7001 IDirect3DPixelShader9_Release(shader_13_coissue_2);
7002 IDirect3DPixelShader9_Release(shader_12_coissue_2);
7003 IDirect3DPixelShader9_Release(shader_11_coissue_2);
7004 IDirect3DPixelShader9_Release(shader_14_coissue);
7005 IDirect3DPixelShader9_Release(shader_13_coissue);
7006 IDirect3DPixelShader9_Release(shader_12_coissue);
7007 IDirect3DPixelShader9_Release(shader_11_coissue);
7008 IDirect3DPixelShader9_Release(shader_14);
7009 IDirect3DPixelShader9_Release(shader_13);
7010 IDirect3DPixelShader9_Release(shader_12);
7011 IDirect3DPixelShader9_Release(shader_11);
7012 refcount = IDirect3DDevice9_Release(device);
7013 ok(!refcount, "Device has %u references left.\n", refcount);
7014 done:
7015 IDirect3D9_Release(d3d);
7016 DestroyWindow(window);
7019 static void nested_loop_test(void)
7021 IDirect3DVertexShader9 *vshader;
7022 IDirect3DPixelShader9 *shader;
7023 IDirect3DDevice9 *device;
7024 IDirect3D9 *d3d;
7025 ULONG refcount;
7026 D3DCAPS9 caps;
7027 DWORD color;
7028 HWND window;
7029 HRESULT hr;
7031 static const DWORD shader_code[] =
7033 0xffff0300, /* ps_3_0 */
7034 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
7035 0x05000051, 0xa00f0001, 0x3d000000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1/32, 0, 0, 0*/
7036 0x05000030, 0xf00f0000, 0x00000004, 0x00000000, 0x00000002, 0x00000000, /* defi i0, 4, 0, 2, 0 */
7037 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
7038 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
7039 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
7040 0x03000002, 0x800f0000, 0x80e40000, 0xa0e40001, /* add r0, r0, c1 */
7041 0x0000001d, /* endloop */
7042 0x0000001d, /* endloop */
7043 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
7044 0x0000ffff /* end */
7046 static const DWORD vshader_code[] =
7048 0xfffe0300, /* vs_3_0 */
7049 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7050 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
7051 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
7052 0x0000ffff /* end */
7054 static const float quad[] =
7056 -1.0f, -1.0f, 0.1f,
7057 -1.0f, 1.0f, 0.1f,
7058 1.0f, -1.0f, 0.1f,
7059 1.0f, 1.0f, 0.1f,
7062 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
7063 0, 0, 640, 480, NULL, NULL, NULL, NULL);
7064 d3d = Direct3DCreate9(D3D_SDK_VERSION);
7065 ok(!!d3d, "Failed to create a D3D object.\n");
7066 if (!(device = create_device(d3d, window, window, TRUE)))
7068 skip("Failed to create a D3D device, skipping tests.\n");
7069 goto done;
7072 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7073 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
7074 if (caps.PixelShaderVersion < D3DPS_VERSION(3, 0) || caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
7076 skip("No shader model 3 support, skipping tests.\n");
7077 IDirect3DDevice9_Release(device);
7078 goto done;
7081 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
7082 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with %08x\n", hr);
7083 hr = IDirect3DDevice9_SetPixelShader(device, shader);
7084 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
7085 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
7086 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
7087 hr = IDirect3DDevice9_SetVertexShader(device, vshader);
7088 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
7089 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
7090 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
7091 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x0000ff00, 1.0f, 0);
7092 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
7094 hr = IDirect3DDevice9_BeginScene(device);
7095 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7096 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
7097 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7098 hr = IDirect3DDevice9_EndScene(device);
7099 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7101 color = getPixelColor(device, 360, 240);
7102 ok(color_match(color, 0x00800000, 1),
7103 "Nested loop test returned color 0x%08x, expected 0x00800000.\n", color);
7105 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7106 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
7108 IDirect3DPixelShader9_Release(shader);
7109 IDirect3DVertexShader9_Release(vshader);
7110 refcount = IDirect3DDevice9_Release(device);
7111 ok(!refcount, "Device has %u references left.\n", refcount);
7112 done:
7113 IDirect3D9_Release(d3d);
7114 DestroyWindow(window);
7117 static void pretransformed_varying_test(void)
7119 /* dcl_position: fails to compile */
7120 static const DWORD blendweight_code[] =
7122 0xffff0300, /* ps_3_0 */
7123 0x0200001f, 0x80000001, 0x900f0000, /* dcl_blendweight, v0 */
7124 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
7125 0x0000ffff /* end */
7127 static const DWORD blendindices_code[] =
7129 0xffff0300, /* ps_3_0 */
7130 0x0200001f, 0x80000002, 0x900f0000, /* dcl_blendindices, v0 */
7131 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
7132 0x0000ffff /* end */
7134 static const DWORD normal_code[] =
7136 0xffff0300, /* ps_3_0 */
7137 0x0200001f, 0x80000003, 0x900f0000, /* dcl_normal, v0 */
7138 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
7139 0x0000ffff /* end */
7141 /* psize: fails? */
7142 static const DWORD texcoord0_code[] =
7144 0xffff0300, /* ps_3_0 */
7145 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord0, v0 */
7146 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
7147 0x0000ffff /* end */
7149 static const DWORD tangent_code[] =
7151 0xffff0300, /* ps_3_0 */
7152 0x0200001f, 0x80000006, 0x900f0000, /* dcl_tangent, v0 */
7153 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
7154 0x0000ffff /* end */
7156 static const DWORD binormal_code[] =
7158 0xffff0300, /* ps_3_0 */
7159 0x0200001f, 0x80000007, 0x900f0000, /* dcl_binormal, v0 */
7160 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
7161 0x0000ffff /* end */
7163 /* tessfactor: fails */
7164 /* positiont: fails */
7165 static const DWORD color_code[] =
7167 0xffff0300, /* ps_3_0 */
7168 0x0200001f, 0x8000000a, 0x900f0000, /* dcl_color0, v0 */
7169 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
7170 0x0000ffff /* end */
7172 static const DWORD fog_code[] =
7174 0xffff0300, /* ps_3_0 */
7175 0x0200001f, 0x8000000b, 0x900f0000, /* dcl_fog, v0 */
7176 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
7177 0x0000ffff /* end */
7179 static const DWORD depth_code[] =
7181 0xffff0300, /* ps_3_0 */
7182 0x0200001f, 0x8000000c, 0x900f0000, /* dcl_depth, v0 */
7183 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
7184 0x0000ffff /* end */
7186 static const DWORD specular_code[] =
7188 0xffff0300, /* ps_3_0 */
7189 0x0200001f, 0x8001000a, 0x900f0000, /* dcl_color1, v0 */
7190 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
7191 0x0000ffff /* end */
7193 /* sample: fails */
7194 static const DWORD texcoord1_code[] =
7196 0xffff0300, /* ps_3_0 */
7197 0x0200001f, 0x80010005, 0x900f0000, /* dcl_texcoord1, v0 */
7198 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
7199 0x0000ffff /* end */
7201 static const DWORD texcoord1_alpha_code[] =
7203 0xffff0300, /* ps_3_0 */
7204 0x0200001f, 0x80010005, 0x900f0000, /* dcl_texcoord1, v0 */
7205 0x02000001, 0x800f0800, 0x90ff0000, /* mov oC0, v0.w */
7206 0x0000ffff /* end */
7209 static const struct
7211 const char *name;
7212 const DWORD *shader_code;
7213 DWORD color;
7214 BOOL todo;
7215 BOOL broken_warp;
7217 tests[] =
7219 {"blendweight", blendweight_code, 0x00191919, TRUE },
7220 {"blendindices", blendindices_code, 0x00333333, TRUE },
7221 {"normal", normal_code, 0x004c4c4c, TRUE },
7222 {"texcoord0", texcoord0_code, 0x00808c8c, FALSE},
7223 {"tangent", tangent_code, 0x00999999, TRUE },
7224 {"binormal", binormal_code, 0x00b2b2b2, TRUE },
7225 {"color", color_code, 0x00e6e6e6, FALSE},
7226 {"fog", fog_code, 0x00666666, TRUE },
7227 {"depth", depth_code, 0x00cccccc, TRUE },
7228 {"specular", specular_code, 0x004488ff, FALSE},
7229 {"texcoord1", texcoord1_code, 0x00000000, FALSE},
7230 {"texcoord1 alpha", texcoord1_alpha_code, 0x00000000, FALSE, TRUE},
7232 /* Declare a monster vertex type :-) */
7233 static const D3DVERTEXELEMENT9 decl_elements[] = {
7234 {0, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT, 0},
7235 {0, 16, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT, 0},
7236 {0, 32, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES, 0},
7237 {0, 48, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
7238 {0, 64, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG, 0},
7239 {0, 80, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
7240 {0, 96, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT, 0},
7241 {0, 112, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL, 0},
7242 {0, 128, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH, 0},
7243 {0, 144, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7244 {0, 148, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 1},
7245 D3DDECL_END()
7248 static const struct
7250 float pos_x, pos_y, pos_z, rhw;
7251 float weight_1, weight_2, weight_3, weight_4;
7252 float index_1, index_2, index_3, index_4;
7253 float normal_1, normal_2, normal_3, normal_4;
7254 float fog_1, fog_2, fog_3, fog_4;
7255 float texcoord_1, texcoord_2, texcoord_3, texcoord_4;
7256 float tangent_1, tangent_2, tangent_3, tangent_4;
7257 float binormal_1, binormal_2, binormal_3, binormal_4;
7258 float depth_1, depth_2, depth_3, depth_4;
7259 D3DCOLOR diffuse;
7260 D3DCOLOR specular;
7262 data[] =
7265 0.0f, 0.0f, 0.1f, 1.0f,
7266 0.1f, 0.1f, 0.1f, 0.1f,
7267 0.2f, 0.2f, 0.2f, 0.2f,
7268 0.3f, 0.3f, 0.3f, 0.3f,
7269 0.4f, 0.4f, 0.4f, 0.4f,
7270 0.5f, 0.55f, 0.55f, 0.55f,
7271 0.6f, 0.6f, 0.6f, 0.7f,
7272 0.7f, 0.7f, 0.7f, 0.6f,
7273 0.8f, 0.8f, 0.8f, 0.8f,
7274 0xe6e6e6e6, /* 0.9 * 256 */
7275 0x224488ff, /* Nothing special */
7278 640.0f, 0.0f, 0.1f, 1.0f,
7279 0.1f, 0.1f, 0.1f, 0.1f,
7280 0.2f, 0.2f, 0.2f, 0.2f,
7281 0.3f, 0.3f, 0.3f, 0.3f,
7282 0.4f, 0.4f, 0.4f, 0.4f,
7283 0.5f, 0.55f, 0.55f, 0.55f,
7284 0.6f, 0.6f, 0.6f, 0.7f,
7285 0.7f, 0.7f, 0.7f, 0.6f,
7286 0.8f, 0.8f, 0.8f, 0.8f,
7287 0xe6e6e6e6, /* 0.9 * 256 */
7288 0x224488ff, /* Nothing special */
7291 0.0f, 480.0f, 0.1f, 1.0f,
7292 0.1f, 0.1f, 0.1f, 0.1f,
7293 0.2f, 0.2f, 0.2f, 0.2f,
7294 0.3f, 0.3f, 0.3f, 0.3f,
7295 0.4f, 0.4f, 0.4f, 0.4f,
7296 0.5f, 0.55f, 0.55f, 0.55f,
7297 0.6f, 0.6f, 0.6f, 0.7f,
7298 0.7f, 0.7f, 0.7f, 0.6f,
7299 0.8f, 0.8f, 0.8f, 0.8f,
7300 0xe6e6e6e6, /* 0.9 * 256 */
7301 0x224488ff, /* Nothing special */
7304 640.0f, 480.0f, 0.1f, 1.0f,
7305 0.1f, 0.1f, 0.1f, 0.1f,
7306 0.2f, 0.2f, 0.2f, 0.2f,
7307 0.3f, 0.3f, 0.3f, 0.3f,
7308 0.4f, 0.4f, 0.4f, 0.4f,
7309 0.5f, 0.55f, 0.55f, 0.55f,
7310 0.6f, 0.6f, 0.6f, 0.7f,
7311 0.7f, 0.7f, 0.7f, 0.6f,
7312 0.8f, 0.8f, 0.8f, 0.8f,
7313 0xe6e6e6e6, /* 0.9 * 256 */
7314 0x224488ff, /* Nothing special */
7317 D3DADAPTER_IDENTIFIER9 identifier;
7318 IDirect3DVertexDeclaration9 *decl;
7319 IDirect3DDevice9 *device;
7320 IDirect3D9 *d3d;
7321 unsigned int i;
7322 ULONG refcount;
7323 D3DCAPS9 caps;
7324 DWORD color;
7325 HWND window;
7326 HRESULT hr;
7327 BOOL warp;
7329 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
7330 0, 0, 640, 480, NULL, NULL, NULL, NULL);
7331 d3d = Direct3DCreate9(D3D_SDK_VERSION);
7332 ok(!!d3d, "Failed to create a D3D object.\n");
7333 if (!(device = create_device(d3d, window, window, TRUE)))
7335 skip("Failed to create a D3D device, skipping tests.\n");
7336 goto done;
7339 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7340 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
7341 if (caps.PixelShaderVersion < D3DPS_VERSION(3, 0) || caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
7343 skip("No shader model 3 support, skipping tests.\n");
7344 IDirect3DDevice9_Release(device);
7345 goto done;
7348 hr = IDirect3D9_GetAdapterIdentifier(d3d, D3DADAPTER_DEFAULT, 0, &identifier);
7349 ok(SUCCEEDED(hr), "Failed to get adapter identifier, hr %#x.\n", hr);
7350 warp = adapter_is_warp(&identifier);
7352 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
7353 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
7354 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
7355 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
7357 for (i = 0; i < sizeof(tests) / sizeof(*tests); ++i)
7359 IDirect3DPixelShader9 *shader;
7361 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
7362 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
7364 hr = IDirect3DDevice9_CreatePixelShader(device, tests[i].shader_code, &shader);
7365 ok(SUCCEEDED(hr), "Failed to create pixel shader for test %s, hr %#x.\n", tests[i].name, hr);
7367 hr = IDirect3DDevice9_SetPixelShader(device, shader);
7368 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
7370 hr = IDirect3DDevice9_BeginScene(device);
7371 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7372 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data, sizeof(*data));
7373 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7374 hr = IDirect3DDevice9_EndScene(device);
7375 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7377 /* This isn't a weekend's job to fix, ignore the problem for now.
7378 * Needs a replacement pipeline. */
7379 color = getPixelColor(device, 360, 240);
7380 if (tests[i].todo)
7381 todo_wine ok(color_match(color, tests[i].color, 1)
7382 || broken(color_match(color, 0x00000000, 1)
7383 && tests[i].shader_code == blendindices_code),
7384 "Test %s returned color 0x%08x, expected 0x%08x (todo).\n",
7385 tests[i].name, color, tests[i].color);
7386 else
7387 ok(color_match(color, tests[i].color, 1) || broken(warp && tests[i].broken_warp),
7388 "Test %s returned color 0x%08x, expected 0x%08x.\n",
7389 tests[i].name, color, tests[i].color);
7391 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7392 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
7394 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
7395 ok(SUCCEEDED(hr), "Failed to set pixel shader for test %s, hr %#x.\n", tests[i].name, hr);
7396 IDirect3DPixelShader9_Release(shader);
7399 IDirect3DVertexDeclaration9_Release(decl);
7400 refcount = IDirect3DDevice9_Release(device);
7401 ok(!refcount, "Device has %u references left.\n", refcount);
7402 done:
7403 IDirect3D9_Release(d3d);
7404 DestroyWindow(window);
7407 static void test_compare_instructions(void)
7409 IDirect3DVertexShader9 *shader_slt_scalar;
7410 IDirect3DVertexShader9 *shader_sge_scalar;
7411 IDirect3DVertexShader9 *shader_slt_vec;
7412 IDirect3DVertexShader9 *shader_sge_vec;
7413 IDirect3DDevice9 *device;
7414 IDirect3D9 *d3d;
7415 D3DCOLOR color;
7416 ULONG refcount;
7417 D3DCAPS9 caps;
7418 HWND window;
7419 HRESULT hr;
7421 static const DWORD shader_sge_vec_code[] =
7423 0xfffe0101, /* vs_1_1 */
7424 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7425 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
7426 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
7427 0x0000000d, 0xd00f0000, 0x80e40000, 0xa0e40001, /* sge oD0, r0, c1 */
7428 0x0000ffff /* end */
7430 static const DWORD shader_slt_vec_code[] =
7432 0xfffe0101, /* vs_1_1 */
7433 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7434 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
7435 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
7436 0x0000000c, 0xd00f0000, 0x80e40000, 0xa0e40001, /* slt oD0, r0, c1 */
7437 0x0000ffff /* end */
7439 static const DWORD shader_sge_scalar_code[] =
7441 0xfffe0101, /* vs_1_1 */
7442 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7443 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
7444 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
7445 0x0000000d, 0xd0010000, 0x80000000, 0xa0550001, /* slt oD0.r, r0.r, c1.b */
7446 0x0000000d, 0xd0020000, 0x80550000, 0xa0aa0001, /* slt oD0.g, r0.g, c1.r */
7447 0x0000000d, 0xd0040000, 0x80aa0000, 0xa0000001, /* slt oD0.b, r0.b, c1.g */
7448 0x0000ffff /* end */
7450 static const DWORD shader_slt_scalar_code[] =
7452 0xfffe0101, /* vs_1_1 */
7453 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7454 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
7455 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
7456 0x0000000c, 0xd0010000, 0x80000000, 0xa0aa0001, /* slt oD0.r, r0.r, c1.b */
7457 0x0000000c, 0xd0020000, 0x80550000, 0xa0000001, /* slt oD0.g, r0.g, c1.r */
7458 0x0000000c, 0xd0040000, 0x80aa0000, 0xa0550001, /* slt oD0.b, r0.b, c1.g */
7459 0x0000ffff /* end */
7461 static const float quad1[] =
7463 -1.0f, -1.0f, 0.1f,
7464 -1.0f, 0.0f, 0.1f,
7465 0.0f, -1.0f, 0.1f,
7466 0.0f, 0.0f, 0.1f,
7468 static const float quad2[] =
7470 0.0f, -1.0f, 0.1f,
7471 0.0f, 0.0f, 0.1f,
7472 1.0f, -1.0f, 0.1f,
7473 1.0f, 0.0f, 0.1f,
7475 static const float quad3[] =
7477 -1.0f, 0.0f, 0.1f,
7478 -1.0f, 1.0f, 0.1f,
7479 0.0f, 0.0f, 0.1f,
7480 0.0f, 1.0f, 0.1f,
7482 static const float quad4[] =
7484 0.0f, 0.0f, 0.1f,
7485 0.0f, 1.0f, 0.1f,
7486 1.0f, 0.0f, 0.1f,
7487 1.0f, 1.0f, 0.1f,
7489 static const float const0[4] = {0.8f, 0.2f, 0.2f, 0.2f};
7490 static const float const1[4] = {0.2f, 0.8f, 0.2f, 0.2f};
7492 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
7493 0, 0, 640, 480, NULL, NULL, NULL, NULL);
7494 d3d = Direct3DCreate9(D3D_SDK_VERSION);
7495 ok(!!d3d, "Failed to create a D3D object.\n");
7496 if (!(device = create_device(d3d, window, window, TRUE)))
7498 skip("Failed to create a D3D device, skipping tests.\n");
7499 goto done;
7502 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7503 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
7504 if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1))
7506 skip("No vs_1_1 support, skipping tests.\n");
7507 IDirect3DDevice9_Release(device);
7508 goto done;
7511 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
7512 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
7514 hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_vec_code, &shader_sge_vec);
7515 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
7516 hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_vec_code, &shader_slt_vec);
7517 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
7518 hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_scalar_code, &shader_sge_scalar);
7519 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
7520 hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_scalar_code, &shader_slt_scalar);
7521 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
7522 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
7523 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
7524 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, const1, 1);
7525 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
7526 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
7527 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
7529 hr = IDirect3DDevice9_BeginScene(device);
7530 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7532 hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_vec);
7533 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
7534 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
7535 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7537 hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_vec);
7538 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
7539 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 3);
7540 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7542 hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_scalar);
7543 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
7544 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
7545 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7547 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
7548 ok(SUCCEEDED(hr), "Failed to set vertex shader constant, hr %#x.\n", hr);
7550 hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_scalar);
7551 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
7552 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
7553 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7555 hr = IDirect3DDevice9_EndScene(device);
7556 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7558 color = getPixelColor(device, 160, 360);
7559 ok(color == 0x00ff00ff, "Compare test: Quad 1(sge vec) returned color 0x%08x, expected 0x00ff00ff\n", color);
7560 color = getPixelColor(device, 480, 360);
7561 ok(color == 0x0000ff00, "Compare test: Quad 2(slt vec) returned color 0x%08x, expected 0x0000ff00\n", color);
7562 color = getPixelColor(device, 160, 120);
7563 ok(color == 0x00ffffff, "Compare test: Quad 3(sge scalar) returned color 0x%08x, expected 0x00ffffff\n", color);
7564 color = getPixelColor(device, 480, 160);
7565 ok(color == 0x000000ff, "Compare test: Quad 4(slt scalar) returned color 0x%08x, expected 0x000000ff\n", color);
7567 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7568 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
7570 IDirect3DVertexShader9_Release(shader_sge_vec);
7571 IDirect3DVertexShader9_Release(shader_slt_vec);
7572 IDirect3DVertexShader9_Release(shader_sge_scalar);
7573 IDirect3DVertexShader9_Release(shader_slt_scalar);
7574 refcount = IDirect3DDevice9_Release(device);
7575 ok(!refcount, "Device has %u references left.\n", refcount);
7576 done:
7577 IDirect3D9_Release(d3d);
7578 DestroyWindow(window);
7581 static void test_vshader_input(void)
7583 IDirect3DVertexDeclaration9 *decl_twotexcrd, *decl_onetexcrd, *decl_twotex_wrongidx, *decl_twotexcrd_rightorder;
7584 IDirect3DVertexDeclaration9 *decl_texcoord_color, *decl_color_color, *decl_color_ubyte, *decl_color_float;
7585 IDirect3DVertexDeclaration9 *decl_nocolor;
7586 IDirect3DVertexShader9 *swapped_shader, *texcoord_color_shader, *color_color_shader;
7587 D3DADAPTER_IDENTIFIER9 identifier;
7588 IDirect3DPixelShader9 *ps;
7589 IDirect3DDevice9 *device;
7590 IDirect3D9 *d3d;
7591 ULONG refcount;
7592 unsigned int i;
7593 D3DCAPS9 caps;
7594 DWORD color;
7595 HWND window;
7596 HRESULT hr;
7597 BOOL warp;
7599 static const DWORD swapped_shader_code_3[] =
7601 0xfffe0300, /* vs_3_0 */
7602 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
7603 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
7604 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7605 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
7606 0x0200001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
7607 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
7608 0x02000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
7609 0x03000002, 0xe00f0001, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
7610 0x0000ffff /* end */
7612 static const DWORD swapped_shader_code_1[] =
7614 0xfffe0101, /* vs_1_1 */
7615 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7616 0x0000001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
7617 0x0000001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
7618 0x00000001, 0xc00f0000, 0x90e40000, /* mov o0, v0 */
7619 0x00000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
7620 0x00000002, 0xd00f0000, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
7621 0x0000ffff /* end */
7623 static const DWORD swapped_shader_code_2[] =
7625 0xfffe0200, /* vs_2_0 */
7626 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7627 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
7628 0x0200001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
7629 0x02000001, 0xc00f0000, 0x90e40000, /* mov o0, v0 */
7630 0x02000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
7631 0x03000002, 0xd00f0000, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
7632 0x0000ffff /* end */
7634 static const DWORD texcoord_color_shader_code_3[] =
7636 0xfffe0300, /* vs_3_0 */
7637 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
7638 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
7639 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7640 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
7641 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
7642 0x02000001, 0xe00f0001, 0x90e40001, /* mov o1, v1 */
7643 0x0000ffff /* end */
7645 static const DWORD texcoord_color_shader_code_2[] =
7647 0xfffe0200, /* vs_2_0 */
7648 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7649 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
7650 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
7651 0x02000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
7652 0x0000ffff /* end */
7654 static const DWORD texcoord_color_shader_code_1[] =
7656 0xfffe0101, /* vs_1_1 */
7657 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7658 0x0000001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
7659 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
7660 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
7661 0x0000ffff /* end */
7663 static const DWORD color_color_shader_code_3[] =
7665 0xfffe0300, /* vs_3_0 */
7666 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
7667 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
7668 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7669 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
7670 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
7671 0x03000005, 0xe00f0001, 0xa0e40000, 0x90e40001, /* mul o1, c0, v1 */
7672 0x0000ffff /* end */
7674 static const DWORD color_color_shader_code_2[] =
7676 0xfffe0200, /* vs_2_0 */
7677 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7678 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
7679 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
7680 0x03000005, 0xd00f0000, 0xa0e40000, 0x90e40001, /* mul oD0, c0, v1 */
7681 0x0000ffff /* end */
7683 static const DWORD color_color_shader_code_1[] =
7685 0xfffe0101, /* vs_1_1 */
7686 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7687 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
7688 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
7689 0x00000005, 0xd00f0000, 0xa0e40000, 0x90e40001, /* mul oD0, c0, v1 */
7690 0x0000ffff /* end */
7692 static const DWORD ps3_code[] =
7694 0xffff0300, /* ps_3_0 */
7695 0x0200001f, 0x8000000a, 0x900f0000, /* dcl_color0 v0 */
7696 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
7697 0x0000ffff /* end */
7699 static const float quad1[] =
7701 -1.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7702 -1.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7703 0.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7704 0.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7706 static const float quad2[] =
7708 0.0f, -1.0f, 0.1f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
7709 0.0f, 0.0f, 0.1f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
7710 1.0f, -1.0f, 0.1f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
7711 1.0f, 0.0f, 0.1f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
7713 static const float quad3[] =
7715 -1.0f, 0.0f, 0.1f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 0.0f, 0.0f,
7716 -1.0f, 1.0f, 0.1f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f,
7717 0.0f, 0.0f, 0.1f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f,
7718 0.0f, 1.0f, 0.1f, -1.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f,
7720 static const float quad4[] =
7722 0.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7723 0.0f, 1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7724 1.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7725 1.0f, 1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7727 static const float quad1_modified[] =
7729 -1.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f,
7730 -1.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f,
7731 0.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f,
7732 0.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, -1.0f, -1.0f, -1.0f, 0.0f,
7734 static const float quad2_modified[] =
7736 0.0f, -1.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
7737 0.0f, 0.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
7738 1.0f, -1.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
7739 1.0f, 0.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
7741 static const struct
7743 struct vec3 position;
7744 DWORD diffuse;
7746 quad1_color[] =
7748 {{-1.0f, -1.0f, 0.1f}, 0x00ff8040},
7749 {{-1.0f, 0.0f, 0.1f}, 0x00ff8040},
7750 {{ 0.0f, -1.0f, 0.1f}, 0x00ff8040},
7751 {{ 0.0f, 0.0f, 0.1f}, 0x00ff8040},
7753 quad2_color[] =
7755 {{ 0.0f, -1.0f, 0.1f}, 0x00ff8040},
7756 {{ 0.0f, 0.0f, 0.1f}, 0x00ff8040},
7757 {{ 1.0f, -1.0f, 0.1f}, 0x00ff8040},
7758 {{ 1.0f, 0.0f, 0.1f}, 0x00ff8040},
7760 quad3_color[] =
7762 {{-1.0f, 0.0f, 0.1f}, 0x00ff8040},
7763 {{-1.0f, 1.0f, 0.1f}, 0x00ff8040},
7764 {{ 0.0f, 0.0f, 0.1f}, 0x00ff8040},
7765 {{ 0.0f, 1.0f, 0.1f}, 0x00ff8040},
7767 static const float quad4_color[] =
7769 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 0.0f, 0.0f,
7770 0.0f, 1.0f, 0.1f, 1.0f, 1.0f, 0.0f, 0.0f,
7771 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 0.0f, 1.0f,
7772 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 0.0f, 1.0f,
7774 static const struct vec3 quad_nocolor[] =
7776 {-1.0f, -1.0f, 0.1f},
7777 {-1.0f, 1.0f, 0.1f},
7778 { 1.0f, -1.0f, 0.1f},
7779 { 1.0f, 1.0f, 0.1f},
7781 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd[] =
7783 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7784 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
7785 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
7786 D3DDECL_END()
7788 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_rightorder[] =
7790 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7791 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
7792 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
7793 D3DDECL_END()
7795 static const D3DVERTEXELEMENT9 decl_elements_onetexcrd[] =
7797 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7798 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
7799 D3DDECL_END()
7801 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_wrongidx[] =
7803 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7804 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
7805 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 2},
7806 D3DDECL_END()
7808 static const D3DVERTEXELEMENT9 decl_elements_texcoord_color[] =
7810 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7811 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
7812 D3DDECL_END()
7814 static const D3DVERTEXELEMENT9 decl_elements_color_color[] =
7816 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7817 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7818 D3DDECL_END()
7820 static const D3DVERTEXELEMENT9 decl_elements_color_ubyte[] =
7822 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7823 {0, 12, D3DDECLTYPE_UBYTE4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7824 D3DDECL_END()
7826 static const D3DVERTEXELEMENT9 decl_elements_color_float[] =
7828 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7829 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7830 D3DDECL_END()
7832 static const D3DVERTEXELEMENT9 decl_elements_nocolor[] =
7834 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7835 D3DDECL_END()
7837 static const float normalize[4] = {1.0f / 256.0f, 1.0f / 256.0f, 1.0f / 256.0f, 1.0f / 256.0f};
7838 static const float no_normalize[4] = {1.0f, 1.0f, 1.0f, 1.0f};
7840 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
7841 0, 0, 640, 480, NULL, NULL, NULL, NULL);
7842 d3d = Direct3DCreate9(D3D_SDK_VERSION);
7843 ok(!!d3d, "Failed to create a D3D object.\n");
7844 if (!(device = create_device(d3d, window, window, TRUE)))
7846 skip("Failed to create a D3D device, skipping tests.\n");
7847 goto done;
7850 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7851 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
7852 if (caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
7854 skip("No vs_3_0 support, skipping tests.\n");
7855 IDirect3DDevice9_Release(device);
7856 goto done;
7859 hr = IDirect3D9_GetAdapterIdentifier(d3d, D3DADAPTER_DEFAULT, 0, &identifier);
7860 ok(SUCCEEDED(hr), "Failed to get adapter identifier, hr %#x.\n", hr);
7861 warp = adapter_is_warp(&identifier);
7863 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd, &decl_twotexcrd);
7864 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
7865 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_onetexcrd, &decl_onetexcrd);
7866 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
7867 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_wrongidx, &decl_twotex_wrongidx);
7868 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
7869 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_rightorder, &decl_twotexcrd_rightorder);
7870 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
7872 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_texcoord_color, &decl_texcoord_color);
7873 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
7874 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_color, &decl_color_color);
7875 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
7876 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_ubyte, &decl_color_ubyte);
7877 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
7878 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_float, &decl_color_float);
7879 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
7880 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_nocolor, &decl_nocolor);
7881 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
7883 hr = IDirect3DDevice9_CreatePixelShader(device, ps3_code, &ps);
7884 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
7886 for (i = 1; i <= 3; ++i)
7888 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 1.0f, 0);
7889 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
7890 if(i == 3) {
7891 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_3, &swapped_shader);
7892 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
7893 hr = IDirect3DDevice9_SetPixelShader(device, ps);
7894 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
7895 } else if(i == 2){
7896 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_2, &swapped_shader);
7897 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
7898 } else if(i == 1) {
7899 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_1, &swapped_shader);
7900 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
7903 hr = IDirect3DDevice9_BeginScene(device);
7904 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7906 hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
7907 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
7909 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
7910 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
7911 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 11);
7912 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7914 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
7915 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
7916 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 11);
7917 if (i == 3 || i == 2)
7918 ok(SUCCEEDED(hr), "Failed to draw, i %u, hr %#x.\n", i, hr);
7919 else if (i == 1)
7920 /* Succeeds or fails, depending on SW or HW vertex processing. */
7921 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
7923 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd_rightorder);
7924 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
7925 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 11);
7926 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7928 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotex_wrongidx);
7929 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
7930 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 11);
7931 if (i == 3 || i == 2)
7932 ok(SUCCEEDED(hr), "Failed to draw, i %u, hr %#x.\n", i, hr);
7933 else if (i == 1)
7934 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
7936 hr = IDirect3DDevice9_EndScene(device);
7937 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7939 if(i == 3 || i == 2) {
7940 color = getPixelColor(device, 160, 360);
7941 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
7942 "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00ffff80\n", color);
7944 /* The last value of the read but undefined stream is used, it is 0x00. The defined input is vec4(1, 0, 0, 0) */
7945 color = getPixelColor(device, 480, 360);
7946 /* On the Windows 8 testbot (WARP) the draw succeeds, but uses
7947 * mostly random data as input. */
7948 ok(color == 0x00ffff00 || color == 0x00ff0000 || broken(warp),
7949 "Got unexpected color 0x%08x for quad 2 (1crd).\n", color);
7950 color = getPixelColor(device, 160, 120);
7951 /* Same as above, accept both the last used value and 0.0 for the undefined streams */
7952 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
7953 "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00ff0080\n", color);
7955 color = getPixelColor(device, 480, 160);
7956 ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
7957 } else if(i == 1) {
7958 color = getPixelColor(device, 160, 360);
7959 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
7960 "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00ffff80\n", color);
7961 color = getPixelColor(device, 480, 360);
7962 /* Accept the clear color as well in this case, since SW VP
7963 * returns an error. On the Windows 8 testbot (WARP) the draw
7964 * succeeds, but uses mostly random data as input. */
7965 ok(color == 0x00ffff00 || color == 0x00ff0000 || broken(warp),
7966 "Got unexpected color 0x%08x for quad 2 (1crd).\n", color);
7967 color = getPixelColor(device, 160, 120);
7968 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
7969 "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00ff0080\n", color);
7970 color = getPixelColor(device, 480, 160);
7971 ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
7974 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7975 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
7977 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff808080, 0.0, 0);
7978 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
7980 /* Now find out if the whole streams are re-read, or just the last
7981 * active value for the vertices is used. */
7982 hr = IDirect3DDevice9_BeginScene(device);
7983 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7985 hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
7986 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
7988 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
7989 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
7990 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 3, quad1_modified, sizeof(float) * 11);
7991 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7993 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
7994 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
7995 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_modified, sizeof(float) * 11);
7996 if (i == 3 || i == 2)
7997 ok(SUCCEEDED(hr), "Failed to draw, i %u, hr %#x.\n", i, hr);
7998 else if (i == 1)
7999 /* Succeeds or fails, depending on SW or HW vertex processing. */
8000 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
8002 hr = IDirect3DDevice9_EndScene(device);
8003 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
8005 color = getPixelColor(device, 480, 350);
8006 /* vs_1_1 may fail, accept the clear color. Some drivers also set the undefined streams to 0, accept that
8007 * as well.
8009 * NOTE: This test fails on the reference rasterizer. In the refrast, the 4 vertices have different colors,
8010 * i.e., the whole old stream is read, and not just the last used attribute. Some games require that this
8011 * does *not* happen, otherwise they can crash because of a read from a bad pointer, so do not accept the
8012 * refrast's result.
8014 * A test app for this behavior is Half Life 2 Episode 2 in dxlevel 95, and related games(Portal, TF2).
8016 ok(color == 0x000000ff || color == 0x00808080 || color == 0x00000000
8017 || broken(color_match(color, D3DCOLOR_ARGB(0x00, 0x0b, 0x75, 0x80), 1)),
8018 "Got unexpected color 0x%08x for quad 2 (different colors).\n", color);
8020 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8021 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
8023 IDirect3DDevice9_SetVertexShader(device, NULL);
8024 IDirect3DDevice9_SetPixelShader(device, NULL);
8025 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
8027 IDirect3DVertexShader9_Release(swapped_shader);
8030 for (i = 1; i <= 3; ++i)
8032 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
8033 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
8034 if(i == 3) {
8035 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_3, &texcoord_color_shader);
8036 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
8037 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_3, &color_color_shader);
8038 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
8039 hr = IDirect3DDevice9_SetPixelShader(device, ps);
8040 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
8041 } else if(i == 2){
8042 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_2, &texcoord_color_shader);
8043 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
8044 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_2, &color_color_shader);
8045 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
8046 } else if(i == 1) {
8047 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_1, &texcoord_color_shader);
8048 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
8049 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_1, &color_color_shader);
8050 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
8053 hr = IDirect3DDevice9_BeginScene(device);
8054 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
8056 hr = IDirect3DDevice9_SetVertexShader(device, texcoord_color_shader);
8057 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
8058 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_texcoord_color);
8059 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8060 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1_color, sizeof(quad1_color[0]));
8061 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8063 hr = IDirect3DDevice9_SetVertexShader(device, color_color_shader);
8064 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
8066 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, normalize, 1);
8067 ok(SUCCEEDED(hr), "Failed to set vertex shader constant, hr %#x.\n", hr);
8068 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_ubyte);
8069 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8070 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_color, sizeof(quad2_color[0]));
8071 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8073 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, no_normalize, 1);
8074 ok(SUCCEEDED(hr), "Failed to set vertex shader constant, hr %#x.\n", hr);
8075 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_color);
8076 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8077 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3_color, sizeof(quad3_color[0]));
8078 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8080 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_float);
8081 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8082 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4_color, sizeof(float) * 7);
8083 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8085 hr = IDirect3DDevice9_EndScene(device);
8086 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
8088 color = getPixelColor(device, 160, 360);
8089 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
8090 "Input test: Quad 1(color-texcoord) returned color 0x%08x, expected 0x00ff8040\n", color);
8091 color = getPixelColor(device, 480, 360);
8092 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x40, 0x80, 0xff), 1),
8093 "Input test: Quad 2(color-ubyte) returned color 0x%08x, expected 0x004080ff\n", color);
8094 color = getPixelColor(device, 160, 120);
8095 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
8096 "Input test: Quad 3(color-color) returned color 0x%08x, expected 0x00ff8040\n", color);
8097 color = getPixelColor(device, 480, 160);
8098 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 1),
8099 "Input test: Quad 4(color-float) returned color 0x%08x, expected 0x00ffff00\n", color);
8101 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8102 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
8104 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_nocolor);
8105 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8107 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
8108 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
8110 hr = IDirect3DDevice9_BeginScene(device);
8111 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
8112 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_nocolor, sizeof(quad_nocolor[0]));
8113 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8114 hr = IDirect3DDevice9_EndScene(device);
8115 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
8117 /* WARP ends up using the color attribute from the previous draw. Let's mark
8118 * that behavior as broken. */
8119 color = getPixelColor(device, 160, 360);
8120 ok(color_match(color, 0x00000000, 1)
8121 || broken(color_match(color, 0x00ffff00, 1)),
8122 "Got unexpected color 0x%08x for no color attribute test.\n", color);
8124 IDirect3DDevice9_SetVertexShader(device, NULL);
8125 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
8126 IDirect3DDevice9_SetPixelShader(device, NULL);
8128 IDirect3DVertexShader9_Release(texcoord_color_shader);
8129 IDirect3DVertexShader9_Release(color_color_shader);
8132 IDirect3DVertexDeclaration9_Release(decl_twotexcrd);
8133 IDirect3DVertexDeclaration9_Release(decl_onetexcrd);
8134 IDirect3DVertexDeclaration9_Release(decl_twotex_wrongidx);
8135 IDirect3DVertexDeclaration9_Release(decl_twotexcrd_rightorder);
8137 IDirect3DVertexDeclaration9_Release(decl_texcoord_color);
8138 IDirect3DVertexDeclaration9_Release(decl_color_color);
8139 IDirect3DVertexDeclaration9_Release(decl_color_ubyte);
8140 IDirect3DVertexDeclaration9_Release(decl_color_float);
8141 IDirect3DVertexDeclaration9_Release(decl_nocolor);
8143 IDirect3DPixelShader9_Release(ps);
8144 refcount = IDirect3DDevice9_Release(device);
8145 ok(!refcount, "Device has %u references left.\n", refcount);
8146 done:
8147 IDirect3D9_Release(d3d);
8148 DestroyWindow(window);
8151 static void srgbtexture_test(void)
8153 /* Fill a texture with 0x7f (~ .5), and then turn on the D3DSAMP_SRGBTEXTURE
8154 * texture stage state to render a quad using that texture. The resulting
8155 * color components should be 0x36 (~ 0.21), per this formula:
8156 * linear_color = ((srgb_color + 0.055) / 1.055) ^ 2.4
8157 * This is true where srgb_color > 0.04045. */
8158 struct IDirect3DTexture9 *texture;
8159 struct IDirect3DSurface9 *surface;
8160 IDirect3DDevice9 *device;
8161 IDirect3D9 *d3d;
8162 D3DCOLOR color;
8163 ULONG refcount;
8164 HWND window;
8165 HRESULT hr;
8167 static const float quad[] =
8169 -1.0f, -1.0f, 0.0f, 0.0f, 1.0f,
8170 -1.0f, 1.0f, 0.0f, 0.0f, 0.0f,
8171 1.0f, -1.0f, 0.0f, 1.0f, 1.0f,
8172 1.0f, 1.0f, 0.0f, 1.0f, 0.0f,
8175 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
8176 0, 0, 640, 480, NULL, NULL, NULL, NULL);
8177 d3d = Direct3DCreate9(D3D_SDK_VERSION);
8178 ok(!!d3d, "Failed to create a D3D object.\n");
8179 if (!(device = create_device(d3d, window, window, TRUE)))
8181 skip("Failed to create a D3D device, skipping tests.\n");
8182 goto done;
8185 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
8186 D3DFMT_X8R8G8B8, D3DUSAGE_QUERY_SRGBREAD, D3DRTYPE_TEXTURE, D3DFMT_A8R8G8B8) != D3D_OK)
8188 skip("D3DFMT_A8R8G8B8 textures with SRGBREAD not supported.\n");
8189 IDirect3DDevice9_Release(device);
8190 goto done;
8193 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
8194 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
8195 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
8196 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
8198 fill_surface(surface, 0xff7f7f7f, 0);
8199 IDirect3DSurface9_Release(surface);
8201 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
8202 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8203 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
8204 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
8206 hr = IDirect3DDevice9_BeginScene(device);
8207 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
8209 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, TRUE);
8210 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
8211 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8212 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
8213 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
8214 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8216 hr = IDirect3DDevice9_EndScene(device);
8217 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
8219 color = getPixelColor(device, 320, 240);
8220 ok(color_match(color, 0x00363636, 1), "sRGB quad has color 0x%08x, expected 0x00363636.\n", color);
8222 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8223 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
8225 IDirect3DTexture9_Release(texture);
8226 refcount = IDirect3DDevice9_Release(device);
8227 ok(!refcount, "Device has %u references left.\n", refcount);
8228 done:
8229 IDirect3D9_Release(d3d);
8230 DestroyWindow(window);
8233 static void test_shademode(void)
8235 IDirect3DVertexBuffer9 *vb_strip;
8236 IDirect3DVertexBuffer9 *vb_list;
8237 IDirect3DVertexShader9 *vs;
8238 IDirect3DPixelShader9 *ps;
8239 IDirect3DDevice9 *device;
8240 DWORD color0, color1;
8241 void *data = NULL;
8242 IDirect3D9 *d3d;
8243 ULONG refcount;
8244 D3DCAPS9 caps;
8245 HWND window;
8246 HRESULT hr;
8247 UINT i;
8248 static const DWORD vs1_code[] =
8250 0xfffe0101, /* vs_1_1 */
8251 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
8252 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
8253 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
8254 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
8255 0x0000ffff
8257 static const DWORD vs2_code[] =
8259 0xfffe0200, /* vs_2_0 */
8260 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
8261 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
8262 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
8263 0x02000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
8264 0x0000ffff
8266 static const DWORD vs3_code[] =
8268 0xfffe0300, /* vs_3_0 */
8269 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
8270 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
8271 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
8272 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color0 o1 */
8273 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
8274 0x02000001, 0xe00f0001, 0x90e40001, /* mov o1, v1 */
8275 0x0000ffff
8277 static const DWORD ps1_code[] =
8279 0xffff0101, /* ps_1_1 */
8280 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
8281 0x0000ffff
8283 static const DWORD ps2_code[] =
8285 0xffff0200, /* ps_2_0 */
8286 0x0200001f, 0x80000000, 0x900f0000, /* dcl v0 */
8287 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
8288 0x0000ffff
8290 static const DWORD ps3_code[] =
8292 0xffff0300, /* ps_3_0 */
8293 0x0200001f, 0x8000000a, 0x900f0000, /* dcl_color0 v0 */
8294 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
8295 0x0000ffff
8297 static const struct
8299 struct vec3 position;
8300 DWORD diffuse;
8302 quad_strip[] =
8304 {{-1.0f, -1.0f, 0.0f}, 0xffff0000},
8305 {{-1.0f, 1.0f, 0.0f}, 0xff00ff00},
8306 {{ 1.0f, -1.0f, 0.0f}, 0xff0000ff},
8307 {{ 1.0f, 1.0f, 0.0f}, 0xffffffff},
8309 quad_list[] =
8311 {{-1.0f, -1.0f, 0.0f}, 0xffff0000},
8312 {{-1.0f, 1.0f, 0.0f}, 0xff00ff00},
8313 {{ 1.0f, -1.0f, 0.0f}, 0xff0000ff},
8315 {{ 1.0f, -1.0f, 0.0f}, 0xff0000ff},
8316 {{-1.0f, 1.0f, 0.0f}, 0xff00ff00},
8317 {{ 1.0f, 1.0f, 0.0f}, 0xffffffff},
8319 static const struct test_shader
8321 DWORD version;
8322 const DWORD *code;
8324 novs = {0, NULL},
8325 vs_1 = {D3DVS_VERSION(1, 1), vs1_code},
8326 vs_2 = {D3DVS_VERSION(2, 0), vs2_code},
8327 vs_3 = {D3DVS_VERSION(3, 0), vs3_code},
8328 nops = {0, NULL},
8329 ps_1 = {D3DPS_VERSION(1, 1), ps1_code},
8330 ps_2 = {D3DPS_VERSION(2, 0), ps2_code},
8331 ps_3 = {D3DPS_VERSION(3, 0), ps3_code};
8332 static const struct
8334 const struct test_shader *vs, *ps;
8335 DWORD primtype;
8336 DWORD shademode;
8337 DWORD color0, color1;
8338 BOOL todo;
8340 tests[] =
8342 {&novs, &nops, D3DPT_TRIANGLESTRIP, D3DSHADE_FLAT, 0x00ff0000, 0x0000ff00, FALSE},
8343 {&novs, &nops, D3DPT_TRIANGLESTRIP, D3DSHADE_PHONG, 0x000dca28, 0x000d45c7, FALSE},
8344 {&novs, &nops, D3DPT_TRIANGLESTRIP, D3DSHADE_GOURAUD, 0x000dca28, 0x000d45c7, FALSE},
8345 {&novs, &nops, D3DPT_TRIANGLESTRIP, D3DSHADE_PHONG, 0x000dca28, 0x000d45c7, FALSE},
8346 {&novs, &nops, D3DPT_TRIANGLELIST, D3DSHADE_FLAT, 0x00ff0000, 0x000000ff, FALSE},
8347 {&novs, &nops, D3DPT_TRIANGLELIST, D3DSHADE_GOURAUD, 0x000dca28, 0x000d45c7, FALSE},
8348 {&vs_1, &ps_1, D3DPT_TRIANGLESTRIP, D3DSHADE_FLAT, 0x00ff0000, 0x0000ff00, FALSE},
8349 {&vs_1, &ps_1, D3DPT_TRIANGLESTRIP, D3DSHADE_GOURAUD, 0x000dca28, 0x000d45c7, FALSE},
8350 {&vs_1, &ps_1, D3DPT_TRIANGLELIST, D3DSHADE_FLAT, 0x00ff0000, 0x000000ff, FALSE},
8351 {&vs_1, &ps_1, D3DPT_TRIANGLELIST, D3DSHADE_GOURAUD, 0x000dca28, 0x000d45c7, FALSE},
8352 {&novs, &ps_1, D3DPT_TRIANGLESTRIP, D3DSHADE_FLAT, 0x00ff0000, 0x0000ff00, FALSE},
8353 {&vs_1, &nops, D3DPT_TRIANGLESTRIP, D3DSHADE_FLAT, 0x00ff0000, 0x0000ff00, FALSE},
8354 {&vs_2, &ps_2, D3DPT_TRIANGLESTRIP, D3DSHADE_FLAT, 0x00ff0000, 0x0000ff00, FALSE},
8355 {&vs_2, &ps_2, D3DPT_TRIANGLESTRIP, D3DSHADE_GOURAUD, 0x000dca28, 0x000d45c7, FALSE},
8356 {&vs_3, &ps_3, D3DPT_TRIANGLESTRIP, D3DSHADE_FLAT, 0x00ff0000, 0x0000ff00, TRUE},
8357 {&vs_3, &ps_3, D3DPT_TRIANGLESTRIP, D3DSHADE_GOURAUD, 0x000dca28, 0x000d45c7, FALSE},
8360 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
8361 0, 0, 640, 480, NULL, NULL, NULL, NULL);
8362 d3d = Direct3DCreate9(D3D_SDK_VERSION);
8363 ok(!!d3d, "Failed to create a D3D object.\n");
8364 if (!(device = create_device(d3d, window, window, TRUE)))
8366 skip("Failed to create a D3D device, skipping tests.\n");
8367 goto done;
8370 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
8371 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8372 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
8373 ok(SUCCEEDED(hr), "Failed to disable fog, hr %#x.\n", hr);
8375 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8376 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
8378 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_strip), 0, 0, D3DPOOL_MANAGED, &vb_strip, NULL);
8379 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
8380 hr = IDirect3DVertexBuffer9_Lock(vb_strip, 0, sizeof(quad_strip), &data, 0);
8381 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
8382 memcpy(data, quad_strip, sizeof(quad_strip));
8383 hr = IDirect3DVertexBuffer9_Unlock(vb_strip);
8384 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
8386 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_list), 0, 0, D3DPOOL_MANAGED, &vb_list, NULL);
8387 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
8388 hr = IDirect3DVertexBuffer9_Lock(vb_list, 0, sizeof(quad_list), &data, 0);
8389 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
8390 memcpy(data, quad_list, sizeof(quad_list));
8391 hr = IDirect3DVertexBuffer9_Unlock(vb_list);
8392 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
8394 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8395 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
8397 /* Try it first with a TRIANGLESTRIP. Do it with different geometry because
8398 * the color fixups we have to do for FLAT shading will be dependent on that. */
8400 for (i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i)
8402 if (tests[i].vs->version)
8404 if (caps.VertexShaderVersion >= tests[i].vs->version)
8406 hr = IDirect3DDevice9_CreateVertexShader(device, tests[i].vs->code, &vs);
8407 ok(hr == D3D_OK, "Failed to create vertex shader, hr %#x.\n", hr);
8408 hr = IDirect3DDevice9_SetVertexShader(device, vs);
8409 ok(hr == D3D_OK, "Failed to set vertex shader, hr %#x.\n", hr);
8411 else
8413 skip("Shader version unsupported, skipping some tests.\n");
8414 continue;
8417 else
8419 vs = NULL;
8421 if (tests[i].ps->version)
8423 if (caps.PixelShaderVersion >= tests[i].ps->version)
8425 hr = IDirect3DDevice9_CreatePixelShader(device, tests[i].ps->code, &ps);
8426 ok(hr == D3D_OK, "Failed to create pixel shader, hr %#x.\n", hr);
8427 hr = IDirect3DDevice9_SetPixelShader(device, ps);
8428 ok(hr == D3D_OK, "Failed to set pixel shader, hr %#x.\n", hr);
8430 else
8432 skip("Shader version unsupported, skipping some tests.\n");
8433 if (vs)
8435 IDirect3DDevice9_SetVertexShader(device, NULL);
8436 IDirect3DVertexShader9_Release(vs);
8438 continue;
8441 else
8443 ps = NULL;
8446 hr = IDirect3DDevice9_SetStreamSource(device, 0,
8447 tests[i].primtype == D3DPT_TRIANGLESTRIP ? vb_strip : vb_list, 0, sizeof(quad_strip[0]));
8448 ok(hr == D3D_OK, "Failed to set stream source, hr %#x.\n", hr);
8450 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
8451 ok(hr == D3D_OK, "Failed to clear, hr %#x.\n", hr);
8453 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, tests[i].shademode);
8454 ok(hr == D3D_OK, "Failed to set shade mode, hr %#x.\n", hr);
8456 hr = IDirect3DDevice9_BeginScene(device);
8457 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
8458 hr = IDirect3DDevice9_DrawPrimitive(device, tests[i].primtype, 0, 2);
8459 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8460 hr = IDirect3DDevice9_EndScene(device);
8461 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
8463 color0 = getPixelColor(device, 100, 100); /* Inside first triangle */
8464 color1 = getPixelColor(device, 500, 350); /* Inside second triangle */
8466 /* For D3DSHADE_FLAT it should take the color of the first vertex of
8467 * each triangle. This requires EXT_provoking_vertex or similar
8468 * functionality being available. */
8469 /* PHONG should be the same as GOURAUD, since no hardware implements
8470 * this. */
8471 todo_wine_if (tests[i].todo)
8473 ok(color_match(color0, tests[i].color0, 1), "Test %u shading has color0 %08x, expected %08x.\n",
8474 i, color0, tests[i].color0);
8475 ok(color_match(color1, tests[i].color1, 1), "Test %u shading has color1 %08x, expected %08x.\n",
8476 i, color1, tests[i].color1);
8478 IDirect3DDevice9_SetVertexShader(device, NULL);
8479 IDirect3DDevice9_SetPixelShader(device, NULL);
8481 if (ps)
8482 IDirect3DPixelShader9_Release(ps);
8483 if (vs)
8484 IDirect3DVertexShader9_Release(vs);
8487 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8488 ok(hr == D3D_OK, "Failed to present, hr %#x.\n", hr);
8490 IDirect3DVertexBuffer9_Release(vb_strip);
8491 IDirect3DVertexBuffer9_Release(vb_list);
8492 refcount = IDirect3DDevice9_Release(device);
8493 ok(!refcount, "Device has %u references left.\n", refcount);
8494 done:
8495 IDirect3D9_Release(d3d);
8496 DestroyWindow(window);
8499 static void test_blend(void)
8501 IDirect3DSurface9 *backbuffer, *offscreen;
8502 IDirect3DTexture9 *offscreenTexture;
8503 IDirect3DDevice9 *device;
8504 IDirect3D9 *d3d;
8505 D3DCOLOR color;
8506 ULONG refcount;
8507 HWND window;
8508 HRESULT hr;
8510 static const struct
8512 struct vec3 position;
8513 DWORD diffuse;
8515 quad1[] =
8517 {{-1.0f, -1.0f, 0.1f}, 0x4000ff00},
8518 {{-1.0f, 0.0f, 0.1f}, 0x4000ff00},
8519 {{ 1.0f, -1.0f, 0.1f}, 0x4000ff00},
8520 {{ 1.0f, 0.0f, 0.1f}, 0x4000ff00},
8522 quad2[] =
8524 {{-1.0f, 0.0f, 0.1f}, 0xc00000ff},
8525 {{-1.0f, 1.0f, 0.1f}, 0xc00000ff},
8526 {{ 1.0f, 0.0f, 0.1f}, 0xc00000ff},
8527 {{ 1.0f, 1.0f, 0.1f}, 0xc00000ff},
8529 static const float composite_quad[][5] =
8531 { 0.0f, -1.0f, 0.1f, 0.0f, 1.0f},
8532 { 0.0f, 1.0f, 0.1f, 0.0f, 0.0f},
8533 { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f},
8534 { 1.0f, 1.0f, 0.1f, 1.0f, 0.0f},
8537 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
8538 0, 0, 640, 480, NULL, NULL, NULL, NULL);
8539 d3d = Direct3DCreate9(D3D_SDK_VERSION);
8540 ok(!!d3d, "Failed to create a D3D object.\n");
8541 if (!(device = create_device(d3d, window, window, TRUE)))
8543 skip("Failed to create a D3D device, skipping tests.\n");
8544 goto done;
8547 /* Clear the render target with alpha = 0.5 */
8548 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x80ff0000, 1.0f, 0);
8549 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
8551 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET,
8552 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
8553 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
8555 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8556 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
8558 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
8559 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
8561 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8562 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
8564 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8565 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8566 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8567 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8568 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
8569 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
8570 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
8571 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
8572 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
8573 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8575 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
8576 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8577 hr = IDirect3DDevice9_BeginScene(device);
8578 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
8580 /* Draw two quads, one with src alpha blending, one with dest alpha
8581 * blending. */
8582 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
8583 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
8584 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
8585 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
8586 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
8587 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8589 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
8590 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
8591 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
8592 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
8593 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
8594 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8596 /* Switch to the offscreen buffer, and redo the testing. The offscreen
8597 * render target doesn't have an alpha channel. DESTALPHA and INVDESTALPHA
8598 * "don't work" on render targets without alpha channel, they give
8599 * essentially ZERO and ONE blend factors. */
8600 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
8601 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
8602 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x80ff0000, 1.0f, 0);
8603 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
8605 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
8606 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
8607 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
8608 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
8609 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
8610 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8612 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
8613 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
8614 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
8615 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
8616 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
8617 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8619 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8620 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
8622 /* Render the offscreen texture onto the frame buffer to be able to
8623 * compare it regularly. Disable alpha blending for the final
8624 * composition. */
8625 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
8626 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
8627 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8628 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
8630 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
8631 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
8632 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, composite_quad, sizeof(float) * 5);
8633 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8635 hr = IDirect3DDevice9_EndScene(device);
8636 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
8638 color = getPixelColor(device, 160, 360);
8639 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
8640 "SRCALPHA on frame buffer returned color %08x, expected 0x00bf4000\n", color);
8642 color = getPixelColor(device, 160, 120);
8643 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x00, 0x80), 2),
8644 "DSTALPHA on frame buffer returned color %08x, expected 0x007f0080\n", color);
8646 color = getPixelColor(device, 480, 360);
8647 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
8648 "SRCALPHA on texture returned color %08x, expected 0x00bf4000\n", color);
8650 color = getPixelColor(device, 480, 120);
8651 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
8652 "DSTALPHA on texture returned color %08x, expected 0x000000ff\n", color);
8654 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8656 IDirect3DSurface9_Release(backbuffer);
8657 IDirect3DTexture9_Release(offscreenTexture);
8658 IDirect3DSurface9_Release(offscreen);
8659 refcount = IDirect3DDevice9_Release(device);
8660 ok(!refcount, "Device has %u references left.\n", refcount);
8661 done:
8662 IDirect3D9_Release(d3d);
8663 DestroyWindow(window);
8666 static void fixed_function_decl_test(void)
8668 IDirect3DVertexDeclaration9 *dcl_float = NULL, *dcl_short = NULL, *dcl_ubyte = NULL, *dcl_color = NULL;
8669 IDirect3DVertexDeclaration9 *dcl_color_2 = NULL, *dcl_ubyte_2 = NULL, *dcl_nocolor, *dcl_positiont;
8670 IDirect3DVertexBuffer9 *vb, *vb2;
8671 IDirect3DDevice9 *device;
8672 BOOL s_ok, ub_ok, f_ok;
8673 DWORD color, size, i;
8674 IDirect3D9 *d3d;
8675 ULONG refcount;
8676 D3DCAPS9 caps;
8677 HWND window;
8678 void *data;
8679 HRESULT hr;
8681 static const D3DVERTEXELEMENT9 decl_elements_d3dcolor[] = {
8682 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8683 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
8684 D3DDECL_END()
8686 static const D3DVERTEXELEMENT9 decl_elements_d3dcolor_2streams[] = {
8687 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8688 {1, 0, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
8689 D3DDECL_END()
8691 static const D3DVERTEXELEMENT9 decl_elements_ubyte4n[] = {
8692 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8693 {0, 12, D3DDECLTYPE_UBYTE4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
8694 D3DDECL_END()
8696 static const D3DVERTEXELEMENT9 decl_elements_ubyte4n_2streams[] = {
8697 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8698 {1, 0, D3DDECLTYPE_UBYTE4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
8699 D3DDECL_END()
8701 static const D3DVERTEXELEMENT9 decl_elements_short4[] = {
8702 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8703 {0, 12, D3DDECLTYPE_USHORT4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
8704 D3DDECL_END()
8706 static const D3DVERTEXELEMENT9 decl_elements_float[] = {
8707 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8708 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
8709 D3DDECL_END()
8711 static const D3DVERTEXELEMENT9 decl_elements_nocolor[] = {
8712 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8713 D3DDECL_END()
8715 static const D3DVERTEXELEMENT9 decl_elements_positiont[] = {
8716 {0, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT, 0},
8717 {0, 16, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
8718 D3DDECL_END()
8720 static const struct
8722 struct vec3 position;
8723 DWORD diffuse;
8725 quad1[] = /* D3DCOLOR */
8727 {{-1.0f, -1.0f, 0.1f}, 0x00ffff00},
8728 {{-1.0f, 0.0f, 0.1f}, 0x00ffff00},
8729 {{ 0.0f, -1.0f, 0.1f}, 0x00ffff00},
8730 {{ 0.0f, 0.0f, 0.1f}, 0x00ffff00},
8732 quad2[] = /* UBYTE4N */
8734 {{-1.0f, 0.0f, 0.1f}, 0x00ffff00},
8735 {{-1.0f, 1.0f, 0.1f}, 0x00ffff00},
8736 {{ 0.0f, 0.0f, 0.1f}, 0x00ffff00},
8737 {{ 0.0f, 1.0f, 0.1f}, 0x00ffff00},
8739 static const struct
8741 struct vec3 position;
8742 struct { unsigned short x, y, z, w; } color;
8744 quad3[] = /* USHORT4N */
8746 {{0.0f, -1.0f, 0.1f}, {0x0000, 0x0000, 0xffff, 0xffff}},
8747 {{0.0f, 0.0f, 0.1f}, {0x0000, 0x0000, 0xffff, 0xffff}},
8748 {{1.0f, -1.0f, 0.1f}, {0x0000, 0x0000, 0xffff, 0xffff}},
8749 {{1.0f, 0.0f, 0.1f}, {0x0000, 0x0000, 0xffff, 0xffff}},
8751 static const struct
8753 struct vec3 position;
8754 struct vec4 color;
8756 quad4[] =
8758 {{0.0f, 0.0f, 0.1f}, {1.0f, 0.0f, 0.0f, 0.0f}},
8759 {{0.0f, 1.0f, 0.1f}, {1.0f, 0.0f, 0.0f, 0.0f}},
8760 {{1.0f, 0.0f, 0.1f}, {1.0f, 0.0f, 0.0f, 0.0f}},
8761 {{1.0f, 1.0f, 0.1f}, {1.0f, 0.0f, 0.0f, 0.0f}},
8763 static const DWORD colors[] =
8765 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8766 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8767 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8768 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8769 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8770 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8771 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8772 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8773 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8774 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8775 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8776 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8777 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8778 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8779 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8780 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8782 static const float quads[] =
8784 -1.0f, -1.0f, 0.1f,
8785 -1.0f, 0.0f, 0.1f,
8786 0.0f, -1.0f, 0.1f,
8787 0.0f, 0.0f, 0.1f,
8789 0.0f, -1.0f, 0.1f,
8790 0.0f, 0.0f, 0.1f,
8791 1.0f, -1.0f, 0.1f,
8792 1.0f, 0.0f, 0.1f,
8794 0.0f, 0.0f, 0.1f,
8795 0.0f, 1.0f, 0.1f,
8796 1.0f, 0.0f, 0.1f,
8797 1.0f, 1.0f, 0.1f,
8799 -1.0f, 0.0f, 0.1f,
8800 -1.0f, 1.0f, 0.1f,
8801 0.0f, 0.0f, 0.1f,
8802 0.0f, 1.0f, 0.1f,
8804 static const struct
8806 struct vec4 position;
8807 DWORD diffuse;
8809 quad_transformed[] =
8811 {{ 90.0f, 110.0f, 0.1f, 2.0f}, 0x00ffff00},
8812 {{570.0f, 110.0f, 0.1f, 2.0f}, 0x00ffff00},
8813 {{ 90.0f, 300.0f, 0.1f, 2.0f}, 0x00ffff00},
8814 {{570.0f, 300.0f, 0.1f, 2.0f}, 0x00ffff00},
8817 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
8818 0, 0, 640, 480, NULL, NULL, NULL, NULL);
8819 d3d = Direct3DCreate9(D3D_SDK_VERSION);
8820 ok(!!d3d, "Failed to create a D3D object.\n");
8821 if (!(device = create_device(d3d, window, window, TRUE)))
8823 skip("Failed to create a D3D device, skipping tests.\n");
8824 goto done;
8827 memset(&caps, 0, sizeof(caps));
8828 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8829 ok(hr == D3D_OK, "GetDeviceCaps failed, hr = %08x\n", hr);
8831 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
8832 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
8834 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor, &dcl_color);
8835 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
8836 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_short4, &dcl_short);
8837 ok(SUCCEEDED(hr) || hr == E_FAIL, "CreateVertexDeclaration failed (%08x)\n", hr);
8838 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_float, &dcl_float);
8839 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
8840 if(caps.DeclTypes & D3DDTCAPS_UBYTE4N) {
8841 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n_2streams, &dcl_ubyte_2);
8842 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
8843 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n, &dcl_ubyte);
8844 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
8845 } else {
8846 trace("D3DDTCAPS_UBYTE4N not supported\n");
8847 dcl_ubyte_2 = NULL;
8848 dcl_ubyte = NULL;
8850 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor_2streams, &dcl_color_2);
8851 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
8852 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_nocolor, &dcl_nocolor);
8853 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
8854 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_positiont, &dcl_positiont);
8855 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
8857 size = max(sizeof(quad1), max(sizeof(quad2), max(sizeof(quad3), max(sizeof(quad4), sizeof(quads)))));
8858 hr = IDirect3DDevice9_CreateVertexBuffer(device, size,
8859 0, 0, D3DPOOL_MANAGED, &vb, NULL);
8860 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
8862 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
8863 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
8865 hr = IDirect3DDevice9_BeginScene(device);
8866 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
8868 f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
8869 if (dcl_color)
8871 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
8872 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8873 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
8874 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8877 /* Tests with non-standard fixed function types fail on the refrast. The
8878 * ATI driver partially accepts them, the NVIDIA driver accepts them all.
8879 * All those differences even though we're using software vertex
8880 * processing. Doh! */
8881 if (dcl_ubyte)
8883 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
8884 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8885 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
8886 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
8887 ub_ok = SUCCEEDED(hr);
8890 if (dcl_short)
8892 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
8893 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8894 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(quad3[0]));
8895 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
8896 s_ok = SUCCEEDED(hr);
8899 if (dcl_float)
8901 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
8902 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8903 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(quad4[0]));
8904 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
8905 f_ok = SUCCEEDED(hr);
8908 hr = IDirect3DDevice9_EndScene(device);
8909 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
8911 if(dcl_short) {
8912 color = getPixelColor(device, 480, 360);
8913 ok(color == 0x000000ff || !s_ok,
8914 "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
8916 if(dcl_ubyte) {
8917 color = getPixelColor(device, 160, 120);
8918 ok(color == 0x0000ffff || !ub_ok,
8919 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
8921 if(dcl_color) {
8922 color = getPixelColor(device, 160, 360);
8923 ok(color == 0x00ffff00,
8924 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
8926 if(dcl_float) {
8927 color = getPixelColor(device, 480, 120);
8928 ok(color == 0x00ff0000 || !f_ok,
8929 "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
8931 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8933 /* The following test with vertex buffers doesn't serve to find out new
8934 * information from windows. It is a plain regression test because wined3d
8935 * uses different codepaths for attribute conversion with vertex buffers.
8936 * It makes sure that the vertex buffer one works, while the above tests
8937 * whether the immediate mode code works. */
8938 f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
8939 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
8940 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
8941 hr = IDirect3DDevice9_BeginScene(device);
8942 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
8944 if (dcl_color)
8946 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad1), &data, 0);
8947 ok(SUCCEEDED(hr), "Failed to lock vertex buffer, hr %#x.\n", hr);
8948 memcpy(data, quad1, sizeof(quad1));
8949 hr = IDirect3DVertexBuffer9_Unlock(vb);
8950 ok(SUCCEEDED(hr), "Failed to unlock vertex buffer, hr %#x.\n", hr);
8951 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
8952 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8953 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad1[0]));
8954 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
8955 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
8956 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8959 if (dcl_ubyte)
8961 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad2), &data, 0);
8962 ok(SUCCEEDED(hr), "Failed to lock vertex buffer, hr %#x.\n", hr);
8963 memcpy(data, quad2, sizeof(quad2));
8964 hr = IDirect3DVertexBuffer9_Unlock(vb);
8965 ok(SUCCEEDED(hr), "Failed to unlock vertex buffer, hr %#x.\n", hr);
8966 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
8967 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8968 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad2[0]));
8969 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
8970 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
8971 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
8972 ub_ok = SUCCEEDED(hr);
8975 if (dcl_short)
8977 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad3), &data, 0);
8978 ok(SUCCEEDED(hr), "Failed to lock vertex buffer, hr %#x.\n", hr);
8979 memcpy(data, quad3, sizeof(quad3));
8980 hr = IDirect3DVertexBuffer9_Unlock(vb);
8981 ok(SUCCEEDED(hr), "Failed to unlock vertex buffer, hr %#x.\n", hr);
8982 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
8983 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8984 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad3[0]));
8985 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
8986 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
8987 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
8988 s_ok = SUCCEEDED(hr);
8991 if (dcl_float)
8993 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad4), &data, 0);
8994 ok(SUCCEEDED(hr), "Failed to lock vertex buffer, hr %#x.\n", hr);
8995 memcpy(data, quad4, sizeof(quad4));
8996 hr = IDirect3DVertexBuffer9_Unlock(vb);
8997 ok(SUCCEEDED(hr), "Failed to unlock vertex buffer, hr %#x.\n", hr);
8998 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
8999 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
9000 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad4[0]));
9001 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
9002 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
9003 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
9004 f_ok = SUCCEEDED(hr);
9007 hr = IDirect3DDevice9_EndScene(device);
9008 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9010 if(dcl_short) {
9011 color = getPixelColor(device, 480, 360);
9012 ok(color == 0x000000ff || !s_ok,
9013 "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
9015 if(dcl_ubyte) {
9016 color = getPixelColor(device, 160, 120);
9017 ok(color == 0x0000ffff || !ub_ok,
9018 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
9020 if(dcl_color) {
9021 color = getPixelColor(device, 160, 360);
9022 ok(color == 0x00ffff00,
9023 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
9025 if(dcl_float) {
9026 color = getPixelColor(device, 480, 120);
9027 ok(color == 0x00ff0000 || !f_ok,
9028 "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
9030 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9032 /* Test with no diffuse color attribute. */
9033 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
9034 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
9036 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_nocolor);
9037 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
9038 hr = IDirect3DDevice9_BeginScene(device);
9039 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9040 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quads, sizeof(float) * 3);
9041 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9042 hr = IDirect3DDevice9_EndScene(device);
9043 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9045 color = getPixelColor(device, 160, 360);
9046 ok(color == 0x00ffffff, "Got unexpected color 0x%08x in the no color attribute test.\n", color);
9048 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9050 /* Test what happens with specular lighting enabled and no specular color attribute. */
9051 f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
9052 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
9053 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
9054 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARENABLE, TRUE);
9055 ok(SUCCEEDED(hr), "Failed to enable specular lighting, hr %#x.\n", hr);
9056 hr = IDirect3DDevice9_BeginScene(device);
9057 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9059 if (dcl_color)
9061 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
9062 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
9063 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
9064 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9066 if (dcl_ubyte)
9068 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
9069 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
9070 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
9071 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
9072 ub_ok = SUCCEEDED(hr);
9074 if (dcl_short)
9076 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
9077 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
9078 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(quad3[0]));
9079 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
9080 s_ok = SUCCEEDED(hr);
9082 if (dcl_float)
9084 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
9085 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
9086 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(quad4[0]));
9087 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
9088 f_ok = SUCCEEDED(hr);
9091 hr = IDirect3DDevice9_EndScene(device);
9092 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9093 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARENABLE, FALSE);
9094 ok(SUCCEEDED(hr), "Failed to disable specular lighting, hr %#x.\n", hr);
9096 if (dcl_short)
9098 color = getPixelColor(device, 480, 360);
9099 ok(color == 0x000000ff || !s_ok,
9100 "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff.\n", color);
9102 if (dcl_ubyte)
9104 color = getPixelColor(device, 160, 120);
9105 ok(color == 0x0000ffff || !ub_ok,
9106 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff.\n", color);
9108 if (dcl_color)
9110 color = getPixelColor(device, 160, 360);
9111 ok(color == 0x00ffff00,
9112 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00.\n", color);
9114 if (dcl_float)
9116 color = getPixelColor(device, 480, 120);
9117 ok(color == 0x00ff0000 || !f_ok,
9118 "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000.\n", color);
9120 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9122 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad_transformed), &data, 0);
9123 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9124 memcpy(data, quad_transformed, sizeof(quad_transformed));
9125 hr = IDirect3DVertexBuffer9_Unlock(vb);
9126 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
9128 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_positiont);
9129 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
9131 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
9132 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9134 hr = IDirect3DDevice9_BeginScene(device);
9135 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9136 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad_transformed[0]));
9137 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
9138 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
9139 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9140 hr = IDirect3DDevice9_EndScene(device);
9141 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9143 color = getPixelColor(device, 88, 108);
9144 ok(color == 0x000000ff,
9145 "pixel 88/108 has color %08x, expected 0x000000ff\n", color);
9146 color = getPixelColor(device, 92, 108);
9147 ok(color == 0x000000ff,
9148 "pixel 92/108 has color %08x, expected 0x000000ff\n", color);
9149 color = getPixelColor(device, 88, 112);
9150 ok(color == 0x000000ff,
9151 "pixel 88/112 has color %08x, expected 0x000000ff\n", color);
9152 color = getPixelColor(device, 92, 112);
9153 ok(color == 0x00ffff00,
9154 "pixel 92/112 has color %08x, expected 0x00ffff00\n", color);
9156 color = getPixelColor(device, 568, 108);
9157 ok(color == 0x000000ff,
9158 "pixel 568/108 has color %08x, expected 0x000000ff\n", color);
9159 color = getPixelColor(device, 572, 108);
9160 ok(color == 0x000000ff,
9161 "pixel 572/108 has color %08x, expected 0x000000ff\n", color);
9162 color = getPixelColor(device, 568, 112);
9163 ok(color == 0x00ffff00,
9164 "pixel 568/112 has color %08x, expected 0x00ffff00\n", color);
9165 color = getPixelColor(device, 572, 112);
9166 ok(color == 0x000000ff,
9167 "pixel 572/112 has color %08x, expected 0x000000ff\n", color);
9169 color = getPixelColor(device, 88, 298);
9170 ok(color == 0x000000ff,
9171 "pixel 88/298 has color %08x, expected 0x000000ff\n", color);
9172 color = getPixelColor(device, 92, 298);
9173 ok(color == 0x00ffff00,
9174 "pixel 92/298 has color %08x, expected 0x00ffff00\n", color);
9175 color = getPixelColor(device, 88, 302);
9176 ok(color == 0x000000ff,
9177 "pixel 88/302 has color %08x, expected 0x000000ff\n", color);
9178 color = getPixelColor(device, 92, 302);
9179 ok(color == 0x000000ff,
9180 "pixel 92/302 has color %08x, expected 0x000000ff\n", color);
9182 color = getPixelColor(device, 568, 298);
9183 ok(color == 0x00ffff00,
9184 "pixel 568/298 has color %08x, expected 0x00ffff00\n", color);
9185 color = getPixelColor(device, 572, 298);
9186 ok(color == 0x000000ff,
9187 "pixel 572/298 has color %08x, expected 0x000000ff\n", color);
9188 color = getPixelColor(device, 568, 302);
9189 ok(color == 0x000000ff,
9190 "pixel 568/302 has color %08x, expected 0x000000ff\n", color);
9191 color = getPixelColor(device, 572, 302);
9192 ok(color == 0x000000ff,
9193 "pixel 572/302 has color %08x, expected 0x000000ff\n", color);
9195 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9197 /* This test is pointless without those two declarations: */
9198 if((!dcl_color_2) || (!dcl_ubyte_2)) {
9199 skip("color-ubyte switching test declarations aren't supported\n");
9200 goto out;
9203 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quads), &data, 0);
9204 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9205 memcpy(data, quads, sizeof(quads));
9206 hr = IDirect3DVertexBuffer9_Unlock(vb);
9207 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
9208 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(colors),
9209 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
9210 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9211 hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(colors), &data, 0);
9212 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9213 memcpy(data, colors, sizeof(colors));
9214 hr = IDirect3DVertexBuffer9_Unlock(vb2);
9215 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
9217 for(i = 0; i < 2; i++) {
9218 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
9219 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9221 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(float) * 3);
9222 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
9223 if(i == 0) {
9224 hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 0, sizeof(DWORD) * 4);
9225 } else {
9226 hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 8, sizeof(DWORD) * 4);
9228 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
9230 hr = IDirect3DDevice9_BeginScene(device);
9231 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9233 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
9234 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
9235 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
9236 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
9237 ub_ok = SUCCEEDED(hr);
9239 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color_2);
9240 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
9241 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
9242 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9244 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
9245 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
9246 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
9247 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
9248 ub_ok = (SUCCEEDED(hr) && ub_ok);
9250 hr = IDirect3DDevice9_EndScene(device);
9251 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9253 if(i == 0) {
9254 color = getPixelColor(device, 480, 360);
9255 ok(color == 0x00ff0000,
9256 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ff0000\n", color);
9257 color = getPixelColor(device, 160, 120);
9258 ok(color == 0x00ffffff,
9259 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
9260 color = getPixelColor(device, 160, 360);
9261 ok(color == 0x000000ff || !ub_ok,
9262 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
9263 color = getPixelColor(device, 480, 120);
9264 ok(color == 0x000000ff || !ub_ok,
9265 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
9266 } else {
9267 color = getPixelColor(device, 480, 360);
9268 ok(color == 0x000000ff,
9269 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x000000ff\n", color);
9270 color = getPixelColor(device, 160, 120);
9271 ok(color == 0x00ffffff,
9272 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
9273 color = getPixelColor(device, 160, 360);
9274 ok(color == 0x00ff0000 || !ub_ok,
9275 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
9276 color = getPixelColor(device, 480, 120);
9277 ok(color == 0x00ff0000 || !ub_ok,
9278 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
9280 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9283 IDirect3DVertexBuffer9_Release(vb2);
9284 out:
9285 IDirect3DVertexBuffer9_Release(vb);
9286 if(dcl_float) IDirect3DVertexDeclaration9_Release(dcl_float);
9287 if(dcl_short) IDirect3DVertexDeclaration9_Release(dcl_short);
9288 if(dcl_ubyte) IDirect3DVertexDeclaration9_Release(dcl_ubyte);
9289 if(dcl_color) IDirect3DVertexDeclaration9_Release(dcl_color);
9290 if(dcl_color_2) IDirect3DVertexDeclaration9_Release(dcl_color_2);
9291 if(dcl_ubyte_2) IDirect3DVertexDeclaration9_Release(dcl_ubyte_2);
9292 IDirect3DVertexDeclaration9_Release(dcl_nocolor);
9293 IDirect3DVertexDeclaration9_Release(dcl_positiont);
9294 refcount = IDirect3DDevice9_Release(device);
9295 ok(!refcount, "Device has %u references left.\n", refcount);
9296 done:
9297 IDirect3D9_Release(d3d);
9298 DestroyWindow(window);
9301 static void test_vshader_float16(void)
9303 IDirect3DVertexDeclaration9 *vdecl = NULL;
9304 IDirect3DVertexBuffer9 *buffer = NULL;
9305 IDirect3DVertexShader9 *shader;
9306 IDirect3DDevice9 *device;
9307 IDirect3D9 *d3d;
9308 ULONG refcount;
9309 D3DCAPS9 caps;
9310 DWORD color;
9311 HWND window;
9312 void *data;
9313 HRESULT hr;
9315 static const D3DVERTEXELEMENT9 decl_elements[] =
9317 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9318 {0, 12, D3DDECLTYPE_FLOAT16_4,D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9319 D3DDECL_END()
9321 static const DWORD shader_code[] =
9323 0xfffe0101, /* vs_1_1 */
9324 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
9325 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
9326 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
9327 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
9328 0x0000ffff,
9330 static const struct vertex_float16color
9332 float x, y, z;
9333 DWORD c1, c2;
9335 quad[] =
9337 { -1.0, -1.0, 0.1, 0x3c000000, 0x00000000 }, /* green */
9338 { -1.0, 0.0, 0.1, 0x3c000000, 0x00000000 },
9339 { 0.0, -1.0, 0.1, 0x3c000000, 0x00000000 },
9340 { 0.0, 0.0, 0.1, 0x3c000000, 0x00000000 },
9342 { 0.0, -1.0, 0.1, 0x00003c00, 0x00000000 }, /* red */
9343 { 0.0, 0.0, 0.1, 0x00003c00, 0x00000000 },
9344 { 1.0, -1.0, 0.1, 0x00003c00, 0x00000000 },
9345 { 1.0, 0.0, 0.1, 0x00003c00, 0x00000000 },
9347 { 0.0, 0.0, 0.1, 0x00000000, 0x00003c00 }, /* blue */
9348 { 0.0, 1.0, 0.1, 0x00000000, 0x00003c00 },
9349 { 1.0, 0.0, 0.1, 0x00000000, 0x00003c00 },
9350 { 1.0, 1.0, 0.1, 0x00000000, 0x00003c00 },
9352 { -1.0, 0.0, 0.1, 0x00000000, 0x3c000000 }, /* alpha */
9353 { -1.0, 1.0, 0.1, 0x00000000, 0x3c000000 },
9354 { 0.0, 0.0, 0.1, 0x00000000, 0x3c000000 },
9355 { 0.0, 1.0, 0.1, 0x00000000, 0x3c000000 },
9358 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
9359 0, 0, 640, 480, NULL, NULL, NULL, NULL);
9360 d3d = Direct3DCreate9(D3D_SDK_VERSION);
9361 ok(!!d3d, "Failed to create a D3D object.\n");
9362 if (!(device = create_device(d3d, window, window, TRUE)))
9364 skip("Failed to create a D3D device, skipping tests.\n");
9365 goto done;
9368 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9369 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
9370 if (caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
9372 skip("No vs_3_0 support, skipping tests.\n");
9373 IDirect3DDevice9_Release(device);
9374 goto done;
9377 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff102030, 1.0f, 0);
9378 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
9380 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vdecl);
9381 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x\n", hr);
9382 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
9383 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
9384 hr = IDirect3DDevice9_SetVertexShader(device, shader);
9385 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
9387 hr = IDirect3DDevice9_BeginScene(device);
9388 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9389 hr = IDirect3DDevice9_SetVertexDeclaration(device, vdecl);
9390 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
9391 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 0, sizeof(quad[0]));
9392 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9393 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 4, sizeof(quad[0]));
9394 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9395 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 8, sizeof(quad[0]));
9396 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9397 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 12, sizeof(quad[0]));
9398 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9399 hr = IDirect3DDevice9_EndScene(device);
9400 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9402 color = getPixelColor(device, 480, 360);
9403 ok(color == 0x00ff0000,
9404 "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
9405 color = getPixelColor(device, 160, 120);
9406 ok(color == 0x00000000,
9407 "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
9408 color = getPixelColor(device, 160, 360);
9409 ok(color == 0x0000ff00,
9410 "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
9411 color = getPixelColor(device, 480, 120);
9412 ok(color == 0x000000ff,
9413 "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
9414 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9416 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
9417 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
9419 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0,
9420 D3DPOOL_MANAGED, &buffer, NULL);
9421 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexBuffer failed, hr=%08x\n", hr);
9422 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, sizeof(quad), &data, 0);
9423 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed, hr=%08x\n", hr);
9424 memcpy(data, quad, sizeof(quad));
9425 hr = IDirect3DVertexBuffer9_Unlock(buffer);
9426 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed, hr=%08x\n", hr);
9427 hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(quad[0]));
9428 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
9430 hr = IDirect3DDevice9_BeginScene(device);
9431 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9432 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
9433 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9434 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
9435 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9436 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
9437 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9438 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 12, 2);
9439 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9440 hr = IDirect3DDevice9_EndScene(device);
9441 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9443 color = getPixelColor(device, 480, 360);
9444 ok(color == 0x00ff0000,
9445 "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
9446 color = getPixelColor(device, 160, 120);
9447 ok(color == 0x00000000,
9448 "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
9449 color = getPixelColor(device, 160, 360);
9450 ok(color == 0x0000ff00,
9451 "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
9452 color = getPixelColor(device, 480, 120);
9453 ok(color == 0x000000ff,
9454 "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
9455 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9457 IDirect3DVertexDeclaration9_Release(vdecl);
9458 IDirect3DVertexShader9_Release(shader);
9459 IDirect3DVertexBuffer9_Release(buffer);
9460 refcount = IDirect3DDevice9_Release(device);
9461 ok(!refcount, "Device has %u references left.\n", refcount);
9462 done:
9463 IDirect3D9_Release(d3d);
9464 DestroyWindow(window);
9467 static void conditional_np2_repeat_test(void)
9469 IDirect3DTexture9 *texture;
9470 IDirect3DDevice9 *device;
9471 D3DLOCKED_RECT rect;
9472 unsigned int x, y;
9473 DWORD *dst, color;
9474 IDirect3D9 *d3d;
9475 ULONG refcount;
9476 D3DCAPS9 caps;
9477 HWND window;
9478 HRESULT hr;
9480 static const float quad[] =
9482 -1.0f, -1.0f, 0.1f, -0.2f, -0.2f,
9483 -1.0f, 1.0f, 0.1f, -0.2f, 1.2f,
9484 1.0f, -1.0f, 0.1f, 1.2f, -0.2f,
9485 1.0f, 1.0f, 0.1f, 1.2f, 1.2f,
9488 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
9489 0, 0, 640, 480, NULL, NULL, NULL, NULL);
9490 d3d = Direct3DCreate9(D3D_SDK_VERSION);
9491 ok(!!d3d, "Failed to create a D3D object.\n");
9492 if (!(device = create_device(d3d, window, window, TRUE)))
9494 skip("Failed to create a D3D device, skipping tests.\n");
9495 goto done;
9498 memset(&caps, 0, sizeof(caps));
9499 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9500 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
9501 if (caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL)
9503 /* NP2 conditional requires the POW2 flag. Check that while we're at it */
9504 ok(caps.TextureCaps & D3DPTEXTURECAPS_POW2,
9505 "Card has conditional NP2 support without power of two restriction set\n");
9507 else if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
9509 skip("No conditional NP2 support, skipping conditional NP2 tests\n");
9510 IDirect3DDevice9_Release(device);
9511 goto done;
9513 else
9515 skip("Card has unconditional NP2 support, skipping conditional NP2 tests\n");
9516 IDirect3DDevice9_Release(device);
9517 goto done;
9520 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff000000, 1.0f, 0);
9521 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
9523 hr = IDirect3DDevice9_CreateTexture(device, 10, 10, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
9524 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
9526 memset(&rect, 0, sizeof(rect));
9527 hr = IDirect3DTexture9_LockRect(texture, 0, &rect, NULL, 0);
9528 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
9529 for(y = 0; y < 10; y++) {
9530 for(x = 0; x < 10; x++) {
9531 dst = (DWORD *) ((BYTE *) rect.pBits + y * rect.Pitch + x * sizeof(DWORD));
9532 if(x == 0 || x == 9 || y == 0 || y == 9) {
9533 *dst = 0x00ff0000;
9534 } else {
9535 *dst = 0x000000ff;
9539 hr = IDirect3DTexture9_UnlockRect(texture, 0);
9540 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
9542 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
9543 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
9544 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9545 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
9546 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
9547 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
9548 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
9549 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
9550 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9551 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
9553 hr = IDirect3DDevice9_BeginScene(device);
9554 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9555 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
9556 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9557 hr = IDirect3DDevice9_EndScene(device);
9558 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9560 color = getPixelColor(device, 1, 1);
9561 ok(color == 0x00ff0000, "NP2: Pixel 1, 1 has color %08x, expected 0x00ff0000\n", color);
9562 color = getPixelColor(device, 639, 479);
9563 ok(color == 0x00ff0000, "NP2: Pixel 639, 479 has color %08x, expected 0x00ff0000\n", color);
9565 color = getPixelColor(device, 135, 101);
9566 ok(color == 0x00ff0000, "NP2: Pixel 135, 101 has color %08x, expected 0x00ff0000\n", color);
9567 color = getPixelColor(device, 140, 101);
9568 ok(color == 0x00ff0000, "NP2: Pixel 140, 101 has color %08x, expected 0x00ff0000\n", color);
9569 color = getPixelColor(device, 135, 105);
9570 ok(color == 0x00ff0000, "NP2: Pixel 135, 105 has color %08x, expected 0x00ff0000\n", color);
9571 color = getPixelColor(device, 140, 105);
9572 ok(color == 0x000000ff, "NP2: Pixel 140, 105 has color %08x, expected 0x000000ff\n", color);
9574 color = getPixelColor(device, 135, 376);
9575 ok(color == 0x00ff0000, "NP2: Pixel 135, 376 has color %08x, expected 0x00ff0000\n", color);
9576 color = getPixelColor(device, 140, 376);
9577 ok(color == 0x000000ff, "NP2: Pixel 140, 376 has color %08x, expected 0x000000ff\n", color);
9578 color = getPixelColor(device, 135, 379);
9579 ok(color == 0x00ff0000, "NP2: Pixel 135, 379 has color %08x, expected 0x00ff0000\n", color);
9580 color = getPixelColor(device, 140, 379);
9581 ok(color == 0x00ff0000, "NP2: Pixel 140, 379 has color %08x, expected 0x00ff0000\n", color);
9583 color = getPixelColor(device, 500, 101);
9584 ok(color == 0x00ff0000, "NP2: Pixel 500, 101 has color %08x, expected 0x00ff0000\n", color);
9585 color = getPixelColor(device, 504, 101);
9586 ok(color == 0x00ff0000, "NP2: Pixel 504, 101 has color %08x, expected 0x00ff0000\n", color);
9587 color = getPixelColor(device, 500, 105);
9588 ok(color == 0x000000ff, "NP2: Pixel 500, 105 has color %08x, expected 0x000000ff\n", color);
9589 color = getPixelColor(device, 504, 105);
9590 ok(color == 0x00ff0000, "NP2: Pixel 504, 105 has color %08x, expected 0x00ff0000\n", color);
9592 color = getPixelColor(device, 500, 376);
9593 ok(color == 0x000000ff, "NP2: Pixel 500, 376 has color %08x, expected 0x000000ff\n", color);
9594 color = getPixelColor(device, 504, 376);
9595 ok(color == 0x00ff0000, "NP2: Pixel 504, 376 has color %08x, expected 0x00ff0000\n", color);
9596 color = getPixelColor(device, 500, 380);
9597 ok(color == 0x00ff0000, "NP2: Pixel 500, 380 has color %08x, expected 0x00ff0000\n", color);
9598 color = getPixelColor(device, 504, 380);
9599 ok(color == 0x00ff0000, "NP2: Pixel 504, 380 has color %08x, expected 0x00ff0000\n", color);
9601 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9603 IDirect3DTexture9_Release(texture);
9604 refcount = IDirect3DDevice9_Release(device);
9605 ok(!refcount, "Device has %u references left.\n", refcount);
9606 done:
9607 IDirect3D9_Release(d3d);
9608 DestroyWindow(window);
9611 static void vface_register_test(void)
9613 IDirect3DSurface9 *surface, *backbuffer;
9614 IDirect3DVertexShader9 *vshader;
9615 IDirect3DPixelShader9 *shader;
9616 IDirect3DTexture9 *texture;
9617 IDirect3DDevice9 *device;
9618 IDirect3D9 *d3d;
9619 ULONG refcount;
9620 D3DCAPS9 caps;
9621 DWORD color;
9622 HWND window;
9623 HRESULT hr;
9625 static const DWORD shader_code[] =
9627 0xffff0300, /* ps_3_0 */
9628 0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
9629 0x05000051, 0xa00f0001, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.0, 0.0, 0.0, 0.0 */
9630 0x0200001f, 0x80000000, 0x900f1001, /* dcl vFace */
9631 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
9632 0x04000058, 0x800f0000, 0x90e41001, 0xa0e40000, 0x80e40001, /* cmp r0, vFace, c0, r1 */
9633 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
9634 0x0000ffff /* END */
9636 static const DWORD vshader_code[] =
9638 0xfffe0300, /* vs_3_0 */
9639 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
9640 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
9641 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
9642 0x0000ffff /* end */
9644 static const float quad[] =
9646 -1.0f, -1.0f, 0.1f,
9647 1.0f, -1.0f, 0.1f,
9648 -1.0f, 0.0f, 0.1f,
9650 1.0f, -1.0f, 0.1f,
9651 1.0f, 0.0f, 0.1f,
9652 -1.0f, 0.0f, 0.1f,
9654 -1.0f, 0.0f, 0.1f,
9655 -1.0f, 1.0f, 0.1f,
9656 1.0f, 0.0f, 0.1f,
9658 1.0f, 0.0f, 0.1f,
9659 -1.0f, 1.0f, 0.1f,
9660 1.0f, 1.0f, 0.1f,
9662 static const float blit[] =
9664 0.0f, -1.0f, 0.1f, 0.0f, 0.0f,
9665 1.0f, -1.0f, 0.1f, 1.0f, 0.0f,
9666 0.0f, 1.0f, 0.1f, 0.0f, 1.0f,
9667 1.0f, 1.0f, 0.1f, 1.0f, 1.0f,
9670 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
9671 0, 0, 640, 480, NULL, NULL, NULL, NULL);
9672 d3d = Direct3DCreate9(D3D_SDK_VERSION);
9673 ok(!!d3d, "Failed to create a D3D object.\n");
9674 if (!(device = create_device(d3d, window, window, TRUE)))
9676 skip("Failed to create a D3D device, skipping tests.\n");
9677 goto done;
9680 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9681 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
9682 if (caps.PixelShaderVersion < D3DPS_VERSION(3, 0) || caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
9684 skip("No shader model 3 support, skipping tests.\n");
9685 IDirect3DDevice9_Release(device);
9686 goto done;
9689 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
9690 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
9691 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
9692 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
9693 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
9694 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
9695 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
9696 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed hr=%08x\n", hr);
9697 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
9698 ok(SUCCEEDED(hr), "Failed to set cull mode, hr %#x.\n", hr);
9699 hr = IDirect3DDevice9_SetPixelShader(device, shader);
9700 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
9701 hr = IDirect3DDevice9_SetVertexShader(device, vshader);
9702 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
9703 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
9704 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
9705 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9706 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
9708 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
9709 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
9711 hr = IDirect3DDevice9_BeginScene(device);
9712 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9714 /* First, draw to the texture and the back buffer to test both offscreen and onscreen cases */
9715 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
9716 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
9717 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
9718 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
9719 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
9720 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9721 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9722 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
9723 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
9724 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9726 /* Blit the texture onto the back buffer to make it visible */
9727 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
9728 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
9729 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
9730 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
9731 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
9732 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
9733 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9734 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
9735 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9736 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
9737 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9738 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
9739 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, blit, sizeof(float) * 5);
9740 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9742 hr = IDirect3DDevice9_EndScene(device);
9743 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9745 color = getPixelColor(device, 160, 360);
9746 ok(color == 0x00ff0000, "vFace: Onscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
9747 color = getPixelColor(device, 160, 120);
9748 ok(color == 0x0000ff00, "vFace: Onscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
9749 color = getPixelColor(device, 480, 360);
9750 ok(color == 0x0000ff00, "vFace: Offscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
9751 color = getPixelColor(device, 480, 120);
9752 ok(color == 0x00ff0000, "vFace: Offscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
9753 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9754 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
9756 IDirect3DPixelShader9_Release(shader);
9757 IDirect3DVertexShader9_Release(vshader);
9758 IDirect3DSurface9_Release(surface);
9759 IDirect3DSurface9_Release(backbuffer);
9760 IDirect3DTexture9_Release(texture);
9761 refcount = IDirect3DDevice9_Release(device);
9762 ok(!refcount, "Device has %u references left.\n", refcount);
9763 done:
9764 IDirect3D9_Release(d3d);
9765 DestroyWindow(window);
9768 static void fixed_function_bumpmap_test(void)
9770 IDirect3DVertexDeclaration9 *vertex_declaration;
9771 IDirect3DTexture9 *texture, *tex1, *tex2;
9772 D3DLOCKED_RECT locked_rect;
9773 IDirect3DDevice9 *device;
9774 BOOL L6V5U5_supported;
9775 float scale, offset;
9776 IDirect3D9 *d3d;
9777 unsigned int i;
9778 D3DCOLOR color;
9779 ULONG refcount;
9780 D3DCAPS9 caps;
9781 HWND window;
9782 HRESULT hr;
9784 static const float quad[][7] =
9786 {-1.0f, -1.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
9787 {-1.0f, 1.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
9788 { 1.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
9789 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
9791 static const D3DVERTEXELEMENT9 decl_elements[] =
9793 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9794 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
9795 {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
9796 D3DDECL_END()
9798 /* use asymmetric matrix to test loading */
9799 static const float bumpenvmat[4] = {0.0f, 0.5f, -0.5f, 0.0f};
9801 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
9802 0, 0, 640, 480, NULL, NULL, NULL, NULL);
9803 d3d = Direct3DCreate9(D3D_SDK_VERSION);
9804 ok(!!d3d, "Failed to create a D3D object.\n");
9805 if (!(device = create_device(d3d, window, window, TRUE)))
9807 skip("Failed to create a D3D device, skipping tests.\n");
9808 goto done;
9811 memset(&caps, 0, sizeof(caps));
9812 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9813 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
9814 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAP))
9816 skip("D3DTEXOPCAPS_BUMPENVMAP not set, skipping bumpmap tests\n");
9817 IDirect3DDevice9_Release(device);
9818 goto done;
9821 /* This check is disabled, some Windows drivers do not handle
9822 * D3DUSAGE_QUERY_LEGACYBUMPMAP properly. They report that it is not
9823 * supported, but after that bump mapping works properly. So just test if
9824 * the format is generally supported, and check the BUMPENVMAP flag. */
9825 L6V5U5_supported = SUCCEEDED(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
9826 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_L6V5U5));
9827 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
9828 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_V8U8)))
9830 skip("D3DFMT_V8U8 not supported for legacy bump mapping\n");
9831 IDirect3DDevice9_Release(device);
9832 return;
9835 /* Generate the textures */
9836 generate_bumpmap_textures(device);
9838 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
9839 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9840 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
9841 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9842 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
9843 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9844 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
9845 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9847 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAP);
9848 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9849 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
9850 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9851 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_CURRENT );
9852 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9854 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9855 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9856 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9857 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9858 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
9859 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9861 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
9862 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9864 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
9865 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
9867 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff00ff, 1.0f, 0);
9868 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
9870 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
9871 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
9872 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
9873 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
9875 hr = IDirect3DDevice9_BeginScene(device);
9876 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
9878 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
9879 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
9881 hr = IDirect3DDevice9_EndScene(device);
9882 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
9884 color = getPixelColor(device, 240, 60);
9885 ok(color_match(color, 0x005ea000, 4), "Got unexpected color 0x%08x.\n", color);
9886 color = getPixelColor(device, 400, 60);
9887 ok(color_match(color, 0x009ea000, 4), "Got unexpected color 0x%08x.\n", color);
9888 color = getPixelColor(device, 80, 180);
9889 ok(color_match(color, 0x005ea000, 4), "Got unexpected color 0x%08x.\n", color);
9890 color = getPixelColor(device, 560, 180);
9891 ok(color_match(color, 0x009ea000, 4), "Got unexpected color 0x%08x.\n", color);
9892 color = getPixelColor(device, 80, 300);
9893 ok(color_match(color, 0x005e6000, 4), "Got unexpected color 0x%08x.\n", color);
9894 color = getPixelColor(device, 560, 300);
9895 ok(color_match(color, 0x009e6000, 4), "Got unexpected color 0x%08x.\n", color);
9896 color = getPixelColor(device, 240, 420);
9897 ok(color_match(color, 0x005e6000, 4), "Got unexpected color 0x%08x.\n", color);
9898 color = getPixelColor(device, 400, 420);
9899 ok(color_match(color, 0x009e6000, 4), "Got unexpected color 0x%08x.\n", color);
9900 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9901 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
9903 for(i = 0; i < 2; i++) {
9904 hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
9905 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
9906 IDirect3DTexture9_Release(texture); /* For the GetTexture */
9907 hr = IDirect3DDevice9_SetTexture(device, i, NULL);
9908 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
9909 IDirect3DTexture9_Release(texture); /* To destroy it */
9912 if (!L6V5U5_supported || !(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAPLUMINANCE))
9914 skip("L6V5U5 / D3DTOP_BUMPENVMAPLUMINANCE not supported, skipping tests.\n");
9915 IDirect3DVertexDeclaration9_Release(vertex_declaration);
9916 IDirect3DDevice9_Release(device);
9917 goto done;
9920 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9921 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
9922 /* This test only tests the luminance part. The bumpmapping part was already tested above and
9923 * would only make this test more complicated
9925 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_L6V5U5, D3DPOOL_MANAGED, &tex1, NULL);
9926 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
9927 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
9928 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
9930 memset(&locked_rect, 0, sizeof(locked_rect));
9931 hr = IDirect3DTexture9_LockRect(tex1, 0, &locked_rect, NULL, 0);
9932 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9933 *((DWORD *)locked_rect.pBits) = 0x4000; /* L = 0.25, V = 0.0, U = 0.0 */
9934 hr = IDirect3DTexture9_UnlockRect(tex1, 0);
9935 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
9937 memset(&locked_rect, 0, sizeof(locked_rect));
9938 hr = IDirect3DTexture9_LockRect(tex2, 0, &locked_rect, NULL, 0);
9939 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9940 *((DWORD *)locked_rect.pBits) = 0x00ff80c0;
9941 hr = IDirect3DTexture9_UnlockRect(tex2, 0);
9942 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
9944 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
9945 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
9946 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
9947 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
9949 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAPLUMINANCE);
9950 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9951 scale = 2.0;
9952 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
9953 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9954 offset = 0.1;
9955 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
9956 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9958 hr = IDirect3DDevice9_BeginScene(device);
9959 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9960 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
9961 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9962 hr = IDirect3DDevice9_EndScene(device);
9963 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9965 color = getPixelColor(device, 320, 240);
9966 /* red: 1.0 * (0.25 * 2.0 + 0.1) = 1.0 * 0.6 = 0.6 = 0x99
9967 * green: 0.5 * (0.25 * 2.0 + 0.1) = 0.5 * 0.6 = 0.3 = 0x4c
9968 * green: 0.75 * (0.25 * 2.0 + 0.1) = 0.75 * 0.6 = 0.45 = 0x72
9970 ok(color_match(color, 0x00994c72, 5), "bumpmap failed: Got color 0x%08x, expected 0x00994c72.\n", color);
9971 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9972 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
9974 /* Check a result scale factor > 1.0 */
9975 scale = 10;
9976 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
9977 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9978 offset = 10;
9979 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
9980 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9982 hr = IDirect3DDevice9_BeginScene(device);
9983 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9984 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
9985 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9986 hr = IDirect3DDevice9_EndScene(device);
9987 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9989 color = getPixelColor(device, 320, 240);
9990 ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
9991 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9992 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
9994 /* Check clamping in the scale factor calculation */
9995 scale = 1000;
9996 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
9997 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9998 offset = -1;
9999 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
10000 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
10002 hr = IDirect3DDevice9_BeginScene(device);
10003 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
10004 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
10005 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10006 hr = IDirect3DDevice9_EndScene(device);
10007 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
10009 color = getPixelColor(device, 320, 240);
10010 ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
10011 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10012 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
10014 IDirect3DTexture9_Release(tex1);
10015 IDirect3DTexture9_Release(tex2);
10016 IDirect3DVertexDeclaration9_Release(vertex_declaration);
10017 refcount = IDirect3DDevice9_Release(device);
10018 ok(!refcount, "Device has %u references left.\n", refcount);
10019 done:
10020 IDirect3D9_Release(d3d);
10021 DestroyWindow(window);
10024 static void stencil_cull_test(void)
10026 IDirect3DDevice9 *device;
10027 IDirect3D9 *d3d;
10028 ULONG refcount;
10029 D3DCAPS9 caps;
10030 HWND window;
10031 HRESULT hr;
10032 static const float quad1[] =
10034 -1.0, -1.0, 0.1,
10035 0.0, -1.0, 0.1,
10036 -1.0, 0.0, 0.1,
10037 0.0, 0.0, 0.1,
10039 static const float quad2[] =
10041 0.0, -1.0, 0.1,
10042 1.0, -1.0, 0.1,
10043 0.0, 0.0, 0.1,
10044 1.0, 0.0, 0.1,
10046 static const float quad3[] =
10048 0.0, 0.0, 0.1,
10049 1.0, 0.0, 0.1,
10050 0.0, 1.0, 0.1,
10051 1.0, 1.0, 0.1,
10053 static const float quad4[] =
10055 -1.0, 0.0, 0.1,
10056 0.0, 0.0, 0.1,
10057 -1.0, 1.0, 0.1,
10058 0.0, 1.0, 0.1,
10060 struct
10062 struct vec3 position;
10063 DWORD diffuse;
10065 painter[] =
10067 {{-1.0f, -1.0f, 0.0f}, 0x00000000},
10068 {{ 1.0f, -1.0f, 0.0f}, 0x00000000},
10069 {{-1.0f, 1.0f, 0.0f}, 0x00000000},
10070 {{ 1.0f, 1.0f, 0.0f}, 0x00000000},
10072 static const WORD indices_cw[] = {0, 1, 3};
10073 static const WORD indices_ccw[] = {0, 2, 3};
10074 unsigned int i;
10075 DWORD color;
10077 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
10078 0, 0, 640, 480, NULL, NULL, NULL, NULL);
10079 d3d = Direct3DCreate9(D3D_SDK_VERSION);
10080 ok(!!d3d, "Failed to create a D3D object.\n");
10081 if (!(device = create_device(d3d, window, window, TRUE)))
10083 skip("Cannot create a device with a D24S8 stencil buffer.\n");
10084 DestroyWindow(window);
10085 IDirect3D9_Release(d3d);
10086 return;
10088 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10089 ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
10090 if (!(caps.StencilCaps & D3DSTENCILCAPS_TWOSIDED))
10092 skip("No two sided stencil support\n");
10093 goto cleanup;
10096 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_STENCIL, 0x00ff0000, 0.0, 0x8);
10097 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
10098 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10099 ok(SUCCEEDED(hr), "Failed to set FVF,hr %#x.\n", hr);
10101 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
10102 ok(hr == D3D_OK, "Failed to disable Z test, %#x.\n", hr);
10103 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10104 ok(hr == D3D_OK, "Failed to disable lighting, %#x.\n", hr);
10105 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_INCR);
10106 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10107 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_DECR);
10108 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10109 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE);
10110 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10111 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, 0x3);
10112 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10114 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILFAIL, D3DSTENCILOP_REPLACE);
10115 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10116 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILZFAIL, D3DSTENCILOP_DECR);
10117 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10118 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILPASS, D3DSTENCILOP_INCR);
10119 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10121 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, TRUE);
10122 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10123 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
10124 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10126 /* First pass: Fill the stencil buffer with some values... */
10127 hr = IDirect3DDevice9_BeginScene(device);
10128 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
10130 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
10131 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10132 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
10133 1 /* PrimCount */, indices_cw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
10134 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10135 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
10136 1 /* PrimCount */, indices_ccw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
10137 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10139 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, TRUE);
10140 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10141 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
10142 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10143 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
10144 1 /* PrimCount */, indices_cw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
10145 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10146 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
10147 1 /* PrimCount */, indices_ccw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
10148 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10150 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
10151 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10152 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
10153 1 /* PrimCount */, indices_cw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
10154 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10155 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
10156 1 /* PrimCount */, indices_ccw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
10157 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10159 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CCW);
10160 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10161 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
10162 1 /* PrimCount */, indices_cw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
10163 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10164 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
10165 1 /* PrimCount */, indices_ccw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
10166 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10168 hr = IDirect3DDevice9_EndScene(device);
10169 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
10171 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
10172 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10173 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
10174 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10175 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
10176 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10177 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
10178 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10179 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
10180 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10181 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFUNC, D3DCMP_EQUAL);
10182 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10184 /* 2nd pass: Make the stencil values visible */
10185 hr = IDirect3DDevice9_BeginScene(device);
10186 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
10187 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10188 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
10189 for (i = 0; i < 16; ++i)
10191 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, i);
10192 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10194 painter[0].diffuse = (i * 16); /* Creates shades of blue */
10195 painter[1].diffuse = (i * 16);
10196 painter[2].diffuse = (i * 16);
10197 painter[3].diffuse = (i * 16);
10198 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, painter, sizeof(painter[0]));
10199 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10201 hr = IDirect3DDevice9_EndScene(device);
10202 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
10204 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
10205 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10207 color = getPixelColor(device, 160, 420);
10208 ok(color == 0x00000030, "CCW triangle, twoside FALSE, cull cw, replace, has color 0x%08x, expected 0x00000030\n", color);
10209 color = getPixelColor(device, 160, 300);
10210 ok(color == 0x00000080, "CW triangle, twoside FALSE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
10212 color = getPixelColor(device, 480, 420);
10213 ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull off, incr, has color 0x%08x, expected 0x00000090\n", color);
10214 color = getPixelColor(device, 480, 300);
10215 ok(color == 0x00000030, "CW triangle, twoside TRUE, cull off, replace, has color 0x%08x, expected 0x00000030\n", color);
10217 color = getPixelColor(device, 160, 180);
10218 ok(color == 0x00000080, "CCW triangle, twoside TRUE, cull ccw, culled, has color 0x%08x, expected 0x00000080\n", color);
10219 color = getPixelColor(device, 160, 60);
10220 ok(color == 0x00000030, "CW triangle, twoside TRUE, cull ccw, replace, has color 0x%08x, expected 0x00000030\n", color);
10222 color = getPixelColor(device, 480, 180);
10223 ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull cw, incr, has color 0x%08x, expected 0x00000090\n", color);
10224 color = getPixelColor(device, 480, 60);
10225 ok(color == 0x00000080, "CW triangle, twoside TRUE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
10227 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10228 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10230 cleanup:
10231 refcount = IDirect3DDevice9_Release(device);
10232 ok(!refcount, "Device has %u references left.\n", refcount);
10233 IDirect3D9_Release(d3d);
10234 DestroyWindow(window);
10237 static void test_fragment_coords(void)
10239 IDirect3DSurface9 *surface = NULL, *backbuffer;
10240 IDirect3DPixelShader9 *shader, *shader_frac;
10241 IDirect3DVertexShader9 *vshader;
10242 IDirect3DDevice9 *device;
10243 D3DLOCKED_RECT lr;
10244 IDirect3D9 *d3d;
10245 ULONG refcount;
10246 D3DCAPS9 caps;
10247 DWORD color;
10248 HWND window;
10249 HRESULT hr;
10250 DWORD *pos;
10252 static const DWORD shader_code[] =
10254 0xffff0300, /* ps_3_0 */
10255 0x0200001f, 0x80000000, 0x90031000, /* dcl vPos.xy */
10256 0x03000002, 0x80030000, 0x90541000, 0xa1fe0000, /* sub r0.xy, vPos.xy, c0.zw */
10257 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */
10258 0x02000001, 0x80080002, 0xa0550000, /* mov r2.a, c0.y */
10259 0x02000001, 0x80010002, 0xa0550000, /* mov r2.r, c0.y */
10260 0x04000058, 0x80020002, 0x80000000, 0x80000001, 0x80550001, /* cmp r2.g, r0.x, r1.x, r1.y */
10261 0x04000058, 0x80040002, 0x80550000, 0x80000001, 0x80550001, /* cmp r2.b, r0.y, r1.x, r1.y */
10262 0x02000001, 0x800f0800, 0x80e40002, /* mov oC0, r2 */
10263 0x0000ffff /* end */
10265 static const DWORD shader_frac_code[] =
10267 0xffff0300, /* ps_3_0 */
10268 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
10269 0x0200001f, 0x80000000, 0x90031000, /* dcl vPos.xy */
10270 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
10271 0x02000013, 0x80030000, 0x90541000, /* frc r0.xy, vPos.xy */
10272 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
10273 0x0000ffff /* end */
10275 static const DWORD vshader_code[] =
10277 0xfffe0300, /* vs_3_0 */
10278 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
10279 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
10280 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
10281 0x0000ffff /* end */
10283 static const float quad[] =
10285 -1.0f, -1.0f, 0.1f, 0.0f, 0.0f,
10286 -1.0f, 1.0f, 0.1f, 0.0f, 1.0f,
10287 1.0f, -1.0f, 0.1f, 1.0f, 0.0f,
10288 1.0f, 1.0f, 0.1f, 1.0f, 1.0f,
10290 float constant[4] = {1.0, 0.0, 320, 240};
10292 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
10293 0, 0, 640, 480, NULL, NULL, NULL, NULL);
10294 d3d = Direct3DCreate9(D3D_SDK_VERSION);
10295 ok(!!d3d, "Failed to create a D3D object.\n");
10296 if (!(device = create_device(d3d, window, window, TRUE)))
10298 skip("Failed to create a D3D device, skipping tests.\n");
10299 goto done;
10302 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10303 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
10304 if (caps.PixelShaderVersion < D3DPS_VERSION(3, 0) || caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
10306 skip("No shader model 3 support, skipping tests.\n");
10307 IDirect3DDevice9_Release(device);
10308 goto done;
10311 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
10312 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
10313 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
10314 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
10315 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
10316 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
10317 hr = IDirect3DDevice9_CreatePixelShader(device, shader_frac_code, &shader_frac);
10318 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
10319 hr = IDirect3DDevice9_SetPixelShader(device, shader);
10320 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
10321 hr = IDirect3DDevice9_SetVertexShader(device, vshader);
10322 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
10323 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10324 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
10325 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
10326 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
10328 hr = IDirect3DDevice9_BeginScene(device);
10329 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
10330 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
10331 ok(SUCCEEDED(hr), "Failed to set pixel shader constant, hr %#x.\n", hr);
10332 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
10333 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10334 hr = IDirect3DDevice9_EndScene(device);
10335 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
10337 /* This has to be pixel exact */
10338 color = getPixelColor(device, 319, 239);
10339 ok(color == 0x00000000, "vPos: Pixel 319,239 has color 0x%08x, expected 0x00000000\n", color);
10340 color = getPixelColor(device, 320, 239);
10341 ok(color == 0x0000ff00, "vPos: Pixel 320,239 has color 0x%08x, expected 0x0000ff00\n", color);
10342 color = getPixelColor(device, 319, 240);
10343 ok(color == 0x000000ff, "vPos: Pixel 319,240 has color 0x%08x, expected 0x000000ff\n", color);
10344 color = getPixelColor(device, 320, 240);
10345 ok(color == 0x0000ffff, "vPos: Pixel 320,240 has color 0x%08x, expected 0x0000ffff\n", color);
10346 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10348 hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_X8R8G8B8, 0, 0, TRUE,
10349 &surface, NULL);
10350 ok(hr == D3D_OK, "IDirect3DDevice9_CreateRenderTarget failed hr=%08x\n", hr);
10351 hr = IDirect3DDevice9_BeginScene(device);
10352 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
10353 constant[2] = 16; constant[3] = 16;
10354 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
10355 ok(SUCCEEDED(hr), "Failed to set pixel shader constant, hr %#x.\n", hr);
10356 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
10357 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
10358 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
10359 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10360 hr = IDirect3DDevice9_EndScene(device);
10361 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
10363 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
10364 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
10366 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
10367 color = *pos & 0x00ffffff;
10368 ok(color == 0x00000000, "Pixel 14/14 has color 0x%08x, expected 0x00000000\n", color);
10369 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 18 * sizeof(DWORD));
10370 color = *pos & 0x00ffffff;
10371 ok(color == 0x0000ff00, "Pixel 14/18 has color 0x%08x, expected 0x0000ff00\n", color);
10372 pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 14 * sizeof(DWORD));
10373 color = *pos & 0x00ffffff;
10374 ok(color == 0x000000ff, "Pixel 18/14 has color 0x%08x, expected 0x000000ff\n", color);
10375 pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 18 * sizeof(DWORD));
10376 color = *pos & 0x00ffffff;
10377 ok(color == 0x0000ffff, "Pixel 18/18 has color 0x%08x, expected 0x0000ffff\n", color);
10379 hr = IDirect3DSurface9_UnlockRect(surface);
10380 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
10382 /* Test the fraction value of vPos. This is tested with the offscreen target and not the backbuffer to
10383 * have full control over the multisampling setting inside this test
10385 hr = IDirect3DDevice9_SetPixelShader(device, shader_frac);
10386 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
10387 hr = IDirect3DDevice9_BeginScene(device);
10388 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
10389 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
10390 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
10391 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
10392 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10393 hr = IDirect3DDevice9_EndScene(device);
10394 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
10396 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
10397 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
10399 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
10400 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
10402 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
10403 color = *pos & 0x00ffffff;
10404 ok(color == 0x00000000, "vPos fraction test has color 0x%08x, expected 0x00000000\n", color);
10406 hr = IDirect3DSurface9_UnlockRect(surface);
10407 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
10409 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
10410 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
10411 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
10412 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
10413 IDirect3DPixelShader9_Release(shader);
10414 IDirect3DPixelShader9_Release(shader_frac);
10415 IDirect3DVertexShader9_Release(vshader);
10416 if(surface) IDirect3DSurface9_Release(surface);
10417 IDirect3DSurface9_Release(backbuffer);
10418 refcount = IDirect3DDevice9_Release(device);
10419 ok(!refcount, "Device has %u references left.\n", refcount);
10420 done:
10421 IDirect3D9_Release(d3d);
10422 DestroyWindow(window);
10425 static BOOL point_match(IDirect3DDevice9 *device, UINT x, UINT y, UINT r)
10427 D3DCOLOR color;
10429 color = D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff);
10430 if (!color_match(getPixelColor(device, x + r, y), color, 1)) return FALSE;
10431 if (!color_match(getPixelColor(device, x - r, y), color, 1)) return FALSE;
10432 if (!color_match(getPixelColor(device, x, y + r), color, 1)) return FALSE;
10433 if (!color_match(getPixelColor(device, x, y - r), color, 1)) return FALSE;
10435 ++r;
10436 color = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff);
10437 if (!color_match(getPixelColor(device, x + r, y), color, 1)) return FALSE;
10438 if (!color_match(getPixelColor(device, x - r, y), color, 1)) return FALSE;
10439 if (!color_match(getPixelColor(device, x, y + r), color, 1)) return FALSE;
10440 if (!color_match(getPixelColor(device, x, y - r), color, 1)) return FALSE;
10442 return TRUE;
10445 static void test_pointsize(void)
10447 static const float a = 1.0f, b = 1.0f, c = 1.0f;
10448 float ptsize, ptsizemax_orig, ptsizemin_orig;
10449 IDirect3DSurface9 *rt, *backbuffer;
10450 IDirect3DTexture9 *tex1, *tex2;
10451 IDirect3DDevice9 *device;
10452 IDirect3DVertexShader9 *vs;
10453 IDirect3DPixelShader9 *ps;
10454 D3DLOCKED_RECT lr;
10455 IDirect3D9 *d3d;
10456 D3DCOLOR color;
10457 ULONG refcount;
10458 D3DCAPS9 caps;
10459 HWND window;
10460 HRESULT hr;
10461 unsigned int i, j;
10463 static const RECT rect = {0, 0, 128, 128};
10464 static const DWORD tex1_data[4] = {0x00ff0000, 0x00ff0000, 0x00000000, 0x00000000};
10465 static const DWORD tex2_data[4] = {0x00000000, 0x0000ff00, 0x00000000, 0x0000ff00};
10466 static const float vertices[] =
10468 64.0f, 64.0f, 0.1f,
10469 128.0f, 64.0f, 0.1f,
10470 192.0f, 64.0f, 0.1f,
10471 256.0f, 64.0f, 0.1f,
10472 320.0f, 64.0f, 0.1f,
10473 384.0f, 64.0f, 0.1f,
10474 448.0f, 64.0f, 0.1f,
10475 512.0f, 64.0f, 0.1f,
10477 static const struct
10479 float x, y, z;
10480 float point_size;
10482 vertex_pointsize = {64.0f, 64.0f, 0.1f, 48.0f},
10483 vertex_pointsize_scaled = {64.0f, 64.0f, 0.1f, 24.0f},
10484 vertex_pointsize_zero = {64.0f, 64.0f, 0.1f, 0.0f};
10485 static const DWORD vshader_code[] =
10487 0xfffe0101, /* vs_1_1 */
10488 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
10489 0x00000005, 0x800f0000, 0x90000000, 0xa0e40000, /* mul r0, v0.x, c0 */
10490 0x00000004, 0x800f0000, 0x90550000, 0xa0e40001, 0x80e40000, /* mad r0, v0.y, c1, r0 */
10491 0x00000004, 0x800f0000, 0x90aa0000, 0xa0e40002, 0x80e40000, /* mad r0, v0.z, c2, r0 */
10492 0x00000004, 0xc00f0000, 0x90ff0000, 0xa0e40003, 0x80e40000, /* mad oPos, v0.w, c3, r0 */
10493 0x0000ffff
10495 static const DWORD vshader_psize_code[] =
10497 0xfffe0101, /* vs_1_1 */
10498 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
10499 0x0000001f, 0x80000004, 0x900f0001, /* dcl_psize v1 */
10500 0x00000005, 0x800f0000, 0x90000000, 0xa0e40000, /* mul r0, v0.x, c0 */
10501 0x00000004, 0x800f0000, 0x90550000, 0xa0e40001, 0x80e40000, /* mad r0, v0.y, c1, r0 */
10502 0x00000004, 0x800f0000, 0x90aa0000, 0xa0e40002, 0x80e40000, /* mad r0, v0.z, c2, r0 */
10503 0x00000004, 0xc00f0000, 0x90ff0000, 0xa0e40003, 0x80e40000, /* mad oPos, v0.w, c3, r0 */
10504 0x00000001, 0xc00f0002, 0x90000001, /* mov oPts, v1.x */
10505 0x0000ffff
10507 static const DWORD pshader_code[] =
10509 0xffff0101, /* ps_1_1 */
10510 0x00000042, 0xb00f0000, /* tex t0 */
10511 0x00000042, 0xb00f0001, /* tex t1 */
10512 0x00000002, 0x800f0000, 0xb0e40000, 0xb0e40001, /* add r0, t0, t1 */
10513 0x0000ffff
10515 static const DWORD pshader2_code[] =
10517 0xffff0200, /* ps_2_0 */
10518 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
10519 0x0200001f, 0x80000000, 0xb00f0001, /* dcl t1 */
10520 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
10521 0x0200001f, 0x90000000, 0xa00f0801, /* dcl_2d s1 */
10522 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
10523 0x03000042, 0x800f0001, 0xb0e40001, 0xa0e40801, /* texld r1, t1, s1 */
10524 0x03000002, 0x800f0000, 0x80e40000, 0x80e40001, /* add r0, r0, r1 */
10525 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
10526 0x0000ffff
10528 static const DWORD pshader2_zw_code[] =
10530 0xffff0200, /* ps_2_0 */
10531 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
10532 0x0200001f, 0x80000000, 0xb00f0001, /* dcl t1 */
10533 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
10534 0x0200001f, 0x90000000, 0xa00f0801, /* dcl_2d s1 */
10535 0x02000001, 0x80030000, 0xb01b0000, /* mov r0.xy, t0.wzyx */
10536 0x02000001, 0x80030001, 0xb01b0001, /* mov r1.xy, t1.wzyx */
10537 0x03000042, 0x800f0000, 0x80e40000, 0xa0e40800, /* texld r0, r0, s0 */
10538 0x03000042, 0x800f0001, 0x80e40001, 0xa0e40801, /* texld r1, r1, s1 */
10539 0x03000002, 0x800f0000, 0x80e40000, 0x80e40001, /* add r0, r0, r1 */
10540 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
10541 0x0000ffff
10543 static const DWORD vshader3_code[] =
10545 0xfffe0300, /* vs_3_0 */
10546 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
10547 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
10548 0x03000005, 0x800f0000, 0x90000000, 0xa0e40000, /* mul r0, v0.x, c0 */
10549 0x04000004, 0x800f0000, 0x90550000, 0xa0e40001, 0x80e40000, /* mad r0, v0.y, c1, r0 */
10550 0x04000004, 0x800f0000, 0x90aa0000, 0xa0e40002, 0x80e40000, /* mad r0, v0.z, c2, r0 */
10551 0x04000004, 0xe00f0000, 0x90ff0000, 0xa0e40003, 0x80e40000, /* mad o0, v0.w, c3, r0 */
10552 0x0000ffff
10554 static const DWORD vshader3_psize_code[] =
10556 0xfffe0300, /* vs_3_0 */
10557 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
10558 0x0200001f, 0x80000004, 0x90010001, /* dcl_psize v1.x */
10559 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
10560 0x0200001f, 0x80000004, 0xe00f0001, /* dcl_psize o1 */
10561 0x03000005, 0x800f0000, 0x90000000, 0xa0e40000, /* mul r0, v0.x, c0 */
10562 0x04000004, 0x800f0000, 0x90550000, 0xa0e40001, 0x80e40000, /* mad r0, v0.y, c1, r0 */
10563 0x04000004, 0x800f0000, 0x90aa0000, 0xa0e40002, 0x80e40000, /* mad r0, v0.z, c2, r0 */
10564 0x04000004, 0xe00f0000, 0x90ff0000, 0xa0e40003, 0x80e40000, /* mad o0, v0.w, c3, r0 */
10565 0x02000001, 0xe00f0001, 0x90000001, /* mov o1, v1.x */
10566 0x0000ffff
10568 static const DWORD pshader3_code[] =
10570 0xffff0300, /* ps_3_0 */
10571 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord0 v0 */
10572 0x0200001f, 0x80010005, 0x900f0001, /* dcl_texcoord1 v1 */
10573 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
10574 0x0200001f, 0x90000000, 0xa00f0801, /* dcl_2d s1 */
10575 0x03000042, 0x800f0000, 0x90e40000, 0xa0e40800, /* texld r0, v0, s0 */
10576 0x03000042, 0x800f0001, 0x90e40001, 0xa0e40801, /* texld r1, v1, s1 */
10577 0x03000002, 0x800f0800, 0x80e40000, 0x80e40001, /* add oC0, r0, r1 */
10578 0x0000ffff
10580 static const DWORD pshader3_zw_code[] =
10582 0xffff0300, /* ps_3_0 */
10583 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord0 v0 */
10584 0x0200001f, 0x80010005, 0x900f0001, /* dcl_texcoord1 v1 */
10585 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
10586 0x0200001f, 0x90000000, 0xa00f0801, /* dcl_2d s1 */
10587 0x03000042, 0x800f0000, 0x90fe0000, 0xa0e40800, /* texld r0, v0.zw, s0 */
10588 0x03000042, 0x800f0001, 0x90fe0001, 0xa0e40801, /* texld r1, v1.zw, s1 */
10589 0x03000002, 0x800f0800, 0x80e40000, 0x80e40001, /* add oC0, r0, r1 */
10590 0x0000ffff
10592 static const struct test_shader
10594 DWORD version;
10595 const DWORD *code;
10597 novs = {0, NULL},
10598 vs1 = {D3DVS_VERSION(1, 1), vshader_code},
10599 vs1_psize = {D3DVS_VERSION(1, 1), vshader_psize_code},
10600 vs3 = {D3DVS_VERSION(3, 0), vshader3_code},
10601 vs3_psize = {D3DVS_VERSION(3, 0), vshader3_psize_code},
10602 nops = {0, NULL},
10603 ps1 = {D3DPS_VERSION(1, 1), pshader_code},
10604 ps2 = {D3DPS_VERSION(2, 0), pshader2_code},
10605 ps2_zw = {D3DPS_VERSION(2, 0), pshader2_zw_code},
10606 ps3 = {D3DPS_VERSION(3, 0), pshader3_code},
10607 ps3_zw = {D3DVS_VERSION(3, 0), pshader3_zw_code};
10608 static const struct
10610 const struct test_shader *vs;
10611 const struct test_shader *ps;
10612 DWORD accepted_fvf;
10613 unsigned int nonscaled_size, scaled_size;
10614 BOOL gives_0_0_texcoord;
10615 BOOL allow_broken;
10617 test_setups[] =
10619 {&novs, &nops, D3DFVF_XYZ, 32, 45, FALSE, FALSE},
10620 {&vs1, &ps1, D3DFVF_XYZ, 32, 32, FALSE, FALSE},
10621 {&novs, &ps1, D3DFVF_XYZ, 32, 45, FALSE, FALSE},
10622 {&vs1, &nops, D3DFVF_XYZ, 32, 32, FALSE, FALSE},
10623 {&novs, &ps2, D3DFVF_XYZ, 32, 45, FALSE, TRUE},
10624 {&novs, &ps2_zw, D3DFVF_XYZ, 32, 45, TRUE, FALSE},
10625 {&vs1, &ps2, D3DFVF_XYZ, 32, 32, FALSE, TRUE},
10626 {&vs1, &ps2_zw, D3DFVF_XYZ, 32, 32, TRUE, FALSE},
10627 {&vs3, &ps3, D3DFVF_XYZ, 32, 32, FALSE, TRUE},
10628 {&vs3, &ps3_zw, D3DFVF_XYZ, 32, 32, TRUE, FALSE},
10629 {&novs, &nops, D3DFVF_XYZ | D3DFVF_PSIZE, 48, 33, FALSE, FALSE},
10630 {&vs1_psize, &ps1, D3DFVF_XYZ | D3DFVF_PSIZE, 48, 24, FALSE, FALSE},
10631 {&vs3_psize, &ps3, D3DFVF_XYZ | D3DFVF_PSIZE, 48, 24, FALSE, TRUE},
10633 static const struct
10635 BOOL zero_size;
10636 BOOL scale;
10637 BOOL override_min;
10638 DWORD fvf;
10639 const void *vertex_data;
10640 unsigned int vertex_size;
10642 tests[] =
10644 {FALSE, FALSE, FALSE, D3DFVF_XYZ, vertices, sizeof(float) * 3},
10645 {FALSE, TRUE, FALSE, D3DFVF_XYZ, vertices, sizeof(float) * 3},
10646 {FALSE, FALSE, TRUE, D3DFVF_XYZ, vertices, sizeof(float) * 3},
10647 {TRUE, FALSE, FALSE, D3DFVF_XYZ, vertices, sizeof(float) * 3},
10648 {FALSE, FALSE, FALSE, D3DFVF_XYZ | D3DFVF_PSIZE, &vertex_pointsize, sizeof(vertex_pointsize)},
10649 {FALSE, TRUE, FALSE, D3DFVF_XYZ | D3DFVF_PSIZE, &vertex_pointsize_scaled, sizeof(vertex_pointsize_scaled)},
10650 {FALSE, FALSE, TRUE, D3DFVF_XYZ | D3DFVF_PSIZE, &vertex_pointsize, sizeof(vertex_pointsize)},
10651 {TRUE, FALSE, FALSE, D3DFVF_XYZ | D3DFVF_PSIZE, &vertex_pointsize_zero, sizeof(vertex_pointsize_zero)},
10653 /* Transforms the coordinate system [-1.0;1.0]x[1.0;-1.0] to
10654 * [0.0;0.0]x[640.0;480.0]. Z is untouched. */
10655 D3DMATRIX matrix =
10657 2.0f / 640.0f, 0.0f, 0.0f, 0.0f,
10658 0.0f, -2.0f / 480.0f, 0.0f, 0.0f,
10659 0.0f, 0.0f, 1.0f, 0.0f,
10660 -1.0f, 1.0f, 0.0f, 1.0f,
10661 }}};
10663 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
10664 0, 0, 640, 480, NULL, NULL, NULL, NULL);
10665 d3d = Direct3DCreate9(D3D_SDK_VERSION);
10666 ok(!!d3d, "Failed to create a D3D object.\n");
10667 if (!(device = create_device(d3d, window, window, TRUE)))
10669 skip("Failed to create a D3D device, skipping tests.\n");
10670 goto done;
10673 memset(&caps, 0, sizeof(caps));
10674 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10675 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
10676 if(caps.MaxPointSize < 32.0) {
10677 skip("MaxPointSize < 32.0, skipping(MaxPointsize = %f)\n", caps.MaxPointSize);
10678 IDirect3DDevice9_Release(device);
10679 goto done;
10682 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
10683 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
10684 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10685 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
10686 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
10687 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
10688 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10689 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
10691 hr = IDirect3DDevice9_BeginScene(device);
10692 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
10694 ptsize = 15.0f;
10695 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
10696 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10697 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
10698 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10700 ptsize = 31.0f;
10701 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
10702 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10703 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[3], sizeof(float) * 3);
10704 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10706 ptsize = 30.75f;
10707 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
10708 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10709 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[6], sizeof(float) * 3);
10710 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10712 if (caps.MaxPointSize >= 63.0f)
10714 ptsize = 63.0f;
10715 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
10716 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10717 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[9], sizeof(float) * 3);
10718 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10720 ptsize = 62.75f;
10721 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
10722 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10723 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[15], sizeof(float) * 3);
10724 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10727 ptsize = 1.0f;
10728 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
10729 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10730 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[12], sizeof(float) * 3);
10731 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10733 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MAX, (DWORD *)&ptsizemax_orig);
10734 ok(SUCCEEDED(hr), "Failed to get render state, hr %#x.\n", hr);
10735 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MIN, (DWORD *)&ptsizemin_orig);
10736 ok(SUCCEEDED(hr), "Failed to get render state, hr %#x.\n", hr);
10738 /* What happens if point scaling is disabled, and POINTSIZE_MAX < POINTSIZE? */
10739 ptsize = 15.0f;
10740 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
10741 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10742 ptsize = 1.0f;
10743 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *(DWORD *)&ptsize);
10744 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10745 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[18], sizeof(float) * 3);
10746 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10748 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *(DWORD *)&ptsizemax_orig);
10749 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10751 /* pointsize < pointsize_min < pointsize_max?
10752 * pointsize = 1.0, pointsize_min = 15.0, pointsize_max = default(usually 64.0) */
10753 ptsize = 1.0f;
10754 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
10755 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10756 ptsize = 15.0f;
10757 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *(DWORD *)&ptsize);
10758 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10759 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[21], sizeof(float) * 3);
10760 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10762 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *(DWORD *)&ptsizemin_orig);
10763 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10765 hr = IDirect3DDevice9_EndScene(device);
10766 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
10768 ok(point_match(device, 64, 64, 7), "point_match(64, 64, 7) failed, expected point size 15.\n");
10769 ok(point_match(device, 128, 64, 15), "point_match(128, 64, 15) failed, expected point size 31.\n");
10770 ok(point_match(device, 192, 64, 15), "point_match(192, 64, 15) failed, expected point size 31.\n");
10772 if (caps.MaxPointSize >= 63.0)
10774 ok(point_match(device, 256, 64, 31), "point_match(256, 64, 31) failed, expected point size 63.\n");
10775 ok(point_match(device, 384, 64, 31), "point_match(384, 64, 31) failed, expected point size 63.\n");
10778 ok(point_match(device, 320, 64, 0), "point_match(320, 64, 0) failed, expected point size 1.\n");
10779 /* ptsize = 15, ptsize_max = 1 --> point has size 1 */
10780 ok(point_match(device, 448, 64, 0), "point_match(448, 64, 0) failed, expected point size 1.\n");
10781 /* ptsize = 1, ptsize_max = default(64), ptsize_min = 15 --> point has size 15 */
10782 ok(point_match(device, 512, 64, 7), "point_match(512, 64, 7) failed, expected point size 15.\n");
10784 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10786 /* The following code tests point sprites with two textures, to see if each texture coordinate unit
10787 * generates texture coordinates for the point(result: Yes, it does)
10789 * However, not all GL implementations support point sprites(they need GL_ARB_point_sprite), but there
10790 * is no point sprite cap bit in d3d because native d3d software emulates point sprites. Until the
10791 * SW emulation is implemented in wined3d, this test will fail on GL drivers that does not support them.
10793 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
10794 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
10796 hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex1, NULL);
10797 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
10798 hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
10799 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
10800 memset(&lr, 0, sizeof(lr));
10801 hr = IDirect3DTexture9_LockRect(tex1, 0, &lr, NULL, 0);
10802 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
10803 memcpy(lr.pBits, tex1_data, sizeof(tex1_data));
10804 hr = IDirect3DTexture9_UnlockRect(tex1, 0);
10805 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
10806 memset(&lr, 0, sizeof(lr));
10807 hr = IDirect3DTexture9_LockRect(tex2, 0, &lr, NULL, 0);
10808 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
10809 memcpy(lr.pBits, tex2_data, sizeof(tex2_data));
10810 hr = IDirect3DTexture9_UnlockRect(tex2, 0);
10811 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
10812 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
10813 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
10814 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
10815 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
10816 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
10817 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
10818 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
10819 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
10820 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
10821 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
10822 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
10823 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
10824 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
10825 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
10827 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSPRITEENABLE, TRUE);
10828 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
10829 ptsize = 32.0;
10830 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
10831 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
10833 hr = IDirect3DDevice9_BeginScene(device);
10834 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
10835 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
10836 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10837 hr = IDirect3DDevice9_EndScene(device);
10838 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
10840 color = getPixelColor(device, 64-4, 64-4);
10841 ok(color == 0x00ff0000, "pSprite: Pixel (64-4),(64-4) has color 0x%08x, expected 0x00ff0000\n", color);
10842 color = getPixelColor(device, 64-4, 64+4);
10843 ok(color == 0x00000000, "pSprite: Pixel (64-4),(64+4) has color 0x%08x, expected 0x00000000\n", color);
10844 color = getPixelColor(device, 64+4, 64+4);
10845 ok(color == 0x0000ff00, "pSprite: Pixel (64+4),(64+4) has color 0x%08x, expected 0x0000ff00\n", color);
10846 color = getPixelColor(device, 64+4, 64-4);
10847 ok(color == 0x00ffff00, "pSprite: Pixel (64+4),(64-4) has color 0x%08x, expected 0x00ffff00\n", color);
10848 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10850 U(matrix).m[0][0] = 1.0f / 64.0f;
10851 U(matrix).m[1][1] = -1.0f / 64.0f;
10852 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
10853 ok(SUCCEEDED(hr), "SetTransform failed, hr %#x.\n", hr);
10855 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
10856 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
10858 hr = IDirect3DDevice9_CreateRenderTarget(device, 128, 128, D3DFMT_A8R8G8B8,
10859 D3DMULTISAMPLE_NONE, 0, TRUE, &rt, NULL );
10860 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
10862 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSCALE_A, *(DWORD *)&a);
10863 ok(SUCCEEDED(hr), "Failed setting point scale attenuation coefficient, hr %#x.\n", hr);
10864 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSCALE_B, *(DWORD *)&b);
10865 ok(SUCCEEDED(hr), "Failed setting point scale attenuation coefficient, hr %#x.\n", hr);
10866 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSCALE_C, *(DWORD *)&c);
10867 ok(SUCCEEDED(hr), "Failed setting point scale attenuation coefficient, hr %#x.\n", hr);
10868 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
10870 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, &S(U(matrix))._11, 4);
10871 ok(SUCCEEDED(hr), "Failed to set vertex shader constants, hr %#x.\n", hr);
10874 if (caps.MaxPointSize < 63.0f)
10876 skip("MaxPointSize %f < 63.0, skipping some tests.\n", caps.MaxPointSize);
10877 goto cleanup;
10880 for (i = 0; i < sizeof(test_setups) / sizeof(test_setups[0]); ++i)
10882 if (caps.VertexShaderVersion < test_setups[i].vs->version
10883 || caps.PixelShaderVersion < test_setups[i].ps->version)
10885 skip("Vertex / pixel shader version not supported, skipping test.\n");
10886 continue;
10888 if (test_setups[i].vs->code)
10890 hr = IDirect3DDevice9_CreateVertexShader(device, test_setups[i].vs->code, &vs);
10891 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x (case %u).\n", hr, i);
10893 else
10895 vs = NULL;
10897 if (test_setups[i].ps->code)
10899 hr = IDirect3DDevice9_CreatePixelShader(device, test_setups[i].ps->code, &ps);
10900 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x (case %u).\n", hr, i);
10902 else
10904 ps = NULL;
10907 hr = IDirect3DDevice9_SetVertexShader(device, vs);
10908 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
10909 hr = IDirect3DDevice9_SetPixelShader(device, ps);
10910 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
10912 for (j = 0; j < sizeof(tests) / sizeof(tests[0]); ++j)
10914 BOOL allow_broken = test_setups[i].allow_broken;
10915 unsigned int size = tests[j].override_min ? 63 : tests[j].zero_size ? 0 : tests[j].scale
10916 ? test_setups[i].scaled_size : test_setups[i].nonscaled_size;
10918 if (test_setups[i].accepted_fvf != tests[j].fvf)
10919 continue;
10921 ptsize = tests[j].zero_size ? 0.0f : 32.0f;
10922 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
10923 ok(SUCCEEDED(hr), "Failed to set pointsize, hr %#x.\n", hr);
10925 ptsize = tests[j].override_min ? 63.0f : tests[j].zero_size ? 0.0f : ptsizemin_orig;
10926 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *(DWORD *)&ptsize);
10927 ok(SUCCEEDED(hr), "Failed to set minimum pointsize, hr %#x.\n", hr);
10929 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSCALEENABLE, tests[j].scale);
10930 ok(SUCCEEDED(hr), "Failed setting point scale state, hr %#x.\n", hr);
10932 hr = IDirect3DDevice9_SetFVF(device, tests[j].fvf);
10933 ok(SUCCEEDED(hr), "Failed setting FVF, hr %#x.\n", hr);
10935 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
10936 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
10937 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
10938 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
10940 hr = IDirect3DDevice9_BeginScene(device);
10941 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
10942 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1,
10943 tests[j].vertex_data, tests[j].vertex_size);
10944 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10945 hr = IDirect3DDevice9_EndScene(device);
10946 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
10948 hr = IDirect3DDevice9_StretchRect(device, rt, &rect, backbuffer, &rect, D3DTEXF_NONE);
10949 ok(SUCCEEDED(hr), "Failed to blit, hr %#x.\n", hr);
10950 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
10951 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
10953 if (tests[j].zero_size)
10955 /* Technically 0 pointsize is undefined in OpenGL but in practice it seems like
10956 * it does the "useful" thing on all the drivers I tried. */
10957 /* On WARP it does draw some pixels, most of the time. */
10958 color = getPixelColor(device, 64, 64);
10959 ok(color_match(color, 0x0000ffff, 0)
10960 || broken(color_match(color, 0x00ff0000, 0))
10961 || broken(color_match(color, 0x00ffff00, 0))
10962 || broken(color_match(color, 0x00000000, 0))
10963 || broken(color_match(color, 0x0000ff00, 0)),
10964 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
10966 else
10968 struct surface_readback rb;
10970 get_rt_readback(backbuffer, &rb);
10971 /* On AMD apparently only the first texcoord is modified by the point coordinates
10972 * when using SM2/3 pixel shaders. */
10973 color = get_readback_color(&rb, 64 - size / 2 + 1, 64 - size / 2 + 1);
10974 ok(color_match(color, 0x00ff0000, 0),
10975 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
10976 color = get_readback_color(&rb, 64 + size / 2 - 1, 64 - size / 2 + 1);
10977 ok(color_match(color, test_setups[i].gives_0_0_texcoord ? 0x00ff0000 : 0x00ffff00, 0)
10978 || (allow_broken && broken(color_match(color, 0x00ff0000, 0))),
10979 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
10980 color = get_readback_color(&rb, 64 - size / 2 + 1, 64 + size / 2 - 1);
10981 ok(color_match(color, test_setups[i].gives_0_0_texcoord ? 0x00ff0000 : 0x00000000, 0),
10982 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
10983 color = get_readback_color(&rb, 64 + size / 2 - 1, 64 + size / 2 - 1);
10984 ok(color_match(color, test_setups[i].gives_0_0_texcoord ? 0x00ff0000 : 0x0000ff00, 0)
10985 || (allow_broken && broken(color_match(color, 0x00000000, 0))),
10986 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
10988 color = get_readback_color(&rb, 64 - size / 2 - 1, 64 - size / 2 - 1);
10989 ok(color_match(color, 0xff00ffff, 0),
10990 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
10991 color = get_readback_color(&rb, 64 + size / 2 + 1, 64 - size / 2 - 1);
10992 ok(color_match(color, 0xff00ffff, 0),
10993 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
10994 color = get_readback_color(&rb, 64 - size / 2 - 1, 64 + size / 2 + 1);
10995 ok(color_match(color, 0xff00ffff, 0),
10996 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
10997 color = get_readback_color(&rb, 64 + size / 2 + 1, 64 + size / 2 + 1);
10998 ok(color_match(color, 0xff00ffff, 0),
10999 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
11001 release_surface_readback(&rb);
11004 IDirect3DDevice9_SetVertexShader(device, NULL);
11005 IDirect3DDevice9_SetPixelShader(device, NULL);
11006 if (vs)
11007 IDirect3DVertexShader9_Release(vs);
11008 if (ps)
11009 IDirect3DVertexShader9_Release(ps);
11012 cleanup:
11013 IDirect3DSurface9_Release(backbuffer);
11014 IDirect3DSurface9_Release(rt);
11016 IDirect3DTexture9_Release(tex1);
11017 IDirect3DTexture9_Release(tex2);
11018 refcount = IDirect3DDevice9_Release(device);
11019 ok(!refcount, "Device has %u references left.\n", refcount);
11020 done:
11021 IDirect3D9_Release(d3d);
11022 DestroyWindow(window);
11025 static void multiple_rendertargets_test(void)
11027 IDirect3DSurface9 *surf1, *surf2, *backbuf, *readback;
11028 IDirect3DPixelShader9 *ps1, *ps2;
11029 IDirect3DTexture9 *tex1, *tex2;
11030 IDirect3DVertexShader9 *vs;
11031 IDirect3DDevice9 *device;
11032 IDirect3D9 *d3d;
11033 ULONG refcount;
11034 D3DCAPS9 caps;
11035 DWORD color;
11036 HWND window;
11037 HRESULT hr;
11038 UINT i, j;
11040 static const DWORD vshader_code[] =
11042 0xfffe0300, /* vs_3_0 */
11043 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
11044 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
11045 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
11046 0x0000ffff /* end */
11048 static const DWORD pshader_code1[] =
11050 0xffff0300, /* ps_3_0 */
11051 0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
11052 0x02000001, 0x800f0800, 0xa0e40000, /* mov oC0, c0 */
11053 0x0000ffff /* end */
11055 static const DWORD pshader_code2[] =
11057 0xffff0300, /* ps_3_0 */
11058 0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
11059 0x05000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c1, 0.0, 0.0, 1.0, 0.0 */
11060 0x02000001, 0x800f0800, 0xa0e40000, /* mov oC0, c0 */
11061 0x02000001, 0x800f0801, 0xa0e40001, /* mov oC1, c1 */
11062 0x0000ffff /* end */
11064 static const float quad[] =
11066 -1.0f, -1.0f, 0.1f,
11067 -1.0f, 1.0f, 0.1f,
11068 1.0f, -1.0f, 0.1f,
11069 1.0f, 1.0f, 0.1f,
11071 static const float texquad[] =
11073 -1.0f, -1.0f, 0.1f, 0.0f, 0.0f,
11074 -1.0f, 1.0f, 0.1f, 0.0f, 1.0f,
11075 0.0f, -1.0f, 0.1f, 1.0f, 0.0f,
11076 0.0f, 1.0f, 0.1f, 1.0f, 1.0f,
11078 0.0f, -1.0f, 0.1f, 0.0f, 0.0f,
11079 0.0f, 1.0f, 0.1f, 0.0f, 1.0f,
11080 1.0f, -1.0f, 0.1f, 1.0f, 0.0f,
11081 1.0f, 1.0f, 0.1f, 1.0f, 1.0f,
11084 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
11085 0, 0, 640, 480, NULL, NULL, NULL, NULL);
11086 d3d = Direct3DCreate9(D3D_SDK_VERSION);
11087 ok(!!d3d, "Failed to create a D3D object.\n");
11088 if (!(device = create_device(d3d, window, window, TRUE)))
11090 skip("Failed to create a D3D device, skipping tests.\n");
11091 goto done;
11094 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11095 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
11096 if (caps.NumSimultaneousRTs < 2)
11098 skip("Only 1 simultaneous render target supported, skipping MRT test.\n");
11099 IDirect3DDevice9_Release(device);
11100 goto done;
11102 if (caps.PixelShaderVersion < D3DPS_VERSION(3, 0) || caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
11104 skip("No shader model 3 support, skipping tests.\n");
11105 IDirect3DDevice9_Release(device);
11106 goto done;
11109 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 1.0f, 0);
11110 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
11112 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 16, 16,
11113 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &readback, NULL);
11114 ok(SUCCEEDED(hr), "CreateOffscreenPlainSurface failed, hr %#x.\n", hr);
11116 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET,
11117 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex1, NULL);
11118 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
11119 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET,
11120 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex2, NULL);
11121 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
11122 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vs);
11123 ok(SUCCEEDED(hr), "CreateVertexShader failed, hr %#x.\n", hr);
11124 hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code1, &ps1);
11125 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
11126 hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code2, &ps2);
11127 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
11129 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuf);
11130 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr=%08x\n", hr);
11131 hr = IDirect3DTexture9_GetSurfaceLevel(tex1, 0, &surf1);
11132 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
11133 hr = IDirect3DTexture9_GetSurfaceLevel(tex2, 0, &surf2);
11134 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
11136 hr = IDirect3DDevice9_SetVertexShader(device, vs);
11137 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
11138 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surf1);
11139 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
11140 hr = IDirect3DDevice9_SetRenderTarget(device, 1, surf2);
11141 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
11142 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
11143 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
11145 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0f, 0);
11146 ok(SUCCEEDED(hr), "Clear failed, hr %#x,\n", hr);
11147 hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, readback);
11148 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
11149 color = getPixelColorFromSurface(readback, 8, 8);
11150 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
11151 "Expected color 0x000000ff, got 0x%08x.\n", color);
11152 hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
11153 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
11154 color = getPixelColorFromSurface(readback, 8, 8);
11155 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
11156 "Expected color 0x000000ff, got 0x%08x.\n", color);
11158 /* Render targets not written by the pixel shader should be unmodified. */
11159 hr = IDirect3DDevice9_SetPixelShader(device, ps1);
11160 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
11161 hr = IDirect3DDevice9_BeginScene(device);
11162 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11163 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
11164 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11165 hr = IDirect3DDevice9_EndScene(device);
11166 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11167 hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, readback);
11168 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
11169 color = getPixelColorFromSurface(readback, 8, 8);
11170 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
11171 "Expected color 0xff00ff00, got 0x%08x.\n", color);
11172 hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
11173 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
11174 for (i = 6; i < 10; ++i)
11176 for (j = 6; j < 10; ++j)
11178 color = getPixelColorFromSurface(readback, j, i);
11179 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
11180 "Expected color 0xff0000ff, got 0x%08x at %u, %u.\n", color, j, i);
11184 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0f, 0);
11185 ok(SUCCEEDED(hr), "Clear failed, hr %#x,\n", hr);
11186 hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, readback);
11187 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
11188 color = getPixelColorFromSurface(readback, 8, 8);
11189 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00), 0),
11190 "Expected color 0x0000ff00, got 0x%08x.\n", color);
11191 hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
11192 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
11193 color = getPixelColorFromSurface(readback, 8, 8);
11194 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00), 0),
11195 "Expected color 0x0000ff00, got 0x%08x.\n", color);
11197 hr = IDirect3DDevice9_SetPixelShader(device, ps2);
11198 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
11200 hr = IDirect3DDevice9_BeginScene(device);
11201 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
11203 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
11204 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
11206 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11207 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
11208 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
11209 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
11210 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11211 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
11212 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuf);
11213 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
11214 hr = IDirect3DDevice9_SetRenderTarget(device, 1, NULL);
11215 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
11216 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
11217 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
11219 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
11220 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
11221 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[0], 5 * sizeof(float));
11222 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
11224 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex2);
11225 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
11226 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[20], 5 * sizeof(float));
11227 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
11229 hr = IDirect3DDevice9_EndScene(device);
11230 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
11232 color = getPixelColor(device, 160, 240);
11233 ok(color == 0x0000ff00, "Texture 1(output color 1) has color 0x%08x, expected 0x0000ff00\n", color);
11234 color = getPixelColor(device, 480, 240);
11235 ok(color == 0x000000ff, "Texture 2(output color 2) has color 0x%08x, expected 0x000000ff\n", color);
11236 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11238 IDirect3DPixelShader9_Release(ps2);
11239 IDirect3DPixelShader9_Release(ps1);
11240 IDirect3DVertexShader9_Release(vs);
11241 IDirect3DTexture9_Release(tex1);
11242 IDirect3DTexture9_Release(tex2);
11243 IDirect3DSurface9_Release(surf1);
11244 IDirect3DSurface9_Release(surf2);
11245 IDirect3DSurface9_Release(backbuf);
11246 IDirect3DSurface9_Release(readback);
11247 refcount = IDirect3DDevice9_Release(device);
11248 ok(!refcount, "Device has %u references left.\n", refcount);
11249 done:
11250 IDirect3D9_Release(d3d);
11251 DestroyWindow(window);
11254 static void pixelshader_blending_test(void)
11256 IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
11257 IDirect3DTexture9 *offscreenTexture = NULL;
11258 IDirect3DDevice9 *device;
11259 IDirect3D9 *d3d;
11260 ULONG refcount;
11261 int fmt_index;
11262 DWORD color;
11263 HWND window;
11264 HRESULT hr;
11266 static const struct
11268 const char *fmtName;
11269 D3DFORMAT textureFormat;
11270 D3DCOLOR resultColorBlending;
11271 D3DCOLOR resultColorNoBlending;
11273 test_formats[] =
11275 {"D3DFMT_G16R16", D3DFMT_G16R16, 0x001818ff, 0x002010ff},
11276 {"D3DFMT_R16F", D3DFMT_R16F, 0x0018ffff, 0x0020ffff},
11277 {"D3DFMT_G16R16F", D3DFMT_G16R16F, 0x001818ff, 0x002010ff},
11278 {"D3DFMT_A16B16G16R16F", D3DFMT_A16B16G16R16F, 0x00181800, 0x00201000},
11279 {"D3DFMT_R32F", D3DFMT_R32F, 0x0018ffff, 0x0020ffff},
11280 {"D3DFMT_G32R32F", D3DFMT_G32R32F, 0x001818ff, 0x002010ff},
11281 {"D3DFMT_A32B32G32R32F", D3DFMT_A32B32G32R32F, 0x00181800, 0x00201000},
11283 static const float quad[][5] =
11285 {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
11286 {-0.5f, 0.5f, 0.1f, 0.0f, 1.0f},
11287 { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
11288 { 0.5f, 0.5f, 0.1f, 1.0f, 1.0f},
11290 static const struct
11292 struct vec3 position;
11293 DWORD diffuse;
11295 /* Quad with R=0x10, G=0x20 */
11296 quad1[] =
11298 {{-1.0f, -1.0f, 0.1f}, 0x80102000},
11299 {{-1.0f, 1.0f, 0.1f}, 0x80102000},
11300 {{ 1.0f, -1.0f, 0.1f}, 0x80102000},
11301 {{ 1.0f, 1.0f, 0.1f}, 0x80102000},
11303 /* Quad with R=0x20, G=0x10 */
11304 quad2[] =
11306 {{-1.0f, -1.0f, 0.1f}, 0x80201000},
11307 {{-1.0f, 1.0f, 0.1f}, 0x80201000},
11308 {{ 1.0f, -1.0f, 0.1f}, 0x80201000},
11309 {{ 1.0f, 1.0f, 0.1f}, 0x80201000},
11312 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
11313 0, 0, 640, 480, NULL, NULL, NULL, NULL);
11314 d3d = Direct3DCreate9(D3D_SDK_VERSION);
11315 ok(!!d3d, "Failed to create a D3D object.\n");
11316 if (!(device = create_device(d3d, window, window, TRUE)))
11318 skip("Failed to create a D3D device, skipping tests.\n");
11319 goto done;
11322 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
11323 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
11325 for (fmt_index = 0; fmt_index < sizeof(test_formats) / sizeof(*test_formats); ++fmt_index)
11327 D3DFORMAT fmt = test_formats[fmt_index].textureFormat;
11329 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
11330 D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, fmt) != D3D_OK)
11332 skip("%s textures not supported as render targets.\n", test_formats[fmt_index].fmtName);
11333 continue;
11336 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
11337 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
11339 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, fmt, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
11340 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
11341 if(!offscreenTexture) {
11342 continue;
11345 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
11346 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
11347 if(!offscreen) {
11348 continue;
11351 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11352 ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
11354 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
11355 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
11356 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
11357 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
11358 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
11359 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
11360 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
11361 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
11362 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11363 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
11365 /* Below we will draw two quads with different colors and try to blend
11366 * them together. The result color is compared with the expected
11367 * outcome. */
11368 hr = IDirect3DDevice9_BeginScene(device);
11369 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
11371 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
11372 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
11373 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ffffff, 1.0f, 0);
11374 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
11376 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
11377 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
11379 /* Draw a quad using color 0x0010200. */
11380 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_ONE);
11381 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
11382 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_ZERO);
11383 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
11384 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
11385 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
11387 /* Draw a quad using color 0x0020100. */
11388 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
11389 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
11390 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
11391 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
11392 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
11393 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
11395 /* We don't want to blend the result on the backbuffer. */
11396 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
11397 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
11399 /* Prepare rendering the 'blended' texture quad to the backbuffer. */
11400 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
11401 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
11402 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)offscreenTexture);
11403 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
11405 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
11406 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
11408 /* This time with the texture. */
11409 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
11410 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
11412 hr = IDirect3DDevice9_EndScene(device);
11413 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
11415 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
11416 D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, D3DRTYPE_TEXTURE, fmt) == D3D_OK)
11418 /* Compare the color of the center quad with our expectation. */
11419 color = getPixelColor(device, 320, 240);
11420 ok(color_match(color, test_formats[fmt_index].resultColorBlending, 1),
11421 "Offscreen failed for %s: Got color 0x%08x, expected 0x%08x.\n",
11422 test_formats[fmt_index].fmtName, color, test_formats[fmt_index].resultColorBlending);
11424 else
11426 /* No pixel shader blending is supported so expect garbage. The
11427 * type of 'garbage' depends on the driver version and OS. E.g. on
11428 * G16R16 ATI reports (on old r9600 drivers) 0x00ffffff and on
11429 * modern ones 0x002010ff which is also what NVIDIA reports. On
11430 * Vista NVIDIA seems to report 0x00ffffff on Geforce7 cards. */
11431 color = getPixelColor(device, 320, 240);
11432 ok((color == 0x00ffffff) || (color == test_formats[fmt_index].resultColorNoBlending),
11433 "Offscreen failed for %s: Got unexpected color 0x%08x, expected no color blending.\n",
11434 test_formats[fmt_index].fmtName, color);
11436 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11438 IDirect3DDevice9_SetTexture(device, 0, NULL);
11439 if(offscreenTexture) {
11440 IDirect3DTexture9_Release(offscreenTexture);
11442 if(offscreen) {
11443 IDirect3DSurface9_Release(offscreen);
11447 IDirect3DSurface9_Release(backbuffer);
11448 refcount = IDirect3DDevice9_Release(device);
11449 ok(!refcount, "Device has %u references left.\n", refcount);
11450 done:
11451 IDirect3D9_Release(d3d);
11452 DestroyWindow(window);
11455 static void tssargtemp_test(void)
11457 IDirect3DDevice9 *device;
11458 IDirect3D9 *d3d;
11459 D3DCOLOR color;
11460 ULONG refcount;
11461 D3DCAPS9 caps;
11462 HWND window;
11463 HRESULT hr;
11465 static const struct
11467 struct vec3 position;
11468 DWORD diffuse;
11470 quad[] =
11472 {{-1.0f, -1.0f, 0.1f}, 0x00ff0000},
11473 {{-1.0f, 1.0f, 0.1f}, 0x00ff0000},
11474 {{ 1.0f, -1.0f, 0.1f}, 0x00ff0000},
11475 {{ 1.0f, 1.0f, 0.1f}, 0x00ff0000},
11478 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
11479 0, 0, 640, 480, NULL, NULL, NULL, NULL);
11480 d3d = Direct3DCreate9(D3D_SDK_VERSION);
11481 ok(!!d3d, "Failed to create a D3D object.\n");
11482 if (!(device = create_device(d3d, window, window, TRUE)))
11484 skip("Failed to create a D3D device, skipping tests.\n");
11485 goto done;
11488 memset(&caps, 0, sizeof(caps));
11489 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11490 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with %08x\n", hr);
11491 if(!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP)) {
11492 skip("D3DPMISCCAPS_TSSARGTEMP not supported\n");
11493 IDirect3DDevice9_Release(device);
11494 goto done;
11497 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff000000, 1.0f, 0);
11498 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
11500 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
11501 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
11502 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
11503 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
11505 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
11506 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
11507 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TFACTOR);
11508 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
11509 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_TEMP);
11510 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
11512 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_ADD);
11513 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
11514 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG1, D3DTA_CURRENT);
11515 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
11516 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG2, D3DTA_TEMP);
11517 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
11519 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
11520 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
11522 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x0000ff00);
11523 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
11524 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11525 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
11526 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11527 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
11529 hr = IDirect3DDevice9_BeginScene(device);
11530 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
11531 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
11532 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
11533 hr = IDirect3DDevice9_EndScene(device);
11534 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
11536 color = getPixelColor(device, 320, 240);
11537 ok(color == 0x00ffff00, "TSSARGTEMP test returned color 0x%08x, expected 0x00ffff00\n", color);
11538 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11540 refcount = IDirect3DDevice9_Release(device);
11541 ok(!refcount, "Device has %u references left.\n", refcount);
11542 done:
11543 IDirect3D9_Release(d3d);
11544 DestroyWindow(window);
11547 /* Drawing Indexed Geometry with instances*/
11548 static void stream_test(void)
11550 IDirect3DVertexDeclaration9 *pDecl = NULL;
11551 IDirect3DVertexShader9 *shader = NULL;
11552 IDirect3DVertexBuffer9 *vb3 = NULL;
11553 IDirect3DVertexBuffer9 *vb2 = NULL;
11554 IDirect3DVertexBuffer9 *vb = NULL;
11555 IDirect3DIndexBuffer9 *ib = NULL;
11556 IDirect3DDevice9 *device;
11557 IDirect3D9 *d3d;
11558 ULONG refcount;
11559 D3DCAPS9 caps;
11560 DWORD color;
11561 HWND window;
11562 unsigned i;
11563 HRESULT hr;
11564 BYTE *data;
11565 DWORD ind;
11567 static const struct testdata
11569 DWORD idxVertex; /* number of instances in the first stream */
11570 DWORD idxColor; /* number of instances in the second stream */
11571 DWORD idxInstance; /* should be 1 ?? */
11572 DWORD color1; /* color 1 instance */
11573 DWORD color2; /* color 2 instance */
11574 DWORD color3; /* color 3 instance */
11575 DWORD color4; /* color 4 instance */
11576 WORD strVertex; /* specify which stream to use 0-2*/
11577 WORD strColor;
11578 WORD strInstance;
11580 testcases[]=
11582 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 0 */
11583 {3, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /* 1 */
11584 {2, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /* 2 */
11585 {1, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /* 3 */
11586 {4, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 4 */
11587 {4, 2, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 5 */
11588 {4, 1, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 6 */
11589 {4, 0, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 7 */
11590 {3, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /* 8 */
11591 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 0, 2}, /* 9 */
11592 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 2, 1}, /* 10 */
11593 {4, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 3, 1}, /* 11 */
11594 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 2, 0, 1}, /* 12 */
11595 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 2, 3}, /* 13 */
11596 #if 0
11597 /* This draws one instance on some machines, no instance on others. */
11598 {0, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /* 14 */
11599 /* This case is handled in a stand alone test,
11600 * SetStreamSourceFreq(0, (D3DSTREAMSOURCE_INSTANCEDATA | 1)) has to
11601 * return D3DERR_INVALIDCALL. */
11602 {4, 4, 1, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 1, 0}, /* 15 */
11603 #endif
11605 static const DWORD shader_code[] =
11607 0xfffe0101, /* vs_1_1 */
11608 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
11609 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
11610 0x0000001f, 0x80000005, 0x900f0002, /* dcl_texcoord v2 */
11611 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
11612 0x00000002, 0xc00f0000, 0x80e40000, 0x90e40002, /* add oPos, r0, v2 */
11613 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
11614 0x0000ffff
11616 static const float quad[][3] =
11618 {-0.5f, -0.5f, 1.1f}, /*0 */
11619 {-0.5f, 0.5f, 1.1f}, /*1 */
11620 { 0.5f, -0.5f, 1.1f}, /*2 */
11621 { 0.5f, 0.5f, 1.1f}, /*3 */
11623 static const float vertcolor[][4] =
11625 {1.0f, 0.0f, 0.0f, 1.0f}, /*0 */
11626 {1.0f, 0.0f, 0.0f, 1.0f}, /*1 */
11627 {1.0f, 0.0f, 0.0f, 1.0f}, /*2 */
11628 {1.0f, 0.0f, 0.0f, 1.0f}, /*3 */
11630 /* 4 position for 4 instances */
11631 static const float instancepos[][3] =
11633 {-0.6f,-0.6f, 0.0f},
11634 { 0.6f,-0.6f, 0.0f},
11635 { 0.6f, 0.6f, 0.0f},
11636 {-0.6f, 0.6f, 0.0f},
11638 static const short indices[] = {0, 1, 2, 2, 1, 3};
11639 D3DVERTEXELEMENT9 decl[] =
11641 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
11642 {1, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
11643 {2, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
11644 D3DDECL_END()
11647 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
11648 0, 0, 640, 480, NULL, NULL, NULL, NULL);
11649 d3d = Direct3DCreate9(D3D_SDK_VERSION);
11650 ok(!!d3d, "Failed to create a D3D object.\n");
11651 if (!(device = create_device(d3d, window, window, TRUE)))
11653 skip("Failed to create a D3D device, skipping tests.\n");
11654 goto done;
11657 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11658 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
11659 if (caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
11661 skip("No vs_3_0 support, skipping tests.\n");
11662 IDirect3DDevice9_Release(device);
11663 goto done;
11666 /* set the default value because it isn't done in wine? */
11667 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
11668 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
11670 /* check for D3DSTREAMSOURCE_INDEXEDDATA at stream0 */
11671 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 0, (D3DSTREAMSOURCE_INSTANCEDATA | 1));
11672 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
11674 /* check wrong cases */
11675 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 0);
11676 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
11677 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
11678 ok(hr == D3D_OK && ind == 1, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
11679 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 2);
11680 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
11681 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
11682 ok(hr == D3D_OK && ind == 2, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
11683 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INDEXEDDATA | 0));
11684 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
11685 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
11686 ok(hr == D3D_OK && ind == (D3DSTREAMSOURCE_INDEXEDDATA | 0), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
11687 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | 0));
11688 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
11689 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
11690 ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
11691 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | D3DSTREAMSOURCE_INDEXEDDATA | 0));
11692 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
11693 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
11694 ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
11696 /* set the default value back */
11697 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
11698 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
11700 /* create all VertexBuffers*/
11701 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0, D3DPOOL_MANAGED, &vb, NULL);
11702 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
11703 if(!vb) {
11704 skip("Failed to create a vertex buffer\n");
11705 IDirect3DDevice9_Release(device);
11706 goto done;
11708 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(vertcolor), 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
11709 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
11710 if(!vb2) {
11711 skip("Failed to create a vertex buffer\n");
11712 goto out;
11714 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(instancepos), 0, 0, D3DPOOL_MANAGED, &vb3, NULL);
11715 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
11716 if(!vb3) {
11717 skip("Failed to create a vertex buffer\n");
11718 goto out;
11721 /* create IndexBuffer*/
11722 hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
11723 ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
11724 if(!ib) {
11725 skip("Failed to create an index buffer\n");
11726 goto out;
11729 /* copy all Buffers (Vertex + Index)*/
11730 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
11731 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
11732 memcpy(data, quad, sizeof(quad));
11733 hr = IDirect3DVertexBuffer9_Unlock(vb);
11734 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
11735 hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(vertcolor), (void **) &data, 0);
11736 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
11737 memcpy(data, vertcolor, sizeof(vertcolor));
11738 hr = IDirect3DVertexBuffer9_Unlock(vb2);
11739 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
11740 hr = IDirect3DVertexBuffer9_Lock(vb3, 0, sizeof(instancepos), (void **) &data, 0);
11741 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
11742 memcpy(data, instancepos, sizeof(instancepos));
11743 hr = IDirect3DVertexBuffer9_Unlock(vb3);
11744 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
11745 hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
11746 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
11747 memcpy(data, indices, sizeof(indices));
11748 hr = IDirect3DIndexBuffer9_Unlock(ib);
11749 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
11751 /* create VertexShader */
11752 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
11753 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
11754 if(!shader) {
11755 skip("Failed to create a vetex shader\n");
11756 goto out;
11759 hr = IDirect3DDevice9_SetVertexShader(device, shader);
11760 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
11762 hr = IDirect3DDevice9_SetIndices(device, ib);
11763 ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
11765 /* run all tests */
11766 for( i = 0; i < sizeof(testcases)/sizeof(testcases[0]); ++i)
11768 struct testdata act = testcases[i];
11769 decl[0].Stream = act.strVertex;
11770 decl[1].Stream = act.strColor;
11771 decl[2].Stream = act.strInstance;
11772 /* create VertexDeclarations */
11773 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl, &pDecl);
11774 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x (case %i)\n", hr, i);
11776 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
11777 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x (case %i)\n", hr, i);
11779 hr = IDirect3DDevice9_BeginScene(device);
11780 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
11782 hr = IDirect3DDevice9_SetVertexDeclaration(device, pDecl);
11783 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
11785 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex,
11786 (D3DSTREAMSOURCE_INDEXEDDATA | act.idxVertex));
11787 ok(SUCCEEDED(hr), "Failed to set stream source frequency, hr %#x.\n", hr);
11788 hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, vb, 0, sizeof(quad[0]));
11789 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
11791 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strColor,
11792 (D3DSTREAMSOURCE_INDEXEDDATA | act.idxColor));
11793 ok(SUCCEEDED(hr), "Failed to set stream source frequency, hr %#x.\n", hr);
11794 hr = IDirect3DDevice9_SetStreamSource(device, act.strColor, vb2, 0, sizeof(vertcolor[0]));
11795 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
11797 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strInstance,
11798 (D3DSTREAMSOURCE_INSTANCEDATA | act.idxInstance));
11799 ok(SUCCEEDED(hr), "Failed to set stream source frequency, hr %#x.\n", hr);
11800 hr = IDirect3DDevice9_SetStreamSource(device, act.strInstance, vb3, 0, sizeof(instancepos[0]));
11801 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
11803 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 0, 4, 0, 2);
11804 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
11805 hr = IDirect3DDevice9_EndScene(device);
11806 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
11808 /* set all StreamSource && StreamSourceFreq back to default */
11809 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, 1);
11810 ok(SUCCEEDED(hr), "Failed to set stream source frequency, hr %#x.\n", hr);
11811 hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, NULL, 0, 0);
11812 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
11813 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxColor, 1);
11814 ok(SUCCEEDED(hr), "Failed to set stream source frequency, hr %#x.\n", hr);
11815 hr = IDirect3DDevice9_SetStreamSource(device, act.idxColor, NULL, 0, 0);
11816 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
11817 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxInstance, 1);
11818 ok(SUCCEEDED(hr), "Failed to set stream source frequency, hr %#x.\n", hr);
11819 hr = IDirect3DDevice9_SetStreamSource(device, act.idxInstance, NULL, 0, 0);
11820 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
11822 hr = IDirect3DVertexDeclaration9_Release(pDecl);
11823 ok(hr == D3D_OK, "IDirect3DVertexDeclaration9_Release failed with %08x (case %i)\n", hr, i);
11825 color = getPixelColor(device, 160, 360);
11826 ok(color == act.color1, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color1, i);
11827 color = getPixelColor(device, 480, 360);
11828 ok(color == act.color2, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color2, i);
11829 color = getPixelColor(device, 480, 120);
11830 ok(color == act.color3, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color3, i);
11831 color = getPixelColor(device, 160, 120);
11832 ok(color == act.color4, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color4, i);
11834 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11835 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x (case %i)\n", hr, i);
11838 out:
11839 if(vb) IDirect3DVertexBuffer9_Release(vb);
11840 if(vb2)IDirect3DVertexBuffer9_Release(vb2);
11841 if(vb3)IDirect3DVertexBuffer9_Release(vb3);
11842 if(ib)IDirect3DIndexBuffer9_Release(ib);
11843 if(shader)IDirect3DVertexShader9_Release(shader);
11844 refcount = IDirect3DDevice9_Release(device);
11845 ok(!refcount, "Device has %u references left.\n", refcount);
11846 done:
11847 IDirect3D9_Release(d3d);
11848 DestroyWindow(window);
11851 static void np2_stretch_rect_test(void)
11853 IDirect3DSurface9 *src = NULL, *dst = NULL, *backbuffer = NULL;
11854 IDirect3DTexture9 *dsttex = NULL;
11855 IDirect3DDevice9 *device;
11856 IDirect3D9 *d3d;
11857 D3DCOLOR color;
11858 ULONG refcount;
11859 HWND window;
11860 HRESULT hr;
11862 static const D3DRECT r1 = {0, 0, 50, 50 };
11863 static const D3DRECT r2 = {50, 0, 100, 50 };
11864 static const D3DRECT r3 = {50, 50, 100, 100};
11865 static const D3DRECT r4 = {0, 50, 50, 100};
11866 static const float quad[] =
11868 -1.0f, -1.0f, 0.1f, 0.0f, 0.0f,
11869 -1.0f, 1.0f, 0.1f, 0.0f, 1.0f,
11870 1.0f, -1.0f, 0.1f, 1.0f, 0.0f,
11871 1.0f, 1.0f, 0.1f, 1.0f, 1.0f,
11874 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
11875 0, 0, 640, 480, NULL, NULL, NULL, NULL);
11876 d3d = Direct3DCreate9(D3D_SDK_VERSION);
11877 ok(!!d3d, "Failed to create a D3D object.\n");
11878 if (!(device = create_device(d3d, window, window, TRUE)))
11880 skip("Failed to create a D3D device, skipping tests.\n");
11881 goto done;
11884 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
11885 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed with %08x\n", hr);
11887 hr = IDirect3DDevice9_CreateRenderTarget(device, 100, 100, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &src, NULL );
11888 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateRenderTarget failed with %08x\n", hr);
11889 hr = IDirect3DDevice9_CreateTexture(device, 25, 25, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &dsttex, NULL);
11890 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
11892 if(!src || !dsttex) {
11893 skip("One or more test resources could not be created\n");
11894 goto cleanup;
11897 hr = IDirect3DTexture9_GetSurfaceLevel(dsttex, 0, &dst);
11898 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
11900 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
11901 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
11903 /* Clear the StretchRect destination for debugging */
11904 hr = IDirect3DDevice9_SetRenderTarget(device, 0, dst);
11905 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
11906 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
11907 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
11909 hr = IDirect3DDevice9_SetRenderTarget(device, 0, src);
11910 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
11912 hr = IDirect3DDevice9_Clear(device, 1, &r1, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
11913 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
11914 hr = IDirect3DDevice9_Clear(device, 1, &r2, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
11915 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
11916 hr = IDirect3DDevice9_Clear(device, 1, &r3, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
11917 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
11918 hr = IDirect3DDevice9_Clear(device, 1, &r4, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
11919 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
11921 /* Stretchrect before setting the render target back to the backbuffer. This will make Wine use
11922 * the target -> texture GL blit path
11924 hr = IDirect3DDevice9_StretchRect(device, src, NULL, dst, NULL, D3DTEXF_POINT);
11925 ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
11926 IDirect3DSurface9_Release(dst);
11928 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
11929 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
11931 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) dsttex);
11932 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
11933 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
11934 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
11935 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
11936 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with %08x\n", hr);
11937 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
11938 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with %08x\n", hr);
11940 hr = IDirect3DDevice9_BeginScene(device);
11941 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
11942 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
11943 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
11944 hr = IDirect3DDevice9_EndScene(device);
11945 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
11947 color = getPixelColor(device, 160, 360);
11948 ok(color == 0x00ff0000, "stretchrect: Pixel 160,360 has color 0x%08x, expected 0x00ff0000\n", color);
11949 color = getPixelColor(device, 480, 360);
11950 ok(color == 0x0000ff00, "stretchrect: Pixel 480,360 has color 0x%08x, expected 0x0000ff00\n", color);
11951 color = getPixelColor(device, 480, 120);
11952 ok(color == 0x000000ff, "stretchrect: Pixel 480,120 has color 0x%08x, expected 0x000000ff\n", color);
11953 color = getPixelColor(device, 160, 120);
11954 ok(color == 0x00000000, "stretchrect: Pixel 160,120 has color 0x%08x, expected 0x00000000\n", color);
11955 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11956 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
11958 cleanup:
11959 if(src) IDirect3DSurface9_Release(src);
11960 if(backbuffer) IDirect3DSurface9_Release(backbuffer);
11961 if(dsttex) IDirect3DTexture9_Release(dsttex);
11962 refcount = IDirect3DDevice9_Release(device);
11963 ok(!refcount, "Device has %u references left.\n", refcount);
11964 done:
11965 IDirect3D9_Release(d3d);
11966 DestroyWindow(window);
11969 static void texop_test(void)
11971 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
11972 IDirect3DTexture9 *texture = NULL;
11973 D3DLOCKED_RECT locked_rect;
11974 IDirect3DDevice9 *device;
11975 IDirect3D9 *d3d;
11976 D3DCOLOR color;
11977 ULONG refcount;
11978 D3DCAPS9 caps;
11979 HWND window;
11980 HRESULT hr;
11981 unsigned i;
11983 static const struct {
11984 float x, y, z;
11985 float s, t;
11986 D3DCOLOR diffuse;
11987 } quad[] = {
11988 {-1.0f, -1.0f, 0.1f, -1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
11989 {-1.0f, 1.0f, 0.1f, -1.0f, 1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
11990 { 1.0f, -1.0f, 0.1f, 1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
11991 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)}
11994 static const D3DVERTEXELEMENT9 decl_elements[] = {
11995 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
11996 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
11997 {0, 20, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
11998 D3DDECL_END()
12001 static const struct {
12002 D3DTEXTUREOP op;
12003 const char *name;
12004 DWORD caps_flag;
12005 D3DCOLOR result;
12006 } test_data[] = {
12007 {D3DTOP_SELECTARG1, "SELECTARG1", D3DTEXOPCAPS_SELECTARG1, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
12008 {D3DTOP_SELECTARG2, "SELECTARG2", D3DTEXOPCAPS_SELECTARG2, D3DCOLOR_ARGB(0x00, 0x33, 0x33, 0x33)},
12009 {D3DTOP_MODULATE, "MODULATE", D3DTEXOPCAPS_MODULATE, D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x00)},
12010 {D3DTOP_MODULATE2X, "MODULATE2X", D3DTEXOPCAPS_MODULATE2X, D3DCOLOR_ARGB(0x00, 0x00, 0x66, 0x00)},
12011 {D3DTOP_MODULATE4X, "MODULATE4X", D3DTEXOPCAPS_MODULATE4X, D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
12012 {D3DTOP_ADD, "ADD", D3DTEXOPCAPS_ADD, D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
12013 {D3DTOP_ADDSIGNED, "ADDSIGNED", D3DTEXOPCAPS_ADDSIGNED, D3DCOLOR_ARGB(0x00, 0x00, 0xb2, 0x00)},
12014 {D3DTOP_ADDSIGNED2X, "ADDSIGNED2X", D3DTEXOPCAPS_ADDSIGNED2X, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
12015 {D3DTOP_SUBTRACT, "SUBTRACT", D3DTEXOPCAPS_SUBTRACT, D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
12016 {D3DTOP_ADDSMOOTH, "ADDSMOOTH", D3DTEXOPCAPS_ADDSMOOTH, D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
12017 {D3DTOP_BLENDDIFFUSEALPHA, "BLENDDIFFUSEALPHA", D3DTEXOPCAPS_BLENDDIFFUSEALPHA, D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
12018 {D3DTOP_BLENDTEXTUREALPHA, "BLENDTEXTUREALPHA", D3DTEXOPCAPS_BLENDTEXTUREALPHA, D3DCOLOR_ARGB(0x00, 0x14, 0xad, 0x14)},
12019 {D3DTOP_BLENDFACTORALPHA, "BLENDFACTORALPHA", D3DTEXOPCAPS_BLENDFACTORALPHA, D3DCOLOR_ARGB(0x00, 0x07, 0xe4, 0x07)},
12020 {D3DTOP_BLENDTEXTUREALPHAPM, "BLENDTEXTUREALPHAPM", D3DTEXOPCAPS_BLENDTEXTUREALPHAPM, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
12021 {D3DTOP_BLENDCURRENTALPHA, "BLENDCURRENTALPHA", D3DTEXOPCAPS_BLENDCURRENTALPHA, D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
12022 {D3DTOP_MODULATEALPHA_ADDCOLOR, "MODULATEALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x1f, 0xff, 0x1f)},
12023 {D3DTOP_MODULATECOLOR_ADDALPHA, "MODULATECOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0x99, 0xcc, 0x99)},
12024 {D3DTOP_MODULATEINVALPHA_ADDCOLOR, "MODULATEINVALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
12025 {D3DTOP_MODULATEINVCOLOR_ADDALPHA, "MODULATEINVCOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0xcc, 0x99, 0xcc)},
12026 /* BUMPENVMAP & BUMPENVMAPLUMINANCE have their own tests */
12027 {D3DTOP_DOTPRODUCT3, "DOTPRODUCT3", D3DTEXOPCAPS_DOTPRODUCT3, D3DCOLOR_ARGB(0x00, 0x99, 0x99, 0x99)},
12028 {D3DTOP_MULTIPLYADD, "MULTIPLYADD", D3DTEXOPCAPS_MULTIPLYADD, D3DCOLOR_ARGB(0x00, 0xff, 0x33, 0x00)},
12029 {D3DTOP_LERP, "LERP", D3DTEXOPCAPS_LERP, D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x33)},
12032 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
12033 0, 0, 640, 480, NULL, NULL, NULL, NULL);
12034 d3d = Direct3DCreate9(D3D_SDK_VERSION);
12035 ok(!!d3d, "Failed to create a D3D object.\n");
12036 if (!(device = create_device(d3d, window, window, TRUE)))
12038 skip("Failed to create a D3D device, skipping tests.\n");
12039 goto done;
12042 memset(&caps, 0, sizeof(caps));
12043 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
12044 ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
12046 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
12047 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed with 0x%08x\n", hr);
12048 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
12049 ok(SUCCEEDED(hr), "SetVertexDeclaration failed with 0x%08x\n", hr);
12051 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
12052 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
12053 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
12054 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
12055 *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x99, 0x00, 0xff, 0x00);
12056 hr = IDirect3DTexture9_UnlockRect(texture, 0);
12057 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
12058 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
12059 ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
12061 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG0, D3DTA_DIFFUSE);
12062 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12063 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
12064 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12065 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
12066 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12068 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
12069 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12071 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
12072 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
12073 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xdd333333);
12074 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
12075 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_ALPHA);
12076 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
12078 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
12079 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
12081 for (i = 0; i < sizeof(test_data) / sizeof(*test_data); ++i)
12083 if (!(caps.TextureOpCaps & test_data[i].caps_flag))
12085 skip("tex operation %s not supported\n", test_data[i].name);
12086 continue;
12089 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, test_data[i].op);
12090 ok(SUCCEEDED(hr), "SetTextureStageState (%s) failed with 0x%08x\n", test_data[i].name, hr);
12092 hr = IDirect3DDevice9_BeginScene(device);
12093 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
12095 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12096 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
12098 hr = IDirect3DDevice9_EndScene(device);
12099 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
12101 color = getPixelColor(device, 320, 240);
12102 ok(color_match(color, test_data[i].result, 3), "Operation %s returned color 0x%08x, expected 0x%08x\n",
12103 test_data[i].name, color, test_data[i].result);
12105 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12106 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
12109 IDirect3DTexture9_Release(texture);
12110 IDirect3DVertexDeclaration9_Release(vertex_declaration);
12111 refcount = IDirect3DDevice9_Release(device);
12112 ok(!refcount, "Device has %u references left.\n", refcount);
12113 done:
12114 IDirect3D9_Release(d3d);
12115 DestroyWindow(window);
12118 static void yuv_color_test(void)
12120 HRESULT hr;
12121 IDirect3DSurface9 *surface, *target;
12122 unsigned int i;
12123 D3DLOCKED_RECT lr;
12124 IDirect3D9 *d3d;
12125 D3DCOLOR color;
12126 D3DFORMAT skip_once = D3DFMT_UNKNOWN;
12127 IDirect3DDevice9 *device;
12128 D3DSURFACE_DESC desc;
12129 ULONG refcount;
12130 HWND window;
12132 static const struct
12134 DWORD in;
12135 D3DFORMAT format;
12136 const char *fmt_string;
12137 D3DCOLOR left, right;
12139 test_data[] =
12141 {0x00000000, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00008700, 0x00008700},
12142 {0xff000000, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00008700, 0x004bff1c},
12143 {0x00ff0000, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00b30000, 0x00b30000},
12144 {0x0000ff00, D3DFMT_UYVY, "D3DFMT_UYVY", 0x004bff1c, 0x00008700},
12145 {0x000000ff, D3DFMT_UYVY, "D3DFMT_UYVY", 0x000030e1, 0x000030e1},
12146 {0xffff0000, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00b30000, 0x00ffd01c},
12147 {0xff00ff00, D3DFMT_UYVY, "D3DFMT_UYVY", 0x004bff1c, 0x004bff1c},
12148 {0xff0000ff, D3DFMT_UYVY, "D3DFMT_UYVY", 0x000030e1, 0x004bffff},
12149 {0x00ffff00, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00ffd01c, 0x00b30000},
12150 {0x00ff00ff, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00b300e1, 0x00b300e1},
12151 {0x0000ffff, D3DFMT_UYVY, "D3DFMT_UYVY", 0x004bffff, 0x001030e1},
12152 {0xffffff00, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00ffd01c, 0x00ffd01c},
12153 {0xffff00ff, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00b300e1, 0x00ff79ff},
12154 {0xffffffff, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00ff79ff, 0x00ff79ff},
12155 {0x4cff4c54, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00ff0000, 0x00ff0000},
12156 {0x00800080, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00000000, 0x00000000},
12157 {0xff80ff80, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00ffffff, 0x00ffffff},
12158 {0x1c6b1cff, D3DFMT_UYVY, "D3DFMT_UYVY", 0x000000fd, 0x000000fd},
12160 {0x00000000, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00008700, 0x00008700},
12161 {0xff000000, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00b30000, 0x00b30000},
12162 {0x00ff0000, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00008700, 0x004bff1c},
12163 {0x0000ff00, D3DFMT_YUY2, "D3DFMT_YUY2", 0x000030e1, 0x000030e1},
12164 {0x000000ff, D3DFMT_YUY2, "D3DFMT_YUY2", 0x004bff1c, 0x00008700},
12165 {0xffff0000, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00b30000, 0x00ffd01c},
12166 {0xff00ff00, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00b300e1, 0x00b300e1},
12167 {0xff0000ff, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00ffd01c, 0x00b30000},
12168 {0x00ffff00, D3DFMT_YUY2, "D3DFMT_YUY2", 0x000030e1, 0x004bffff},
12169 {0x00ff00ff, D3DFMT_YUY2, "D3DFMT_YUY2", 0x004bff1c, 0x004bff1c},
12170 {0x0000ffff, D3DFMT_YUY2, "D3DFMT_YUY2", 0x004bffff, 0x000030e1},
12171 {0xffffff00, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00b300e1, 0x00ff79ff},
12172 {0xffff00ff, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00ffd01c, 0x00ffd01c},
12173 {0xffffffff, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00ff79ff, 0x00ff79ff},
12174 {0x4cff4c54, D3DFMT_YUY2, "D3DFMT_YUY2", 0x000b8b00, 0x00b6ffa3},
12175 {0x00800080, D3DFMT_YUY2, "D3DFMT_YUY2", 0x0000ff00, 0x0000ff00},
12176 {0xff80ff80, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00ff00ff, 0x00ff00ff},
12177 {0x1c6b1cff, D3DFMT_YUY2, "D3DFMT_YUY2", 0x006dff45, 0x0000d500},
12180 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
12181 0, 0, 640, 480, NULL, NULL, NULL, NULL);
12182 d3d = Direct3DCreate9(D3D_SDK_VERSION);
12183 ok(!!d3d, "Failed to create a D3D object.\n");
12184 if (!(device = create_device(d3d, window, window, TRUE)))
12186 skip("Failed to create a D3D device, skipping tests.\n");
12187 goto done;
12190 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &target);
12191 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
12192 hr = IDirect3DSurface9_GetDesc(target, &desc);
12193 ok(SUCCEEDED(hr), "Failed to get surface description, hr %#x.\n", hr);
12195 for (i = 0; i < sizeof(test_data) / sizeof(test_data[0]); i++)
12197 /* Some(all?) Windows drivers do not support YUV 3D textures, only 2D surfaces in StretchRect.
12198 * Thus use StretchRect to draw the YUV surface onto the screen instead of drawPrimitive. */
12199 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
12200 D3DFMT_X8R8G8B8, 0, D3DRTYPE_SURFACE, test_data[i].format)))
12202 if (skip_once != test_data[i].format)
12204 skip("%s is not supported.\n", test_data[i].fmt_string);
12205 skip_once = test_data[i].format;
12207 continue;
12209 if (FAILED(IDirect3D9_CheckDeviceFormatConversion(d3d, 0,
12210 D3DDEVTYPE_HAL, test_data[i].format, desc.Format)))
12212 if (skip_once != test_data[i].format)
12214 skip("Driver cannot blit %s surfaces.\n", test_data[i].fmt_string);
12215 skip_once = test_data[i].format;
12217 continue;
12220 /* A pixel is effectively 16 bit large, but two pixels are stored together, so the minimum size is 2x1.
12221 * However, Nvidia Windows drivers have problems with 2x1 YUY2/UYVY surfaces, so use a 4x1 surface and
12222 * fill the second block with dummy data. If the surface has a size of 2x1, those drivers ignore the
12223 * second luminance value, resulting in an incorrect color in the right pixel. */
12224 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 4, 1, test_data[i].format,
12225 D3DPOOL_DEFAULT, &surface, NULL);
12226 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
12229 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
12230 ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
12231 ((DWORD *)lr.pBits)[0] = test_data[i].in;
12232 ((DWORD *)lr.pBits)[1] = 0x00800080;
12233 hr = IDirect3DSurface9_UnlockRect(surface);
12234 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
12236 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00000000, 1.0f, 0);
12237 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
12238 hr = IDirect3DDevice9_StretchRect(device, surface, NULL, target, NULL, D3DTEXF_POINT);
12239 ok(SUCCEEDED(hr), "Failed to draw surface onto backbuffer, hr %#x.\n", hr);
12241 /* Some Windows drivers (mostly Nvidia, but also some VM drivers) insist on doing linear filtering
12242 * although we asked for point filtering. Be careful when reading the results and use the pixel
12243 * centers. In the future we may want to add tests for the filtered pixels as well.
12245 * Unfortunately different implementations(Windows-Nvidia and Mac-AMD tested) interpret some colors
12246 * vastly differently, so we need a max diff of 18. */
12247 color = getPixelColor(device, 1, 240);
12248 ok(color_match(color, test_data[i].left, 18),
12249 "Input 0x%08x: Got color 0x%08x for pixel 1/1, expected 0x%08x, format %s.\n",
12250 test_data[i].in, color, test_data[i].left, test_data[i].fmt_string);
12251 color = getPixelColor(device, 318, 240);
12252 ok(color_match(color, test_data[i].right, 18),
12253 "Input 0x%08x: Got color 0x%08x for pixel 2/1, expected 0x%08x, format %s.\n",
12254 test_data[i].in, color, test_data[i].right, test_data[i].fmt_string);
12255 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12256 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
12257 IDirect3DSurface9_Release(surface);
12260 IDirect3DSurface9_Release(target);
12261 refcount = IDirect3DDevice9_Release(device);
12262 ok(!refcount, "Device has %u references left.\n", refcount);
12263 done:
12264 IDirect3D9_Release(d3d);
12265 DestroyWindow(window);
12268 static void yuv_layout_test(void)
12270 HRESULT hr;
12271 IDirect3DSurface9 *surface, *target;
12272 unsigned int fmt, i, x, y;
12273 D3DFORMAT format;
12274 const char *fmt_string;
12275 D3DLOCKED_RECT lr;
12276 IDirect3D9 *d3d;
12277 D3DCOLOR color;
12278 DWORD ref_color;
12279 BYTE *buf, *chroma_buf, *u_buf, *v_buf;
12280 UINT width = 20, height = 16;
12281 IDirect3DDevice9 *device;
12282 ULONG refcount;
12283 D3DCAPS9 caps;
12284 D3DSURFACE_DESC desc;
12285 HWND window;
12287 static const struct
12289 DWORD color1, color2;
12290 DWORD rgb1, rgb2;
12292 test_data[] =
12294 { 0x000000, 0xffffff, 0x00008800, 0x00ff7dff },
12295 { 0xff0000, 0x00ffff, 0x004aff14, 0x00b800ee },
12296 { 0x00ff00, 0xff00ff, 0x000024ee, 0x00ffe114 },
12297 { 0x0000ff, 0xffff00, 0x00b80000, 0x004affff },
12298 { 0xffff00, 0x0000ff, 0x004affff, 0x00b80000 },
12299 { 0xff00ff, 0x00ff00, 0x00ffe114, 0x000024ee },
12300 { 0x00ffff, 0xff0000, 0x00b800ee, 0x004aff14 },
12301 { 0xffffff, 0x000000, 0x00ff7dff, 0x00008800 },
12304 static const struct
12306 D3DFORMAT format;
12307 const char *str;
12309 formats[] =
12311 { D3DFMT_UYVY, "D3DFMT_UYVY", },
12312 { D3DFMT_YUY2, "D3DFMT_YUY2", },
12313 { MAKEFOURCC('Y','V','1','2'), "D3DFMT_YV12", },
12314 { MAKEFOURCC('N','V','1','2'), "D3DFMT_NV12", },
12317 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
12318 0, 0, 640, 480, NULL, NULL, NULL, NULL);
12319 d3d = Direct3DCreate9(D3D_SDK_VERSION);
12320 ok(!!d3d, "Failed to create a D3D object.\n");
12321 if (!(device = create_device(d3d, window, window, TRUE)))
12323 skip("Failed to create a D3D device, skipping tests.\n");
12324 goto done;
12327 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
12328 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
12329 if (caps.TextureCaps & D3DPTEXTURECAPS_POW2
12330 && !(caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL))
12332 skip("No NP2 texture support, skipping YUV texture layout test.\n");
12333 IDirect3DDevice9_Release(device);
12334 goto done;
12337 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &target);
12338 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr = %#x.\n", hr);
12339 hr = IDirect3DSurface9_GetDesc(target, &desc);
12340 ok(SUCCEEDED(hr), "Failed to get surface description, hr %#x.\n", hr);
12342 for (fmt = 0; fmt < sizeof(formats) / sizeof(formats[0]); fmt++)
12344 format = formats[fmt].format;
12345 fmt_string = formats[fmt].str;
12347 /* Some (all?) Windows drivers do not support YUV 3D textures, only 2D surfaces in
12348 * StretchRect. Thus use StretchRect to draw the YUV surface onto the screen instead
12349 * of drawPrimitive. */
12350 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
12351 D3DRTYPE_SURFACE, format) != D3D_OK)
12353 skip("%s is not supported.\n", fmt_string);
12354 continue;
12356 if (FAILED(IDirect3D9_CheckDeviceFormatConversion(d3d, 0,
12357 D3DDEVTYPE_HAL, format, desc.Format)))
12359 skip("Driver cannot blit %s surfaces.\n", fmt_string);
12360 continue;
12363 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, width, height, format, D3DPOOL_DEFAULT, &surface, NULL);
12364 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed, hr = %#x.\n", hr);
12366 for (i = 0; i < sizeof(test_data) / sizeof(test_data[0]); i++)
12368 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
12369 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr = %#x.\n", hr);
12370 buf = lr.pBits;
12371 chroma_buf = buf + lr.Pitch * height;
12372 if (format == MAKEFOURCC('Y','V','1','2'))
12374 v_buf = chroma_buf;
12375 u_buf = chroma_buf + height / 2 * lr.Pitch/2;
12377 /* Draw the top left quarter of the screen with color1, the rest with color2 */
12378 for (y = 0; y < height; y++)
12380 for (x = 0; x < width; x += 2)
12382 DWORD color = (x < width / 2 && y < height / 2) ? test_data[i].color1 : test_data[i].color2;
12383 BYTE Y = (color >> 16) & 0xff;
12384 BYTE U = (color >> 8) & 0xff;
12385 BYTE V = (color >> 0) & 0xff;
12386 if (format == D3DFMT_UYVY)
12388 buf[y * lr.Pitch + 2 * x + 0] = U;
12389 buf[y * lr.Pitch + 2 * x + 1] = Y;
12390 buf[y * lr.Pitch + 2 * x + 2] = V;
12391 buf[y * lr.Pitch + 2 * x + 3] = Y;
12393 else if (format == D3DFMT_YUY2)
12395 buf[y * lr.Pitch + 2 * x + 0] = Y;
12396 buf[y * lr.Pitch + 2 * x + 1] = U;
12397 buf[y * lr.Pitch + 2 * x + 2] = Y;
12398 buf[y * lr.Pitch + 2 * x + 3] = V;
12400 else if (format == MAKEFOURCC('Y','V','1','2'))
12402 buf[y * lr.Pitch + x + 0] = Y;
12403 buf[y * lr.Pitch + x + 1] = Y;
12404 u_buf[(y / 2) * (lr.Pitch / 2) + (x / 2)] = U;
12405 v_buf[(y / 2) * (lr.Pitch / 2) + (x / 2)] = V;
12407 else if (format == MAKEFOURCC('N','V','1','2'))
12409 buf[y * lr.Pitch + x + 0] = Y;
12410 buf[y * lr.Pitch + x + 1] = Y;
12411 chroma_buf[(y / 2) * lr.Pitch + 2 * (x / 2) + 0] = U;
12412 chroma_buf[(y / 2) * lr.Pitch + 2 * (x / 2) + 1] = V;
12416 hr = IDirect3DSurface9_UnlockRect(surface);
12417 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr = %#x.\n", hr);
12419 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00000000, 1.0f, 0);
12420 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %#x.\n", hr);
12421 hr = IDirect3DDevice9_StretchRect(device, surface, NULL, target, NULL, D3DTEXF_POINT);
12422 ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %#x.\n", hr);
12424 /* Some Windows drivers (mostly Nvidia, but also some VM drivers) insist on doing linear filtering
12425 * although we asked for point filtering. To prevent running into precision problems, read at points
12426 * with some margin within each quadrant.
12428 * Unfortunately different implementations(Windows-Nvidia and Mac-AMD tested) interpret some colors
12429 * vastly differently, so we need a max diff of 18. */
12430 for (y = 0; y < 4; y++)
12432 for (x = 0; x < 4; x++)
12434 UINT xcoord = (1 + 2 * x) * 640 / 8;
12435 UINT ycoord = (1 + 2 * y) * 480 / 8;
12436 ref_color = (y < 2 && x < 2) ? test_data[i].rgb1 : test_data[i].rgb2;
12437 color = getPixelColor(device, xcoord, ycoord);
12438 ok(color_match(color, ref_color, 18),
12439 "Format %s: Got color %#x for pixel (%d/%d)/(%d/%d), pixel %d %d, expected %#x.\n",
12440 fmt_string, color, x, 4, y, 4, xcoord, ycoord, ref_color);
12443 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12445 ok(SUCCEEDED(hr), "Present failed with %#x.\n", hr);
12447 IDirect3DSurface9_Release(surface);
12450 IDirect3DSurface9_Release(target);
12451 refcount = IDirect3DDevice9_Release(device);
12452 ok(!refcount, "Device has %u references left.\n", refcount);
12453 done:
12454 IDirect3D9_Release(d3d);
12455 DestroyWindow(window);
12458 static void texop_range_test(void)
12460 IDirect3DTexture9 *texture;
12461 D3DLOCKED_RECT locked_rect;
12462 IDirect3DDevice9 *device;
12463 IDirect3D9 *d3d;
12464 ULONG refcount;
12465 D3DCAPS9 caps;
12466 DWORD color;
12467 HWND window;
12468 HRESULT hr;
12470 static const struct
12472 float x, y, z;
12473 D3DCOLOR diffuse;
12475 quad[] =
12477 {-1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
12478 {-1.0f, 1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
12479 { 1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
12480 { 1.0f, 1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)}
12483 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
12484 0, 0, 640, 480, NULL, NULL, NULL, NULL);
12485 d3d = Direct3DCreate9(D3D_SDK_VERSION);
12486 ok(!!d3d, "Failed to create a D3D object.\n");
12487 if (!(device = create_device(d3d, window, window, TRUE)))
12489 skip("Failed to create a D3D device, skipping tests.\n");
12490 goto done;
12493 /* We need ADD and SUBTRACT operations */
12494 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
12495 ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
12496 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_ADD))
12498 skip("D3DTOP_ADD is not supported, skipping value range test.\n");
12499 IDirect3DDevice9_Release(device);
12500 goto done;
12502 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_SUBTRACT))
12504 skip("D3DTEXOPCAPS_SUBTRACT is not supported, skipping value range test.\n");
12505 IDirect3DDevice9_Release(device);
12506 goto done;
12509 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
12510 ok(SUCCEEDED(hr), "SetFVF failed with 0x%08x\n", hr);
12511 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
12512 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
12513 /* Stage 1: result = diffuse(=1.0) + diffuse
12514 * stage 2: result = result - tfactor(= 0.5)
12516 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
12517 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
12518 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
12519 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12520 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
12521 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12522 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
12523 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12524 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
12525 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12526 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_TFACTOR);
12527 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12528 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
12529 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12531 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
12532 ok(SUCCEEDED(hr), "Failed to clear device, hr %#x.\n\n", hr);
12533 hr = IDirect3DDevice9_BeginScene(device);
12534 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
12535 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12536 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
12537 hr = IDirect3DDevice9_EndScene(device);
12538 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
12540 color = getPixelColor(device, 320, 240);
12541 ok(color_match(color, 0x00808080, 1), "texop Range > 1.0 returned 0x%08x, expected 0x00808080\n",
12542 color);
12543 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12544 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
12546 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
12547 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
12548 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
12549 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
12550 *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00);
12551 hr = IDirect3DTexture9_UnlockRect(texture, 0);
12552 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
12553 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
12554 ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
12556 /* Stage 1: result = texture(=0.0) - tfactor(= 0.5)
12557 * stage 2: result = result + diffuse(1.0)
12559 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
12560 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
12561 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
12562 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12563 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
12564 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12565 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
12566 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12567 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
12568 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12569 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
12570 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12571 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
12572 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12574 hr = IDirect3DDevice9_BeginScene(device);
12575 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
12576 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12577 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
12578 hr = IDirect3DDevice9_EndScene(device);
12579 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
12581 color = getPixelColor(device, 320, 240);
12582 ok(color_match(color, 0x00ffffff, 1), "texop Range < 0.0 returned 0x%08x, expected 0x00ffffff\n",
12583 color);
12584 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12585 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
12587 IDirect3DTexture9_Release(texture);
12588 refcount = IDirect3DDevice9_Release(device);
12589 ok(!refcount, "Device has %u references left.\n", refcount);
12590 done:
12591 IDirect3D9_Release(d3d);
12592 DestroyWindow(window);
12595 static void alphareplicate_test(void)
12597 IDirect3DDevice9 *device;
12598 IDirect3D9 *d3d;
12599 ULONG refcount;
12600 DWORD color;
12601 HWND window;
12602 HRESULT hr;
12604 static const struct
12606 struct vec3 position;
12607 DWORD diffuse;
12609 quad[] =
12611 {{-1.0f, -1.0f, 0.1f}, 0x80ff00ff},
12612 {{-1.0f, 1.0f, 0.1f}, 0x80ff00ff},
12613 {{ 1.0f, -1.0f, 0.1f}, 0x80ff00ff},
12614 {{ 1.0f, 1.0f, 0.1f}, 0x80ff00ff},
12617 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
12618 0, 0, 640, 480, NULL, NULL, NULL, NULL);
12619 d3d = Direct3DCreate9(D3D_SDK_VERSION);
12620 ok(!!d3d, "Failed to create a D3D object.\n");
12621 if (!(device = create_device(d3d, window, window, TRUE)))
12623 skip("Failed to create a D3D device, skipping tests.\n");
12624 goto done;
12627 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
12628 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
12630 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
12631 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
12633 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
12634 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
12635 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
12636 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
12638 hr = IDirect3DDevice9_BeginScene(device);
12639 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
12640 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12641 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
12642 hr = IDirect3DDevice9_EndScene(device);
12643 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
12645 color = getPixelColor(device, 320, 240);
12646 ok(color_match(color, 0x00808080, 1), "alphareplicate test 0x%08x, expected 0x00808080\n",
12647 color);
12648 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12649 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
12651 refcount = IDirect3DDevice9_Release(device);
12652 ok(!refcount, "Device has %u references left.\n", refcount);
12653 done:
12654 IDirect3D9_Release(d3d);
12655 DestroyWindow(window);
12658 static void dp3_alpha_test(void)
12660 IDirect3DDevice9 *device;
12661 IDirect3D9 *d3d;
12662 ULONG refcount;
12663 D3DCAPS9 caps;
12664 DWORD color;
12665 HWND window;
12666 HRESULT hr;
12668 static const struct
12670 struct vec3 position;
12671 DWORD diffuse;
12673 quad[] =
12675 {{-1.0f, -1.0f, 0.1f}, 0x408080c0},
12676 {{-1.0f, 1.0f, 0.1f}, 0x408080c0},
12677 {{ 1.0f, -1.0f, 0.1f}, 0x408080c0},
12678 {{ 1.0f, 1.0f, 0.1f}, 0x408080c0},
12681 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
12682 0, 0, 640, 480, NULL, NULL, NULL, NULL);
12683 d3d = Direct3DCreate9(D3D_SDK_VERSION);
12684 ok(!!d3d, "Failed to create a D3D object.\n");
12685 if (!(device = create_device(d3d, window, window, TRUE)))
12687 skip("Failed to create a D3D device, skipping tests.\n");
12688 goto done;
12691 memset(&caps, 0, sizeof(caps));
12692 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
12693 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
12694 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_DOTPRODUCT3))
12696 skip("D3DTOP_DOTPRODUCT3 not supported\n");
12697 IDirect3DDevice9_Release(device);
12698 goto done;
12701 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
12702 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
12704 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
12705 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
12707 /* dp3_x4 r0, diffuse_bias, tfactor_bias
12708 * mov r0.a, diffuse.a
12709 * mov r0, r0.a
12711 * It turns out that the 2nd line is ignored, and the dp3 result written into r0.a instead
12712 * thus with input vec4(0.5, 0.5, 0.75, 0.25) and vec4(1.0, 1.0, 1.0, 1.0) the result is
12713 * (0.0 * 0.5 + 0.0 * 0.5 + 0.25 * 0.5) * 4 = 0.125 * 4 = 0.5, with a bunch of inprecision.
12715 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DOTPRODUCT3);
12716 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
12717 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
12718 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
12719 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
12720 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
12721 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
12722 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
12723 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
12724 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
12725 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
12726 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
12727 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT | D3DTA_ALPHAREPLICATE);
12728 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
12729 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
12730 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
12731 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xffffffff);
12732 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
12733 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
12734 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
12736 hr = IDirect3DDevice9_BeginScene(device);
12737 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
12738 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12739 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
12740 hr = IDirect3DDevice9_EndScene(device);
12741 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
12743 color = getPixelColor(device, 320, 240);
12744 ok(color_match(color, 0x00808080, 4), "dp3 alpha test 0x%08x, expected 0x00808080\n",
12745 color);
12746 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12747 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
12749 refcount = IDirect3DDevice9_Release(device);
12750 ok(!refcount, "Device has %u references left.\n", refcount);
12751 done:
12752 IDirect3D9_Release(d3d);
12753 DestroyWindow(window);
12756 static void zwriteenable_test(void)
12758 IDirect3DDevice9 *device;
12759 IDirect3D9 *d3d;
12760 D3DCOLOR color;
12761 ULONG refcount;
12762 HWND window;
12763 HRESULT hr;
12765 static const struct
12767 struct vec3 position;
12768 DWORD diffuse;
12770 quad1[] =
12772 {{-1.0f, -1.0f, 0.1f}, 0x00ff0000},
12773 {{-1.0f, 1.0f, 0.1f}, 0x00ff0000},
12774 {{ 1.0f, -1.0f, 0.1f}, 0x00ff0000},
12775 {{ 1.0f, 1.0f, 0.1f}, 0x00ff0000},
12777 quad2[] =
12779 {{-1.0f, -1.0f, 0.9f}, 0x0000ff00},
12780 {{-1.0f, 1.0f, 0.9f}, 0x0000ff00},
12781 {{ 1.0f, -1.0f, 0.9f}, 0x0000ff00},
12782 {{ 1.0f, 1.0f, 0.9f}, 0x0000ff00},
12785 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
12786 0, 0, 640, 480, NULL, NULL, NULL, NULL);
12787 d3d = Direct3DCreate9(D3D_SDK_VERSION);
12788 ok(!!d3d, "Failed to create a D3D object.\n");
12789 if (!(device = create_device(d3d, window, window, TRUE)))
12791 skip("Failed to create a D3D device, skipping tests.\n");
12792 goto done;
12795 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
12796 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
12798 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
12799 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
12800 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
12801 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
12802 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
12803 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
12804 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
12805 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
12806 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
12807 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
12809 hr = IDirect3DDevice9_BeginScene(device);
12810 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
12811 /* The Z buffer is filled with 1.0. Draw a red quad with z = 0.1,
12812 * zenable = D3DZB_FALSE, zwriteenable = TRUE. The red color is written
12813 * because the z test is disabled. The question is whether the z = 0.1
12814 * values are written into the Z buffer. After the draw, set
12815 * zenable = TRUE and draw a green quad at z = 0.9. If the values are
12816 * written, the z test will fail(0.9 > 0.1) and the red color remains. If
12817 * the values are not written, the z test succeeds(0.9 < 1.0) and the
12818 * green color is written. It turns out that the screen is green, so
12819 * zenable = D3DZB_FALSE and zwriteenable = TRUE does NOT write to the z
12820 * buffer. */
12821 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
12822 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
12823 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
12824 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
12825 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
12826 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
12827 hr = IDirect3DDevice9_EndScene(device);
12828 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
12830 color = getPixelColor(device, 320, 240);
12831 ok(color_match(color, 0x0000ff00, 1), "zwriteenable test returned 0x%08x, expected 0x0000ff00\n",
12832 color);
12833 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12834 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
12836 refcount = IDirect3DDevice9_Release(device);
12837 ok(!refcount, "Device has %u references left.\n", refcount);
12838 done:
12839 IDirect3D9_Release(d3d);
12840 DestroyWindow(window);
12843 static void alphatest_test(void)
12845 #define ALPHATEST_PASSED 0x0000ff00
12846 #define ALPHATEST_FAILED 0x00ff0000
12847 IDirect3DDevice9 *device;
12848 unsigned int i, j;
12849 IDirect3D9 *d3d;
12850 D3DCOLOR color;
12851 ULONG refcount;
12852 D3DCAPS9 caps;
12853 HWND window;
12854 HRESULT hr;
12856 static const struct
12858 D3DCMPFUNC func;
12859 D3DCOLOR color_less;
12860 D3DCOLOR color_equal;
12861 D3DCOLOR color_greater;
12863 testdata[] =
12865 {D3DCMP_NEVER, ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_FAILED},
12866 {D3DCMP_LESS, ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_FAILED},
12867 {D3DCMP_EQUAL, ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_FAILED},
12868 {D3DCMP_LESSEQUAL, ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_FAILED},
12869 {D3DCMP_GREATER, ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_PASSED},
12870 {D3DCMP_NOTEQUAL, ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_PASSED},
12871 {D3DCMP_GREATEREQUAL, ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_PASSED},
12872 {D3DCMP_ALWAYS, ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_PASSED},
12874 static const struct
12876 struct vec3 position;
12877 DWORD diffuse;
12879 quad[] =
12881 {{-1.0f, -1.0f, 0.1f}, ALPHATEST_PASSED | 0x80000000},
12882 {{-1.0f, 1.0f, 0.1f}, ALPHATEST_PASSED | 0x80000000},
12883 {{ 1.0f, -1.0f, 0.1f}, ALPHATEST_PASSED | 0x80000000},
12884 {{ 1.0f, 1.0f, 0.1f}, ALPHATEST_PASSED | 0x80000000},
12887 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
12888 0, 0, 640, 480, NULL, NULL, NULL, NULL);
12889 d3d = Direct3DCreate9(D3D_SDK_VERSION);
12890 ok(!!d3d, "Failed to create a D3D object.\n");
12891 if (!(device = create_device(d3d, window, window, TRUE)))
12893 skip("Failed to create a D3D device, skipping tests.\n");
12894 goto done;
12897 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
12898 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
12900 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
12901 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
12902 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, TRUE);
12903 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
12904 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
12905 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
12907 for (j = 0; j < 2; ++j)
12909 if (j == 1)
12911 /* Try a pixel shader instead of fixed function. The wined3d code
12912 * may emulate the alpha test either for performance reasons
12913 * (floating point RTs) or to work around driver bugs (GeForce
12914 * 7x00 cards on MacOS). There may be a different codepath for ffp
12915 * and shader in this case, and the test should cover both. */
12916 IDirect3DPixelShader9 *ps;
12917 static const DWORD shader_code[] =
12919 0xffff0101, /* ps_1_1 */
12920 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
12921 0x0000ffff /* end */
12923 memset(&caps, 0, sizeof(caps));
12924 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
12925 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with 0x%08x\n", hr);
12926 if(caps.PixelShaderVersion < D3DPS_VERSION(1, 1)) {
12927 break;
12930 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &ps);
12931 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with 0x%08x\n", hr);
12932 hr = IDirect3DDevice9_SetPixelShader(device, ps);
12933 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with 0x%08x\n", hr);
12934 IDirect3DPixelShader9_Release(ps);
12937 for(i = 0; i < (sizeof(testdata)/sizeof(testdata[0])); i++) {
12938 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAFUNC, testdata[i].func);
12939 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
12941 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
12942 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
12943 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x90);
12944 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
12945 hr = IDirect3DDevice9_BeginScene(device);
12946 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
12947 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12948 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
12949 hr = IDirect3DDevice9_EndScene(device);
12950 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
12951 color = getPixelColor(device, 320, 240);
12952 ok(color_match(color, testdata[i].color_less, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha < ref, func %u\n",
12953 color, testdata[i].color_less, testdata[i].func);
12954 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12955 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
12957 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
12958 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
12959 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x80);
12960 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
12961 hr = IDirect3DDevice9_BeginScene(device);
12962 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
12963 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12964 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
12965 hr = IDirect3DDevice9_EndScene(device);
12966 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
12967 color = getPixelColor(device, 320, 240);
12968 ok(color_match(color, testdata[i].color_equal, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha == ref, func %u\n",
12969 color, testdata[i].color_equal, testdata[i].func);
12970 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12971 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
12973 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
12974 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
12975 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x70);
12976 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
12977 hr = IDirect3DDevice9_BeginScene(device);
12978 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
12979 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12980 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
12981 hr = IDirect3DDevice9_EndScene(device);
12982 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
12983 color = getPixelColor(device, 320, 240);
12984 ok(color_match(color, testdata[i].color_greater, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha > ref, func %u\n",
12985 color, testdata[i].color_greater, testdata[i].func);
12986 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12987 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
12991 refcount = IDirect3DDevice9_Release(device);
12992 ok(!refcount, "Device has %u references left.\n", refcount);
12993 done:
12994 IDirect3D9_Release(d3d);
12995 DestroyWindow(window);
12998 static void sincos_test(void)
13000 IDirect3DVertexShader9 *sin_shader, *cos_shader;
13001 IDirect3DDevice9 *device;
13002 struct vec3 data[1280];
13003 IDirect3D9 *d3d;
13004 unsigned int i;
13005 ULONG refcount;
13006 D3DCAPS9 caps;
13007 HWND window;
13008 HRESULT hr;
13010 static const DWORD sin_shader_code[] =
13012 0xfffe0200, /* vs_2_0 */
13013 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
13014 0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a, /* def c2, 3.14159, 1, 0, 0.85 */
13015 0x03000005, 0x80010001, 0x90000000, 0xa0000002, /* mul r1.x, v0.x, c2.x */
13016 0x04000025, 0x80020000, 0x80000001, 0xa0e40000, 0xa0e40001, /* sincos r0.y, r1.x, c0, c1 */
13017 0x02000001, 0xc00d0000, 0x90e40000, /* mov oPos.xzw, v0 */
13018 0x03000005, 0xc0020000, 0x80550000, 0xa0ff0002, /* mul oPos.y, r0.y, c2.w */
13019 0x02000001, 0xd00f0000, 0xa0a60002, /* mov oD0, c2.zyzz */
13020 0x0000ffff /* end */
13022 static const DWORD cos_shader_code[] =
13024 0xfffe0200, /* vs_2_0 */
13025 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
13026 0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a, /* def c2, 3.14159, 1, 0, 0.85 */
13027 0x03000005, 0x80010001, 0x90000000, 0xa0000002, /* mul r1.x, v0.x, c2.x */
13028 0x04000025, 0x80010000, 0x80000001, 0xa0e40000, 0xa0e40001, /* sincos r0.x, r1.x, c0, c1 */
13029 0x02000001, 0xc00d0000, 0x90e40000, /* mov oPos.xzw, v0 */
13030 0x03000005, 0xc0020000, 0x80000000, 0xa0ff0002, /* mul oPos.y, r0.x, c2.w */
13031 0x02000001, 0xd00f0000, 0xa0a90002, /* mov oD0, c2.yzzz */
13032 0x0000ffff /* end */
13034 static const float sincosc1[4] = {D3DSINCOSCONST1};
13035 static const float sincosc2[4] = {D3DSINCOSCONST2};
13037 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
13038 0, 0, 640, 480, NULL, NULL, NULL, NULL);
13039 d3d = Direct3DCreate9(D3D_SDK_VERSION);
13040 ok(!!d3d, "Failed to create a D3D object.\n");
13041 if (!(device = create_device(d3d, window, window, TRUE)))
13043 skip("Failed to create a D3D device, skipping tests.\n");
13044 goto done;
13047 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
13048 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
13049 if (caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
13051 skip("No vs_2_0 support, skipping tests.\n");
13052 IDirect3DDevice9_Release(device);
13053 goto done;
13056 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
13057 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
13059 hr = IDirect3DDevice9_CreateVertexShader(device, sin_shader_code, &sin_shader);
13060 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
13061 hr = IDirect3DDevice9_CreateVertexShader(device, cos_shader_code, &cos_shader);
13062 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
13063 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
13064 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
13065 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, sincosc1, 1);
13066 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
13067 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, sincosc2, 1);
13068 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
13070 /* Generate a point from -1 to 1 every 0.5 pixels */
13071 for(i = 0; i < 1280; i++) {
13072 data[i].x = (-640.0 + i) / 640.0;
13073 data[i].y = 0.0;
13074 data[i].z = 0.1;
13077 hr = IDirect3DDevice9_BeginScene(device);
13078 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
13080 hr = IDirect3DDevice9_SetVertexShader(device, sin_shader);
13081 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
13082 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
13083 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
13085 hr = IDirect3DDevice9_SetVertexShader(device, cos_shader);
13086 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
13087 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
13088 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
13090 hr = IDirect3DDevice9_EndScene(device);
13091 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
13093 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13094 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present returned %#x.\n", hr);
13095 /* TODO: Find a way to properly validate the lines. Precicion issues make this a kinda nasty task */
13097 IDirect3DVertexShader9_Release(sin_shader);
13098 IDirect3DVertexShader9_Release(cos_shader);
13099 refcount = IDirect3DDevice9_Release(device);
13100 ok(!refcount, "Device has %u references left.\n", refcount);
13101 done:
13102 IDirect3D9_Release(d3d);
13103 DestroyWindow(window);
13106 static void loop_index_test(void)
13108 IDirect3DVertexShader9 *shader;
13109 IDirect3DDevice9 *device;
13110 IDirect3D9 *d3d;
13111 float values[4];
13112 ULONG refcount;
13113 D3DCAPS9 caps;
13114 DWORD color;
13115 HWND window;
13116 HRESULT hr;
13118 static const DWORD shader_code[] =
13120 0xfffe0200, /* vs_2_0 */
13121 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
13122 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
13123 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
13124 0x04000002, 0x800f0000, 0x80e40000, 0xa0e42001, 0xf0e40800, /* add r0, r0, c[aL + 1] */
13125 0x0000001d, /* endloop */
13126 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
13127 0x02000001, 0xd00f0000, 0x80e40000, /* mov oD0, r0 */
13128 0x0000ffff /* END */
13130 static const float quad[] =
13132 -1.0f, -1.0f, 0.1f,
13133 -1.0f, 1.0f, 0.1f,
13134 1.0f, -1.0f, 0.1f,
13135 1.0f, 1.0f, 0.1f,
13137 static const float zero[4] = {0.0f, 0.0f, 0.0f, 0.0f};
13138 static const float one[4] = {1.0f, 1.0f, 1.0f, 1.0f};
13139 static const int i0[4] = {2, 10, -3, 0};
13141 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
13142 0, 0, 640, 480, NULL, NULL, NULL, NULL);
13143 d3d = Direct3DCreate9(D3D_SDK_VERSION);
13144 ok(!!d3d, "Failed to create a D3D object.\n");
13145 if (!(device = create_device(d3d, window, window, TRUE)))
13147 skip("Failed to create a D3D device, skipping tests.\n");
13148 goto done;
13151 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
13152 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
13153 if (caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
13155 skip("No vs_2_0 support, skipping tests.\n");
13156 IDirect3DDevice9_Release(device);
13157 goto done;
13160 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
13161 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
13162 hr = IDirect3DDevice9_SetVertexShader(device, shader);
13163 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
13164 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
13165 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
13166 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff0000, 1.0f, 0);
13167 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
13169 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, zero, 1);
13170 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13171 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, one, 1);
13172 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13173 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, one, 1);
13174 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13175 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 3, one, 1);
13176 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13177 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 4, one, 1);
13178 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13179 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 5, one, 1);
13180 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13181 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 6, one, 1);
13182 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13183 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, one, 1);
13184 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13185 values[0] = 1.0;
13186 values[1] = 1.0;
13187 values[2] = 0.0;
13188 values[3] = 0.0;
13189 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 8, values, 1);
13190 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13191 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 9, one, 1);
13192 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13193 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 10, one, 1);
13194 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13195 values[0] = -1.0;
13196 values[1] = 0.0;
13197 values[2] = 0.0;
13198 values[3] = 0.0;
13199 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 11, values, 1);
13200 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13201 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 12, one, 1);
13202 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13203 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 13, one, 1);
13204 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13205 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 14, one, 1);
13206 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13207 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 15, one, 1);
13208 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13210 hr = IDirect3DDevice9_SetVertexShaderConstantI(device, 0, i0, 1);
13211 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantI returned %#x.\n", hr);
13213 hr = IDirect3DDevice9_BeginScene(device);
13214 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
13215 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
13216 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
13217 hr = IDirect3DDevice9_EndScene(device);
13218 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
13219 color = getPixelColor(device, 320, 240);
13220 ok(color_match(color, 0x0000ff00, 1),
13221 "aL indexing test returned color 0x%08x, expected 0x0000ff00\n", color);
13222 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13223 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
13225 IDirect3DVertexShader9_Release(shader);
13226 refcount = IDirect3DDevice9_Release(device);
13227 ok(!refcount, "Device has %u references left.\n", refcount);
13228 done:
13229 IDirect3D9_Release(d3d);
13230 DestroyWindow(window);
13233 static void sgn_test(void)
13235 IDirect3DVertexShader9 *shader;
13236 IDirect3DDevice9 *device;
13237 IDirect3D9 *d3d;
13238 ULONG refcount;
13239 D3DCAPS9 caps;
13240 DWORD color;
13241 HWND window;
13242 HRESULT hr;
13244 static const DWORD shader_code[] =
13246 0xfffe0200, /* vs_2_0 */
13247 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position o0 */
13248 0x05000051, 0xa00f0000, 0xbf000000, 0x00000000, 0x3f000000, 0x41400000, /* def c0, -0.5, 0.0, 0.5, 12.0 */
13249 0x05000051, 0xa00f0001, 0x3fc00000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.5, 0.0, 0.0, 0.0 */
13250 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
13251 0x04000022, 0x800f0000, 0xa0e40000, 0x80e40001, 0x80e40002, /* sgn r0, c0, r1, r2 */
13252 0x03000002, 0xd00f0000, 0x80e40000, 0xa0e40001, /* add oD0, r0, c1 */
13253 0x0000ffff /* end */
13255 static const float quad[] =
13257 -1.0f, -1.0f, 0.1f,
13258 -1.0f, 1.0f, 0.1f,
13259 1.0f, -1.0f, 0.1f,
13260 1.0f, 1.0f, 0.1f,
13263 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
13264 0, 0, 640, 480, NULL, NULL, NULL, NULL);
13265 d3d = Direct3DCreate9(D3D_SDK_VERSION);
13266 ok(!!d3d, "Failed to create a D3D object.\n");
13267 if (!(device = create_device(d3d, window, window, TRUE)))
13269 skip("Failed to create a D3D device, skipping tests.\n");
13270 goto done;
13273 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
13274 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
13275 if (caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
13277 skip("No vs_2_0 support, skipping tests.\n");
13278 IDirect3DDevice9_Release(device);
13279 goto done;
13282 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
13283 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
13284 hr = IDirect3DDevice9_SetVertexShader(device, shader);
13285 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
13286 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
13287 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
13288 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff0000, 1.0f, 0);
13289 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
13291 hr = IDirect3DDevice9_BeginScene(device);
13292 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
13293 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
13294 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
13295 hr = IDirect3DDevice9_EndScene(device);
13296 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
13297 color = getPixelColor(device, 320, 240);
13298 ok(color_match(color, 0x008000ff, 1),
13299 "sgn test returned color 0x%08x, expected 0x008000ff\n", color);
13300 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13301 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
13303 IDirect3DVertexShader9_Release(shader);
13304 refcount = IDirect3DDevice9_Release(device);
13305 ok(!refcount, "Device has %u references left.\n", refcount);
13306 done:
13307 IDirect3D9_Release(d3d);
13308 DestroyWindow(window);
13311 static void viewport_test(void)
13313 IDirect3DDevice9 *device;
13314 BOOL draw_failed = TRUE;
13315 D3DVIEWPORT9 vp;
13316 IDirect3D9 *d3d;
13317 ULONG refcount;
13318 DWORD color;
13319 HWND window;
13320 HRESULT hr;
13322 static const float quad[] =
13324 -0.5f, -0.5f, 0.1f,
13325 -0.5f, 0.5f, 0.1f,
13326 0.5f, -0.5f, 0.1f,
13327 0.5f, 0.5f, 0.1f,
13330 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
13331 0, 0, 640, 480, NULL, NULL, NULL, NULL);
13332 d3d = Direct3DCreate9(D3D_SDK_VERSION);
13333 ok(!!d3d, "Failed to create a D3D object.\n");
13334 if (!(device = create_device(d3d, window, window, TRUE)))
13336 skip("Failed to create a D3D device, skipping tests.\n");
13337 goto done;
13340 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff0000, 1.0f, 0);
13341 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
13343 /* Test a viewport with Width and Height bigger than the surface dimensions
13345 * TODO: Test Width < surface.width, but X + Width > surface.width
13346 * TODO: Test Width < surface.width, what happens with the height?
13348 * The expected behavior is that the viewport behaves like the "default"
13349 * viewport with X = Y = 0, Width = surface_width, Height = surface_height,
13350 * MinZ = 0.0, MaxZ = 1.0.
13352 * Starting with Windows 7 the behavior among driver versions is not
13353 * consistent. The SetViewport call is accepted on all drivers. Some
13354 * drivers(older nvidia ones) refuse to draw and return an error. Newer
13355 * nvidia drivers draw, but use the actual values in the viewport and only
13356 * display the upper left part on the surface.
13358 memset(&vp, 0, sizeof(vp));
13359 vp.X = 0;
13360 vp.Y = 0;
13361 vp.Width = 10000;
13362 vp.Height = 10000;
13363 vp.MinZ = 0.0;
13364 vp.MaxZ = 0.0;
13365 hr = IDirect3DDevice9_SetViewport(device, &vp);
13366 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
13368 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
13369 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
13371 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
13372 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
13373 hr = IDirect3DDevice9_BeginScene(device);
13374 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
13375 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
13376 ok(hr == D3D_OK || broken(hr == D3DERR_INVALIDCALL), "Got unexpected hr %#x.\n", hr);
13377 draw_failed = FAILED(hr);
13378 hr = IDirect3DDevice9_EndScene(device);
13379 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
13381 if(!draw_failed)
13383 color = getPixelColor(device, 158, 118);
13384 ok(color == 0x00ff0000, "viewport test: (158,118) has color %08x\n", color);
13385 color = getPixelColor(device, 162, 118);
13386 ok(color == 0x00ff0000, "viewport test: (162,118) has color %08x\n", color);
13387 color = getPixelColor(device, 158, 122);
13388 ok(color == 0x00ff0000, "viewport test: (158,122) has color %08x\n", color);
13389 color = getPixelColor(device, 162, 122);
13390 ok(color == 0x00ffffff || broken(color == 0x00ff0000), "viewport test: (162,122) has color %08x\n", color);
13392 color = getPixelColor(device, 478, 358);
13393 ok(color == 0x00ffffff || broken(color == 0x00ff0000), "viewport test: (478,358 has color %08x\n", color);
13394 color = getPixelColor(device, 482, 358);
13395 ok(color == 0x00ff0000, "viewport test: (482,358) has color %08x\n", color);
13396 color = getPixelColor(device, 478, 362);
13397 ok(color == 0x00ff0000, "viewport test: (478,362) has color %08x\n", color);
13398 color = getPixelColor(device, 482, 362);
13399 ok(color == 0x00ff0000, "viewport test: (482,362) has color %08x\n", color);
13402 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13403 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
13405 refcount = IDirect3DDevice9_Release(device);
13406 ok(!refcount, "Device has %u references left.\n", refcount);
13407 done:
13408 IDirect3D9_Release(d3d);
13409 DestroyWindow(window);
13412 /* This test tests depth clamping / clipping behaviour:
13413 * - With software vertex processing, depth values are clamped to the
13414 * minimum / maximum z value when D3DRS_CLIPPING is disabled, and clipped
13415 * when D3DRS_CLIPPING is enabled. Pretransformed vertices behave the
13416 * same as regular vertices here.
13417 * - With hardware vertex processing, D3DRS_CLIPPING seems to be ignored.
13418 * Normal vertices are always clipped. Pretransformed vertices are
13419 * clipped when D3DPMISCCAPS_CLIPTLVERTS is set, clamped when it isn't.
13420 * - The viewport's MinZ/MaxZ is irrelevant for this.
13422 static void depth_clamp_test(void)
13424 IDirect3DDevice9 *device;
13425 D3DVIEWPORT9 vp;
13426 IDirect3D9 *d3d;
13427 D3DCOLOR color;
13428 ULONG refcount;
13429 D3DCAPS9 caps;
13430 HWND window;
13431 HRESULT hr;
13433 static const struct
13435 struct vec4 position;
13436 DWORD diffuse;
13438 quad1[] =
13440 {{ 0.0f, 0.0f, 5.0f, 1.0f}, 0xff002b7f},
13441 {{640.0f, 0.0f, 5.0f, 1.0f}, 0xff002b7f},
13442 {{ 0.0f, 480.0f, 5.0f, 1.0f}, 0xff002b7f},
13443 {{640.0f, 480.0f, 5.0f, 1.0f}, 0xff002b7f},
13445 quad2[] =
13447 {{ 0.0f, 300.0f, 10.0f, 1.0f}, 0xfff9e814},
13448 {{640.0f, 300.0f, 10.0f, 1.0f}, 0xfff9e814},
13449 {{ 0.0f, 360.0f, 10.0f, 1.0f}, 0xfff9e814},
13450 {{640.0f, 360.0f, 10.0f, 1.0f}, 0xfff9e814},
13452 quad3[] =
13454 {{112.0f, 108.0f, 5.0f, 1.0f}, 0xffffffff},
13455 {{208.0f, 108.0f, 5.0f, 1.0f}, 0xffffffff},
13456 {{112.0f, 204.0f, 5.0f, 1.0f}, 0xffffffff},
13457 {{208.0f, 204.0f, 5.0f, 1.0f}, 0xffffffff},
13459 quad4[] =
13461 {{ 42.0f, 41.0f, 10.0f, 1.0f}, 0xffffffff},
13462 {{112.0f, 41.0f, 10.0f, 1.0f}, 0xffffffff},
13463 {{ 42.0f, 108.0f, 10.0f, 1.0f}, 0xffffffff},
13464 {{112.0f, 108.0f, 10.0f, 1.0f}, 0xffffffff},
13466 static const struct
13468 struct vec3 position;
13469 DWORD diffuse;
13471 quad5[] =
13473 {{-0.5f, 0.5f, 10.0f}, 0xff14f914},
13474 {{ 0.5f, 0.5f, 10.0f}, 0xff14f914},
13475 {{-0.5f, -0.5f, 10.0f}, 0xff14f914},
13476 {{ 0.5f, -0.5f, 10.0f}, 0xff14f914},
13478 quad6[] =
13480 {{-1.0f, 0.5f, 10.0f}, 0xfff91414},
13481 {{ 1.0f, 0.5f, 10.0f}, 0xfff91414},
13482 {{-1.0f, 0.25f, 10.0f}, 0xfff91414},
13483 {{ 1.0f, 0.25f, 10.0f}, 0xfff91414},
13486 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
13487 0, 0, 640, 480, NULL, NULL, NULL, NULL);
13488 d3d = Direct3DCreate9(D3D_SDK_VERSION);
13489 ok(!!d3d, "Failed to create a D3D object.\n");
13490 if (!(device = create_device(d3d, window, window, TRUE)))
13492 skip("Failed to create a D3D device, skipping tests.\n");
13493 goto done;
13496 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
13497 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
13499 vp.X = 0;
13500 vp.Y = 0;
13501 vp.Width = 640;
13502 vp.Height = 480;
13503 vp.MinZ = 0.0;
13504 vp.MaxZ = 7.5;
13506 hr = IDirect3DDevice9_SetViewport(device, &vp);
13507 if(FAILED(hr))
13509 /* Windows 7 rejects MaxZ > 1.0, Windows XP allows it. This doesn't break
13510 * the tests because the 7.5 is just intended to show that it doesn't have
13511 * any influence on the drawing or D3DRS_CLIPPING = FALSE. Set an accepted
13512 * viewport and continue.
13514 ok(broken(hr == D3DERR_INVALIDCALL), "D3D rejected maxZ > 1.0\n");
13515 vp.MaxZ = 1.0;
13516 hr = IDirect3DDevice9_SetViewport(device, &vp);
13518 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
13520 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0, 0);
13521 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
13523 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
13524 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13525 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
13526 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13527 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13528 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13529 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
13530 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13532 hr = IDirect3DDevice9_BeginScene(device);
13533 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13535 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
13536 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
13538 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
13539 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13540 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
13541 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13543 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
13544 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13546 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
13547 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13548 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(*quad4));
13549 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13551 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
13552 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13554 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
13555 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
13557 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad5, sizeof(*quad5));
13558 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13560 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
13561 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13563 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad6, sizeof(*quad6));
13564 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13566 hr = IDirect3DDevice9_EndScene(device);
13567 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13569 if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
13571 color = getPixelColor(device, 75, 75);
13572 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
13573 color = getPixelColor(device, 150, 150);
13574 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
13575 color = getPixelColor(device, 320, 240);
13576 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
13577 color = getPixelColor(device, 320, 330);
13578 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
13579 color = getPixelColor(device, 320, 330);
13580 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
13582 else
13584 color = getPixelColor(device, 75, 75);
13585 ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
13586 color = getPixelColor(device, 150, 150);
13587 ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
13588 color = getPixelColor(device, 320, 240);
13589 ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);
13590 color = getPixelColor(device, 320, 330);
13591 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
13592 color = getPixelColor(device, 320, 330);
13593 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
13596 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13597 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
13599 refcount = IDirect3DDevice9_Release(device);
13600 ok(!refcount, "Device has %u references left.\n", refcount);
13601 done:
13602 IDirect3D9_Release(d3d);
13603 DestroyWindow(window);
13606 static void depth_bounds_test(void)
13608 static const struct
13610 struct vec4 position;
13611 DWORD diffuse;
13613 quad1[] =
13615 {{ 0.0f, 0.0f, 0.0f, 1.0f}, 0xfff9e814},
13616 {{640.0f, 0.0f, 0.0f, 1.0f}, 0xfff9e814},
13617 {{ 0.0f, 480.0f, 1.0f, 1.0f}, 0xfff9e814},
13618 {{640.0f, 480.0f, 1.0f, 1.0f}, 0xfff9e814},
13620 quad2[] =
13622 {{ 0.0f, 0.0f, 0.6f, 1.0f}, 0xff002b7f},
13623 {{640.0f, 0.0f, 0.6f, 1.0f}, 0xff002b7f},
13624 {{ 0.0f, 480.0f, 0.6f, 1.0f}, 0xff002b7f},
13625 {{640.0f, 480.0f, 0.6f, 1.0f}, 0xff002b7f},
13627 quad3[] =
13629 {{ 0.0f, 100.0f, 0.6f, 1.0f}, 0xfff91414},
13630 {{640.0f, 100.0f, 0.6f, 1.0f}, 0xfff91414},
13631 {{ 0.0f, 160.0f, 0.6f, 1.0f}, 0xfff91414},
13632 {{640.0f, 160.0f, 0.6f, 1.0f}, 0xfff91414},
13635 union {
13636 DWORD d;
13637 float f;
13638 } tmpvalue;
13640 IDirect3DSurface9 *offscreen_surface = NULL;
13641 IDirect3DDevice9 *device;
13642 IDirect3D9 *d3d;
13643 D3DCOLOR color;
13644 ULONG refcount;
13645 HWND window;
13646 HRESULT hr;
13648 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
13649 0, 0, 640, 480, NULL, NULL, NULL, NULL);
13650 d3d = Direct3DCreate9(D3D_SDK_VERSION);
13651 ok(!!d3d, "Failed to create a D3D object.\n");
13652 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
13653 D3DFMT_X8R8G8B8, 0, D3DRTYPE_SURFACE, MAKEFOURCC('N','V','D','B')) != D3D_OK)
13655 skip("No NVDB (depth bounds test) support, skipping tests.\n");
13656 goto done;
13658 if (!(device = create_device(d3d, window, window, TRUE)))
13660 skip("Failed to create a D3D device, skipping tests.\n");
13661 goto done;
13664 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
13665 MAKEFOURCC('N','V','D','B'), D3DPOOL_DEFAULT, &offscreen_surface, NULL);
13666 ok(FAILED(hr), "Able to create surface, hr %#x.\n", hr);
13667 if (offscreen_surface) IDirect3DSurface9_Release(offscreen_surface);
13669 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0, 0);
13670 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
13672 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
13673 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13674 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
13675 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13676 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13677 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13678 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
13679 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13682 hr = IDirect3DDevice9_BeginScene(device);
13683 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13685 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
13686 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
13688 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
13689 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13691 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_X, MAKEFOURCC('N','V','D','B'));
13692 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13694 tmpvalue.f = 0.625;
13695 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_Z, tmpvalue.d);
13696 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13698 tmpvalue.f = 0.75;
13699 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_W, tmpvalue.d);
13700 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13702 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
13703 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13705 tmpvalue.f = 0.75;
13706 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_Z, tmpvalue.d);
13707 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13709 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
13710 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13712 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_X, 0);
13713 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13715 hr = IDirect3DDevice9_EndScene(device);
13716 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13718 color = getPixelColor(device, 150, 130);
13719 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
13720 color = getPixelColor(device, 150, 200);
13721 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
13722 color = getPixelColor(device, 150, 300-5);
13723 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
13724 color = getPixelColor(device, 150, 300+5);
13725 ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);/**/
13726 color = getPixelColor(device, 150, 330);
13727 ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);
13728 color = getPixelColor(device, 150, 360-5);
13729 ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);/**/
13730 color = getPixelColor(device, 150, 360+5);
13731 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
13733 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13734 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
13735 refcount = IDirect3DDevice9_Release(device);
13736 ok(!refcount, "Device has %u references left.\n", refcount);
13737 done:
13738 IDirect3D9_Release(d3d);
13739 DestroyWindow(window);
13742 static void depth_buffer_test(void)
13744 static const struct
13746 struct vec3 position;
13747 DWORD diffuse;
13749 quad1[] =
13751 {{-1.0, 1.0, 0.33f}, 0xff00ff00},
13752 {{ 1.0, 1.0, 0.33f}, 0xff00ff00},
13753 {{-1.0, -1.0, 0.33f}, 0xff00ff00},
13754 {{ 1.0, -1.0, 0.33f}, 0xff00ff00},
13756 quad2[] =
13758 {{-1.0, 1.0, 0.50f}, 0xffff00ff},
13759 {{ 1.0, 1.0, 0.50f}, 0xffff00ff},
13760 {{-1.0, -1.0, 0.50f}, 0xffff00ff},
13761 {{ 1.0, -1.0, 0.50f}, 0xffff00ff},
13763 quad3[] =
13765 {{-1.0, 1.0, 0.66f}, 0xffff0000},
13766 {{ 1.0, 1.0, 0.66f}, 0xffff0000},
13767 {{-1.0, -1.0, 0.66f}, 0xffff0000},
13768 {{ 1.0, -1.0, 0.66f}, 0xffff0000},
13770 static const DWORD expected_colors[4][4] =
13772 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
13773 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
13774 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x00ff0000},
13775 {0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
13778 IDirect3DSurface9 *backbuffer, *rt1, *rt2, *rt3;
13779 IDirect3DDevice9 *device;
13780 unsigned int i, j;
13781 D3DVIEWPORT9 vp;
13782 IDirect3D9 *d3d;
13783 D3DCOLOR color;
13784 ULONG refcount;
13785 HWND window;
13786 HRESULT hr;
13788 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
13789 0, 0, 640, 480, NULL, NULL, NULL, NULL);
13790 d3d = Direct3DCreate9(D3D_SDK_VERSION);
13791 ok(!!d3d, "Failed to create a D3D object.\n");
13792 if (!(device = create_device(d3d, window, window, TRUE)))
13794 skip("Failed to create a D3D device, skipping tests.\n");
13795 goto done;
13798 vp.X = 0;
13799 vp.Y = 0;
13800 vp.Width = 640;
13801 vp.Height = 480;
13802 vp.MinZ = 0.0;
13803 vp.MaxZ = 1.0;
13805 hr = IDirect3DDevice9_SetViewport(device, &vp);
13806 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
13808 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
13809 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13810 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
13811 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13812 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13813 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13814 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
13815 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13816 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
13817 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
13819 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
13820 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
13821 hr = IDirect3DDevice9_CreateRenderTarget(device, 320, 240, D3DFMT_A8R8G8B8,
13822 D3DMULTISAMPLE_NONE, 0, FALSE, &rt1, NULL);
13823 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
13824 hr = IDirect3DDevice9_CreateRenderTarget(device, 480, 360, D3DFMT_A8R8G8B8,
13825 D3DMULTISAMPLE_NONE, 0, FALSE, &rt2, NULL);
13826 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
13827 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
13828 D3DMULTISAMPLE_NONE, 0, FALSE, &rt3, NULL);
13829 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
13831 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt3);
13832 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
13833 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0f, 0);
13834 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
13836 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
13837 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
13838 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
13839 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
13841 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt1);
13842 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
13843 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0f, 0);
13844 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
13846 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt2);
13847 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
13848 hr = IDirect3DDevice9_BeginScene(device);
13849 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13850 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
13851 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13852 hr = IDirect3DDevice9_EndScene(device);
13853 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13855 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
13856 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
13858 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
13859 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13861 hr = IDirect3DDevice9_BeginScene(device);
13862 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13863 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
13864 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13865 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
13866 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13867 hr = IDirect3DDevice9_EndScene(device);
13868 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13870 for (i = 0; i < 4; ++i)
13872 for (j = 0; j < 4; ++j)
13874 unsigned int x = 80 * ((2 * j) + 1);
13875 unsigned int y = 60 * ((2 * i) + 1);
13876 color = getPixelColor(device, x, y);
13877 ok(color_match(color, expected_colors[i][j], 0),
13878 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors[i][j], x, y, color);
13882 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13883 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
13885 IDirect3DSurface9_Release(backbuffer);
13886 IDirect3DSurface9_Release(rt3);
13887 IDirect3DSurface9_Release(rt2);
13888 IDirect3DSurface9_Release(rt1);
13889 refcount = IDirect3DDevice9_Release(device);
13890 ok(!refcount, "Device has %u references left.\n", refcount);
13891 done:
13892 IDirect3D9_Release(d3d);
13893 DestroyWindow(window);
13896 /* Test that partial depth copies work the way they're supposed to. The clear
13897 * on rt2 only needs a partial copy of the onscreen depth/stencil buffer, and
13898 * the following draw should only copy back the part that was modified. */
13899 static void depth_buffer2_test(void)
13901 static const struct
13903 struct vec3 position;
13904 DWORD diffuse;
13906 quad[] =
13908 {{-1.0f, 1.0f, 0.66f}, 0xffff0000},
13909 {{ 1.0f, 1.0f, 0.66f}, 0xffff0000},
13910 {{-1.0f, -1.0f, 0.66f}, 0xffff0000},
13911 {{ 1.0f, -1.0f, 0.66f}, 0xffff0000},
13914 IDirect3DSurface9 *backbuffer, *rt1, *rt2;
13915 IDirect3DDevice9 *device;
13916 unsigned int i, j;
13917 D3DVIEWPORT9 vp;
13918 IDirect3D9 *d3d;
13919 D3DCOLOR color;
13920 ULONG refcount;
13921 HWND window;
13922 HRESULT hr;
13924 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
13925 0, 0, 640, 480, NULL, NULL, NULL, NULL);
13926 d3d = Direct3DCreate9(D3D_SDK_VERSION);
13927 ok(!!d3d, "Failed to create a D3D object.\n");
13928 if (!(device = create_device(d3d, window, window, TRUE)))
13930 skip("Failed to create a D3D device, skipping tests.\n");
13931 goto done;
13934 vp.X = 0;
13935 vp.Y = 0;
13936 vp.Width = 640;
13937 vp.Height = 480;
13938 vp.MinZ = 0.0;
13939 vp.MaxZ = 1.0;
13941 hr = IDirect3DDevice9_SetViewport(device, &vp);
13942 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
13944 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
13945 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13946 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
13947 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13948 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13949 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13950 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
13951 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13952 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
13953 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
13955 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
13956 D3DMULTISAMPLE_NONE, 0, FALSE, &rt1, NULL);
13957 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
13958 hr = IDirect3DDevice9_CreateRenderTarget(device, 480, 360, D3DFMT_A8R8G8B8,
13959 D3DMULTISAMPLE_NONE, 0, FALSE, &rt2, NULL);
13960 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
13961 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
13962 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
13964 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt1);
13965 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
13966 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
13967 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
13969 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
13970 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
13971 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 0.5f, 0);
13972 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
13974 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt2);
13975 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
13976 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0f, 0);
13977 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
13979 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
13980 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
13982 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
13983 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13985 hr = IDirect3DDevice9_BeginScene(device);
13986 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13987 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13988 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13989 hr = IDirect3DDevice9_EndScene(device);
13990 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13992 for (i = 0; i < 4; ++i)
13994 for (j = 0; j < 4; ++j)
13996 unsigned int x = 80 * ((2 * j) + 1);
13997 unsigned int y = 60 * ((2 * i) + 1);
13998 color = getPixelColor(device, x, y);
13999 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
14000 "Expected color 0x0000ff00 at %u,%u, got 0x%08x.\n", x, y, color);
14004 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14005 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
14007 IDirect3DSurface9_Release(backbuffer);
14008 IDirect3DSurface9_Release(rt2);
14009 IDirect3DSurface9_Release(rt1);
14010 refcount = IDirect3DDevice9_Release(device);
14011 ok(!refcount, "Device has %u references left.\n", refcount);
14012 done:
14013 IDirect3D9_Release(d3d);
14014 DestroyWindow(window);
14017 static void depth_blit_test(void)
14019 static const struct
14021 struct vec3 position;
14022 DWORD diffuse;
14024 quad1[] =
14026 {{-1.0f, 1.0f, 0.33f}, 0xff00ff00},
14027 {{ 1.0f, 1.0f, 0.33f}, 0xff00ff00},
14028 {{-1.0f, -1.0f, 0.33f}, 0xff00ff00},
14029 {{ 1.0f, -1.0f, 0.33f}, 0xff00ff00},
14031 quad2[] =
14033 {{-1.0f, 1.0f, 0.66f}, 0xff0000ff},
14034 {{ 1.0f, 1.0f, 0.66f}, 0xff0000ff},
14035 {{-1.0f, -1.0f, 0.66f}, 0xff0000ff},
14036 {{ 1.0f, -1.0f, 0.66f}, 0xff0000ff},
14038 static const DWORD expected_colors[4][4] =
14040 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
14041 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
14042 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x00ff0000},
14043 {0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
14046 IDirect3DSurface9 *backbuffer, *ds1, *ds2, *ds3;
14047 IDirect3DDevice9 *device;
14048 RECT src_rect, dst_rect;
14049 unsigned int i, j;
14050 D3DVIEWPORT9 vp;
14051 IDirect3D9 *d3d;
14052 D3DCOLOR color;
14053 ULONG refcount;
14054 HWND window;
14055 HRESULT hr;
14057 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
14058 0, 0, 640, 480, NULL, NULL, NULL, NULL);
14059 d3d = Direct3DCreate9(D3D_SDK_VERSION);
14060 ok(!!d3d, "Failed to create a D3D object.\n");
14061 if (!(device = create_device(d3d, window, window, TRUE)))
14063 skip("Failed to create a D3D device, skipping tests.\n");
14064 goto done;
14067 vp.X = 0;
14068 vp.Y = 0;
14069 vp.Width = 640;
14070 vp.Height = 480;
14071 vp.MinZ = 0.0;
14072 vp.MaxZ = 1.0;
14074 hr = IDirect3DDevice9_SetViewport(device, &vp);
14075 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
14077 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
14078 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
14079 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds1);
14080 ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
14081 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8, 0, 0, FALSE, &ds2, NULL);
14082 ok(SUCCEEDED(hr), "CreateDepthStencilSurface failed, hr %#x.\n", hr);
14083 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds2);
14084 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
14085 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 320, 240, D3DFMT_D24S8, 0, 0, FALSE, &ds3, NULL);
14086 ok(SUCCEEDED(hr), "CreateDepthStencilSurface failed, hr %#x.\n", hr);
14088 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
14089 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14090 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
14091 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14092 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
14093 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14094 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
14095 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
14097 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
14098 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
14099 SetRect(&dst_rect, 0, 0, 480, 360);
14100 hr = IDirect3DDevice9_Clear(device, 1, (D3DRECT *)&dst_rect, D3DCLEAR_ZBUFFER, 0, 0.5f, 0);
14101 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
14102 SetRect(&dst_rect, 0, 0, 320, 240);
14103 hr = IDirect3DDevice9_Clear(device, 1, (D3DRECT *)&dst_rect, D3DCLEAR_ZBUFFER, 0, 1.0f, 0);
14104 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
14106 /* Partial blit. */
14107 SetRect(&src_rect, 0, 0, 320, 240);
14108 SetRect(&dst_rect, 0, 0, 320, 240);
14109 hr = IDirect3DDevice9_StretchRect(device, ds2, &src_rect, ds1, &dst_rect, D3DTEXF_POINT);
14110 ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
14111 /* Flipped. */
14112 SetRect(&src_rect, 0, 0, 640, 480);
14113 SetRect(&dst_rect, 0, 480, 640, 0);
14114 hr = IDirect3DDevice9_StretchRect(device, ds2, &src_rect, ds1, &dst_rect, D3DTEXF_POINT);
14115 ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
14116 /* Full, explicit. */
14117 SetRect(&src_rect, 0, 0, 640, 480);
14118 SetRect(&dst_rect, 0, 0, 640, 480);
14119 hr = IDirect3DDevice9_StretchRect(device, ds2, &src_rect, ds1, &dst_rect, D3DTEXF_POINT);
14120 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
14121 /* Filtered blit. */
14122 hr = IDirect3DDevice9_StretchRect(device, ds2, NULL, ds1, NULL, D3DTEXF_LINEAR);
14123 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
14124 /* Depth -> color blit.*/
14125 hr = IDirect3DDevice9_StretchRect(device, ds2, NULL, backbuffer, NULL, D3DTEXF_POINT);
14126 ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
14127 IDirect3DSurface9_Release(backbuffer);
14128 /* Full surface, different sizes */
14129 hr = IDirect3DDevice9_StretchRect(device, ds3, NULL, ds1, NULL, D3DTEXF_POINT);
14130 ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
14131 hr = IDirect3DDevice9_StretchRect(device, ds1, NULL, ds3, NULL, D3DTEXF_POINT);
14132 ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
14134 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds1);
14135 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
14136 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER | D3DCLEAR_TARGET, 0xffff0000, 1.0f, 0);
14137 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
14138 hr = IDirect3DDevice9_StretchRect(device, ds2, NULL, ds1, NULL, D3DTEXF_POINT);
14139 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
14141 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
14142 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14143 hr = IDirect3DDevice9_BeginScene(device);
14144 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14145 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
14146 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14147 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
14148 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14149 hr = IDirect3DDevice9_EndScene(device);
14150 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14152 for (i = 0; i < 4; ++i)
14154 for (j = 0; j < 4; ++j)
14156 unsigned int x = 80 * ((2 * j) + 1);
14157 unsigned int y = 60 * ((2 * i) + 1);
14158 color = getPixelColor(device, x, y);
14159 ok(color_match(color, expected_colors[i][j], 0),
14160 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors[i][j], x, y, color);
14164 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14165 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
14167 IDirect3DSurface9_Release(ds3);
14168 IDirect3DSurface9_Release(ds2);
14169 IDirect3DSurface9_Release(ds1);
14170 refcount = IDirect3DDevice9_Release(device);
14171 ok(!refcount, "Device has %u references left.\n", refcount);
14172 done:
14173 IDirect3D9_Release(d3d);
14174 DestroyWindow(window);
14177 static void intz_test(void)
14179 static const DWORD ps_code[] =
14181 0xffff0200, /* ps_2_0 */
14182 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
14183 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
14184 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0.0, 0.0, 0.0, 1.0 */
14185 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */
14186 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
14187 0x03010042, 0x800f0001, 0xb0e40000, 0xa0e40800, /* texldp r1, t0, s0 */
14188 0x02000001, 0x80020000, 0x80000001, /* mov r0.y, r1.x */
14189 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
14190 0x0000ffff, /* end */
14192 struct
14194 float x, y, z;
14195 float s, t, p, q;
14197 quad[] =
14199 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f},
14200 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
14201 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
14202 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f},
14204 half_quad_1[] =
14206 { -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f},
14207 { 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
14208 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
14209 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f},
14211 half_quad_2[] =
14213 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f},
14214 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
14215 { -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
14216 { 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f},
14218 struct
14220 UINT x, y;
14221 D3DCOLOR color;
14223 expected_colors[] =
14225 { 80, 100, 0x20204020},
14226 {240, 100, 0x6060bf60},
14227 {400, 100, 0x9f9f409f},
14228 {560, 100, 0xdfdfbfdf},
14229 { 80, 450, 0x20204020},
14230 {240, 450, 0x6060bf60},
14231 {400, 450, 0x9f9f409f},
14232 {560, 450, 0xdfdfbfdf},
14235 IDirect3DSurface9 *original_rt, *rt;
14236 struct surface_readback rb;
14237 IDirect3DTexture9 *texture;
14238 IDirect3DPixelShader9 *ps;
14239 IDirect3DDevice9 *device;
14240 IDirect3DSurface9 *ds;
14241 IDirect3D9 *d3d;
14242 ULONG refcount;
14243 D3DCAPS9 caps;
14244 HWND window;
14245 HRESULT hr;
14246 UINT i;
14248 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
14249 0, 0, 640, 480, NULL, NULL, NULL, NULL);
14250 d3d = Direct3DCreate9(D3D_SDK_VERSION);
14251 ok(!!d3d, "Failed to create a D3D object.\n");
14252 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
14253 D3DFMT_X8R8G8B8, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, MAKEFOURCC('I','N','T','Z'))))
14255 skip("No INTZ support, skipping INTZ test.\n");
14256 goto done;
14258 if (!(device = create_device(d3d, window, window, TRUE)))
14260 skip("Failed to create a D3D device, skipping tests.\n");
14261 goto done;
14264 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
14265 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
14266 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
14268 skip("No pixel shader 2.0 support, skipping INTZ test.\n");
14269 IDirect3DDevice9_Release(device);
14270 goto done;
14272 if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
14274 skip("No unconditional NP2 texture support, skipping INTZ test.\n");
14275 IDirect3DDevice9_Release(device);
14276 goto done;
14279 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
14280 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
14282 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
14283 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
14284 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
14285 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
14286 D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
14287 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
14288 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
14289 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
14291 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
14292 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
14293 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
14294 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14295 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
14296 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14297 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
14298 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14299 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
14300 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14302 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
14303 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
14304 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
14305 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
14306 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
14307 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
14308 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
14309 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
14310 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
14311 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
14313 /* Render offscreen, using the INTZ texture as depth buffer */
14314 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
14315 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
14316 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
14317 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
14318 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
14319 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
14320 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
14321 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
14323 /* Setup the depth/stencil surface. */
14324 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
14325 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
14327 hr = IDirect3DDevice9_BeginScene(device);
14328 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14329 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
14330 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14331 hr = IDirect3DDevice9_EndScene(device);
14332 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14334 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
14335 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
14336 IDirect3DSurface9_Release(ds);
14337 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
14338 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
14339 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
14340 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
14341 hr = IDirect3DDevice9_SetPixelShader(device, ps);
14342 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
14344 /* Read the depth values back. */
14345 hr = IDirect3DDevice9_BeginScene(device);
14346 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14347 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
14348 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14349 hr = IDirect3DDevice9_EndScene(device);
14350 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14352 get_rt_readback(original_rt, &rb);
14353 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
14355 D3DCOLOR color = get_readback_color(&rb, expected_colors[i].x, expected_colors[i].y);
14356 ok(color_match(color, expected_colors[i].color, 1),
14357 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
14358 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
14360 release_surface_readback(&rb);
14362 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14363 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
14365 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
14366 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
14367 IDirect3DTexture9_Release(texture);
14369 /* Render onscreen while using the INTZ texture as depth buffer */
14370 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
14371 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
14372 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
14373 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
14374 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
14375 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
14376 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
14377 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
14379 /* Setup the depth/stencil surface. */
14380 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
14381 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
14383 hr = IDirect3DDevice9_BeginScene(device);
14384 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14385 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
14386 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14387 hr = IDirect3DDevice9_EndScene(device);
14388 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14390 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
14391 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
14392 IDirect3DSurface9_Release(ds);
14393 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
14394 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
14395 hr = IDirect3DDevice9_SetPixelShader(device, ps);
14396 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
14398 /* Read the depth values back. */
14399 hr = IDirect3DDevice9_BeginScene(device);
14400 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14401 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
14402 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14403 hr = IDirect3DDevice9_EndScene(device);
14404 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14406 get_rt_readback(original_rt, &rb);
14407 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
14409 D3DCOLOR color = get_readback_color(&rb, expected_colors[i].x, expected_colors[i].y);
14410 ok(color_match(color, expected_colors[i].color, 1),
14411 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
14412 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
14414 release_surface_readback(&rb);
14416 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14417 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
14419 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
14420 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
14421 IDirect3DTexture9_Release(texture);
14423 /* Render offscreen, then onscreen, and finally check the INTZ texture in both areas */
14424 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
14425 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
14426 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
14427 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
14429 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
14430 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
14431 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
14432 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
14433 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
14434 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
14436 /* Setup the depth/stencil surface. */
14437 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
14438 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
14440 hr = IDirect3DDevice9_BeginScene(device);
14441 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14442 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, half_quad_1, sizeof(*half_quad_1));
14443 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14444 hr = IDirect3DDevice9_EndScene(device);
14445 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14447 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
14448 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
14450 hr = IDirect3DDevice9_BeginScene(device);
14451 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14452 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, half_quad_2, sizeof(*half_quad_2));
14453 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14454 hr = IDirect3DDevice9_EndScene(device);
14455 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14457 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
14458 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
14459 IDirect3DSurface9_Release(ds);
14460 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
14461 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
14462 hr = IDirect3DDevice9_SetPixelShader(device, ps);
14463 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
14465 /* Read the depth values back. */
14466 hr = IDirect3DDevice9_BeginScene(device);
14467 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14468 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
14469 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14470 hr = IDirect3DDevice9_EndScene(device);
14471 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14473 get_rt_readback(original_rt, &rb);
14474 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
14476 D3DCOLOR color = get_readback_color(&rb, expected_colors[i].x, expected_colors[i].y);
14477 ok(color_match(color, expected_colors[i].color, 1),
14478 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
14479 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
14481 release_surface_readback(&rb);
14483 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14484 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
14486 IDirect3DTexture9_Release(texture);
14487 IDirect3DPixelShader9_Release(ps);
14488 IDirect3DSurface9_Release(original_rt);
14489 IDirect3DSurface9_Release(rt);
14490 refcount = IDirect3DDevice9_Release(device);
14491 ok(!refcount, "Device has %u references left.\n", refcount);
14492 done:
14493 IDirect3D9_Release(d3d);
14494 DestroyWindow(window);
14497 static void shadow_test(void)
14499 static const DWORD ps_code[] =
14501 0xffff0200, /* ps_2_0 */
14502 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
14503 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
14504 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0.0, 0.0, 0.0, 1.0 */
14505 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */
14506 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
14507 0x03010042, 0x800f0001, 0xb0e40000, 0xa0e40800, /* texldp r1, t0, s0 */
14508 0x02000001, 0x80020000, 0x80000001, /* mov r0.y, r1.x */
14509 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
14510 0x0000ffff, /* end */
14512 struct
14514 D3DFORMAT format;
14515 const char *name;
14517 formats[] =
14519 {D3DFMT_D16_LOCKABLE, "D3DFMT_D16_LOCKABLE"},
14520 {D3DFMT_D32, "D3DFMT_D32"},
14521 {D3DFMT_D15S1, "D3DFMT_D15S1"},
14522 {D3DFMT_D24S8, "D3DFMT_D24S8"},
14523 {D3DFMT_D24X8, "D3DFMT_D24X8"},
14524 {D3DFMT_D24X4S4, "D3DFMT_D24X4S4"},
14525 {D3DFMT_D16, "D3DFMT_D16"},
14526 {D3DFMT_D32F_LOCKABLE, "D3DFMT_D32F_LOCKABLE"},
14527 {D3DFMT_D24FS8, "D3DFMT_D24FS8"},
14529 struct
14531 float x, y, z;
14532 float s, t, p, q;
14534 quad[] =
14536 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f},
14537 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f},
14538 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
14539 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f},
14541 struct
14543 UINT x, y;
14544 D3DCOLOR color;
14546 expected_colors[] =
14548 {400, 60, 0x00000000},
14549 {560, 180, 0xffff00ff},
14550 {560, 300, 0xffff00ff},
14551 {400, 420, 0xffffffff},
14552 {240, 420, 0xffffffff},
14553 { 80, 300, 0x00000000},
14554 { 80, 180, 0x00000000},
14555 {240, 60, 0x00000000},
14558 IDirect3DSurface9 *original_ds, *original_rt, *rt;
14559 struct surface_readback rb;
14560 IDirect3DPixelShader9 *ps;
14561 IDirect3DDevice9 *device;
14562 IDirect3D9 *d3d;
14563 ULONG refcount;
14564 D3DCAPS9 caps;
14565 HWND window;
14566 HRESULT hr;
14567 UINT i;
14569 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
14570 0, 0, 640, 480, NULL, NULL, NULL, NULL);
14571 d3d = Direct3DCreate9(D3D_SDK_VERSION);
14572 ok(!!d3d, "Failed to create a D3D object.\n");
14573 if (!(device = create_device(d3d, window, window, TRUE)))
14575 skip("Failed to create a D3D device, skipping tests.\n");
14576 goto done;
14579 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
14580 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
14581 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
14583 skip("No pixel shader 2.0 support, skipping shadow test.\n");
14584 IDirect3DDevice9_Release(device);
14585 goto done;
14588 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
14589 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
14590 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
14591 ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
14593 hr = IDirect3DDevice9_CreateRenderTarget(device, 1024, 1024, D3DFMT_A8R8G8B8,
14594 D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
14595 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
14596 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
14597 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
14599 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
14600 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
14601 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
14602 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14603 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
14604 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14605 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
14606 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14607 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
14608 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14610 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
14611 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
14612 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
14613 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
14614 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
14615 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
14616 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
14617 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
14618 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
14619 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
14621 for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
14623 D3DFORMAT format = formats[i].format;
14624 IDirect3DTexture9 *texture;
14625 IDirect3DSurface9 *ds;
14626 unsigned int j;
14628 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
14629 D3DFMT_X8R8G8B8, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, format)))
14630 continue;
14632 hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 1,
14633 D3DUSAGE_DEPTHSTENCIL, format, D3DPOOL_DEFAULT, &texture, NULL);
14634 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
14636 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
14637 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
14639 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
14640 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
14642 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
14643 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
14645 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
14646 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
14648 /* Setup the depth/stencil surface. */
14649 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
14650 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
14652 hr = IDirect3DDevice9_BeginScene(device);
14653 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14654 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
14655 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14656 hr = IDirect3DDevice9_EndScene(device);
14657 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14659 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
14660 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
14661 IDirect3DSurface9_Release(ds);
14663 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
14664 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
14666 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
14667 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
14669 hr = IDirect3DDevice9_SetPixelShader(device, ps);
14670 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
14672 /* Do the actual shadow mapping. */
14673 hr = IDirect3DDevice9_BeginScene(device);
14674 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14675 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
14676 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14677 hr = IDirect3DDevice9_EndScene(device);
14678 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14680 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
14681 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
14682 IDirect3DTexture9_Release(texture);
14684 get_rt_readback(original_rt, &rb);
14685 for (j = 0; j < sizeof(expected_colors) / sizeof(*expected_colors); ++j)
14687 D3DCOLOR color = get_readback_color(&rb, expected_colors[j].x, expected_colors[j].y);
14688 ok(color_match(color, expected_colors[j].color, 0),
14689 "Expected color 0x%08x at (%u, %u) for format %s, got 0x%08x.\n",
14690 expected_colors[j].color, expected_colors[j].x, expected_colors[j].y,
14691 formats[i].name, color);
14693 release_surface_readback(&rb);
14695 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14696 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
14699 IDirect3DPixelShader9_Release(ps);
14700 IDirect3DSurface9_Release(original_ds);
14701 IDirect3DSurface9_Release(original_rt);
14702 IDirect3DSurface9_Release(rt);
14703 refcount = IDirect3DDevice9_Release(device);
14704 ok(!refcount, "Device has %u references left.\n", refcount);
14705 done:
14706 IDirect3D9_Release(d3d);
14707 DestroyWindow(window);
14710 static void clip_planes(IDirect3DDevice9 *device, const char *test_name)
14712 static const struct
14714 struct vec3 position;
14715 DWORD diffuse;
14717 quad1[] =
14719 {{-1.0f, -1.0f, 0.0f}, 0xfff9e814},
14720 {{-1.0f, 1.0f, 0.0f}, 0xfff9e814},
14721 {{ 1.0f, -1.0f, 0.0f}, 0xfff9e814},
14722 {{ 1.0f, 1.0f, 0.0f}, 0xfff9e814},
14724 quad2[] =
14726 {{-1.0f, -1.0f, 0.0f}, 0xff002b7f},
14727 {{-1.0f, 1.0f, 0.0f}, 0xff002b7f},
14728 {{ 1.0f, -1.0f, 0.0f}, 0xff002b7f},
14729 {{ 1.0f, 1.0f, 0.0f}, 0xff002b7f},
14731 D3DCOLOR color;
14732 HRESULT hr;
14734 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 1.0, 0);
14735 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
14737 hr = IDirect3DDevice9_BeginScene(device);
14738 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14740 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
14741 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
14743 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPLANEENABLE, 0);
14744 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14745 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
14746 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14748 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPLANEENABLE, 0x1);
14749 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14750 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
14751 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14753 hr = IDirect3DDevice9_EndScene(device);
14754 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14756 color = getPixelColor(device, 1, 240);
14757 ok(color_match(color, 0x00002b7f, 1), "%s test: color 0x%08x.\n", test_name, color);
14758 color = getPixelColor(device, 638, 240);
14759 ok(color_match(color, 0x00002b7f, 1), "%s test: color 0x%08x.\n", test_name, color);
14761 color = getPixelColor(device, 1, 241);
14762 ok(color_match(color, 0x00f9e814, 1), "%s test: color 0x%08x.\n", test_name, color);
14763 color = getPixelColor(device, 638, 241);
14764 ok(color_match(color, 0x00f9e814, 1), "%s test: color 0x%08x.\n", test_name, color);
14767 static void clip_planes_test(void)
14769 IDirect3DSurface9 *offscreen_surface, *original_rt;
14770 IDirect3DTexture9 *offscreen = NULL;
14771 IDirect3DVertexShader9 *shader;
14772 IDirect3DDevice9 *device;
14773 IDirect3D9 *d3d;
14774 ULONG refcount;
14775 D3DCAPS9 caps;
14776 HWND window;
14777 HRESULT hr;
14779 static const float plane0[4] = {0.0f, 1.0f, 0.0f, 0.5f / 480.0f}; /* a quarter-pixel offset */
14780 static const DWORD shader_code[] =
14782 0xfffe0200, /* vs_2_0 */
14783 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
14784 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
14785 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
14786 0x02000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
14787 0x0000ffff /* end */
14790 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
14791 0, 0, 640, 480, NULL, NULL, NULL, NULL);
14792 d3d = Direct3DCreate9(D3D_SDK_VERSION);
14793 ok(!!d3d, "Failed to create a D3D object.\n");
14794 if (!(device = create_device(d3d, window, window, TRUE)))
14796 skip("Failed to create a D3D device, skipping tests.\n");
14797 goto done;
14800 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
14801 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
14802 if (caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
14804 skip("No vs_2_0 support, skipping tests.\n");
14805 IDirect3DDevice9_Release(device);
14806 goto done;
14809 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
14810 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
14812 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
14813 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14814 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
14815 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14816 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
14817 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14818 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
14819 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14821 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
14822 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed, hr=%08x\n", hr);
14823 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
14824 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
14826 IDirect3DDevice9_SetClipPlane(device, 0, plane0);
14828 clip_planes(device, "Onscreen FFP");
14830 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &offscreen, NULL);
14831 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
14832 hr = IDirect3DTexture9_GetSurfaceLevel(offscreen, 0, &offscreen_surface);
14833 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
14834 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen_surface);
14835 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
14837 clip_planes(device, "Offscreen FFP");
14839 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14840 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
14842 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
14843 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
14844 hr = IDirect3DDevice9_SetVertexShader(device, shader);
14845 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
14847 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
14848 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
14850 clip_planes(device, "Onscreen vertex shader");
14852 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen_surface);
14853 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
14855 clip_planes(device, "Offscreen vertex shader");
14857 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14858 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
14860 IDirect3DVertexShader9_Release(shader);
14861 IDirect3DSurface9_Release(original_rt);
14862 IDirect3DSurface9_Release(offscreen_surface);
14863 IDirect3DTexture9_Release(offscreen);
14864 refcount = IDirect3DDevice9_Release(device);
14865 ok(!refcount, "Device has %u references left.\n", refcount);
14866 done:
14867 IDirect3D9_Release(d3d);
14868 DestroyWindow(window);
14871 static void fp_special_test(void)
14873 /* Microsoft's assembler generates nan and inf with "1.#QNAN" and "1.#INF." respectively */
14874 static const DWORD vs_header[] =
14876 0xfffe0200, /* vs_2_0 */
14877 0x05000051, 0xa00f0000, 0x00000000, 0x3f000000, 0x3f800000, 0x40000000, /* def c0, 0.0, 0.5, 1.0, 2.0 */
14878 0x05000051, 0xa00f0001, 0x7fc00000, 0xff800000, 0x7f800000, 0x00000000, /* def c1, nan, -inf, inf, 0 */
14879 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
14880 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
14883 static const DWORD vs_log[] = {0x0200000f, 0x80010000, 0x90000001}; /* log r0.x, v1.x */
14884 static const DWORD vs_pow[] =
14885 {0x03000020, 0x80010000, 0x90000001, 0x90000001}; /* pow r0.x, v1.x, v1.x */
14886 static const DWORD vs_nrm[] = {0x02000024, 0x80070000, 0x90000001}; /* nrm r0.xyz, v1.x */
14887 static const DWORD vs_rcp1[] = {0x02000006, 0x80010000, 0x90000001}; /* rcp r0.x, v1.x */
14888 static const DWORD vs_rcp2[] = {0x02000006, 0x80010000, 0x91000001}; /* rcp r0.x, -v1.x */
14889 static const DWORD vs_rsq1[] = {0x02000007, 0x80010000, 0x90000001}; /* rsq r0.x, v1.x */
14890 static const DWORD vs_rsq2[] = {0x02000007, 0x80010000, 0x91000001}; /* rsq r0.x, -v1.x */
14891 static const DWORD vs_lit[] = {0x02000010, 0x800f0000, 0x90000001, /* lit r0, v1.xxxx */
14892 0x02000001, 0x80010000, 0x80aa0000}; /* mov r0.x, v0.z */
14893 static const DWORD vs_def1[] = {0x02000001, 0x80010000, 0xa0000001}; /* mov r0.x, c1.x */
14894 static const DWORD vs_def2[] = {0x02000001, 0x80010000, 0xa0550001}; /* mov r0.x, c1.y */
14895 static const DWORD vs_def3[] = {0x02000001, 0x80010000, 0xa0aa0001}; /* mov r0.x, c1.z */
14897 static const DWORD vs_footer[] =
14899 0x03000005, 0x80020000, 0x80000000, 0xa0ff0000, /* mul r0.y, r0.x, c0.w */
14900 0x0300000d, 0x80040000, 0x80000000, 0x80550000, /* sge r0.z, r0.x, r0.y */
14901 0x0300000d, 0x80020000, 0x80e40000, 0x80000000, /* sge r0.y, r0, r0.x */
14902 0x03000005, 0x80040000, 0x80550000, 0x80e40000, /* mul r0.z, r0.y, r0 */
14903 0x0300000b, 0x80080000, 0x81aa0000, 0x80aa0000, /* max r0.w, -r0.z, r0.z */
14904 0x0300000c, 0x80020000, 0x80000000, 0x80000000, /* slt r0.y, r0.x, r0.x */
14905 0x03000002, 0x80040000, 0x80550000, 0x80550000, /* add r0.z, r0.y, r0.y */
14906 0x0300000c, 0x80020000, 0xa0000000, 0x80ff0000, /* slt r0.y, c0.x, r0.w */
14907 0x0300000b, 0x80080000, 0x81aa0000, 0x80aa0000, /* max r0.w, -r0.z, r0.z */
14908 0x03000002, 0x80040000, 0x81550000, 0xa0e40000, /* add r0.z, -r0.y, c0 */
14909 0x0300000c, 0x80080000, 0xa0000000, 0x80e40000, /* slt r0.w, c0.x, r0 */
14910 0x03000005, 0x80040000, 0x80ff0000, 0x80e40000, /* mul r0.z, r0.w, r0 */
14911 0x04000004, 0x80020000, 0x80aa0000, 0xa0e40000, 0x80e40000, /* mad r0.y, r0.z, c0, r0 */
14912 0x02000001, 0xe0030000, 0x80e40000, /* mov oT0.xy, r0 */
14913 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
14914 0x0000ffff, /* end */
14917 static const struct
14919 const char *name;
14920 const DWORD *ops;
14921 DWORD size;
14922 D3DCOLOR r500;
14923 D3DCOLOR r600;
14924 D3DCOLOR nv40;
14925 D3DCOLOR nv50;
14926 D3DCOLOR warp;
14928 vs_body[] =
14930 /* The basic ideas here are:
14931 * 2.0 * +/-INF == +/-INF
14932 * NAN != NAN
14934 * The vertex shader value is written to the red component, with 0.0
14935 * and +/-INF mapping to 0xff, and NAN to 0x7f. Anything else should
14936 * result in 0x00. The pixel shader value is written to the green
14937 * component, but here 0.0 also results in 0x00. The actual value is
14938 * written to the blue component.
14940 * There are considerable differences between graphics cards in how
14941 * these are handled, but pow and nrm never generate INF or NAN on
14942 * real hardware. */
14943 {"log", vs_log, sizeof(vs_log), 0x00000000, 0x00000000, 0x00ff0000, 0x00ff7f00, 0x00ff8000},
14944 {"pow", vs_pow, sizeof(vs_pow), 0x000000ff, 0x000000ff, 0x0000ff00, 0x000000ff, 0x00008000},
14945 {"nrm", vs_nrm, sizeof(vs_nrm), 0x00ff0000, 0x00ff0000, 0x0000ff00, 0x00ff0000, 0x00008000},
14946 {"rcp1", vs_rcp1, sizeof(vs_rcp1), 0x000000ff, 0x000000ff, 0x00ff00ff, 0x00ff7f00, 0x00ff8000},
14947 {"rcp2", vs_rcp2, sizeof(vs_rcp2), 0x000000ff, 0x00000000, 0x00ff0000, 0x00ff7f00, 0x00ff8000},
14948 {"rsq1", vs_rsq1, sizeof(vs_rsq1), 0x000000ff, 0x000000ff, 0x00ff00ff, 0x00ff7f00, 0x00ff8000},
14949 {"rsq2", vs_rsq2, sizeof(vs_rsq2), 0x000000ff, 0x000000ff, 0x00ff00ff, 0x00ff7f00, 0x00ff8000},
14950 {"lit", vs_lit, sizeof(vs_lit), 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
14951 {"def1", vs_def1, sizeof(vs_def1), 0x000000ff, 0x00007f00, 0x0000ff00, 0x00007f00, 0x00008000},
14952 {"def2", vs_def2, sizeof(vs_def2), 0x00ff0000, 0x00ff7f00, 0x00ff0000, 0x00ff7f00, 0x00ff8000},
14953 {"def3", vs_def3, sizeof(vs_def3), 0x00ff00ff, 0x00ff7f00, 0x00ff00ff, 0x00ff7f00, 0x00ff8000},
14956 static const DWORD ps_code[] =
14958 0xffff0200, /* ps_2_0 */
14959 0x05000051, 0xa00f0000, 0x00000000, 0x3f000000, 0x3f800000, 0x40000000, /* def c0, 0.0, 0.5, 1.0, 2.0 */
14960 0x0200001f, 0x80000000, 0xb0030000, /* dcl t0.xy */
14961 0x0300000b, 0x80010001, 0xb0e40000, 0xa0e40000, /* max r1.x, t0, c0 */
14962 0x0300000a, 0x80010000, 0xb0e40000, 0xa0e40000, /* min r0.x, t0, c0 */
14963 0x03000002, 0x80010000, 0x80e40000, 0x81e40001, /* add r0.x, r0, -r1 */
14964 0x04000004, 0x80010001, 0xb0e40000, 0xa0ff0000, 0xb1e40000, /* mad r1.x, t0, c0.w. -t0 */
14965 0x02000023, 0x80010002, 0x80e40001, /* abs r2.x, r1 */
14966 0x02000023, 0x80010000, 0x80e40000, /* abs r0.x, r0 */
14967 0x02000023, 0x80010001, 0xb0e40000, /* abs r1.x, t0 */
14968 0x04000058, 0x80010002, 0x81e40002, 0xa0aa0000, 0xa0e40000, /* cmp r2.x, -r2, c0.z, c0 */
14969 0x02000023, 0x80010002, 0x80e40002, /* abs r2.x, r2 */
14970 0x04000058, 0x80010001, 0x81e40001, 0xa0aa0000, 0xa0e40000, /* cmp r1.x, -r1, c0.z, c0 */
14971 0x02000023, 0x80010001, 0x80e40001, /* abs r1.x, r1 */
14972 0x04000058, 0x80010003, 0x81e40002, 0xa0aa0000, 0xa0e40000, /* cmp r3.x, -r2, c0.z, c0 */
14973 0x04000058, 0x80010002, 0x81e40001, 0xa0aa0000, 0xa0e40000, /* cmp r2.x, -r1, c0.z, c0 */
14974 0x04000058, 0x80010000, 0x81e40000, 0xa0550000, 0xa0e40000, /* cmp r0.x, -r0, c0.y, c0 */
14975 0x03000005, 0x80010002, 0x80e40002, 0x80e40003, /* mul r2.x, r2, r3 */
14976 0x04000058, 0x80010000, 0x81e40002, 0xa0aa0000, 0x80e40000, /* cmp r0.x, -r2, c0.z, r0 */
14977 0x04000058, 0x80020000, 0x81000001, 0x80000000, 0xa0000000, /* cmp r0.y, -r1.x, r0.x, c0.x */
14978 0x02000001, 0x80050000, 0xb0c90000, /* mov r0.xz, t0.yzxw */
14979 0x02000001, 0x80080000, 0xa0aa0000, /* mov r0.w, c0.z */
14980 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
14981 0x0000ffff, /* end */
14984 struct
14986 float x, y, z;
14987 float s;
14989 quad[] =
14991 { -1.0f, 1.0f, 0.0f, 0.0f},
14992 { 1.0f, 1.0f, 1.0f, 0.0f},
14993 { -1.0f, -1.0f, 0.0f, 0.0f},
14994 { 1.0f, -1.0f, 1.0f, 0.0f},
14997 IDirect3DPixelShader9 *ps;
14998 IDirect3DDevice9 *device;
14999 UINT body_size = 0;
15000 IDirect3D9 *d3d;
15001 DWORD *vs_code;
15002 ULONG refcount;
15003 D3DCAPS9 caps;
15004 HWND window;
15005 HRESULT hr;
15006 UINT i;
15008 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
15009 0, 0, 640, 480, NULL, NULL, NULL, NULL);
15010 d3d = Direct3DCreate9(D3D_SDK_VERSION);
15011 ok(!!d3d, "Failed to create a D3D object.\n");
15012 if (!(device = create_device(d3d, window, window, TRUE)))
15014 skip("Failed to create a D3D device, skipping tests.\n");
15015 goto done;
15018 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
15019 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
15020 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0) || caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
15022 skip("No shader model 2.0 support, skipping floating point specials test.\n");
15023 IDirect3DDevice9_Release(device);
15024 goto done;
15027 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE1(0));
15028 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
15030 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
15031 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
15032 hr = IDirect3DDevice9_SetPixelShader(device, ps);
15033 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
15035 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
15036 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15038 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0f, 0);
15039 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
15041 for (i = 0; i < sizeof(vs_body) / sizeof(*vs_body); ++i)
15043 if (vs_body[i].size > body_size) body_size = vs_body[i].size;
15046 vs_code = HeapAlloc(GetProcessHeap(), 0, sizeof(vs_header) + body_size + sizeof(vs_footer));
15047 memcpy(vs_code, vs_header, sizeof(vs_header));
15049 for (i = 0; i < sizeof(vs_body) / sizeof(*vs_body); ++i)
15051 DWORD offset = sizeof(vs_header) / sizeof(*vs_header);
15052 IDirect3DVertexShader9 *vs;
15053 D3DCOLOR color;
15055 memcpy(vs_code + offset, vs_body[i].ops, vs_body[i].size);
15056 offset += vs_body[i].size / sizeof(*vs_body[i].ops);
15057 memcpy(vs_code + offset, vs_footer, sizeof(vs_footer));
15059 hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vs);
15060 ok(SUCCEEDED(hr), "CreateVertexShader failed, hr %#x.\n", hr);
15061 hr = IDirect3DDevice9_SetVertexShader(device, vs);
15062 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
15064 hr = IDirect3DDevice9_BeginScene(device);
15065 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
15066 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15067 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
15068 hr = IDirect3DDevice9_EndScene(device);
15069 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
15071 color = getPixelColor(device, 320, 240);
15072 ok(color_match(color, vs_body[i].r500, 1)
15073 || color_match(color, vs_body[i].r600, 1)
15074 || color_match(color, vs_body[i].nv40, 1)
15075 || color_match(color, vs_body[i].nv50, 1)
15076 || broken(color_match(color, vs_body[i].warp, 1)),
15077 "Expected color 0x%08x, 0x%08x, 0x%08x or 0x%08x for instruction \"%s\", got 0x%08x.\n",
15078 vs_body[i].r500, vs_body[i].r600, vs_body[i].nv40, vs_body[i].nv50, vs_body[i].name, color);
15080 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
15081 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
15083 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
15084 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
15085 IDirect3DVertexShader9_Release(vs);
15088 HeapFree(GetProcessHeap(), 0, vs_code);
15090 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
15091 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
15092 IDirect3DPixelShader9_Release(ps);
15093 refcount = IDirect3DDevice9_Release(device);
15094 ok(!refcount, "Device has %u references left.\n", refcount);
15095 done:
15096 IDirect3D9_Release(d3d);
15097 DestroyWindow(window);
15100 static void srgbwrite_format_test(void)
15102 IDirect3D9 *d3d;
15103 IDirect3DSurface9 *rt, *backbuffer;
15104 IDirect3DTexture9 *texture;
15105 IDirect3DDevice9 *device;
15106 ULONG refcount;
15107 HWND window;
15108 HRESULT hr;
15109 int i;
15110 DWORD color_rgb = 0x00808080, color_srgb = 0x00bcbcbc, color;
15111 static const struct
15113 D3DFORMAT fmt;
15114 const char *name;
15116 formats[] =
15118 { D3DFMT_R5G6B5, "D3DFMT_R5G6B5" },
15119 { D3DFMT_X8R8G8B8, "D3DFMT_X8R8G8B8" },
15120 { D3DFMT_A8R8G8B8, "D3DFMT_A8R8G8B8" },
15121 { D3DFMT_A16B16G16R16F, "D3DFMT_A16B16G16R16F" },
15122 { D3DFMT_A32B32G32R32F, "D3DFMT_A32B32G32R32F" },
15124 static const struct
15126 float x, y, z;
15127 float u, v;
15129 quad[] =
15131 {-1.0f, -1.0f, 0.1f, 0.0f, 0.0f},
15132 {-1.0f, 1.0f, 0.1f, 1.0f, 0.0f},
15133 { 1.0f, -1.0f, 0.1f, 0.0f, 1.0f},
15134 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f}
15137 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
15138 0, 0, 640, 480, NULL, NULL, NULL, NULL);
15139 d3d = Direct3DCreate9(D3D_SDK_VERSION);
15140 ok(!!d3d, "Failed to create a D3D object.\n");
15141 if (!(device = create_device(d3d, window, window, TRUE)))
15143 skip("Failed to create a D3D device, skipping tests.\n");
15144 goto done;
15147 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
15148 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
15149 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
15150 ok(SUCCEEDED(hr), "GetBackBuffer failed, hr %#x.\n", hr);
15151 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
15152 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
15153 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
15154 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15156 for(i = 0; i < (sizeof(formats) / sizeof(*formats)); i++)
15158 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
15159 D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, formats[i].fmt)))
15161 skip("Format %s not supported as render target, skipping test.\n",
15162 formats[i].name);
15163 continue;
15166 hr = IDirect3DDevice9_CreateTexture(device, 8, 8, 1, D3DUSAGE_RENDERTARGET,
15167 formats[i].fmt, D3DPOOL_DEFAULT, &texture, NULL);
15168 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
15169 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff0000, 1.0f, 0);
15170 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
15172 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &rt);
15173 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
15174 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
15175 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
15176 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x000000ff, 0.0f, 0);
15177 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
15179 hr = IDirect3DDevice9_BeginScene(device);
15180 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
15182 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, TRUE);
15183 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
15184 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TFACTOR);
15185 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
15186 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15187 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
15189 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, FALSE);
15190 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
15191 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
15192 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
15193 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
15194 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
15195 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
15196 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
15197 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15198 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
15199 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
15200 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
15202 hr = IDirect3DDevice9_EndScene(device);
15203 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
15205 IDirect3DSurface9_Release(rt);
15206 IDirect3DTexture9_Release(texture);
15208 color = getPixelColor(device, 360, 240);
15209 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
15210 D3DUSAGE_QUERY_SRGBWRITE,
15211 D3DRTYPE_TEXTURE, formats[i].fmt) == D3D_OK)
15213 /* Big slop for R5G6B5 */
15214 ok(color_match(color, color_srgb, 5), "Format %s supports srgb, expected color 0x%08x, got 0x%08x\n",
15215 formats[i].name, color_srgb, color);
15217 else
15219 /* Big slop for R5G6B5 */
15220 ok(color_match(color, color_rgb, 5), "Format %s does not support srgb, expected color 0x%08x, got 0x%08x\n",
15221 formats[i].name, color_rgb, color);
15224 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
15225 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
15228 IDirect3DSurface9_Release(backbuffer);
15229 refcount = IDirect3DDevice9_Release(device);
15230 ok(!refcount, "Device has %u references left.\n", refcount);
15231 done:
15232 IDirect3D9_Release(d3d);
15233 DestroyWindow(window);
15236 static void ds_size_test(void)
15238 IDirect3DSurface9 *ds, *rt, *old_rt, *old_ds, *readback;
15239 IDirect3DDevice9 *device;
15240 DWORD num_passes;
15241 IDirect3D9 *d3d;
15242 ULONG refcount;
15243 HWND window;
15244 HRESULT hr;
15246 static const struct
15248 float x, y, z;
15250 quad[] =
15252 {-1.0f, -1.0f, 0.0f},
15253 {-1.0f, 1.0f, 0.0f},
15254 { 1.0f, -1.0f, 0.0f},
15255 { 1.0f, 1.0f, 0.0f},
15258 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
15259 0, 0, 640, 480, NULL, NULL, NULL, NULL);
15260 d3d = Direct3DCreate9(D3D_SDK_VERSION);
15261 ok(!!d3d, "Failed to create a D3D object.\n");
15262 if (!(device = create_device(d3d, window, window, TRUE)))
15264 skip("Failed to create a D3D device, skipping tests.\n");
15265 goto done;
15268 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
15269 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateRenderTarget failed, hr %#x.\n", hr);
15270 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 32, 32, D3DFMT_D24X8, D3DMULTISAMPLE_NONE, 0, TRUE, &ds, NULL);
15271 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateDepthStencilSurface failed, hr %#x.\n", hr);
15272 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &readback, NULL);
15273 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateOffscreenPlainSurface failed, hr %#x.\n", hr);
15275 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
15276 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
15278 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
15279 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
15280 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
15281 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
15282 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
15283 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
15284 hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
15285 ok(SUCCEEDED(hr), "IDirect3DDevice9_ValidateDevice failed, hr %#x.\n", hr);
15286 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &old_rt);
15287 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetRenderTarget failed, hr %#x.\n", hr);
15288 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &old_ds);
15289 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetDepthStencilSurface failed, hr %#x.\n", hr);
15290 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
15291 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
15292 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
15293 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetDepthStencilSurface failed, hr %#x.\n", hr);
15294 hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
15295 ok(SUCCEEDED(hr), "IDirect3DDevice9_ValidateDevice failed, hr %#x.\n", hr);
15297 /* The D3DCLEAR_TARGET clear works. D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER returns OK,
15298 * but does not change the surface's contents. */
15299 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x000000FF, 0.0f, 0);
15300 ok(SUCCEEDED(hr), "Target clear failed, hr %#x.\n", hr);
15301 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 0.2f, 0);
15302 ok(SUCCEEDED(hr), "Z Buffer clear failed, hr %#x.\n", hr);
15303 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff0000, 0.5f, 0);
15304 ok(SUCCEEDED(hr), "Target and Z Buffer clear failed, hr %#x.\n", hr);
15306 /* Nvidia does not clear the surface(The color is still 0x000000ff), AMD does(the color is 0x00ff0000) */
15308 /* Turning on any depth-related state results in a ValidateDevice failure */
15309 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
15310 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
15311 hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
15312 ok(hr == D3DERR_CONFLICTINGRENDERSTATE || hr == D3D_OK, "IDirect3DDevice9_ValidateDevice returned %#x, expected "
15313 "D3DERR_CONFLICTINGRENDERSTATE.\n", hr);
15314 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
15315 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
15316 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
15317 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
15318 hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
15319 ok(hr == D3DERR_CONFLICTINGRENDERSTATE || hr == D3D_OK, "IDirect3DDevice9_ValidateDevice returned %#x, expected "
15320 "D3DERR_CONFLICTINGRENDERSTATE.\n", hr);
15322 /* Try to draw with the device in an invalid state. */
15323 hr = IDirect3DDevice9_BeginScene(device);
15324 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
15325 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15326 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
15327 hr = IDirect3DDevice9_EndScene(device);
15328 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
15330 /* Don't check the resulting draw unless we find an app that needs it. On
15331 * NVIDIA ValidateDevice() returns CONFLICTINGRENDERSTATE, so the result
15332 * is undefined. On AMD D3D seems to assume the stored Z buffer value is
15333 * 0.0 for all pixels, even those that are covered by the depth buffer. */
15335 hr = IDirect3DDevice9_SetRenderTarget(device, 0, old_rt);
15336 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
15337 hr = IDirect3DDevice9_SetDepthStencilSurface(device, old_ds);
15338 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetDepthStencilSurface failed, hr %#x.\n", hr);
15339 hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
15340 ok(SUCCEEDED(hr), "IDirect3DDevice9_ValidateDevice failed, hr %#x.\n", hr);
15342 IDirect3DSurface9_Release(readback);
15343 IDirect3DSurface9_Release(ds);
15344 IDirect3DSurface9_Release(rt);
15345 IDirect3DSurface9_Release(old_rt);
15346 IDirect3DSurface9_Release(old_ds);
15347 refcount = IDirect3DDevice9_Release(device);
15348 ok(!refcount, "Device has %u references left.\n", refcount);
15349 done:
15350 IDirect3D9_Release(d3d);
15351 DestroyWindow(window);
15354 static void unbound_sampler_test(void)
15356 IDirect3DPixelShader9 *ps, *ps_cube, *ps_volume;
15357 IDirect3DSurface9 *rt, *old_rt;
15358 IDirect3DDevice9 *device;
15359 IDirect3D9 *d3d;
15360 ULONG refcount;
15361 D3DCAPS9 caps;
15362 DWORD color;
15363 HWND window;
15364 HRESULT hr;
15366 static const DWORD ps_code[] =
15368 0xffff0200, /* ps_2_0 */
15369 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
15370 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
15371 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
15372 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
15373 0x0000ffff, /* end */
15375 static const DWORD ps_code_cube[] =
15377 0xffff0200, /* ps_2_0 */
15378 0x0200001f, 0x98000000, 0xa00f0800, /* dcl_cube s0 */
15379 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
15380 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
15381 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
15382 0x0000ffff, /* end */
15384 static const DWORD ps_code_volume[] =
15386 0xffff0200, /* ps_2_0 */
15387 0x0200001f, 0xa0000000, 0xa00f0800, /* dcl_volume s0 */
15388 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
15389 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
15390 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
15391 0x0000ffff, /* end */
15394 static const struct
15396 float x, y, z;
15397 float u, v;
15399 quad[] =
15401 {-1.0f, -1.0f, 0.1f, 0.0f, 0.0f},
15402 {-1.0f, 1.0f, 0.1f, 1.0f, 0.0f},
15403 { 1.0f, -1.0f, 0.1f, 0.0f, 1.0f},
15404 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f}
15407 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
15408 0, 0, 640, 480, NULL, NULL, NULL, NULL);
15409 d3d = Direct3DCreate9(D3D_SDK_VERSION);
15410 ok(!!d3d, "Failed to create a D3D object.\n");
15411 if (!(device = create_device(d3d, window, window, TRUE)))
15413 skip("Failed to create a D3D device, skipping tests.\n");
15414 goto done;
15417 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
15418 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
15419 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
15421 skip("No ps_2_0 support, skipping tests.\n");
15422 IDirect3DDevice9_Release(device);
15423 goto done;
15425 if (!(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP) || !(caps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP))
15427 skip("No cube / volume texture support, skipping tests.\n");
15428 IDirect3DDevice9_Release(device);
15429 goto done;
15432 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
15433 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStage failed, %#x.\n", hr);
15435 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
15436 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreatePixelShader failed, hr %#x.\n", hr);
15437 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code_cube, &ps_cube);
15438 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreatePixelShader failed, hr %#x.\n", hr);
15439 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code_volume, &ps_volume);
15440 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreatePixelShader failed, hr %#x.\n", hr);
15442 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &rt, NULL);
15443 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateRenderTarget failed, hr %#x.\n", hr);
15445 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &old_rt);
15446 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetRenderTarget failed, hr %#x.\n", hr);
15448 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
15449 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
15451 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 );
15452 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed, hr %#x.\n", hr);
15454 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x56ffffff, 1.0f, 0);
15455 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed, hr %#x.\n", hr);
15457 hr = IDirect3DDevice9_SetPixelShader(device, ps);
15458 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetPixelShader failed, hr %#x.\n", hr);
15460 hr = IDirect3DDevice9_BeginScene(device);
15461 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
15462 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15463 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
15464 hr = IDirect3DDevice9_EndScene(device);
15465 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
15467 color = getPixelColorFromSurface(rt, 32, 32);
15468 ok(color == 0xff000000, "Unbound sampler color is %#x.\n", color);
15470 /* Now try with a cube texture */
15471 hr = IDirect3DDevice9_SetPixelShader(device, ps_cube);
15472 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetPixelShader failed, hr %#x.\n", hr);
15474 hr = IDirect3DDevice9_BeginScene(device);
15475 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
15476 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15477 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
15478 hr = IDirect3DDevice9_EndScene(device);
15479 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
15481 color = getPixelColorFromSurface(rt, 32, 32);
15482 ok(color == 0xff000000, "Unbound sampler color is %#x.\n", color);
15484 /* And then with a volume texture */
15485 hr = IDirect3DDevice9_SetPixelShader(device, ps_volume);
15486 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetPixelShader failed, hr %#x.\n", hr);
15488 hr = IDirect3DDevice9_BeginScene(device);
15489 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
15490 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15491 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
15492 hr = IDirect3DDevice9_EndScene(device);
15493 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
15495 color = getPixelColorFromSurface(rt, 32, 32);
15496 ok(color == 0xff000000, "Unbound sampler color is %#x.\n", color);
15498 IDirect3DSurface9_Release(rt);
15499 IDirect3DSurface9_Release(old_rt);
15500 IDirect3DPixelShader9_Release(ps);
15501 IDirect3DPixelShader9_Release(ps_cube);
15502 IDirect3DPixelShader9_Release(ps_volume);
15503 refcount = IDirect3DDevice9_Release(device);
15504 ok(!refcount, "Device has %u references left.\n", refcount);
15505 done:
15506 IDirect3D9_Release(d3d);
15507 DestroyWindow(window);
15510 static void update_surface_test(void)
15512 static const BYTE blocks[][8] =
15514 {0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00}, /* White */
15515 {0x00, 0xf8, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00}, /* Red */
15516 {0xe0, 0xff, 0xe0, 0xff, 0x00, 0x00, 0x00, 0x00}, /* Yellow */
15517 {0xe0, 0x07, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00}, /* Green */
15518 {0xff, 0x07, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00}, /* Cyan */
15519 {0x1f, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00}, /* Blue */
15520 {0x1f, 0xf8, 0x1f, 0xf8, 0x00, 0x00, 0x00, 0x00}, /* Magenta */
15522 static const struct
15524 UINT x, y;
15525 D3DCOLOR color;
15527 expected_colors[] =
15529 { 18, 240, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0xff)},
15530 { 57, 240, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff)},
15531 {109, 240, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0xff)},
15532 {184, 240, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
15533 {290, 240, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
15534 {440, 240, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
15535 {584, 240, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff)},
15537 static const struct
15539 float x, y, z, w;
15540 float u, v;
15542 tri[] =
15544 { 0.0f, 480.0f, 0.0f, 1.0f, 0.0f, 0.0f},
15545 { 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
15546 {640.0f, 240.0f, 0.0f, 10.0f, 100.0f, 0.5f},
15548 static const RECT rect_2x2 = {0, 0, 2, 2};
15549 static const struct
15551 UINT src_level;
15552 UINT dst_level;
15553 const RECT *r;
15554 HRESULT hr;
15556 block_size_tests[] =
15558 {1, 0, NULL, D3D_OK},
15559 {0, 1, NULL, D3DERR_INVALIDCALL},
15560 {5, 4, NULL, D3DERR_INVALIDCALL},
15561 {4, 5, NULL, D3DERR_INVALIDCALL},
15562 {4, 5, &rect_2x2, D3DERR_INVALIDCALL},
15563 {5, 5, &rect_2x2, D3D_OK},
15566 IDirect3DSurface9 *src_surface, *dst_surface;
15567 IDirect3DTexture9 *src_tex, *dst_tex;
15568 IDirect3DDevice9 *device;
15569 IDirect3D9 *d3d;
15570 ULONG refcount;
15571 UINT count, i;
15572 HWND window;
15573 HRESULT hr;
15575 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
15576 0, 0, 640, 480, NULL, NULL, NULL, NULL);
15577 d3d = Direct3DCreate9(D3D_SDK_VERSION);
15578 ok(!!d3d, "Failed to create a D3D object.\n");
15579 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
15580 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_DXT1)))
15582 skip("DXT1 not supported, skipping tests.\n");
15583 goto done;
15585 if (!(device = create_device(d3d, window, window, TRUE)))
15587 skip("Failed to create a D3D device, skipping tests.\n");
15588 goto done;
15591 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 0, 0, D3DFMT_DXT1, D3DPOOL_SYSTEMMEM, &src_tex, NULL);
15592 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
15593 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 0, 0, D3DFMT_DXT1, D3DPOOL_DEFAULT, &dst_tex, NULL);
15594 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
15596 count = IDirect3DTexture9_GetLevelCount(src_tex);
15597 ok(count == 7, "Got level count %u, expected 7.\n", count);
15599 for (i = 0; i < count; ++i)
15601 UINT row_count, block_count, x, y;
15602 D3DSURFACE_DESC desc;
15603 BYTE *row, *block;
15604 D3DLOCKED_RECT r;
15606 hr = IDirect3DTexture9_GetLevelDesc(src_tex, i, &desc);
15607 ok(SUCCEEDED(hr), "Failed to get level desc, hr %#x.\n", hr);
15609 hr = IDirect3DTexture9_LockRect(src_tex, i, &r, NULL, 0);
15610 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
15612 row_count = ((desc.Height + 3) & ~3) / 4;
15613 block_count = ((desc.Width + 3) & ~3) / 4;
15614 row = r.pBits;
15616 for (y = 0; y < row_count; ++y)
15618 block = row;
15619 for (x = 0; x < block_count; ++x)
15621 memcpy(block, blocks[i], sizeof(blocks[i]));
15622 block += sizeof(blocks[i]);
15624 row += r.Pitch;
15627 hr = IDirect3DTexture9_UnlockRect(src_tex, i);
15628 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
15631 for (i = 0; i < sizeof(block_size_tests) / sizeof(*block_size_tests); ++i)
15633 hr = IDirect3DTexture9_GetSurfaceLevel(src_tex, block_size_tests[i].src_level, &src_surface);
15634 ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
15635 hr = IDirect3DTexture9_GetSurfaceLevel(dst_tex, block_size_tests[i].dst_level, &dst_surface);
15636 ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
15638 hr = IDirect3DDevice9_UpdateSurface(device, src_surface, block_size_tests[i].r, dst_surface, NULL);
15639 ok(hr == block_size_tests[i].hr, "Update surface returned %#x for test %u, expected %#x.\n",
15640 hr, i, block_size_tests[i].hr);
15642 IDirect3DSurface9_Release(dst_surface);
15643 IDirect3DSurface9_Release(src_surface);
15646 for (i = 0; i < count; ++i)
15648 hr = IDirect3DTexture9_GetSurfaceLevel(src_tex, i, &src_surface);
15649 ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
15650 hr = IDirect3DTexture9_GetSurfaceLevel(dst_tex, i, &dst_surface);
15651 ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
15653 hr = IDirect3DDevice9_UpdateSurface(device, src_surface, NULL, dst_surface, NULL);
15654 ok(SUCCEEDED(hr), "Failed to update surface at level %u, hr %#x.\n", i, hr);
15656 IDirect3DSurface9_Release(dst_surface);
15657 IDirect3DSurface9_Release(src_surface);
15660 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
15661 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15662 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
15663 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
15664 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_TEX1);
15665 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
15666 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)dst_tex);
15667 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
15668 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
15669 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
15670 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
15671 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
15673 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0f, 0);
15674 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
15676 hr = IDirect3DDevice9_BeginScene(device);
15677 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
15678 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 1, tri, sizeof(*tri));
15679 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
15680 hr = IDirect3DDevice9_EndScene(device);
15681 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
15683 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
15685 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
15686 ok(color_match(color, expected_colors[i].color, 0),
15687 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
15688 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
15691 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
15692 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
15694 IDirect3DTexture9_Release(dst_tex);
15695 IDirect3DTexture9_Release(src_tex);
15696 refcount = IDirect3DDevice9_Release(device);
15697 ok(!refcount, "Device has %u references left.\n", refcount);
15698 done:
15699 IDirect3D9_Release(d3d);
15700 DestroyWindow(window);
15703 static void multisample_get_rtdata_test(void)
15705 IDirect3DSurface9 *original_ds, *original_rt, *rt, *readback;
15706 IDirect3DDevice9 *device;
15707 IDirect3D9 *d3d;
15708 ULONG refcount;
15709 HWND window;
15710 HRESULT hr;
15712 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
15713 0, 0, 640, 480, NULL, NULL, NULL, NULL);
15714 d3d = Direct3DCreate9(D3D_SDK_VERSION);
15715 ok(!!d3d, "Failed to create a D3D object.\n");
15716 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
15717 D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
15719 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping tests.\n");
15720 goto done;
15722 if (!(device = create_device(d3d, window, window, TRUE)))
15724 skip("Failed to create a D3D device, skipping tests.\n");
15725 goto done;
15728 hr = IDirect3DDevice9_CreateRenderTarget(device, 256, 256, D3DFMT_A8R8G8B8,
15729 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt, NULL);
15730 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
15731 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 256, 256, D3DFMT_A8R8G8B8,
15732 D3DPOOL_SYSTEMMEM, &readback, NULL);
15733 ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
15735 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
15736 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
15737 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
15738 ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#x.\n", hr);
15740 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
15741 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
15742 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
15743 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
15745 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
15746 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
15747 hr = IDirect3DDevice9_GetRenderTargetData(device, rt, readback);
15748 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
15750 hr = IDirect3DDevice9_SetDepthStencilSurface(device, original_ds);
15751 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
15752 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
15753 ok(SUCCEEDED(hr), "Failed to restore original render target, hr %#x.\n", hr);
15755 IDirect3DSurface9_Release(original_ds);
15756 IDirect3DSurface9_Release(original_rt);
15757 IDirect3DSurface9_Release(readback);
15758 IDirect3DSurface9_Release(rt);
15759 refcount = IDirect3DDevice9_Release(device);
15760 ok(!refcount, "Device has %u references left.\n", refcount);
15761 done:
15762 IDirect3D9_Release(d3d);
15763 DestroyWindow(window);
15766 static void multisampled_depth_buffer_test(void)
15768 IDirect3DDevice9 *device = 0;
15769 IDirect3DSurface9 *original_rt, *rt, *readback, *ds, *original_ds;
15770 IDirect3D9 *d3d;
15771 D3DCAPS9 caps;
15772 HRESULT hr;
15773 D3DPRESENT_PARAMETERS present_parameters;
15774 unsigned int i;
15775 static const struct
15777 float x, y, z;
15778 D3DCOLOR color;
15780 quad_1[] =
15782 { -1.0f, 1.0f, 0.0f, 0xffff0000},
15783 { 1.0f, 1.0f, 1.0f, 0xffff0000},
15784 { -1.0f, -1.0f, 0.0f, 0xffff0000},
15785 { 1.0f, -1.0f, 1.0f, 0xffff0000},
15787 quad_2[] =
15789 { -1.0f, 1.0f, 1.0f, 0xff0000ff},
15790 { 1.0f, 1.0f, 0.0f, 0xff0000ff},
15791 { -1.0f, -1.0f, 1.0f, 0xff0000ff},
15792 { 1.0f, -1.0f, 0.0f, 0xff0000ff},
15794 static const struct
15796 UINT x, y;
15797 D3DCOLOR color;
15799 expected_colors[] =
15801 { 80, 100, D3DCOLOR_ARGB(0xff, 0xff, 0x00, 0x00)},
15802 {240, 100, D3DCOLOR_ARGB(0xff, 0xff, 0x00, 0x00)},
15803 {400, 100, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff)},
15804 {560, 100, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff)},
15805 { 80, 450, D3DCOLOR_ARGB(0xff, 0xff, 0x00, 0x00)},
15806 {240, 450, D3DCOLOR_ARGB(0xff, 0xff, 0x00, 0x00)},
15807 {400, 450, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff)},
15808 {560, 450, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff)},
15811 d3d = Direct3DCreate9(D3D_SDK_VERSION);
15812 ok(!!d3d, "Failed to create a D3D object.\n");
15814 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT,
15815 D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
15817 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping multisampled depth buffer test.\n");
15818 IDirect3D9_Release(d3d);
15819 return;
15821 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT,
15822 D3DDEVTYPE_HAL, D3DFMT_D24S8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
15824 skip("Multisampling not supported for D3DFMT_D24S8, skipping multisampled depth buffer test.\n");
15825 IDirect3D9_Release(d3d);
15826 return;
15829 ZeroMemory(&present_parameters, sizeof(present_parameters));
15830 present_parameters.Windowed = TRUE;
15831 present_parameters.hDeviceWindow = create_window();
15832 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
15833 present_parameters.BackBufferWidth = 640;
15834 present_parameters.BackBufferHeight = 480;
15835 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
15836 present_parameters.EnableAutoDepthStencil = TRUE;
15837 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
15838 present_parameters.MultiSampleType = D3DMULTISAMPLE_2_SAMPLES;
15840 hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
15841 present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING,
15842 &present_parameters, &device);
15843 ok(hr == D3D_OK, "Failed to create a device, hr %#x.\n", hr);
15845 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
15846 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
15847 if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
15849 skip("No unconditional NP2 texture support, skipping multisampled depth buffer test.\n");
15850 goto cleanup;
15853 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
15854 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt, NULL);
15855 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
15856 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
15857 D3DMULTISAMPLE_NONE, 0, TRUE, &readback, NULL);
15858 ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
15860 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
15861 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
15862 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds);
15863 ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#x.\n", hr);
15865 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
15866 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15867 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
15868 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15869 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
15870 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15871 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
15872 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15873 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
15874 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
15876 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
15877 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
15879 /* Render onscreen and then offscreen */
15880 hr = IDirect3DDevice9_BeginScene(device);
15881 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
15882 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_1, sizeof(*quad_1));
15883 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
15884 hr = IDirect3DDevice9_EndScene(device);
15885 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
15887 hr = IDirect3DDevice9_StretchRect(device, original_rt, NULL, rt, NULL, D3DTEXF_POINT);
15888 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
15889 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
15890 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
15892 hr = IDirect3DDevice9_BeginScene(device);
15893 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
15894 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_2, sizeof(*quad_2));
15895 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
15896 hr = IDirect3DDevice9_EndScene(device);
15897 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
15899 hr = IDirect3DDevice9_StretchRect(device, rt, NULL, readback, NULL, D3DTEXF_POINT);
15900 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
15902 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
15904 D3DCOLOR color = getPixelColorFromSurface(readback, expected_colors[i].x, expected_colors[i].y);
15905 ok(color_match(color, expected_colors[i].color, 1),
15906 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
15907 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
15910 hr = IDirect3DDevice9_StretchRect(device, rt, NULL, original_rt, NULL, D3DTEXF_POINT);
15911 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
15912 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
15913 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
15915 /* Render offscreen and then onscreen */
15916 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
15917 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
15918 IDirect3DSurface9_Release(ds);
15919 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
15920 D3DMULTISAMPLE_2_SAMPLES, 0, TRUE, &ds, NULL);
15921 ok(SUCCEEDED(hr), "Failed to create depth/stencil, hr %#x.\n", hr);
15922 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
15923 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
15925 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
15926 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
15928 hr = IDirect3DDevice9_BeginScene(device);
15929 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
15930 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_1, sizeof(*quad_1));
15931 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
15932 hr = IDirect3DDevice9_EndScene(device);
15933 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
15935 hr = IDirect3DDevice9_StretchRect(device, rt, NULL, original_rt, NULL, D3DTEXF_POINT);
15936 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
15937 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
15938 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
15940 hr = IDirect3DDevice9_BeginScene(device);
15941 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
15942 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_2, sizeof(*quad_2));
15943 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
15944 hr = IDirect3DDevice9_EndScene(device);
15945 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
15947 hr = IDirect3DDevice9_StretchRect(device, original_rt, NULL, readback, NULL, D3DTEXF_POINT);
15948 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
15950 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
15952 D3DCOLOR color = getPixelColorFromSurface(readback, expected_colors[i].x, expected_colors[i].y);
15953 ok(color_match(color, expected_colors[i].color, 1),
15954 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
15955 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
15958 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
15959 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
15961 IDirect3DSurface9_Release(ds);
15962 IDirect3DSurface9_Release(readback);
15963 IDirect3DSurface9_Release(rt);
15964 IDirect3DSurface9_Release(original_rt);
15965 cleanup_device(device);
15967 ZeroMemory(&present_parameters, sizeof(present_parameters));
15968 present_parameters.Windowed = TRUE;
15969 present_parameters.hDeviceWindow = create_window();
15970 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
15971 present_parameters.BackBufferWidth = 640;
15972 present_parameters.BackBufferHeight = 480;
15973 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
15974 present_parameters.EnableAutoDepthStencil = TRUE;
15975 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
15976 present_parameters.MultiSampleType = D3DMULTISAMPLE_NONE;
15978 hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
15979 present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING,
15980 &present_parameters, &device);
15981 ok(hr == D3D_OK, "Failed to create a device, hr %#x.\n", hr);
15983 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
15984 ok(SUCCEEDED(hr), "Failed to clear depth buffer, hr %#x.\n", hr);
15986 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
15987 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt, NULL);
15988 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
15989 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
15990 D3DMULTISAMPLE_NONE, 0, TRUE, &readback, NULL);
15991 ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
15992 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
15993 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &ds, NULL);
15994 ok(SUCCEEDED(hr), "CreateDepthStencilSurface failed, hr %#x.\n", hr);
15996 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
15997 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
15998 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
15999 ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#x.\n", hr);
16000 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
16001 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
16002 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
16003 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16005 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
16006 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16007 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
16008 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16009 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
16010 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16011 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
16012 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16013 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
16014 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
16016 /* Render to a multisampled offscreen frame buffer and then blit to
16017 * the onscreen (not multisampled) frame buffer. */
16018 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
16019 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
16021 hr = IDirect3DDevice9_BeginScene(device);
16022 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
16023 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_1, sizeof(*quad_1));
16024 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16025 hr = IDirect3DDevice9_EndScene(device);
16026 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
16028 hr = IDirect3DDevice9_StretchRect(device, rt, NULL, original_rt, NULL, D3DTEXF_POINT);
16029 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
16030 hr = IDirect3DDevice9_StretchRect(device, ds, NULL, original_ds, NULL, D3DTEXF_POINT);
16031 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
16033 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
16034 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
16035 hr = IDirect3DDevice9_SetDepthStencilSurface(device, original_ds);
16036 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16038 hr = IDirect3DDevice9_BeginScene(device);
16039 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
16040 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_2, sizeof(*quad_2));
16041 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16042 hr = IDirect3DDevice9_EndScene(device);
16043 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
16045 hr = IDirect3DDevice9_StretchRect(device, original_rt, NULL, readback, NULL, D3DTEXF_POINT);
16046 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
16048 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
16050 D3DCOLOR color = getPixelColorFromSurface(readback, expected_colors[i].x, expected_colors[i].y);
16051 ok(color_match(color, expected_colors[i].color, 1),
16052 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
16053 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
16056 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16057 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
16059 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
16060 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16061 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
16062 ok(SUCCEEDED(hr), "Failed to restore original render target, hr %#x.\n", hr);
16064 IDirect3DSurface9_Release(original_ds);
16065 IDirect3DSurface9_Release(original_rt);
16066 IDirect3DSurface9_Release(ds);
16067 IDirect3DSurface9_Release(readback);
16068 IDirect3DSurface9_Release(rt);
16069 cleanup:
16070 cleanup_device(device);
16071 IDirect3D9_Release(d3d);
16074 static void resz_test(void)
16076 IDirect3DDevice9 *device = 0;
16077 IDirect3DSurface9 *rt, *original_rt, *ds, *readback, *intz_ds;
16078 D3DCAPS9 caps;
16079 HRESULT hr;
16080 D3DPRESENT_PARAMETERS present_parameters;
16081 unsigned int i;
16082 static const DWORD ps_code[] =
16084 0xffff0200, /* ps_2_0 */
16085 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
16086 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
16087 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0.0, 0.0, 0.0, 1.0 */
16088 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */
16089 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
16090 0x02000001, 0x80010001, 0x80e40000, /* mov r1.x, r0 */
16091 0x03010042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texldp r0, t0, s0 */
16092 0x02000001, 0x80020001, 0x80000000, /* mov r1.y, r0.x */
16093 0x02000001, 0x800f0800, 0x80e40001, /* mov oC0, r1 */
16094 0x0000ffff, /* end */
16096 struct
16098 float x, y, z;
16099 float s, t, p, q;
16101 quad[] =
16103 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f},
16104 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
16105 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
16106 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f},
16108 struct
16110 UINT x, y;
16111 D3DCOLOR color;
16113 expected_colors[] =
16115 { 80, 100, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
16116 {240, 100, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
16117 {400, 100, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
16118 {560, 100, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
16119 { 80, 450, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
16120 {240, 450, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
16121 {400, 450, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
16122 {560, 450, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
16124 IDirect3DTexture9 *texture;
16125 IDirect3DPixelShader9 *ps;
16126 IDirect3D9 *d3d;
16127 DWORD value;
16129 d3d = Direct3DCreate9(D3D_SDK_VERSION);
16130 ok(!!d3d, "Failed to create a D3D object.\n");
16132 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT,
16133 D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
16135 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping RESZ test.\n");
16136 IDirect3D9_Release(d3d);
16137 return;
16139 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT,
16140 D3DDEVTYPE_HAL, D3DFMT_D24S8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
16142 skip("Multisampling not supported for D3DFMT_D24S8, skipping RESZ test.\n");
16143 IDirect3D9_Release(d3d);
16144 return;
16147 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
16148 D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, MAKEFOURCC('I','N','T','Z'))))
16150 skip("No INTZ support, skipping RESZ test.\n");
16151 IDirect3D9_Release(d3d);
16152 return;
16155 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
16156 D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE, MAKEFOURCC('R','E','S','Z'))))
16158 skip("No RESZ support, skipping RESZ test.\n");
16159 IDirect3D9_Release(d3d);
16160 return;
16163 ZeroMemory(&present_parameters, sizeof(present_parameters));
16164 present_parameters.Windowed = TRUE;
16165 present_parameters.hDeviceWindow = create_window();
16166 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
16167 present_parameters.BackBufferWidth = 640;
16168 present_parameters.BackBufferHeight = 480;
16169 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
16170 present_parameters.EnableAutoDepthStencil = FALSE;
16171 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
16172 present_parameters.MultiSampleType = D3DMULTISAMPLE_NONE;
16174 hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
16175 present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device);
16176 ok(hr == D3D_OK, "Failed to create a device, hr %#x.\n", hr);
16178 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
16179 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
16180 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
16182 skip("No pixel shader 2.0 support, skipping INTZ test.\n");
16183 cleanup_device(device);
16184 IDirect3D9_Release(d3d);
16185 return;
16187 if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
16189 skip("No unconditional NP2 texture support, skipping INTZ test.\n");
16190 cleanup_device(device);
16191 IDirect3D9_Release(d3d);
16192 return;
16195 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
16196 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
16198 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
16199 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt, NULL);
16200 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
16201 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
16202 D3DMULTISAMPLE_2_SAMPLES, 0, TRUE, &ds, NULL);
16203 ok(SUCCEEDED(hr), "Failed to create depth/stencil, hr %#x.\n", hr);
16204 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
16205 D3DMULTISAMPLE_NONE, 0, TRUE, &readback, NULL);
16206 ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
16208 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
16209 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
16210 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
16211 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &intz_ds);
16212 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
16213 hr = IDirect3DDevice9_SetDepthStencilSurface(device, intz_ds);
16214 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16215 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 1.0f, 0);
16216 ok(SUCCEEDED(hr), "Failed to clear depth/stencil, hr %#x.\n", hr);
16217 IDirect3DSurface9_Release(intz_ds);
16218 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
16219 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
16221 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
16222 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
16223 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
16224 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16225 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
16226 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16227 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
16228 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16229 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
16230 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16232 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
16233 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
16234 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
16235 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
16236 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
16237 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
16238 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
16239 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
16240 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
16241 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
16243 /* Render offscreen (multisampled), blit the depth buffer
16244 * into the INTZ texture and then check its contents */
16245 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
16246 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
16247 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
16248 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16249 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
16250 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
16252 hr = IDirect3DDevice9_BeginScene(device);
16253 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
16254 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16255 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16257 /* The destination depth texture has to be bound to sampler 0 */
16258 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
16259 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
16261 /* the ATI "spec" says you have to do a dummy draw to ensure correct commands ordering */
16262 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
16263 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16264 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
16265 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16266 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0);
16267 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16268 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16269 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16270 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
16271 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16272 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
16273 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16274 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0xf);
16275 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16277 /* The actual multisampled depth buffer resolve happens here */
16278 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
16279 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
16280 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, &value);
16281 ok(SUCCEEDED(hr) && value == 0x7fa05000, "GetRenderState failed, hr %#x, value %#x.\n", hr, value);
16283 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
16284 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
16285 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
16286 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16287 hr = IDirect3DDevice9_SetPixelShader(device, ps);
16288 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
16290 /* Read the depth values back */
16291 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16292 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16293 hr = IDirect3DDevice9_EndScene(device);
16294 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
16296 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
16298 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
16299 ok(color_match(color, expected_colors[i].color, 1),
16300 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
16301 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
16304 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16305 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
16307 IDirect3DSurface9_Release(ds);
16308 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
16309 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
16310 IDirect3DTexture9_Release(texture);
16311 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
16312 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
16313 IDirect3DPixelShader9_Release(ps);
16314 IDirect3DSurface9_Release(readback);
16315 IDirect3DSurface9_Release(original_rt);
16316 IDirect3DSurface9_Release(rt);
16317 cleanup_device(device);
16319 ZeroMemory(&present_parameters, sizeof(present_parameters));
16320 present_parameters.Windowed = TRUE;
16321 present_parameters.hDeviceWindow = create_window();
16322 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
16323 present_parameters.BackBufferWidth = 640;
16324 present_parameters.BackBufferHeight = 480;
16325 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
16326 present_parameters.EnableAutoDepthStencil = TRUE;
16327 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
16328 present_parameters.MultiSampleType = D3DMULTISAMPLE_2_SAMPLES;
16330 hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
16331 present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device);
16332 ok(hr == D3D_OK, "Failed to create a device, hr %#x.\n", hr);
16334 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
16335 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
16336 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds);
16337 ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#x.\n", hr);
16338 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
16339 D3DMULTISAMPLE_NONE, 0, TRUE, &readback, NULL);
16340 ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
16341 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
16342 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
16343 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
16344 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &intz_ds);
16345 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
16346 hr = IDirect3DDevice9_SetRenderTarget(device, 0, readback);
16347 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
16348 hr = IDirect3DDevice9_SetDepthStencilSurface(device, intz_ds);
16349 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16350 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 1.0f, 0);
16351 ok(SUCCEEDED(hr), "Failed to clear depth/stencil, hr %#x.\n", hr);
16352 IDirect3DSurface9_Release(intz_ds);
16353 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
16354 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
16356 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
16357 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
16358 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
16359 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16360 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
16361 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16362 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
16363 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16364 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
16365 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16367 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
16368 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
16369 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
16370 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
16371 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
16372 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
16373 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
16374 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
16375 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
16376 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
16378 /* Render onscreen, blit the depth buffer into the INTZ texture
16379 * and then check its contents */
16380 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
16381 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
16382 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
16383 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16384 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
16385 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
16387 hr = IDirect3DDevice9_BeginScene(device);
16388 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
16389 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16390 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16391 hr = IDirect3DDevice9_EndScene(device);
16392 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
16394 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
16395 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
16397 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
16398 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16399 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
16400 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16401 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0);
16402 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16403 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16404 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16405 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
16406 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16407 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
16408 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16409 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0xf);
16410 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16412 /* The actual multisampled depth buffer resolve happens here */
16413 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
16414 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
16415 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, &value);
16416 ok(SUCCEEDED(hr) && value == 0x7fa05000, "GetRenderState failed, hr %#x, value %#x.\n", hr, value);
16418 hr = IDirect3DDevice9_SetRenderTarget(device, 0, readback);
16419 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
16420 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
16421 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16422 hr = IDirect3DDevice9_SetPixelShader(device, ps);
16423 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
16425 /* Read the depth values back */
16426 hr = IDirect3DDevice9_BeginScene(device);
16427 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
16428 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16429 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16430 hr = IDirect3DDevice9_EndScene(device);
16431 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
16433 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
16435 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
16436 ok(color_match(color, expected_colors[i].color, 1),
16437 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
16438 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
16441 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16442 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
16445 /* Test edge cases - try with no texture at all */
16446 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
16447 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
16448 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
16449 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
16450 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
16451 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16452 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
16453 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16455 hr = IDirect3DDevice9_BeginScene(device);
16456 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
16457 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16458 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16459 hr = IDirect3DDevice9_EndScene(device);
16460 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
16462 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
16463 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
16465 /* With a non-multisampled depth buffer */
16466 IDirect3DSurface9_Release(ds);
16467 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
16468 D3DMULTISAMPLE_NONE, 0, TRUE, &ds, NULL);
16469 ok(SUCCEEDED(hr), "Failed to create depth stencil surface, hr %#x.\n", hr);
16471 hr = IDirect3DDevice9_SetRenderTarget(device, 0, readback);
16472 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
16473 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
16474 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16475 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
16476 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
16478 hr = IDirect3DDevice9_BeginScene(device);
16479 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
16480 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16481 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16483 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
16484 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
16486 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
16487 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16488 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
16489 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16490 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0);
16491 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16492 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16493 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16494 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
16495 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16496 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
16497 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16498 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0xf);
16499 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16500 hr = IDirect3DDevice9_EndScene(device);
16501 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
16503 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
16504 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
16506 hr = IDirect3DDevice9_SetPixelShader(device, ps);
16507 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
16509 /* Read the depth values back. */
16510 hr = IDirect3DDevice9_BeginScene(device);
16511 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
16512 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16513 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16514 hr = IDirect3DDevice9_EndScene(device);
16515 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
16517 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
16519 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
16520 ok(color_match(color, expected_colors[i].color, 1),
16521 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
16522 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
16525 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16526 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
16528 /* Without a current depth-stencil buffer set */
16529 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
16530 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
16531 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
16532 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16534 hr = IDirect3DDevice9_BeginScene(device);
16535 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
16536 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16537 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16538 hr = IDirect3DDevice9_EndScene(device);
16539 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
16541 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
16542 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
16544 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
16545 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16546 IDirect3DSurface9_Release(ds);
16547 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
16548 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
16549 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
16550 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
16551 IDirect3DTexture9_Release(texture);
16552 IDirect3DPixelShader9_Release(ps);
16553 IDirect3DSurface9_Release(readback);
16554 IDirect3DSurface9_Release(original_rt);
16555 cleanup_device(device);
16556 IDirect3D9_Release(d3d);
16559 static void zenable_test(void)
16561 static const struct
16563 struct vec4 position;
16564 D3DCOLOR diffuse;
16566 tquad[] =
16568 {{ 0.0f, 480.0f, -0.5f, 1.0f}, 0xff00ff00},
16569 {{ 0.0f, 0.0f, -0.5f, 1.0f}, 0xff00ff00},
16570 {{640.0f, 480.0f, 1.5f, 1.0f}, 0xff00ff00},
16571 {{640.0f, 0.0f, 1.5f, 1.0f}, 0xff00ff00},
16573 IDirect3DDevice9 *device;
16574 IDirect3D9 *d3d;
16575 D3DCOLOR color;
16576 ULONG refcount;
16577 D3DCAPS9 caps;
16578 HWND window;
16579 HRESULT hr;
16580 UINT x, y;
16581 UINT i, j;
16582 UINT test;
16583 IDirect3DSurface9 *ds;
16585 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
16586 0, 0, 640, 480, NULL, NULL, NULL, NULL);
16587 d3d = Direct3DCreate9(D3D_SDK_VERSION);
16588 ok(!!d3d, "Failed to create a D3D object.\n");
16589 if (!(device = create_device(d3d, window, window, TRUE)))
16591 skip("Failed to create a D3D device, skipping tests.\n");
16592 goto done;
16595 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds);
16596 ok(SUCCEEDED(hr), "Failed to get depth stencil surface, hr %#x.\n", hr);
16598 for (test = 0; test < 2; ++test)
16600 /* The Windows 8 testbot (WARP) appears to clip with
16601 * ZENABLE = D3DZB_TRUE and no depth buffer set. */
16602 static const D3DCOLOR expected_broken[] =
16604 0x00ff0000, 0x0000ff00, 0x0000ff00, 0x00ff0000,
16605 0x00ff0000, 0x0000ff00, 0x0000ff00, 0x00ff0000,
16606 0x00ff0000, 0x0000ff00, 0x0000ff00, 0x00ff0000,
16607 0x00ff0000, 0x0000ff00, 0x0000ff00, 0x00ff0000,
16610 if (!test)
16612 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
16613 ok(SUCCEEDED(hr), "Failed to set depth stencil surface, hr %#x.\n", hr);
16615 else
16617 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
16618 ok(SUCCEEDED(hr), "Failed to disable z-buffering, hr %#x.\n", hr);
16619 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
16620 ok(SUCCEEDED(hr), "Failed to set depth stencil surface, hr %#x.\n", hr);
16621 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 0.0f, 0);
16622 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
16624 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
16625 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
16627 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0f, 0);
16628 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
16629 hr = IDirect3DDevice9_BeginScene(device);
16630 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
16631 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, tquad, sizeof(*tquad));
16632 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
16633 hr = IDirect3DDevice9_EndScene(device);
16634 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
16636 for (i = 0; i < 4; ++i)
16638 for (j = 0; j < 4; ++j)
16640 x = 80 * ((2 * j) + 1);
16641 y = 60 * ((2 * i) + 1);
16642 color = getPixelColor(device, x, y);
16643 ok(color_match(color, 0x0000ff00, 1)
16644 || broken(color_match(color, expected_broken[i * 4 + j], 1) && !test),
16645 "Expected color 0x0000ff00 at %u, %u, got 0x%08x, test %u.\n",
16646 x, y, color, test);
16650 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16651 ok(SUCCEEDED(hr), "Failed to present backbuffer, hr %#x.\n", hr);
16654 IDirect3DSurface9_Release(ds);
16656 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
16657 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
16659 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1)
16660 && caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
16662 static const DWORD vs_code[] =
16664 0xfffe0101, /* vs_1_1 */
16665 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
16666 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
16667 0x00000001, 0xd00f0000, 0x90e40000, /* mov oD0, v0 */
16668 0x0000ffff
16670 static const DWORD ps_code[] =
16672 0xffff0101, /* ps_1_1 */
16673 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
16674 0x0000ffff /* end */
16676 static const struct vec3 quad[] =
16678 {-1.0f, -1.0f, -0.5f},
16679 {-1.0f, 1.0f, -0.5f},
16680 { 1.0f, -1.0f, 1.5f},
16681 { 1.0f, 1.0f, 1.5f},
16683 static const D3DCOLOR expected[] =
16685 0x00ff0000, 0x0060df60, 0x009fdf9f, 0x00ff0000,
16686 0x00ff0000, 0x00609f60, 0x009f9f9f, 0x00ff0000,
16687 0x00ff0000, 0x00606060, 0x009f609f, 0x00ff0000,
16688 0x00ff0000, 0x00602060, 0x009f209f, 0x00ff0000,
16690 /* The Windows 8 testbot (WARP) appears to not clip z for regular
16691 * vertices either. */
16692 static const D3DCOLOR expected_broken[] =
16694 0x0020df20, 0x0060df60, 0x009fdf9f, 0x00dfdfdf,
16695 0x00209f20, 0x00609f60, 0x009f9f9f, 0x00df9fdf,
16696 0x00206020, 0x00606060, 0x009f609f, 0x00df60df,
16697 0x00202020, 0x00602060, 0x009f209f, 0x00df20df,
16700 IDirect3DVertexShader9 *vs;
16701 IDirect3DPixelShader9 *ps;
16703 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
16704 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
16705 hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vs);
16706 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
16707 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
16708 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
16709 hr = IDirect3DDevice9_SetVertexShader(device, vs);
16710 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
16711 hr = IDirect3DDevice9_SetPixelShader(device, ps);
16712 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
16714 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0f, 0);
16715 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
16716 hr = IDirect3DDevice9_BeginScene(device);
16717 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
16718 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16719 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
16720 hr = IDirect3DDevice9_EndScene(device);
16721 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
16723 for (i = 0; i < 4; ++i)
16725 for (j = 0; j < 4; ++j)
16727 x = 80 * ((2 * j) + 1);
16728 y = 60 * ((2 * i) + 1);
16729 color = getPixelColor(device, x, y);
16730 ok(color_match(color, expected[i * 4 + j], 1)
16731 || broken(color_match(color, expected_broken[i * 4 + j], 1)),
16732 "Expected color 0x%08x at %u, %u, got 0x%08x.\n", expected[i * 4 + j], x, y, color);
16736 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16737 ok(SUCCEEDED(hr), "Failed to present backbuffer, hr %#x.\n", hr);
16739 IDirect3DPixelShader9_Release(ps);
16740 IDirect3DVertexShader9_Release(vs);
16743 refcount = IDirect3DDevice9_Release(device);
16744 ok(!refcount, "Device has %u references left.\n", refcount);
16745 done:
16746 IDirect3D9_Release(d3d);
16747 DestroyWindow(window);
16750 static void fog_special_test(void)
16752 static const struct
16754 struct vec3 position;
16755 D3DCOLOR diffuse;
16757 quad[] =
16759 {{ -1.0f, -1.0f, 0.0f}, 0xff00ff00},
16760 {{ -1.0f, 1.0f, 0.0f}, 0xff00ff00},
16761 {{ 1.0f, -1.0f, 1.0f}, 0xff00ff00},
16762 {{ 1.0f, 1.0f, 1.0f}, 0xff00ff00}
16764 static const struct
16766 DWORD vertexmode, tablemode;
16767 BOOL vs, ps;
16768 D3DCOLOR color_left, color_right;
16770 tests[] =
16772 {D3DFOG_LINEAR, D3DFOG_NONE, FALSE, FALSE, 0x00ff0000, 0x00ff0000},
16773 {D3DFOG_LINEAR, D3DFOG_NONE, FALSE, TRUE, 0x00ff0000, 0x00ff0000},
16774 {D3DFOG_LINEAR, D3DFOG_NONE, TRUE, FALSE, 0x00ff0000, 0x00ff0000},
16775 {D3DFOG_LINEAR, D3DFOG_NONE, TRUE, TRUE, 0x00ff0000, 0x00ff0000},
16777 {D3DFOG_NONE, D3DFOG_LINEAR, FALSE, FALSE, 0x0000ff00, 0x00ff0000},
16778 {D3DFOG_NONE, D3DFOG_LINEAR, FALSE, TRUE, 0x0000ff00, 0x00ff0000},
16779 {D3DFOG_NONE, D3DFOG_LINEAR, TRUE, FALSE, 0x0000ff00, 0x00ff0000},
16780 {D3DFOG_NONE, D3DFOG_LINEAR, TRUE, TRUE, 0x0000ff00, 0x00ff0000},
16782 static const DWORD pixel_shader_code[] =
16784 0xffff0101, /* ps_1_1 */
16785 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
16786 0x0000ffff
16788 static const DWORD vertex_shader_code[] =
16790 0xfffe0101, /* vs_1_1 */
16791 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
16792 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
16793 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
16794 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
16795 0x0000ffff
16797 static const D3DMATRIX identity =
16799 1.0f, 0.0f, 0.0f, 0.0f,
16800 0.0f, 1.0f, 0.0f, 0.0f,
16801 0.0f, 0.0f, 1.0f, 0.0f,
16802 0.0f, 0.0f, 0.0f, 1.0f,
16803 }}};
16804 union
16806 float f;
16807 DWORD d;
16808 } conv;
16809 DWORD color;
16810 HRESULT hr;
16811 unsigned int i;
16812 IDirect3DPixelShader9 *ps;
16813 IDirect3DVertexShader9 *vs;
16814 IDirect3DDevice9 *device;
16815 IDirect3D9 *d3d;
16816 ULONG refcount;
16817 D3DCAPS9 caps;
16818 HWND window;
16820 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
16821 0, 0, 640, 480, NULL, NULL, NULL, NULL);
16822 d3d = Direct3DCreate9(D3D_SDK_VERSION);
16823 ok(!!d3d, "Failed to create a D3D object.\n");
16824 if (!(device = create_device(d3d, window, window, TRUE)))
16826 skip("Failed to create a D3D device, skipping tests.\n");
16827 goto done;
16830 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
16831 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
16832 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
16834 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code, &vs);
16835 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
16837 else
16839 skip("Vertex Shaders not supported, skipping some fog tests.\n");
16840 vs = NULL;
16842 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
16844 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &ps);
16845 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
16847 else
16849 skip("Pixel Shaders not supported, skipping some fog tests.\n");
16850 ps = NULL;
16853 /* The table fog tests seem to depend on the projection matrix explicitly
16854 * being set to an identity matrix, even though that's the default.
16855 * (AMD Radeon HD 6310, Windows 7) */
16856 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &identity);
16857 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
16859 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
16860 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
16861 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
16862 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
16863 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
16864 ok(SUCCEEDED(hr), "Failed to enable fog, hr %#x.\n", hr);
16865 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xffff0000);
16866 ok(SUCCEEDED(hr), "Failed to set fog color, hr %#x.\n", hr);
16868 conv.f = 0.5f;
16869 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, conv.d);
16870 ok(SUCCEEDED(hr), "Failed to set fog start, hr %#x.\n", hr);
16871 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, conv.d);
16872 ok(SUCCEEDED(hr), "Failed to set fog end, hr %#x.\n", hr);
16874 for (i = 0; i < sizeof(tests) / sizeof(*tests); i++)
16876 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
16877 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
16879 if (!tests[i].vs)
16881 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
16882 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
16884 else if (vs)
16886 hr = IDirect3DDevice9_SetVertexShader(device, vs);
16887 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
16889 else
16891 continue;
16894 if (!tests[i].ps)
16896 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
16897 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
16899 else if (ps)
16901 hr = IDirect3DDevice9_SetPixelShader(device, ps);
16902 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
16904 else
16906 continue;
16909 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, tests[i].vertexmode);
16910 ok(SUCCEEDED(hr), "Failed to set fogvertexmode, hr %#x.\n", hr);
16911 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, tests[i].tablemode);
16912 ok(SUCCEEDED(hr), "Failed to set fogtablemode, hr %#x.\n", hr);
16914 hr = IDirect3DDevice9_BeginScene(device);
16915 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
16916 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16917 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
16918 hr = IDirect3DDevice9_EndScene(device);
16919 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
16921 color = getPixelColor(device, 310, 240);
16922 ok(color_match(color, tests[i].color_left, 1),
16923 "Expected left color 0x%08x, got 0x%08x, case %u.\n", tests[i].color_left, color, i);
16924 color = getPixelColor(device, 330, 240);
16925 ok(color_match(color, tests[i].color_right, 1),
16926 "Expected right color 0x%08x, got 0x%08x, case %u.\n", tests[i].color_right, color, i);
16928 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16929 ok(SUCCEEDED(hr), "Failed to present backbuffer, hr %#x.\n", hr);
16932 if (vs)
16933 IDirect3DVertexShader9_Release(vs);
16934 if (ps)
16935 IDirect3DPixelShader9_Release(ps);
16936 refcount = IDirect3DDevice9_Release(device);
16937 ok(!refcount, "Device has %u references left.\n", refcount);
16938 done:
16939 IDirect3D9_Release(d3d);
16940 DestroyWindow(window);
16943 static void volume_srgb_test(void)
16945 HRESULT hr;
16946 unsigned int i, j;
16947 IDirect3DVolumeTexture9 *tex1, *tex2;
16948 D3DPOOL pool;
16949 D3DLOCKED_BOX locked_box;
16950 IDirect3DDevice9 *device;
16951 IDirect3D9 *d3d;
16952 D3DCOLOR color;
16953 ULONG refcount;
16954 HWND window;
16956 static const struct
16958 BOOL srgb;
16959 DWORD color;
16961 tests[] =
16963 /* Try toggling on and off */
16964 { FALSE, 0x007f7f7f },
16965 { TRUE, 0x00363636 },
16966 { FALSE, 0x007f7f7f },
16968 static const struct
16970 struct vec3 pos;
16971 struct vec3 texcrd;
16973 quad[] =
16975 {{-1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}},
16976 {{-1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}},
16977 {{ 1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}},
16978 {{ 1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}},
16981 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
16982 0, 0, 640, 480, NULL, NULL, NULL, NULL);
16983 d3d = Direct3DCreate9(D3D_SDK_VERSION);
16984 ok(!!d3d, "Failed to create a D3D object.\n");
16985 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
16986 D3DUSAGE_QUERY_SRGBREAD, D3DRTYPE_VOLUMETEXTURE, D3DFMT_A8R8G8B8) != D3D_OK)
16988 skip("D3DFMT_A8R8G8B8 volume textures with SRGBREAD not supported.\n");
16989 goto done;
16991 if (!(device = create_device(d3d, window, window, TRUE)))
16993 skip("Failed to create a D3D device, skipping tests.\n");
16994 goto done;
16997 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
16998 ok(SUCCEEDED(hr), "Failed to set color op 0, hr %#x.\n", hr);
16999 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
17000 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
17001 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
17002 ok(SUCCEEDED(hr), "Failed to set color op 0, hr %#x.\n", hr);
17003 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE3(0));
17004 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr);
17006 for (i = 0; i < 2; i++)
17008 if (!i)
17009 pool = D3DPOOL_SYSTEMMEM;
17010 else
17011 pool = D3DPOOL_MANAGED;
17013 hr = IDirect3DDevice9_CreateVolumeTexture(device, 1, 1, 1, 1, 0, D3DFMT_A8R8G8B8, pool, &tex1, NULL);
17014 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
17015 hr = IDirect3DVolumeTexture9_LockBox(tex1, 0, &locked_box, NULL, 0);
17016 ok(SUCCEEDED(hr), "Failed to lock volume texture, hr %#x.\n", hr);
17017 *((DWORD *)locked_box.pBits) = 0x7f7f7f7f;
17018 hr = IDirect3DVolumeTexture9_UnlockBox(tex1, 0);
17019 ok(SUCCEEDED(hr), "Failed to lock volume texture, hr %#x.\n", hr);
17021 if (!i)
17023 hr = IDirect3DDevice9_CreateVolumeTexture(device, 1, 1, 1, 1, 0,
17024 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex2, NULL);
17025 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
17026 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex1, (IDirect3DBaseTexture9 *)tex2);
17027 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17028 IDirect3DVolumeTexture9_Release(tex1);
17030 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex2);
17031 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
17032 IDirect3DVolumeTexture9_Release(tex2);
17034 else
17036 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex1);
17037 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
17038 IDirect3DVolumeTexture9_Release(tex1);
17041 for (j = 0; j < sizeof(tests) / sizeof(*tests); j++)
17043 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, tests[j].srgb);
17044 ok(SUCCEEDED(hr), "Failed to set srgb state, hr %#x.\n", hr);
17046 hr = IDirect3DDevice9_BeginScene(device);
17047 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
17048 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
17049 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
17050 hr = IDirect3DDevice9_EndScene(device);
17051 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
17053 color = getPixelColor(device, 320, 240);
17054 ok(color_match(color, tests[j].color, 2),
17055 "Expected color 0x%08x, got 0x%08x, i = %u, j = %u.\n", tests[j].color, color, i, j);
17057 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17058 ok(SUCCEEDED(hr), "Failed to present backbuffer, hr %#x.\n", hr);
17062 refcount = IDirect3DDevice9_Release(device);
17063 ok(!refcount, "Device has %u references left.\n", refcount);
17064 done:
17065 IDirect3D9_Release(d3d);
17066 DestroyWindow(window);
17069 static void volume_dxt5_test(void)
17071 IDirect3DVolumeTexture9 *texture;
17072 IDirect3DDevice9 *device;
17073 D3DLOCKED_BOX box;
17074 IDirect3D9 *d3d;
17075 unsigned int i;
17076 ULONG refcount;
17077 DWORD color;
17078 HWND window;
17079 HRESULT hr;
17081 static const char texture_data[] =
17083 /* A 8x4x2 texture consisting of 4 4x4 blocks. The colors of the blocks are red, green, blue and white. */
17084 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00,
17085 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00,
17086 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00,
17087 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00
17089 static const struct
17091 struct vec3 position;
17092 struct vec3 texcrd;
17094 quads[] =
17096 {{ -1.0f, -1.0f, 0.0f}, { 0.0f, 0.0f, 0.25f}},
17097 {{ -1.0f, 1.0f, 0.0f}, { 0.0f, 1.0f, 0.25f}},
17098 {{ 0.0f, -1.0f, 1.0f}, { 1.0f, 0.0f, 0.25f}},
17099 {{ 0.0f, 1.0f, 1.0f}, { 1.0f, 1.0f, 0.25f}},
17101 {{ 0.0f, -1.0f, 0.0f}, { 0.0f, 0.0f, 0.75f}},
17102 {{ 0.0f, 1.0f, 0.0f}, { 0.0f, 1.0f, 0.75f}},
17103 {{ 1.0f, -1.0f, 1.0f}, { 1.0f, 0.0f, 0.75f}},
17104 {{ 1.0f, 1.0f, 1.0f}, { 1.0f, 1.0f, 0.75f}},
17106 static const DWORD expected_colors[] = {0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff};
17108 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
17109 0, 0, 640, 480, NULL, NULL, NULL, NULL);
17110 d3d = Direct3DCreate9(D3D_SDK_VERSION);
17111 ok(!!d3d, "Failed to create a D3D object.\n");
17112 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
17113 D3DFMT_X8R8G8B8, 0, D3DRTYPE_VOLUMETEXTURE, D3DFMT_DXT5)))
17115 skip("DXT5 volume textures are not supported, skipping test.\n");
17116 goto done;
17118 if (!(device = create_device(d3d, window, window, TRUE)))
17120 skip("Failed to create a D3D device, skipping tests.\n");
17121 goto done;
17124 hr = IDirect3DDevice9_CreateVolumeTexture(device, 8, 4, 2, 1, 0, D3DFMT_DXT5,
17125 D3DPOOL_MANAGED, &texture, NULL);
17126 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
17128 hr = IDirect3DVolumeTexture9_LockBox(texture, 0, &box, NULL, 0);
17129 ok(SUCCEEDED(hr), "Failed to lock volume texture, hr %#x.\n", hr);
17130 memcpy(box.pBits, texture_data, sizeof(texture_data));
17131 hr = IDirect3DVolumeTexture9_UnlockBox(texture, 0);
17132 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#x.\n", hr);
17134 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE3(0));
17135 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
17136 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
17137 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
17138 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
17139 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
17140 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
17141 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
17142 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
17143 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
17144 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
17145 ok(SUCCEEDED(hr), "Failed to set mag filter, hr %#x.\n", hr);
17147 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff00ff, 1.0f, 0);
17148 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
17149 hr = IDirect3DDevice9_BeginScene(device);
17150 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
17151 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads));
17152 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
17153 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[4], sizeof(*quads));
17154 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
17155 hr = IDirect3DDevice9_EndScene(device);
17156 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
17158 for (i = 0; i < 4; i++)
17160 color = getPixelColor(device, 80 + 160 * i, 240);
17161 ok (color_match(color, expected_colors[i], 1),
17162 "Expected color 0x%08x, got 0x%08x, case %u.\n", expected_colors[i], color, i);
17165 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17166 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17167 IDirect3DVolumeTexture9_Release(texture);
17168 refcount = IDirect3DDevice9_Release(device);
17169 ok(!refcount, "Device has %u references left.\n", refcount);
17170 done:
17171 IDirect3D9_Release(d3d);
17172 DestroyWindow(window);
17175 static void volume_v16u16_test(void)
17177 IDirect3DVolumeTexture9 *texture;
17178 IDirect3DPixelShader9 *shader;
17179 IDirect3DDevice9 *device;
17180 D3DLOCKED_BOX box;
17181 IDirect3D9 *d3d;
17182 unsigned int i;
17183 ULONG refcount;
17184 D3DCAPS9 caps;
17185 SHORT *texel;
17186 DWORD color;
17187 HWND window;
17188 HRESULT hr;
17190 static const struct
17192 struct vec3 position;
17193 struct vec3 texcrd;
17195 quads[] =
17197 {{ -1.0f, -1.0f, 0.0f}, { 0.0f, 0.0f, 0.25f}},
17198 {{ -1.0f, 1.0f, 0.0f}, { 0.0f, 1.0f, 0.25f}},
17199 {{ 0.0f, -1.0f, 1.0f}, { 1.0f, 0.0f, 0.25f}},
17200 {{ 0.0f, 1.0f, 1.0f}, { 1.0f, 1.0f, 0.25f}},
17202 {{ 0.0f, -1.0f, 0.0f}, { 0.0f, 0.0f, 0.75f}},
17203 {{ 0.0f, 1.0f, 0.0f}, { 0.0f, 1.0f, 0.75f}},
17204 {{ 1.0f, -1.0f, 1.0f}, { 1.0f, 0.0f, 0.75f}},
17205 {{ 1.0f, 1.0f, 1.0f}, { 1.0f, 1.0f, 0.75f}},
17207 static const DWORD shader_code[] =
17209 0xffff0101, /* ps_1_1 */
17210 0x00000051, 0xa00f0000, 0x3f000000, 0x3f000000, /* def c0, 0.5, 0.5, */
17211 0x3f000000, 0x3f000000, /* 0.5, 0.5 */
17212 0x00000042, 0xb00f0000, /* tex t0 */
17213 0x00000004, 0x800f0000, 0xb0e40000, 0xa0e40000, 0xa0e40000, /* mad r0, t0, c0, c0 */
17214 0x0000ffff /* end */
17217 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
17218 0, 0, 640, 480, NULL, NULL, NULL, NULL);
17219 d3d = Direct3DCreate9(D3D_SDK_VERSION);
17220 ok(!!d3d, "Failed to create a D3D object.\n");
17221 if (!(device = create_device(d3d, window, window, TRUE)))
17223 skip("Failed to create a D3D device, skipping tests.\n");
17224 goto done;
17227 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
17228 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
17229 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 1))
17231 skip("No ps_1_1 support, skipping tests.\n");
17232 IDirect3DDevice9_Release(device);
17233 goto done;
17235 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
17236 D3DFMT_X8R8G8B8, 0, D3DRTYPE_VOLUMETEXTURE, D3DFMT_V16U16)))
17238 skip("Volume V16U16 textures are not supported, skipping test.\n");
17239 IDirect3DDevice9_Release(device);
17240 goto done;
17243 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE3(0));
17244 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
17245 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
17246 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
17247 hr = IDirect3DDevice9_SetPixelShader(device, shader);
17248 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
17249 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
17250 ok(SUCCEEDED(hr), "Failed to set filter, hr %#x.\n", hr);
17252 for (i = 0; i < 2; i++)
17254 D3DPOOL pool;
17256 if (i)
17257 pool = D3DPOOL_SYSTEMMEM;
17258 else
17259 pool = D3DPOOL_MANAGED;
17261 hr = IDirect3DDevice9_CreateVolumeTexture(device, 1, 2, 2, 1, 0, D3DFMT_V16U16,
17262 pool, &texture, NULL);
17263 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
17265 hr = IDirect3DVolumeTexture9_LockBox(texture, 0, &box, NULL, 0);
17266 ok(SUCCEEDED(hr), "Failed to lock volume texture, hr %#x.\n", hr);
17268 texel = (SHORT *)((BYTE *)box.pBits + 0 * box.RowPitch + 0 * box.SlicePitch);
17269 texel[0] = 32767;
17270 texel[1] = 32767;
17271 texel = (SHORT *)((BYTE *)box.pBits + 1 * box.RowPitch + 0 * box.SlicePitch);
17272 texel[0] = -32768;
17273 texel[1] = 0;
17274 texel = (SHORT *)((BYTE *)box.pBits + 0 * box.RowPitch + 1 * box.SlicePitch);
17275 texel[0] = -16384;
17276 texel[1] = 16384;
17277 texel = (SHORT *)((BYTE *)box.pBits + 1 * box.RowPitch + 1 * box.SlicePitch);
17278 texel[0] = 0;
17279 texel[1] = 0;
17281 hr = IDirect3DVolumeTexture9_UnlockBox(texture, 0);
17282 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#x.\n", hr);
17284 if (i)
17286 IDirect3DVolumeTexture9 *texture2;
17288 hr = IDirect3DDevice9_CreateVolumeTexture(device, 1, 2, 2, 1, 0, D3DFMT_V16U16,
17289 D3DPOOL_DEFAULT, &texture2, NULL);
17290 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
17292 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)texture,
17293 (IDirect3DBaseTexture9 *)texture2);
17294 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17296 IDirect3DVolumeTexture9_Release(texture);
17297 texture = texture2;
17300 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
17301 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
17303 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff00ff, 1.0f, 0);
17304 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
17305 hr = IDirect3DDevice9_BeginScene(device);
17306 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
17307 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads));
17308 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
17309 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[4], sizeof(*quads));
17310 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
17311 hr = IDirect3DDevice9_EndScene(device);
17312 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
17314 color = getPixelColor(device, 120, 160);
17315 ok (color_match(color, 0x000080ff, 2),
17316 "Expected color 0x000080ff, got 0x%08x, V16U16 input -32768, 0.\n", color);
17317 color = getPixelColor(device, 120, 400);
17318 ok (color_match(color, 0x00ffffff, 2),
17319 "Expected color 0x00ffffff, got 0x%08x, V16U16 input 32767, 32767.\n", color);
17320 color = getPixelColor(device, 360, 160);
17321 ok (color_match(color, 0x007f7fff, 2),
17322 "Expected color 0x007f7fff, got 0x%08x, V16U16 input 0, 0.\n", color);
17323 color = getPixelColor(device, 360, 400);
17324 ok (color_match(color, 0x0040c0ff, 2),
17325 "Expected color 0x0040c0ff, got 0x%08x, V16U16 input -16384, 16384.\n", color);
17327 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17328 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17330 IDirect3DVolumeTexture9_Release(texture);
17333 IDirect3DPixelShader9_Release(shader);
17334 refcount = IDirect3DDevice9_Release(device);
17335 ok(!refcount, "Device has %u references left.\n", refcount);
17336 done:
17337 IDirect3D9_Release(d3d);
17338 DestroyWindow(window);
17341 static void add_dirty_rect_test_draw(IDirect3DDevice9 *device)
17343 HRESULT hr;
17344 static const struct
17346 struct vec3 position;
17347 struct vec2 texcoord;
17349 quad[] =
17351 {{-1.0, -1.0, 0.0}, {0.0, 0.0}},
17352 {{-1.0, 1.0, 0.0}, {0.0, 1.0}},
17353 {{ 1.0, -1.0, 0.0}, {1.0, 0.0}},
17354 {{ 1.0, 1.0, 0.0}, {1.0, 1.0}},
17357 hr = IDirect3DDevice9_BeginScene(device);
17358 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
17359 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad, sizeof(*quad));
17360 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
17361 hr = IDirect3DDevice9_EndScene(device);
17362 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
17365 static void add_dirty_rect_test(void)
17367 HRESULT hr;
17368 IDirect3DTexture9 *tex_dst1, *tex_dst2, *tex_src_red, *tex_src_green, *tex_managed;
17369 IDirect3DSurface9 *surface_dst2, *surface_src_green, *surface_src_red, *surface_managed;
17370 IDirect3DDevice9 *device;
17371 IDirect3D9 *d3d;
17372 unsigned int i;
17373 ULONG refcount;
17374 DWORD *texel;
17375 HWND window;
17376 D3DLOCKED_RECT locked_rect;
17377 static const RECT part_rect = {96, 96, 160, 160};
17378 DWORD color;
17380 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
17381 0, 0, 640, 480, NULL, NULL, NULL, NULL);
17382 d3d = Direct3DCreate9(D3D_SDK_VERSION);
17383 ok(!!d3d, "Failed to create a D3D object.\n");
17384 if (!(device = create_device(d3d, window, window, TRUE)))
17386 skip("Failed to create a D3D device, skipping tests.\n");
17387 IDirect3D9_Release(d3d);
17388 DestroyWindow(window);
17389 return;
17392 hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 1, 0, D3DFMT_X8R8G8B8,
17393 D3DPOOL_DEFAULT, &tex_dst1, NULL);
17394 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
17395 hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 1, 0, D3DFMT_X8R8G8B8,
17396 D3DPOOL_DEFAULT, &tex_dst2, NULL);
17397 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
17398 hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 1, 0, D3DFMT_X8R8G8B8,
17399 D3DPOOL_SYSTEMMEM, &tex_src_red, NULL);
17400 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
17401 hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 1, 0, D3DFMT_X8R8G8B8,
17402 D3DPOOL_SYSTEMMEM, &tex_src_green, NULL);
17403 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
17404 hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 1, 0, D3DFMT_X8R8G8B8,
17405 D3DPOOL_MANAGED, &tex_managed, NULL);
17406 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
17408 hr = IDirect3DTexture9_GetSurfaceLevel(tex_dst2, 0, &surface_dst2);
17409 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
17410 hr = IDirect3DTexture9_GetSurfaceLevel(tex_src_green, 0, &surface_src_green);
17411 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
17412 hr = IDirect3DTexture9_GetSurfaceLevel(tex_src_red, 0, &surface_src_red);
17413 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
17414 hr = IDirect3DTexture9_GetSurfaceLevel(tex_managed, 0, &surface_managed);
17415 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
17417 fill_surface(surface_src_red, 0x00ff0000, 0);
17418 fill_surface(surface_src_green, 0x0000ff00, 0);
17420 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
17421 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr);
17422 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
17423 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
17424 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
17425 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
17427 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
17428 (IDirect3DBaseTexture9 *)tex_dst1);
17429 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17431 /* The second UpdateTexture call writing to tex_dst2 is ignored because tex_src_green is not dirty. */
17432 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_red,
17433 (IDirect3DBaseTexture9 *)tex_dst2);
17434 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17435 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
17436 (IDirect3DBaseTexture9 *)tex_dst2);
17437 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17439 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex_dst1);
17440 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
17441 add_dirty_rect_test_draw(device);
17442 color = getPixelColor(device, 320, 240);
17443 ok(color_match(color, 0x0000ff00, 1),
17444 "Expected color 0x0000ff00, got 0x%08x.\n", color);
17445 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17446 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17448 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex_dst2);
17449 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
17450 add_dirty_rect_test_draw(device);
17451 color = getPixelColor(device, 320, 240);
17452 todo_wine ok(color_match(color, 0x00ff0000, 1),
17453 "Expected color 0x00ff0000, got 0x%08x.\n", color);
17454 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17455 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17457 /* AddDirtyRect on the destination is ignored. */
17458 hr = IDirect3DTexture9_AddDirtyRect(tex_dst2, &part_rect);
17459 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
17460 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
17461 (IDirect3DBaseTexture9 *)tex_dst2);
17462 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17463 add_dirty_rect_test_draw(device);
17464 color = getPixelColor(device, 320, 240);
17465 todo_wine ok(color_match(color, 0x00ff0000, 1),
17466 "Expected color 0x00ff0000, got 0x%08x.\n", color);
17467 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17468 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17470 hr = IDirect3DTexture9_AddDirtyRect(tex_dst2, NULL);
17471 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
17472 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
17473 (IDirect3DBaseTexture9 *)tex_dst2);
17474 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17475 add_dirty_rect_test_draw(device);
17476 color = getPixelColor(device, 320, 240);
17477 todo_wine ok(color_match(color, 0x00ff0000, 1),
17478 "Expected color 0x00ff0000, got 0x%08x.\n", color);
17479 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17480 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17482 /* AddDirtyRect on the source makes UpdateTexture work. Partial rectangle
17483 * tracking is supported. */
17484 hr = IDirect3DTexture9_AddDirtyRect(tex_src_green, &part_rect);
17485 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
17486 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
17487 (IDirect3DBaseTexture9 *)tex_dst2);
17488 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17489 add_dirty_rect_test_draw(device);
17490 color = getPixelColor(device, 320, 240);
17491 ok(color_match(color, 0x0000ff00, 1),
17492 "Expected color 0x0000ff00, got 0x%08x.\n", color);
17493 color = getPixelColor(device, 1, 1);
17494 todo_wine ok(color_match(color, 0x00ff0000, 1),
17495 "Expected color 0x00ff0000, got 0x%08x.\n", color);
17496 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17497 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17499 hr = IDirect3DTexture9_AddDirtyRect(tex_src_green, NULL);
17500 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
17501 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
17502 (IDirect3DBaseTexture9 *)tex_dst2);
17503 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17504 add_dirty_rect_test_draw(device);
17505 color = getPixelColor(device, 1, 1);
17506 ok(color_match(color, 0x0000ff00, 1),
17507 "Expected color 0x0000ff00, got 0x%08x.\n", color);
17509 /* Locks with NO_DIRTY_UPDATE are ignored. */
17510 fill_surface(surface_src_green, 0x00000080, D3DLOCK_NO_DIRTY_UPDATE);
17511 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
17512 (IDirect3DBaseTexture9 *)tex_dst2);
17513 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17514 add_dirty_rect_test_draw(device);
17515 color = getPixelColor(device, 320, 240);
17516 todo_wine ok(color_match(color, 0x0000ff00, 1),
17517 "Expected color 0x0000ff00, got 0x%08x.\n", color);
17518 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17519 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17521 /* Readonly maps write to D3DPOOL_SYSTEMMEM, but don't record a dirty rectangle. */
17522 fill_surface(surface_src_green, 0x000000ff, D3DLOCK_READONLY);
17523 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
17524 (IDirect3DBaseTexture9 *)tex_dst2);
17525 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17526 add_dirty_rect_test_draw(device);
17527 color = getPixelColor(device, 320, 240);
17528 todo_wine ok(color_match(color, 0x0000ff00, 1),
17529 "Expected color 0x0000ff00, got 0x%08x.\n", color);
17530 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17531 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17533 hr = IDirect3DTexture9_AddDirtyRect(tex_src_green, NULL);
17534 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
17535 (IDirect3DBaseTexture9 *)tex_dst2);
17536 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17537 add_dirty_rect_test_draw(device);
17538 color = getPixelColor(device, 320, 240);
17539 ok(color_match(color, 0x000000ff, 1),
17540 "Expected color 0x000000ff, got 0x%08x.\n", color);
17541 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17542 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17544 /* Maps without either of these flags record a dirty rectangle. */
17545 fill_surface(surface_src_green, 0x00ffffff, 0);
17546 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
17547 (IDirect3DBaseTexture9 *)tex_dst2);
17548 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17549 add_dirty_rect_test_draw(device);
17550 color = getPixelColor(device, 320, 240);
17551 ok(color_match(color, 0x00ffffff, 1),
17552 "Expected color 0x00ffffff, got 0x%08x.\n", color);
17553 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17554 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17556 /* Partial LockRect works just like a partial AddDirtyRect call. */
17557 hr = IDirect3DTexture9_LockRect(tex_src_green, 0, &locked_rect, &part_rect, 0);
17558 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
17559 texel = locked_rect.pBits;
17560 for (i = 0; i < 64; i++)
17561 texel[i] = 0x00ff00ff;
17562 for (i = 1; i < 64; i++)
17563 memcpy((BYTE *)locked_rect.pBits + i * locked_rect.Pitch, locked_rect.pBits, locked_rect.Pitch);
17564 hr = IDirect3DTexture9_UnlockRect(tex_src_green, 0);
17565 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
17566 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
17567 (IDirect3DBaseTexture9 *)tex_dst2);
17568 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17569 add_dirty_rect_test_draw(device);
17570 color = getPixelColor(device, 320, 240);
17571 ok(color_match(color, 0x00ff00ff, 1),
17572 "Expected color 0x00ff00ff, got 0x%08x.\n", color);
17573 color = getPixelColor(device, 1, 1);
17574 ok(color_match(color, 0x00ffffff, 1),
17575 "Expected color 0x00ffffff, got 0x%08x.\n", color);
17576 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17577 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17579 fill_surface(surface_src_red, 0x00ff0000, 0);
17580 fill_surface(surface_src_green, 0x0000ff00, 0);
17582 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
17583 (IDirect3DBaseTexture9 *)tex_dst1);
17584 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17585 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex_dst1);
17586 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
17587 add_dirty_rect_test_draw(device);
17588 color = getPixelColor(device, 320, 240);
17589 ok(color_match(color, 0x0000ff00, 1),
17590 "Expected color 0x0000ff00, got 0x%08x.\n", color);
17591 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17592 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17594 /* UpdateSurface ignores the missing dirty marker. */
17595 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_red,
17596 (IDirect3DBaseTexture9 *)tex_dst2);
17597 hr = IDirect3DDevice9_UpdateSurface(device, surface_src_green, NULL, surface_dst2, NULL);
17598 ok(SUCCEEDED(hr), "Failed to update surface, hr %#x.\n", hr);
17599 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex_dst2);
17600 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
17601 add_dirty_rect_test_draw(device);
17602 color = getPixelColor(device, 320, 240);
17603 ok(color_match(color, 0x0000ff00, 1),
17604 "Expected color 0x0000ff00, got 0x%08x.\n", color);
17605 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17606 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17608 fill_surface(surface_managed, 0x00ff0000, 0);
17609 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex_managed);
17610 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
17611 add_dirty_rect_test_draw(device);
17612 color = getPixelColor(device, 320, 240);
17613 ok(color_match(color, 0x00ff0000, 1),
17614 "Expected color 0x00ff0000, got 0x%08x.\n", color);
17615 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17616 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17618 /* Managed textures also honor D3DLOCK_NO_DIRTY_UPDATE. */
17619 fill_surface(surface_managed, 0x0000ff00, D3DLOCK_NO_DIRTY_UPDATE);
17620 add_dirty_rect_test_draw(device);
17621 color = getPixelColor(device, 320, 240);
17622 ok(color_match(color, 0x00ff0000, 1),
17623 "Expected color 0x00ff0000, got 0x%08x.\n", color);
17624 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17625 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17627 /* AddDirtyRect uploads the new contents.
17628 * Side note, not tested in the test: Partial surface updates work, and two separate
17629 * dirty rectangles are tracked individually. Tested on Nvidia Kepler, other drivers
17630 * untested. */
17631 hr = IDirect3DTexture9_AddDirtyRect(tex_managed, NULL);
17632 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
17633 add_dirty_rect_test_draw(device);
17634 color = getPixelColor(device, 320, 240);
17635 ok(color_match(color, 0x0000ff00, 1),
17636 "Expected color 0x0000ff00, got 0x%08x.\n", color);
17637 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17638 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17640 /* So does EvictManagedResources. */
17641 fill_surface(surface_managed, 0x000000ff, D3DLOCK_NO_DIRTY_UPDATE);
17642 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
17643 hr = IDirect3DDevice9_EvictManagedResources(device);
17644 ok(SUCCEEDED(hr), "Failed to evict managed resources, hr %#x.\n", hr);
17645 add_dirty_rect_test_draw(device);
17646 color = getPixelColor(device, 320, 240);
17647 ok(color_match(color, 0x000000ff, 1),
17648 "Expected color 0x000000ff, got 0x%08x.\n", color);
17649 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17650 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17652 /* AddDirtyRect on a locked texture is allowed. */
17653 hr = IDirect3DTexture9_LockRect(tex_src_red, 0, &locked_rect, NULL, 0);
17654 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
17655 hr = IDirect3DTexture9_AddDirtyRect(tex_src_red, NULL);
17656 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
17657 hr = IDirect3DTexture9_UnlockRect(tex_src_red, 0);
17658 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
17660 /* Redundant AddDirtyRect calls are ok. */
17661 hr = IDirect3DTexture9_AddDirtyRect(tex_managed, NULL);
17662 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
17663 hr = IDirect3DTexture9_AddDirtyRect(tex_managed, NULL);
17664 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
17666 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
17667 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
17668 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
17669 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
17670 IDirect3DSurface9_Release(surface_dst2);
17671 IDirect3DSurface9_Release(surface_managed);
17672 IDirect3DSurface9_Release(surface_src_red);
17673 IDirect3DSurface9_Release(surface_src_green);
17674 IDirect3DTexture9_Release(tex_src_red);
17675 IDirect3DTexture9_Release(tex_src_green);
17676 IDirect3DTexture9_Release(tex_dst1);
17677 IDirect3DTexture9_Release(tex_dst2);
17678 IDirect3DTexture9_Release(tex_managed);
17679 refcount = IDirect3DDevice9_Release(device);
17680 ok(!refcount, "Device has %u references left.\n", refcount);
17681 IDirect3D9_Release(d3d);
17682 DestroyWindow(window);
17685 static void test_per_stage_constant(void)
17687 IDirect3DDevice9 *device;
17688 IDirect3D9 *d3d;
17689 D3DCOLOR color;
17690 ULONG refcount;
17691 D3DCAPS9 caps;
17692 HWND window;
17693 HRESULT hr;
17695 static const struct
17697 struct vec3 position;
17698 D3DCOLOR diffuse;
17700 quad[] =
17702 {{-1.0f, -1.0f, 0.1f}, 0xffff0000},
17703 {{-1.0f, 1.0f, 0.1f}, 0xffff0000},
17704 {{ 1.0f, -1.0f, 0.1f}, 0xffff0000},
17705 {{ 1.0f, 1.0f, 0.1f}, 0xffff0000},
17708 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
17709 0, 0, 640, 480, NULL, NULL, NULL, NULL);
17710 d3d = Direct3DCreate9(D3D_SDK_VERSION);
17711 ok(!!d3d, "Failed to create a D3D object.\n");
17712 if (!(device = create_device(d3d, window, window, TRUE)))
17714 skip("Failed to create a D3D device, skipping tests.\n");
17715 goto done;
17718 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
17719 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
17720 if (!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_PERSTAGECONSTANT))
17722 skip("Per-stage constants not supported, skipping tests.\n");
17723 IDirect3DDevice9_Release(device);
17724 goto done;
17727 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
17728 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
17729 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
17730 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
17731 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
17732 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
17733 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
17734 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
17735 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
17736 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
17738 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_CONSTANT, 0x80a1b2c3);
17739 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
17740 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_CONSTANT);
17741 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
17742 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
17743 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
17745 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
17746 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
17748 hr = IDirect3DDevice9_BeginScene(device);
17749 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
17750 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
17751 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
17752 hr = IDirect3DDevice9_EndScene(device);
17753 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
17755 color = getPixelColor(device, 320, 240);
17756 ok(color_match(color, 0x00a1b2c3, 1), "Got unexpected color 0x%08x.\n", color);
17757 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17758 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17760 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_CONSTANT | D3DTA_COMPLEMENT);
17761 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
17763 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
17764 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
17766 hr = IDirect3DDevice9_BeginScene(device);
17767 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
17768 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
17769 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
17770 hr = IDirect3DDevice9_EndScene(device);
17771 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
17773 color = getPixelColor(device, 320, 240);
17774 ok(color_match(color, 0x005e4d3c, 1), "Got unexpected color 0x%08x.\n", color);
17775 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17776 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17778 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_CONSTANT | D3DTA_ALPHAREPLICATE);
17779 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
17781 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
17782 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
17784 hr = IDirect3DDevice9_BeginScene(device);
17785 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
17786 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
17787 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
17788 hr = IDirect3DDevice9_EndScene(device);
17789 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
17791 color = getPixelColor(device, 320, 240);
17792 ok(color_match(color, 0x00808080, 1), "Got unexpected color 0x%08x.\n", color);
17793 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17794 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17796 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_CONSTANT);
17797 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
17798 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
17799 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
17800 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_CURRENT);
17801 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
17803 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
17804 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
17806 hr = IDirect3DDevice9_BeginScene(device);
17807 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
17808 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
17809 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
17810 hr = IDirect3DDevice9_EndScene(device);
17811 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
17813 color = getPixelColor(device, 320, 240);
17814 ok(color_match(color, 0x0080007f, 1), "Got unexpected color 0x%08x.\n", color);
17815 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17816 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17818 refcount = IDirect3DDevice9_Release(device);
17819 ok(!refcount, "Device has %u references left.\n", refcount);
17820 done:
17821 IDirect3D9_Release(d3d);
17822 DestroyWindow(window);
17825 static void test_3dc_formats(void)
17827 static const char ati1n_data[] =
17829 /* A 4x4 texture with the color component at 50%. */
17830 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
17832 static const char ati2n_data[] =
17834 /* A 8x4 texture consisting of 2 4x4 blocks. The first block has 50% first color component,
17835 * 0% second component. Second block is the opposite. */
17836 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
17837 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
17839 static const struct
17841 struct vec3 position;
17842 struct vec2 texcoord;
17844 quads[] =
17846 {{-1.0f, -1.0f, 0.0f}, {0.0f, 0.0f}},
17847 {{-1.0f, 1.0f, 0.0f}, {0.0f, 1.0f}},
17848 {{ 0.0f, -1.0f, 1.0f}, {1.0f, 0.0f}},
17849 {{ 0.0f, 1.0f, 1.0f}, {1.0f, 1.0f}},
17851 {{ 0.0f, -1.0f, 0.0f}, {0.0f, 0.0f}},
17852 {{ 0.0f, 1.0f, 0.0f}, {0.0f, 1.0f}},
17853 {{ 1.0f, -1.0f, 1.0f}, {1.0f, 0.0f}},
17854 {{ 1.0f, 1.0f, 1.0f}, {1.0f, 1.0f}},
17856 static const DWORD ati1n_fourcc = MAKEFOURCC('A','T','I','1');
17857 static const DWORD ati2n_fourcc = MAKEFOURCC('A','T','I','2');
17858 static const struct
17860 struct vec2 position;
17861 D3DCOLOR amd_r500;
17862 D3DCOLOR amd_r600;
17863 D3DCOLOR nvidia_old;
17864 D3DCOLOR nvidia_new;
17866 expected_colors[] =
17868 {{ 80, 240}, 0x007fffff, 0x003f3f3f, 0x007f7f7f, 0x007f0000},
17869 {{240, 240}, 0x007fffff, 0x003f3f3f, 0x007f7f7f, 0x007f0000},
17870 {{400, 240}, 0x00007fff, 0x00007fff, 0x00007fff, 0x00007fff},
17871 {{560, 240}, 0x007f00ff, 0x007f00ff, 0x007f00ff, 0x007f00ff},
17873 IDirect3D9 *d3d;
17874 IDirect3DDevice9 *device;
17875 IDirect3DTexture9 *ati1n_texture, *ati2n_texture;
17876 D3DCAPS9 caps;
17877 D3DLOCKED_RECT rect;
17878 D3DCOLOR color;
17879 ULONG refcount;
17880 HWND window;
17881 HRESULT hr;
17882 unsigned int i;
17884 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
17885 0, 0, 640, 480, NULL, NULL, NULL, NULL);
17886 d3d = Direct3DCreate9(D3D_SDK_VERSION);
17887 ok(!!d3d, "Failed to create a D3D object.\n");
17888 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
17889 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, ati1n_fourcc)))
17891 skip("ATI1N textures are not supported, skipping test.\n");
17892 goto done;
17894 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
17895 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, ati2n_fourcc)))
17897 skip("ATI2N textures are not supported, skipping test.\n");
17898 goto done;
17900 if (!(device = create_device(d3d, window, window, TRUE)))
17902 skip("Failed to create a D3D device, skipping tests.\n");
17903 goto done;
17905 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
17906 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
17907 if (!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP))
17909 skip("D3DTA_TEMP not supported, skipping tests.\n");
17910 IDirect3DDevice9_Release(device);
17911 goto done;
17914 hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, 0, ati1n_fourcc,
17915 D3DPOOL_MANAGED, &ati1n_texture, NULL);
17916 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
17918 hr = IDirect3DTexture9_LockRect(ati1n_texture, 0, &rect, NULL, 0);
17919 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
17920 memcpy(rect.pBits, ati1n_data, sizeof(ati1n_data));
17921 hr = IDirect3DTexture9_UnlockRect(ati1n_texture, 0);
17922 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
17924 hr = IDirect3DDevice9_CreateTexture(device, 8, 4, 1, 0, ati2n_fourcc,
17925 D3DPOOL_MANAGED, &ati2n_texture, NULL);
17926 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
17928 hr = IDirect3DTexture9_LockRect(ati2n_texture, 0, &rect, NULL, 0);
17929 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
17930 memcpy(rect.pBits, ati2n_data, sizeof(ati2n_data));
17931 hr = IDirect3DTexture9_UnlockRect(ati2n_texture, 0);
17932 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
17934 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE2(0));
17935 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
17936 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BLENDTEXTUREALPHA);
17937 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
17938 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
17939 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
17940 /* The temporary register is initialized to 0. */
17941 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TEMP);
17942 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
17943 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
17944 ok(SUCCEEDED(hr), "Failed to set alpha op, hr %#x.\n", hr);
17945 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
17946 ok(SUCCEEDED(hr), "Failed to set alpha arg, hr %#x.\n", hr);
17947 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
17948 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
17949 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
17950 ok(SUCCEEDED(hr), "Failed to set mag filter, hr %#x.\n", hr);
17952 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff00ff, 1.0f, 0);
17953 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
17954 hr = IDirect3DDevice9_BeginScene(device);
17955 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
17956 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)ati1n_texture);
17957 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
17958 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads));
17959 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
17960 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)ati2n_texture);
17961 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
17962 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[4], sizeof(*quads));
17963 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
17964 hr = IDirect3DDevice9_EndScene(device);
17965 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
17967 for (i = 0; i < 4; ++i)
17969 color = getPixelColor(device, expected_colors[i].position.x, expected_colors[i].position.y);
17970 ok (color_match(color, expected_colors[i].amd_r500, 1)
17971 || color_match(color, expected_colors[i].amd_r600, 1)
17972 || color_match(color, expected_colors[i].nvidia_old, 1)
17973 || color_match(color, expected_colors[i].nvidia_new, 1),
17974 "Got unexpected color 0x%08x, case %u.\n", color, i);
17977 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17978 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17979 IDirect3DTexture9_Release(ati2n_texture);
17980 IDirect3DTexture9_Release(ati1n_texture);
17981 refcount = IDirect3DDevice9_Release(device);
17982 ok(!refcount, "Device has %u references left.\n", refcount);
17984 done:
17985 IDirect3D9_Release(d3d);
17986 DestroyWindow(window);
17989 static void test_fog_interpolation(void)
17991 HRESULT hr;
17992 IDirect3DDevice9 *device;
17993 IDirect3D9 *d3d;
17994 ULONG refcount;
17995 HWND window;
17996 D3DCOLOR color;
17997 static const struct
17999 struct vec3 position;
18000 D3DCOLOR diffuse;
18001 D3DCOLOR specular;
18003 quad[] =
18005 {{-1.0f, -1.0f, 0.0f}, 0xffff0000, 0xff000000},
18006 {{-1.0f, 1.0f, 0.0f}, 0xffff0000, 0xff000000},
18007 {{ 1.0f, -1.0f, 1.0f}, 0xffff0000, 0x00000000},
18008 {{ 1.0f, 1.0f, 1.0f}, 0xffff0000, 0x00000000},
18010 union
18012 DWORD d;
18013 float f;
18014 } conv;
18015 unsigned int i;
18016 static const struct
18018 D3DFOGMODE vfog, tfog;
18019 D3DSHADEMODE shade;
18020 D3DCOLOR middle_color;
18021 BOOL todo;
18023 tests[] =
18025 {D3DFOG_NONE, D3DFOG_NONE, D3DSHADE_FLAT, 0x00007f80, FALSE},
18026 {D3DFOG_NONE, D3DFOG_NONE, D3DSHADE_GOURAUD, 0x00007f80, FALSE},
18027 {D3DFOG_EXP, D3DFOG_NONE, D3DSHADE_FLAT, 0x00007f80, TRUE},
18028 {D3DFOG_EXP, D3DFOG_NONE, D3DSHADE_GOURAUD, 0x00007f80, TRUE},
18029 {D3DFOG_NONE, D3DFOG_EXP, D3DSHADE_FLAT, 0x0000ea15, FALSE},
18030 {D3DFOG_NONE, D3DFOG_EXP, D3DSHADE_GOURAUD, 0x0000ea15, FALSE},
18031 {D3DFOG_EXP, D3DFOG_EXP, D3DSHADE_FLAT, 0x0000ea15, FALSE},
18032 {D3DFOG_EXP, D3DFOG_EXP, D3DSHADE_GOURAUD, 0x0000ea15, FALSE},
18034 static const D3DMATRIX ident_mat =
18036 1.0f, 0.0f, 0.0f, 0.0f,
18037 0.0f, 1.0f, 0.0f, 0.0f,
18038 0.0f, 0.0f, 1.0f, 0.0f,
18039 0.0f, 0.0f, 0.0f, 1.0f
18040 }}};
18041 D3DCAPS9 caps;
18043 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
18044 0, 0, 640, 480, NULL, NULL, NULL, NULL);
18045 d3d = Direct3DCreate9(D3D_SDK_VERSION);
18046 ok(!!d3d, "Failed to create a D3D object.\n");
18048 if (!(device = create_device(d3d, window, window, TRUE)))
18050 skip("Failed to create a D3D device, skipping tests.\n");
18051 IDirect3D9_Release(d3d);
18052 DestroyWindow(window);
18053 return;
18056 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
18057 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
18058 if (!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE))
18059 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping some fog tests\n");
18061 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
18062 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr);
18063 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
18064 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18065 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
18066 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18067 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
18068 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18069 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0x0000ff00);
18070 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18071 conv.f = 5.0;
18072 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGDENSITY, conv.d);
18073 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18075 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
18076 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
18077 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TFACTOR);
18078 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
18079 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x000000ff);
18080 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18082 /* Some of the tests seem to depend on the projection matrix explicitly
18083 * being set to an identity matrix, even though that's the default.
18084 * (AMD Radeon X1600, AMD Radeon HD 6310, Windows 7). Without this,
18085 * the drivers seem to use a static z = 1.0 input for the fog equation.
18086 * The input value is independent of the actual z and w component of
18087 * the vertex position. */
18088 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &ident_mat);
18089 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
18091 for (i = 0; i < sizeof(tests) / sizeof(*tests); i++)
18093 if(!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE) && tests[i].tfog)
18094 continue;
18096 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00808080, 0.0f, 0);
18097 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
18099 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, tests[i].shade);
18100 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18101 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, tests[i].vfog);
18102 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18103 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, tests[i].tfog);
18104 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18105 hr = IDirect3DDevice9_BeginScene(device);
18106 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
18107 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
18108 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
18109 hr = IDirect3DDevice9_EndScene(device);
18110 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
18112 color = getPixelColor(device, 0, 240);
18113 ok(color_match(color, 0x000000ff, 2), "Got unexpected color 0x%08x, case %u.\n", color, i);
18114 color = getPixelColor(device, 320, 240);
18115 todo_wine_if (tests[i].todo)
18116 ok(color_match(color, tests[i].middle_color, 2),
18117 "Got unexpected color 0x%08x, case %u.\n", color, i);
18118 color = getPixelColor(device, 639, 240);
18119 ok(color_match(color, 0x0000fd02, 2), "Got unexpected color 0x%08x, case %u.\n", color, i);
18120 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
18121 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
18124 refcount = IDirect3DDevice9_Release(device);
18125 ok(!refcount, "Device has %u references left.\n", refcount);
18126 IDirect3D9_Release(d3d);
18127 DestroyWindow(window);
18130 static void test_negative_fixedfunction_fog(void)
18132 HRESULT hr;
18133 IDirect3DDevice9 *device;
18134 IDirect3D9 *d3d;
18135 ULONG refcount;
18136 HWND window;
18137 D3DCOLOR color;
18138 static const struct
18140 struct vec3 position;
18141 D3DCOLOR diffuse;
18143 quad[] =
18145 {{-1.0f, -1.0f, -0.5f}, 0xffff0000},
18146 {{-1.0f, 1.0f, -0.5f}, 0xffff0000},
18147 {{ 1.0f, -1.0f, -0.5f}, 0xffff0000},
18148 {{ 1.0f, 1.0f, -0.5f}, 0xffff0000},
18150 static const struct
18152 struct vec4 position;
18153 D3DCOLOR diffuse;
18155 tquad[] =
18157 {{ 0.0f, 0.0f, -0.5f, 1.0f}, 0xffff0000},
18158 {{640.0f, 0.0f, -0.5f, 1.0f}, 0xffff0000},
18159 {{ 0.0f, 480.0f, -0.5f, 1.0f}, 0xffff0000},
18160 {{640.0f, 480.0f, -0.5f, 1.0f}, 0xffff0000},
18162 unsigned int i;
18163 static const D3DMATRIX zero =
18165 1.0f, 0.0f, 0.0f, 0.0f,
18166 0.0f, 1.0f, 0.0f, 0.0f,
18167 0.0f, 0.0f, 0.0f, 0.0f,
18168 0.0f, 0.0f, 0.0f, 1.0f
18169 }}};
18170 /* Needed to make AMD drivers happy. Yeah, it is not supposed to
18171 * have an effect on RHW draws. */
18172 static const D3DMATRIX identity =
18174 1.0f, 0.0f, 0.0f, 0.0f,
18175 0.0f, 1.0f, 0.0f, 0.0f,
18176 0.0f, 0.0f, 1.0f, 0.0f,
18177 0.0f, 0.0f, 0.0f, 1.0f
18178 }}};
18179 static const struct
18181 DWORD pos_type;
18182 const void *quad;
18183 size_t stride;
18184 const D3DMATRIX *matrix;
18185 union
18187 float f;
18188 DWORD d;
18189 } start, end;
18190 D3DFOGMODE vfog, tfog;
18191 DWORD color, color_broken, color_broken2;
18193 tests[] =
18195 /* Run the XYZRHW tests first. Depth clamping is broken after RHW draws on the testbot.
18197 * Geforce8+ GPUs on Windows abs() table fog, everything else does not. */
18198 {D3DFVF_XYZRHW, tquad, sizeof(*tquad), &identity, { 0.0f}, {1.0f},
18199 D3DFOG_NONE, D3DFOG_LINEAR, 0x00ff0000, 0x00808000, 0x00808000},
18200 /* r200 GPUs and presumably all d3d8 and older HW clamp the fog
18201 * parameters to 0.0 and 1.0 in the table fog case. */
18202 {D3DFVF_XYZRHW, tquad, sizeof(*tquad), &identity, {-1.0f}, {0.0f},
18203 D3DFOG_NONE, D3DFOG_LINEAR, 0x00808000, 0x00ff0000, 0x0000ff00},
18204 /* test_fog_interpolation shows that vertex fog evaluates the fog
18205 * equation in the vertex pipeline. Start = -1.0 && end = 0.0 shows
18206 * that the abs happens before the fog equation is evaluated.
18208 * Vertex fog abs() behavior is the same on all GPUs. */
18209 {D3DFVF_XYZ, quad, sizeof(*quad), &zero, { 0.0f}, {1.0f},
18210 D3DFOG_LINEAR, D3DFOG_NONE, 0x00808000, 0x00808000, 0x00808000},
18211 {D3DFVF_XYZ, quad, sizeof(*quad), &zero, {-1.0f}, {0.0f},
18212 D3DFOG_LINEAR, D3DFOG_NONE, 0x0000ff00, 0x0000ff00, 0x0000ff00},
18213 {D3DFVF_XYZ, quad, sizeof(*quad), &zero, { 0.0f}, {1.0f},
18214 D3DFOG_EXP, D3DFOG_NONE, 0x009b6400, 0x009b6400, 0x009b6400},
18216 D3DCAPS9 caps;
18218 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
18219 0, 0, 640, 480, NULL, NULL, NULL, NULL);
18220 d3d = Direct3DCreate9(D3D_SDK_VERSION);
18221 ok(!!d3d, "Failed to create a D3D object.\n");
18223 if (!(device = create_device(d3d, window, window, TRUE)))
18225 skip("Failed to create a D3D device, skipping tests.\n");
18226 IDirect3D9_Release(d3d);
18227 DestroyWindow(window);
18228 return;
18231 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
18232 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
18233 if (!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE))
18234 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping some fog tests.\n");
18236 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
18237 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18238 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
18239 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18240 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
18241 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18242 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0x0000ff00);
18243 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18244 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
18245 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
18247 for (i = 0; i < sizeof(tests) / sizeof(*tests); i++)
18249 if (!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE) && tests[i].tfog)
18250 continue;
18252 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x000000ff, 0.0f, 0);
18253 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
18255 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, tests[i].matrix);
18256 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
18257 hr = IDirect3DDevice9_SetFVF(device, tests[i].pos_type | D3DFVF_DIFFUSE);
18258 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr);
18259 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, tests[i].start.d);
18260 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18261 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, tests[i].end.d);
18262 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18263 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, tests[i].vfog);
18264 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18265 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, tests[i].tfog);
18266 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18268 hr = IDirect3DDevice9_BeginScene(device);
18269 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
18270 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, tests[i].quad, tests[i].stride);
18271 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
18272 hr = IDirect3DDevice9_EndScene(device);
18273 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
18275 color = getPixelColor(device, 320, 240);
18276 ok(color_match(color, tests[i].color, 2) || broken(color_match(color, tests[i].color_broken, 2))
18277 || broken(color_match(color, tests[i].color_broken2, 2)),
18278 "Got unexpected color 0x%08x, case %u.\n", color, i);
18279 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
18280 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
18283 refcount = IDirect3DDevice9_Release(device);
18284 ok(!refcount, "Device has %u references left.\n", refcount);
18285 IDirect3D9_Release(d3d);
18286 DestroyWindow(window);
18289 static void test_position_index(void)
18291 static const D3DVERTEXELEMENT9 decl_elements[] =
18293 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
18294 {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 1},
18295 D3DDECL_END()
18297 /* Declaring (and using) a position1 output semantic in a VS fails at draw time on AMD
18298 * but works on Nvidia.
18299 * MSDN is not consistent on this point. */
18300 static const DWORD vs_code[] =
18302 0xfffe0300, /* vs_3_0 */
18303 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position0 v0 */
18304 0x0200001f, 0x80010000, 0x900f0001, /* dcl_position1 v1 */
18305 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position0 o0 */
18306 0x0200001f, 0x80010000, 0xe00f0001, /* dcl_position1 o1 */
18307 0x0200001f, 0x80000005, 0xe00f0002, /* dcl_texcoord0 o2 */
18308 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
18309 0x02000001, 0xe00f0001, 0x90e40001, /* mov o1, v1 */
18310 0x02000001, 0xe00f0002, 0x90e40001, /* mov o2, v1 */
18311 0x0000ffff /* end */
18313 static const DWORD vs_code_2[] =
18315 0xfffe0300, /* vs_3_0 */
18316 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position0 v0 */
18317 0x0200001f, 0x80010000, 0x900f0001, /* dcl_position1 v1 */
18318 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position0 o0 */
18319 0x0200001f, 0x80000005, 0xe00f0002, /* dcl_texcoord0 o2 */
18320 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
18321 0x02000001, 0xe00f0002, 0x90e40001, /* mov o2, v1 */
18322 0x0000ffff /* end */
18324 static const DWORD ps_code[] =
18326 0xffff0300, /* ps_3_0 */
18327 0x0200001f, 0x80010000, 0x900f0000, /* dcl_position1 v0 */
18328 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
18329 0x0000ffff /* end */
18331 static const DWORD ps_code_2[] =
18333 0xffff0300, /* ps_3_0 */
18334 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord0 v0 */
18335 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
18336 0x0000ffff /* end */
18338 /* This one is considered invalid by the native shader assembler. */
18339 static const DWORD ps_code_bad[] =
18341 0xffff0300, /* ps_3_0 */
18342 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position0 v0 */
18343 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
18344 0x0000ffff /* end */
18346 static const struct
18348 struct vec3 position;
18349 struct vec3 position1;
18351 quad[] =
18353 {{-1.0f, -1.0f, 0.5f}, {1.0f, 0.0f, 0.0f}},
18354 {{-1.0f, 1.0f, 0.5f}, {1.0f, 0.0f, 0.0f}},
18355 {{ 1.0f, -1.0f, 0.5f}, {0.0f, 1.0f, 0.0f}},
18356 {{ 1.0f, 1.0f, 0.5f}, {0.0f, 1.0f, 0.0f}},
18358 static const struct
18360 struct vec2 position;
18361 D3DCOLOR expected_color;
18362 D3DCOLOR broken_color;
18364 expected_colors[] =
18366 {{ 80, 240}, 0x00df2000, 0x00ff00ff},
18367 {{240, 240}, 0x009f6000, 0x00ff00ff},
18368 {{400, 240}, 0x00609f00, 0x00ff00ff},
18369 {{560, 240}, 0x0020df00, 0x00ff00ff},
18371 IDirect3D9 *d3d;
18372 IDirect3DDevice9 *device;
18373 IDirect3DVertexDeclaration9 *vertex_declaration;
18374 IDirect3DVertexShader9 *vs, *vs2;
18375 IDirect3DPixelShader9 *ps, *ps2;
18376 D3DCAPS9 caps;
18377 D3DCOLOR color;
18378 ULONG refcount;
18379 HWND window;
18380 HRESULT hr;
18381 unsigned int i;
18383 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
18384 0, 0, 640, 480, NULL, NULL, NULL, NULL);
18385 d3d = Direct3DCreate9(D3D_SDK_VERSION);
18386 ok(!!d3d, "Failed to create a D3D object.\n");
18387 if (!(device = create_device(d3d, window, window, TRUE)))
18389 skip("Failed to create a D3D device, skipping tests.\n");
18390 goto done;
18393 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
18394 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
18395 if (caps.VertexShaderVersion < D3DVS_VERSION(3, 0)
18396 || caps.PixelShaderVersion < D3DPS_VERSION(3, 0))
18398 skip("Shader model 3.0 unsupported, skipping tests.\n");
18399 IDirect3DDevice9_Release(device);
18400 goto done;
18403 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
18404 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed, hr %#x\n", hr);
18406 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
18407 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x\n", hr);
18409 hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vs);
18410 ok(SUCCEEDED(hr), "CreateVertexShader failed, hr %#x.\n", hr);
18411 hr = IDirect3DDevice9_CreateVertexShader(device, vs_code_2, &vs2);
18412 ok(SUCCEEDED(hr), "CreateVertexShader failed, hr %#x.\n", hr);
18414 hr = IDirect3DDevice9_SetVertexShader(device, vs);
18415 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
18417 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code_bad, &ps);
18418 ok(hr == D3DERR_INVALIDCALL, "CreatePixelShader returned hr %#x.\n", hr);
18420 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
18421 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
18422 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code_2, &ps2);
18423 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
18425 hr = IDirect3DDevice9_SetPixelShader(device, ps);
18426 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
18428 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff00ff, 1.0f, 0);
18429 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
18430 hr = IDirect3DDevice9_BeginScene(device);
18431 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
18432 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
18433 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
18434 hr = IDirect3DDevice9_EndScene(device);
18435 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
18437 for (i = 0; i < sizeof(expected_colors) / sizeof(expected_colors[0]); ++i)
18439 color = getPixelColor(device, expected_colors[i].position.x, expected_colors[i].position.y);
18440 ok (color_match(color, expected_colors[i].expected_color, 1)
18441 || broken(color_match(color, expected_colors[i].broken_color, 1)),
18442 "Got unexpected color 0x%08x, case %u.\n", color, i);
18445 hr = IDirect3DDevice9_SetPixelShader(device, ps2);
18446 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
18448 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff00ff, 1.0f, 0);
18449 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
18450 hr = IDirect3DDevice9_BeginScene(device);
18451 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
18452 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
18453 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
18454 hr = IDirect3DDevice9_EndScene(device);
18455 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
18457 for (i = 0; i < sizeof(expected_colors) / sizeof(expected_colors[0]); ++i)
18459 color = getPixelColor(device, expected_colors[i].position.x, expected_colors[i].position.y);
18460 ok (color_match(color, expected_colors[i].expected_color, 1)
18461 || broken(color_match(color, expected_colors[i].broken_color, 1)),
18462 "Got unexpected color 0x%08x, case %u.\n", color, i);
18465 hr = IDirect3DDevice9_SetVertexShader(device, vs2);
18466 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
18468 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff00ff, 1.0f, 0);
18469 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
18470 hr = IDirect3DDevice9_BeginScene(device);
18471 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
18472 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
18473 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
18474 hr = IDirect3DDevice9_EndScene(device);
18475 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
18477 for (i = 0; i < sizeof(expected_colors) / sizeof(expected_colors[0]); ++i)
18479 color = getPixelColor(device, expected_colors[i].position.x, expected_colors[i].position.y);
18480 ok (color_match(color, expected_colors[i].expected_color, 1),
18481 "Got unexpected color 0x%08x, case %u.\n", color, i);
18484 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
18485 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
18487 IDirect3DPixelShader9_Release(ps2);
18488 IDirect3DPixelShader9_Release(ps);
18489 IDirect3DVertexShader9_Release(vs2);
18490 IDirect3DVertexShader9_Release(vs);
18491 IDirect3DVertexDeclaration9_Release(vertex_declaration);
18492 refcount = IDirect3DDevice9_Release(device);
18493 ok(!refcount, "Device has %u references left.\n", refcount);
18495 done:
18496 IDirect3D9_Release(d3d);
18497 DestroyWindow(window);
18500 static void test_table_fog_zw(void)
18502 HRESULT hr;
18503 IDirect3DDevice9 *device;
18504 IDirect3D9 *d3d;
18505 ULONG refcount;
18506 HWND window;
18507 D3DCOLOR color;
18508 D3DCAPS9 caps;
18509 static struct
18511 struct vec4 position;
18512 D3DCOLOR diffuse;
18514 quad[] =
18516 {{ 0.0f, 0.0f, 0.0f, 0.0f}, 0xffff0000},
18517 {{640.0f, 0.0f, 0.0f, 0.0f}, 0xffff0000},
18518 {{ 0.0f, 480.0f, 0.0f, 0.0f}, 0xffff0000},
18519 {{640.0f, 480.0f, 0.0f, 0.0f}, 0xffff0000},
18521 static const D3DMATRIX identity =
18523 1.0f, 0.0f, 0.0f, 0.0f,
18524 0.0f, 1.0f, 0.0f, 0.0f,
18525 0.0f, 0.0f, 1.0f, 0.0f,
18526 0.0f, 0.0f, 0.0f, 1.0f
18527 }}};
18528 static const struct
18530 float z, w;
18531 D3DZBUFFERTYPE z_test;
18532 D3DCOLOR color;
18534 tests[] =
18536 {0.7f, 0.0f, D3DZB_TRUE, 0x004cb200},
18537 {0.7f, 0.0f, D3DZB_FALSE, 0x004cb200},
18538 {0.7f, 0.3f, D3DZB_TRUE, 0x004cb200},
18539 {0.7f, 0.3f, D3DZB_FALSE, 0x004cb200},
18540 {0.7f, 3.0f, D3DZB_TRUE, 0x004cb200},
18541 {0.7f, 3.0f, D3DZB_FALSE, 0x004cb200},
18542 {0.3f, 0.0f, D3DZB_TRUE, 0x00b24c00},
18543 {0.3f, 0.0f, D3DZB_FALSE, 0x00b24c00},
18545 unsigned int i;
18547 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
18548 0, 0, 640, 480, NULL, NULL, NULL, NULL);
18549 d3d = Direct3DCreate9(D3D_SDK_VERSION);
18550 ok(!!d3d, "Failed to create a D3D object.\n");
18552 if (!(device = create_device(d3d, window, window, TRUE)))
18554 skip("Failed to create a D3D device, skipping tests.\n");
18555 IDirect3D9_Release(d3d);
18556 DestroyWindow(window);
18557 return;
18560 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
18561 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
18562 if (!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE))
18564 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping POSITIONT table fog test.\n");
18565 goto done;
18568 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
18569 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18570 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
18571 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18572 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0x0000ff00);
18573 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18574 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
18575 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
18576 /* Work around an AMD Windows driver bug. Needs a proj matrix applied redundantly. */
18577 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &identity);
18578 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
18579 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
18580 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18581 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
18582 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr);
18584 for (i = 0; i < sizeof(tests) / sizeof(*tests); ++i)
18586 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
18587 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
18589 quad[0].position.z = tests[i].z;
18590 quad[1].position.z = tests[i].z;
18591 quad[2].position.z = tests[i].z;
18592 quad[3].position.z = tests[i].z;
18593 quad[0].position.w = tests[i].w;
18594 quad[1].position.w = tests[i].w;
18595 quad[2].position.w = tests[i].w;
18596 quad[3].position.w = tests[i].w;
18597 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, tests[i].z_test);
18598 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18600 hr = IDirect3DDevice9_BeginScene(device);
18601 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
18602 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
18603 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
18604 hr = IDirect3DDevice9_EndScene(device);
18605 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
18607 color = getPixelColor(device, 320, 240);
18608 ok(color_match(color, tests[i].color, 2),
18609 "Got unexpected color 0x%08x, expected 0x%08x, case %u.\n", color, tests[i].color, i);
18610 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
18611 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
18614 done:
18615 refcount = IDirect3DDevice9_Release(device);
18616 ok(!refcount, "Device has %u references left.\n", refcount);
18617 IDirect3D9_Release(d3d);
18618 DestroyWindow(window);
18621 static void test_signed_formats(void)
18623 IDirect3DDevice9 *device;
18624 HWND window;
18625 HRESULT hr;
18626 unsigned int i, j, x, y;
18627 IDirect3DTexture9 *texture, *texture_sysmem;
18628 IDirect3DSurface9 *src_surface, *dst_surface;
18629 D3DLOCKED_RECT locked_rect;
18630 IDirect3DPixelShader9 *shader, *shader_alpha;
18631 IDirect3D9 *d3d;
18632 D3DCOLOR color;
18633 D3DCAPS9 caps;
18634 ULONG refcount;
18636 /* The input data was designed for D3DFMT_L6V5U5 and then transferred
18637 * to the other formats because L6V5U5 is the lowest precision format.
18638 * It tests the extreme values -1.0 (-16) and 1.0 (15) for U/V and
18639 * 0.0 (0) and 1.0 (63) for L, the neutral point 0 as well as -1 and 1.
18640 * Some other intermediate values are tested too. The input value -15
18641 * (min + 1) is tested as well. Unlike what OpenGL 4.4 says in section
18642 * 2.3.4.1, this value does not represent -1.0. In the interest of re-
18643 * using the expected output data the 8 bit and 16 bit values in V8U8
18644 * and V16U16 match (post-normalization) the 5 bit input values. Thus
18645 * -1, 1 and -127 are not tested in V8U8.
18647 * 8 bit specific values like -127 are tested in the Q channel of
18648 * D3DFMT_Q8W8V8U8. Here d3d seems to follow the rules from the GL
18649 * spec. AMD's r200 is broken though and returns a value < -1.0 for
18650 * -128. The difference between using -127 or -128 as the lowest
18651 * possible value gets lost in the slop of 1 though. */
18652 static const USHORT content_v8u8[4][4] =
18654 {0x0000, 0x7f7f, 0x8880, 0x0000},
18655 {0x0080, 0x8000, 0x7f00, 0x007f},
18656 {0x193b, 0xe8c8, 0x0808, 0xf8f8},
18657 {0x4444, 0xc0c0, 0xa066, 0x22e0},
18659 static const DWORD content_v16u16[4][4] =
18661 {0x00000000, 0x7fff7fff, 0x88008000, 0x00000000},
18662 {0x00008000, 0x80000000, 0x7fff0000, 0x00007fff},
18663 {0x19993bbb, 0xe800c800, 0x08880888, 0xf800f800},
18664 {0x44444444, 0xc000c000, 0xa0006666, 0x2222e000},
18666 static const DWORD content_q8w8v8u8[4][4] =
18668 {0x00000000, 0xff7f7f7f, 0x7f008880, 0x817f0000},
18669 {0x10000080, 0x20008000, 0x30007f00, 0x4000007f},
18670 {0x5020193b, 0x6028e8c8, 0x70020808, 0x807ff8f8},
18671 {0x90414444, 0xa000c0c0, 0x8261a066, 0x834922e0},
18673 static const DWORD content_x8l8v8u8[4][4] =
18675 {0x00000000, 0x00ff7f7f, 0x00008880, 0x00ff0000},
18676 {0x00000080, 0x00008000, 0x00007f00, 0x0000007f},
18677 {0x0041193b, 0x0051e8c8, 0x00040808, 0x00fff8f8},
18678 {0x00824444, 0x0000c0c0, 0x00c2a066, 0x009222e0},
18680 /* D3DFMT_L6V5U5 has poor precision on some GPUs. On a GeForce 7 the highest V and U value (15)
18681 * results in the output color 0xfb, which is 4 steps away from the correct value 0xff. It is
18682 * not the ~0xf0 you'd get if you blindly left-shifted the 5 bit value to form an 8 bit value
18683 * though.
18685 * There may also be an off-by-one bug involved: The value -7 should result in the output 0x47,
18686 * but ends up as 0x4d. Likewise, -3 becomes 0x6e instead of 0x67. Those values are close to
18687 * the proper results of -6 and -2.
18689 * On Wine the emulation with unsigned R5G6B5 has poor precision, e.g. the signed 0 becomes 16,
18690 * and ((16 / 31) - 0.5) * 2.0 is 0.032 instead of 0.000. The final output result we read back
18691 * is 0x84 instead of 0x80. */
18692 static const USHORT content_l6v5u5[4][4] =
18694 {0x0000, 0xfdef, 0x0230, 0xfc00},
18695 {0x0010, 0x0200, 0x01e0, 0x000f},
18696 {0x4067, 0x53b9, 0x0421, 0xffff},
18697 {0x8108, 0x0318, 0xc28c, 0x909c},
18699 static const struct
18701 D3DFORMAT format;
18702 const char *name;
18703 const void *content;
18704 SIZE_T pixel_size;
18705 BOOL blue, alpha;
18706 unsigned int slop, slop_broken, alpha_broken;
18708 formats[] =
18710 {D3DFMT_V8U8, "D3DFMT_V8U8", content_v8u8, sizeof(WORD), FALSE, FALSE, 1, 0, FALSE},
18711 {D3DFMT_V16U16, "D3DFMT_V16U16", content_v16u16, sizeof(DWORD), FALSE, FALSE, 1, 0, FALSE},
18712 {D3DFMT_Q8W8V8U8, "D3DFMT_Q8W8V8U8", content_q8w8v8u8, sizeof(DWORD), TRUE, TRUE, 1, 0, TRUE },
18713 {D3DFMT_X8L8V8U8, "D3DFMT_X8L8V8U8", content_x8l8v8u8, sizeof(DWORD), TRUE, FALSE, 1, 0, FALSE},
18714 {D3DFMT_L6V5U5, "D3DFMT_L6V5U5", content_l6v5u5, sizeof(WORD), TRUE, FALSE, 4, 7, FALSE},
18716 static const struct
18718 D3DPOOL pool;
18719 UINT width;
18720 RECT src_rect;
18721 POINT dst_point;
18723 tests[] =
18725 {D3DPOOL_SYSTEMMEM, 4, {1, 1, 2, 3}, {2, 0}},
18726 {D3DPOOL_SYSTEMMEM, 1, {0, 1, 1, 3}, {0, 0}},
18727 {D3DPOOL_MANAGED, 4, {1, 1, 2, 3}, {2, 0}},
18728 {D3DPOOL_MANAGED, 1, {0, 1, 1, 3}, {0, 0}},
18730 static const DWORD shader_code[] =
18732 0xffff0101, /* ps_1_1 */
18733 0x00000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, /* def c0, 0.5, 0.5, 0,5, 0,5 */
18734 0x00000042, 0xb00f0000, /* tex t0 */
18735 0x00000004, 0x800f0000, 0xb0e40000, 0xa0e40000, 0xa0e40000, /* mad r0, t0, c0, c0 */
18736 0x0000ffff /* end */
18738 static const DWORD shader_code_alpha[] =
18740 /* The idea of this shader is to replicate the alpha value in .rg, and set
18741 * blue to 1.0 iff the alpha value is < -1.0 and 0.0 otherwise. */
18742 0xffff0101, /* ps_1_1 */
18743 0x00000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, /* def c0, 0.5, 0.5, 0.5, 0.5 */
18744 0x00000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0 */
18745 0x00000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c2, 0.0, 0.0, 1.0, 0.0 */
18746 0x00000042, 0xb00f0000, /* tex t0 */
18747 0x00000004, 0x80070000, 0xb0ff0000, 0xa0e40000, 0xa0e40000, /* mad r0.rgb, t0.a, c0, c0 */
18748 0x00000003, 0x80080000, 0xb1ff0000, 0xa0e40000, /* sub r0.a, -t0.a, c0 */
18749 0x00000050, 0x80080000, 0x80ff0000, 0xa0ff0001, 0xa0ff0002, /* cnd r0.a, r0.a, c1.a, c2.a */
18750 0x00000005, 0x80070001, 0xa0e40001, 0x80e40000, /* mul r1.rgb, c1, r0 */
18751 0x00000004, 0x80070000, 0x80ff0000, 0xa0e40002, 0x80e40001, /* mad r0.rgb, r0.a, c2, r1 */
18752 0x0000ffff /* end */
18754 static const struct
18756 struct vec3 position;
18757 struct vec2 texcrd;
18759 quad[] =
18761 /* Flip the y coordinate to make the input and
18762 * output arrays easier to compare. */
18763 {{ -1.0f, -1.0f, 0.0f}, { 0.0f, 1.0f}},
18764 {{ -1.0f, 1.0f, 0.0f}, { 0.0f, 0.0f}},
18765 {{ 1.0f, -1.0f, 0.0f}, { 1.0f, 1.0f}},
18766 {{ 1.0f, 1.0f, 0.0f}, { 1.0f, 0.0f}},
18768 static const D3DCOLOR expected_alpha[4][4] =
18770 {0x00808000, 0x007f7f00, 0x00ffff00, 0x00000000},
18771 {0x00909000, 0x00a0a000, 0x00b0b000, 0x00c0c000},
18772 {0x00d0d000, 0x00e0e000, 0x00f0f000, 0x00000000},
18773 {0x00101000, 0x00202000, 0x00010100, 0x00020200},
18775 static const BOOL alpha_broken[4][4] =
18777 {FALSE, FALSE, FALSE, FALSE},
18778 {FALSE, FALSE, FALSE, FALSE},
18779 {FALSE, FALSE, FALSE, TRUE },
18780 {FALSE, FALSE, FALSE, FALSE},
18782 static const D3DCOLOR expected_colors[4][4] =
18784 {0x00808080, 0x00fefeff, 0x00010780, 0x008080ff},
18785 {0x00018080, 0x00800180, 0x0080fe80, 0x00fe8080},
18786 {0x00ba98a0, 0x004767a8, 0x00888881, 0x007878ff},
18787 {0x00c3c3c0, 0x003f3f80, 0x00e51fe1, 0x005fa2c8},
18789 static const D3DCOLOR expected_colors2[4][4] =
18791 {0x00808080, 0x00fefeff, 0x00800180, 0x008080ff},
18792 {0x00018080, 0x00800180, 0x004767a8, 0x00fe8080},
18793 {0x00ba98a0, 0x004767a8, 0x00888881, 0x007878ff},
18794 {0x00c3c3c0, 0x003f3f80, 0x00e51fe1, 0x005fa2c8},
18796 static const D3DCOLOR expected_colors3[4] =
18798 0x00018080,
18799 0x00ba98a0,
18800 0x00ba98a0,
18801 0x00c3c3c0,
18803 D3DCOLOR expected_color;
18805 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
18806 0, 0, 640, 480, NULL, NULL, NULL, NULL);
18807 d3d = Direct3DCreate9(D3D_SDK_VERSION);
18808 ok(!!d3d, "Failed to create a D3D object.\n");
18810 if (!(device = create_device(d3d, window, window, TRUE)))
18812 skip("Failed to create a D3D device, skipping tests.\n");
18813 IDirect3D9_Release(d3d);
18814 DestroyWindow(window);
18815 return;
18818 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
18819 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
18821 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 1))
18823 skip("Pixel shaders not supported, skipping converted format test.\n");
18824 goto done;
18827 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
18828 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18829 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
18830 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
18831 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
18832 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
18833 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_alpha, &shader_alpha);
18834 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
18836 for (i = 0; i < sizeof(formats) / sizeof(*formats); i++)
18838 hr = IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
18839 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, formats[i].format);
18840 if (FAILED(hr))
18842 skip("Format %s not supported, skipping.\n", formats[i].name);
18843 continue;
18846 for (j = 0; j < sizeof(tests) / sizeof(*tests); j++)
18848 texture_sysmem = NULL;
18849 hr = IDirect3DDevice9_CreateTexture(device, tests[j].width, 4, 1, 0,
18850 formats[i].format, tests[j].pool, &texture, NULL);
18851 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
18853 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
18854 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
18855 for (y = 0; y < 4; y++)
18857 memcpy((char *)locked_rect.pBits + y * locked_rect.Pitch,
18858 (char *)formats[i].content + y * 4 * formats[i].pixel_size,
18859 tests[j].width * formats[i].pixel_size);
18861 hr = IDirect3DTexture9_UnlockRect(texture, 0);
18862 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
18864 if (tests[j].pool == D3DPOOL_SYSTEMMEM)
18866 texture_sysmem = texture;
18867 hr = IDirect3DDevice9_CreateTexture(device, tests[j].width, 4, 1, 0,
18868 formats[i].format, D3DPOOL_DEFAULT, &texture, NULL);
18869 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
18871 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)texture_sysmem,
18872 (IDirect3DBaseTexture9 *)texture);
18873 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
18876 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
18877 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
18878 hr = IDirect3DDevice9_SetPixelShader(device, shader_alpha);
18879 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
18881 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00330033, 0.0f, 0);
18882 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
18883 hr = IDirect3DDevice9_BeginScene(device);
18884 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
18885 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(*quad));
18886 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
18887 hr = IDirect3DDevice9_EndScene(device);
18888 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
18890 for (y = 0; y < 4; y++)
18892 for (x = 0; x < tests[j].width; x++)
18894 BOOL r200_broken = formats[i].alpha_broken && alpha_broken[y][x];
18895 if (formats[i].alpha)
18896 expected_color = expected_alpha[y][x];
18897 else
18898 expected_color = 0x00ffff00;
18900 color = getPixelColor(device, 80 + 160 * x, 60 + 120 * y);
18901 ok(color_match(color, expected_color, 1) || broken(r200_broken),
18902 "Expected color 0x%08x, got 0x%08x, format %s, location %ux%u.\n",
18903 expected_color, color, formats[i].name, x, y);
18906 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
18907 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
18909 hr = IDirect3DDevice9_SetPixelShader(device, shader);
18910 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
18912 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00330033, 0.0f, 0);
18913 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
18914 hr = IDirect3DDevice9_BeginScene(device);
18915 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
18916 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(*quad));
18917 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
18918 hr = IDirect3DDevice9_EndScene(device);
18919 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
18921 for (y = 0; y < 4; y++)
18923 for (x = 0; x < tests[j].width; x++)
18925 expected_color = expected_colors[y][x];
18926 if (!formats[i].blue)
18927 expected_color |= 0x000000ff;
18929 color = getPixelColor(device, 80 + 160 * x, 60 + 120 * y);
18930 ok(color_match(color, expected_color, formats[i].slop)
18931 || broken(color_match(color, expected_color, formats[i].slop_broken)),
18932 "Expected color 0x%08x, got 0x%08x, format %s, location %ux%u.\n",
18933 expected_color, color, formats[i].name, x, y);
18936 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
18937 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
18939 if (tests[j].pool != D3DPOOL_SYSTEMMEM)
18941 IDirect3DTexture9_Release(texture);
18942 continue;
18945 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &dst_surface);
18946 ok(SUCCEEDED(hr), "Failed to get surface, hr %#x.\n", hr);
18947 IDirect3DTexture9_GetSurfaceLevel(texture_sysmem, 0, &src_surface);
18948 ok(SUCCEEDED(hr), "Failed to get surface, hr %#x.\n", hr);
18950 hr = IDirect3DDevice9_UpdateSurface(device, src_surface,
18951 &tests[j].src_rect, dst_surface, &tests[j].dst_point);
18952 ok(SUCCEEDED(hr), "Failed to update surface, hr %#x.\n", hr);
18954 IDirect3DSurface9_Release(dst_surface);
18955 IDirect3DSurface9_Release(src_surface);
18957 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00003300, 0.0f, 0);
18958 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
18959 hr = IDirect3DDevice9_BeginScene(device);
18960 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
18961 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(*quad));
18962 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
18963 hr = IDirect3DDevice9_EndScene(device);
18964 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
18966 for (y = 0; y < 4; y++)
18968 for (x = 0; x < tests[j].width; x++)
18970 if (tests[j].width == 4)
18971 expected_color = expected_colors2[y][x];
18972 else
18973 expected_color = expected_colors3[y];
18975 if (!formats[i].blue)
18976 expected_color |= 0x000000ff;
18978 color = getPixelColor(device, 80 + 160 * x, 60 + 120 * y);
18979 ok(color_match(color, expected_color, formats[i].slop)
18980 || broken(color_match(color, expected_color, formats[i].slop_broken)),
18981 "Expected color 0x%08x, got 0x%08x, format %s, location %ux%u.\n",
18982 expected_color, color, formats[i].name, x, y);
18985 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
18986 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
18988 IDirect3DTexture9_Release(texture_sysmem);
18989 IDirect3DTexture9_Release(texture);
18993 IDirect3DPixelShader9_Release(shader);
18994 IDirect3DPixelShader9_Release(shader_alpha);
18996 done:
18997 refcount = IDirect3DDevice9_Release(device);
18998 ok(!refcount, "Device has %u references left.\n", refcount);
18999 IDirect3D9_Release(d3d);
19000 DestroyWindow(window);
19003 static void test_multisample_mismatch(void)
19005 IDirect3DDevice9 *device;
19006 IDirect3D9 *d3d;
19007 HWND window;
19008 HRESULT hr;
19009 D3DCOLOR color;
19010 ULONG refcount;
19011 IDirect3DSurface9 *rt, *rt_multi, *ds;
19012 static const struct
19014 struct vec3 position;
19015 DWORD color;
19017 quad[] =
19019 {{ -1.0f, -1.0f, 0.0f}, 0x000000ff},
19020 {{ -1.0f, 1.0f, 0.0f}, 0x000000ff},
19021 {{ 1.0f, -1.0f, 1.0f}, 0x000000ff},
19022 {{ 1.0f, 1.0f, 1.0f}, 0x000000ff},
19025 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
19026 0, 0, 640, 480, NULL, NULL, NULL, NULL);
19027 d3d = Direct3DCreate9(D3D_SDK_VERSION);
19028 ok(!!d3d, "Failed to create a D3D object.\n");
19029 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
19030 D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
19032 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping multisample mismatch test.\n");
19033 IDirect3D9_Release(d3d);
19034 return;
19036 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
19037 D3DFMT_D24X8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
19039 skip("Multisampling not supported for D3DFMT_D24X8, skipping multisample mismatch test.\n");
19040 IDirect3D9_Release(d3d);
19041 return;
19044 if (!(device = create_device(d3d, window, window, TRUE)))
19046 skip("Failed to create a D3D device, skipping tests.\n");
19047 IDirect3D9_Release(d3d);
19048 DestroyWindow(window);
19049 return;
19052 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
19053 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt_multi, NULL);
19054 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
19056 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 0.1f, 0);
19057 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
19059 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds);
19060 ok(SUCCEEDED(hr), "Failed to set depth stencil, hr %#x.\n", hr);
19061 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &rt);
19062 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
19063 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt_multi);
19064 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
19066 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
19067 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
19068 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
19069 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
19071 /* Clear with incompatible buffers. Partial and combined clears. */
19072 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0f, 0);
19073 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
19074 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 0.3f, 0);
19075 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
19076 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x0000ff00, 0.5f, 0);
19077 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
19079 /* The color buffer is reliably cleared on AMD and Nvidia GPUs. */
19080 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
19081 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
19082 hr = IDirect3DDevice9_StretchRect(device, rt_multi, NULL, rt, NULL, D3DTEXF_POINT);
19083 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
19084 color = getPixelColor(device, 320, 240);
19085 ok(color_match(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
19086 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19087 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
19089 /* Check depth buffer values. AMD GPUs (r500 and evergreen tested) clear the depth buffer
19090 * like you'd expect in a correct framebuffer setup. Nvidia doesn't clear it, neither in
19091 * the Z only clear case nor in the combined clear case. */
19092 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
19093 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
19094 hr = IDirect3DDevice9_BeginScene(device);
19095 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
19096 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
19097 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
19098 hr = IDirect3DDevice9_EndScene(device);
19099 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
19100 color = getPixelColor(device, 62, 240);
19101 ok(color_match(color, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color);
19102 color = getPixelColor(device, 64, 240);
19103 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x000000ff, 1)),
19104 "Got unexpected color 0x%08x.\n", color);
19105 color = getPixelColor(device, 318, 240);
19106 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x000000ff, 1)),
19107 "Got unexpected color 0x%08x.\n", color);
19108 color = getPixelColor(device, 322, 240);
19109 ok(color_match(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
19110 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19111 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
19113 /* Draw with incompatible buffers. AMD even performs Z testing, and the Z test
19114 * results appear to be correct for this simple draw. Nvidia doesn't draw unless
19115 * the depth test is disabled. Setting ZFUNC = ALWAYS doesn't make the geometry
19116 * show up either. Only test the ZENABLE = FALSE case for now. */
19117 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
19118 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
19119 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt_multi);
19120 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
19121 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0f, 0);
19122 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
19123 hr = IDirect3DDevice9_BeginScene(device);
19124 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
19125 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
19126 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
19127 hr = IDirect3DDevice9_EndScene(device);
19128 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
19130 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
19131 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
19132 hr = IDirect3DDevice9_StretchRect(device, rt_multi, NULL, rt, NULL, D3DTEXF_POINT);
19133 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
19134 color = getPixelColor(device, 320, 240);
19135 ok(color_match(color, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color);
19136 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19137 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
19139 IDirect3DSurface9_Release(ds);
19141 /* Test the reverse situation: Multisampled depth buffer, single sampled color buffer.
19142 * Color clears work as expected, AMD also clears the depth buffer, Nvidia does not. */
19143 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24X8,
19144 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &ds, NULL);
19145 ok(SUCCEEDED(hr), "Failed to create depth/stencil, hr %#x.\n", hr);
19146 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
19147 ok(SUCCEEDED(hr), "Failed to set depth stencil surface, hr %#x.\n", hr);
19148 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt_multi);
19149 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
19150 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ffff00, 0.1f, 0);
19151 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
19153 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
19154 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
19155 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0f, 0);
19156 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
19157 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 0.3f, 0);
19158 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
19159 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x0000ff00, 0.5f, 0);
19160 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
19162 color = getPixelColor(device, 320, 240);
19163 ok(color_match(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
19164 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19165 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
19167 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt_multi);
19168 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
19169 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
19170 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
19171 hr = IDirect3DDevice9_BeginScene(device);
19172 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
19173 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
19174 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
19175 hr = IDirect3DDevice9_EndScene(device);
19176 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
19178 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
19179 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
19180 hr = IDirect3DDevice9_StretchRect(device, rt_multi, NULL, rt, NULL, D3DTEXF_POINT);
19181 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
19182 color = getPixelColor(device, 62, 240);
19183 ok(color_match(color, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color);
19184 color = getPixelColor(device, 318, 240);
19185 ok(color_match(color, 0x00ffff00, 1) || broken(color_match(color, 0x000000ff, 1)),
19186 "Got unexpected color 0x%08x.\n", color);
19187 color = getPixelColor(device, 322, 240);
19188 ok(color_match(color, 0x00ffff00, 1), "Got unexpected color 0x%08x.\n", color);
19189 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19190 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
19192 /* Draw with a single sampled color buffer and a multisampled depth buffer. Again
19193 * AMD seems to perform correct Z testing, Nvidia doesn't draw unless the Z test
19194 * is disabled. Again only test the ZENABLE = FALSE case. */
19195 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0f, 0);
19196 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
19197 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
19198 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
19199 hr = IDirect3DDevice9_BeginScene(device);
19200 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
19201 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
19202 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
19203 hr = IDirect3DDevice9_EndScene(device);
19204 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
19205 color = getPixelColor(device, 320, 240);
19206 ok(color_match(color, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color);
19207 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19208 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
19210 IDirect3DSurface9_Release(rt);
19211 IDirect3DSurface9_Release(ds);
19212 IDirect3DSurface9_Release(rt_multi);
19214 refcount = IDirect3DDevice9_Release(device);
19215 ok(!refcount, "Device has %u references left.\n", refcount);
19216 IDirect3D9_Release(d3d);
19217 DestroyWindow(window);
19220 static void test_texcoordindex(void)
19222 static const D3DMATRIX mat =
19224 1.0f, 0.0f, 0.0f, 0.0f,
19225 0.0f, 0.0f, 0.0f, 0.0f,
19226 0.0f, 0.0f, 0.0f, 0.0f,
19227 0.0f, 0.0f, 0.0f, 0.0f,
19228 }}};
19229 static const struct
19231 struct vec3 pos;
19232 struct vec2 texcoord1;
19233 struct vec2 texcoord2;
19234 struct vec2 texcoord3;
19236 quad[] =
19238 {{-1.0f, -1.0f, 0.0f}, {0.0f, 1.0f}, {0.0f, 0.0f}, {1.0f, 1.0f}},
19239 {{-1.0f, 1.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 1.0f}, {1.0f, 0.0f}},
19240 {{ 1.0f, -1.0f, 0.0f}, {1.0f, 1.0f}, {1.0f, 0.0f}, {0.0f, 1.0f}},
19241 {{ 1.0f, 1.0f, 0.0f}, {1.0f, 0.0f}, {1.0f, 1.0f}, {0.0f, 0.0f}},
19243 IDirect3DDevice9 *device;
19244 IDirect3D9 *d3d9;
19245 HWND window;
19246 HRESULT hr;
19247 IDirect3DTexture9 *texture1, *texture2;
19248 D3DLOCKED_RECT locked_rect;
19249 ULONG refcount;
19250 D3DCOLOR color;
19251 DWORD *ptr;
19253 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
19254 0, 0, 640, 480, NULL, NULL, NULL, NULL);
19255 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
19256 ok(!!d3d9, "Failed to create a D3D object.\n");
19257 if (!(device = create_device(d3d9, window, window, TRUE)))
19259 skip("Failed to create a D3D device, skipping tests.\n");
19260 IDirect3D9_Release(d3d9);
19261 DestroyWindow(window);
19262 return;
19265 hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture1, NULL);
19266 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
19267 hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture2, NULL);
19268 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
19270 hr = IDirect3DTexture9_LockRect(texture1, 0, &locked_rect, NULL, D3DLOCK_DISCARD);
19271 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
19272 ptr = locked_rect.pBits;
19273 ptr[0] = 0xff000000;
19274 ptr[1] = 0xff00ff00;
19275 ptr[2] = 0xff0000ff;
19276 ptr[3] = 0xff00ffff;
19277 hr = IDirect3DTexture9_UnlockRect(texture1, 0);
19278 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
19280 hr = IDirect3DTexture9_LockRect(texture2, 0, &locked_rect, NULL, D3DLOCK_DISCARD);
19281 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
19282 ptr = locked_rect.pBits;
19283 ptr[0] = 0xff000000;
19284 ptr[1] = 0xff0000ff;
19285 ptr[2] = 0xffff0000;
19286 ptr[3] = 0xffff00ff;
19287 hr = IDirect3DTexture9_UnlockRect(texture2, 0);
19288 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
19290 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture1);
19291 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
19292 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *)texture2);
19293 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
19294 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX3);
19295 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
19296 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
19297 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
19298 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
19299 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
19300 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
19301 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
19302 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
19303 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
19304 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
19305 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
19306 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
19307 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
19308 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
19309 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
19311 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXCOORDINDEX, 1);
19312 ok(SUCCEEDED(hr), "Failed to set texcoord index, hr %#x.\n", hr);
19313 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXCOORDINDEX, 0);
19314 ok(SUCCEEDED(hr), "Failed to set texcoord index, hr %#x.\n", hr);
19316 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 1.0f, 0);
19317 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
19319 hr = IDirect3DDevice9_BeginScene(device);
19320 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
19321 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
19322 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
19323 hr = IDirect3DDevice9_EndScene(device);
19324 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
19326 color = getPixelColor(device, 160, 120);
19327 ok(color_match(color, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color);
19328 color = getPixelColor(device, 480, 120);
19329 ok(color_match(color, 0x0000ffff, 2), "Got unexpected color 0x%08x.\n", color);
19330 color = getPixelColor(device, 160, 360);
19331 ok(color_match(color, 0x00ff0000, 2), "Got unexpected color 0x%08x.\n", color);
19332 color = getPixelColor(device, 480, 360);
19333 ok(color_match(color, 0x00ffffff, 2), "Got unexpected color 0x%08x.\n", color);
19335 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
19336 ok(SUCCEEDED(hr), "Failed to set texture transform flags, hr %#x.\n", hr);
19337 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE1, &mat);
19338 ok(SUCCEEDED(hr), "Failed to set transformation matrix, hr %#x.\n", hr);
19340 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 1.0f, 0);
19341 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
19343 hr = IDirect3DDevice9_BeginScene(device);
19344 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
19345 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
19346 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
19347 hr = IDirect3DDevice9_EndScene(device);
19348 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
19350 color = getPixelColor(device, 160, 120);
19351 ok(color_match(color, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color);
19352 color = getPixelColor(device, 480, 120);
19353 ok(color_match(color, 0x0000ffff, 2), "Got unexpected color 0x%08x.\n", color);
19354 color = getPixelColor(device, 160, 360);
19355 ok(color_match(color, 0x00000000, 2), "Got unexpected color 0x%08x.\n", color);
19356 color = getPixelColor(device, 480, 360);
19357 ok(color_match(color, 0x0000ffff, 2), "Got unexpected color 0x%08x.\n", color);
19359 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
19360 ok(SUCCEEDED(hr), "Failed to set texture transform flags, hr %#x.\n", hr);
19361 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXCOORDINDEX, 2);
19362 ok(SUCCEEDED(hr), "Failed to set texcoord index, hr %#x.\n", hr);
19364 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 1.0f, 0);
19365 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
19367 hr = IDirect3DDevice9_BeginScene(device);
19368 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
19369 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
19370 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
19371 hr = IDirect3DDevice9_EndScene(device);
19372 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
19374 color = getPixelColor(device, 160, 120);
19375 ok(color_match(color, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color);
19376 color = getPixelColor(device, 480, 120);
19377 ok(color_match(color, 0x0000ffff, 2), "Got unexpected color 0x%08x.\n", color);
19378 color = getPixelColor(device, 160, 360);
19379 ok(color_match(color, 0x00ff00ff, 2), "Got unexpected color 0x%08x.\n", color);
19380 color = getPixelColor(device, 480, 360);
19381 ok(color_match(color, 0x00ffff00, 2), "Got unexpected color 0x%08x.\n", color);
19383 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19384 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
19386 IDirect3DTexture9_Release(texture1);
19387 IDirect3DTexture9_Release(texture2);
19389 refcount = IDirect3DDevice9_Release(device);
19390 ok(!refcount, "Device has %u references left.\n", refcount);
19391 IDirect3D9_Release(d3d9);
19392 DestroyWindow(window);
19395 static void test_vertex_blending(void)
19397 IDirect3DDevice9 *device;
19398 IDirect3D9 *d3d;
19399 D3DCAPS9 caps;
19400 D3DCOLOR color;
19401 ULONG refcount;
19402 HWND window;
19403 HRESULT hr;
19404 int i;
19406 static const D3DMATRIX view_mat =
19408 2.0f / 10.0f, 0.0f, 0.0f, 0.0f,
19409 0.0f, 2.0f / 10.0f, 0.0f, 0.0f,
19410 0.0f, 0.0f, 1.0f, 0.0f,
19411 0.0f, 0.0f, 0.0f, 1.0f
19412 }}},
19413 upper_left =
19415 1.0f, 0.0f, 0.0f, 0.0f,
19416 0.0f, 1.0f, 0.0f, 0.0f,
19417 0.0f, 0.0f, 1.0f, 0.0f,
19418 -4.0f, 4.0f, 0.0f, 1.0f
19419 }}},
19420 lower_left =
19422 1.0f, 0.0f, 0.0f, 0.0f,
19423 0.0f, 1.0f, 0.0f, 0.0f,
19424 0.0f, 0.0f, 1.0f, 0.0f,
19425 -4.0f, -4.0f, 0.0f, 1.0f
19426 }}},
19427 upper_right =
19429 1.0f, 0.0f, 0.0f, 0.0f,
19430 0.0f, 1.0f, 0.0f, 0.0f,
19431 0.0f, 0.0f, 1.0f, 0.0f,
19432 4.0f, 4.0f, 0.0f, 1.0f
19433 }}},
19434 lower_right =
19436 1.0f, 0.0f, 0.0f, 0.0f,
19437 0.0f, 1.0f, 0.0f, 0.0f,
19438 0.0f, 0.0f, 1.0f, 0.0f,
19439 4.0f, -4.0f, 0.0f, 1.0f
19440 }}};
19442 static const POINT quad_upper_right_points[] =
19444 {576, 48}, {-1, -1},
19446 quad_upper_right_empty_points[] =
19448 {64, 48}, {64, 432}, {576, 432}, {320, 240}, {-1, -1}
19450 quad_center_points[] =
19452 {320, 240}, {-1, -1}
19454 quad_center_empty_points[] =
19456 {64, 48}, {576, 48}, {64, 432}, {576, 432}, {-1, -1}
19458 quad_upper_center_points[] =
19460 {320, 48}, {-1, -1}
19462 quad_upper_center_empty_points[] =
19464 {320, 240}, {64, 48}, {576, 48}, {-1, -1}
19466 quad_fullscreen_points[] =
19468 {320, 48}, {320, 240}, {64, 48}, {576, 48}, {64, 432}, {576, 432}, {-1, -1}
19470 quad_fullscreen_empty_points[] =
19472 {-1, -1}
19475 static const struct
19477 struct
19479 struct vec3 position;
19480 struct vec3 blendweights;
19482 vertex_data[4];
19483 const POINT *quad_points;
19484 const POINT *empty_points;
19486 tests[] =
19488 /* upper right */
19490 {{{-1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}},
19491 {{-1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}},
19492 {{ 1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}},
19493 {{ 1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}}},
19494 quad_upper_right_points, quad_upper_right_empty_points
19496 /* center */
19498 {{{-1.0f, -1.0f, 0.0f}, {0.25f, 0.25f, 0.25f}},
19499 {{-1.0f, 1.0f, 0.0f}, {0.25f, 0.25f, 0.25f}},
19500 {{ 1.0f, -1.0f, 0.0f}, {0.25f, 0.25f, 0.25f}},
19501 {{ 1.0f, 1.0f, 0.0f}, {0.25f, 0.25f, 0.25f}}},
19502 quad_center_points, quad_center_empty_points
19504 /* upper center */
19506 {{{-1.0f, -1.0f, 0.0f}, {0.5f, 0.0f, 0.0f}},
19507 {{-1.0f, 1.0f, 0.0f}, {0.5f, 0.0f, 0.0f}},
19508 {{ 1.0f, -1.0f, 0.0f}, {0.5f, 0.0f, 0.0f}},
19509 {{ 1.0f, 1.0f, 0.0f}, {0.5f, 0.0f, 0.0f}}},
19510 quad_upper_center_points, quad_upper_center_empty_points
19512 /* full screen */
19514 {{{-1.0f, -1.0f, 0.0f}, {0.0f, 1.0f, 0.0f}},
19515 {{-1.0f, 1.0f, 0.0f}, {1.0f, 0.0f, 0.0f}},
19516 {{ 1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, 1.0f}},
19517 {{ 1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}}},
19518 quad_fullscreen_points, quad_fullscreen_empty_points
19522 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
19523 0, 0, 640, 480, NULL, NULL, NULL, NULL);
19524 d3d = Direct3DCreate9(D3D_SDK_VERSION);
19525 ok(!!d3d, "Failed to create a D3D object.\n");
19526 if (!(device = create_device(d3d, window, window, TRUE)))
19528 skip("Failed to create a D3D device, skipping tests.\n");
19529 goto done;
19532 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
19533 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
19534 if (caps.MaxVertexBlendMatrices < 4)
19536 skip("Only %u vertex blend matrices supported, skipping tests.\n", caps.MaxVertexBlendMatrices);
19537 IDirect3DDevice9_Release(device);
19538 goto done;
19541 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
19542 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
19544 hr = IDirect3DDevice9_SetTransform(device, D3DTS_VIEW, &view_mat);
19545 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
19547 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), &upper_left);
19548 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
19549 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(1), &lower_left);
19550 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
19551 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(2), &lower_right);
19552 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
19553 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(3), &upper_right);
19554 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
19556 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_VERTEXBLEND, D3DVBF_3WEIGHTS);
19557 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed %08x\n", hr);
19559 for (i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i)
19561 const POINT *point;
19563 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
19564 ok(SUCCEEDED(hr), "Failed to clear %08x\n", hr);
19566 hr = IDirect3DDevice9_BeginScene(device);
19567 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
19569 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZB3);
19570 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
19572 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, tests[i].vertex_data, 6 * sizeof(float));
19573 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
19575 hr = IDirect3DDevice9_EndScene(device);
19576 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
19578 point = tests[i].quad_points;
19579 while (point->x != -1 && point->y != -1)
19581 color = getPixelColor(device, point->x, point->y);
19582 ok(color_match(color, 0x00ffffff, 1), "Expected quad at %dx%d.\n", point->x, point->y);
19583 ++point;
19586 point = tests[i].empty_points;
19587 while (point->x != -1 && point->y != -1)
19589 color = getPixelColor(device, point->x, point->y);
19590 ok(color_match(color, 0x00000000, 1), "Unexpected quad at %dx%d.\n", point->x, point->y);
19591 ++point;
19594 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19595 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
19598 refcount = IDirect3DDevice9_Release(device);
19599 ok(!refcount, "Device has %u references left.\n", refcount);
19601 done:
19602 IDirect3D9_Release(d3d);
19603 DestroyWindow(window);
19606 static void test_updatetexture(void)
19608 IDirect3DDevice9 *device;
19609 IDirect3D9 *d3d9;
19610 HWND window;
19611 HRESULT hr;
19612 IDirect3DBaseTexture9 *src, *dst;
19613 unsigned int t, i, f, l, x, y, z;
19614 D3DLOCKED_RECT locked_rect;
19615 D3DLOCKED_BOX locked_box;
19616 ULONG refcount;
19617 D3DCAPS9 caps;
19618 D3DCOLOR color;
19619 BOOL ati2n_supported, do_visual_test;
19620 static const struct
19622 struct vec3 pos;
19623 struct vec2 texcoord;
19625 quad[] =
19627 {{-1.0f, -1.0f, 0.0f}, {0.0f, 1.0f}},
19628 {{-1.0f, 1.0f, 0.0f}, {0.0f, 0.0f}},
19629 {{ 1.0f, -1.0f, 0.0f}, {1.0f, 1.0f}},
19630 {{ 1.0f, 1.0f, 0.0f}, {1.0f, 0.0f}},
19632 static const struct
19634 struct vec3 pos;
19635 struct vec3 texcoord;
19637 quad_cube_tex[] =
19639 {{-1.0f, -1.0f, 0.0f}, {1.0f, -0.5f, 0.5f}},
19640 {{-1.0f, 1.0f, 0.0f}, {1.0f, 0.5f, 0.5f}},
19641 {{ 1.0f, -1.0f, 0.0f}, {1.0f, -0.5f, -0.5f}},
19642 {{ 1.0f, 1.0f, 0.0f}, {1.0f, 0.5f, -0.5f}},
19644 static const struct
19646 UINT src_width, src_height;
19647 UINT dst_width, dst_height;
19648 UINT src_levels, dst_levels;
19649 D3DFORMAT src_format, dst_format;
19650 BOOL broken;
19652 tests[] =
19654 {8, 8, 8, 8, 0, 0, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 0 */
19655 {8, 8, 8, 8, 4, 4, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 1 */
19656 {8, 8, 8, 8, 2, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 2 */
19657 {8, 8, 8, 8, 1, 1, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 3 */
19658 {8, 8, 8, 8, 4, 0, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 4 */
19659 {8, 8, 2, 2, 4, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 5 */
19660 /* The WARP renderer doesn't handle these cases correctly. */
19661 {8, 8, 8, 8, 4, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, TRUE}, /* 6 */
19662 {8, 8, 4, 4, 4, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, TRUE}, /* 7 */
19663 /* Not clear what happens here on Windows, it doesn't make much sense
19664 * though (on Nvidia it seems to upload the 4x4 surface into the 7x7
19665 * one or something like that). */
19666 /* {8, 8, 7, 7, 4, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, */
19667 {8, 8, 8, 8, 1, 4, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 8 */
19668 {4, 4, 8, 8, 1, 1, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 9 */
19669 /* This one causes weird behavior on Windows (it probably writes out
19670 * of the texture memory). */
19671 /* {8, 8, 4, 4, 1, 1, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, */
19672 {8, 4, 4, 2, 4, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 10 */
19673 {8, 4, 2, 4, 4, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 11 */
19674 {8, 8, 8, 8, 4, 4, D3DFMT_A8R8G8B8, D3DFMT_X8R8G8B8, FALSE}, /* 12 */
19675 {8, 8, 8, 8, 4, 4, D3DFMT_X8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 13 */
19676 /* The data is converted correctly on AMD, on Nvidia nothing happens
19677 * (it draws a black quad). */
19678 {8, 8, 8, 8, 4, 4, D3DFMT_A8R8G8B8, D3DFMT_R5G6B5, TRUE}, /* 14 */
19679 /* Here the data is converted on AMD, just copied and "reinterpreted" as
19680 * a 32 bit float on Nvidia (specifically the tested value becomes a
19681 * very small float number which we get as 0 in the test). */
19682 {8, 8, 8, 8, 4, 4, D3DFMT_A8R8G8B8, D3DFMT_R32F, TRUE}, /* 15 */
19683 /* This one doesn't seem to give the expected results on AMD. */
19684 /* {8, 8, 8, 8, 4, 4, D3DFMT_A8R8G8B8, D3DFMT_Q8W8V8U8, FALSE}, */
19685 {8, 8, 8, 8, 4, 4, MAKEFOURCC('A','T','I','2'), MAKEFOURCC('A','T','I','2'), FALSE}, /* 16 */
19686 {8, 8, 8, 8, 4, 2, MAKEFOURCC('A','T','I','2'), MAKEFOURCC('A','T','I','2'), FALSE}, /* 17 */
19687 {8, 8, 2, 2, 4, 2, MAKEFOURCC('A','T','I','2'), MAKEFOURCC('A','T','I','2'), FALSE}, /* 18 */
19689 static const struct
19691 D3DRESOURCETYPE type;
19692 DWORD fvf;
19693 const void *quad;
19694 unsigned int vertex_size;
19695 DWORD cap;
19696 const char *name;
19698 texture_types[] =
19700 {D3DRTYPE_TEXTURE, D3DFVF_XYZ | D3DFVF_TEX1,
19701 quad, sizeof(*quad), D3DPTEXTURECAPS_MIPMAP, "2D mipmapped"},
19703 {D3DRTYPE_CUBETEXTURE, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE3(0),
19704 quad_cube_tex, sizeof(*quad_cube_tex), D3DPTEXTURECAPS_CUBEMAP, "Cube"},
19706 {D3DRTYPE_VOLUMETEXTURE, D3DFVF_XYZ | D3DFVF_TEX1,
19707 quad, sizeof(*quad), D3DPTEXTURECAPS_VOLUMEMAP, "Volume"}
19710 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
19711 0, 0, 640, 480, NULL, NULL, NULL, NULL);
19712 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
19713 ok(!!d3d9, "Failed to create a D3D object.\n");
19714 if (!(device = create_device(d3d9, window, window, TRUE)))
19716 skip("Failed to create a D3D device, skipping tests.\n");
19717 IDirect3D9_Release(d3d9);
19718 DestroyWindow(window);
19719 return;
19722 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
19723 ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
19725 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
19726 ok(SUCCEEDED(hr), "Failed to set texture filtering state, hr %#x.\n", hr);
19727 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
19728 ok(SUCCEEDED(hr), "Failed to set texture clamping state, hr %#x.\n", hr);
19729 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
19730 ok(SUCCEEDED(hr), "Failed to set texture clamping state, hr %#x.\n", hr);
19731 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSW, D3DTADDRESS_CLAMP);
19732 ok(SUCCEEDED(hr), "Failed to set texture clamping state, hr %#x.\n", hr);
19733 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
19734 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
19735 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
19736 ok(hr == D3D_OK, "Failed to set texture stage state, hr %#x.\n", hr);
19737 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
19738 ok(hr == D3D_OK, "Failed to set texture stage state, hr %#x.\n", hr);
19740 for (t = 0; t < sizeof(texture_types) / sizeof(*texture_types); ++t)
19742 if (!(caps.TextureCaps & texture_types[t].cap))
19744 skip("%s textures not supported, skipping some tests.\n", texture_types[t].name);
19745 continue;
19748 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
19749 D3DFMT_X8R8G8B8, 0, texture_types[t].type, MAKEFOURCC('A','T','I','2'))))
19751 skip("%s ATI2N textures are not supported, skipping some tests.\n", texture_types[t].name);
19752 ati2n_supported = FALSE;
19754 else
19756 ati2n_supported = TRUE;
19759 hr = IDirect3DDevice9_SetFVF(device, texture_types[t].fvf);
19760 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
19762 for (i = 0; i < sizeof(tests) / sizeof(*tests); ++i)
19764 if (tests[i].src_format == MAKEFOURCC('A','T','I','2') && !ati2n_supported)
19765 continue;
19767 switch (texture_types[t].type)
19769 case D3DRTYPE_TEXTURE:
19770 hr = IDirect3DDevice9_CreateTexture(device,
19771 tests[i].src_width, tests[i].src_height,
19772 tests[i].src_levels, 0, tests[i].src_format, D3DPOOL_SYSTEMMEM,
19773 (IDirect3DTexture9 **)&src, NULL);
19774 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x, case %u, %u.\n", hr, t, i);
19775 hr = IDirect3DDevice9_CreateTexture(device,
19776 tests[i].dst_width, tests[i].dst_height,
19777 tests[i].dst_levels, 0, tests[i].dst_format, D3DPOOL_DEFAULT,
19778 (IDirect3DTexture9 **)&dst, NULL);
19779 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x, case %u, %u.\n", hr, t, i);
19780 break;
19781 case D3DRTYPE_CUBETEXTURE:
19782 hr = IDirect3DDevice9_CreateCubeTexture(device,
19783 tests[i].src_width,
19784 tests[i].src_levels, 0, tests[i].src_format, D3DPOOL_SYSTEMMEM,
19785 (IDirect3DCubeTexture9 **)&src, NULL);
19786 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x, case %u, %u.\n", hr, t, i);
19787 hr = IDirect3DDevice9_CreateCubeTexture(device,
19788 tests[i].dst_width,
19789 tests[i].dst_levels, 0, tests[i].dst_format, D3DPOOL_DEFAULT,
19790 (IDirect3DCubeTexture9 **)&dst, NULL);
19791 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x, case %u, %u.\n", hr, t, i);
19792 break;
19793 case D3DRTYPE_VOLUMETEXTURE:
19794 hr = IDirect3DDevice9_CreateVolumeTexture(device,
19795 tests[i].src_width, tests[i].src_height, tests[i].src_width,
19796 tests[i].src_levels, 0, tests[i].src_format, D3DPOOL_SYSTEMMEM,
19797 (IDirect3DVolumeTexture9 **)&src, NULL);
19798 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x, case %u, %u.\n", hr, t, i);
19799 hr = IDirect3DDevice9_CreateVolumeTexture(device,
19800 tests[i].dst_width, tests[i].dst_height, tests[i].dst_width,
19801 tests[i].dst_levels, 0, tests[i].dst_format, D3DPOOL_DEFAULT,
19802 (IDirect3DVolumeTexture9 **)&dst, NULL);
19803 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x, case %u, %u.\n", hr, t, i);
19804 break;
19805 default:
19806 trace("Unexpected resource type.\n");
19809 /* Skip the visual part of the test for ATI2N (laziness) and cases that
19810 * give a different (and unlikely to be useful) result. */
19811 do_visual_test = (tests[i].src_format == D3DFMT_A8R8G8B8 || tests[i].src_format == D3DFMT_X8R8G8B8)
19812 && tests[i].src_levels != 0
19813 && tests[i].src_width >= tests[i].dst_width && tests[i].src_height >= tests[i].dst_height
19814 && !(tests[i].src_width > tests[i].src_height && tests[i].dst_width < tests[i].dst_height);
19816 if (do_visual_test)
19818 DWORD *ptr = NULL;
19819 unsigned int width, height, depth, row_pitch = 0, slice_pitch = 0;
19821 for (f = 0; f < (texture_types[t].type == D3DRTYPE_CUBETEXTURE ? 6 : 1); ++f)
19823 width = tests[i].src_width;
19824 height = texture_types[t].type != D3DRTYPE_CUBETEXTURE ? tests[i].src_height : tests[i].src_width;
19825 depth = texture_types[t].type == D3DRTYPE_VOLUMETEXTURE ? width : 1;
19827 for (l = 0; l < tests[i].src_levels; ++l)
19829 switch (texture_types[t].type)
19831 case D3DRTYPE_TEXTURE:
19832 hr = IDirect3DTexture9_LockRect((IDirect3DTexture9 *)src,
19833 l, &locked_rect, NULL, 0);
19834 ptr = locked_rect.pBits;
19835 row_pitch = locked_rect.Pitch / sizeof(*ptr);
19836 break;
19837 case D3DRTYPE_CUBETEXTURE:
19838 hr = IDirect3DCubeTexture9_LockRect((IDirect3DCubeTexture9 *)src,
19839 f, l, &locked_rect, NULL, 0);
19840 ptr = locked_rect.pBits;
19841 row_pitch = locked_rect.Pitch / sizeof(*ptr);
19842 break;
19843 case D3DRTYPE_VOLUMETEXTURE:
19844 hr = IDirect3DVolumeTexture9_LockBox((IDirect3DVolumeTexture9 *)src,
19845 l, &locked_box, NULL, 0);
19846 ptr = locked_box.pBits;
19847 row_pitch = locked_box.RowPitch / sizeof(*ptr);
19848 slice_pitch = locked_box.SlicePitch / sizeof(*ptr);
19849 break;
19850 default:
19851 trace("Unexpected resource type.\n");
19853 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
19855 for (z = 0; z < depth; ++z)
19857 for (y = 0; y < height; ++y)
19859 for (x = 0; x < width; ++x)
19861 ptr[z * slice_pitch + y * row_pitch + x] = 0xff000000
19862 | (DWORD)(x / (width - 1.0f) * 255.0f) << 16
19863 | (DWORD)(y / (height - 1.0f) * 255.0f) << 8;
19868 switch (texture_types[t].type)
19870 case D3DRTYPE_TEXTURE:
19871 hr = IDirect3DTexture9_UnlockRect((IDirect3DTexture9 *)src, l);
19872 break;
19873 case D3DRTYPE_CUBETEXTURE:
19874 hr = IDirect3DCubeTexture9_UnlockRect((IDirect3DCubeTexture9 *)src, f, l);
19875 break;
19876 case D3DRTYPE_VOLUMETEXTURE:
19877 hr = IDirect3DVolumeTexture9_UnlockBox((IDirect3DVolumeTexture9 *)src, l);
19878 break;
19879 default:
19880 trace("Unexpected resource type.\n");
19882 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
19884 width >>= 1;
19885 if (!width)
19886 width = 1;
19887 height >>= 1;
19888 if (!height)
19889 height = 1;
19890 depth >>= 1;
19891 if (!depth)
19892 depth = 1;
19897 hr = IDirect3DDevice9_UpdateTexture(device, src, dst);
19898 if (FAILED(hr))
19900 todo_wine ok(SUCCEEDED(hr), "Failed to update texture, hr %#x, case %u, %u.\n", hr, t, i);
19901 IDirect3DBaseTexture9_Release(src);
19902 IDirect3DBaseTexture9_Release(dst);
19903 continue;
19905 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x, case %u, %u.\n", hr, t, i);
19907 if (do_visual_test)
19909 hr = IDirect3DDevice9_SetTexture(device, 0, dst);
19910 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
19912 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 1.0f, 0);
19913 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
19915 hr = IDirect3DDevice9_BeginScene(device);
19916 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
19917 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,
19918 texture_types[t].quad, texture_types[t].vertex_size);
19919 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
19920 hr = IDirect3DDevice9_EndScene(device);
19921 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
19923 color = getPixelColor(device, 320, 240);
19924 ok (color_match(color, 0x007f7f00, 2) || broken(tests[i].broken)
19925 || broken(color == 0x00adbeef), /* WARP device often just breaks down. */
19926 "Got unexpected color 0x%08x, case %u, %u.\n", color, t, i);
19929 IDirect3DBaseTexture9_Release(src);
19930 IDirect3DBaseTexture9_Release(dst);
19933 refcount = IDirect3DDevice9_Release(device);
19934 ok(!refcount, "Device has %u references left.\n", refcount);
19935 IDirect3D9_Release(d3d9);
19936 DestroyWindow(window);
19939 static void test_depthbias(void)
19941 IDirect3DDevice9 *device;
19942 IDirect3D9 *d3d;
19943 IDirect3DSurface9 *ds;
19944 D3DCAPS9 caps;
19945 D3DCOLOR color;
19946 ULONG refcount;
19947 HWND window;
19948 HRESULT hr;
19949 unsigned int i;
19950 static const D3DFORMAT formats[] =
19952 D3DFMT_D16, D3DFMT_D24X8, D3DFMT_D32, D3DFMT_D24S8, MAKEFOURCC('I','N','T','Z'),
19954 /* The scaling factor detection function detects the wrong factor for
19955 * float formats on Nvidia, therefore the following tests are disabled.
19956 * The wined3d function detects 2^23 like for fixed point formats but
19957 * the test needs 2^22 to pass.
19959 * AMD GPUs need a different scaling factor for float depth buffers
19960 * (2^24) than fixed point (2^23), but the wined3d detection function
19961 * works there, producing the right result in the test.
19963 * D3DFMT_D32F_LOCKABLE, D3DFMT_D24FS8,
19967 static const struct
19969 struct vec3 position;
19971 quad[] =
19973 {{-1.0f, -1.0f, 0.0f}},
19974 {{-1.0f, 1.0f, 0.0f}},
19975 {{ 1.0f, -1.0f, 1.0f}},
19976 {{ 1.0f, 1.0f, 1.0f}},
19978 union
19980 float f;
19981 DWORD d;
19982 } conv;
19984 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
19985 0, 0, 640, 480, NULL, NULL, NULL, NULL);
19986 d3d = Direct3DCreate9(D3D_SDK_VERSION);
19987 ok(!!d3d, "Failed to create a D3D object.\n");
19988 if (!(device = create_device(d3d, window, window, TRUE)))
19990 skip("Failed to create a D3D device, skipping tests.\n");
19991 goto done;
19994 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
19995 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
19996 if (!(caps.RasterCaps & D3DPRASTERCAPS_DEPTHBIAS))
19998 IDirect3DDevice9_Release(device);
19999 skip("D3DPRASTERCAPS_DEPTHBIAS not supported.\n");
20000 goto done;
20003 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
20004 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
20005 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
20006 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
20007 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP,D3DTOP_SELECTARG1);
20008 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
20009 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TFACTOR);
20010 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
20011 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
20012 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
20014 for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
20016 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
20017 D3DFMT_X8R8G8B8, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, formats[i])))
20019 skip("Depth format %u not supported, skipping.\n", formats[i]);
20020 continue;
20023 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, formats[i],
20024 D3DMULTISAMPLE_NONE, 0, FALSE, &ds, NULL);
20025 ok(SUCCEEDED(hr), "Failed to create depth stencil surface, hr %#x.\n", hr);
20026 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
20027 ok(SUCCEEDED(hr), "Failed to set depth stencil surface, hr %#x.\n", hr);
20028 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 0.5f, 0);
20029 ok(SUCCEEDED(hr), "Failed to clear %08x\n", hr);
20031 hr = IDirect3DDevice9_BeginScene(device);
20032 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
20034 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x00ff0000);
20035 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
20036 conv.f = -0.2f;
20037 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DEPTHBIAS, conv.d);
20038 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
20039 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
20040 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
20042 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x0000ff00);
20043 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
20044 conv.f = 0.0f;
20045 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DEPTHBIAS, conv.d);
20046 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
20047 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
20048 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
20050 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x000000ff);
20051 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
20052 conv.f = 0.2f;
20053 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DEPTHBIAS, conv.d);
20054 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
20055 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
20056 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
20058 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x00ffffff);
20059 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
20060 conv.f = 0.4f;
20061 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DEPTHBIAS, conv.d);
20062 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
20063 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
20064 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
20066 color = getPixelColor(device, 61, 240);
20067 ok(color_match(color, 0x00ffffff, 1), "Got unexpected color %08x at x=62, format %u.\n", color, formats[i]);
20068 color = getPixelColor(device, 65, 240);
20070 /* The broken results are for the WARP driver on the testbot. It seems to initialize
20071 * a scaling factor based on the first depth format that is used. Other formats with
20072 * a different depth size then render incorrectly. */
20073 ok(color_match(color, 0x000000ff, 1) || broken(color_match(color, 0x00ffffff, 1)),
20074 "Got unexpected color %08x at x=64, format %u.\n", color, formats[i]);
20075 color = getPixelColor(device, 190, 240);
20076 ok(color_match(color, 0x000000ff, 1) || broken(color_match(color, 0x00ffffff, 1)),
20077 "Got unexpected color %08x at x=190, format %u.\n", color, formats[i]);
20079 color = getPixelColor(device, 194, 240);
20080 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ffffff, 1)),
20081 "Got unexpected color %08x at x=194, format %u.\n", color, formats[i]);
20082 color = getPixelColor(device, 318, 240);
20083 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ffffff, 1)),
20084 "Got unexpected color %08x at x=318, format %u.\n", color, formats[i]);
20086 color = getPixelColor(device, 322, 240);
20087 ok(color_match(color, 0x00ff0000, 1) || broken(color_match(color, 0x00000000, 1)),
20088 "Got unexpected color %08x at x=322, format %u.\n", color, formats[i]);
20089 color = getPixelColor(device, 446, 240);
20090 ok(color_match(color, 0x00ff0000, 1) || broken(color_match(color, 0x00000000, 1)),
20091 "Got unexpected color %08x at x=446, format %u.\n", color, formats[i]);
20093 color = getPixelColor(device, 450, 240);
20094 ok(color_match(color, 0x00000000, 1), "Got unexpected color %08x at x=446, format %u.\n", color, formats[i]);
20096 hr = IDirect3DDevice9_EndScene(device);
20097 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
20099 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
20100 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
20101 IDirect3DSurface9_Release(ds);
20104 refcount = IDirect3DDevice9_Release(device);
20105 ok(!refcount, "Device has %u references left.\n", refcount);
20107 done:
20108 IDirect3D9_Release(d3d);
20109 DestroyWindow(window);
20112 static void test_flip(void)
20114 IDirect3DDevice9 *device;
20115 IDirect3D9 *d3d;
20116 ULONG refcount;
20117 HWND window;
20118 HRESULT hr;
20119 IDirect3DSurface9 *back_buffers[3], *test_surface;
20120 unsigned int i;
20121 D3DCOLOR color;
20122 D3DPRESENT_PARAMETERS present_parameters = {0};
20124 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
20125 0, 0, 640, 480, NULL, NULL, NULL, NULL);
20126 d3d = Direct3DCreate9(D3D_SDK_VERSION);
20127 ok(!!d3d, "Failed to create a D3D object.\n");
20129 present_parameters.BackBufferWidth = 640;
20130 present_parameters.BackBufferHeight = 480;
20131 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
20132 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
20133 present_parameters.hDeviceWindow = window;
20134 present_parameters.Windowed = TRUE;
20135 present_parameters.BackBufferCount = 3;
20136 present_parameters.Flags = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER;
20137 hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
20138 window, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device);
20139 if (!device)
20141 skip("Failed to create a D3D device, skipping tests.\n");
20142 IDirect3D9_Release(d3d);
20143 DestroyWindow(window);
20144 return;
20147 for (i = 0; i < sizeof(back_buffers) / sizeof(*back_buffers); ++i)
20149 hr = IDirect3DDevice9_GetBackBuffer(device, 0, i, D3DBACKBUFFER_TYPE_MONO, &back_buffers[i]);
20150 ok(SUCCEEDED(hr), "Failed to get back buffer, hr %#x.\n", hr);
20152 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &test_surface);
20153 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
20154 ok(test_surface == back_buffers[0], "Expected render target %p, got %p.\n", back_buffers[0], test_surface);
20155 IDirect3DSurface9_Release(test_surface);
20157 hr = IDirect3DDevice9_SetRenderTarget(device, 0, back_buffers[2]);
20158 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
20160 hr = IDirect3DDevice9_ColorFill(device, back_buffers[0], NULL, 0xffff0000);
20161 ok(SUCCEEDED(hr), "Failed to color fill, hr %#x.\n", hr);
20162 hr = IDirect3DDevice9_ColorFill(device, back_buffers[1], NULL, 0xff00ff00);
20163 ok(SUCCEEDED(hr), "Failed to color fill, hr %#x.\n", hr);
20164 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0f, 0);
20165 ok(SUCCEEDED(hr), "Failed to clear, hr %#x\n", hr);
20167 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
20168 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
20170 /* Render target is unmodified. */
20171 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &test_surface);
20172 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
20173 ok(test_surface == back_buffers[2], "Expected render target %p, got %p.\n", back_buffers[2], test_surface);
20174 IDirect3DSurface9_Release(test_surface);
20176 /* Backbuffer surface pointers are unmodified */
20177 for (i = 0; i < sizeof(back_buffers) / sizeof(*back_buffers); ++i)
20179 hr = IDirect3DDevice9_GetBackBuffer(device, 0, i, D3DBACKBUFFER_TYPE_MONO, &test_surface);
20180 ok(SUCCEEDED(hr), "Failed to get back buffer, hr %#x.\n", hr);
20181 ok(test_surface == back_buffers[i], "Expected back buffer %u = %p, got %p.\n",
20182 i, back_buffers[i], test_surface);
20183 IDirect3DSurface9_Release(test_surface);
20186 /* Contents were changed. */
20187 color = getPixelColorFromSurface(back_buffers[0], 1, 1);
20188 ok(color == 0xff00ff00, "Got unexpected color 0x%08x.\n", color);
20189 color = getPixelColorFromSurface(back_buffers[1], 1, 1);
20190 ok(color == 0xff0000ff, "Got unexpected color 0x%08x.\n", color);
20192 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff808080, 0.0f, 0);
20193 ok(SUCCEEDED(hr), "Failed to clear, hr %#x\n", hr);
20195 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
20196 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
20198 color = getPixelColorFromSurface(back_buffers[0], 1, 1);
20199 ok(color == 0xff0000ff, "Got unexpected color 0x%08x.\n", color);
20200 color = getPixelColorFromSurface(back_buffers[1], 1, 1);
20201 ok(color == 0xff808080, "Got unexpected color 0x%08x.\n", color);
20203 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
20204 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
20206 color = getPixelColorFromSurface(back_buffers[0], 1, 1);
20207 ok(color == 0xff808080, "Got unexpected color 0x%08x.\n", color);
20209 for (i = 0; i < sizeof(back_buffers) / sizeof(*back_buffers); ++i)
20210 IDirect3DSurface9_Release(back_buffers[i]);
20212 refcount = IDirect3DDevice9_Release(device);
20213 ok(!refcount, "Device has %u references left.\n", refcount);
20215 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
20216 D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
20218 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping multisample flip test.\n");
20219 goto done;
20222 present_parameters.BackBufferCount = 2;
20223 present_parameters.MultiSampleType = D3DMULTISAMPLE_2_SAMPLES;
20224 present_parameters.Flags = 0;
20225 hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
20226 window, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device);
20228 for (i = 0; i < present_parameters.BackBufferCount; ++i)
20230 hr = IDirect3DDevice9_GetBackBuffer(device, 0, i, D3DBACKBUFFER_TYPE_MONO, &back_buffers[i]);
20231 ok(SUCCEEDED(hr), "Failed to get back buffer, hr %#x.\n", hr);
20234 hr = IDirect3DDevice9_SetRenderTarget(device, 0, back_buffers[1]);
20235 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
20236 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff808080, 0.0f, 0);
20237 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
20239 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
20240 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
20242 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
20243 D3DMULTISAMPLE_NONE, 0, TRUE, &test_surface, NULL);
20244 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
20245 hr = IDirect3DDevice9_StretchRect(device, back_buffers[0], NULL, test_surface, NULL, D3DTEXF_POINT);
20246 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
20248 color = getPixelColorFromSurface(test_surface, 1, 1);
20249 ok(color == 0xff808080, "Got unexpected color 0x%08x.\n", color);
20251 IDirect3DSurface9_Release(test_surface);
20252 for (i = 0; i < present_parameters.BackBufferCount; ++i)
20253 IDirect3DSurface9_Release(back_buffers[i]);
20255 refcount = IDirect3DDevice9_Release(device);
20256 ok(!refcount, "Device has %u references left.\n", refcount);
20258 done:
20259 IDirect3D9_Release(d3d);
20260 DestroyWindow(window);
20263 static void test_uninitialized_varyings(void)
20265 static const D3DMATRIX mat =
20267 1.0f, 0.0f, 0.0f, 0.0f,
20268 0.0f, 1.0f, 0.0f, 0.0f,
20269 0.0f, 0.0f, 1.0f, 0.0f,
20270 0.0f, 0.0f, 0.0f, 1.0f,
20271 }}};
20272 static const struct vec3 quad[] =
20274 {-1.0f, -1.0f, 0.1f},
20275 {-1.0f, 1.0f, 0.1f},
20276 { 1.0f, -1.0f, 0.1f},
20277 { 1.0f, 1.0f, 0.1f},
20279 static const DWORD vs1_code[] =
20281 0xfffe0101, /* vs_1_1 */
20282 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
20283 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
20284 0x0000ffff
20286 static const DWORD vs1_partial_code[] =
20288 0xfffe0101, /* vs_1_1 */
20289 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
20290 0x00000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, /* def c0, 0.5, 0.5, 0.5, 0.5 */
20291 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
20292 0x00000001, 0xd0010000, 0xa0e40000, /* mov oD0.x, c0 */
20293 0x00000001, 0xd0010001, 0xa0e40000, /* mov oD1.x, c0 */
20294 0x00000001, 0xe0010000, 0xa0e40000, /* mov oT0.x, c0 */
20295 0x0000ffff
20297 static const DWORD vs2_code[] =
20299 0xfffe0200, /* vs_2_0 */
20300 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
20301 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
20302 0x0000ffff
20304 static const DWORD vs2_partial_code[] =
20306 0xfffe0200, /* vs_2_0 */
20307 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
20308 0x05000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, /* def c0, 0.5, 0.5, 0.5, 0.5 */
20309 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
20310 0x02000001, 0xd0010000, 0xa0e40000, /* mov oD0.x, c0 */
20311 0x02000001, 0xd0010001, 0xa0e40000, /* mov oD1.x, c0 */
20312 0x02000001, 0xe0010000, 0xa0e40000, /* mov oT0.x, c0 */
20313 0x0000ffff
20315 static const DWORD vs3_code[] =
20317 0xfffe0300, /* vs_3_0 */
20318 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
20319 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
20320 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
20321 0x0000ffff
20323 static const DWORD vs3_partial_code[] =
20325 0xfffe0300, /* vs_3_0 */
20326 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
20327 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
20328 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color0 o1 */
20329 0x0200001f, 0x8001000a, 0xe00f0002, /* dcl_color1 o2 */
20330 0x0200001f, 0x80000005, 0xe00f0003, /* dcl_texcoord0 o3 */
20331 0x05000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, /* def c0, 0.5, 0.5, 0.5, 0.5 */
20332 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
20333 0x02000001, 0xe0010001, 0xa0e40000, /* mov o1.x, c0 */
20334 0x02000001, 0xe0010002, 0xa0e40000, /* mov o2.x, c0 */
20335 0x02000001, 0xe0010003, 0xa0e40000, /* mov o3.x, c0 */
20336 0x0000ffff
20338 static const DWORD ps1_diffuse_code[] =
20340 0xffff0101, /* ps_1_1 */
20341 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
20342 0x0000ffff
20344 static const DWORD ps1_specular_code[] =
20346 0xffff0101, /* ps_1_1 */
20347 0x00000001, 0x800f0000, 0x90e40001, /* mov r0, v1 */
20348 0x0000ffff
20350 static const DWORD ps1_texcoord_code[] =
20352 0xffff0101, /* ps_1_1 */
20353 0x00000040, 0xb00f0000, /* texcoord t0 */
20354 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
20355 0x0000ffff
20357 static const DWORD ps2_diffuse_code[] =
20359 0xffff0200, /* ps_2_0 */
20360 0x0200001f, 0x80000000, 0x900f0000, /* dcl v0 */
20361 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
20362 0x0000ffff
20364 static const DWORD ps2_specular_code[] =
20366 0xffff0200, /* ps_2_0 */
20367 0x0200001f, 0x80000000, 0x900f0001, /* dcl v1 */
20368 0x02000001, 0x800f0800, 0x90e40001, /* mov oC0, v1 */
20369 0x0000ffff
20371 static const DWORD ps2_texcoord_code[] =
20373 0xffff0200, /* ps_2_0 */
20374 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
20375 0x02000001, 0x800f0800, 0xb0e40000, /* mov oC0, t0 */
20376 0x0000ffff
20378 static const DWORD ps3_diffuse_code[] =
20380 0xffff0300, /* ps_3_0 */
20381 0x0200001f, 0x8000000a, 0x900f0000, /* dcl_color0 v0 */
20382 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
20383 0x0000ffff
20385 static const DWORD ps3_specular_code[] =
20387 0xffff0300, /* ps_3_0 */
20388 0x0200001f, 0x8001000a, 0x900f0001, /* dcl_color1 v1 */
20389 0x02000001, 0x800f0800, 0x90e40001, /* mov oC0, v1 */
20390 0x0000ffff
20392 static const DWORD ps3_texcoord_code[] =
20394 0xffff0300, /* ps_3_0 */
20395 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord0 v0 */
20396 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
20397 0x0000ffff
20399 static const struct
20401 DWORD vs_version;
20402 const DWORD *vs;
20403 DWORD ps_version;
20404 const DWORD *ps;
20405 D3DCOLOR expected;
20406 BOOL allow_zero_alpha;
20407 BOOL allow_zero;
20408 BOOL broken_warp;
20410 /* On AMD specular color is generally initialized to 0x00000000 and texcoords to 0xff000000
20411 * while on Nvidia it's the opposite. Just allow both. */
20412 tests[] =
20414 {D3DVS_VERSION(1, 1), vs1_code, 0, NULL, 0xffffffff},
20415 { 0, NULL, D3DPS_VERSION(1, 1), ps1_texcoord_code, 0xff000000, TRUE},
20416 { 0, NULL, D3DPS_VERSION(2, 0), ps2_texcoord_code, 0xff000000, TRUE},
20417 {D3DVS_VERSION(1, 1), vs1_code, D3DPS_VERSION(1, 1), ps1_diffuse_code, 0xffffffff},
20418 {D3DVS_VERSION(1, 1), vs1_code, D3DPS_VERSION(1, 1), ps1_specular_code, 0xff000000, TRUE, FALSE, TRUE},
20419 {D3DVS_VERSION(1, 1), vs1_code, D3DPS_VERSION(1, 1), ps1_texcoord_code, 0xff000000, TRUE},
20420 {D3DVS_VERSION(2, 0), vs2_code, D3DPS_VERSION(2, 0), ps2_diffuse_code, 0xffffffff},
20421 {D3DVS_VERSION(2, 0), vs2_code, D3DPS_VERSION(2, 0), ps2_specular_code, 0xff000000, TRUE, FALSE, TRUE},
20422 {D3DVS_VERSION(2, 0), vs2_code, D3DPS_VERSION(2, 0), ps2_texcoord_code, 0xff000000, TRUE},
20423 {D3DVS_VERSION(3, 0), vs3_code, D3DPS_VERSION(3, 0), ps3_diffuse_code, 0xffffffff, FALSE, TRUE},
20424 {D3DVS_VERSION(3, 0), vs3_code, D3DPS_VERSION(3, 0), ps3_specular_code, 0x00000000, FALSE, FALSE, TRUE},
20425 {D3DVS_VERSION(3, 0), vs3_code, D3DPS_VERSION(3, 0), ps3_texcoord_code, 0x00000000, FALSE, FALSE, TRUE},
20426 {D3DVS_VERSION(1, 1), vs1_partial_code, 0, NULL, 0xff7fffff, FALSE, FALSE, TRUE},
20427 {D3DVS_VERSION(1, 1), vs1_partial_code, D3DPS_VERSION(1, 1), ps1_diffuse_code, 0xff7fffff, FALSE, FALSE, TRUE},
20428 {D3DVS_VERSION(1, 1), vs1_partial_code, D3DPS_VERSION(1, 1), ps1_specular_code, 0xff7f0000, TRUE},
20429 {D3DVS_VERSION(1, 1), vs1_partial_code, D3DPS_VERSION(1, 1), ps1_texcoord_code, 0xff7f0000, TRUE},
20430 {D3DVS_VERSION(2, 0), vs2_partial_code, D3DPS_VERSION(2, 0), ps2_diffuse_code, 0xff7fffff, FALSE, FALSE, TRUE},
20431 {D3DVS_VERSION(2, 0), vs2_partial_code, D3DPS_VERSION(2, 0), ps2_specular_code, 0xff7f0000, TRUE},
20432 {D3DVS_VERSION(2, 0), vs2_partial_code, D3DPS_VERSION(2, 0), ps2_texcoord_code, 0xff7f0000, TRUE},
20433 /* Fails on Radeon HD 2600 with 0x008000ff aka nonsensical color. */
20434 /* {D3DVS_VERSION(3, 0), vs3_partial_code, D3DPS_VERSION(3, 0), ps3_diffuse_code, 0xff7fffff, TRUE}, */
20435 /* Randomly fails on Radeon HD 2600. */
20436 /* {D3DVS_VERSION(3, 0), vs3_partial_code, D3DPS_VERSION(3, 0), ps3_specular_code, 0x007f0000}, */
20437 {D3DVS_VERSION(3, 0), vs3_partial_code, D3DPS_VERSION(3, 0), ps3_texcoord_code, 0xff7f0000, TRUE},
20439 IDirect3DDevice9 *device;
20440 IDirect3D9 *d3d;
20441 HWND window;
20442 HRESULT hr;
20443 D3DADAPTER_IDENTIFIER9 identifier;
20444 IDirect3DSurface9 *backbuffer;
20445 struct surface_readback rb;
20446 IDirect3DVertexShader9 *vs;
20447 IDirect3DPixelShader9 *ps;
20448 unsigned int i;
20449 ULONG refcount;
20450 D3DCAPS9 caps;
20451 D3DCOLOR color;
20452 BOOL warp;
20454 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
20455 0, 0, 640, 480, NULL, NULL, NULL, NULL);
20456 d3d = Direct3DCreate9(D3D_SDK_VERSION);
20457 ok(!!d3d, "Failed to create a D3D object.\n");
20458 if (!(device = create_device(d3d, window, window, TRUE)))
20460 skip("Failed to create a D3D device, skipping tests.\n");
20461 IDirect3D9_Release(d3d);
20462 DestroyWindow(window);
20463 return;
20466 hr = IDirect3D9_GetAdapterIdentifier(d3d, D3DADAPTER_DEFAULT, 0, &identifier);
20467 ok(SUCCEEDED(hr), "Failed to get adapter identifier, hr %#x.\n", hr);
20468 warp = adapter_is_warp(&identifier);
20470 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
20471 ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
20473 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
20474 ok(SUCCEEDED(hr), "Failed to get backbuffer, hr %#x.\n", hr);
20476 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLD, &mat);
20477 ok(SUCCEEDED(hr), "Failed to set world transform, hr %#x.\n", hr);
20478 hr = IDirect3DDevice9_SetTransform(device, D3DTS_VIEW, &mat);
20479 ok(SUCCEEDED(hr), "Failed to set view transform, hr %#x.\n", hr);
20480 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &mat);
20481 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
20482 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
20483 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#x.\n", hr);
20484 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
20485 ok(SUCCEEDED(hr), "Failed to disable Z test, hr %#x.\n", hr);
20486 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
20487 ok(SUCCEEDED(hr), "Failed to disable fog, hr %#x.\n", hr);
20488 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
20489 ok(SUCCEEDED(hr), "Failed to disable stencil test, hr %#x.\n", hr);
20490 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
20491 ok(SUCCEEDED(hr), "Failed to disable culling, hr %#x.\n", hr);
20493 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
20494 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
20496 for (i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i)
20498 if (caps.VertexShaderVersion < tests[i].vs_version
20499 || caps.PixelShaderVersion < tests[i].ps_version)
20501 skip("Vertex / pixel shader version not supported, skipping test %u.\n", i);
20502 continue;
20504 if (tests[i].vs)
20506 hr = IDirect3DDevice9_CreateVertexShader(device, tests[i].vs, &vs);
20507 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x (case %u).\n", hr, i);
20509 else
20511 vs = NULL;
20513 if (tests[i].ps)
20515 hr = IDirect3DDevice9_CreatePixelShader(device, tests[i].ps, &ps);
20516 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x (case %u).\n", hr, i);
20518 else
20520 ps = NULL;
20523 hr = IDirect3DDevice9_SetVertexShader(device, vs);
20524 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
20525 hr = IDirect3DDevice9_SetPixelShader(device, ps);
20526 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
20528 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
20529 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
20531 hr = IDirect3DDevice9_BeginScene(device);
20532 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
20534 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
20535 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
20537 hr = IDirect3DDevice9_EndScene(device);
20538 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
20540 get_rt_readback(backbuffer, &rb);
20541 color = get_readback_color(&rb, 320, 240);
20542 ok(color_match(color, tests[i].expected, 1)
20543 || (tests[i].allow_zero_alpha && color_match(color, tests[i].expected & 0x00ffffff, 1))
20544 || (tests[i].allow_zero && !color) || (broken(warp && tests[i].broken_warp)),
20545 "Got unexpected color 0x%08x, case %u.\n", color, i);
20546 release_surface_readback(&rb);
20548 if (vs)
20549 IDirect3DVertexShader9_Release(vs);
20550 if (ps)
20551 IDirect3DVertexShader9_Release(ps);
20554 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
20555 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
20557 IDirect3DSurface9_Release(backbuffer);
20558 refcount = IDirect3DDevice9_Release(device);
20559 ok(!refcount, "Device has %u references left.\n", refcount);
20560 IDirect3D9_Release(d3d);
20561 DestroyWindow(window);
20564 static void test_multisample_init(void)
20566 IDirect3DDevice9 *device;
20567 IDirect3D9 *d3d;
20568 IDirect3DSurface9 *back, *multi;
20569 ULONG refcount;
20570 HWND window;
20571 HRESULT hr;
20572 D3DCOLOR color;
20573 unsigned int x, y;
20574 struct surface_readback rb;
20575 BOOL all_zero = TRUE;
20577 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
20578 0, 0, 640, 480, NULL, NULL, NULL, NULL);
20579 d3d = Direct3DCreate9(D3D_SDK_VERSION);
20580 ok(!!d3d, "Failed to create a D3D object.\n");
20582 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
20583 D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
20585 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping multisample init test.\n");
20586 goto done;
20589 if (!(device = create_device(d3d, window, window, TRUE)))
20591 skip("Failed to create a D3D device, skipping tests.\n");
20592 goto done;
20595 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &back);
20596 ok(SUCCEEDED(hr), "Failed to get back buffer, hr %#x.\n", hr);
20597 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
20598 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &multi, NULL);
20599 ok(SUCCEEDED(hr), "Failed to create multisampled render target, hr %#x.\n", hr);
20601 hr = IDirect3DDevice9_StretchRect(device, multi, NULL, back, NULL, D3DTEXF_POINT);
20602 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
20604 get_rt_readback(back, &rb);
20605 for (y = 0; y < 480; ++y)
20607 for (x = 0; x < 640; x++)
20609 color = get_readback_color(&rb, x, y);
20610 if (!color_match(color, 0x00000000, 0))
20612 all_zero = FALSE;
20613 break;
20616 if (!all_zero)
20617 break;
20619 release_surface_readback(&rb);
20620 ok(all_zero, "Got unexpected color 0x%08x, position %ux%u.\n", color, x, y);
20622 IDirect3DSurface9_Release(multi);
20623 IDirect3DSurface9_Release(back);
20625 refcount = IDirect3DDevice9_Release(device);
20626 ok(!refcount, "Device has %u references left.\n", refcount);
20628 done:
20629 IDirect3D9_Release(d3d);
20630 DestroyWindow(window);
20633 static void test_texture_blending(void)
20635 #define STATE_END() {0xffffffff, 0xffffffff}
20636 #define IS_STATE_END(s) (s.name == 0xffffffff && s.value == 0xffffffff)
20638 IDirect3DTexture9 *texture_bumpmap, *texture_red;
20639 IDirect3DSurface9 *backbuffer;
20640 struct surface_readback rb;
20641 D3DLOCKED_RECT locked_rect;
20642 IDirect3DDevice9 *device;
20643 unsigned int i, j, k;
20644 IDirect3D9 *d3d;
20645 D3DCOLOR color;
20646 ULONG refcount;
20647 D3DCAPS9 caps;
20648 HWND window;
20649 HRESULT hr;
20651 static const struct
20653 struct vec3 position;
20654 DWORD diffuse;
20656 quad[] =
20658 {{-1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0x80, 0xff, 0xff, 0x02)},
20659 {{-1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0x80, 0xff, 0xff, 0x02)},
20660 {{ 1.0f, -1.0f, 0.1f}, D3DCOLOR_ARGB(0x80, 0xff, 0xff, 0x02)},
20661 {{ 1.0f, 1.0f, 0.1f}, D3DCOLOR_ARGB(0x80, 0xff, 0xff, 0x02)},
20664 static const float bumpenvmat[4] = {1.0f, 1.0f, 0.0f, 0.0f};
20666 struct texture_stage_state
20668 D3DTEXTURESTAGESTATETYPE name;
20669 DWORD value;
20672 struct texture_stage
20674 enum
20676 TEXTURE_INVALID,
20677 TEXTURE_NONE,
20678 TEXTURE_BUMPMAP,
20679 TEXTURE_RED,
20681 texture;
20682 struct texture_stage_state state[20];
20685 static const struct texture_stage default_stage_state =
20687 TEXTURE_NONE,
20689 {D3DTSS_COLOROP, D3DTOP_DISABLE},
20690 {D3DTSS_COLORARG1, D3DTA_TEXTURE},
20691 {D3DTSS_COLORARG2, D3DTA_CURRENT},
20692 {D3DTSS_ALPHAOP, D3DTOP_DISABLE},
20693 {D3DTSS_ALPHAARG1, D3DTA_TEXTURE},
20694 {D3DTSS_ALPHAARG2, D3DTA_CURRENT},
20695 {D3DTSS_BUMPENVMAT00, 0},
20696 {D3DTSS_BUMPENVMAT01, 0},
20697 {D3DTSS_BUMPENVMAT10, 0},
20698 {D3DTSS_BUMPENVMAT11, 0},
20699 {D3DTSS_BUMPENVLSCALE, 0},
20700 {D3DTSS_BUMPENVLOFFSET, 0},
20701 {D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE},
20702 {D3DTSS_COLORARG0, D3DTA_CURRENT},
20703 {D3DTSS_ALPHAARG0, D3DTA_CURRENT},
20704 {D3DTSS_RESULTARG, D3DTA_CURRENT},
20705 {D3DTSS_CONSTANT, 0},
20706 STATE_END(),
20710 const struct test
20712 DWORD tex_op_caps;
20713 D3DCOLOR expected_color;
20714 struct texture_stage stage[8];
20716 tests[] =
20719 D3DTEXOPCAPS_DISABLE,
20720 0x80ffff02,
20723 TEXTURE_NONE,
20725 STATE_END(),
20731 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1,
20732 0x80ffff02,
20735 TEXTURE_NONE,
20737 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
20738 {D3DTSS_COLORARG1, D3DTA_CURRENT},
20739 STATE_END(),
20742 {TEXTURE_INVALID}
20746 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1,
20747 0x80ffff02,
20750 TEXTURE_NONE,
20752 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
20753 {D3DTSS_COLORARG1, D3DTA_CURRENT},
20754 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
20755 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
20756 STATE_END(),
20762 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1,
20763 0x80ffff02,
20766 TEXTURE_NONE,
20768 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
20769 {D3DTSS_COLORARG1, D3DTA_DIFFUSE},
20770 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
20771 {D3DTSS_ALPHAARG1, D3DTA_DIFFUSE},
20772 STATE_END(),
20778 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1,
20779 0x00000000,
20782 TEXTURE_NONE,
20784 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
20785 {D3DTSS_COLORARG1, D3DTA_TEMP},
20786 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
20787 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
20788 STATE_END(),
20794 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_SUBTRACT,
20795 0x80f0f000,
20798 TEXTURE_NONE,
20800 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
20801 {D3DTSS_COLORARG1, D3DTA_CURRENT},
20802 STATE_END(),
20806 TEXTURE_NONE,
20808 {D3DTSS_COLOROP, D3DTOP_SUBTRACT},
20809 {D3DTSS_COLORARG1, D3DTA_CURRENT},
20810 {D3DTSS_COLORARG2, D3DTA_CONSTANT},
20811 {D3DTSS_CONSTANT, 0x0f0f0f0f},
20812 STATE_END(),
20815 {TEXTURE_INVALID}
20819 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_SUBTRACT,
20820 0x71f0f000,
20823 TEXTURE_NONE,
20825 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
20826 {D3DTSS_COLORARG1, D3DTA_CURRENT},
20827 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
20828 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
20829 STATE_END(),
20833 TEXTURE_NONE,
20835 {D3DTSS_COLOROP, D3DTOP_SUBTRACT},
20836 {D3DTSS_COLORARG1, D3DTA_CURRENT},
20837 {D3DTSS_COLORARG2, D3DTA_CONSTANT},
20838 {D3DTSS_ALPHAOP, D3DTOP_SUBTRACT},
20839 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
20840 {D3DTSS_ALPHAARG2, D3DTA_CONSTANT},
20841 {D3DTSS_CONSTANT, 0x0f0f0f0f},
20842 STATE_END(),
20845 {TEXTURE_INVALID}
20850 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE,
20851 0x80ff0000,
20854 TEXTURE_BUMPMAP,
20856 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
20857 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
20858 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
20859 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
20860 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
20861 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
20862 {D3DTSS_ALPHAARG1, D3DTA_TEXTURE},
20863 STATE_END(),
20868 TEXTURE_RED,
20870 {D3DTSS_COLOROP, D3DTOP_MODULATE},
20871 STATE_END(),
20874 {TEXTURE_INVALID}
20878 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE,
20879 0x80ff0000,
20882 TEXTURE_BUMPMAP,
20884 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
20885 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
20886 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
20887 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
20888 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
20889 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
20890 {D3DTSS_ALPHAARG1, D3DTA_DIFFUSE},
20891 STATE_END(),
20895 TEXTURE_RED,
20897 {D3DTSS_COLOROP, D3DTOP_MODULATE},
20898 STATE_END(),
20901 {TEXTURE_INVALID}
20905 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE,
20906 0x80ff0000,
20909 TEXTURE_BUMPMAP,
20911 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
20912 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
20913 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
20914 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
20915 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
20916 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
20917 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
20918 STATE_END(),
20922 TEXTURE_RED,
20924 {D3DTSS_COLOROP, D3DTOP_MODULATE},
20925 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
20926 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
20927 STATE_END(),
20930 {TEXTURE_INVALID}
20934 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE,
20935 0x00ff0000,
20938 TEXTURE_BUMPMAP,
20940 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
20941 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
20942 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
20943 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
20944 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
20945 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
20946 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
20947 STATE_END(),
20951 TEXTURE_RED,
20953 {D3DTSS_COLOROP, D3DTOP_MODULATE},
20954 {D3DTSS_COLORARG1, D3DTA_TEXTURE},
20955 {D3DTSS_COLORARG2, D3DTA_CURRENT},
20956 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
20957 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
20958 STATE_END(),
20961 {TEXTURE_INVALID}
20965 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE,
20966 0x80ff0000,
20969 TEXTURE_BUMPMAP,
20971 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
20972 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
20973 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
20974 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
20975 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
20976 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
20977 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
20978 STATE_END(),
20982 TEXTURE_RED,
20984 {D3DTSS_COLOROP, D3DTOP_MODULATE},
20985 {D3DTSS_COLORARG1, D3DTA_TEXTURE},
20986 {D3DTSS_COLORARG2, D3DTA_CURRENT},
20987 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
20988 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
20989 STATE_END(),
20992 {TEXTURE_INVALID}
20997 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE
20998 | D3DTEXOPCAPS_ADD,
20999 0x80ff0000,
21002 TEXTURE_BUMPMAP,
21004 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
21005 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
21006 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
21007 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
21008 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
21009 {D3DTSS_ALPHAOP, D3DTOP_ADD},
21010 {D3DTSS_ALPHAARG1, D3DTA_DIFFUSE},
21011 {D3DTSS_ALPHAARG2, D3DTA_CONSTANT},
21012 {D3DTSS_CONSTANT, 0x0fffffff},
21013 STATE_END(),
21017 TEXTURE_RED,
21019 {D3DTSS_COLOROP, D3DTOP_MODULATE},
21020 {D3DTSS_COLORARG1, D3DTA_TEXTURE},
21021 {D3DTSS_COLORARG2, D3DTA_CURRENT},
21022 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21023 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
21024 STATE_END(),
21027 {TEXTURE_INVALID}
21031 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE
21032 | D3DTEXOPCAPS_MODULATE2X,
21033 0x80ff0000,
21036 TEXTURE_BUMPMAP,
21038 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
21039 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
21040 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
21041 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
21042 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
21043 {D3DTSS_ALPHAOP, D3DTOP_MODULATE2X},
21044 {D3DTSS_ALPHAARG1, D3DTA_DIFFUSE},
21045 {D3DTSS_ALPHAARG2, D3DTA_CONSTANT},
21046 {D3DTSS_CONSTANT, 0x01ffffff},
21047 STATE_END(),
21051 TEXTURE_RED,
21053 {D3DTSS_COLOROP, D3DTOP_MODULATE},
21054 {D3DTSS_COLORARG1, D3DTA_TEXTURE},
21055 {D3DTSS_COLORARG2, D3DTA_CURRENT},
21056 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21057 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
21058 STATE_END(),
21061 {TEXTURE_INVALID}
21065 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP | D3DTEXOPCAPS_MODULATE
21066 | D3DTEXOPCAPS_MODULATE2X,
21067 0x80ffff00,
21070 TEXTURE_BUMPMAP,
21072 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
21073 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
21074 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
21075 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
21076 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
21077 {D3DTSS_ALPHAOP, D3DTOP_MODULATE2X},
21078 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
21079 {D3DTSS_ALPHAARG2, D3DTA_CONSTANT},
21080 {D3DTSS_CONSTANT, 0x01ffffff},
21081 STATE_END(),
21085 TEXTURE_RED,
21087 {D3DTSS_COLOROP, D3DTOP_MODULATE},
21088 {D3DTSS_COLORARG1, D3DTA_CURRENT},
21089 {D3DTSS_COLORARG2, D3DTA_CURRENT},
21090 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21091 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
21092 {D3DTSS_ALPHAARG2, D3DTA_CONSTANT},
21093 {D3DTSS_ALPHAARG0, D3DTA_CONSTANT},
21094 STATE_END(),
21097 {TEXTURE_INVALID}
21101 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP,
21102 0x01234567,
21105 TEXTURE_NONE,
21107 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
21108 {D3DTSS_COLORARG1, D3DTA_CONSTANT},
21109 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21110 {D3DTSS_ALPHAARG1, D3DTA_CONSTANT},
21111 {D3DTSS_RESULTARG, D3DTA_TEMP},
21112 {D3DTSS_CONSTANT, 0x01234567},
21113 STATE_END(),
21117 TEXTURE_BUMPMAP,
21119 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
21120 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
21121 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
21122 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
21123 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
21124 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21125 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
21126 {D3DTSS_RESULTARG, D3DTA_TEMP},
21127 STATE_END(),
21131 TEXTURE_RED,
21133 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
21134 {D3DTSS_COLORARG1, D3DTA_TEXTURE},
21135 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21136 {D3DTSS_ALPHAARG1, D3DTA_TEXTURE},
21137 STATE_END(),
21141 TEXTURE_NONE,
21143 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
21144 {D3DTSS_COLORARG1, D3DTA_TEMP},
21145 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21146 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
21147 STATE_END(),
21150 {TEXTURE_INVALID}
21154 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP,
21155 0x00234567,
21158 TEXTURE_NONE,
21160 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
21161 {D3DTSS_COLORARG1, D3DTA_CONSTANT},
21162 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21163 {D3DTSS_ALPHAARG1, D3DTA_CONSTANT},
21164 {D3DTSS_RESULTARG, D3DTA_TEMP},
21165 {D3DTSS_CONSTANT, 0x01234567},
21166 STATE_END(),
21170 TEXTURE_BUMPMAP,
21172 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
21173 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
21174 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
21175 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
21176 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
21177 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21178 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
21179 STATE_END(),
21183 TEXTURE_RED,
21185 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
21186 {D3DTSS_COLORARG1, D3DTA_TEXTURE},
21187 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21188 {D3DTSS_ALPHAARG1, D3DTA_TEXTURE},
21189 STATE_END(),
21193 TEXTURE_NONE,
21195 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
21196 {D3DTSS_COLORARG1, D3DTA_TEMP},
21197 STATE_END(),
21200 {TEXTURE_INVALID}
21204 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP,
21205 0x01234567,
21208 TEXTURE_NONE,
21210 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
21211 {D3DTSS_COLORARG1, D3DTA_CONSTANT},
21212 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21213 {D3DTSS_ALPHAARG1, D3DTA_CONSTANT},
21214 {D3DTSS_RESULTARG, D3DTA_TEMP},
21215 {D3DTSS_CONSTANT, 0x01234567},
21216 STATE_END(),
21220 TEXTURE_BUMPMAP,
21222 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
21223 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
21224 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
21225 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
21226 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
21227 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21228 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
21229 {D3DTSS_RESULTARG, D3DTA_TEMP},
21230 STATE_END(),
21234 TEXTURE_RED,
21236 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
21237 {D3DTSS_COLORARG1, D3DTA_TEXTURE},
21238 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21239 {D3DTSS_ALPHAARG1, D3DTA_TEXTURE},
21240 STATE_END(),
21244 TEXTURE_NONE,
21246 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
21247 {D3DTSS_COLORARG1, D3DTA_TEMP},
21248 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21249 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
21250 STATE_END(),
21253 {TEXTURE_INVALID}
21257 D3DTEXOPCAPS_DISABLE | D3DTEXOPCAPS_SELECTARG1 | D3DTEXOPCAPS_BUMPENVMAP,
21258 0x01234567,
21261 TEXTURE_NONE,
21263 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
21264 {D3DTSS_COLORARG1, D3DTA_CONSTANT},
21265 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21266 {D3DTSS_ALPHAARG1, D3DTA_CONSTANT},
21267 {D3DTSS_RESULTARG, D3DTA_CURRENT},
21268 {D3DTSS_CONSTANT, 0x01234567},
21269 STATE_END(),
21273 TEXTURE_BUMPMAP,
21275 {D3DTSS_COLOROP, D3DTOP_BUMPENVMAP},
21276 {D3DTSS_BUMPENVMAT00, *(DWORD *)&bumpenvmat[0]},
21277 {D3DTSS_BUMPENVMAT01, *(DWORD *)&bumpenvmat[1]},
21278 {D3DTSS_BUMPENVMAT10, *(DWORD *)&bumpenvmat[2]},
21279 {D3DTSS_BUMPENVMAT11, *(DWORD *)&bumpenvmat[3]},
21280 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21281 {D3DTSS_ALPHAARG1, D3DTA_TEMP},
21282 {D3DTSS_RESULTARG, D3DTA_TEMP},
21283 STATE_END(),
21287 TEXTURE_RED,
21289 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
21290 {D3DTSS_COLORARG1, D3DTA_TEXTURE},
21291 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21292 {D3DTSS_ALPHAARG1, D3DTA_TEXTURE},
21293 {D3DTSS_RESULTARG, D3DTA_TEMP},
21294 STATE_END(),
21298 TEXTURE_NONE,
21300 {D3DTSS_COLOROP, D3DTOP_SELECTARG1},
21301 {D3DTSS_COLORARG1, D3DTA_CURRENT},
21302 {D3DTSS_ALPHAOP, D3DTOP_SELECTARG1},
21303 {D3DTSS_ALPHAARG1, D3DTA_CURRENT},
21304 {D3DTSS_RESULTARG, D3DTA_CURRENT},
21305 STATE_END(),
21308 {TEXTURE_INVALID}
21313 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
21314 0, 0, 640, 480, NULL, NULL, NULL, NULL);
21315 d3d = Direct3DCreate9(D3D_SDK_VERSION);
21316 ok(!!d3d, "Failed to create a D3D object.\n");
21317 if (!(device = create_device(d3d, window, window, TRUE)))
21319 skip("Failed to create a D3D device.\n");
21320 goto done;
21323 memset(&caps, 0, sizeof(caps));
21324 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
21325 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr %#x.\n", hr);
21327 if(!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP))
21329 skip("D3DPMISCCAPS_TSSARGTEMP not supported.\n");
21330 IDirect3DDevice9_Release(device);
21331 goto done;
21334 if (!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_PERSTAGECONSTANT))
21336 skip("D3DPMISCCAPS_PERSTAGECONSTANT not supported.\n");
21337 IDirect3DDevice9_Release(device);
21338 goto done;
21341 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
21342 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_V8U8)))
21344 skip("D3DFMT_V8U8 not supported for legacy bump mapping.\n");
21345 IDirect3DDevice9_Release(device);
21346 goto done;
21349 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
21350 ok(hr == D3D_OK, "Can't get back buffer, hr %#x.\n", hr);
21352 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture_bumpmap, NULL);
21353 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr %#x.\n", hr);
21354 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture_red, NULL);
21355 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr %#x.\n", hr);
21357 memset(&locked_rect, 0, sizeof(locked_rect));
21358 hr = IDirect3DTexture9_LockRect(texture_bumpmap, 0, &locked_rect, NULL, 0);
21359 ok(SUCCEEDED(hr), "LockRect failed, hr %#x.\n", hr);
21360 *((WORD *)locked_rect.pBits) = 0xff00;
21361 hr = IDirect3DTexture9_UnlockRect(texture_bumpmap, 0);
21362 ok(SUCCEEDED(hr), "UnlockRect failed, hr %#x.\n", hr);
21364 memset(&locked_rect, 0, sizeof(locked_rect));
21365 hr = IDirect3DTexture9_LockRect(texture_red, 0, &locked_rect, NULL, 0);
21366 ok(SUCCEEDED(hr), "LockRect failed, hr %#x.\n", hr);
21367 *((DWORD *)locked_rect.pBits) = 0x00ff0000;
21368 hr = IDirect3DTexture9_UnlockRect(texture_red, 0);
21369 ok(SUCCEEDED(hr), "UnlockRect failed, hr %#x.\n", hr);
21371 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
21372 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
21373 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
21374 ok(hr == D3D_OK, "Failed to disable lighting, hr %#x.\n", hr);
21376 for (i = 0; i < sizeof(tests) / sizeof(*tests); ++i)
21378 const struct test *current_test = &tests[i];
21380 if ((caps.TextureOpCaps & current_test->tex_op_caps) != current_test->tex_op_caps)
21382 skip("Texture operations %#x not supported.\n", current_test->tex_op_caps);
21383 continue;
21386 for (j = 0; j < caps.MaxTextureBlendStages; ++j)
21388 IDirect3DTexture9 *current_texture = NULL;
21390 for (k = 0; !IS_STATE_END(default_stage_state.state[k]); ++k)
21392 hr = IDirect3DDevice9_SetTextureStageState(device, j,
21393 default_stage_state.state[k].name, default_stage_state.state[k].value);
21394 ok(SUCCEEDED(hr), "Test %u: SetTextureStageState failed, hr %#x.\n", i, hr);
21397 if (current_test->stage[j].texture != TEXTURE_INVALID)
21399 const struct texture_stage_state *current_state = current_test->stage[j].state;
21401 switch (current_test->stage[j].texture)
21403 case TEXTURE_RED:
21404 current_texture = texture_red;
21405 break;
21406 case TEXTURE_BUMPMAP:
21407 current_texture = texture_bumpmap;
21408 break;
21409 default:
21410 current_texture = NULL;
21411 break;
21414 for (k = 0; !IS_STATE_END(current_state[k]); ++k)
21416 hr = IDirect3DDevice9_SetTextureStageState(device, j,
21417 current_state[k].name, current_state[k].value);
21418 ok(SUCCEEDED(hr), "Test %u: SetTextureStageState failed, hr %#x.\n", i, hr);
21422 hr = IDirect3DDevice9_SetTexture(device, j, (IDirect3DBaseTexture9 *)current_texture);
21423 ok(SUCCEEDED(hr), "Test %u: SetTexture failed, hr %#x.\n", i, hr);
21426 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
21427 ok(hr == D3D_OK, "Test %u: IDirect3DDevice9_Clear failed, hr %#x.\n", i, hr);
21429 hr = IDirect3DDevice9_BeginScene(device);
21430 ok(SUCCEEDED(hr), "Test %u: BeginScene failed, hr %#x.\n", i, hr);
21431 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
21432 ok(SUCCEEDED(hr), "Test %u: DrawPrimitiveUP failed, hr %#x.\n", i, hr);
21433 hr = IDirect3DDevice9_EndScene(device);
21434 ok(SUCCEEDED(hr), "Test %u: EndScene failed, hr %#x.\n", i, hr);
21436 get_rt_readback(backbuffer, &rb);
21437 color = get_readback_color(&rb, 320, 240);
21438 ok(color_match(color, current_test->expected_color, 1),
21439 "Test %u: Got color 0x%08x, expected 0x%08x.\n", i, color, current_test->expected_color);
21440 release_surface_readback(&rb);
21441 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
21442 ok(SUCCEEDED(hr), "Test %u: Present failed, hr %#x.\n", i, hr);
21445 IDirect3DTexture9_Release(texture_bumpmap);
21446 IDirect3DTexture9_Release(texture_red);
21447 IDirect3DSurface9_Release(backbuffer);
21448 refcount = IDirect3DDevice9_Release(device);
21449 ok(!refcount, "Device has %u references left.\n", refcount);
21450 done:
21451 IDirect3D9_Release(d3d);
21452 DestroyWindow(window);
21455 START_TEST(visual)
21457 D3DADAPTER_IDENTIFIER9 identifier;
21458 IDirect3D9 *d3d;
21459 HRESULT hr;
21461 if (!(d3d = Direct3DCreate9(D3D_SDK_VERSION)))
21463 skip("could not create D3D9 object\n");
21464 return;
21467 memset(&identifier, 0, sizeof(identifier));
21468 hr = IDirect3D9_GetAdapterIdentifier(d3d, 0, 0, &identifier);
21469 ok(SUCCEEDED(hr), "Failed to get adapter identifier, hr %#x.\n", hr);
21470 trace("Driver string: \"%s\"\n", identifier.Driver);
21471 trace("Description string: \"%s\"\n", identifier.Description);
21472 /* Only Windows XP's default VGA driver should have an empty description */
21473 ok(identifier.Description[0] || broken(!strcmp(identifier.Driver, "vga.dll")), "Empty driver description.\n");
21474 trace("Device name string: \"%s\"\n", identifier.DeviceName);
21475 ok(identifier.DeviceName[0], "Empty device name.\n");
21476 trace("Driver version %d.%d.%d.%d\n",
21477 HIWORD(U(identifier.DriverVersion).HighPart), LOWORD(U(identifier.DriverVersion).HighPart),
21478 HIWORD(U(identifier.DriverVersion).LowPart), LOWORD(U(identifier.DriverVersion).LowPart));
21480 IDirect3D9_Release(d3d);
21482 test_sanity();
21483 depth_clamp_test();
21484 stretchrect_test();
21485 lighting_test();
21486 test_specular_lighting();
21487 clear_test();
21488 color_fill_test();
21489 fog_test();
21490 test_cube_wrap();
21491 z_range_test();
21492 maxmip_test();
21493 offscreen_test();
21494 ds_size_test();
21495 test_blend();
21496 test_shademode();
21497 srgbtexture_test();
21498 release_buffer_test();
21499 float_texture_test();
21500 g16r16_texture_test();
21501 pixelshader_blending_test();
21502 texture_transform_flags_test();
21503 autogen_mipmap_test();
21504 fixed_function_decl_test();
21505 conditional_np2_repeat_test();
21506 fixed_function_bumpmap_test();
21507 test_pointsize();
21508 tssargtemp_test();
21509 np2_stretch_rect_test();
21510 yuv_color_test();
21511 yuv_layout_test();
21512 zwriteenable_test();
21513 alphatest_test();
21514 viewport_test();
21515 test_constant_clamp_vs();
21516 test_compare_instructions();
21517 test_mova();
21518 loop_index_test();
21519 sincos_test();
21520 sgn_test();
21521 clip_planes_test();
21522 test_vshader_input();
21523 test_vshader_float16();
21524 stream_test();
21525 fog_with_shader_test();
21526 texbem_test();
21527 texdepth_test();
21528 texkill_test();
21529 volume_v16u16_test();
21530 constant_clamp_ps_test();
21531 cnd_test();
21532 dp2add_ps_test();
21533 unbound_sampler_test();
21534 nested_loop_test();
21535 pretransformed_varying_test();
21536 vface_register_test();
21537 test_fragment_coords();
21538 multiple_rendertargets_test();
21539 texop_test();
21540 texop_range_test();
21541 alphareplicate_test();
21542 dp3_alpha_test();
21543 depth_buffer_test();
21544 depth_buffer2_test();
21545 depth_blit_test();
21546 intz_test();
21547 shadow_test();
21548 fp_special_test();
21549 depth_bounds_test();
21550 srgbwrite_format_test();
21551 update_surface_test();
21552 multisample_get_rtdata_test();
21553 zenable_test();
21554 fog_special_test();
21555 volume_srgb_test();
21556 volume_dxt5_test();
21557 add_dirty_rect_test();
21558 multisampled_depth_buffer_test();
21559 resz_test();
21560 stencil_cull_test();
21561 test_per_stage_constant();
21562 test_3dc_formats();
21563 test_fog_interpolation();
21564 test_negative_fixedfunction_fog();
21565 test_position_index();
21566 test_table_fog_zw();
21567 test_signed_formats();
21568 test_multisample_mismatch();
21569 test_texcoordindex();
21570 test_vertex_blending();
21571 test_updatetexture();
21572 test_depthbias();
21573 test_flip();
21574 test_uninitialized_varyings();
21575 test_multisample_init();
21576 test_texture_blending();