d3d9/tests: Multisampled render targets are zeroed on creation.
[wine.git] / dlls / d3d9 / tests / visual.c
blob7ab751cc3b7a79917349ee451c222f30991fec1a
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 /* Tests the correctness of clearing parameters */
877 HRESULT hr;
878 D3DRECT rect[2];
879 D3DRECT rect_negneg;
880 DWORD color;
881 D3DVIEWPORT9 old_vp, vp;
882 RECT scissor;
883 DWORD oldColorWrite;
884 BOOL invalid_clear_failed = FALSE;
885 IDirect3DDevice9 *device;
886 IDirect3D9 *d3d;
887 ULONG refcount;
888 HWND window;
890 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
891 0, 0, 640, 480, NULL, NULL, NULL, NULL);
892 d3d = Direct3DCreate9(D3D_SDK_VERSION);
893 ok(!!d3d, "Failed to create a D3D object.\n");
894 if (!(device = create_device(d3d, window, window, TRUE)))
896 skip("Failed to create a D3D device, skipping tests.\n");
897 goto done;
900 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
901 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
903 /* Positive x, negative y */
904 rect[0].x1 = 0;
905 rect[0].y1 = 480;
906 rect[0].x2 = 320;
907 rect[0].y2 = 240;
909 /* Positive x, positive y */
910 rect[1].x1 = 0;
911 rect[1].y1 = 0;
912 rect[1].x2 = 320;
913 rect[1].y2 = 240;
914 /* Clear 2 rectangles with one call. The refrast returns an error in this case, every real driver tested so far
915 * returns D3D_OK, but ignores the rectangle silently
917 hr = IDirect3DDevice9_Clear(device, 2, rect, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
918 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %08x\n", hr);
919 if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
921 /* negative x, negative y */
922 rect_negneg.x1 = 640;
923 rect_negneg.y1 = 240;
924 rect_negneg.x2 = 320;
925 rect_negneg.y2 = 0;
926 hr = IDirect3DDevice9_Clear(device, 1, &rect_negneg, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
927 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Clear failed with %08x\n", hr);
928 if(hr == D3DERR_INVALIDCALL) invalid_clear_failed = TRUE;
930 color = getPixelColor(device, 160, 360); /* lower left quad */
931 ok(color == 0x00ffffff, "Clear rectangle 3(pos, neg) has color %08x\n", color);
932 color = getPixelColor(device, 160, 120); /* upper left quad */
933 if(invalid_clear_failed) {
934 /* If the negative rectangle was refused, the other rectangles in the list shouldn't be cleared either */
935 ok(color == 0x00ffffff, "Clear rectangle 1(pos, pos) has color %08x\n", color);
936 } else {
937 /* If the negative rectangle was dropped silently, the correct ones are cleared */
938 ok(color == 0x00ff0000, "Clear rectangle 1(pos, pos) has color %08x\n", color);
940 color = getPixelColor(device, 480, 360); /* lower right quad */
941 ok(color == 0x00ffffff, "Clear rectangle 4(NULL) has color %08x\n", color);
942 color = getPixelColor(device, 480, 120); /* upper right quad */
943 ok(color == 0x00ffffff, "Clear rectangle 4(neg, neg) has color %08x\n", color);
945 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
947 /* Hack to work around a nvidia windows driver bug. The clear below is supposed to
948 * clear the red quad in the top left part of the render target. For some reason it
949 * doesn't work if the clear color is 0xffffffff on some versions of the Nvidia Windows
950 * driver(tested on 8.17.12.5896, Win7). A clear with a different color works around
951 * this bug and fixes the clear with the white color. Even 0xfeffffff works, but let's
952 * pick some obvious value
954 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xdeadbabe, 0.0, 0);
955 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
957 /* Test how the viewport affects clears */
958 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
959 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
960 hr = IDirect3DDevice9_GetViewport(device, &old_vp);
961 ok(hr == D3D_OK, "IDirect3DDevice9_GetViewport failed with %08x\n", hr);
963 vp.X = 160;
964 vp.Y = 120;
965 vp.Width = 160;
966 vp.Height = 120;
967 vp.MinZ = 0.0;
968 vp.MaxZ = 1.0;
969 hr = IDirect3DDevice9_SetViewport(device, &vp);
970 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
971 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
972 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
974 vp.X = 320;
975 vp.Y = 240;
976 vp.Width = 320;
977 vp.Height = 240;
978 vp.MinZ = 0.0;
979 vp.MaxZ = 1.0;
980 hr = IDirect3DDevice9_SetViewport(device, &vp);
981 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
982 rect[0].x1 = 160;
983 rect[0].y1 = 120;
984 rect[0].x2 = 480;
985 rect[0].y2 = 360;
986 hr = IDirect3DDevice9_Clear(device, 1, &rect[0], D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
987 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
989 hr = IDirect3DDevice9_SetViewport(device, &old_vp);
990 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
992 color = getPixelColor(device, 158, 118);
993 ok(color == 0x00ffffff, "(158,118) has color %08x\n", color);
994 color = getPixelColor(device, 162, 118);
995 ok(color == 0x00ffffff, "(162,118) has color %08x\n", color);
996 color = getPixelColor(device, 158, 122);
997 ok(color == 0x00ffffff, "(158,122) has color %08x\n", color);
998 color = getPixelColor(device, 162, 122);
999 ok(color == 0x000000ff, "(162,122) has color %08x\n", color);
1001 color = getPixelColor(device, 318, 238);
1002 ok(color == 0x000000ff, "(318,238) has color %08x\n", color);
1003 color = getPixelColor(device, 322, 238);
1004 ok(color == 0x00ffffff, "(322,328) has color %08x\n", color);
1005 color = getPixelColor(device, 318, 242);
1006 ok(color == 0x00ffffff, "(318,242) has color %08x\n", color);
1007 color = getPixelColor(device, 322, 242);
1008 ok(color == 0x0000ff00, "(322,242) has color %08x\n", color);
1010 color = getPixelColor(device, 478, 358);
1011 ok(color == 0x0000ff00, "(478,358 has color %08x\n", color);
1012 color = getPixelColor(device, 482, 358);
1013 ok(color == 0x00ffffff, "(482,358) has color %08x\n", color);
1014 color = getPixelColor(device, 478, 362);
1015 ok(color == 0x00ffffff, "(478,362) has color %08x\n", color);
1016 color = getPixelColor(device, 482, 362);
1017 ok(color == 0x00ffffff, "(482,362) has color %08x\n", color);
1019 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1021 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
1022 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
1024 scissor.left = 160;
1025 scissor.right = 480;
1026 scissor.top = 120;
1027 scissor.bottom = 360;
1028 hr = IDirect3DDevice9_SetScissorRect(device, &scissor);
1029 ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
1030 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, TRUE);
1031 ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
1033 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
1034 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
1035 hr = IDirect3DDevice9_Clear(device, 1, &rect[1], D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1036 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
1038 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SCISSORTESTENABLE, FALSE);
1039 ok(hr == D3D_OK, "IDirect3DDevice_SetScissorRect failed with %08x\n", hr);
1041 color = getPixelColor(device, 158, 118);
1042 ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
1043 color = getPixelColor(device, 162, 118);
1044 ok(color == 0x00ffffff, "Pixel 162/118 has color %08x\n", color);
1045 color = getPixelColor(device, 158, 122);
1046 ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
1047 color = getPixelColor(device, 162, 122);
1048 ok(color == 0x00ff0000, "Pixel 162/122 has color %08x\n", color);
1050 color = getPixelColor(device, 158, 358);
1051 ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
1052 color = getPixelColor(device, 162, 358);
1053 ok(color == 0x0000ff00, "Pixel 162/358 has color %08x\n", color);
1054 color = getPixelColor(device, 158, 358);
1055 ok(color == 0x00ffffff, "Pixel 158/358 has color %08x\n", color);
1056 color = getPixelColor(device, 162, 362);
1057 ok(color == 0x00ffffff, "Pixel 162/362 has color %08x\n", color);
1059 color = getPixelColor(device, 478, 118);
1060 ok(color == 0x00ffffff, "Pixel 158/118 has color %08x\n", color);
1061 color = getPixelColor(device, 478, 122);
1062 ok(color == 0x0000ff00, "Pixel 162/118 has color %08x\n", color);
1063 color = getPixelColor(device, 482, 122);
1064 ok(color == 0x00ffffff, "Pixel 158/122 has color %08x\n", color);
1065 color = getPixelColor(device, 482, 358);
1066 ok(color == 0x00ffffff, "Pixel 162/122 has color %08x\n", color);
1068 color = getPixelColor(device, 478, 358);
1069 ok(color == 0x0000ff00, "Pixel 478/358 has color %08x\n", color);
1070 color = getPixelColor(device, 478, 362);
1071 ok(color == 0x00ffffff, "Pixel 478/118 has color %08x\n", color);
1072 color = getPixelColor(device, 482, 358);
1073 ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
1074 color = getPixelColor(device, 482, 362);
1075 ok(color == 0x00ffffff, "Pixel 482/122 has color %08x\n", color);
1077 color = getPixelColor(device, 318, 238);
1078 ok(color == 0x00ff0000, "Pixel 318/238 has color %08x\n", color);
1079 color = getPixelColor(device, 318, 242);
1080 ok(color == 0x0000ff00, "Pixel 318/242 has color %08x\n", color);
1081 color = getPixelColor(device, 322, 238);
1082 ok(color == 0x0000ff00, "Pixel 322/238 has color %08x\n", color);
1083 color = getPixelColor(device, 322, 242);
1084 ok(color == 0x0000ff00, "Pixel 322/242 has color %08x\n", color);
1086 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1088 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_COLORWRITEENABLE, &oldColorWrite);
1089 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderState failed with %08x\n", hr);
1090 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED);
1091 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
1093 /* Same nvidia windows driver trouble with white clears as earlier in the same test */
1094 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xdeadbeef, 0.0, 0);
1095 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
1097 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
1098 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
1100 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, oldColorWrite);
1101 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with %08x\n", hr);
1103 /* Colorwriteenable does not affect the clear */
1104 color = getPixelColor(device, 320, 240);
1105 ok(color == 0x00ffffff, "Color write protected clear returned color %08x\n", color);
1107 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1109 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ffffff, 0.0, 0);
1110 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with %08x\n", hr);
1112 rect[0].x1 = 0;
1113 rect[0].y1 = 0;
1114 rect[0].x2 = 640;
1115 rect[0].y2 = 480;
1116 hr = IDirect3DDevice9_Clear(device, 0, rect, D3DCLEAR_TARGET, 0x00ff0000, 0.0, 0);
1117 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with %08x\n", hr);
1119 color = getPixelColor(device, 320, 240);
1120 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff), 1),
1121 "Clear with count = 0, rect != NULL has color %08x\n", color);
1123 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1125 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
1126 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with %08x\n", hr);
1127 hr = IDirect3DDevice9_Clear(device, 1, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
1128 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with %08x\n", hr);
1130 color = getPixelColor(device, 320, 240);
1131 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
1132 "Clear with count = 1, rect = NULL has color %08x\n", color);
1134 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1136 refcount = IDirect3DDevice9_Release(device);
1137 ok(!refcount, "Device has %u references left.\n", refcount);
1138 done:
1139 IDirect3D9_Release(d3d);
1140 DestroyWindow(window);
1143 static void color_fill_test(void)
1145 IDirect3DSurface9 *surface;
1146 IDirect3DTexture9 *texture;
1147 D3DCOLOR fill_color, color;
1148 DWORD fill_a, expected_a;
1149 IDirect3DDevice9 *device;
1150 IDirect3D9 *d3d;
1151 ULONG refcount;
1152 HWND window;
1153 HRESULT hr;
1154 static const struct
1156 D3DPOOL pool;
1157 DWORD usage;
1158 HRESULT hr;
1160 resource_types[] =
1162 {D3DPOOL_DEFAULT, 0, D3DERR_INVALIDCALL},
1163 {D3DPOOL_DEFAULT, D3DUSAGE_DYNAMIC, D3DERR_INVALIDCALL},
1164 {D3DPOOL_DEFAULT, D3DUSAGE_RENDERTARGET, D3D_OK},
1165 {D3DPOOL_SYSTEMMEM, 0, D3DERR_INVALIDCALL},
1166 {D3DPOOL_MANAGED, 0, D3DERR_INVALIDCALL},
1167 {D3DPOOL_SCRATCH, 0, D3DERR_INVALIDCALL},
1169 static const struct
1171 D3DFORMAT format;
1172 const char *name;
1173 enum
1175 CHECK_FILL_VALUE = 0x1,
1176 TODO_FILL_RETURN = 0x2,
1177 BLOCKS = 0x4,
1178 } flags;
1179 DWORD fill_value;
1181 formats[] =
1183 {D3DFMT_A8R8G8B8, "D3DFMT_A8R8G8B8", CHECK_FILL_VALUE, 0xdeadbeef},
1184 /* D3DFMT_X8R8G8B8 either set X = A or X = 0, depending on the driver. */
1185 {D3DFMT_R5G6B5, "D3DFMT_R5G6B5", CHECK_FILL_VALUE, 0xadfdadfd},
1186 {D3DFMT_G16R16, "D3DFMT_G16R16", CHECK_FILL_VALUE, 0xbebeadad},
1187 /* Real hardware reliably fills the surface with the blue channel but
1188 * the testbot fills it with 0x00. Wine incorrectly uses the alpha
1189 * channel. Don't bother checking the result because P8 surfaces are
1190 * essentially useless in d3d9. */
1191 {D3DFMT_P8, "D3DFMT_P8", 0, 0xefefefef},
1192 /* Windows drivers produce different results for these formats.
1193 * No driver produces a YUV value that matches the input RGB
1194 * value, and no driver produces a proper DXT compression block.
1196 * Even the clear value 0 does not reliably produce a fill value
1197 * that will return vec4(0.0, 0.0, 0.0, 0.0) when sampled.
1199 * The YUV tests are disabled because they produce a driver-dependent
1200 * result on Wine.
1201 * {D3DFMT_YUY2, "D3DFMT_YUY2", BLOCKS, 0},
1202 * {D3DFMT_UYVY, "D3DFMT_UYVY", BLOCKS, 0}, */
1203 {D3DFMT_DXT1, "D3DFMT_DXT1", BLOCKS | TODO_FILL_RETURN, 0},
1204 /* Vendor-specific formats like ATI2N are a non-issue here since they're not
1205 * supported as offscreen plain surfaces and do not support D3DUSAGE_RENDERTARGET
1206 * when created as texture. */
1208 unsigned int i;
1209 D3DLOCKED_RECT locked_rect;
1210 DWORD *surface_data;
1211 static const RECT rect = {4, 4, 8, 8}, rect2 = {5, 5, 7, 7};
1213 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
1214 0, 0, 640, 480, NULL, NULL, NULL, NULL);
1215 d3d = Direct3DCreate9(D3D_SDK_VERSION);
1216 ok(!!d3d, "Failed to create a D3D object.\n");
1217 if (!(device = create_device(d3d, window, window, TRUE)))
1219 skip("Failed to create a D3D device, skipping tests.\n");
1220 goto done;
1223 /* Test ColorFill on a the backbuffer (should pass) */
1224 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &surface);
1225 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
1227 fill_color = 0x112233;
1228 hr = IDirect3DDevice9_ColorFill(device, surface, NULL, fill_color);
1229 ok(SUCCEEDED(hr), "Color fill failed, hr %#x.\n", hr);
1231 color = getPixelColor(device, 0, 0);
1232 ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
1234 IDirect3DSurface9_Release(surface);
1236 /* Test ColorFill on a render target surface (should pass) */
1237 hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_A8R8G8B8,
1238 D3DMULTISAMPLE_NONE, 0, TRUE, &surface, NULL );
1239 ok(hr == D3D_OK, "Unable to create render target surface, hr = %08x\n", hr);
1241 fill_color = 0x445566;
1242 hr = IDirect3DDevice9_ColorFill(device, surface, NULL, fill_color);
1243 ok(SUCCEEDED(hr), "Color fill failed, hr %#x.\n", hr);
1245 color = getPixelColorFromSurface(surface, 0, 0);
1246 ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
1248 IDirect3DSurface9_Release(surface);
1250 /* Test ColorFill on an offscreen plain surface in D3DPOOL_DEFAULT (should pass) */
1251 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
1252 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surface, NULL);
1253 ok(hr == D3D_OK, "Unable to create offscreen plain surface, hr = %08x\n", hr);
1255 fill_color = 0x778899;
1256 hr = IDirect3DDevice9_ColorFill(device, surface, NULL, fill_color);
1257 ok(SUCCEEDED(hr), "Color fill failed, hr %#x.\n", hr);
1259 color = getPixelColorFromSurface(surface, 0, 0);
1260 ok(color == fill_color, "Expected color %08x, got %08x\n", fill_color, color);
1262 IDirect3DSurface9_Release(surface);
1264 /* Try ColorFill on an offscreen surface in sysmem (should fail) */
1265 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
1266 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surface, NULL);
1267 ok(hr == D3D_OK, "Unable to create offscreen plain surface, hr = %08x\n", hr);
1269 hr = IDirect3DDevice9_ColorFill(device, surface, NULL, 0);
1270 ok(hr == D3DERR_INVALIDCALL, "ColorFill on offscreen sysmem surface failed with hr = %08x\n", hr);
1272 IDirect3DSurface9_Release(surface);
1274 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 32, 32, D3DFMT_D16,
1275 D3DMULTISAMPLE_NONE, 0, TRUE, &surface, NULL);
1276 ok(SUCCEEDED(hr), "Failed to create depth stencil surface, hr = %08x.\n", hr);
1278 hr = IDirect3DDevice9_ColorFill(device, surface, NULL, 0);
1279 ok(hr == D3DERR_INVALIDCALL, "ColorFill on a depth stencil surface returned hr = %08x.\n", hr);
1281 IDirect3DSurface9_Release(surface);
1283 for (i = 0; i < sizeof(resource_types) / sizeof(resource_types[0]); i++)
1285 texture = NULL;
1286 hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, resource_types[i].usage,
1287 D3DFMT_A8R8G8B8, resource_types[i].pool, &texture, NULL);
1288 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x, i=%u.\n", hr, i);
1289 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
1290 ok(SUCCEEDED(hr), "Failed to get surface, hr %#x, i=%u.\n", hr, i);
1292 hr = IDirect3DDevice9_ColorFill(device, surface, NULL, fill_color);
1293 ok(hr == resource_types[i].hr, "Got unexpected hr %#x, expected %#x, i=%u.\n",
1294 hr, resource_types[i].hr, i);
1296 IDirect3DSurface9_Release(surface);
1297 IDirect3DTexture9_Release(texture);
1300 for (i = 0; i < sizeof(formats) / sizeof(formats[0]); i++)
1302 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
1303 D3DFMT_X8R8G8B8, 0, D3DRTYPE_SURFACE, formats[i].format) != D3D_OK)
1305 skip("Offscreenplain %s surfaces not supported, skipping colorfill test\n", formats[i].name);
1306 continue;
1309 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
1310 formats[i].format, D3DPOOL_DEFAULT, &surface, NULL);
1311 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x, fmt=%s.\n", hr, formats[i].name);
1313 hr = IDirect3DDevice9_ColorFill(device, surface, NULL, 0xdeadbeef);
1314 if (formats[i].flags & TODO_FILL_RETURN)
1315 todo_wine ok(SUCCEEDED(hr), "Failed to color fill, hr %#x, fmt=%s.\n", hr, formats[i].name);
1316 else
1317 ok(SUCCEEDED(hr), "Failed to color fill, hr %#x, fmt=%s.\n", hr, formats[i].name);
1319 hr = IDirect3DDevice9_ColorFill(device, surface, &rect, 0xdeadbeef);
1320 if (formats[i].flags & TODO_FILL_RETURN)
1321 todo_wine ok(SUCCEEDED(hr), "Failed to color fill, hr %#x, fmt=%s.\n", hr, formats[i].name);
1322 else
1323 ok(SUCCEEDED(hr), "Failed to color fill, hr %#x, fmt=%s.\n", hr, formats[i].name);
1325 if (SUCCEEDED(hr))
1327 hr = IDirect3DDevice9_ColorFill(device, surface, &rect2, 0xdeadbeef);
1328 if (formats[i].flags & BLOCKS)
1329 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x, fmt=%s.\n", hr, formats[i].name);
1330 else
1331 ok(SUCCEEDED(hr), "Failed to color fill, hr %#x, fmt=%s.\n", hr, formats[i].name);
1334 if (formats[i].flags & CHECK_FILL_VALUE)
1336 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, D3DLOCK_READONLY);
1337 ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x, fmt=%s.\n", hr, formats[i].name);
1338 surface_data = locked_rect.pBits;
1339 fill_a = (surface_data[0] & 0xff000000) >> 24;
1340 expected_a = (formats[i].fill_value & 0xff000000) >> 24;
1341 /* Windows drivers disagree on how to promote the 8 bit per channel
1342 * input argument to 16 bit for D3DFMT_G16R16. */
1343 ok(color_match(surface_data[0], formats[i].fill_value, 2) &&
1344 abs((expected_a) - (fill_a)) < 3,
1345 "Expected clear value 0x%08x, got 0x%08x, fmt=%s.\n",
1346 formats[i].fill_value, surface_data[0], formats[i].name);
1347 hr = IDirect3DSurface9_UnlockRect(surface);
1348 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x, fmt=%s.\n", hr, formats[i].name);
1351 IDirect3DSurface9_Release(surface);
1354 refcount = IDirect3DDevice9_Release(device);
1355 ok(!refcount, "Device has %u references left.\n", refcount);
1356 done:
1357 IDirect3D9_Release(d3d);
1358 DestroyWindow(window);
1362 * c7 mova ARGB mov ARGB
1363 * -2.4 -2 0x00ffff00 -3 0x00ff0000
1364 * -1.6 -2 0x00ffff00 -2 0x00ffff00
1365 * -0.4 0 0x0000ffff -1 0x0000ff00
1366 * 0.4 0 0x0000ffff 0 0x0000ffff
1367 * 1.6 2 0x00ff00ff 1 0x000000ff
1368 * 2.4 2 0x00ff00ff 2 0x00ff00ff
1370 static void test_mova(void)
1372 IDirect3DVertexDeclaration9 *vertex_declaration;
1373 IDirect3DVertexShader9 *mova_shader;
1374 IDirect3DVertexShader9 *mov_shader;
1375 IDirect3DDevice9 *device;
1376 unsigned int i, j;
1377 IDirect3D9 *d3d;
1378 ULONG refcount;
1379 D3DCAPS9 caps;
1380 HWND window;
1381 HRESULT hr;
1383 static const DWORD mova_test[] =
1385 0xfffe0200, /* vs_2_0 */
1386 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
1387 0x05000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
1388 0x05000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0 */
1389 0x05000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0 */
1390 0x05000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0 */
1391 0x05000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0 */
1392 0x05000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0 */
1393 0x05000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0 */
1394 0x0200002e, 0xb0010000, 0xa0000007, /* mova a0.x, c7.x */
1395 0x03000001, 0xd00f0000, 0xa0e42003, 0xb0000000, /* mov oD0, c[a0.x + 3] */
1396 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1397 0x0000ffff /* END */
1399 static const DWORD mov_test[] =
1401 0xfffe0101, /* vs_1_1 */
1402 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
1403 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
1404 0x00000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0 */
1405 0x00000051, 0xa00f0002, 0x00000000, 0x3f800000, 0x00000000, 0x3f800000, /* def c2, 0.0, 1.0, 0.0, 1.0 */
1406 0x00000051, 0xa00f0003, 0x00000000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c3, 0.0, 1.0, 1.0, 1.0 */
1407 0x00000051, 0xa00f0004, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c4, 0.0, 0.0, 1.0, 1.0 */
1408 0x00000051, 0xa00f0005, 0x3f800000, 0x00000000, 0x3f800000, 0x3f800000, /* def c5, 1.0, 0.0, 1.0, 1.0 */
1409 0x00000051, 0xa00f0006, 0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000, /* def c6, 1.0, 1.0, 1.0, 1.0 */
1410 0x00000001, 0xb0010000, 0xa0000007, /* mov a0.x, c7.x */
1411 0x00000001, 0xd00f0000, 0xa0e42003, /* mov oD0, c[a0.x + 3] */
1412 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
1413 0x0000ffff /* END */
1415 static const struct
1417 float in[4];
1418 DWORD out;
1420 test_data[2][6] =
1423 {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff0000},
1424 {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
1425 {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ff00},
1426 {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
1427 {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x000000ff},
1428 {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
1431 {{-2.4f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
1432 {{-1.6f, 0.0f, 0.0f, 0.0f}, 0x00ffff00},
1433 {{-0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
1434 {{ 0.4f, 0.0f, 0.0f, 0.0f}, 0x0000ffff},
1435 {{ 1.6f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff},
1436 {{ 2.4f, 0.0f, 0.0f, 0.0f}, 0x00ff00ff}
1439 static const struct vec3 quad[] =
1441 {-1.0f, -1.0f, 0.0f},
1442 {-1.0f, 1.0f, 0.0f},
1443 { 1.0f, -1.0f, 0.0f},
1444 { 1.0f, 1.0f, 0.0f},
1446 static const D3DVERTEXELEMENT9 decl_elements[] =
1448 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
1449 D3DDECL_END()
1452 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
1453 0, 0, 640, 480, NULL, NULL, NULL, NULL);
1454 d3d = Direct3DCreate9(D3D_SDK_VERSION);
1455 ok(!!d3d, "Failed to create a D3D object.\n");
1456 if (!(device = create_device(d3d, window, window, TRUE)))
1458 skip("Failed to create a D3D device, skipping tests.\n");
1459 goto done;
1462 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
1463 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
1464 if (caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
1466 skip("No vs_2_0 support, skipping tests.\n");
1467 IDirect3DDevice9_Release(device);
1468 goto done;
1471 hr = IDirect3DDevice9_CreateVertexShader(device, mova_test, &mova_shader);
1472 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1473 hr = IDirect3DDevice9_CreateVertexShader(device, mov_test, &mov_shader);
1474 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
1475 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
1476 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
1477 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
1478 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
1480 hr = IDirect3DDevice9_SetVertexShader(device, mov_shader);
1481 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1482 for (j = 0; j < sizeof(test_data) / sizeof(*test_data); ++j)
1484 for (i = 0; i < sizeof(*test_data) / sizeof(**test_data); ++i)
1486 DWORD color;
1488 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, test_data[j][i].in, 1);
1489 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
1491 hr = IDirect3DDevice9_BeginScene(device);
1492 ok(SUCCEEDED(hr), "BeginScene failed (%08x)\n", hr);
1494 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
1495 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
1497 hr = IDirect3DDevice9_EndScene(device);
1498 ok(SUCCEEDED(hr), "EndScene failed (%08x)\n", hr);
1500 color = getPixelColor(device, 320, 240);
1501 ok(color == test_data[j][i].out, "Expected color %08x, got %08x (for input %f, instruction %s)\n",
1502 test_data[j][i].out, color, test_data[j][i].in[0], j == 0 ? "mov" : "mova");
1504 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1505 ok(SUCCEEDED(hr), "Present failed (%08x)\n", hr);
1507 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
1508 ok(SUCCEEDED(hr), "Clear failed (%08x)\n", hr);
1510 hr = IDirect3DDevice9_SetVertexShader(device, mova_shader);
1511 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
1514 IDirect3DVertexDeclaration9_Release(vertex_declaration);
1515 IDirect3DVertexShader9_Release(mova_shader);
1516 IDirect3DVertexShader9_Release(mov_shader);
1517 refcount = IDirect3DDevice9_Release(device);
1518 ok(!refcount, "Device has %u references left.\n", refcount);
1519 done:
1520 IDirect3D9_Release(d3d);
1521 DestroyWindow(window);
1524 static void fog_test(void)
1526 float start = 0.0f, end = 1.0f;
1527 IDirect3DDevice9 *device;
1528 IDirect3D9 *d3d;
1529 D3DCOLOR color;
1530 ULONG refcount;
1531 D3DCAPS9 caps;
1532 HWND window;
1533 HRESULT hr;
1534 int i;
1536 /* Gets full z based fog with linear fog, no fog with specular color. */
1537 static const struct
1539 float x, y, z;
1540 D3DCOLOR diffuse;
1541 D3DCOLOR specular;
1543 untransformed_1[] =
1545 {-1.0f, -1.0f, 0.1f, 0xffff0000, 0xff000000},
1546 {-1.0f, 0.0f, 0.1f, 0xffff0000, 0xff000000},
1547 { 0.0f, 0.0f, 0.1f, 0xffff0000, 0xff000000},
1548 { 0.0f, -1.0f, 0.1f, 0xffff0000, 0xff000000},
1550 /* Ok, I am too lazy to deal with transform matrices. */
1551 untransformed_2[] =
1553 {-1.0f, 0.0f, 1.0f, 0xffff0000, 0xff000000},
1554 {-1.0f, 1.0f, 1.0f, 0xffff0000, 0xff000000},
1555 { 0.0f, 1.0f, 1.0f, 0xffff0000, 0xff000000},
1556 { 0.0f, 0.0f, 1.0f, 0xffff0000, 0xff000000},
1558 untransformed_3[] =
1560 {-1.0f, -1.0f, 0.5f, 0xffff0000, 0xff000000},
1561 {-1.0f, 1.0f, 0.5f, 0xffff0000, 0xff000000},
1562 { 1.0f, -1.0f, 0.5f, 0xffff0000, 0xff000000},
1563 { 1.0f, 1.0f, 0.5f, 0xffff0000, 0xff000000},
1565 far_quad1[] =
1567 {-1.0f, -1.0f, 0.5f, 0xffff0000, 0xff000000},
1568 {-1.0f, 0.0f, 0.5f, 0xffff0000, 0xff000000},
1569 { 0.0f, 0.0f, 0.5f, 0xffff0000, 0xff000000},
1570 { 0.0f, -1.0f, 0.5f, 0xffff0000, 0xff000000},
1572 far_quad2[] =
1574 {-1.0f, 0.0f, 1.5f, 0xffff0000, 0xff000000},
1575 {-1.0f, 1.0f, 1.5f, 0xffff0000, 0xff000000},
1576 { 0.0f, 1.0f, 1.5f, 0xffff0000, 0xff000000},
1577 { 0.0f, 0.0f, 1.5f, 0xffff0000, 0xff000000},
1579 /* Untransformed ones. Give them a different diffuse color to make the
1580 * test look nicer. It also makes making sure that they are drawn
1581 * correctly easier. */
1582 static const struct
1584 float x, y, z, rhw;
1585 D3DCOLOR diffuse;
1586 D3DCOLOR specular;
1588 transformed_1[] =
1590 {320.0f, 0.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
1591 {640.0f, 0.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
1592 {640.0f, 240.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
1593 {320.0f, 240.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
1595 transformed_2[] =
1597 {320.0f, 240.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
1598 {640.0f, 240.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
1599 {640.0f, 480.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
1600 {320.0f, 480.0f, 1.0f, 1.0f, 0xffffff00, 0xff000000},
1602 static const struct
1604 struct vec3 position;
1605 DWORD diffuse;
1607 rev_fog_quads[] =
1609 {{-1.0f, -1.0f, 0.1f}, 0x000000ff},
1610 {{-1.0f, 0.0f, 0.1f}, 0x000000ff},
1611 {{ 0.0f, 0.0f, 0.1f}, 0x000000ff},
1612 {{ 0.0f, -1.0f, 0.1f}, 0x000000ff},
1614 {{ 0.0f, -1.0f, 0.9f}, 0x000000ff},
1615 {{ 0.0f, 0.0f, 0.9f}, 0x000000ff},
1616 {{ 1.0f, 0.0f, 0.9f}, 0x000000ff},
1617 {{ 1.0f, -1.0f, 0.9f}, 0x000000ff},
1619 {{ 0.0f, 0.0f, 0.4f}, 0x000000ff},
1620 {{ 0.0f, 1.0f, 0.4f}, 0x000000ff},
1621 {{ 1.0f, 1.0f, 0.4f}, 0x000000ff},
1622 {{ 1.0f, 0.0f, 0.4f}, 0x000000ff},
1624 {{-1.0f, 0.0f, 0.7f}, 0x000000ff},
1625 {{-1.0f, 1.0f, 0.7f}, 0x000000ff},
1626 {{ 0.0f, 1.0f, 0.7f}, 0x000000ff},
1627 {{ 0.0f, 0.0f, 0.7f}, 0x000000ff},
1629 static const D3DMATRIX ident_mat =
1631 1.0f, 0.0f, 0.0f, 0.0f,
1632 0.0f, 1.0f, 0.0f, 0.0f,
1633 0.0f, 0.0f, 1.0f, 0.0f,
1634 0.0f, 0.0f, 0.0f, 1.0f
1635 }}};
1636 static const D3DMATRIX world_mat1 =
1638 1.0f, 0.0f, 0.0f, 0.0f,
1639 0.0f, 1.0f, 0.0f, 0.0f,
1640 0.0f, 0.0f, 1.0f, 0.0f,
1641 0.0f, 0.0f, -0.5f, 1.0f
1642 }}};
1643 static const D3DMATRIX world_mat2 =
1645 1.0f, 0.0f, 0.0f, 0.0f,
1646 0.0f, 1.0f, 0.0f, 0.0f,
1647 0.0f, 0.0f, 1.0f, 0.0f,
1648 0.0f, 0.0f, 1.0f, 1.0f
1649 }}};
1650 static const D3DMATRIX proj_mat =
1652 1.0f, 0.0f, 0.0f, 0.0f,
1653 0.0f, 1.0f, 0.0f, 0.0f,
1654 0.0f, 0.0f, 1.0f, 0.0f,
1655 0.0f, 0.0f, -1.0f, 1.0f
1656 }}};
1657 static const WORD Indices[] = {0, 1, 2, 2, 3, 0};
1658 static const WORD Indices2[] =
1660 0, 1, 2, 2, 3, 0,
1661 4, 5, 6, 6, 7, 4,
1662 8, 9, 10, 10, 11, 8,
1663 12, 13, 14, 14, 15, 12,
1666 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
1667 0, 0, 640, 480, NULL, NULL, NULL, NULL);
1668 d3d = Direct3DCreate9(D3D_SDK_VERSION);
1669 ok(!!d3d, "Failed to create a D3D object.\n");
1670 if (!(device = create_device(d3d, window, window, TRUE)))
1672 skip("Failed to create a D3D device, skipping tests.\n");
1673 goto done;
1676 memset(&caps, 0, sizeof(caps));
1677 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
1678 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
1679 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1680 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1682 /* Setup initial states: No lighting, fog on, fog color */
1683 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
1684 ok(SUCCEEDED(hr), "Failed to disable D3DRS_ZENABLE, hr %#x.\n", hr);
1685 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
1686 ok(hr == D3D_OK, "Turning off lighting returned %08x\n", hr);
1687 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
1688 ok(hr == D3D_OK, "Turning on fog calculations returned %08x\n", hr);
1689 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xff00ff00 /* A nice green */);
1690 ok(hr == D3D_OK, "Setting fog color returned %#08x\n", hr);
1691 /* Some of the tests seem to depend on the projection matrix explicitly
1692 * being set to an identity matrix, even though that's the default.
1693 * (AMD Radeon HD 6310, Windows 7) */
1694 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &ident_mat);
1695 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
1697 /* First test: Both table fog and vertex fog off */
1698 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1699 ok(hr == D3D_OK, "Turning off table fog returned %08x\n", hr);
1700 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
1701 ok(hr == D3D_OK, "Turning off vertex fog returned %08x\n", hr);
1703 /* Start = 0, end = 1. Should be default, but set them */
1704 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1705 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1706 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1707 ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1709 hr = IDirect3DDevice9_BeginScene(device);
1710 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
1712 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1713 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
1715 /* Untransformed, vertex fog = NONE, table fog = NONE:
1716 * Read the fog weighting from the specular color. */
1717 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1718 2 /* PrimCount */, Indices, D3DFMT_INDEX16, untransformed_1, sizeof(untransformed_1[0]));
1719 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1721 /* That makes it use the Z value */
1722 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1723 ok(SUCCEEDED(hr), "Failed to set D3DFOG_LINEAR fog vertex mode, hr %#x.\n", hr);
1724 /* Untransformed, vertex fog != none (or table fog != none):
1725 * Use the Z value as input into the equation. */
1726 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1727 2 /* PrimCount */, Indices, D3DFMT_INDEX16, untransformed_2, sizeof(untransformed_2[0]));
1728 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1730 /* transformed verts */
1731 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1732 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
1733 /* Transformed, vertex fog != NONE, pixel fog == NONE:
1734 * Use specular color alpha component. */
1735 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1736 2 /* PrimCount */, Indices, D3DFMT_INDEX16, transformed_1, sizeof(transformed_1[0]));
1737 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1739 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
1740 ok(SUCCEEDED(hr), "Failed to set D3DFOG_LINEAR fog table mode, hr %#x.\n", hr);
1741 /* Transformed, table fog != none, vertex anything:
1742 * Use Z value as input to the fog equation. */
1743 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1744 2 /* PrimCount */, Indices, D3DFMT_INDEX16, transformed_2, sizeof(transformed_2[0]));
1745 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1747 hr = IDirect3DDevice9_EndScene(device);
1748 ok(hr == D3D_OK, "EndScene returned %08x\n", hr);
1750 color = getPixelColor(device, 160, 360);
1751 ok(color == 0x00ff0000, "Untransformed vertex with no table or vertex fog has color %08x\n", color);
1752 color = getPixelColor(device, 160, 120);
1753 ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with linear vertex fog has color %08x\n", color);
1754 color = getPixelColor(device, 480, 120);
1755 ok(color == 0x00ffff00, "Transformed vertex with linear vertex fog has color %08x\n", color);
1756 if(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)
1758 color = getPixelColor(device, 480, 360);
1759 ok(color_match(color, 0x0000ff00, 1), "Transformed vertex with linear table fog has color %08x\n", color);
1761 else
1763 /* Without fog table support the vertex fog is still applied, even though table fog is turned on.
1764 * The settings above result in no fogging with vertex fog
1766 color = getPixelColor(device, 480, 120);
1767 ok(color == 0x00ffff00, "Transformed vertex with linear vertex fog has color %08x\n", color);
1768 trace("Info: Table fog not supported by this device\n");
1770 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1772 /* Now test the special case fogstart == fogend */
1773 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
1774 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1776 hr = IDirect3DDevice9_BeginScene(device);
1777 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
1779 start = 512;
1780 end = 512;
1781 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *)&start));
1782 ok(SUCCEEDED(hr), "Failed to set fog start, hr %#x.\n", hr);
1783 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *)&end));
1784 ok(SUCCEEDED(hr), "Failed to set fog end, hr %#x.\n", hr);
1786 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1787 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
1788 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
1789 ok(SUCCEEDED(hr), "Failed to set D3DFOG_LINEAR fog vertex mode, hr %#x.\n", hr);
1790 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
1791 ok(SUCCEEDED(hr), "Failed to set D3DFOG_NONE fog table mode, hr %#x.\n", hr);
1793 /* Untransformed vertex, z coord = 0.1, fogstart = 512, fogend = 512.
1794 * Would result in a completely fog-free primitive because start > zcoord,
1795 * but because start == end, the primitive is fully covered by fog. The
1796 * same happens to the 2nd untransformed quad with z = 1.0. The third
1797 * transformed quad remains unfogged because the fogcoords are read from
1798 * the specular color and has fixed fogstart and fogend. */
1799 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1800 2 /* PrimCount */, Indices, D3DFMT_INDEX16, untransformed_1, sizeof(untransformed_1[0]));
1801 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1802 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1803 2 /* PrimCount */, Indices, D3DFMT_INDEX16, untransformed_2, sizeof(untransformed_2[0]));
1804 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1806 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1807 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
1808 /* Transformed, vertex fog != NONE, pixel fog == NONE:
1809 * Use specular color alpha component. */
1810 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
1811 2 /* PrimCount */, Indices, D3DFMT_INDEX16, transformed_1, sizeof(transformed_1[0]));
1812 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1814 hr = IDirect3DDevice9_EndScene(device);
1815 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
1817 color = getPixelColor(device, 160, 360);
1818 ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with vertex fog and z = 0.1 has color %08x\n", color);
1819 color = getPixelColor(device, 160, 120);
1820 ok(color_match(color, 0x0000ff00, 1), "Untransformed vertex with vertex fog and z = 1.0 has color %08x\n", color);
1821 color = getPixelColor(device, 480, 120);
1822 ok(color == 0x00ffff00, "Transformed vertex with linear vertex fog has color %08x\n", color);
1823 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1825 /* Test "reversed" fog without shaders. With shaders this fails on a few Windows D3D implementations,
1826 * but without shaders it seems to work everywhere
1828 end = 0.2;
1829 start = 0.8;
1830 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1831 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1832 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1833 ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1834 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
1835 ok( hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
1837 /* Test reversed fog without shaders. ATI cards have problems with reversed fog and shaders, so
1838 * it doesn't seem very important for games. ATI cards also have problems with reversed table fog,
1839 * so skip this for now
1841 for(i = 0; i < 1 /*2 - Table fog test disabled, fails on ATI */; i++) {
1842 const char *mode = (i ? "table" : "vertex");
1843 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
1844 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
1845 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, i == 0 ? D3DFOG_LINEAR : D3DFOG_NONE);
1846 ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1847 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, i == 0 ? D3DFOG_NONE : D3DFOG_LINEAR);
1848 ok( hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
1849 hr = IDirect3DDevice9_BeginScene(device);
1850 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
1851 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 16 /* NumVerts */,
1852 8 /* PrimCount */, Indices2, D3DFMT_INDEX16, rev_fog_quads, sizeof(rev_fog_quads[0]));
1853 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1854 hr = IDirect3DDevice9_EndScene(device);
1855 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
1857 color = getPixelColor(device, 160, 360);
1858 ok(color_match(color, 0x0000ff00, 1),
1859 "Reversed %s fog: z=0.1 has color 0x%08x, expected 0x0000ff00 or 0x0000fe00\n", mode, color);
1861 color = getPixelColor(device, 160, 120);
1862 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x2b, 0xd4), 2),
1863 "Reversed %s fog: z=0.7 has color 0x%08x\n", mode, color);
1865 color = getPixelColor(device, 480, 120);
1866 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xaa, 0x55), 2),
1867 "Reversed %s fog: z=0.4 has color 0x%08x\n", mode, color);
1869 color = getPixelColor(device, 480, 360);
1870 ok(color == 0x000000ff, "Reversed %s fog: z=0.9 has color 0x%08x, expected 0x000000ff\n", mode, color);
1872 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1874 if(!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)) {
1875 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping reversed table fog test\n");
1876 break;
1880 if (caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)
1882 /* A simple fog + non-identity world matrix test */
1883 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), &world_mat1);
1884 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %#08x\n", hr);
1886 start = 0.0;
1887 end = 1.0;
1888 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *)&start));
1889 ok(hr == D3D_OK, "Setting fog start returned %08x\n", hr);
1890 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *)&end));
1891 ok(hr == D3D_OK, "Setting fog end returned %08x\n", hr);
1892 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
1893 ok(hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR returned %#08x\n", hr);
1894 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
1895 ok(hr == D3D_OK, "Turning off vertex fog returned %#08x\n", hr);
1897 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1898 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %#08x\n", hr);
1900 hr = IDirect3DDevice9_BeginScene(device);
1901 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
1903 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1904 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
1906 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
1907 2, Indices, D3DFMT_INDEX16, far_quad1, sizeof(far_quad1[0]));
1908 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1909 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
1910 2, Indices, D3DFMT_INDEX16, far_quad2, sizeof(far_quad2[0]));
1911 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1913 hr = IDirect3DDevice9_EndScene(device);
1914 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
1916 color = getPixelColor(device, 160, 360);
1917 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00), 4),
1918 "Unfogged quad has color %08x\n", color);
1919 color = getPixelColor(device, 160, 120);
1920 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
1921 "Fogged out quad has color %08x\n", color);
1923 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1925 /* Test fog behavior with an orthogonal (but non-identity) projection matrix */
1926 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), &world_mat2);
1927 ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
1928 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &proj_mat);
1929 ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
1931 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1932 ok(hr == D3D_OK, "Clear returned %#08x\n", hr);
1934 hr = IDirect3DDevice9_BeginScene(device);
1935 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
1937 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1938 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
1940 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
1941 2, Indices, D3DFMT_INDEX16, untransformed_1, sizeof(untransformed_1[0]));
1942 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1943 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0, 4,
1944 2, Indices, D3DFMT_INDEX16, untransformed_2, sizeof(untransformed_2[0]));
1945 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
1947 hr = IDirect3DDevice9_EndScene(device);
1948 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
1950 color = getPixelColor(device, 160, 360);
1951 ok(color_match(color, 0x00e51900, 4), "Partially fogged quad has color %08x\n", color);
1952 color = getPixelColor(device, 160, 120);
1953 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
1954 "Fogged out quad has color %08x\n", color);
1956 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
1958 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), &ident_mat);
1959 ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
1960 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &ident_mat);
1961 ok(hr == D3D_OK, "SetTransform returned %#08x\n", hr);
1963 else
1965 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping some fog tests\n");
1968 /* Test RANGEFOG vs FOGTABLEMODE */
1969 if ((caps.RasterCaps & (D3DPRASTERCAPS_FOGTABLE | D3DPRASTERCAPS_FOGRANGE)) ==
1970 (D3DPRASTERCAPS_FOGTABLE | D3DPRASTERCAPS_FOGRANGE))
1972 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
1973 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed, hr %#x.\n", hr);
1974 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
1975 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed, hr %#x.\n", hr);
1977 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_RANGEFOGENABLE, TRUE);
1978 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
1980 /* z=0.5, x = +/- 1.0, y = +/- 1.0. In case of z fog the fog coordinate is
1981 * 0.5. With range fog it is sqrt(x*x + y*y + z*z) = 1.5 for all vertices.
1982 * Note that the fog coordinate is interpolated linearly across the vertices,
1983 * so the different eye distance at the screen center should not matter. */
1984 start = 0.75f;
1985 end = 0.75001f;
1986 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, *((DWORD *) &start));
1987 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
1988 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, *((DWORD *) &end));
1989 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
1991 /* Table fog: Range fog is not used */
1992 hr = IDirect3DDevice9_BeginScene(device);
1993 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
1995 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
1996 ok(SUCCEEDED(hr), "Failed to set D3DFOG_LINEAR fog table mode, hr %#x.\n", hr);
1997 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,
1998 untransformed_3, sizeof(*untransformed_3));
1999 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2001 hr = IDirect3DDevice9_EndScene(device);
2002 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
2004 color = getPixelColor(device, 10, 10);
2005 ok(color == 0x00ff0000, "Rangefog with table fog returned color 0x%08x\n", color);
2006 color = getPixelColor(device, 630, 10);
2007 ok(color == 0x00ff0000, "Rangefog with table fog returned color 0x%08x\n", color);
2008 color = getPixelColor(device, 10, 470);
2009 ok(color == 0x00ff0000, "Rangefog with table fog returned color 0x%08x\n", color);
2010 color = getPixelColor(device, 630, 470);
2011 ok(color == 0x00ff0000, "Rangefog with table fog returned color 0x%08x\n", color);
2013 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2014 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed, hr %#x.\n", hr);
2016 /* Vertex fog: Rangefog is used */
2017 hr = IDirect3DDevice9_BeginScene(device);
2018 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
2020 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
2021 ok(SUCCEEDED(hr), "Failed to set D3DFOG_NONE fog table mode, hr %#x.\n", hr);
2022 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_LINEAR);
2023 ok(SUCCEEDED(hr), "Failed to set D3DFOG_LINEAR fog vertex mode, hr %#x.\n", hr);
2024 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,
2025 untransformed_3, sizeof(*untransformed_3));
2026 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2028 hr = IDirect3DDevice9_EndScene(device);
2029 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
2031 color = getPixelColor(device, 10, 10);
2032 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
2033 "Rangefog with vertex fog returned color 0x%08x\n", color);
2034 color = getPixelColor(device, 630, 10);
2035 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
2036 "Rangefog with vertex fog returned color 0x%08x\n", color);
2037 color = getPixelColor(device, 10, 470);
2038 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
2039 "Rangefog with vertex fog returned color 0x%08x\n", color);
2040 color = getPixelColor(device, 630, 470);
2041 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1),
2042 "Rangefog with vertex fog returned color 0x%08x\n", color);
2044 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2045 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed, hr %#x.\n", hr);
2047 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_RANGEFOGENABLE, FALSE);
2048 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
2050 else
2052 skip("Range fog or table fog not supported, skipping range fog tests\n");
2055 refcount = IDirect3DDevice9_Release(device);
2056 ok(!refcount, "Device has %u references left.\n", refcount);
2057 done:
2058 IDirect3D9_Release(d3d);
2059 DestroyWindow(window);
2062 /* This test verifies the behaviour of cube maps wrt. texture wrapping.
2063 * D3D cube map wrapping always behaves like GL_CLAMP_TO_EDGE,
2064 * regardless of the actual addressing mode set. The way this test works is
2065 * that we sample in one of the corners of the cubemap with filtering enabled,
2066 * and check the interpolated color. There are essentially two reasonable
2067 * things an implementation can do: Either pick one of the faces and
2068 * interpolate the edge texel with itself (i.e., clamp within the face), or
2069 * interpolate between the edge texels of the three involved faces. It should
2070 * never involve the border color or the other side (texcoord wrapping) of a
2071 * face in the interpolation. */
2072 static void test_cube_wrap(void)
2074 IDirect3DVertexDeclaration9 *vertex_declaration;
2075 IDirect3DSurface9 *face_surface, *surface;
2076 IDirect3DCubeTexture9 *texture;
2077 D3DLOCKED_RECT locked_rect;
2078 IDirect3DDevice9 *device;
2079 unsigned int x, y, face;
2080 IDirect3D9 *d3d;
2081 ULONG refcount;
2082 D3DCAPS9 caps;
2083 HWND window;
2084 HRESULT hr;
2086 static const float quad[][6] =
2088 {-1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
2089 {-1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
2090 { 1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
2091 { 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f},
2093 static const D3DVERTEXELEMENT9 decl_elements[] =
2095 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2096 {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
2097 D3DDECL_END()
2099 static const struct
2101 D3DTEXTUREADDRESS mode;
2102 const char *name;
2104 address_modes[] =
2106 {D3DTADDRESS_WRAP, "D3DTADDRESS_WRAP"},
2107 {D3DTADDRESS_MIRROR, "D3DTADDRESS_MIRROR"},
2108 {D3DTADDRESS_CLAMP, "D3DTADDRESS_CLAMP"},
2109 {D3DTADDRESS_BORDER, "D3DTADDRESS_BORDER"},
2110 {D3DTADDRESS_MIRRORONCE, "D3DTADDRESS_MIRRORONCE"},
2113 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
2114 0, 0, 640, 480, NULL, NULL, NULL, NULL);
2115 d3d = Direct3DCreate9(D3D_SDK_VERSION);
2116 ok(!!d3d, "Failed to create a D3D object.\n");
2117 if (!(device = create_device(d3d, window, window, TRUE)))
2119 skip("Failed to create a D3D device, skipping tests.\n");
2120 goto done;
2123 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
2124 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
2125 if (!(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP))
2127 skip("No cube texture support, skipping tests.\n");
2128 IDirect3DDevice9_Release(device);
2129 goto done;
2132 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
2133 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
2134 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
2135 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
2137 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 128, 128,
2138 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surface, NULL);
2139 ok(SUCCEEDED(hr), "CreateOffscreenPlainSurface failed (0x%08x)\n", hr);
2141 hr = IDirect3DDevice9_CreateCubeTexture(device, 128, 1, 0, D3DFMT_A8R8G8B8,
2142 D3DPOOL_DEFAULT, &texture, NULL);
2143 ok(SUCCEEDED(hr), "CreateCubeTexture failed (0x%08x)\n", hr);
2145 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
2146 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2148 for (y = 0; y < 128; ++y)
2150 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
2151 for (x = 0; x < 64; ++x)
2153 *ptr++ = 0xff0000ff;
2155 for (x = 64; x < 128; ++x)
2157 *ptr++ = 0xffff0000;
2161 hr = IDirect3DSurface9_UnlockRect(surface);
2162 ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
2164 hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, 0, 0, &face_surface);
2165 ok(SUCCEEDED(hr), "GetCubeMapSurface failed (0x%08x)\n", hr);
2167 hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
2168 ok(SUCCEEDED(hr), "UpdateSurface failed (0x%08x)\n", hr);
2170 IDirect3DSurface9_Release(face_surface);
2172 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
2173 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2175 for (y = 0; y < 128; ++y)
2177 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
2178 for (x = 0; x < 64; ++x)
2180 *ptr++ = 0xffff0000;
2182 for (x = 64; x < 128; ++x)
2184 *ptr++ = 0xff0000ff;
2188 hr = IDirect3DSurface9_UnlockRect(surface);
2189 ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
2191 /* Create cube faces */
2192 for (face = 1; face < 6; ++face)
2194 hr= IDirect3DCubeTexture9_GetCubeMapSurface(texture, face, 0, &face_surface);
2195 ok(SUCCEEDED(hr), "GetCubeMapSurface failed (0x%08x)\n", hr);
2197 hr = IDirect3DDevice9_UpdateSurface(device, surface, NULL, face_surface, NULL);
2198 ok(SUCCEEDED(hr), "UpdateSurface failed (0x%08x)\n", hr);
2200 IDirect3DSurface9_Release(face_surface);
2203 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
2204 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
2206 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
2207 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
2208 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
2209 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
2210 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_BORDERCOLOR, 0xff00ff00);
2211 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_BORDERCOLOR failed (0x%08x)\n", hr);
2213 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
2214 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2216 for (x = 0; x < (sizeof(address_modes) / sizeof(*address_modes)); ++x)
2218 DWORD color;
2220 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, address_modes[x].mode);
2221 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU (%s) failed (0x%08x)\n", address_modes[x].name, hr);
2222 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, address_modes[x].mode);
2223 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV (%s) failed (0x%08x)\n", address_modes[x].name, hr);
2225 hr = IDirect3DDevice9_BeginScene(device);
2226 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
2228 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
2229 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
2231 hr = IDirect3DDevice9_EndScene(device);
2232 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
2234 color = getPixelColor(device, 320, 240);
2235 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
2236 "Got color 0x%08x for addressing mode %s, expected 0x000000ff.\n",
2237 color, address_modes[x].name);
2239 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2240 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
2242 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
2243 ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
2246 IDirect3DVertexDeclaration9_Release(vertex_declaration);
2247 IDirect3DCubeTexture9_Release(texture);
2248 IDirect3DSurface9_Release(surface);
2249 refcount = IDirect3DDevice9_Release(device);
2250 ok(!refcount, "Device has %u references left.\n", refcount);
2251 done:
2252 IDirect3D9_Release(d3d);
2253 DestroyWindow(window);
2256 static void offscreen_test(void)
2258 IDirect3DSurface9 *backbuffer, *offscreen;
2259 IDirect3DTexture9 *offscreenTexture;
2260 IDirect3DDevice9 *device;
2261 IDirect3D9 *d3d;
2262 D3DCOLOR color;
2263 ULONG refcount;
2264 HWND window;
2265 HRESULT hr;
2267 static const float quad[][5] =
2269 {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
2270 {-0.5f, 0.5f, 0.1f, 0.0f, 1.0f},
2271 { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
2272 { 0.5f, 0.5f, 0.1f, 1.0f, 1.0f},
2275 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
2276 0, 0, 640, 480, NULL, NULL, NULL, NULL);
2277 d3d = Direct3DCreate9(D3D_SDK_VERSION);
2278 ok(!!d3d, "Failed to create a D3D object.\n");
2279 if (!(device = create_device(d3d, window, window, TRUE)))
2281 skip("Failed to create a D3D device, skipping tests.\n");
2282 goto done;
2285 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 1.0f, 0);
2286 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
2288 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET,
2289 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
2290 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
2291 if (!offscreenTexture)
2293 trace("Failed to create an X8R8G8B8 offscreen texture, trying R5G6B5.\n");
2294 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET,
2295 D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
2296 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
2297 if (!offscreenTexture)
2299 skip("Cannot create an offscreen render target.\n");
2300 IDirect3DDevice9_Release(device);
2301 goto done;
2305 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
2306 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
2308 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
2309 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
2311 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
2312 ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
2314 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
2315 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
2316 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
2317 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
2318 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
2319 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
2320 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
2321 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
2322 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
2323 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
2325 hr = IDirect3DDevice9_BeginScene(device);
2326 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
2328 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
2329 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
2330 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 1.0f, 0);
2331 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
2333 /* Draw without textures - Should result in a white quad. */
2334 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
2335 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2337 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
2338 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
2339 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)offscreenTexture);
2340 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
2342 /* This time with the texture. */
2343 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
2344 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
2346 hr = IDirect3DDevice9_EndScene(device);
2347 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
2349 /* Center quad - should be white */
2350 color = getPixelColor(device, 320, 240);
2351 ok(color == 0x00ffffff, "Offscreen failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
2352 /* Some quad in the cleared part of the texture */
2353 color = getPixelColor(device, 170, 240);
2354 ok(color == 0x00ff00ff, "Offscreen failed: Got color 0x%08x, expected 0x00ff00ff.\n", color);
2355 /* Part of the originally cleared back buffer */
2356 color = getPixelColor(device, 10, 10);
2357 ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2358 color = getPixelColor(device, 10, 470);
2359 ok(color == 0x00ff0000, "Offscreen failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
2361 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2363 IDirect3DSurface9_Release(backbuffer);
2364 IDirect3DTexture9_Release(offscreenTexture);
2365 IDirect3DSurface9_Release(offscreen);
2366 refcount = IDirect3DDevice9_Release(device);
2367 ok(!refcount, "Device has %u references left.\n", refcount);
2368 done:
2369 IDirect3D9_Release(d3d);
2370 DestroyWindow(window);
2373 /* This test tests fog in combination with shaders.
2374 * What's tested: linear fog (vertex and table) with pixel shader
2375 * linear table fog with non foggy vertex shader
2376 * vertex fog with foggy vertex shader, non-linear
2377 * fog with shader, non-linear fog with foggy shader,
2378 * linear table fog with foggy shader */
2379 static void fog_with_shader_test(void)
2381 IDirect3DVertexShader9 *vertex_shader[4] = {NULL, NULL, NULL, NULL};
2382 IDirect3DPixelShader9 *pixel_shader[3] = {NULL, NULL, NULL};
2383 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
2384 IDirect3DDevice9 *device;
2385 unsigned int i, j;
2386 IDirect3D9 *d3d;
2387 ULONG refcount;
2388 D3DCAPS9 caps;
2389 DWORD color;
2390 HWND window;
2391 HRESULT hr;
2392 union
2394 float f;
2395 DWORD i;
2396 } start, end;
2398 /* basic vertex shader without fog computation ("non foggy") */
2399 static const DWORD vertex_shader_code1[] =
2401 0xfffe0101, /* vs_1_1 */
2402 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
2403 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
2404 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
2405 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
2406 0x0000ffff
2408 /* basic vertex shader with reversed fog computation ("foggy") */
2409 static const DWORD vertex_shader_code2[] =
2411 0xfffe0101, /* vs_1_1 */
2412 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
2413 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
2414 0x00000051, 0xa00f0000, 0xbfa00000, 0x00000000, 0xbf666666, 0x00000000, /* def c0, -1.25, 0.0, -0.9, 0.0 */
2415 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
2416 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
2417 0x00000002, 0x800f0000, 0x90aa0000, 0xa0aa0000, /* add r0, v0.z, c0.z */
2418 0x00000005, 0xc00f0001, 0x80000000, 0xa0000000, /* mul oFog, r0.x, c0.x */
2419 0x0000ffff
2421 /* basic vertex shader with reversed fog computation ("foggy"), vs_2_0 */
2422 static const DWORD vertex_shader_code3[] =
2424 0xfffe0200, /* vs_2_0 */
2425 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
2426 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
2427 0x05000051, 0xa00f0000, 0xbfa00000, 0x00000000, 0xbf666666, 0x00000000, /* def c0, -1.25, 0.0, -0.9, 0.0 */
2428 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
2429 0x02000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
2430 0x03000002, 0x800f0000, 0x90aa0000, 0xa0aa0000, /* add r0, v0.z, c0.z */
2431 0x03000005, 0xc00f0001, 0x80000000, 0xa0000000, /* mul oFog, r0.x, c0.x */
2432 0x0000ffff
2434 /* basic pixel shader */
2435 static const DWORD pixel_shader_code[] =
2437 0xffff0101, /* ps_1_1 */
2438 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
2439 0x0000ffff
2441 static const DWORD pixel_shader_code2[] =
2443 0xffff0200, /* ps_2_0 */
2444 0x0200001f, 0x80000000, 0x900f0000, /* dcl v0 */
2445 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
2446 0x0000ffff
2448 struct
2450 struct vec3 position;
2451 DWORD diffuse;
2453 quad[] =
2455 {{-1.0f, -1.0f, 0.0f}, 0xffff0000},
2456 {{-1.0f, 1.0f, 0.0f}, 0xffff0000},
2457 {{ 1.0f, -1.0f, 0.0f}, 0xffff0000},
2458 {{ 1.0f, 1.0f, 0.0f}, 0xffff0000},
2460 static const D3DVERTEXELEMENT9 decl_elements[] =
2462 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2463 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
2464 D3DDECL_END()
2466 /* This reference data was collected on a nVidia GeForce 7600GS driver
2467 * version 84.19 DirectX version 9.0c on Windows XP. */
2468 static const struct test_data_t
2470 int vshader;
2471 int pshader;
2472 D3DFOGMODE vfog;
2473 D3DFOGMODE tfog;
2474 unsigned int color[11];
2476 test_data[] =
2478 /* only pixel shader: */
2479 {0, 1, D3DFOG_NONE, D3DFOG_LINEAR,
2480 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2481 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2482 {0, 1, D3DFOG_EXP, D3DFOG_LINEAR,
2483 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2484 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2485 {0, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
2486 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2487 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2488 {0, 1, D3DFOG_LINEAR, D3DFOG_NONE,
2489 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2490 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2491 {0, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
2492 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2493 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2495 /* vertex shader */
2496 {1, 0, D3DFOG_NONE, D3DFOG_NONE,
2497 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
2498 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
2499 {1, 0, D3DFOG_NONE, D3DFOG_LINEAR,
2500 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2501 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2502 {1, 0, D3DFOG_EXP, D3DFOG_LINEAR,
2503 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2504 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2506 {1, 0, D3DFOG_EXP2, D3DFOG_LINEAR,
2507 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2508 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2509 {1, 0, D3DFOG_LINEAR, D3DFOG_LINEAR,
2510 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2511 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2513 /* vertex shader and pixel shader */
2514 /* The next 4 tests would read the fog coord output, but it isn't available.
2515 * The result is a fully fogged quad, no matter what the Z coord is. This is on
2516 * a geforce 7400, 97.52 driver, Windows Vista, but probably hardware dependent.
2517 * These tests should be disabled if some other hardware behaves differently
2519 {1, 1, D3DFOG_NONE, D3DFOG_NONE,
2520 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
2521 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
2522 {1, 1, D3DFOG_LINEAR, D3DFOG_NONE,
2523 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
2524 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
2525 {1, 1, D3DFOG_EXP, D3DFOG_NONE,
2526 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
2527 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
2528 {1, 1, D3DFOG_EXP2, D3DFOG_NONE,
2529 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00,
2530 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00, 0x0000ff00}},
2532 /* These use the Z coordinate with linear table fog */
2533 {1, 1, D3DFOG_NONE, D3DFOG_LINEAR,
2534 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2535 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2536 {1, 1, D3DFOG_EXP, D3DFOG_LINEAR,
2537 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2538 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2539 {1, 1, D3DFOG_EXP2, D3DFOG_LINEAR,
2540 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2541 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2542 {1, 1, D3DFOG_LINEAR, D3DFOG_LINEAR,
2543 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2544 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2546 /* Non-linear table fog without fog coord */
2547 {1, 1, D3DFOG_NONE, D3DFOG_EXP,
2548 {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
2549 0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
2550 {1, 1, D3DFOG_NONE, D3DFOG_EXP2,
2551 {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
2552 0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
2554 /* These tests fail on older Nvidia drivers */
2555 /* foggy vertex shader */
2556 {2, 0, D3DFOG_NONE, D3DFOG_NONE,
2557 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2558 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2559 {2, 0, D3DFOG_EXP, D3DFOG_NONE,
2560 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2561 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2562 {2, 0, D3DFOG_EXP2, D3DFOG_NONE,
2563 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2564 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2565 {2, 0, D3DFOG_LINEAR, D3DFOG_NONE,
2566 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2567 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2569 {3, 0, D3DFOG_NONE, D3DFOG_NONE,
2570 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2571 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2572 {3, 0, D3DFOG_EXP, D3DFOG_NONE,
2573 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2574 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2575 {3, 0, D3DFOG_EXP2, D3DFOG_NONE,
2576 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2577 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2578 {3, 0, D3DFOG_LINEAR, D3DFOG_NONE,
2579 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2580 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2582 /* foggy vertex shader and pixel shader. First 4 tests with vertex fog,
2583 * all using the fixed fog-coord linear fog
2585 /* vs_1_1 with ps_1_1 */
2586 {2, 1, D3DFOG_NONE, D3DFOG_NONE,
2587 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2588 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2589 {2, 1, D3DFOG_EXP, D3DFOG_NONE,
2590 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2591 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2592 {2, 1, D3DFOG_EXP2, D3DFOG_NONE,
2593 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2594 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2595 {2, 1, D3DFOG_LINEAR, D3DFOG_NONE,
2596 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2597 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2599 /* vs_2_0 with ps_1_1 */
2600 {3, 1, D3DFOG_NONE, D3DFOG_NONE,
2601 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2602 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2603 {3, 1, D3DFOG_EXP, D3DFOG_NONE,
2604 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2605 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2606 {3, 1, D3DFOG_EXP2, D3DFOG_NONE,
2607 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2608 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2609 {3, 1, D3DFOG_LINEAR, D3DFOG_NONE,
2610 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2611 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2613 /* vs_1_1 with ps_2_0 */
2614 {2, 2, D3DFOG_NONE, D3DFOG_NONE,
2615 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2616 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2617 {2, 2, D3DFOG_EXP, D3DFOG_NONE,
2618 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2619 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2620 {2, 2, D3DFOG_EXP2, D3DFOG_NONE,
2621 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2622 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2623 {2, 2, D3DFOG_LINEAR, D3DFOG_NONE,
2624 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2625 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2627 /* vs_2_0 with ps_2_0 */
2628 {3, 2, D3DFOG_NONE, D3DFOG_NONE,
2629 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2630 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2631 {3, 2, D3DFOG_EXP, D3DFOG_NONE,
2632 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2633 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2634 {3, 2, D3DFOG_EXP2, D3DFOG_NONE,
2635 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2636 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2637 {3, 2, D3DFOG_LINEAR, D3DFOG_NONE,
2638 {0x00ff0000, 0x00fe0100, 0x00de2100, 0x00bf4000, 0x009f6000, 0x007f8000,
2639 0x005fa000, 0x003fc000, 0x001fe000, 0x0000ff00, 0x0000ff00}},
2641 /* These use table fog. Here the shader-provided fog coordinate is
2642 * ignored and the z coordinate used instead
2644 {2, 1, D3DFOG_NONE, D3DFOG_EXP,
2645 {0x00ff0000, 0x00e71800, 0x00d12e00, 0x00bd4200, 0x00ab5400, 0x009b6400,
2646 0x008d7200, 0x007f8000, 0x00738c00, 0x00689700, 0x005ea100}},
2647 {2, 1, D3DFOG_NONE, D3DFOG_EXP2,
2648 {0x00fd0200, 0x00f50200, 0x00f50a00, 0x00e91600, 0x00d92600, 0x00c73800,
2649 0x00b24d00, 0x009c6300, 0x00867900, 0x00728d00, 0x005ea100}},
2650 {2, 1, D3DFOG_NONE, D3DFOG_LINEAR,
2651 {0x00ff0000, 0x00ff0000, 0x00df2000, 0x00bf4000, 0x009f6000, 0x007f8000,
2652 0x005fa000, 0x0040bf00, 0x0020df00, 0x0000ff00, 0x0000ff00}},
2654 static const D3DMATRIX identity =
2656 1.0f, 0.0f, 0.0f, 0.0f,
2657 0.0f, 1.0f, 0.0f, 0.0f,
2658 0.0f, 0.0f, 1.0f, 0.0f,
2659 0.0f, 0.0f, 0.0f, 1.0f,
2660 }}};
2662 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
2663 0, 0, 640, 480, NULL, NULL, NULL, NULL);
2664 d3d = Direct3DCreate9(D3D_SDK_VERSION);
2665 ok(!!d3d, "Failed to create a D3D object.\n");
2666 if (!(device = create_device(d3d, window, window, TRUE)))
2668 skip("Failed to create a D3D device, skipping tests.\n");
2669 goto done;
2672 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
2673 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
2674 if (caps.VertexShaderVersion < D3DVS_VERSION(2, 0) || caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
2676 skip("No shader model 2 support, skipping tests.\n");
2677 IDirect3DDevice9_Release(device);
2678 goto done;
2681 /* NOTE: Changing these values will not affect the tests with foggy vertex
2682 * shader, as the values are hardcoded in the shader. */
2683 start.f = 0.1f;
2684 end.f = 0.9f;
2686 /* Some of the tests seem to depend on the projection matrix explicitly
2687 * being set to an identity matrix, even though that's the default.
2688 * (AMD Radeon HD 6310, Windows 7) */
2689 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &identity);
2690 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
2692 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code1, &vertex_shader[1]);
2693 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
2694 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code2, &vertex_shader[2]);
2695 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
2696 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code3, &vertex_shader[3]);
2697 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
2698 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader[1]);
2699 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
2700 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code2, &pixel_shader[2]);
2701 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
2702 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
2703 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
2705 /* Setup initial states: No lighting, fog on, fog color */
2706 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
2707 ok(hr == D3D_OK, "Turning off lighting failed (%08x)\n", hr);
2708 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
2709 ok(hr == D3D_OK, "Turning on fog calculations failed (%08x)\n", hr);
2710 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xff00ff00 /* A nice green */);
2711 ok(hr == D3D_OK, "Setting fog color failed (%08x)\n", hr);
2712 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
2713 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
2715 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_NONE);
2716 ok(hr == D3D_OK, "Turning off table fog failed (%08x)\n", hr);
2717 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
2718 ok(hr == D3D_OK, "Turning off vertex fog failed (%08x)\n", hr);
2720 /* Use fogtart = 0.1 and end = 0.9 to test behavior outside the fog transition phase, too*/
2721 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, start.i);
2722 ok(hr == D3D_OK, "Setting fog start failed (%08x)\n", hr);
2723 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, end.i);
2724 ok(hr == D3D_OK, "Setting fog end failed (%08x)\n", hr);
2726 for (i = 0; i < sizeof(test_data)/sizeof(test_data[0]); i++)
2728 hr = IDirect3DDevice9_SetVertexShader(device, vertex_shader[test_data[i].vshader]);
2729 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
2730 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader[test_data[i].pshader]);
2731 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
2732 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, test_data[i].vfog);
2733 ok( hr == D3D_OK, "Setting fog vertex mode to D3DFOG_LINEAR failed (%08x)\n", hr);
2734 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, test_data[i].tfog);
2735 ok( hr == D3D_OK, "Setting fog table mode to D3DFOG_LINEAR failed (%08x)\n", hr);
2737 for(j=0; j < 11; j++)
2739 /* Don't use the whole zrange to prevent rounding errors */
2740 quad[0].position.z = 0.001f + (float)j / 10.02f;
2741 quad[1].position.z = 0.001f + (float)j / 10.02f;
2742 quad[2].position.z = 0.001f + (float)j / 10.02f;
2743 quad[3].position.z = 0.001f + (float)j / 10.02f;
2745 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff00ff, 1.0f, 0);
2746 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
2748 hr = IDirect3DDevice9_BeginScene(device);
2749 ok( hr == D3D_OK, "BeginScene returned failed (%08x)\n", hr);
2751 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
2752 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
2754 hr = IDirect3DDevice9_EndScene(device);
2755 ok(hr == D3D_OK, "EndScene failed (%08x)\n", hr);
2757 /* As the red and green component are the result of blending use 5% tolerance on the expected value */
2758 color = getPixelColor(device, 128, 240);
2759 ok(color_match(color, test_data[i].color[j], 13),
2760 "fog vs%i ps%i fvm%i ftm%i %d: got color %08x, expected %08x +-5%%\n",
2761 test_data[i].vshader, test_data[i].pshader, test_data[i].vfog, test_data[i].tfog, j, color, test_data[i].color[j]);
2764 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
2766 IDirect3DVertexShader9_Release(vertex_shader[1]);
2767 IDirect3DVertexShader9_Release(vertex_shader[2]);
2768 IDirect3DVertexShader9_Release(vertex_shader[3]);
2769 IDirect3DPixelShader9_Release(pixel_shader[1]);
2770 IDirect3DPixelShader9_Release(pixel_shader[2]);
2771 IDirect3DVertexDeclaration9_Release(vertex_declaration);
2772 refcount = IDirect3DDevice9_Release(device);
2773 ok(!refcount, "Device has %u references left.\n", refcount);
2774 done:
2775 IDirect3D9_Release(d3d);
2776 DestroyWindow(window);
2779 static void generate_bumpmap_textures(IDirect3DDevice9 *device) {
2780 unsigned int i, x, y;
2781 HRESULT hr;
2782 IDirect3DTexture9 *texture[2] = {NULL, NULL};
2783 D3DLOCKED_RECT locked_rect;
2785 /* Generate the textures */
2786 for(i=0; i<2; i++)
2788 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, 0, i?D3DFMT_A8R8G8B8:D3DFMT_V8U8,
2789 D3DPOOL_MANAGED, &texture[i], NULL);
2790 ok(SUCCEEDED(hr), "CreateTexture failed (0x%08x)\n", hr);
2792 hr = IDirect3DTexture9_LockRect(texture[i], 0, &locked_rect, NULL, 0);
2793 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
2794 for (y = 0; y < 128; ++y)
2796 if(i)
2797 { /* Set up black texture with 2x2 texel white spot in the middle */
2798 DWORD *ptr = (DWORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
2799 for (x = 0; x < 128; ++x)
2801 *ptr++ = D3DCOLOR_ARGB(0xff, x * 2, y * 2, 0);
2804 else
2805 { /* Set up a displacement map which points away from the center parallel to the closest axis.
2806 * (if multiplied with bumpenvmat)
2808 WORD *ptr = (WORD *)(((BYTE *)locked_rect.pBits) + (y * locked_rect.Pitch));
2809 for (x = 0; x < 128; ++x)
2811 if(abs(x-64)>abs(y-64))
2813 if(x < 64)
2814 *ptr++ = 0xc000;
2815 else
2816 *ptr++ = 0x4000;
2818 else
2820 if(y < 64)
2821 *ptr++ = 0x0040;
2822 else
2823 *ptr++ = 0x00c0;
2828 hr = IDirect3DTexture9_UnlockRect(texture[i], 0);
2829 ok(SUCCEEDED(hr), "UnlockRect failed (0x%08x)\n", hr);
2831 hr = IDirect3DDevice9_SetTexture(device, i, (IDirect3DBaseTexture9 *)texture[i]);
2832 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
2834 /* Disable texture filtering */
2835 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MINFILTER, D3DTEXF_POINT);
2836 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
2837 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
2838 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
2840 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
2841 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSU failed (0x%08x)\n", hr);
2842 hr = IDirect3DDevice9_SetSamplerState(device, i, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
2843 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_ADDRESSV failed (0x%08x)\n", hr);
2847 /* Test the behavior of the texbem instruction with normal 2D and projective
2848 * 2D textures. */
2849 static void texbem_test(void)
2851 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
2852 /* Use asymmetric matrix to test loading. */
2853 float bumpenvmat[4] = {0.0f, 0.5f, -0.5f, 0.0f};
2854 IDirect3DPixelShader9 *pixel_shader = NULL;
2855 IDirect3DTexture9 *texture1, *texture2;
2856 IDirect3DTexture9 *texture = NULL;
2857 D3DLOCKED_RECT locked_rect;
2858 IDirect3DDevice9 *device;
2859 IDirect3D9 *d3d;
2860 ULONG refcount;
2861 D3DCAPS9 caps;
2862 DWORD color;
2863 HWND window;
2864 HRESULT hr;
2865 int i;
2867 static const DWORD pixel_shader_code[] =
2869 0xffff0101, /* ps_1_1*/
2870 0x00000042, 0xb00f0000, /* tex t0*/
2871 0x00000043, 0xb00f0001, 0xb0e40000, /* texbem t1, t0*/
2872 0x00000001, 0x800f0000, 0xb0e40001, /* mov r0, t1*/
2873 0x0000ffff
2875 static const DWORD double_texbem_code[] =
2877 0xffff0103, /* ps_1_3 */
2878 0x00000042, 0xb00f0000, /* tex t0 */
2879 0x00000043, 0xb00f0001, 0xb0e40000, /* texbem t1, t0 */
2880 0x00000042, 0xb00f0002, /* tex t2 */
2881 0x00000043, 0xb00f0003, 0xb0e40002, /* texbem t3, t2 */
2882 0x00000002, 0x800f0000, 0xb0e40001, 0xb0e40003, /* add r0, t1, t3 */
2883 0x0000ffff /* end */
2885 static const float quad[][7] =
2887 {-1.0f, -1.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
2888 {-1.0f, 1.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
2889 { 1.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
2890 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
2892 static const float quad_proj[][9] =
2894 {-1.0f, -1.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 128.0f},
2895 {-1.0f, 1.0f, 0.1f, 0.0f, 1.0f, 0.0f, 128.0f, 0.0f, 128.0f},
2896 { 1.0f, -1.0f, 0.1f, 1.0f, 0.0f, 128.0f, 0.0f, 0.0f, 128.0f},
2897 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 128.0f, 128.0f, 0.0f, 128.0f},
2899 static const float double_quad[] =
2901 -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.5f, 0.5f, 0.0f, 0.0f, 0.5f, 0.5f,
2902 -1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.5f, 0.5f, 0.0f, 0.0f, 0.5f, 0.5f,
2903 1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.5f, 0.5f, 0.0f, 0.0f, 0.5f, 0.5f,
2904 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.5f, 0.5f, 0.0f, 0.0f, 0.5f, 0.5f,
2906 static const D3DVERTEXELEMENT9 decl_elements[][4] =
2909 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2910 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
2911 {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
2912 D3DDECL_END()
2915 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
2916 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
2917 {0, 20, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
2918 D3DDECL_END()
2922 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
2923 0, 0, 640, 480, NULL, NULL, NULL, NULL);
2924 d3d = Direct3DCreate9(D3D_SDK_VERSION);
2925 ok(!!d3d, "Failed to create a D3D object.\n");
2926 if (!(device = create_device(d3d, window, window, TRUE)))
2928 skip("Failed to create a D3D device, skipping tests.\n");
2929 goto done;
2932 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
2933 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
2934 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 1))
2936 skip("No ps_1_1 support, skipping tests.\n");
2937 IDirect3DDevice9_Release(device);
2938 goto done;
2941 generate_bumpmap_textures(device);
2943 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
2944 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
2945 IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
2946 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
2947 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
2949 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
2950 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
2952 for(i=0; i<2; i++)
2954 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
2955 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
2957 if(i)
2959 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4|D3DTTFF_PROJECTED);
2960 ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
2963 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements[i], &vertex_declaration);
2964 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
2965 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
2966 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
2968 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &pixel_shader);
2969 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
2970 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
2971 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
2973 hr = IDirect3DDevice9_BeginScene(device);
2974 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
2976 if(!i)
2977 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
2978 else
2979 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad_proj[0], sizeof(quad_proj[0]));
2980 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
2982 hr = IDirect3DDevice9_EndScene(device);
2983 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
2985 /* The Window 8 testbot (WARP) seems to use the transposed
2986 * D3DTSS_BUMPENVMAT matrix. */
2987 color = getPixelColor(device, 160, 240);
2988 ok(color_match(color, 0x007e8000, 4) || broken(color_match(color, 0x00007e00, 4)),
2989 "Got unexpected color 0x%08x.\n", color);
2990 color = getPixelColor(device, 480, 240);
2991 ok(color_match(color, 0x007e8000, 4) || broken(color_match(color, 0x00fe7e00, 4)),
2992 "Got unexpected color 0x%08x.\n", color);
2993 color = getPixelColor(device, 320, 120);
2994 ok(color_match(color, 0x007e8000, 4) || broken(color_match(color, 0x0080fe00, 4)),
2995 "Got unexpected color 0x%08x.\n", color);
2996 color = getPixelColor(device, 320, 360);
2997 ok(color_match(color, 0x007e8000, 4) || broken(color_match(color, 0x00800000, 4)),
2998 "Got unexpected color 0x%08x.\n", color);
3000 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3001 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3003 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
3004 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
3005 IDirect3DPixelShader9_Release(pixel_shader);
3007 hr = IDirect3DDevice9_SetVertexDeclaration(device, NULL);
3008 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (%08x)\n", hr);
3009 IDirect3DVertexDeclaration9_Release(vertex_declaration);
3012 /* clean up */
3013 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0, 0.0f, 0);
3014 ok(SUCCEEDED(hr), "Clear failed (0x%08x)\n", hr);
3016 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
3017 ok(SUCCEEDED(hr), "SetTextureStageState D3DTSS_TEXTURETRANSFORMFLAGS failed (0x%08x)\n", hr);
3019 for(i=0; i<2; i++)
3021 hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
3022 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
3023 IDirect3DTexture9_Release(texture); /* For the GetTexture */
3024 hr = IDirect3DDevice9_SetTexture(device, i, NULL);
3025 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
3026 IDirect3DTexture9_Release(texture);
3029 /* Test double texbem */
3030 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture, NULL);
3031 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
3032 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_V8U8, D3DPOOL_MANAGED, &texture1, NULL);
3033 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
3034 hr = IDirect3DDevice9_CreateTexture(device, 8, 8, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture2, NULL);
3035 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed (0x%08x)\n", hr);
3036 hr = IDirect3DDevice9_CreatePixelShader(device, double_texbem_code, &pixel_shader);
3037 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
3039 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
3040 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
3041 ((signed char *) locked_rect.pBits)[0] = (-1.0 / 8.0) * 127;
3042 ((signed char *) locked_rect.pBits)[1] = ( 1.0 / 8.0) * 127;
3044 hr = IDirect3DTexture9_UnlockRect(texture, 0);
3045 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
3047 hr = IDirect3DTexture9_LockRect(texture1, 0, &locked_rect, NULL, 0);
3048 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
3049 ((signed char *) locked_rect.pBits)[0] = (-2.0 / 8.0) * 127;
3050 ((signed char *) locked_rect.pBits)[1] = (-4.0 / 8.0) * 127;
3051 hr = IDirect3DTexture9_UnlockRect(texture1, 0);
3052 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
3055 /* Some data without any meaning, just to have an 8x8 array to see which element is picked */
3056 #define tex 0x00ff0000
3057 #define tex1 0x0000ff00
3058 #define origin 0x000000ff
3059 static const DWORD pixel_data[] = {
3060 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
3061 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
3062 0x000000ff, tex1 , 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
3063 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
3064 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, origin, 0x000000ff, tex , 0x000000ff,
3065 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
3066 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
3067 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
3069 #undef tex1
3070 #undef tex2
3071 #undef origin
3073 hr = IDirect3DTexture9_LockRect(texture2, 0, &locked_rect, NULL, 0);
3074 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
3075 for(i = 0; i < 8; i++) {
3076 memcpy(((char *) locked_rect.pBits) + i * locked_rect.Pitch, pixel_data + 8 * i, 8 * sizeof(DWORD));
3078 hr = IDirect3DTexture9_UnlockRect(texture2, 0);
3079 ok(SUCCEEDED(hr), "LockRect failed (0x%08x)\n", hr);
3082 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
3083 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
3084 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) texture2);
3085 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
3086 hr = IDirect3DDevice9_SetTexture(device, 2, (IDirect3DBaseTexture9 *) texture1);
3087 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
3088 hr = IDirect3DDevice9_SetTexture(device, 3, (IDirect3DBaseTexture9 *) texture2);
3089 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (0x%08x)\n", hr);
3090 hr = IDirect3DDevice9_SetPixelShader(device, pixel_shader);
3091 ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
3092 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX4);
3093 ok(SUCCEEDED(hr), "Direct3DDevice9_SetPixelShader failed (0x%08x)\n", hr);
3095 bumpenvmat[0] =-1.0; bumpenvmat[2] = 2.0;
3096 bumpenvmat[1] = 0.0; bumpenvmat[3] = 0.0;
3097 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
3098 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
3099 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
3100 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
3101 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
3102 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
3103 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
3104 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
3106 bumpenvmat[0] = 1.5; bumpenvmat[2] = 0.0;
3107 bumpenvmat[1] = 0.0; bumpenvmat[3] = 0.5;
3108 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
3109 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
3110 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
3111 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
3112 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
3113 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
3114 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
3115 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState returned %#x.\n", hr);
3117 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
3118 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
3119 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
3120 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
3121 hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
3122 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
3123 hr = IDirect3DDevice9_SetSamplerState(device, 1, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
3124 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
3125 hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
3126 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
3127 hr = IDirect3DDevice9_SetSamplerState(device, 2, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
3128 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
3129 hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
3130 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
3131 hr = IDirect3DDevice9_SetSamplerState(device, 3, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
3132 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetSamplerState returned %#x.\n", hr);
3134 hr = IDirect3DDevice9_BeginScene(device);
3135 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
3136 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, double_quad, sizeof(float) * 11);
3137 ok(SUCCEEDED(hr), "Failed to draw primitive, hr %#x.\n", hr);
3138 hr = IDirect3DDevice9_EndScene(device);
3139 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
3140 /* The Window 8 testbot (WARP) seems to use the transposed
3141 * D3DTSS_BUMPENVMAT matrix. */
3142 color = getPixelColor(device, 320, 240);
3143 ok(color_match(color, 0x00ffff00, 1) || broken(color_match(color, 0x0000ffff, 1)),
3144 "Got unexpected color 0x%08x.\n", color);
3146 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3147 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
3149 IDirect3DPixelShader9_Release(pixel_shader);
3150 IDirect3DTexture9_Release(texture);
3151 IDirect3DTexture9_Release(texture1);
3152 IDirect3DTexture9_Release(texture2);
3153 refcount = IDirect3DDevice9_Release(device);
3154 ok(!refcount, "Device has %u references left.\n", refcount);
3155 done:
3156 IDirect3D9_Release(d3d);
3157 DestroyWindow(window);
3160 static void z_range_test(void)
3162 IDirect3DVertexShader9 *shader;
3163 IDirect3DDevice9 *device;
3164 IDirect3D9 *d3d;
3165 ULONG refcount;
3166 D3DCAPS9 caps;
3167 DWORD color;
3168 HWND window;
3169 HRESULT hr;
3171 static const struct
3173 struct vec3 position;
3174 DWORD diffuse;
3176 quad[] =
3178 {{-1.0f, 0.0f, 1.1f}, 0xffff0000},
3179 {{-1.0f, 1.0f, 1.1f}, 0xffff0000},
3180 {{ 1.0f, 0.0f, -1.1f}, 0xffff0000},
3181 {{ 1.0f, 1.0f, -1.1f}, 0xffff0000},
3183 quad2[] =
3185 {{-1.0f, 0.0f, 1.1f}, 0xff0000ff},
3186 {{-1.0f, 1.0f, 1.1f}, 0xff0000ff},
3187 {{ 1.0f, 0.0f, -1.1f}, 0xff0000ff},
3188 {{ 1.0f, 1.0f, -1.1f}, 0xff0000ff},
3190 static const struct
3192 struct vec4 position;
3193 DWORD diffuse;
3195 quad3[] =
3197 {{640.0f, 240.0f, -1.1f, 1.0f}, 0xffffff00},
3198 {{640.0f, 480.0f, -1.1f, 1.0f}, 0xffffff00},
3199 {{ 0.0f, 240.0f, 1.1f, 1.0f}, 0xffffff00},
3200 {{ 0.0f, 480.0f, 1.1f, 1.0f}, 0xffffff00},
3202 quad4[] =
3204 {{640.0f, 240.0f, -1.1f, 1.0f}, 0xff00ff00},
3205 {{640.0f, 480.0f, -1.1f, 1.0f}, 0xff00ff00},
3206 {{ 0.0f, 240.0f, 1.1f, 1.0f}, 0xff00ff00},
3207 {{ 0.0f, 480.0f, 1.1f, 1.0f}, 0xff00ff00},
3209 static const DWORD shader_code[] =
3211 0xfffe0101, /* vs_1_1 */
3212 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
3213 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
3214 0x00000001, 0xd00f0000, 0xa0e40000, /* mov oD0, c0 */
3215 0x0000ffff /* end */
3217 static const float color_const_1[] = {1.0f, 0.0f, 0.0f, 1.0f};
3218 static const float color_const_2[] = {0.0f, 0.0f, 1.0f, 1.0f};
3220 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
3221 0, 0, 640, 480, NULL, NULL, NULL, NULL);
3222 d3d = Direct3DCreate9(D3D_SDK_VERSION);
3223 ok(!!d3d, "Failed to create a D3D object.\n");
3224 if (!(device = create_device(d3d, window, window, TRUE)))
3226 skip("Failed to create a D3D device, skipping tests.\n");
3227 goto done;
3230 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
3231 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
3233 /* Does the Present clear the depth stencil? Clear the depth buffer with some value != 0,
3234 * then call Present. Then clear the color buffer to make sure it has some defined content
3235 * after the Present with D3DSWAPEFFECT_DISCARD. After that draw a plane that is somewhere cut
3236 * by the depth value. */
3237 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.75f, 0);
3238 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
3239 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3240 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
3241 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
3242 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
3244 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
3245 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
3246 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
3247 ok(SUCCEEDED(hr), "Failed to enable clipping, hr %#x.\n", hr);
3248 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
3249 ok(SUCCEEDED(hr), "Failed to enable z test, hr %#x.\n", hr);
3250 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
3251 ok(SUCCEEDED(hr), "Failed to disable z writes, hr %#x.\n", hr);
3252 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
3253 ok(SUCCEEDED(hr), "Failed to set z function, hr %#x.\n", hr);
3254 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
3255 ok(SUCCEEDED(hr), "Failed set FVF, hr %#x.\n", hr);
3257 hr = IDirect3DDevice9_BeginScene(device);
3258 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
3260 /* Test the untransformed vertex path */
3261 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
3262 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
3263 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
3264 ok(SUCCEEDED(hr), "Failed to set z function, hr %#x.\n", hr);
3265 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
3266 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
3268 /* Test the transformed vertex path */
3269 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
3270 ok(SUCCEEDED(hr), "Failed set FVF, hr %#x.\n", hr);
3272 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(quad4[0]));
3273 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
3274 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
3275 ok(SUCCEEDED(hr), "Failed to set z function, hr %#x.\n", hr);
3276 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(quad3[0]));
3277 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
3279 hr = IDirect3DDevice9_EndScene(device);
3280 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
3282 /* Do not test the exact corner pixels, but go pretty close to them */
3284 /* Clipped because z > 1.0 */
3285 color = getPixelColor(device, 28, 238);
3286 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
3287 color = getPixelColor(device, 28, 241);
3288 if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
3289 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
3290 else
3291 ok(color_match(color, 0x00ffff00, 0), "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
3293 /* Not clipped, > z buffer clear value(0.75).
3295 * On the r500 driver on Windows D3DCMP_GREATER and D3DCMP_GREATEREQUAL are broken for depth
3296 * values > 0.5. The range appears to be distorted, apparently an incoming value of ~0.875 is
3297 * equal to a stored depth buffer value of 0.5. */
3298 color = getPixelColor(device, 31, 238);
3299 ok(color_match(color, 0x00ff0000, 0), "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
3300 color = getPixelColor(device, 31, 241);
3301 ok(color_match(color, 0x00ffff00, 0), "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
3302 color = getPixelColor(device, 100, 238);
3303 ok(color_match(color, 0x00ff0000, 0) || broken(color_match(color, 0x00ffffff, 0)),
3304 "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
3305 color = getPixelColor(device, 100, 241);
3306 ok(color_match(color, 0x00ffff00, 0) || broken(color_match(color, 0x00ffffff, 0)),
3307 "Z range failed: Got color 0x%08x, expected 0x00ffff00.\n", color);
3309 /* Not clipped, < z buffer clear value */
3310 color = getPixelColor(device, 104, 238);
3311 ok(color_match(color, 0x000000ff, 0), "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
3312 color = getPixelColor(device, 104, 241);
3313 ok(color_match(color, 0x0000ff00, 0), "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
3314 color = getPixelColor(device, 318, 238);
3315 ok(color_match(color, 0x000000ff, 0), "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
3316 color = getPixelColor(device, 318, 241);
3317 ok(color_match(color, 0x0000ff00, 0), "Z range failed: Got color 0x%08x, expected 0x0000ff00.\n", color);
3319 /* Clipped because z < 0.0 */
3320 color = getPixelColor(device, 321, 238);
3321 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
3322 color = getPixelColor(device, 321, 241);
3323 if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
3324 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
3325 else
3326 ok(color_match(color, 0x0000ff00, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
3328 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3329 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
3331 /* Test the shader path */
3332 if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1))
3334 skip("Vertex shaders not supported, skipping tests.\n");
3335 IDirect3DDevice9_Release(device);
3336 goto done;
3338 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
3339 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
3341 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
3342 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
3344 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
3345 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
3346 hr = IDirect3DDevice9_SetVertexShader(device, shader);
3347 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
3349 hr = IDirect3DDevice9_BeginScene(device);
3350 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
3352 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, color_const_1, 1);
3353 ok(SUCCEEDED(hr), "Failed to set vs constant 0, hr %#x.\n", hr);
3354 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
3355 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
3357 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESS);
3358 ok(SUCCEEDED(hr), "Failed to set z function, hr %#x.\n", hr);
3359 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, color_const_2, 1);
3360 ok(SUCCEEDED(hr), "Failed to set vs constant 0, hr %#x.\n", hr);
3361 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
3362 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
3364 hr = IDirect3DDevice9_EndScene(device);
3365 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
3367 IDirect3DVertexShader9_Release(shader);
3369 /* Z < 1.0 */
3370 color = getPixelColor(device, 28, 238);
3371 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
3373 /* 1.0 < z < 0.75 */
3374 color = getPixelColor(device, 31, 238);
3375 ok(color_match(color, 0x00ff0000, 0), "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
3376 color = getPixelColor(device, 100, 238);
3377 ok(color_match(color, 0x00ff0000, 0) || broken(color_match(color, 0x00ffffff, 0)),
3378 "Z range failed: Got color 0x%08x, expected 0x00ff0000.\n", color);
3380 /* 0.75 < z < 0.0 */
3381 color = getPixelColor(device, 104, 238);
3382 ok(color_match(color, 0x000000ff, 0), "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
3383 color = getPixelColor(device, 318, 238);
3384 ok(color_match(color, 0x000000ff, 0), "Z range failed: Got color 0x%08x, expected 0x000000ff.\n", color);
3386 /* 0.0 < z */
3387 color = getPixelColor(device, 321, 238);
3388 ok(color_match(color, 0x00ffffff, 0), "Z range failed: Got color 0x%08x, expected 0x00ffffff.\n", color);
3390 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
3391 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
3393 refcount = IDirect3DDevice9_Release(device);
3394 ok(!refcount, "Device has %u references left.\n", refcount);
3395 done:
3396 IDirect3D9_Release(d3d);
3397 DestroyWindow(window);
3400 static void fill_surface(IDirect3DSurface9 *surface, DWORD color, DWORD flags)
3402 D3DSURFACE_DESC desc;
3403 D3DLOCKED_RECT l;
3404 HRESULT hr;
3405 unsigned int x, y;
3406 DWORD *mem;
3408 memset(&desc, 0, sizeof(desc));
3409 memset(&l, 0, sizeof(l));
3410 hr = IDirect3DSurface9_GetDesc(surface, &desc);
3411 ok(hr == D3D_OK, "IDirect3DSurface9_GetDesc failed with %08x\n", hr);
3412 hr = IDirect3DSurface9_LockRect(surface, &l, NULL, flags);
3413 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed with %08x\n", hr);
3414 if(FAILED(hr)) return;
3416 for(y = 0; y < desc.Height; y++)
3418 mem = (DWORD *) ((BYTE *) l.pBits + y * l.Pitch);
3419 for(x = 0; x < l.Pitch / sizeof(DWORD); x++)
3421 mem[x] = color;
3424 hr = IDirect3DSurface9_UnlockRect(surface);
3425 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed with %08x\n", hr);
3428 static void stretchrect_test(void)
3430 IDirect3DSurface9 *surf_tex_rt32, *surf_tex_rt64, *surf_tex_rt_dest64, *surf_tex_rt_dest640_480;
3431 IDirect3DSurface9 *surf_offscreen32, *surf_offscreen64, *surf_offscreen_dest64;
3432 IDirect3DTexture9 *tex_rt32, *tex_rt64, *tex_rt_dest64, *tex_rt_dest640_480;
3433 IDirect3DSurface9 *surf_tex32, *surf_tex64, *surf_tex_dest64;
3434 IDirect3DSurface9 *surf_rt32, *surf_rt64, *surf_rt_dest64;
3435 IDirect3DTexture9 *tex32, *tex64, *tex_dest64;
3436 IDirect3DSurface9 *surf_temp32, *surf_temp64;
3437 IDirect3DSurface9 *backbuffer;
3438 IDirect3DDevice9 *device;
3439 IDirect3D9 *d3d;
3440 D3DCOLOR color;
3441 ULONG refcount;
3442 HWND window;
3443 HRESULT hr;
3445 static const RECT src_rect = {0, 0, 640, 480};
3446 static const RECT src_rect_flipy = {0, 480, 640, 0};
3447 static const RECT dst_rect = {0, 0, 640, 480};
3448 static const RECT dst_rect_flipy = {0, 480, 640, 0};
3449 static const RECT src_rect64 = {0, 0, 64, 64};
3450 static const RECT src_rect64_flipy = {0, 64, 64, 0};
3451 static const RECT dst_rect64 = {0, 0, 64, 64};
3452 static const RECT dst_rect64_flipy = {0, 64, 64, 0};
3454 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
3455 0, 0, 640, 480, NULL, NULL, NULL, NULL);
3456 d3d = Direct3DCreate9(D3D_SDK_VERSION);
3457 ok(!!d3d, "Failed to create a D3D object.\n");
3458 if (!(device = create_device(d3d, window, window, TRUE)))
3460 skip("Failed to create a D3D device, skipping tests.\n");
3461 goto done;
3464 /* Create our temporary surfaces in system memory. */
3465 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
3466 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp32, NULL);
3467 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
3468 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64,
3469 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf_temp64, NULL);
3470 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
3472 /* Create offscreen plain surfaces in D3DPOOL_DEFAULT. */
3473 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
3474 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen32, NULL);
3475 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
3476 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64,
3477 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen64, NULL);
3478 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
3479 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64,
3480 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &surf_offscreen_dest64, NULL);
3481 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
3483 /* Create render target surfaces. */
3484 hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32,
3485 D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt32, NULL );
3486 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
3487 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64,
3488 D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt64, NULL );
3489 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
3490 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64,
3491 D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &surf_rt_dest64, NULL );
3492 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
3493 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
3494 ok(SUCCEEDED(hr), "Failed to get back buffer, hr %#x.\n", hr);
3496 /* Create render target textures. */
3497 hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, D3DUSAGE_RENDERTARGET,
3498 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt32, NULL);
3499 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
3500 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET,
3501 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt64, NULL);
3502 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
3503 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, D3DUSAGE_RENDERTARGET,
3504 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt_dest64, NULL);
3505 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
3506 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1, D3DUSAGE_RENDERTARGET,
3507 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_rt_dest640_480, NULL);
3508 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
3509 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt32, 0, &surf_tex_rt32);
3510 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
3511 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt64, 0, &surf_tex_rt64);
3512 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
3513 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt_dest64, 0, &surf_tex_rt_dest64);
3514 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
3515 hr = IDirect3DTexture9_GetSurfaceLevel(tex_rt_dest640_480, 0, &surf_tex_rt_dest640_480);
3516 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
3518 /* Create regular textures in D3DPOOL_DEFAULT. */
3519 hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex32, NULL);
3520 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
3521 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex64, NULL);
3522 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
3523 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex_dest64, NULL);
3524 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
3525 hr = IDirect3DTexture9_GetSurfaceLevel(tex32, 0, &surf_tex32);
3526 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
3527 hr = IDirect3DTexture9_GetSurfaceLevel(tex64, 0, &surf_tex64);
3528 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
3529 hr = IDirect3DTexture9_GetSurfaceLevel(tex_dest64, 0, &surf_tex_dest64);
3530 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
3532 /**********************************************************************
3533 * Tests for when the source parameter is an offscreen plain surface. *
3534 **********************************************************************/
3536 /* Fill the offscreen 64x64 surface with green. */
3537 fill_surface(surf_offscreen64, 0xff00ff00, 0);
3539 /* offscreenplain ==> offscreenplain, same size. */
3540 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_offscreen_dest64, NULL, D3DTEXF_NONE);
3541 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3542 color = getPixelColorFromSurface(surf_offscreen_dest64, 32, 32);
3543 ok(color == 0xff00ff00, "Got unexpected color 0x%08x.\n", color);
3544 /* Blit without scaling. */
3545 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64,
3546 surf_offscreen_dest64, &dst_rect64, D3DTEXF_NONE);
3547 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3548 /* Flipping in y-direction through src_rect, no scaling (not allowed). */
3549 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy,
3550 surf_offscreen_dest64, &dst_rect64, D3DTEXF_NONE);
3551 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3552 /* Flipping in y-direction through dst_rect, no scaling (not allowed). */
3553 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64,
3554 surf_offscreen_dest64, &dst_rect64_flipy, D3DTEXF_NONE);
3555 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3557 /* offscreenplain ==> rendertarget texture, same size. */
3558 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_rt_dest64, NULL, D3DTEXF_NONE);
3559 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3560 /* We can't lock rendertarget textures, so copy to our temp surface first. */
3561 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3562 ok(SUCCEEDED(hr), "Failed to get render target data, hr %#x.\n", hr);
3563 color = getPixelColorFromSurface(surf_temp64, 32, 32);
3564 ok(color == 0xff00ff00, "Got unexpected color 0x%08x.\n", color);
3565 /* Blit without scaling. */
3566 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64,
3567 surf_tex_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3568 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3569 /* Flipping in y-direction through src_rect, no scaling (not allowed). */
3570 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy,
3571 surf_tex_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3572 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3573 /* Flipping in y-direction through dst_rect, no scaling (not allowed). */
3574 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64,
3575 surf_tex_rt_dest64, &dst_rect64_flipy, D3DTEXF_NONE);
3576 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3578 /* offscreenplain ==> rendertarget surface, same size. */
3579 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_rt_dest64, NULL, D3DTEXF_NONE);
3580 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3581 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
3582 ok(color == 0xff00ff00, "Got unexpected color 0x%08x.\n", color);
3583 /* Blit without scaling. */
3584 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64,
3585 surf_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3586 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3587 /* Flipping in y-direction through src_rect, no scaling (not allowed). */
3588 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64_flipy,
3589 surf_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3590 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3591 /* Flipping in y-direction through dst_rect, no scaling (not allowed). */
3592 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, &src_rect64,
3593 surf_rt_dest64, &dst_rect64_flipy, D3DTEXF_NONE);
3594 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3596 /* offscreenplain ==> texture, same size (should fail). */
3597 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen64, NULL, surf_tex_dest64, NULL, D3DTEXF_NONE);
3598 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3600 /* Fill the smaller offscreen surface with red. */
3601 fill_surface(surf_offscreen32, 0xffff0000, 0);
3603 /* offscreenplain ==> offscreenplain, scaling (should fail). */
3604 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_offscreen64, NULL, D3DTEXF_NONE);
3605 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3607 /* offscreenplain ==> rendertarget texture, scaling. */
3608 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_rt_dest64, NULL, D3DTEXF_NONE);
3609 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3610 /* We can't lock rendertarget textures, so copy to our temp surface first. */
3611 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3612 ok(SUCCEEDED(hr), "Failed to get render target data, hr %#x.\n", hr);
3613 color = getPixelColorFromSurface(surf_temp64, 48, 48);
3614 ok(color == 0xffff0000, "Got unexpected color 0x%08x.\n", color);
3616 /* offscreenplain ==> rendertarget surface, scaling. */
3617 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_rt_dest64, NULL, D3DTEXF_NONE);
3618 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3619 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
3620 ok(color == 0xffff0000, "Got unexpected color 0x%08x.\n", color);
3622 /* offscreenplain ==> texture, scaling (should fail). */
3623 hr = IDirect3DDevice9_StretchRect(device, surf_offscreen32, NULL, surf_tex_dest64, NULL, D3DTEXF_NONE);
3624 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3626 /*************************************************************
3627 * Tests for when the source parameter is a regular texture. *
3628 *************************************************************/
3630 /* Fill the surface of the regular texture with blue. */
3631 /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT. */
3632 fill_surface(surf_temp64, 0xff0000ff, 0);
3633 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex64, NULL);
3634 ok(SUCCEEDED(hr), "Failed to update surface, hr %#x.\n", hr);
3636 /* texture ==> offscreenplain, same size. */
3637 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_offscreen64, NULL, D3DTEXF_NONE);
3638 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3640 /* texture ==> rendertarget texture, same size. */
3641 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_rt_dest64, NULL, D3DTEXF_NONE);
3642 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3643 /* We can't lock rendertarget textures, so copy to our temp surface first. */
3644 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3645 ok(SUCCEEDED(hr), "Failed to get render target data, hr %#x.\n", hr);
3646 color = getPixelColorFromSurface(surf_temp64, 32, 32);
3647 ok(color == 0xff0000ff, "Got unexpected color 0x%08x.\n", color);
3648 /* Blit without scaling. */
3649 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64,
3650 surf_tex_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3651 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3652 /* Flipping in y-direction through src_rect, no scaling (not allowed). */
3653 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64_flipy,
3654 surf_tex_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3655 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3656 /* Flipping in y-direction through dst_rect, no scaling (not allowed). */
3657 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64,
3658 surf_tex_rt_dest64, &dst_rect64_flipy, D3DTEXF_NONE);
3659 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3661 /* texture ==> rendertarget surface, same size. */
3662 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_rt_dest64, NULL, D3DTEXF_NONE);
3663 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3664 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
3665 ok(color == 0xff0000ff, "Got unexpected color 0x%08x.\n", color);
3666 /* Blit without scaling. */
3667 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64,
3668 surf_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3669 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3670 /* Flipping in y-direction through src_rect, no scaling (not allowed). */
3671 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64_flipy,
3672 surf_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3673 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3674 /* Flipping in y-direction through dst_rect, no scaling (not allowed). */
3675 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, &src_rect64,
3676 surf_rt_dest64, &dst_rect64_flipy, D3DTEXF_NONE);
3677 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3679 /* texture ==> texture, same size (should fail). */
3680 hr = IDirect3DDevice9_StretchRect(device, surf_tex64, NULL, surf_tex_dest64, NULL, D3DTEXF_NONE);
3681 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3683 /* Fill the surface of the smaller regular texture with red. */
3684 /* Can't fill the surf_tex directly because it's created in D3DPOOL_DEFAULT. */
3685 fill_surface(surf_temp32, 0xffff0000, 0);
3686 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex32, NULL);
3687 ok(SUCCEEDED(hr), "Failed to update surface, hr %#x.\n", hr);
3689 /* texture ==> offscreenplain, scaling (should fail). */
3690 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_offscreen64, NULL, D3DTEXF_NONE);
3691 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3693 /* texture ==> rendertarget texture, scaling. */
3694 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_rt_dest64, NULL, D3DTEXF_NONE);
3695 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3696 /* We can't lock rendertarget textures, so copy to our temp surface first. */
3697 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3698 ok(SUCCEEDED(hr), "Failed to get render target data, hr %#x.\n", hr);
3699 color = getPixelColorFromSurface(surf_temp64, 48, 48);
3700 ok(color == 0xffff0000, "Got unexpected color 0x%08x.\n", color);
3702 /* texture ==> rendertarget surface, scaling. */
3703 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_rt_dest64, NULL, D3DTEXF_NONE);
3704 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3705 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
3706 ok(color == 0xffff0000, "Got unexpected color 0x%08x.\n", color);
3708 /* texture ==> texture, scaling (should fail). */
3709 hr = IDirect3DDevice9_StretchRect(device, surf_tex32, NULL, surf_tex_dest64, NULL, D3DTEXF_NONE);
3710 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3712 /******************************************************************
3713 * Tests for when the source parameter is a rendertarget texture. *
3714 ******************************************************************/
3716 /* Fill the surface of the rendertarget texture with white. */
3717 /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT. */
3718 fill_surface(surf_temp64, 0xffffffff, 0);
3719 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp64, NULL, surf_tex_rt64, NULL);
3720 ok(SUCCEEDED(hr), "Failed to update surface, hr %#x.\n", hr);
3722 /* rendertarget texture ==> offscreenplain, same size. */
3723 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_offscreen64, NULL, D3DTEXF_NONE);
3724 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3726 /* rendertarget texture ==> rendertarget texture, same size. */
3727 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_rt_dest64, NULL, D3DTEXF_NONE);
3728 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3729 /* We can't lock rendertarget textures, so copy to our temp surface first. */
3730 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3731 ok(SUCCEEDED(hr), "Failed to get render target data, hr %#x.\n", hr);
3732 color = getPixelColorFromSurface(surf_temp64, 32, 32);
3733 ok(color == 0xffffffff, "Got unexpected color 0x%08x.\n", color);
3734 /* Blit without scaling. */
3735 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64,
3736 surf_tex_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3737 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3738 /* Flipping in y-direction through src_rect, no scaling (not allowed). */
3739 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64_flipy,
3740 surf_tex_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3741 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3742 /* Flipping in y-direction through dst_rect, no scaling (not allowed). */
3743 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64,
3744 surf_tex_rt_dest64, &dst_rect64_flipy, D3DTEXF_NONE);
3745 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3747 /* rendertarget texture ==> rendertarget surface, same size. */
3748 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_rt_dest64, NULL, D3DTEXF_NONE);
3749 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3750 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
3751 ok(color == 0xffffffff, "Got unexpected color 0x%08x.\n", color);
3752 /* Blit without scaling. */
3753 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64,
3754 surf_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3755 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3756 /* Flipping in y-direction through src_rect, no scaling (not allowed). */
3757 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64_flipy,
3758 surf_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3759 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3760 /* Flipping in y-direction through dst_rect, no scaling (not allowed). */
3761 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, &src_rect64,
3762 surf_rt_dest64, &dst_rect64_flipy, D3DTEXF_NONE);
3763 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3765 /* rendertarget texture ==> texture, same size (should fail). */
3766 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt64, NULL, surf_tex_dest64, NULL, D3DTEXF_NONE);
3767 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3769 /* Fill the surface of the smaller rendertarget texture with red. */
3770 /* Can't fill the surf_tex_rt directly because it's created in D3DPOOL_DEFAULT. */
3771 fill_surface(surf_temp32, 0xffff0000, 0);
3772 hr = IDirect3DDevice9_UpdateSurface(device, surf_temp32, NULL, surf_tex_rt32, NULL);
3773 ok(SUCCEEDED(hr), "Failed to update surface, hr %#x.\n", hr);
3775 /* rendertarget texture ==> offscreenplain, scaling (should fail). */
3776 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_offscreen64, NULL, D3DTEXF_NONE);
3777 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3779 /* rendertarget texture ==> rendertarget texture, scaling. */
3780 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_rt_dest64, NULL, D3DTEXF_NONE);
3781 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3782 /* We can't lock rendertarget textures, so copy to our temp surface first. */
3783 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3784 ok(SUCCEEDED(hr), "Failed to get render target data, hr %#x.\n", hr);
3785 color = getPixelColorFromSurface(surf_temp64, 48, 48);
3786 ok(color == 0xffff0000, "Got unexpected color 0x%08x.\n", color);
3788 /* rendertarget texture ==> rendertarget surface, scaling. */
3789 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_rt_dest64, NULL, D3DTEXF_NONE);
3790 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3791 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
3792 ok(color == 0xffff0000, "Got unexpected color 0x%08x.\n", color);
3794 /* rendertarget texture ==> texture, scaling (should fail). */
3795 hr = IDirect3DDevice9_StretchRect(device, surf_tex_rt32, NULL, surf_tex_dest64, NULL, D3DTEXF_NONE);
3796 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3798 /******************************************************************
3799 * Tests for when the source parameter is a rendertarget surface. *
3800 ******************************************************************/
3802 /* Fill the surface of the rendertarget surface with black. */
3803 fill_surface(surf_rt64, 0xff000000, 0);
3805 /* rendertarget texture ==> offscreenplain, same size. */
3806 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_offscreen64, NULL, D3DTEXF_NONE);
3807 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3809 /* rendertarget surface ==> rendertarget texture, same size. */
3810 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_rt_dest64, NULL, D3DTEXF_NONE);
3811 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3812 /* We can't lock rendertarget textures, so copy to our temp surface first. */
3813 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3814 ok(SUCCEEDED(hr), "Failed to get render target data, hr %#x.\n", hr);
3815 color = getPixelColorFromSurface(surf_temp64, 32, 32);
3816 ok(color == 0xff000000, "Got unexpected color 0x%08x.\n", color);
3817 /* Blit without scaling. */
3818 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64,
3819 surf_tex_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3820 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3821 /* Flipping in y-direction through src_rect, no scaling (not allowed). */
3822 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64_flipy,
3823 surf_tex_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3824 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3825 /* Flipping in y-direction through dst_rect, no scaling (not allowed). */
3826 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64,
3827 surf_tex_rt_dest64, &dst_rect64_flipy, D3DTEXF_NONE);
3828 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3830 /* rendertarget surface ==> rendertarget surface, same size. */
3831 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_rt_dest64, NULL, D3DTEXF_NONE);
3832 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3833 color = getPixelColorFromSurface(surf_rt_dest64, 32, 32);
3834 ok(color == 0xff000000, "Got unexpected color 0x%08x.\n", color);
3835 /* Blit without scaling. */
3836 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64,
3837 surf_rt_dest64, &dst_rect64, D3DTEXF_NONE);
3838 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3839 /* Flipping in y-direction through src_rect, no scaling (not allowed). */
3840 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64_flipy,
3841 surf_rt_dest64, &dst_rect64_flipy, D3DTEXF_NONE);
3842 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3843 /* Flipping in y-direction through dst_rect, no scaling (not allowed). */
3844 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, &src_rect64,
3845 surf_rt_dest64, &dst_rect64_flipy, D3DTEXF_NONE);
3846 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3848 /* rendertarget surface ==> texture, same size (should fail). */
3849 hr = IDirect3DDevice9_StretchRect(device, surf_rt64, NULL, surf_tex_dest64, NULL, D3DTEXF_NONE);
3850 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3852 /* Fill the surface of the smaller rendertarget texture with red. */
3853 fill_surface(surf_rt32, 0xffff0000, 0);
3855 /* rendertarget surface ==> offscreenplain, scaling (should fail). */
3856 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_offscreen64, NULL, D3DTEXF_NONE);
3857 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3859 /* rendertarget surface ==> rendertarget texture, scaling. */
3860 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_rt_dest64, NULL, D3DTEXF_NONE);
3861 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3862 /* We can't lock rendertarget textures, so copy to our temp surface first. */
3863 hr = IDirect3DDevice9_GetRenderTargetData(device, surf_tex_rt_dest64, surf_temp64);
3864 ok(SUCCEEDED(hr), "Failed to get render target data, hr %#x.\n", hr);
3865 color = getPixelColorFromSurface(surf_temp64, 48, 48);
3866 ok(color == 0xffff0000, "Got unexpected color 0x%08x.\n", color);
3868 /* rendertarget surface ==> rendertarget surface, scaling. */
3869 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_rt_dest64, NULL, D3DTEXF_NONE);
3870 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3871 color = getPixelColorFromSurface(surf_rt_dest64, 48, 48);
3872 ok(color == 0xffff0000, "Got unexpected color 0x%08x.\n", color);
3874 /* rendertarget surface ==> texture, scaling (should fail). */
3875 hr = IDirect3DDevice9_StretchRect(device, surf_rt32, NULL, surf_tex_dest64, NULL, D3DTEXF_NONE);
3876 todo_wine ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3878 /* backbuffer ==> surface tests (no scaling). */
3879 /* Blit with NULL rectangles. */
3880 hr = IDirect3DDevice9_StretchRect(device, backbuffer, NULL, surf_tex_rt_dest640_480, NULL, D3DTEXF_NONE);
3881 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3882 /* Blit without scaling. */
3883 hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect,
3884 surf_tex_rt_dest640_480, &dst_rect, D3DTEXF_NONE);
3885 ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
3886 /* Flipping in y-direction through src_rect, no scaling (not allowed). */
3887 hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect_flipy,
3888 surf_tex_rt_dest640_480, &dst_rect, D3DTEXF_NONE);
3889 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3890 /* Flipping in y-direction through dst_rect, no scaling (not allowed). */
3891 hr = IDirect3DDevice9_StretchRect(device, backbuffer, &src_rect,
3892 surf_tex_rt_dest640_480, &dst_rect_flipy, D3DTEXF_NONE);
3893 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
3895 /* TODO: Test format conversions. */
3897 IDirect3DSurface9_Release(backbuffer);
3898 IDirect3DSurface9_Release(surf_rt32);
3899 IDirect3DSurface9_Release(surf_rt64);
3900 IDirect3DSurface9_Release(surf_rt_dest64);
3901 IDirect3DSurface9_Release(surf_temp32);
3902 IDirect3DSurface9_Release(surf_temp64);
3903 IDirect3DSurface9_Release(surf_offscreen32);
3904 IDirect3DSurface9_Release(surf_offscreen64);
3905 IDirect3DSurface9_Release(surf_offscreen_dest64);
3906 IDirect3DSurface9_Release(surf_tex_rt32);
3907 IDirect3DTexture9_Release(tex_rt32);
3908 IDirect3DSurface9_Release(surf_tex_rt64);
3909 IDirect3DTexture9_Release(tex_rt64);
3910 IDirect3DSurface9_Release(surf_tex_rt_dest64);
3911 IDirect3DTexture9_Release(tex_rt_dest64);
3912 IDirect3DSurface9_Release(surf_tex_rt_dest640_480);
3913 IDirect3DTexture9_Release(tex_rt_dest640_480);
3914 IDirect3DSurface9_Release(surf_tex32);
3915 IDirect3DTexture9_Release(tex32);
3916 IDirect3DSurface9_Release(surf_tex64);
3917 IDirect3DTexture9_Release(tex64);
3918 IDirect3DSurface9_Release(surf_tex_dest64);
3919 IDirect3DTexture9_Release(tex_dest64);
3920 refcount = IDirect3DDevice9_Release(device);
3921 ok(!refcount, "Device has %u references left.\n", refcount);
3922 done:
3923 IDirect3D9_Release(d3d);
3924 DestroyWindow(window);
3927 static void maxmip_test(void)
3929 IDirect3DTexture9 *texture;
3930 IDirect3DSurface9 *surface;
3931 IDirect3DDevice9 *device;
3932 IDirect3D9 *d3d;
3933 D3DCOLOR color;
3934 ULONG refcount;
3935 D3DCAPS9 caps;
3936 HWND window;
3937 HRESULT hr;
3938 DWORD ret;
3940 static const struct
3942 struct
3944 float x, y, z;
3945 float s, t;
3947 v[4];
3949 quads[] =
3952 {-1.0, -1.0, 0.0, 0.0, 0.0},
3953 {-1.0, 0.0, 0.0, 0.0, 1.0},
3954 { 0.0, -1.0, 0.0, 1.0, 0.0},
3955 { 0.0, 0.0, 0.0, 1.0, 1.0},
3958 { 0.0, -1.0, 0.0, 0.0, 0.0},
3959 { 0.0, 0.0, 0.0, 0.0, 1.0},
3960 { 1.0, -1.0, 0.0, 1.0, 0.0},
3961 { 1.0, 0.0, 0.0, 1.0, 1.0},
3964 { 0.0, 0.0, 0.0, 0.0, 0.0},
3965 { 0.0, 1.0, 0.0, 0.0, 1.0},
3966 { 1.0, 0.0, 0.0, 1.0, 0.0},
3967 { 1.0, 1.0, 0.0, 1.0, 1.0},
3970 {-1.0, 0.0, 0.0, 0.0, 0.0},
3971 {-1.0, 1.0, 0.0, 0.0, 1.0},
3972 { 0.0, 0.0, 0.0, 1.0, 0.0},
3973 { 0.0, 1.0, 0.0, 1.0, 1.0},
3977 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
3978 0, 0, 640, 480, NULL, NULL, NULL, NULL);
3979 d3d = Direct3DCreate9(D3D_SDK_VERSION);
3980 ok(!!d3d, "Failed to create a D3D object.\n");
3981 if (!(device = create_device(d3d, window, window, TRUE)))
3983 skip("Failed to create a D3D device, skipping tests.\n");
3984 goto done;
3987 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
3988 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
3989 if (!(caps.TextureCaps & D3DPTEXTURECAPS_MIPMAP))
3991 skip("No mipmap support, skipping tests.\n");
3992 IDirect3DDevice9_Release(device);
3993 goto done;
3996 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 3, 0,
3997 D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
3998 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
4000 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
4001 ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
4002 fill_surface(surface, 0xffff0000, 0);
4003 IDirect3DSurface9_Release(surface);
4004 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 1, &surface);
4005 ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
4006 fill_surface(surface, 0xff00ff00, 0);
4007 IDirect3DSurface9_Release(surface);
4008 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 2, &surface);
4009 ok(SUCCEEDED(hr), "IDirect3DTexture9_GetSurfaceLevel returned %#x.\n", hr);
4010 fill_surface(surface, 0xff0000ff, 0);
4011 IDirect3DSurface9_Release(surface);
4013 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4014 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
4015 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4016 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4018 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
4019 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
4020 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
4021 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
4023 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
4024 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4026 hr = IDirect3DDevice9_BeginScene(device);
4027 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
4029 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
4030 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4031 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads->v));
4032 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4034 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
4035 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4036 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[1], sizeof(*quads->v));
4037 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4039 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
4040 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4041 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[2], sizeof(*quads->v));
4042 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4044 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
4045 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4046 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[3], sizeof(*quads->v));
4047 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4049 hr = IDirect3DDevice9_EndScene(device);
4050 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
4052 /* With mipmapping disabled, the max mip level is ignored, only level 0 is used */
4053 color = getPixelColor(device, 160, 360);
4054 ok(color == 0x00ff0000, "MaxMip 0, no mipfilter has color 0x%08x.\n", color);
4055 color = getPixelColor(device, 480, 360);
4056 ok(color == 0x00ff0000, "MaxMip 1, no mipfilter has color 0x%08x.\n", color);
4057 color = getPixelColor(device, 480, 120);
4058 ok(color == 0x00ff0000, "MaxMip 2, no mipfilter has color 0x%08x.\n", color);
4059 color = getPixelColor(device, 160, 120);
4060 ok(color == 0x00ff0000, "MaxMip 3, no mipfilter has color 0x%08x.\n", color);
4061 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4062 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
4064 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
4065 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
4067 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
4068 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4070 hr = IDirect3DDevice9_BeginScene(device);
4071 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
4073 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
4074 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4075 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads->v));
4076 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4078 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
4079 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4080 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[1], sizeof(*quads->v));
4081 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4083 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
4084 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4085 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[2], sizeof(*quads->v));
4086 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4088 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 3);
4089 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4090 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[3], sizeof(*quads->v));
4091 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4093 hr = IDirect3DDevice9_EndScene(device);
4094 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
4096 /* Max Mip level 0-2 sample from the specified texture level, Max Mip
4097 * level 3 (> levels in texture) samples from the highest level in the
4098 * texture (level 2). */
4099 color = getPixelColor(device, 160, 360);
4100 ok(color == 0x00ff0000, "MaxMip 0, point mipfilter has color 0x%08x.\n", color);
4101 color = getPixelColor(device, 480, 360);
4102 ok(color == 0x0000ff00, "MaxMip 1, point mipfilter has color 0x%08x.\n", color);
4103 color = getPixelColor(device, 480, 120);
4104 ok(color == 0x000000ff, "MaxMip 2, point mipfilter has color 0x%08x.\n", color);
4105 color = getPixelColor(device, 160, 120);
4106 ok(color == 0x000000ff, "MaxMip 3, point mipfilter has color 0x%08x.\n", color);
4107 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4108 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
4110 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0, 0);
4111 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4113 hr = IDirect3DDevice9_BeginScene(device);
4114 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
4116 /* Mipmapping OFF, LOD level smaller than MAXMIPLEVEL. LOD level limits */
4117 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
4118 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4119 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 0);
4120 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4121 ret = IDirect3DTexture9_SetLOD(texture, 1);
4122 ok(ret == 0, "Got unexpected LOD %u.\n", ret);
4123 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads->v));
4124 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4126 /* Mipmapping ON, LOD level smaller than max mip level. LOD level limits */
4127 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
4128 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4129 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 1);
4130 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4131 ret = IDirect3DTexture9_SetLOD(texture, 2);
4132 ok(ret == 1, "Got unexpected LOD %u.\n", ret);
4133 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[1], sizeof(*quads->v));
4134 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4136 /* Mipmapping ON, LOD level bigger than max mip level. MAXMIPLEVEL limits */
4137 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
4138 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4139 ret = IDirect3DTexture9_SetLOD(texture, 1);
4140 ok(ret == 2, "Got unexpected LOD %u.\n", ret);
4141 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[2], sizeof(*quads->v));
4142 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4144 /* Mipmapping OFF, LOD level bigger than max mip level. LOD level limits */
4145 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
4146 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4147 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAXMIPLEVEL, 2);
4148 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
4149 ret = IDirect3DTexture9_SetLOD(texture, 1);
4150 ok(ret == 1, "Got unexpected LOD %u.\n", ret);
4151 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[3], sizeof(*quads->v));
4152 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4154 hr = IDirect3DDevice9_EndScene(device);
4155 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
4157 /* Max Mip level 0-2 sample from the specified texture level, Max Mip
4158 * level 3 (> levels in texture) samples from the highest level in the
4159 * texture (level 2). */
4160 color = getPixelColor(device, 160, 360);
4161 ok(color == 0x0000ff00, "MaxMip 0, LOD 1, none mipfilter has color 0x%08x.\n", color);
4162 color = getPixelColor(device, 480, 360);
4163 ok(color == 0x000000ff, "MaxMip 1, LOD 2, point mipfilter has color 0x%08x.\n", color);
4164 color = getPixelColor(device, 480, 120);
4165 ok(color == 0x000000ff, "MaxMip 2, LOD 1, point mipfilter has color 0x%08x.\n", color);
4166 color = getPixelColor(device, 160, 120);
4167 ok(color == 0x0000ff00, "MaxMip 2, LOD 1, none mipfilter has color 0x%08x.\n", color);
4169 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4170 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
4172 IDirect3DTexture9_Release(texture);
4173 refcount = IDirect3DDevice9_Release(device);
4174 ok(!refcount, "Device has %u references left.\n", refcount);
4175 done:
4176 IDirect3D9_Release(d3d);
4177 DestroyWindow(window);
4180 static void release_buffer_test(void)
4182 IDirect3DVertexBuffer9 *vb;
4183 IDirect3DIndexBuffer9 *ib;
4184 IDirect3DDevice9 *device;
4185 IDirect3D9 *d3d;
4186 D3DCOLOR color;
4187 ULONG refcount;
4188 HWND window;
4189 HRESULT hr;
4190 BYTE *data;
4191 LONG ref;
4193 static const short indices[] = {3, 4, 5};
4194 static const struct
4196 struct vec3 position;
4197 DWORD diffuse;
4199 quad[] =
4201 {{-1.0f, -1.0f, 0.1f}, 0xffff0000},
4202 {{-1.0f, 1.0f, 0.1f}, 0xffff0000},
4203 {{ 1.0f, 1.0f, 0.1f}, 0xffff0000},
4205 {{-1.0f, -1.0f, 0.1f}, 0xff00ff00},
4206 {{-1.0f, 1.0f, 0.1f}, 0xff00ff00},
4207 {{ 1.0f, 1.0f, 0.1f}, 0xff00ff00},
4210 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
4211 0, 0, 640, 480, NULL, NULL, NULL, NULL);
4212 d3d = Direct3DCreate9(D3D_SDK_VERSION);
4213 ok(!!d3d, "Failed to create a D3D object.\n");
4214 if (!(device = create_device(d3d, window, window, TRUE)))
4216 skip("Failed to create a D3D device, skipping tests.\n");
4217 goto done;
4220 /* Index and vertex buffers should always be creatable */
4221 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0,
4222 D3DFVF_XYZ | D3DFVF_DIFFUSE, D3DPOOL_MANAGED, &vb, NULL);
4223 ok(SUCCEEDED(hr), "Failed to create vertex buffer, hr %#x.\n", hr);
4224 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
4225 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
4226 memcpy(data, quad, sizeof(quad));
4227 hr = IDirect3DVertexBuffer9_Unlock(vb);
4228 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
4230 hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0,
4231 D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
4232 ok(SUCCEEDED(hr), "Failed to create index buffer, hr %#x.\n", hr);
4233 hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
4234 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
4235 memcpy(data, indices, sizeof(indices));
4236 hr = IDirect3DIndexBuffer9_Unlock(ib);
4237 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
4239 hr = IDirect3DDevice9_SetIndices(device, ib);
4240 ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
4241 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad[0]));
4242 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
4243 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
4244 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4245 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
4246 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
4248 /* Now destroy the bound index buffer and draw again */
4249 ref = IDirect3DIndexBuffer9_Release(ib);
4250 ok(ref == 0, "Index Buffer reference count is %08d\n", ref);
4252 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
4253 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
4255 hr = IDirect3DDevice9_BeginScene(device);
4256 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
4257 /* Deliberately using minvertexindex = 0 and numVertices = 6 to prevent
4258 * D3D from making assumptions about the indices or vertices. */
4259 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 3, 3, 0, 1);
4260 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4261 hr = IDirect3DDevice9_EndScene(device);
4262 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
4264 color = getPixelColor(device, 160, 120);
4265 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 1), "Got unexpected color 0x%08x.\n", color);
4266 color = getPixelColor(device, 480, 360);
4267 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1), "Got unexpected color 0x%08x.\n", color);
4269 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4270 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4272 /* Index buffer was already destroyed as part of the test */
4273 IDirect3DVertexBuffer9_Release(vb);
4274 refcount = IDirect3DDevice9_Release(device);
4275 ok(!refcount, "Device has %u references left.\n", refcount);
4276 done:
4277 IDirect3D9_Release(d3d);
4278 DestroyWindow(window);
4281 static void float_texture_test(void)
4283 IDirect3DTexture9 *texture;
4284 IDirect3DDevice9 *device;
4285 D3DLOCKED_RECT lr;
4286 IDirect3D9 *d3d;
4287 ULONG refcount;
4288 float *data;
4289 DWORD color;
4290 HWND window;
4291 HRESULT hr;
4293 static const float quad[] =
4295 -1.0f, -1.0f, 0.1f, 0.0f, 0.0f,
4296 -1.0f, 1.0f, 0.1f, 0.0f, 1.0f,
4297 1.0f, -1.0f, 0.1f, 1.0f, 0.0f,
4298 1.0f, 1.0f, 0.1f, 1.0f, 1.0f,
4301 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
4302 0, 0, 640, 480, NULL, NULL, NULL, NULL);
4303 d3d = Direct3DCreate9(D3D_SDK_VERSION);
4304 ok(!!d3d, "Failed to create a D3D object.\n");
4305 if (!(device = create_device(d3d, window, window, TRUE)))
4307 skip("Failed to create a D3D device, skipping tests.\n");
4308 goto done;
4311 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
4312 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_R32F) != D3D_OK)
4314 skip("D3DFMT_R32F textures not supported\n");
4315 IDirect3DDevice9_Release(device);
4316 goto done;
4319 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_R32F, D3DPOOL_MANAGED, &texture, NULL);
4320 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
4322 memset(&lr, 0, sizeof(lr));
4323 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
4324 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
4325 data = lr.pBits;
4326 *data = 0.0;
4327 hr = IDirect3DTexture9_UnlockRect(texture, 0);
4328 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
4330 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
4331 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
4332 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
4333 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
4335 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
4336 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
4338 hr = IDirect3DDevice9_BeginScene(device);
4339 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
4340 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4341 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
4342 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4343 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4344 hr = IDirect3DDevice9_EndScene(device);
4345 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
4347 color = getPixelColor(device, 240, 320);
4348 ok(color == 0x0000ffff, "R32F with value 0.0 has color %08x, expected 0x0000ffff\n", color);
4350 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4351 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4353 IDirect3DTexture9_Release(texture);
4354 refcount = IDirect3DDevice9_Release(device);
4355 ok(!refcount, "Device has %u references left.\n", refcount);
4356 done:
4357 IDirect3D9_Release(d3d);
4358 DestroyWindow(window);
4361 static void g16r16_texture_test(void)
4363 IDirect3DTexture9 *texture;
4364 IDirect3DDevice9 *device;
4365 D3DLOCKED_RECT lr;
4366 IDirect3D9 *d3d;
4367 ULONG refcount;
4368 DWORD *data;
4369 DWORD color;
4370 HWND window;
4371 HRESULT hr;
4373 static const float quad[] =
4375 -1.0f, -1.0f, 0.1f, 0.0f, 0.0f,
4376 -1.0f, 1.0f, 0.1f, 0.0f, 1.0f,
4377 1.0f, -1.0f, 0.1f, 1.0f, 0.0f,
4378 1.0f, 1.0f, 0.1f, 1.0f, 1.0f,
4381 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
4382 0, 0, 640, 480, NULL, NULL, NULL, NULL);
4383 d3d = Direct3DCreate9(D3D_SDK_VERSION);
4384 ok(!!d3d, "Failed to create a D3D object.\n");
4385 if (!(device = create_device(d3d, window, window, TRUE)))
4387 skip("Failed to create a D3D device, skipping tests.\n");
4388 goto done;
4391 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
4392 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_G16R16) != D3D_OK)
4394 skip("D3DFMT_G16R16 textures not supported\n");
4395 IDirect3DDevice9_Release(device);
4396 goto done;
4399 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_G16R16, D3DPOOL_MANAGED, &texture, NULL);
4400 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
4402 memset(&lr, 0, sizeof(lr));
4403 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
4404 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
4405 data = lr.pBits;
4406 *data = 0x0f00f000;
4407 hr = IDirect3DTexture9_UnlockRect(texture, 0);
4408 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
4410 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
4411 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
4412 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
4413 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
4415 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
4416 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
4418 hr = IDirect3DDevice9_BeginScene(device);
4419 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
4420 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4421 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
4422 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
4423 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
4424 hr = IDirect3DDevice9_EndScene(device);
4425 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
4427 color = getPixelColor(device, 240, 320);
4428 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xf0, 0x0f, 0xff), 1),
4429 "D3DFMT_G16R16 with value 0x00ffff00 has color %08x, expected 0x00f00fff\n", color);
4431 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4432 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4434 IDirect3DTexture9_Release(texture);
4435 refcount = IDirect3DDevice9_Release(device);
4436 ok(!refcount, "Device has %u references left.\n", refcount);
4437 done:
4438 IDirect3D9_Release(d3d);
4439 DestroyWindow(window);
4442 static void check_rect(IDirect3DDevice9 *device, RECT r, const char *message)
4444 LONG x_coords[2][2] =
4446 {r.left - 1, r.left + 1},
4447 {r.right + 1, r.right - 1},
4449 LONG y_coords[2][2] =
4451 {r.top - 1, r.top + 1},
4452 {r.bottom + 1, r.bottom - 1}
4454 unsigned int i, j, x_side, y_side;
4456 for (i = 0; i < 2; ++i)
4458 for (j = 0; j < 2; ++j)
4460 for (x_side = 0; x_side < 2; ++x_side)
4462 for (y_side = 0; y_side < 2; ++y_side)
4464 unsigned int x = x_coords[i][x_side], y = y_coords[j][y_side];
4465 DWORD color;
4466 DWORD expected = (x_side == 1 && y_side == 1) ? 0x00ffffff : 0;
4468 color = getPixelColor(device, x, y);
4469 ok(color == expected, "%s: Pixel (%d, %d) has color %08x, expected %08x\n",
4470 message, x, y, color, expected);
4477 struct projected_textures_test_run
4479 const char *message;
4480 DWORD flags;
4481 IDirect3DVertexDeclaration9 *decl;
4482 BOOL vs, ps;
4483 RECT rect;
4486 static void projected_textures_test(IDirect3DDevice9 *device,
4487 struct projected_textures_test_run tests[4])
4489 unsigned int i;
4491 static const DWORD vertex_shader[] =
4493 0xfffe0101, /* vs_1_1 */
4494 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
4495 0x0000001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
4496 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
4497 0x00000001, 0xe00f0000, 0x90e40001, /* mov oT0, v1 */
4498 0x0000ffff /* end */
4500 static const DWORD pixel_shader[] =
4502 0xffff0103, /* ps_1_3 */
4503 0x00000042, 0xb00f0000, /* tex t0 */
4504 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
4505 0x0000ffff /* end */
4507 IDirect3DVertexShader9 *vs = NULL;
4508 IDirect3DPixelShader9 *ps = NULL;
4509 IDirect3D9 *d3d;
4510 D3DCAPS9 caps;
4511 HRESULT hr;
4513 IDirect3DDevice9_GetDirect3D(device, &d3d);
4514 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
4515 ok(SUCCEEDED(hr), "GetDeviceCaps failed (%08x)\n", hr);
4516 IDirect3D9_Release(d3d);
4518 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
4520 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader, &vs);
4521 ok(SUCCEEDED(hr), "CreateVertexShader failed (%08x)\n", hr);
4523 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 3))
4525 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader, &ps);
4526 ok(SUCCEEDED(hr), "CreatePixelShader failed (%08x)\n", hr);
4529 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0f, 0);
4530 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4532 hr = IDirect3DDevice9_BeginScene(device);
4533 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
4535 for (i = 0; i < 4; ++i)
4537 DWORD value = 0xdeadbeef;
4538 static const float proj_quads[] =
4540 -1.0f, -1.0f, 0.1f, 0.0f, 0.0f, 4.0f, 6.0f,
4541 -1.0f, 0.0f, 0.1f, 0.0f, 4.0f, 4.0f, 6.0f,
4542 0.0f, -1.0f, 0.1f, 4.0f, 0.0f, 4.0f, 6.0f,
4543 0.0f, 0.0f, 0.1f, 4.0f, 4.0f, 4.0f, 6.0f,
4545 0.0f, -1.0f, 0.1f, 0.0f, 0.0f, 4.0f, 6.0f,
4546 0.0f, 0.0f, 0.1f, 0.0f, 4.0f, 4.0f, 6.0f,
4547 1.0f, -1.0f, 0.1f, 4.0f, 0.0f, 4.0f, 6.0f,
4548 1.0f, 0.0f, 0.1f, 4.0f, 4.0f, 4.0f, 6.0f,
4550 -1.0f, 0.0f, 0.1f, 0.0f, 0.0f, 4.0f, 6.0f,
4551 -1.0f, 1.0f, 0.1f, 0.0f, 4.0f, 4.0f, 6.0f,
4552 0.0f, 0.0f, 0.1f, 4.0f, 0.0f, 4.0f, 6.0f,
4553 0.0f, 1.0f, 0.1f, 4.0f, 4.0f, 4.0f, 6.0f,
4555 0.0f, 0.0f, 0.1f, 0.0f, 0.0f, 4.0f, 6.0f,
4556 0.0f, 1.0f, 0.1f, 0.0f, 4.0f, 4.0f, 6.0f,
4557 1.0f, 0.0f, 0.1f, 4.0f, 0.0f, 4.0f, 6.0f,
4558 1.0f, 1.0f, 0.1f, 4.0f, 4.0f, 4.0f, 6.0f,
4561 if (tests[i].vs)
4563 if (!vs)
4565 skip("Vertex shaders not supported, skipping\n");
4566 continue;
4568 hr = IDirect3DDevice9_SetVertexShader(device, vs);
4570 else
4571 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
4572 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
4573 if (tests[i].ps)
4575 if (!ps)
4577 skip("Pixel shaders not supported, skipping\n");
4578 continue;
4580 hr = IDirect3DDevice9_SetPixelShader(device, ps);
4582 else
4583 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4584 ok(SUCCEEDED(hr), "SetPixelShader failed (%08x)\n", hr);
4586 hr = IDirect3DDevice9_SetVertexDeclaration(device, tests[i].decl);
4587 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
4589 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, tests[i].flags);
4590 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4591 hr = IDirect3DDevice9_GetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, &value);
4592 ok(SUCCEEDED(hr) && value == tests[i].flags,
4593 "GetTextureStageState returned: hr %08x, value %08x.\n", hr, value);
4595 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,
4596 &proj_quads[i * 4 * 7], 7 * sizeof(float));
4597 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4600 hr = IDirect3DDevice9_EndScene(device);
4601 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
4603 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
4604 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
4605 if (vs) IDirect3DVertexShader9_Release(vs);
4606 if (ps) IDirect3DPixelShader9_Release(ps);
4608 for (i = 0; i < 4; ++i)
4610 if ((!tests[i].vs || vs) && (!tests[i].ps || ps))
4611 check_rect(device, tests[i].rect, tests[i].message);
4614 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4615 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4618 static void texture_transform_flags_test(void)
4620 HRESULT hr;
4621 IDirect3D9 *d3d;
4622 D3DFORMAT fmt = D3DFMT_X8R8G8B8;
4623 D3DCAPS9 caps;
4624 IDirect3DTexture9 *texture = NULL;
4625 IDirect3DVolumeTexture9 *volume = NULL;
4626 IDirect3DDevice9 *device;
4627 unsigned int x, y, z;
4628 D3DLOCKED_RECT lr;
4629 D3DLOCKED_BOX lb;
4630 D3DCOLOR color;
4631 ULONG refcount;
4632 HWND window;
4633 UINT w, h;
4634 IDirect3DVertexDeclaration9 *decl, *decl2, *decl3, *decl4;
4636 static const D3DVERTEXELEMENT9 decl_elements[] = {
4637 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4638 {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
4639 D3DDECL_END()
4641 static const D3DVERTEXELEMENT9 decl_elements2[] = {
4642 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4643 {0, 12, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
4644 D3DDECL_END()
4646 static const D3DVERTEXELEMENT9 decl_elements3[] = {
4647 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4648 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
4649 D3DDECL_END()
4651 static const D3DVERTEXELEMENT9 decl_elements4[] = {
4652 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
4653 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
4654 D3DDECL_END()
4656 static const unsigned char proj_texdata[] = {0x00, 0x00, 0x00, 0x00,
4657 0x00, 0xff, 0x00, 0x00,
4658 0x00, 0x00, 0x00, 0x00,
4659 0x00, 0x00, 0x00, 0x00};
4660 static const D3DMATRIX identity =
4662 1.0f, 0.0f, 0.0f, 0.0f,
4663 0.0f, 1.0f, 0.0f, 0.0f,
4664 0.0f, 0.0f, 1.0f, 0.0f,
4665 0.0f, 0.0f, 0.0f, 1.0f,
4666 }}};
4668 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
4669 0, 0, 640, 480, NULL, NULL, NULL, NULL);
4670 d3d = Direct3DCreate9(D3D_SDK_VERSION);
4671 ok(!!d3d, "Failed to create a D3D object.\n");
4672 if (!(device = create_device(d3d, window, window, TRUE)))
4674 skip("Failed to create a D3D device, skipping tests.\n");
4675 goto done;
4678 memset(&lr, 0, sizeof(lr));
4679 memset(&lb, 0, sizeof(lb));
4680 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
4681 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16) == D3D_OK)
4682 fmt = D3DFMT_A16B16G16R16;
4684 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
4685 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
4686 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements2, &decl2);
4687 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
4688 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements3, &decl3);
4689 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
4690 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements4, &decl4);
4691 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
4692 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, FALSE);
4693 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_SRGBTEXTURE) returned %08x\n", hr);
4694 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
4695 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MAGFILTER) returned %08x\n", hr);
4696 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
4697 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MINFILTER) returned %08x\n", hr);
4698 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
4699 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_MIPFILTER) returned %08x\n", hr);
4700 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
4701 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSU) returned %08x\n", hr);
4702 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
4703 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSV) returned %08x\n", hr);
4704 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSW, D3DTADDRESS_CLAMP);
4705 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState(D3DSAMP_ADDRESSW) returned %08x\n", hr);
4706 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
4707 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState(D3DTSS_COLOROP) returned %08x\n", hr);
4708 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
4709 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState(D3DTSS_COLORARG1) returned %08x\n", hr);
4710 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
4711 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState(D3DRS_LIGHTING) returned %08x\n", hr);
4712 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
4713 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4715 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
4716 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps returned %08x\n", hr);
4717 w = min(1024, caps.MaxTextureWidth);
4718 h = min(1024, caps.MaxTextureHeight);
4719 hr = IDirect3DDevice9_CreateTexture(device, w, h, 1,
4720 0, fmt, D3DPOOL_MANAGED, &texture, NULL);
4721 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
4722 if (!texture)
4724 skip("Failed to create the test texture.\n");
4725 IDirect3DDevice9_Release(device);
4726 goto done;
4729 /* Unfortunately there is no easy way to set up a texture coordinate passthrough
4730 * in d3d fixed function pipeline, so create a texture that has a gradient from 0.0 to
4731 * 1.0 in red and green for the x and y coords
4733 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
4734 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect returned %08x\n", hr);
4735 for(y = 0; y < h; y++) {
4736 for(x = 0; x < w; x++) {
4737 double r_f = (double) y / (double) h;
4738 double g_f = (double) x / (double) w;
4739 if(fmt == D3DFMT_A16B16G16R16) {
4740 unsigned short r, g;
4741 unsigned short *dst = (unsigned short *) (((char *) lr.pBits) + y * lr.Pitch + x * 8);
4742 r = (unsigned short) (r_f * 65536.0);
4743 g = (unsigned short) (g_f * 65536.0);
4744 dst[0] = r;
4745 dst[1] = g;
4746 dst[2] = 0;
4747 dst[3] = 65535;
4748 } else {
4749 unsigned char *dst = ((unsigned char *) lr.pBits) + y * lr.Pitch + x * 4;
4750 unsigned char r = (unsigned char) (r_f * 255.0);
4751 unsigned char g = (unsigned char) (g_f * 255.0);
4752 dst[0] = 0;
4753 dst[1] = g;
4754 dst[2] = r;
4755 dst[3] = 255;
4759 hr = IDirect3DTexture9_UnlockRect(texture, 0);
4760 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect returned %08x\n", hr);
4761 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
4762 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
4764 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4765 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4766 hr = IDirect3DDevice9_BeginScene(device);
4767 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
4768 if(SUCCEEDED(hr))
4770 static const float quad1[] =
4772 -1.0f, -1.0f, 0.1f, 1.0f, 1.0f,
4773 -1.0f, 0.0f, 0.1f, 1.0f, 1.0f,
4774 0.0f, -1.0f, 0.1f, 1.0f, 1.0f,
4775 0.0f, 0.0f, 0.1f, 1.0f, 1.0f,
4777 static const float quad2[] =
4779 -1.0f, 0.0f, 0.1f, 1.0f, 1.0f,
4780 -1.0f, 1.0f, 0.1f, 1.0f, 1.0f,
4781 0.0f, 0.0f, 0.1f, 1.0f, 1.0f,
4782 0.0f, 1.0f, 0.1f, 1.0f, 1.0f,
4784 static const float quad3[] =
4786 0.0f, 0.0f, 0.1f, 0.5f, 0.5f,
4787 0.0f, 1.0f, 0.1f, 0.5f, 0.5f,
4788 1.0f, 0.0f, 0.1f, 0.5f, 0.5f,
4789 1.0f, 1.0f, 0.1f, 0.5f, 0.5f,
4791 static const float quad4[] =
4793 320.0f, 480.0f, 0.1f, 1.0f, 0.0f, 1.0f,
4794 320.0f, 240.0f, 0.1f, 1.0f, 0.0f, 1.0f,
4795 640.0f, 480.0f, 0.1f, 1.0f, 0.0f, 1.0f,
4796 640.0f, 240.0f, 0.1f, 1.0f, 0.0f, 1.0f,
4798 D3DMATRIX mat =
4800 0.0f, 0.0f, 0.0f, 0.0f,
4801 0.0f, 0.0f, 0.0f, 0.0f,
4802 0.0f, 0.0f, 0.0f, 0.0f,
4803 0.0f, 0.0f, 0.0f, 0.0f,
4804 }}};
4806 /* What happens with the texture matrix if D3DTSS_TEXTURETRANSFORMFLAGS is disabled? */
4807 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &mat);
4808 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4809 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
4810 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4812 /* What happens with transforms enabled? */
4813 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
4814 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4815 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
4816 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4818 /* What happens if 4 coords are used, but only 2 given ?*/
4819 U(mat).m[2][0] = 1.0f;
4820 U(mat).m[3][1] = 1.0f;
4821 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &mat);
4822 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4823 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4);
4824 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4825 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
4826 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4828 /* What happens with transformed geometry? This setup lead to 0/0 coords with untransformed
4829 * geometry. If the same applies to transformed vertices, the quad will be black, otherwise red,
4830 * due to the coords in the vertices. (turns out red, indeed)
4832 memset(&mat, 0, sizeof(mat));
4833 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &mat);
4834 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4835 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_TEX1);
4836 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4837 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
4838 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4839 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
4840 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4842 hr = IDirect3DDevice9_EndScene(device);
4843 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
4845 color = getPixelColor(device, 160, 360);
4846 ok(color_match(color, 0x00ffff00, 1), "quad 1 has color %08x, expected 0x00ffff00\n", color);
4847 color = getPixelColor(device, 160, 120);
4848 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
4849 color = getPixelColor(device, 480, 120);
4850 ok(color_match(color, 0x0000ff00, 1), "quad 3 has color %08x, expected 0x0000ff00\n", color);
4851 color = getPixelColor(device, 480, 360);
4852 ok(color_match(color, 0x00ff0000, 1), "quad 4 has color %08x, expected 0x00ff0000\n", color);
4853 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4854 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4856 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
4857 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
4859 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
4860 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
4861 hr = IDirect3DDevice9_BeginScene(device);
4862 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
4863 if(SUCCEEDED(hr))
4865 static const float quad1[] =
4867 -1.0f, -1.0f, 0.1f, 0.8f, 0.2f,
4868 -1.0f, 0.0f, 0.1f, 0.8f, 0.2f,
4869 0.0f, -1.0f, 0.1f, 0.8f, 0.2f,
4870 0.0f, 0.0f, 0.1f, 0.8f, 0.2f,
4872 static const float quad2[] =
4874 -1.0f, 0.0f, 0.1f, 0.5f, 1.0f,
4875 -1.0f, 1.0f, 0.1f, 0.5f, 1.0f,
4876 0.0f, 0.0f, 0.1f, 0.5f, 1.0f,
4877 0.0f, 1.0f, 0.1f, 0.5f, 1.0f,
4879 static const float quad3[] =
4881 0.0f, 0.0f, 0.1f, 0.5f, 1.0f,
4882 0.0f, 1.0f, 0.1f, 0.5f, 1.0f,
4883 1.0f, 0.0f, 0.1f, 0.5f, 1.0f,
4884 1.0f, 1.0f, 0.1f, 0.5f, 1.0f,
4886 static const float quad4[] =
4888 0.0f, -1.0f, 0.1f, 0.8f, 0.2f,
4889 0.0f, 0.0f, 0.1f, 0.8f, 0.2f,
4890 1.0f, -1.0f, 0.1f, 0.8f, 0.2f,
4891 1.0f, 0.0f, 0.1f, 0.8f, 0.2f,
4893 D3DMATRIX mat =
4895 0.0f, 0.0f, 0.0f, 0.0f,
4896 0.0f, 0.0f, 0.0f, 0.0f,
4897 0.0f, 1.0f, 0.0f, 0.0f,
4898 0.0f, 0.0f, 0.0f, 0.0f,
4899 }}};
4901 /* What happens to the default 1 in the 3rd coordinate if it is disabled? */
4902 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &mat);
4903 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4904 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
4905 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4907 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 5 * sizeof(float));
4908 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4910 /* D3DTFF_COUNT1 does not work on Nvidia drivers. It behaves like D3DTTFF_DISABLE. On ATI drivers
4911 * it behaves like COUNT2 because normal textures require 2 coords. */
4912 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
4913 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4914 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 5 * sizeof(float));
4915 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4917 /* Just to be sure, the same as quad2 above */
4918 memset(&mat, 0, sizeof(mat));
4919 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &mat);
4920 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
4921 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
4922 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4923 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 5 * sizeof(float));
4924 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4926 /* Now, what happens to the 2nd coordinate(that is disabled in the matrix) if it is not
4927 * used? And what happens to the first? */
4928 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
4929 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
4930 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
4931 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (%08x)\n", hr);
4933 hr = IDirect3DDevice9_EndScene(device);
4934 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
4936 color = getPixelColor(device, 160, 360);
4937 ok(color_match(color, 0x00ff0000, 1), "quad 1 has color %08x, expected 0x00ff0000\n", color);
4938 color = getPixelColor(device, 160, 120);
4939 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x0000000\n", color);
4940 color = getPixelColor(device, 480, 120);
4941 ok(color_match(color, 0x00ff8000, 1) || color == 0x00000000,
4942 "quad 3 has color %08x, expected 0x00ff8000\n", color);
4943 color = getPixelColor(device, 480, 360);
4944 ok(color_match(color, 0x0033cc00, 1) || color_match(color, 0x00ff0000, 1),
4945 "quad 4 has color %08x, expected 0x0033cc00\n", color);
4946 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
4947 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
4949 IDirect3DTexture9_Release(texture);
4951 /* Test projected textures, without any fancy matrices */
4952 hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, 0, D3DFMT_L8, D3DPOOL_MANAGED, &texture, NULL);
4953 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
4954 if (SUCCEEDED(hr))
4956 struct projected_textures_test_run projected_tests_1[4] =
4959 "D3DTTFF_COUNT4 | D3DTTFF_PROJECTED - bottom left",
4960 D3DTTFF_COUNT4 | D3DTTFF_PROJECTED,
4961 decl3,
4962 FALSE, TRUE,
4963 {120, 300, 240, 390},
4966 "D3DTTFF_COUNT3 | D3DTTFF_PROJECTED - bottom right",
4967 D3DTTFF_COUNT3 | D3DTTFF_PROJECTED,
4968 decl3,
4969 FALSE, TRUE,
4970 {400, 360, 480, 420},
4972 /* Try with some invalid values */
4974 "0xffffffff (draws like COUNT4 | PROJECTED) - top left",
4975 0xffffffff,
4976 decl3,
4977 FALSE, TRUE,
4978 {120, 60, 240, 150}
4981 "D3DTTFF_COUNT3 | D3DTTFF_PROJECTED (draws non-projected) - top right",
4982 D3DTTFF_COUNT3 | D3DTTFF_PROJECTED,
4983 decl4,
4984 FALSE, TRUE,
4985 {340, 210, 360, 225},
4988 struct projected_textures_test_run projected_tests_2[4] =
4991 "D3DTTFF_PROJECTED (like COUNT4 | PROJECTED, texcoord has 4 components) - bottom left",
4992 D3DTTFF_PROJECTED,
4993 decl3,
4994 FALSE, TRUE,
4995 {120, 300, 240, 390},
4998 "D3DTTFF_PROJECTED (like COUNT3 | PROJECTED, texcoord has only 3 components) - bottom right",
4999 D3DTTFF_PROJECTED,
5000 decl,
5001 FALSE, TRUE,
5002 {400, 360, 480, 420},
5005 "0xffffffff (like COUNT3 | PROJECTED, texcoord has only 3 components) - top left",
5006 0xffffffff,
5007 decl,
5008 FALSE, TRUE,
5009 {80, 120, 160, 180},
5012 "D3DTTFF_COUNT1 (draws non-projected) - top right",
5013 D3DTTFF_COUNT1,
5014 decl4,
5015 FALSE, TRUE,
5016 {340, 210, 360, 225},
5019 struct projected_textures_test_run projected_tests_3[4] =
5022 "D3DTTFF_COUNT3 | D3DTTFF_PROJECTED (like COUNT4 | PROJECTED) - bottom left",
5023 D3DTTFF_PROJECTED,
5024 decl3,
5025 TRUE, FALSE,
5026 {120, 300, 240, 390},
5029 "D3DTTFF_COUNT3 | D3DTTFF_PROJECTED (like COUNT4 | PROJECTED) - bottom right",
5030 D3DTTFF_COUNT3 | D3DTTFF_PROJECTED,
5031 decl3,
5032 TRUE, TRUE,
5033 {440, 300, 560, 390},
5036 "0xffffffff (like COUNT4 | PROJECTED) - top left",
5037 0xffffffff,
5038 decl3,
5039 TRUE, TRUE,
5040 {120, 60, 240, 150},
5043 "D3DTTFF_PROJECTED (like COUNT4 | PROJECTED) - top right",
5044 D3DTTFF_PROJECTED,
5045 decl3,
5046 FALSE, FALSE,
5047 {440, 60, 560, 150},
5051 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &identity);
5052 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
5054 hr = IDirect3DTexture9_LockRect(texture, 0, &lr, NULL, 0);
5055 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed with %08x\n", hr);
5056 for(x = 0; x < 4; x++) {
5057 memcpy(((BYTE *) lr.pBits) + lr.Pitch * x, proj_texdata + 4 * x, 4 * sizeof(proj_texdata[0]));
5059 hr = IDirect3DTexture9_UnlockRect(texture, 0);
5060 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed with %08x\n", hr);
5061 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
5062 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
5064 projected_textures_test(device, projected_tests_1);
5065 projected_textures_test(device, projected_tests_2);
5066 projected_textures_test(device, projected_tests_3);
5068 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
5069 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
5070 IDirect3DTexture9_Release(texture);
5073 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff203040, 0.0, 0);
5074 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5075 /* Use a smaller volume texture than the biggest possible size for memory and performance reasons
5076 * Thus watch out if sampling from texels between 0 and 1.
5078 hr = IDirect3DDevice9_CreateVolumeTexture(device, 32, 32, 32, 1, 0, fmt, D3DPOOL_MANAGED, &volume, 0);
5079 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL,
5080 "IDirect3DDevice9_CreateVolumeTexture failed with %08x\n", hr);
5081 if(!volume) {
5082 skip("Failed to create a volume texture\n");
5083 goto out;
5086 hr = IDirect3DVolumeTexture9_LockBox(volume, 0, &lb, NULL, 0);
5087 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_LockBox failed with %08x\n", hr);
5088 for(z = 0; z < 32; z++) {
5089 for(y = 0; y < 32; y++) {
5090 for(x = 0; x < 32; x++) {
5091 char size = (fmt == D3DFMT_A16B16G16R16 ? 8 : 4);
5092 void *mem = ((char *) lb.pBits) + y * lb.RowPitch + z * lb.SlicePitch + x * size;
5093 float r_f = (float) x / 31.0;
5094 float g_f = (float) y / 31.0;
5095 float b_f = (float) z / 31.0;
5097 if(fmt == D3DFMT_A16B16G16R16) {
5098 unsigned short *mem_s = mem;
5099 mem_s[0] = r_f * 65535.0;
5100 mem_s[1] = g_f * 65535.0;
5101 mem_s[2] = b_f * 65535.0;
5102 mem_s[3] = 65535;
5103 } else {
5104 unsigned char *mem_c = mem;
5105 mem_c[0] = b_f * 255.0;
5106 mem_c[1] = g_f * 255.0;
5107 mem_c[2] = r_f * 255.0;
5108 mem_c[3] = 255;
5113 hr = IDirect3DVolumeTexture9_UnlockBox(volume, 0);
5114 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
5116 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) volume);
5117 ok(hr == D3D_OK, "IDirect3DVolumeTexture9_UnlockBox failed with %08x\n", hr);
5119 hr = IDirect3DDevice9_BeginScene(device);
5120 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
5121 if(SUCCEEDED(hr))
5123 static const float quad1[] =
5125 -1.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5126 -1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5127 0.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5128 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5130 static const float quad2[] =
5132 -1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5133 -1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5134 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5135 0.0f, 1.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5137 static const float quad3[] =
5139 0.0f, 0.0f, 0.1f, 0.0f, 0.0f,
5140 0.0f, 1.0f, 0.1f, 0.0f, 0.0f,
5141 1.0f, 0.0f, 0.1f, 0.0f, 0.0f,
5142 1.0f, 1.0f, 0.1f, 0.0f, 0.0f,
5144 static const float quad4[] =
5146 0.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5147 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5148 1.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5149 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5151 D3DMATRIX mat =
5153 1.0f, 0.0f, 0.0f, 0.0f,
5154 0.0f, 0.0f, 1.0f, 0.0f,
5155 0.0f, 1.0f, 0.0f, 0.0f,
5156 0.0f, 0.0f, 0.0f, 1.0f,
5157 }}};
5158 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
5159 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
5161 /* Draw a quad with all 3 coords enabled. Nothing fancy. v and w are swapped, but have the same
5162 * values
5164 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &mat);
5165 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
5166 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
5167 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
5168 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
5169 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5171 /* Now disable the w coordinate. Does that change the input, or the output. The coordinates
5172 * are swapped by the matrix. If it changes the input, the v coord will be missing(green),
5173 * otherwise the w will be missing(blue).
5174 * turns out that on nvidia cards the blue color is missing, so it is an output modification.
5175 * On ATI cards the COUNT2 is ignored, and it behaves in the same way as COUNT3. */
5176 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
5177 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
5178 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
5179 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5181 /* default values? Set up the identity matrix, pass in 2 vertex coords, and enable 3 */
5182 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &identity);
5183 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
5184 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
5185 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
5186 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
5187 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
5188 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 5 * sizeof(float));
5189 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5191 /* D3DTTFF_COUNT1. Set a NULL matrix, and count1, pass in all values as 1.0. Nvidia has count1 ==
5192 * disable. ATI extends it up to the amount of values needed for the volume texture
5194 memset(&mat, 0, sizeof(mat));
5195 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &mat);
5196 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
5197 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT1);
5198 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
5199 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
5200 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
5201 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
5202 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5204 hr = IDirect3DDevice9_EndScene(device);
5205 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
5208 color = getPixelColor(device, 160, 360);
5209 ok(color == 0x00ffffff, "quad 1 has color %08x, expected 0x00ffffff\n", color);
5210 color = getPixelColor(device, 160, 120);
5211 ok(color == 0x00ffff00 /* NV*/ || color == 0x00ffffff /* ATI */,
5212 "quad 2 has color %08x, expected 0x00ffff00\n", color);
5213 color = getPixelColor(device, 480, 120);
5214 ok(color == 0x000000ff, "quad 3 has color %08x, expected 0x000000ff\n", color);
5215 color = getPixelColor(device, 480, 360);
5216 ok(color == 0x00ffffff || color == 0x0000ff00, "quad 4 has color %08x, expected 0x00ffffff\n", color);
5218 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5219 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5221 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff303030, 0.0, 0);
5222 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5223 hr = IDirect3DDevice9_BeginScene(device);
5224 ok(hr == D3D_OK, "IDirect3DDevice9_BeginScene failed with %08x\n", hr);
5225 if(SUCCEEDED(hr))
5227 static const float quad1[] =
5229 -1.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5230 -1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5231 0.0f, -1.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5232 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 1.0f,
5234 static const float quad2[] =
5236 -1.0f, 0.0f, 0.1f,
5237 -1.0f, 1.0f, 0.1f,
5238 0.0f, 0.0f, 0.1f,
5239 0.0f, 1.0f, 0.1f,
5241 static const float quad3[] =
5243 0.0f, 0.0f, 0.1f, 1.0f,
5244 0.0f, 1.0f, 0.1f, 1.0f,
5245 1.0f, 0.0f, 0.1f, 1.0f,
5246 1.0f, 1.0f, 0.1f, 1.0f,
5248 static const D3DMATRIX mat =
5250 0.0f, 0.0f, 0.0f, 0.0f,
5251 0.0f, 0.0f, 0.0f, 0.0f,
5252 0.0f, 0.0f, 0.0f, 0.0f,
5253 0.0f, 1.0f, 0.0f, 0.0f,
5254 }}};
5255 static const D3DMATRIX mat2 =
5257 0.0f, 0.0f, 0.0f, 1.0f,
5258 1.0f, 0.0f, 0.0f, 0.0f,
5259 0.0f, 1.0f, 0.0f, 0.0f,
5260 0.0f, 0.0f, 1.0f, 0.0f,
5261 }}};
5262 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
5263 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
5265 /* Default values? 4 coords used, 3 passed. What happens to the 4th?
5266 * Use COUNT3 because newer Nvidia drivers return black when there are more (output) coords
5267 * than being used by the texture(volume tex -> 3). Again, as shown in earlier test the COUNTx
5268 * affects the post-transformation output, so COUNT3 plus the matrix above is OK for testing the
5269 * 4th *input* coordinate.
5271 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &mat);
5272 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
5273 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3);
5274 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed (%08x)\n", hr);
5275 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
5276 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5278 /* None passed */
5279 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &identity);
5280 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
5281 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5282 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
5283 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
5284 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5286 /* 4 used, 1 passed */
5287 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl2);
5288 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
5289 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE0, &mat2);
5290 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed with %08x\n", hr);
5291 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 4 * sizeof(float));
5292 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
5294 hr = IDirect3DDevice9_EndScene(device);
5295 ok(hr == D3D_OK, "IDirect3DDevice9_EndScene failed with %08x\n", hr);
5297 color = getPixelColor(device, 160, 360);
5298 ok(color == 0x0000ff00, "quad 1 has color %08x, expected 0x0000ff00\n", color);
5299 color = getPixelColor(device, 160, 120);
5300 ok(color == 0x00000000, "quad 2 has color %08x, expected 0x00000000\n", color);
5301 color = getPixelColor(device, 480, 120);
5302 ok(color == 0x00ff0000, "quad 3 has color %08x, expected 0x00ff0000\n", color);
5303 /* Quad4: unused */
5305 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5306 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5308 IDirect3DVolumeTexture9_Release(volume);
5310 out:
5311 IDirect3DVertexDeclaration9_Release(decl);
5312 IDirect3DVertexDeclaration9_Release(decl2);
5313 IDirect3DVertexDeclaration9_Release(decl3);
5314 IDirect3DVertexDeclaration9_Release(decl4);
5315 refcount = IDirect3DDevice9_Release(device);
5316 ok(!refcount, "Device has %u references left.\n", refcount);
5317 done:
5318 IDirect3D9_Release(d3d);
5319 DestroyWindow(window);
5322 static void texdepth_test(void)
5324 IDirect3DPixelShader9 *shader;
5325 IDirect3DDevice9 *device;
5326 IDirect3D9 *d3d;
5327 ULONG refcount;
5328 D3DCAPS9 caps;
5329 DWORD color;
5330 HWND window;
5331 HRESULT hr;
5333 static const float texdepth_test_data1[] = { 0.25f, 2.0f, 0.0f, 0.0f};
5334 static const float texdepth_test_data2[] = { 0.25f, 0.5f, 0.0f, 0.0f};
5335 static const float texdepth_test_data3[] = {-1.00f, 0.1f, 0.0f, 0.0f};
5336 static const float texdepth_test_data4[] = {-0.25f, -0.5f, 0.0f, 0.0f};
5337 static const float texdepth_test_data5[] = { 1.00f, -0.1f, 0.0f, 0.0f};
5338 static const float texdepth_test_data6[] = { 1.00f, 0.5f, 0.0f, 0.0f};
5339 static const float texdepth_test_data7[] = { 0.50f, 0.0f, 0.0f, 0.0f};
5340 static const DWORD shader_code[] =
5342 0xffff0104, /* ps_1_4 */
5343 0x00000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c1, 0, 0, 1, 1 */
5344 0x00000001, 0x800f0005, 0xa0e40000, /* mov r5, c0 */
5345 0x0000fffd, /* phase */
5346 0x00000057, 0x800f0005, /* texdepth r5 */
5347 0x00000001, 0x800f0000, 0xa0e40001, /* mov r0, c1 */
5348 0x0000ffff /* end */
5350 static const float vertex[] =
5352 -1.0f, -1.0f, 0.0f,
5353 -1.0f, 1.0f, 0.0f,
5354 1.0f, -1.0f, 1.0f,
5355 1.0f, 1.0f, 1.0f,
5358 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
5359 0, 0, 640, 480, NULL, NULL, NULL, NULL);
5360 d3d = Direct3DCreate9(D3D_SDK_VERSION);
5361 ok(!!d3d, "Failed to create a D3D object.\n");
5362 if (!(device = create_device(d3d, window, window, TRUE)))
5364 skip("Failed to create a D3D device, skipping tests.\n");
5365 goto done;
5368 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
5369 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
5370 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 4))
5372 skip("No ps_1_4 support, skipping tests.\n");
5373 IDirect3DDevice9_Release(device);
5374 goto done;
5377 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
5378 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5380 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffff00, 0.0, 0);
5381 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5382 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
5383 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
5384 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
5385 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
5386 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
5387 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
5388 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
5389 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
5390 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
5391 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF returned %#x.\n", hr);
5393 /* Fill the depth buffer with a gradient */
5394 hr = IDirect3DDevice9_BeginScene(device);
5395 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5396 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
5397 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5398 hr = IDirect3DDevice9_EndScene(device);
5399 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5401 /* Now perform the actual tests. Same geometry, but with the shader */
5402 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_GREATER);
5403 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
5404 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
5405 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
5406 hr = IDirect3DDevice9_SetPixelShader(device, shader);
5407 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed (%08x)\n", hr);
5409 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data1, 1);
5410 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5411 hr = IDirect3DDevice9_BeginScene(device);
5412 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5413 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
5414 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5415 hr = IDirect3DDevice9_EndScene(device);
5416 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5418 color = getPixelColor(device, 158, 240);
5419 ok(color == 0x000000ff, "Pixel 158(25%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
5420 color = getPixelColor(device, 162, 240);
5421 ok(color == 0x00ffffff, "Pixel 158(25%% + 2 pixel) has color %08x, expected 0x00ffffff\n", color);
5423 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5424 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5426 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
5427 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
5429 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data2, 1);
5430 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5431 hr = IDirect3DDevice9_BeginScene(device);
5432 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5433 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
5434 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5435 hr = IDirect3DDevice9_EndScene(device);
5436 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5438 color = getPixelColor(device, 318, 240);
5439 ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
5440 color = getPixelColor(device, 322, 240);
5441 ok(color == 0x00ffff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
5443 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5444 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5446 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
5447 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
5449 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data3, 1);
5450 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5451 hr = IDirect3DDevice9_BeginScene(device);
5452 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5453 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
5454 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5455 hr = IDirect3DDevice9_EndScene(device);
5456 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5458 color = getPixelColor(device, 1, 240);
5459 ok(color == 0x00ff0000, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ff0000\n", color);
5461 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5462 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5464 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
5465 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
5467 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data4, 1);
5468 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5469 hr = IDirect3DDevice9_BeginScene(device);
5470 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5471 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
5472 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5473 hr = IDirect3DDevice9_EndScene(device);
5474 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5476 color = getPixelColor(device, 318, 240);
5477 ok(color == 0x000000ff, "Pixel 318(50%% - 2 pixel) has color %08x, expected 0x000000ff\n", color);
5478 color = getPixelColor(device, 322, 240);
5479 ok(color == 0x0000ff00, "Pixel 322(50%% + 2 pixel) has color %08x, expected 0x0000ff00\n", color);
5481 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5482 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5484 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
5485 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
5487 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data5, 1);
5488 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5489 hr = IDirect3DDevice9_BeginScene(device);
5490 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5491 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
5492 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5493 hr = IDirect3DDevice9_EndScene(device);
5494 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5496 color = getPixelColor(device, 1, 240);
5497 ok(color == 0x00ffff00, "Pixel 1(0%% + 2 pixel) has color %08x, expected 0x00ffff00\n", color);
5499 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5500 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5502 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
5503 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
5505 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data6, 1);
5506 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5507 hr = IDirect3DDevice9_BeginScene(device);
5508 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5509 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
5510 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5511 hr = IDirect3DDevice9_EndScene(device);
5512 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5514 color = getPixelColor(device, 638, 240);
5515 ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
5517 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5518 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5520 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
5521 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
5523 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, texdepth_test_data7, 1);
5524 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
5525 hr = IDirect3DDevice9_BeginScene(device);
5526 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5527 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 3 * sizeof(float));
5528 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5529 hr = IDirect3DDevice9_EndScene(device);
5530 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5532 color = getPixelColor(device, 638, 240);
5533 ok(color == 0x000000ff, "Pixel 638(100%% + 2 pixel) has color %08x, expected 0x000000ff\n", color);
5535 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5536 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5538 IDirect3DPixelShader9_Release(shader);
5539 refcount = IDirect3DDevice9_Release(device);
5540 ok(!refcount, "Device has %u references left.\n", refcount);
5541 done:
5542 IDirect3D9_Release(d3d);
5543 DestroyWindow(window);
5546 static void texkill_test(void)
5548 IDirect3DPixelShader9 *shader;
5549 IDirect3DDevice9 *device;
5550 IDirect3D9 *d3d;
5551 ULONG refcount;
5552 D3DCAPS9 caps;
5553 DWORD color;
5554 HWND window;
5555 HRESULT hr;
5557 static const float vertex[] =
5559 /* bottom top right left */
5560 -1.0f, -1.0f, 1.0f, -0.1f, 0.9f, 0.9f, -0.1f,
5561 -1.0f, 1.0f, 1.0f, -0.1f, 0.9f, -0.1f, 0.9f,
5562 1.0f, -1.0f, 0.0f, 0.9f, -0.1f, 0.9f, -0.1f,
5563 1.0f, 1.0f, 0.0f, 0.9f, -0.1f, -0.1f, 0.9f,
5565 static const DWORD shader_code_11[] =
5567 0xffff0101, /* ps_1_1 */
5568 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 1.0, 0.0, 0.0, 1.0 */
5569 0x00000041, 0xb00f0000, /* texkill t0 */
5570 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
5571 0x0000ffff /* end */
5573 static const DWORD shader_code_20[] =
5575 0xffff0200, /* ps_2_0 */
5576 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
5577 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x3f800000, 0x3f800000, /* def c0, 0.0, 0.0, 1.0, 1.0 */
5578 0x01000041, 0xb00f0000, /* texkill t0 */
5579 0x02000001, 0x800f0800, 0xa0e40000, /* mov oC0, c0 */
5580 0x0000ffff /* end */
5583 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
5584 0, 0, 640, 480, NULL, NULL, NULL, NULL);
5585 d3d = Direct3DCreate9(D3D_SDK_VERSION);
5586 ok(!!d3d, "Failed to create a D3D object.\n");
5587 if (!(device = create_device(d3d, window, window, TRUE)))
5589 skip("Failed to create a D3D device, skipping tests.\n");
5590 goto done;
5593 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
5594 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
5595 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 1))
5597 skip("No ps_1_1 support, skipping tests.\n");
5598 IDirect3DDevice9_Release(device);
5599 goto done;
5602 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
5603 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5604 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader);
5605 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5607 hr = IDirect3DDevice9_SetPixelShader(device, shader);
5608 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5609 hr = IDirect3DDevice9_BeginScene(device);
5610 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5611 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEXCOORDSIZE4(0) | D3DFVF_TEX1);
5612 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
5613 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
5614 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5615 hr = IDirect3DDevice9_EndScene(device);
5616 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5618 color = getPixelColor(device, 63, 46);
5619 ok(color == 0x0000ff00, "Pixel 63/46 has color %08x, expected 0x0000ff00\n", color);
5620 color = getPixelColor(device, 66, 46);
5621 ok(color == 0x0000ff00, "Pixel 66/64 has color %08x, expected 0x0000ff00\n", color);
5622 color = getPixelColor(device, 63, 49);
5623 ok(color == 0x0000ff00, "Pixel 63/49 has color %08x, expected 0x0000ff00\n", color);
5624 color = getPixelColor(device, 66, 49);
5625 ok(color == 0x00ff0000, "Pixel 66/49 has color %08x, expected 0x00ff0000\n", color);
5627 color = getPixelColor(device, 578, 46);
5628 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
5629 color = getPixelColor(device, 575, 46);
5630 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
5631 color = getPixelColor(device, 578, 49);
5632 ok(color == 0x0000ff00, "Pixel 578/49 has color %08x, expected 0x0000ff00\n", color);
5633 color = getPixelColor(device, 575, 49);
5634 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
5636 color = getPixelColor(device, 63, 430);
5637 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
5638 color = getPixelColor(device, 63, 433);
5639 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
5640 color = getPixelColor(device, 66, 433);
5641 ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
5642 color = getPixelColor(device, 66, 430);
5643 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
5645 color = getPixelColor(device, 578, 430);
5646 ok(color == 0x0000ff00, "Pixel 578/46 has color %08x, expected 0x0000ff00\n", color);
5647 color = getPixelColor(device, 578, 433);
5648 ok(color == 0x0000ff00, "Pixel 575/64 has color %08x, expected 0x0000ff00\n", color);
5649 color = getPixelColor(device, 575, 433);
5650 ok(color == 0x00ff0000, "Pixel 578/49 has color %08x, expected 0x00ff0000\n", color);
5651 color = getPixelColor(device, 575, 430);
5652 ok(color == 0x00ff0000, "Pixel 575/49 has color %08x, expected 0x00ff0000\n", color);
5654 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5655 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5657 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
5658 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5659 IDirect3DPixelShader9_Release(shader);
5661 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 0.0, 0);
5662 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
5663 if (FAILED(IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader)))
5665 skip("Failed to create 2.0 test shader, most likely not supported.\n");
5666 IDirect3DDevice9_Release(device);
5667 goto done;
5670 hr = IDirect3DDevice9_SetPixelShader(device, shader);
5671 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
5672 hr = IDirect3DDevice9_BeginScene(device);
5673 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5674 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, vertex, 7 * sizeof(float));
5675 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5676 hr = IDirect3DDevice9_EndScene(device);
5677 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5679 color = getPixelColor(device, 63, 46);
5680 ok(color == 0x00ffff00, "Pixel 63/46 has color %08x, expected 0x00ffff00\n", color);
5681 color = getPixelColor(device, 66, 46);
5682 ok(color == 0x00ffff00, "Pixel 66/64 has color %08x, expected 0x00ffff00\n", color);
5683 color = getPixelColor(device, 63, 49);
5684 ok(color == 0x00ffff00, "Pixel 63/49 has color %08x, expected 0x00ffff00\n", color);
5685 color = getPixelColor(device, 66, 49);
5686 ok(color == 0x000000ff, "Pixel 66/49 has color %08x, expected 0x000000ff\n", color);
5688 color = getPixelColor(device, 578, 46);
5689 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
5690 color = getPixelColor(device, 575, 46);
5691 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
5692 color = getPixelColor(device, 578, 49);
5693 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
5694 color = getPixelColor(device, 575, 49);
5695 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
5697 color = getPixelColor(device, 63, 430);
5698 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
5699 color = getPixelColor(device, 63, 433);
5700 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
5701 color = getPixelColor(device, 66, 433);
5702 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
5703 color = getPixelColor(device, 66, 430);
5704 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
5706 color = getPixelColor(device, 578, 430);
5707 ok(color == 0x00ffff00, "Pixel 578/46 has color %08x, expected 0x00ffff00\n", color);
5708 color = getPixelColor(device, 578, 433);
5709 ok(color == 0x00ffff00, "Pixel 575/64 has color %08x, expected 0x00ffff00\n", color);
5710 color = getPixelColor(device, 575, 433);
5711 ok(color == 0x00ffff00, "Pixel 578/49 has color %08x, expected 0x00ffff00\n", color);
5712 color = getPixelColor(device, 575, 430);
5713 ok(color == 0x000000ff, "Pixel 575/49 has color %08x, expected 0x000000ff\n", color);
5715 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5716 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5718 IDirect3DPixelShader9_Release(shader);
5719 refcount = IDirect3DDevice9_Release(device);
5720 ok(!refcount, "Device has %u references left.\n", refcount);
5721 done:
5722 IDirect3D9_Release(d3d);
5723 DestroyWindow(window);
5726 static void autogen_mipmap_test(void)
5728 IDirect3DTexture9 *texture = NULL;
5729 IDirect3DSurface9 *surface;
5730 IDirect3DDevice9 *device;
5731 unsigned int x, y;
5732 D3DLOCKED_RECT lr;
5733 IDirect3D9 *d3d;
5734 D3DCOLOR color;
5735 ULONG refcount;
5736 HWND window;
5737 HRESULT hr;
5739 static const RECT r1 = {256, 256, 512, 512};
5740 static const RECT r2 = {512, 256, 768, 512};
5741 static const RECT r3 = {256, 512, 512, 768};
5742 static const RECT r4 = {512, 512, 768, 768};
5743 static const float quad[] =
5745 -0.5f, -0.5f, 0.1f, 0.0f, 0.0f,
5746 -0.5f, 0.5f, 0.1f, 0.0f, 1.0f,
5747 0.5f, -0.5f, 0.1f, 1.0f, 0.0f,
5748 0.5f, 0.5f, 0.1f, 1.0f, 1.0f,
5751 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
5752 0, 0, 640, 480, NULL, NULL, NULL, NULL);
5753 d3d = Direct3DCreate9(D3D_SDK_VERSION);
5754 ok(!!d3d, "Failed to create a D3D object.\n");
5755 if (!(device = create_device(d3d, window, window, TRUE)))
5757 skip("Failed to create a D3D device, skipping tests.\n");
5758 goto done;
5761 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
5762 D3DFMT_X8R8G8B8, D3DUSAGE_AUTOGENMIPMAP, D3DRTYPE_TEXTURE, D3DFMT_X8R8G8B8) != D3D_OK)
5764 skip("No autogenmipmap support.\n");
5765 IDirect3DDevice9_Release(device);
5766 goto done;
5769 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffff00, 1.0f, 0);
5770 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5772 /* Make the mipmap big, so that a smaller mipmap is used
5774 hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 0, D3DUSAGE_AUTOGENMIPMAP,
5775 D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, 0);
5776 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture returned %08x\n", hr);
5778 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
5779 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel returned %08x\n", hr);
5780 memset(&lr, 0, sizeof(lr));
5781 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
5782 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect returned %08x\n", hr);
5783 for(y = 0; y < 1024; y++) {
5784 for(x = 0; x < 1024; x++) {
5785 DWORD *dst = (DWORD *) (((BYTE *) lr.pBits) + y * lr.Pitch + x * 4);
5786 POINT pt;
5788 pt.x = x;
5789 pt.y = y;
5790 if(PtInRect(&r1, pt)) {
5791 *dst = 0xffff0000;
5792 } else if(PtInRect(&r2, pt)) {
5793 *dst = 0xff00ff00;
5794 } else if(PtInRect(&r3, pt)) {
5795 *dst = 0xff0000ff;
5796 } else if(PtInRect(&r4, pt)) {
5797 *dst = 0xff000000;
5798 } else {
5799 *dst = 0xffffffff;
5803 hr = IDirect3DSurface9_UnlockRect(surface);
5804 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect returned %08x\n", hr);
5805 IDirect3DSurface9_Release(surface);
5807 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
5808 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture returned %08x\n", hr);
5809 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
5810 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed with %08x\n", hr);
5811 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
5812 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
5814 hr = IDirect3DDevice9_BeginScene(device);
5815 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5816 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
5817 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
5818 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
5819 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5820 hr = IDirect3DDevice9_EndScene(device);
5821 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
5822 IDirect3DTexture9_Release(texture);
5824 color = getPixelColor(device, 200, 200);
5825 ok(color == 0x00ffffff, "pixel 200/200 has color %08x, expected 0x00ffffff\n", color);
5826 color = getPixelColor(device, 280, 200);
5827 ok(color == 0x000000ff, "pixel 280/200 has color %08x, expected 0x000000ff\n", color);
5828 color = getPixelColor(device, 360, 200);
5829 ok(color == 0x00000000, "pixel 360/200 has color %08x, expected 0x00000000\n", color);
5830 color = getPixelColor(device, 440, 200);
5831 ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
5832 color = getPixelColor(device, 200, 270);
5833 ok(color == 0x00ffffff, "pixel 200/270 has color %08x, expected 0x00ffffff\n", color);
5834 color = getPixelColor(device, 280, 270);
5835 ok(color == 0x00ff0000, "pixel 280/270 has color %08x, expected 0x00ff0000\n", color);
5836 color = getPixelColor(device, 360, 270);
5837 ok(color == 0x0000ff00, "pixel 360/270 has color %08x, expected 0x0000ff00\n", color);
5838 color = getPixelColor(device, 440, 270);
5839 ok(color == 0x00ffffff, "pixel 440/200 has color %08x, expected 0x00ffffff\n", color);
5840 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
5841 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
5843 refcount = IDirect3DDevice9_Release(device);
5844 ok(!refcount, "Device has %u references left.\n", refcount);
5845 done:
5846 IDirect3D9_Release(d3d);
5847 DestroyWindow(window);
5850 static void test_constant_clamp_vs(void)
5852 IDirect3DVertexShader9 *shader_11, *shader_11_2, *shader_20, *shader_20_2;
5853 IDirect3DVertexDeclaration9 *decl;
5854 IDirect3DDevice9 *device;
5855 IDirect3D9 *d3d;
5856 D3DCOLOR color;
5857 ULONG refcount;
5858 D3DCAPS9 caps;
5859 HWND window;
5860 HRESULT hr;
5862 static const DWORD shader_code_11[] =
5864 0xfffe0101, /* vs_1_1 */
5865 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5866 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
5867 0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
5868 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5869 0x0000ffff /* end */
5871 static const DWORD shader_code_11_2[] =
5873 0xfffe0101, /* vs_1_1 */
5874 0x00000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000, /* dcl ... */
5875 0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* dcl ... */
5876 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5877 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
5878 0x00000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
5879 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5880 0x0000ffff /* end */
5882 static const DWORD shader_code_20[] =
5884 0xfffe0200, /* vs_2_0 */
5885 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5886 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
5887 0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
5888 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5889 0x0000ffff /* end */
5891 static const DWORD shader_code_20_2[] =
5893 0xfffe0200, /* vs_2_0 */
5894 0x05000051, 0xa00f0001, 0x3fa00000, 0xbf000000, 0xbfc00000, 0x3f800000,
5895 0x05000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000,
5896 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
5897 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
5898 0x03000002, 0xd00f0000, 0x80e40001, 0xa0e40002, /* add oD0, r1, c2 */
5899 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
5900 0x0000ffff /* end */
5902 static const D3DVERTEXELEMENT9 decl_elements[] =
5904 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
5905 D3DDECL_END()
5907 static const float quad1[] =
5909 -1.0f, -1.0f, 0.1f,
5910 -1.0f, 0.0f, 0.1f,
5911 0.0f, -1.0f, 0.1f,
5912 0.0f, 0.0f, 0.1f,
5914 static const float quad2[] =
5916 0.0f, -1.0f, 0.1f,
5917 0.0f, 0.0f, 0.1f,
5918 1.0f, -1.0f, 0.1f,
5919 1.0f, 0.0f, 0.1f,
5921 static const float quad3[] =
5923 0.0f, 0.0f, 0.1f,
5924 0.0f, 1.0f, 0.1f,
5925 1.0f, 0.0f, 0.1f,
5926 1.0f, 1.0f, 0.1f,
5928 static const float quad4[] =
5930 -1.0f, 0.0f, 0.1f,
5931 -1.0f, 1.0f, 0.1f,
5932 0.0f, 0.0f, 0.1f,
5933 0.0f, 1.0f, 0.1f,
5935 static const float test_data_c1[4] = { 1.25f, -0.50f, -1.50f, 1.0f};
5936 static const float test_data_c2[4] = {-0.50f, 1.25f, 2.00f, 1.0f};
5938 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
5939 0, 0, 640, 480, NULL, NULL, NULL, NULL);
5940 d3d = Direct3DCreate9(D3D_SDK_VERSION);
5941 ok(!!d3d, "Failed to create a D3D object.\n");
5942 if (!(device = create_device(d3d, window, window, TRUE)))
5944 skip("Failed to create a D3D device, skipping tests.\n");
5945 goto done;
5948 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
5949 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
5950 if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1))
5952 skip("No vs_1_1 support, skipping tests.\n");
5953 IDirect3DDevice9_Release(device);
5954 goto done;
5957 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
5958 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
5960 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11, &shader_11);
5961 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5962 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_11_2, &shader_11_2);
5963 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
5964 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20, &shader_20);
5965 if(FAILED(hr)) shader_20 = NULL;
5966 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code_20_2, &shader_20_2);
5967 if(FAILED(hr)) shader_20_2 = NULL;
5968 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
5969 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
5971 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, test_data_c1, 1);
5972 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
5973 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, test_data_c2, 1);
5974 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF returned %08x\n", hr);
5975 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
5976 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
5978 hr = IDirect3DDevice9_BeginScene(device);
5979 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
5981 hr = IDirect3DDevice9_SetVertexShader(device, shader_11);
5982 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
5983 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
5984 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5986 hr = IDirect3DDevice9_SetVertexShader(device, shader_11_2);
5987 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
5988 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
5989 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5991 if (shader_20)
5993 hr = IDirect3DDevice9_SetVertexShader(device, shader_20);
5994 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
5995 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
5996 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
5999 if (shader_20_2)
6001 hr = IDirect3DDevice9_SetVertexShader(device, shader_20_2);
6002 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
6003 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
6004 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6007 hr = IDirect3DDevice9_EndScene(device);
6008 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6010 color = getPixelColor(device, 160, 360);
6011 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
6012 "quad 1 has color %08x, expected 0x00bfbf80\n", color);
6013 color = getPixelColor(device, 480, 360);
6014 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
6015 "quad 2 has color %08x, expected 0x00bfbf80\n", color);
6016 if(shader_20) {
6017 color = getPixelColor(device, 480, 120);
6018 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
6019 "quad 3 has color %08x, expected 0x00bfbf80\n", color);
6021 if(shader_20_2) {
6022 color = getPixelColor(device, 160, 120);
6023 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
6024 "quad 4 has color %08x, expected 0x00bfbf80\n", color);
6026 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6027 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6029 IDirect3DVertexDeclaration9_Release(decl);
6030 if(shader_20_2) IDirect3DVertexShader9_Release(shader_20_2);
6031 if(shader_20) IDirect3DVertexShader9_Release(shader_20);
6032 IDirect3DVertexShader9_Release(shader_11_2);
6033 IDirect3DVertexShader9_Release(shader_11);
6034 refcount = IDirect3DDevice9_Release(device);
6035 ok(!refcount, "Device has %u references left.\n", refcount);
6036 done:
6037 IDirect3D9_Release(d3d);
6038 DestroyWindow(window);
6041 static void constant_clamp_ps_test(void)
6043 IDirect3DPixelShader9 *shader_11, *shader_12, *shader_14, *shader_20;
6044 IDirect3DDevice9 *device;
6045 IDirect3D9 *d3d;
6046 ULONG refcount;
6047 D3DCAPS9 caps;
6048 DWORD color;
6049 HWND window;
6050 HRESULT hr;
6052 static const DWORD shader_code_11[] =
6054 0xffff0101, /* ps_1_1 */
6055 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
6056 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
6057 0x0000ffff /* end */
6059 static const DWORD shader_code_12[] =
6061 0xffff0102, /* ps_1_2 */
6062 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
6063 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
6064 0x0000ffff /* end */
6066 /* Skip 1.3 shaders because we have only 4 quads (ok, could make them
6067 * smaller if needed). 1.2 and 1.4 shaders behave the same, so it's
6068 * unlikely that 1.3 shaders are different. During development of this
6069 * test, 1.3 shaders were verified too. */
6070 static const DWORD shader_code_14[] =
6072 0xffff0104, /* ps_1_4 */
6073 /* Try to make one constant local. It gets clamped too, although the
6074 * binary contains the bigger numbers. */
6075 0x00000051, 0xa00f0002, 0xbf000000, 0x3fa00000, 0x40000000, 0x3f800000, /* def c2, -0.5, 1.25, 2, 1 */
6076 0x00000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
6077 0x00000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
6078 0x0000ffff /* end */
6080 static const DWORD shader_code_20[] =
6082 0xffff0200, /* ps_2_0 */
6083 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
6084 0x03000002, 0x800f0000, 0x80e40001, 0xa0e40002, /* add r0, r1, c2 */
6085 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
6086 0x0000ffff /* end */
6088 static const float quad1[] =
6090 -1.0f, -1.0f, 0.1f,
6091 -1.0f, 0.0f, 0.1f,
6092 0.0f, -1.0f, 0.1f,
6093 0.0f, 0.0f, 0.1f,
6095 static const float quad2[] =
6097 0.0f, -1.0f, 0.1f,
6098 0.0f, 0.0f, 0.1f,
6099 1.0f, -1.0f, 0.1f,
6100 1.0f, 0.0f, 0.1f,
6102 static const float quad3[] =
6104 0.0f, 0.0f, 0.1f,
6105 0.0f, 1.0f, 0.1f,
6106 1.0f, 0.0f, 0.1f,
6107 1.0f, 1.0f, 0.1f,
6109 static const float quad4[] =
6111 -1.0f, 0.0f, 0.1f,
6112 -1.0f, 1.0f, 0.1f,
6113 0.0f, 0.0f, 0.1f,
6114 0.0f, 1.0f, 0.1f,
6116 static const float test_data_c1[4] = { 1.25f, -0.50f, -1.50f, 1.0f};
6117 static const float test_data_c2[4] = {-0.50f, 1.25f, 2.00f, 1.0f};
6119 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
6120 0, 0, 640, 480, NULL, NULL, NULL, NULL);
6121 d3d = Direct3DCreate9(D3D_SDK_VERSION);
6122 ok(!!d3d, "Failed to create a D3D object.\n");
6123 if (!(device = create_device(d3d, window, window, TRUE)))
6125 skip("Failed to create a D3D device, skipping tests.\n");
6126 goto done;
6129 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6130 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
6131 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 4))
6133 skip("No ps_1_4 support, skipping tests.\n");
6134 IDirect3DDevice9_Release(device);
6135 goto done;
6138 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
6139 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6141 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
6142 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6143 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
6144 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6145 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
6146 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6147 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_20, &shader_20);
6148 if(FAILED(hr)) shader_20 = NULL;
6150 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
6151 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
6152 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
6153 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
6154 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6155 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
6157 hr = IDirect3DDevice9_BeginScene(device);
6158 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6160 hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
6161 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6162 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 3 * sizeof(float));
6163 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6165 hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
6166 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6167 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 3 * sizeof(float));
6168 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6170 hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
6171 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6172 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 3 * sizeof(float));
6173 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6175 if (shader_20)
6177 hr = IDirect3DDevice9_SetPixelShader(device, shader_20);
6178 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6179 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 3 * sizeof(float));
6180 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6183 hr = IDirect3DDevice9_EndScene(device);
6184 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6186 color = getPixelColor(device, 160, 360);
6187 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
6188 "quad 1 has color %08x, expected 0x00808000\n", color);
6189 color = getPixelColor(device, 480, 360);
6190 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
6191 "quad 2 has color %08x, expected 0x00808000\n", color);
6192 color = getPixelColor(device, 480, 120);
6193 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x80, 0x80, 0x00), 1),
6194 "quad 3 has color %08x, expected 0x00808000\n", color);
6195 if(shader_20) {
6196 color = getPixelColor(device, 160, 120);
6197 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0xbf, 0x80), 1),
6198 "quad 4 has color %08x, expected 0x00bfbf80\n", color);
6200 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6201 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6203 if(shader_20) IDirect3DPixelShader9_Release(shader_20);
6204 IDirect3DPixelShader9_Release(shader_14);
6205 IDirect3DPixelShader9_Release(shader_12);
6206 IDirect3DPixelShader9_Release(shader_11);
6207 refcount = IDirect3DDevice9_Release(device);
6208 ok(!refcount, "Device has %u references left.\n", refcount);
6209 done:
6210 IDirect3D9_Release(d3d);
6211 DestroyWindow(window);
6214 static void dp2add_ps_test(void)
6216 IDirect3DPixelShader9 *shader_dp2add_sat;
6217 IDirect3DPixelShader9 *shader_dp2add;
6218 IDirect3DDevice9 *device;
6219 IDirect3D9 *d3d;
6220 ULONG refcount;
6221 D3DCAPS9 caps;
6222 DWORD color;
6223 HWND window;
6224 HRESULT hr;
6226 /* DP2ADD is defined as: (src0.r * src1.r) + (src0.g * src1.g) + src2.
6227 * One D3D restriction of all shader instructions except SINCOS is that no more than 2
6228 * source tokens can be constants. So, for this exercise, we move contents of c0 to
6229 * r0 first.
6230 * The result here for the r,g,b components should be roughly 0.5:
6231 * (0.5 * 0.5) + (0.5 * 0.5) + 0.0 = 0.5 */
6232 static const DWORD shader_code_dp2add[] = {
6233 0xffff0200, /* ps_2_0 */
6234 0x05000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f800000, 0x00000000, /* def c0, 0.5, 0.5, 1.0, 0 */
6236 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
6237 0x0400005a, 0x80070000, 0x80000000, 0x80000000, 0x80ff0000, /* dp2add r0.rgb, r0, r0, r0.a */
6239 0x02000001, 0x80080000, 0xa0aa0000, /* mov r0.a, c0.b */
6240 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
6241 0x0000ffff /* end */
6244 /* Test the _sat modifier, too. Result here should be:
6245 * DP2: (-0.5 * -0.5) + (-0.5 * -0.5) + 2.0 = 2.5
6246 * _SAT: ==> 1.0
6247 * ADD: (1.0 + -0.5) = 0.5
6249 static const DWORD shader_code_dp2add_sat[] = {
6250 0xffff0200, /* ps_2_0 */
6251 0x05000051, 0xa00f0000, 0xbf000000, 0xbf000000, 0x3f800000, 0x40000000, /* def c0, -0.5, -0.5, 1.0, 2.0 */
6253 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
6254 0x0400005a, 0x80170000, 0x80000000, 0x80000000, 0x80ff0000, /* dp2add_sat r0.rgb, r0, r0, r0.a */
6255 0x03000002, 0x80070000, 0x80e40000, 0xa0000000, /* add r0.rgb, r0, c0.r */
6257 0x02000001, 0x80080000, 0xa0aa0000, /* mov r0.a, c0.b */
6258 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
6259 0x0000ffff /* end */
6261 static const float quad[] =
6263 -1.0f, -1.0f, 0.1f,
6264 -1.0f, 1.0f, 0.1f,
6265 1.0f, -1.0f, 0.1f,
6266 1.0f, 1.0f, 0.1f,
6269 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
6270 0, 0, 640, 480, NULL, NULL, NULL, NULL);
6271 d3d = Direct3DCreate9(D3D_SDK_VERSION);
6272 ok(!!d3d, "Failed to create a D3D object.\n");
6273 if (!(device = create_device(d3d, window, window, TRUE)))
6275 skip("Failed to create a D3D device, skipping tests.\n");
6276 goto done;
6279 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6280 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
6281 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
6283 skip("No ps_2_0 support, skipping tests.\n");
6284 IDirect3DDevice9_Release(device);
6285 goto done;
6288 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff000000, 1.0f, 0);
6289 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6291 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add, &shader_dp2add);
6292 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6294 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_dp2add_sat, &shader_dp2add_sat);
6295 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6297 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6298 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
6300 hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add);
6301 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
6302 hr = IDirect3DDevice9_BeginScene(device);
6303 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6304 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
6305 ok(SUCCEEDED(hr), "Failed to draw primitive, hr %#x.\n", hr);
6306 hr = IDirect3DDevice9_EndScene(device);
6307 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6309 color = getPixelColor(device, 360, 240);
6310 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x7f, 0x7f), 1), "Got unexpected color 0x%08x.\n", color);
6312 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6313 ok(SUCCEEDED(hr), "Failed to present frame, hr %#x.\n", hr);
6314 IDirect3DPixelShader9_Release(shader_dp2add);
6316 hr = IDirect3DDevice9_SetPixelShader(device, shader_dp2add_sat);
6317 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
6318 hr = IDirect3DDevice9_BeginScene(device);
6319 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6320 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
6321 ok(SUCCEEDED(hr), "Failed to draw primitive, hr %#x.\n", hr);
6322 hr = IDirect3DDevice9_EndScene(device);
6323 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6325 color = getPixelColor(device, 360, 240);
6326 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x7f, 0x7f), 1), "Got unexpected color 0x%08x.\n", color);
6328 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6329 ok(SUCCEEDED(hr), "Failed to present frame, hr %#x.\n", hr);
6330 IDirect3DPixelShader9_Release(shader_dp2add_sat);
6332 refcount = IDirect3DDevice9_Release(device);
6333 ok(!refcount, "Device has %u references left.\n", refcount);
6334 done:
6335 IDirect3D9_Release(d3d);
6336 DestroyWindow(window);
6339 static void cnd_test(void)
6341 IDirect3DPixelShader9 *shader_11_coissue_2, *shader_12_coissue_2, *shader_13_coissue_2, *shader_14_coissue_2;
6342 IDirect3DPixelShader9 *shader_11_coissue, *shader_12_coissue, *shader_13_coissue, *shader_14_coissue;
6343 IDirect3DPixelShader9 *shader_11, *shader_12, *shader_13, *shader_14;
6344 IDirect3DDevice9 *device;
6345 IDirect3D9 *d3d;
6346 ULONG refcount;
6347 D3DCAPS9 caps;
6348 HWND window;
6349 DWORD color;
6350 HRESULT hr;
6352 /* ps 1.x shaders are rather picky with writemasks and source swizzles.
6353 * The dp3 is used to copy r0.r to all components of r1, then copy r1.a to
6354 * r0.a. Essentially it does a mov r0.a, r0.r, which isn't allowed as-is
6355 * in 1.x pixel shaders. */
6356 static const DWORD shader_code_11[] =
6358 0xffff0101, /* ps_1_1 */
6359 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
6360 0x00000040, 0xb00f0000, /* texcoord t0 */
6361 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, ???(t0) */
6362 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3 r1, r0, c0 */
6363 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
6364 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
6365 0x0000ffff /* end */
6367 static const DWORD shader_code_12[] =
6369 0xffff0102, /* ps_1_2 */
6370 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
6371 0x00000040, 0xb00f0000, /* texcoord t0 */
6372 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
6373 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3 r1, r0, c0 */
6374 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
6375 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
6376 0x0000ffff /* end */
6378 static const DWORD shader_code_13[] =
6380 0xffff0103, /* ps_1_3 */
6381 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
6382 0x00000040, 0xb00f0000, /* texcoord t0 */
6383 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
6384 0x00000008, 0x800f0001, 0x80e40000, 0xa0e40000, /* dp3, r1, r0, c0 */
6385 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
6386 0x00000050, 0x800f0000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0.a, c1, c2 */
6387 0x0000ffff /* end */
6389 static const DWORD shader_code_14[] =
6391 0xffff0104, /* ps_1_3 */
6392 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
6393 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0, t0 */
6394 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
6395 0x00000050, 0x800f0000, 0x80e40000, 0xa0e40001, 0xa0e40002, /* cnd r0, r0, c1, c2 */
6396 0x0000ffff /* end */
6399 /* Special fun: The coissue flag on cnd: Apparently cnd always selects the 2nd source,
6400 * as if the src0 comparison against 0.5 always evaluates to true. The coissue flag isn't
6401 * set by the compiler, it was added manually after compilation. Note that the COISSUE
6402 * flag on a color(.xyz) operation is only allowed after an alpha operation. DirectX doesn't
6403 * have proper docs, but GL_ATI_fragment_shader explains the pairing of color and alpha ops
6404 * well enough.
6406 * The shader attempts to test the range [-1;1] against coissued cnd, which is a bit tricky.
6407 * The input from t0 is [0;1]. 0.5 is subtracted, then we have to multiply with 2. Since
6408 * constants are clamped to [-1;1], a 2.0 is constructed by adding c0.r(=1.0) to c0.r into r1.r,
6409 * then r1(2.0, 0.0, 0.0, 0.0) is passed to dp3(explained above).
6411 static const DWORD shader_code_11_coissue[] =
6413 0xffff0101, /* ps_1_1 */
6414 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
6415 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
6416 0x00000040, 0xb00f0000, /* texcoord t0 */
6417 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
6418 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
6419 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
6420 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
6421 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
6422 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.xyz, r0.a, c1, c2*/
6423 0x0000ffff /* end */
6425 static const DWORD shader_code_11_coissue_2[] =
6427 0xffff0101, /* ps_1_1 */
6428 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
6429 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
6430 0x00000040, 0xb00f0000, /* texcoord t0 */
6431 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
6432 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
6433 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
6434 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
6435 0x00000001, 0x800f0000, 0x80e40001, /* mov r0, r1 */
6436 0x00000001, 0x80070000, 0x80ff0001, /* mov r0.xyz, r1.a */
6437 0x40000050, 0x80080000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.a, r0.a, c1, c2 */
6438 0x00000001, 0x80070000, 0x80ff0000, /* mov r0.xyz, r0.a */
6439 0x0000ffff /* end */
6441 static const DWORD shader_code_12_coissue[] =
6443 0xffff0102, /* ps_1_2 */
6444 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
6445 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
6446 0x00000040, 0xb00f0000, /* texcoord t0 */
6447 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
6448 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
6449 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
6450 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
6451 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
6452 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.xyz, r0.a, c1, c2*/
6453 0x0000ffff /* end */
6455 static const DWORD shader_code_12_coissue_2[] =
6457 0xffff0102, /* ps_1_2 */
6458 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
6459 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
6460 0x00000040, 0xb00f0000, /* texcoord t0 */
6461 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
6462 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
6463 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
6464 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
6465 0x00000001, 0x800f0000, 0x80e40001, /* mov r0, r1 */
6466 0x00000001, 0x80070000, 0x80ff0001, /* mov r0.xyz, r1.a */
6467 0x40000050, 0x80080000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.a, r0.a, c1, c2 */
6468 0x00000001, 0x80070000, 0x80ff0000, /* mov r0.xyz, r0.a */
6469 0x0000ffff /* end */
6471 static const DWORD shader_code_13_coissue[] =
6473 0xffff0103, /* ps_1_3 */
6474 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
6475 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
6476 0x00000040, 0xb00f0000, /* texcoord t0 */
6477 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
6478 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
6479 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
6480 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
6481 0x00000001, 0x80080000, 0x80ff0001, /* mov r0.a, r1.a */
6482 0x40000050, 0x80070000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.xyz, r0.a, c1, c2*/
6483 0x0000ffff /* end */
6485 static const DWORD shader_code_13_coissue_2[] =
6487 0xffff0103, /* ps_1_3 */
6488 0x00000051, 0xa00f0000, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 1, 0, 0, 0 */
6489 0x00000051, 0xa00f0003, 0x3f000000, 0x3f000000, 0x3f000000, 0x00000000, /* def c3, 0.5, 0.5, 0.5, 0 */
6490 0x00000040, 0xb00f0000, /* texcoord t0 */
6491 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
6492 0x00000003, 0x800f0000, 0x80e40000, 0xa0e40003, /* sub r0, r0, c3 */
6493 0x00000002, 0x800f0001, 0xa0e40000, 0xa0e40000, /* add r1, c0, c0 */
6494 0x00000008, 0x800f0001, 0x80e40000, 0x80e40001, /* dp3 r1, r0, r1 */
6495 0x00000001, 0x800f0000, 0x80e40001, /* mov r0, r1 */
6496 0x00000001, 0x80070000, 0x80ff0001, /* mov r0.xyz, r1.a */
6497 0x40000050, 0x80080000, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r0.a, r0.a, c1, c2 */
6498 0x00000001, 0x80070000, 0x80ff0000, /* mov r0.xyz, r0.a */
6499 0x0000ffff /* end */
6501 /* ps_1_4 does not have a different cnd behavior, just pass the [0;1]
6502 * texcrd result to cnd, it will compare against 0.5. */
6503 static const DWORD shader_code_14_coissue[] =
6505 0xffff0104, /* ps_1_4 */
6506 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
6507 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0.xyz, t0 */
6508 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
6509 0x40000050, 0x80070000, 0x80e40000, 0xa0e40001, 0xa0e40002, /* +cnd r0.xyz, r0, c1, c2 */
6510 0x0000ffff /* end */
6512 static const DWORD shader_code_14_coissue_2[] =
6514 0xffff0104, /* ps_1_4 */
6515 0x00000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
6516 0x00000040, 0x80070000, 0xb0e40000, /* texcrd r0.xyz, t0 */
6517 0x00000001, 0x80080000, 0x80000000, /* mov r0.a, r0.x */
6518 0x00000001, 0x80070001, 0xa0ff0000, /* mov r1.xyz, c0.a */
6519 0x40000050, 0x80080001, 0x80ff0000, 0xa0e40001, 0xa0e40002, /* +cnd r1.a, r0.a, c1, c2 */
6520 0x00000001, 0x80070000, 0x80ff0001, /* mov r0.xyz, r1.a */
6521 0x00000001, 0x80080000, 0xa0ff0000, /* mov r0.a, c0.a */
6522 0x0000ffff /* end */
6524 static const float quad1[] =
6526 -1.0f, -1.0f, 0.1f, 0.0f, 0.0f, 1.0f,
6527 -1.0f, 0.0f, 0.1f, 0.0f, 1.0f, 0.0f,
6528 0.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f,
6529 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 0.0f,
6531 static const float quad2[] =
6533 0.0f, -1.0f, 0.1f, 0.0f, 0.0f, 1.0f,
6534 0.0f, 0.0f, 0.1f, 0.0f, 1.0f, 0.0f,
6535 1.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f,
6536 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 0.0f,
6538 static const float quad3[] =
6540 0.0f, 0.0f, 0.1f, 0.0f, 0.0f, 1.0f,
6541 0.0f, 1.0f, 0.1f, 0.0f, 1.0f, 0.0f,
6542 1.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f,
6543 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 0.0f,
6545 static const float quad4[] =
6547 -1.0f, 0.0f, 0.1f, 0.0f, 0.0f, 1.0f,
6548 -1.0f, 1.0f, 0.1f, 0.0f, 1.0f, 0.0f,
6549 0.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f,
6550 0.0f, 1.0f, 0.1f, 1.0f, 1.0f, 0.0f,
6552 static const float test_data_c1[4] = {0.0f, 0.0f, 0.0f, 0.0f};
6553 static const float test_data_c2[4] = {1.0f, 1.0f, 1.0f, 1.0f};
6554 static const float test_data_c1_coi[4] = {0.0f, 1.0f, 0.0f, 0.0f};
6555 static const float test_data_c2_coi[4] = {1.0f, 0.0f, 1.0f, 1.0f};
6557 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
6558 0, 0, 640, 480, NULL, NULL, NULL, NULL);
6559 d3d = Direct3DCreate9(D3D_SDK_VERSION);
6560 ok(!!d3d, "Failed to create a D3D object.\n");
6561 if (!(device = create_device(d3d, window, window, TRUE)))
6563 skip("Failed to create a D3D device, skipping tests.\n");
6564 goto done;
6567 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6568 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
6569 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 4))
6571 skip("No ps_1_4 support, skipping tests.\n");
6572 IDirect3DDevice9_Release(device);
6573 goto done;
6576 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
6577 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6579 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11, &shader_11);
6580 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6581 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12, &shader_12);
6582 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6583 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13, &shader_13);
6584 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6585 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14, &shader_14);
6586 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6587 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11_coissue, &shader_11_coissue);
6588 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6589 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12_coissue, &shader_12_coissue);
6590 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6591 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13_coissue, &shader_13_coissue);
6592 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6593 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14_coissue, &shader_14_coissue);
6594 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6595 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_11_coissue_2, &shader_11_coissue_2);
6596 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6597 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_12_coissue_2, &shader_12_coissue_2);
6598 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6599 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_13_coissue_2, &shader_13_coissue_2);
6600 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6601 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_14_coissue_2, &shader_14_coissue_2);
6602 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
6604 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1, 1);
6605 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
6606 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2, 1);
6607 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
6608 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
6609 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
6611 hr = IDirect3DDevice9_BeginScene(device);
6612 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6614 hr = IDirect3DDevice9_SetPixelShader(device, shader_11);
6615 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6616 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
6617 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6619 hr = IDirect3DDevice9_SetPixelShader(device, shader_12);
6620 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6621 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
6622 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6624 hr = IDirect3DDevice9_SetPixelShader(device, shader_13);
6625 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6626 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
6627 ok(hr == D3D_OK, "DrawPrimitiveUP failed (%08x)\n", hr);
6629 hr = IDirect3DDevice9_SetPixelShader(device, shader_14);
6630 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6631 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
6632 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6634 hr = IDirect3DDevice9_EndScene(device);
6635 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6637 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
6638 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
6640 /* This is the 1.4 test. Each component(r, g, b) is tested separately against 0.5 */
6641 color = getPixelColor(device, 158, 118);
6642 ok(color == 0x00ff00ff, "pixel 158, 118 has color %08x, expected 0x00ff00ff\n", color);
6643 color = getPixelColor(device, 162, 118);
6644 ok(color == 0x000000ff, "pixel 162, 118 has color %08x, expected 0x000000ff\n", color);
6645 color = getPixelColor(device, 158, 122);
6646 ok(color == 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color);
6647 color = getPixelColor(device, 162, 122);
6648 ok(color == 0x0000ffff, "pixel 162, 122 has color %08x, expected 0x0000ffff\n", color);
6650 /* 1.1 shader. All 3 components get set, based on the .w comparison */
6651 color = getPixelColor(device, 158, 358);
6652 ok(color == 0x00ffffff, "pixel 158, 358 has color %08x, expected 0x00ffffff\n", color);
6653 color = getPixelColor(device, 162, 358);
6654 ok(color_match(color, 0x00000000, 1), "pixel 162, 358 has color 0x%08x, expected 0x00000000.\n", color);
6655 color = getPixelColor(device, 158, 362);
6656 ok(color == 0x00ffffff, "pixel 158, 362 has color %08x, expected 0x00ffffff\n", color);
6657 color = getPixelColor(device, 162, 362);
6658 ok(color_match(color, 0x00000000, 1), "pixel 162, 362 has color 0x%08x, expected 0x00000000.\n", color);
6660 /* 1.2 shader */
6661 color = getPixelColor(device, 478, 358);
6662 ok(color == 0x00ffffff, "pixel 478, 358 has color %08x, expected 0x00ffffff\n", color);
6663 color = getPixelColor(device, 482, 358);
6664 ok(color_match(color, 0x00000000, 1), "pixel 482, 358 has color 0x%08x, expected 0x00000000.\n", color);
6665 color = getPixelColor(device, 478, 362);
6666 ok(color == 0x00ffffff, "pixel 478, 362 has color %08x, expected 0x00ffffff\n", color);
6667 color = getPixelColor(device, 482, 362);
6668 ok(color_match(color, 0x00000000, 1), "pixel 482, 362 has color 0x%08x, expected 0x00000000.\n", color);
6670 /* 1.3 shader */
6671 color = getPixelColor(device, 478, 118);
6672 ok(color == 0x00ffffff, "pixel 478, 118 has color %08x, expected 0x00ffffff\n", color);
6673 color = getPixelColor(device, 482, 118);
6674 ok(color_match(color, 0x00000000, 1), "pixel 482, 118 has color 0x%08x, expected 0x00000000.\n", color);
6675 color = getPixelColor(device, 478, 122);
6676 ok(color == 0x00ffffff, "pixel 478, 122 has color %08x, expected 0x00ffffff\n", color);
6677 color = getPixelColor(device, 482, 122);
6678 ok(color_match(color, 0x00000000, 1), "pixel 482, 122 has color 0x%08x, expected 0x00000000.\n", color);
6680 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6681 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6683 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
6684 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6685 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 1, test_data_c1_coi, 1);
6686 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
6687 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 2, test_data_c2_coi, 1);
6688 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShaderConstantF returned %08x\n", hr);
6690 hr = IDirect3DDevice9_BeginScene(device);
6691 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6693 hr = IDirect3DDevice9_SetPixelShader(device, shader_11_coissue);
6694 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6695 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
6696 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6698 hr = IDirect3DDevice9_SetPixelShader(device, shader_12_coissue);
6699 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6700 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
6701 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6703 hr = IDirect3DDevice9_SetPixelShader(device, shader_13_coissue);
6704 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6705 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
6706 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6708 hr = IDirect3DDevice9_SetPixelShader(device, shader_14_coissue);
6709 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6710 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
6711 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6713 hr = IDirect3DDevice9_EndScene(device);
6714 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6716 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
6717 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
6719 /* This is the 1.4 test. The coissue doesn't change the behavior here, but keep in mind
6720 * that we swapped the values in c1 and c2 to make the other tests return some color
6722 color = getPixelColor(device, 158, 118);
6723 ok(color == 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color);
6724 color = getPixelColor(device, 162, 118);
6725 ok(color == 0x0000ffff, "pixel 162, 118 has color %08x, expected 0x0000ffff\n", color);
6726 color = getPixelColor(device, 158, 122);
6727 ok(color == 0x00ff00ff, "pixel 162, 122 has color %08x, expected 0x00ff00ff\n", color);
6728 color = getPixelColor(device, 162, 122);
6729 ok(color == 0x000000ff, "pixel 162, 122 has color %08x, expected 0x000000ff\n", color);
6731 /* 1.1 shader. coissue flag changed the semantic of cnd, c1 is always selected
6732 * (The Win7 nvidia driver always selects c2)
6734 color = getPixelColor(device, 158, 358);
6735 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6736 "pixel 158, 358 has color %08x, expected 0x0000ff00\n", color);
6737 color = getPixelColor(device, 162, 358);
6738 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6739 "pixel 162, 358 has color %08x, expected 0x0000ff00\n", color);
6740 color = getPixelColor(device, 158, 362);
6741 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6742 "pixel 158, 362 has color %08x, expected 0x0000ff00\n", color);
6743 color = getPixelColor(device, 162, 362);
6744 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6745 "pixel 162, 362 has color %08x, expected 0x0000ff00\n", color);
6747 /* 1.2 shader */
6748 color = getPixelColor(device, 478, 358);
6749 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6750 "pixel 478, 358 has color %08x, expected 0x0000ff00\n", color);
6751 color = getPixelColor(device, 482, 358);
6752 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6753 "pixel 482, 358 has color %08x, expected 0x0000ff00\n", color);
6754 color = getPixelColor(device, 478, 362);
6755 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6756 "pixel 478, 362 has color %08x, expected 0x0000ff00\n", color);
6757 color = getPixelColor(device, 482, 362);
6758 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6759 "pixel 482, 362 has color %08x, expected 0x0000ff00\n", color);
6761 /* 1.3 shader */
6762 color = getPixelColor(device, 478, 118);
6763 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6764 "pixel 478, 118 has color %08x, expected 0x0000ff00\n", color);
6765 color = getPixelColor(device, 482, 118);
6766 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6767 "pixel 482, 118 has color %08x, expected 0x0000ff00\n", color);
6768 color = getPixelColor(device, 478, 122);
6769 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6770 "pixel 478, 122 has color %08x, expected 0x0000ff00\n", color);
6771 color = getPixelColor(device, 482, 122);
6772 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ff00ff, 1)),
6773 "pixel 482, 122 has color %08x, expected 0x0000ff00\n", color);
6775 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6776 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6778 /* Retest with the coissue flag on the alpha instruction instead. This
6779 * works "as expected". The Windows 8 testbot (WARP) seems to handle this
6780 * the same as coissue on .rgb. */
6781 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ffff, 0.0, 0);
6782 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6784 hr = IDirect3DDevice9_BeginScene(device);
6785 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6787 hr = IDirect3DDevice9_SetPixelShader(device, shader_11_coissue_2);
6788 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6789 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, 6 * sizeof(float));
6790 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6792 hr = IDirect3DDevice9_SetPixelShader(device, shader_12_coissue_2);
6793 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6794 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, 6 * sizeof(float));
6795 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6797 hr = IDirect3DDevice9_SetPixelShader(device, shader_13_coissue_2);
6798 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6799 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, 6 * sizeof(float));
6800 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6802 hr = IDirect3DDevice9_SetPixelShader(device, shader_14_coissue_2);
6803 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
6804 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, 6 * sizeof(float));
6805 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6807 hr = IDirect3DDevice9_EndScene(device);
6808 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6810 /* 1.4 shader */
6811 color = getPixelColor(device, 158, 118);
6812 ok(color == 0x00ffffff, "pixel 158, 118 has color %08x, expected 0x00ffffff\n", color);
6813 color = getPixelColor(device, 162, 118);
6814 ok(color == 0x00000000, "pixel 162, 118 has color %08x, expected 0x00000000\n", color);
6815 color = getPixelColor(device, 158, 122);
6816 ok(color == 0x00ffffff, "pixel 162, 122 has color %08x, expected 0x00ffffff\n", color);
6817 color = getPixelColor(device, 162, 122);
6818 ok(color == 0x00000000, "pixel 162, 122 has color %08x, expected 0x00000000\n", color);
6820 /* 1.1 shader */
6821 color = getPixelColor(device, 238, 358);
6822 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
6823 "pixel 238, 358 has color %08x, expected 0x00ffffff\n", color);
6824 color = getPixelColor(device, 242, 358);
6825 ok(color_match(color, 0x00000000, 1),
6826 "pixel 242, 358 has color %08x, expected 0x00000000\n", color);
6827 color = getPixelColor(device, 238, 362);
6828 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
6829 "pixel 238, 362 has color %08x, expected 0x00ffffff\n", color);
6830 color = getPixelColor(device, 242, 362);
6831 ok(color_match(color, 0x00000000, 1),
6832 "pixel 242, 362 has color %08x, expected 0x00000000\n", color);
6834 /* 1.2 shader */
6835 color = getPixelColor(device, 558, 358);
6836 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
6837 "pixel 558, 358 has color %08x, expected 0x00ffffff\n", color);
6838 color = getPixelColor(device, 562, 358);
6839 ok(color_match(color, 0x00000000, 1),
6840 "pixel 562, 358 has color %08x, expected 0x00000000\n", color);
6841 color = getPixelColor(device, 558, 362);
6842 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
6843 "pixel 558, 362 has color %08x, expected 0x00ffffff\n", color);
6844 color = getPixelColor(device, 562, 362);
6845 ok(color_match(color, 0x00000000, 1),
6846 "pixel 562, 362 has color %08x, expected 0x00000000\n", color);
6848 /* 1.3 shader */
6849 color = getPixelColor(device, 558, 118);
6850 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
6851 "pixel 558, 118 has color %08x, expected 0x00ffffff\n", color);
6852 color = getPixelColor(device, 562, 118);
6853 ok(color_match(color, 0x00000000, 1),
6854 "pixel 562, 118 has color %08x, expected 0x00000000\n", color);
6855 color = getPixelColor(device, 558, 122);
6856 ok(color_match(color, 0x00ffffff, 1) || broken(color_match(color, 0x00000000, 1)),
6857 "pixel 558, 122 has color %08x, expected 0x00ffffff\n", color);
6858 color = getPixelColor(device, 562, 122);
6859 ok(color_match(color, 0x00000000, 1),
6860 "pixel 562, 122 has color %08x, expected 0x00000000\n", color);
6862 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6863 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6865 IDirect3DPixelShader9_Release(shader_14_coissue_2);
6866 IDirect3DPixelShader9_Release(shader_13_coissue_2);
6867 IDirect3DPixelShader9_Release(shader_12_coissue_2);
6868 IDirect3DPixelShader9_Release(shader_11_coissue_2);
6869 IDirect3DPixelShader9_Release(shader_14_coissue);
6870 IDirect3DPixelShader9_Release(shader_13_coissue);
6871 IDirect3DPixelShader9_Release(shader_12_coissue);
6872 IDirect3DPixelShader9_Release(shader_11_coissue);
6873 IDirect3DPixelShader9_Release(shader_14);
6874 IDirect3DPixelShader9_Release(shader_13);
6875 IDirect3DPixelShader9_Release(shader_12);
6876 IDirect3DPixelShader9_Release(shader_11);
6877 refcount = IDirect3DDevice9_Release(device);
6878 ok(!refcount, "Device has %u references left.\n", refcount);
6879 done:
6880 IDirect3D9_Release(d3d);
6881 DestroyWindow(window);
6884 static void nested_loop_test(void)
6886 IDirect3DVertexShader9 *vshader;
6887 IDirect3DPixelShader9 *shader;
6888 IDirect3DDevice9 *device;
6889 IDirect3D9 *d3d;
6890 ULONG refcount;
6891 D3DCAPS9 caps;
6892 DWORD color;
6893 HWND window;
6894 HRESULT hr;
6896 static const DWORD shader_code[] =
6898 0xffff0300, /* ps_3_0 */
6899 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0, 0, 0, 1 */
6900 0x05000051, 0xa00f0001, 0x3d000000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1/32, 0, 0, 0*/
6901 0x05000030, 0xf00f0000, 0x00000004, 0x00000000, 0x00000002, 0x00000000, /* defi i0, 4, 0, 2, 0 */
6902 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
6903 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
6904 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
6905 0x03000002, 0x800f0000, 0x80e40000, 0xa0e40001, /* add r0, r0, c1 */
6906 0x0000001d, /* endloop */
6907 0x0000001d, /* endloop */
6908 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
6909 0x0000ffff /* end */
6911 static const DWORD vshader_code[] =
6913 0xfffe0300, /* vs_3_0 */
6914 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
6915 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
6916 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
6917 0x0000ffff /* end */
6919 static const float quad[] =
6921 -1.0f, -1.0f, 0.1f,
6922 -1.0f, 1.0f, 0.1f,
6923 1.0f, -1.0f, 0.1f,
6924 1.0f, 1.0f, 0.1f,
6927 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
6928 0, 0, 640, 480, NULL, NULL, NULL, NULL);
6929 d3d = Direct3DCreate9(D3D_SDK_VERSION);
6930 ok(!!d3d, "Failed to create a D3D object.\n");
6931 if (!(device = create_device(d3d, window, window, TRUE)))
6933 skip("Failed to create a D3D device, skipping tests.\n");
6934 goto done;
6937 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
6938 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
6939 if (caps.PixelShaderVersion < D3DPS_VERSION(3, 0) || caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
6941 skip("No shader model 3 support, skipping tests.\n");
6942 IDirect3DDevice9_Release(device);
6943 goto done;
6946 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
6947 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with %08x\n", hr);
6948 hr = IDirect3DDevice9_SetPixelShader(device, shader);
6949 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with %08x\n", hr);
6950 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
6951 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
6952 hr = IDirect3DDevice9_SetVertexShader(device, vshader);
6953 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
6954 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
6955 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
6956 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x0000ff00, 1.0f, 0);
6957 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
6959 hr = IDirect3DDevice9_BeginScene(device);
6960 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
6961 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
6962 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
6963 hr = IDirect3DDevice9_EndScene(device);
6964 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
6966 color = getPixelColor(device, 360, 240);
6967 ok(color_match(color, 0x00800000, 1),
6968 "Nested loop test returned color 0x%08x, expected 0x00800000.\n", color);
6970 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
6971 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
6973 IDirect3DPixelShader9_Release(shader);
6974 IDirect3DVertexShader9_Release(vshader);
6975 refcount = IDirect3DDevice9_Release(device);
6976 ok(!refcount, "Device has %u references left.\n", refcount);
6977 done:
6978 IDirect3D9_Release(d3d);
6979 DestroyWindow(window);
6982 static void pretransformed_varying_test(void)
6984 /* dcl_position: fails to compile */
6985 static const DWORD blendweight_code[] =
6987 0xffff0300, /* ps_3_0 */
6988 0x0200001f, 0x80000001, 0x900f0000, /* dcl_blendweight, v0 */
6989 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
6990 0x0000ffff /* end */
6992 static const DWORD blendindices_code[] =
6994 0xffff0300, /* ps_3_0 */
6995 0x0200001f, 0x80000002, 0x900f0000, /* dcl_blendindices, v0 */
6996 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
6997 0x0000ffff /* end */
6999 static const DWORD normal_code[] =
7001 0xffff0300, /* ps_3_0 */
7002 0x0200001f, 0x80000003, 0x900f0000, /* dcl_normal, v0 */
7003 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
7004 0x0000ffff /* end */
7006 /* psize: fails? */
7007 static const DWORD texcoord0_code[] =
7009 0xffff0300, /* ps_3_0 */
7010 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord0, v0 */
7011 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
7012 0x0000ffff /* end */
7014 static const DWORD tangent_code[] =
7016 0xffff0300, /* ps_3_0 */
7017 0x0200001f, 0x80000006, 0x900f0000, /* dcl_tangent, v0 */
7018 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
7019 0x0000ffff /* end */
7021 static const DWORD binormal_code[] =
7023 0xffff0300, /* ps_3_0 */
7024 0x0200001f, 0x80000007, 0x900f0000, /* dcl_binormal, v0 */
7025 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
7026 0x0000ffff /* end */
7028 /* tessfactor: fails */
7029 /* positiont: fails */
7030 static const DWORD color_code[] =
7032 0xffff0300, /* ps_3_0 */
7033 0x0200001f, 0x8000000a, 0x900f0000, /* dcl_color0, v0 */
7034 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
7035 0x0000ffff /* end */
7037 static const DWORD fog_code[] =
7039 0xffff0300, /* ps_3_0 */
7040 0x0200001f, 0x8000000b, 0x900f0000, /* dcl_fog, v0 */
7041 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
7042 0x0000ffff /* end */
7044 static const DWORD depth_code[] =
7046 0xffff0300, /* ps_3_0 */
7047 0x0200001f, 0x8000000c, 0x900f0000, /* dcl_depth, v0 */
7048 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
7049 0x0000ffff /* end */
7051 static const DWORD specular_code[] =
7053 0xffff0300, /* ps_3_0 */
7054 0x0200001f, 0x8001000a, 0x900f0000, /* dcl_color1, v0 */
7055 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
7056 0x0000ffff /* end */
7058 /* sample: fails */
7059 static const DWORD texcoord1_code[] =
7061 0xffff0300, /* ps_3_0 */
7062 0x0200001f, 0x80010005, 0x900f0000, /* dcl_texcoord1, v0 */
7063 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
7064 0x0000ffff /* end */
7066 static const DWORD texcoord1_alpha_code[] =
7068 0xffff0300, /* ps_3_0 */
7069 0x0200001f, 0x80010005, 0x900f0000, /* dcl_texcoord1, v0 */
7070 0x02000001, 0x800f0800, 0x90ff0000, /* mov oC0, v0.w */
7071 0x0000ffff /* end */
7074 static const struct
7076 const char *name;
7077 const DWORD *shader_code;
7078 DWORD color;
7079 BOOL todo;
7080 BOOL broken_warp;
7082 tests[] =
7084 {"blendweight", blendweight_code, 0x00191919, TRUE },
7085 {"blendindices", blendindices_code, 0x00333333, TRUE },
7086 {"normal", normal_code, 0x004c4c4c, TRUE },
7087 {"texcoord0", texcoord0_code, 0x00808c8c, FALSE},
7088 {"tangent", tangent_code, 0x00999999, TRUE },
7089 {"binormal", binormal_code, 0x00b2b2b2, TRUE },
7090 {"color", color_code, 0x00e6e6e6, FALSE},
7091 {"fog", fog_code, 0x00666666, TRUE },
7092 {"depth", depth_code, 0x00cccccc, TRUE },
7093 {"specular", specular_code, 0x004488ff, FALSE},
7094 {"texcoord1", texcoord1_code, 0x00000000, FALSE},
7095 {"texcoord1 alpha", texcoord1_alpha_code, 0x00000000, FALSE, TRUE},
7097 /* Declare a monster vertex type :-) */
7098 static const D3DVERTEXELEMENT9 decl_elements[] = {
7099 {0, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT, 0},
7100 {0, 16, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT, 0},
7101 {0, 32, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES, 0},
7102 {0, 48, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
7103 {0, 64, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_FOG, 0},
7104 {0, 80, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
7105 {0, 96, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT, 0},
7106 {0, 112, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL, 0},
7107 {0, 128, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_DEPTH, 0},
7108 {0, 144, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7109 {0, 148, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 1},
7110 D3DDECL_END()
7113 static const struct
7115 float pos_x, pos_y, pos_z, rhw;
7116 float weight_1, weight_2, weight_3, weight_4;
7117 float index_1, index_2, index_3, index_4;
7118 float normal_1, normal_2, normal_3, normal_4;
7119 float fog_1, fog_2, fog_3, fog_4;
7120 float texcoord_1, texcoord_2, texcoord_3, texcoord_4;
7121 float tangent_1, tangent_2, tangent_3, tangent_4;
7122 float binormal_1, binormal_2, binormal_3, binormal_4;
7123 float depth_1, depth_2, depth_3, depth_4;
7124 D3DCOLOR diffuse;
7125 D3DCOLOR specular;
7127 data[] =
7130 0.0f, 0.0f, 0.1f, 1.0f,
7131 0.1f, 0.1f, 0.1f, 0.1f,
7132 0.2f, 0.2f, 0.2f, 0.2f,
7133 0.3f, 0.3f, 0.3f, 0.3f,
7134 0.4f, 0.4f, 0.4f, 0.4f,
7135 0.5f, 0.55f, 0.55f, 0.55f,
7136 0.6f, 0.6f, 0.6f, 0.7f,
7137 0.7f, 0.7f, 0.7f, 0.6f,
7138 0.8f, 0.8f, 0.8f, 0.8f,
7139 0xe6e6e6e6, /* 0.9 * 256 */
7140 0x224488ff, /* Nothing special */
7143 640.0f, 0.0f, 0.1f, 1.0f,
7144 0.1f, 0.1f, 0.1f, 0.1f,
7145 0.2f, 0.2f, 0.2f, 0.2f,
7146 0.3f, 0.3f, 0.3f, 0.3f,
7147 0.4f, 0.4f, 0.4f, 0.4f,
7148 0.5f, 0.55f, 0.55f, 0.55f,
7149 0.6f, 0.6f, 0.6f, 0.7f,
7150 0.7f, 0.7f, 0.7f, 0.6f,
7151 0.8f, 0.8f, 0.8f, 0.8f,
7152 0xe6e6e6e6, /* 0.9 * 256 */
7153 0x224488ff, /* Nothing special */
7156 0.0f, 480.0f, 0.1f, 1.0f,
7157 0.1f, 0.1f, 0.1f, 0.1f,
7158 0.2f, 0.2f, 0.2f, 0.2f,
7159 0.3f, 0.3f, 0.3f, 0.3f,
7160 0.4f, 0.4f, 0.4f, 0.4f,
7161 0.5f, 0.55f, 0.55f, 0.55f,
7162 0.6f, 0.6f, 0.6f, 0.7f,
7163 0.7f, 0.7f, 0.7f, 0.6f,
7164 0.8f, 0.8f, 0.8f, 0.8f,
7165 0xe6e6e6e6, /* 0.9 * 256 */
7166 0x224488ff, /* Nothing special */
7169 640.0f, 480.0f, 0.1f, 1.0f,
7170 0.1f, 0.1f, 0.1f, 0.1f,
7171 0.2f, 0.2f, 0.2f, 0.2f,
7172 0.3f, 0.3f, 0.3f, 0.3f,
7173 0.4f, 0.4f, 0.4f, 0.4f,
7174 0.5f, 0.55f, 0.55f, 0.55f,
7175 0.6f, 0.6f, 0.6f, 0.7f,
7176 0.7f, 0.7f, 0.7f, 0.6f,
7177 0.8f, 0.8f, 0.8f, 0.8f,
7178 0xe6e6e6e6, /* 0.9 * 256 */
7179 0x224488ff, /* Nothing special */
7182 D3DADAPTER_IDENTIFIER9 identifier;
7183 IDirect3DVertexDeclaration9 *decl;
7184 IDirect3DDevice9 *device;
7185 IDirect3D9 *d3d;
7186 unsigned int i;
7187 ULONG refcount;
7188 D3DCAPS9 caps;
7189 DWORD color;
7190 HWND window;
7191 HRESULT hr;
7192 BOOL warp;
7194 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
7195 0, 0, 640, 480, NULL, NULL, NULL, NULL);
7196 d3d = Direct3DCreate9(D3D_SDK_VERSION);
7197 ok(!!d3d, "Failed to create a D3D object.\n");
7198 if (!(device = create_device(d3d, window, window, TRUE)))
7200 skip("Failed to create a D3D device, skipping tests.\n");
7201 goto done;
7204 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7205 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
7206 if (caps.PixelShaderVersion < D3DPS_VERSION(3, 0) || caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
7208 skip("No shader model 3 support, skipping tests.\n");
7209 IDirect3DDevice9_Release(device);
7210 goto done;
7213 hr = IDirect3D9_GetAdapterIdentifier(d3d, D3DADAPTER_DEFAULT, 0, &identifier);
7214 ok(SUCCEEDED(hr), "Failed to get adapter identifier, hr %#x.\n", hr);
7215 warp = adapter_is_warp(&identifier);
7217 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
7218 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
7219 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
7220 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration returned %08x\n", hr);
7222 for (i = 0; i < sizeof(tests) / sizeof(*tests); ++i)
7224 IDirect3DPixelShader9 *shader;
7226 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
7227 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
7229 hr = IDirect3DDevice9_CreatePixelShader(device, tests[i].shader_code, &shader);
7230 ok(SUCCEEDED(hr), "Failed to create pixel shader for test %s, hr %#x.\n", tests[i].name, hr);
7232 hr = IDirect3DDevice9_SetPixelShader(device, shader);
7233 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
7235 hr = IDirect3DDevice9_BeginScene(device);
7236 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7237 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, data, sizeof(*data));
7238 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7239 hr = IDirect3DDevice9_EndScene(device);
7240 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7242 /* This isn't a weekend's job to fix, ignore the problem for now.
7243 * Needs a replacement pipeline. */
7244 color = getPixelColor(device, 360, 240);
7245 if (tests[i].todo)
7246 todo_wine ok(color_match(color, tests[i].color, 1)
7247 || broken(color_match(color, 0x00000000, 1)
7248 && tests[i].shader_code == blendindices_code),
7249 "Test %s returned color 0x%08x, expected 0x%08x (todo).\n",
7250 tests[i].name, color, tests[i].color);
7251 else
7252 ok(color_match(color, tests[i].color, 1) || broken(warp && tests[i].broken_warp),
7253 "Test %s returned color 0x%08x, expected 0x%08x.\n",
7254 tests[i].name, color, tests[i].color);
7256 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7257 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
7259 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
7260 ok(SUCCEEDED(hr), "Failed to set pixel shader for test %s, hr %#x.\n", tests[i].name, hr);
7261 IDirect3DPixelShader9_Release(shader);
7264 IDirect3DVertexDeclaration9_Release(decl);
7265 refcount = IDirect3DDevice9_Release(device);
7266 ok(!refcount, "Device has %u references left.\n", refcount);
7267 done:
7268 IDirect3D9_Release(d3d);
7269 DestroyWindow(window);
7272 static void test_compare_instructions(void)
7274 IDirect3DVertexShader9 *shader_slt_scalar;
7275 IDirect3DVertexShader9 *shader_sge_scalar;
7276 IDirect3DVertexShader9 *shader_slt_vec;
7277 IDirect3DVertexShader9 *shader_sge_vec;
7278 IDirect3DDevice9 *device;
7279 IDirect3D9 *d3d;
7280 D3DCOLOR color;
7281 ULONG refcount;
7282 D3DCAPS9 caps;
7283 HWND window;
7284 HRESULT hr;
7286 static const DWORD shader_sge_vec_code[] =
7288 0xfffe0101, /* vs_1_1 */
7289 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7290 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
7291 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
7292 0x0000000d, 0xd00f0000, 0x80e40000, 0xa0e40001, /* sge oD0, r0, c1 */
7293 0x0000ffff /* end */
7295 static const DWORD shader_slt_vec_code[] =
7297 0xfffe0101, /* vs_1_1 */
7298 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7299 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
7300 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
7301 0x0000000c, 0xd00f0000, 0x80e40000, 0xa0e40001, /* slt oD0, r0, c1 */
7302 0x0000ffff /* end */
7304 static const DWORD shader_sge_scalar_code[] =
7306 0xfffe0101, /* vs_1_1 */
7307 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7308 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
7309 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
7310 0x0000000d, 0xd0010000, 0x80000000, 0xa0550001, /* slt oD0.r, r0.r, c1.b */
7311 0x0000000d, 0xd0020000, 0x80550000, 0xa0aa0001, /* slt oD0.g, r0.g, c1.r */
7312 0x0000000d, 0xd0040000, 0x80aa0000, 0xa0000001, /* slt oD0.b, r0.b, c1.g */
7313 0x0000ffff /* end */
7315 static const DWORD shader_slt_scalar_code[] =
7317 0xfffe0101, /* vs_1_1 */
7318 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7319 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
7320 0x00000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
7321 0x0000000c, 0xd0010000, 0x80000000, 0xa0aa0001, /* slt oD0.r, r0.r, c1.b */
7322 0x0000000c, 0xd0020000, 0x80550000, 0xa0000001, /* slt oD0.g, r0.g, c1.r */
7323 0x0000000c, 0xd0040000, 0x80aa0000, 0xa0550001, /* slt oD0.b, r0.b, c1.g */
7324 0x0000ffff /* end */
7326 static const float quad1[] =
7328 -1.0f, -1.0f, 0.1f,
7329 -1.0f, 0.0f, 0.1f,
7330 0.0f, -1.0f, 0.1f,
7331 0.0f, 0.0f, 0.1f,
7333 static const float quad2[] =
7335 0.0f, -1.0f, 0.1f,
7336 0.0f, 0.0f, 0.1f,
7337 1.0f, -1.0f, 0.1f,
7338 1.0f, 0.0f, 0.1f,
7340 static const float quad3[] =
7342 -1.0f, 0.0f, 0.1f,
7343 -1.0f, 1.0f, 0.1f,
7344 0.0f, 0.0f, 0.1f,
7345 0.0f, 1.0f, 0.1f,
7347 static const float quad4[] =
7349 0.0f, 0.0f, 0.1f,
7350 0.0f, 1.0f, 0.1f,
7351 1.0f, 0.0f, 0.1f,
7352 1.0f, 1.0f, 0.1f,
7354 static const float const0[4] = {0.8f, 0.2f, 0.2f, 0.2f};
7355 static const float const1[4] = {0.2f, 0.8f, 0.2f, 0.2f};
7357 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
7358 0, 0, 640, 480, NULL, NULL, NULL, NULL);
7359 d3d = Direct3DCreate9(D3D_SDK_VERSION);
7360 ok(!!d3d, "Failed to create a D3D object.\n");
7361 if (!(device = create_device(d3d, window, window, TRUE)))
7363 skip("Failed to create a D3D device, skipping tests.\n");
7364 goto done;
7367 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7368 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
7369 if (caps.VertexShaderVersion < D3DVS_VERSION(1, 1))
7371 skip("No vs_1_1 support, skipping tests.\n");
7372 IDirect3DDevice9_Release(device);
7373 goto done;
7376 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
7377 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
7379 hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_vec_code, &shader_sge_vec);
7380 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
7381 hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_vec_code, &shader_slt_vec);
7382 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
7383 hr = IDirect3DDevice9_CreateVertexShader(device, shader_sge_scalar_code, &shader_sge_scalar);
7384 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
7385 hr = IDirect3DDevice9_CreateVertexShader(device, shader_slt_scalar_code, &shader_slt_scalar);
7386 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
7387 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
7388 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
7389 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, const1, 1);
7390 ok(SUCCEEDED(hr), "SetVertexShaderConstantF failed (%08x)\n", hr);
7391 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
7392 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed (%08x)\n", hr);
7394 hr = IDirect3DDevice9_BeginScene(device);
7395 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7397 hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_vec);
7398 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
7399 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 3);
7400 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7402 hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_vec);
7403 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
7404 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 3);
7405 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7407 hr = IDirect3DDevice9_SetVertexShader(device, shader_sge_scalar);
7408 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
7409 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 3);
7410 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7412 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, const0, 1);
7413 ok(SUCCEEDED(hr), "Failed to set vertex shader constant, hr %#x.\n", hr);
7415 hr = IDirect3DDevice9_SetVertexShader(device, shader_slt_scalar);
7416 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
7417 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 3);
7418 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7420 hr = IDirect3DDevice9_EndScene(device);
7421 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7423 color = getPixelColor(device, 160, 360);
7424 ok(color == 0x00ff00ff, "Compare test: Quad 1(sge vec) returned color 0x%08x, expected 0x00ff00ff\n", color);
7425 color = getPixelColor(device, 480, 360);
7426 ok(color == 0x0000ff00, "Compare test: Quad 2(slt vec) returned color 0x%08x, expected 0x0000ff00\n", color);
7427 color = getPixelColor(device, 160, 120);
7428 ok(color == 0x00ffffff, "Compare test: Quad 3(sge scalar) returned color 0x%08x, expected 0x00ffffff\n", color);
7429 color = getPixelColor(device, 480, 160);
7430 ok(color == 0x000000ff, "Compare test: Quad 4(slt scalar) returned color 0x%08x, expected 0x000000ff\n", color);
7432 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7433 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
7435 IDirect3DVertexShader9_Release(shader_sge_vec);
7436 IDirect3DVertexShader9_Release(shader_slt_vec);
7437 IDirect3DVertexShader9_Release(shader_sge_scalar);
7438 IDirect3DVertexShader9_Release(shader_slt_scalar);
7439 refcount = IDirect3DDevice9_Release(device);
7440 ok(!refcount, "Device has %u references left.\n", refcount);
7441 done:
7442 IDirect3D9_Release(d3d);
7443 DestroyWindow(window);
7446 static void test_vshader_input(void)
7448 IDirect3DVertexDeclaration9 *decl_twotexcrd, *decl_onetexcrd, *decl_twotex_wrongidx, *decl_twotexcrd_rightorder;
7449 IDirect3DVertexDeclaration9 *decl_texcoord_color, *decl_color_color, *decl_color_ubyte, *decl_color_float;
7450 IDirect3DVertexDeclaration9 *decl_nocolor;
7451 IDirect3DVertexShader9 *swapped_shader, *texcoord_color_shader, *color_color_shader;
7452 D3DADAPTER_IDENTIFIER9 identifier;
7453 IDirect3DPixelShader9 *ps;
7454 IDirect3DDevice9 *device;
7455 IDirect3D9 *d3d;
7456 ULONG refcount;
7457 unsigned int i;
7458 D3DCAPS9 caps;
7459 DWORD color;
7460 HWND window;
7461 HRESULT hr;
7462 BOOL warp;
7464 static const DWORD swapped_shader_code_3[] =
7466 0xfffe0300, /* vs_3_0 */
7467 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
7468 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
7469 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7470 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
7471 0x0200001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
7472 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
7473 0x02000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
7474 0x03000002, 0xe00f0001, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
7475 0x0000ffff /* end */
7477 static const DWORD swapped_shader_code_1[] =
7479 0xfffe0101, /* vs_1_1 */
7480 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7481 0x0000001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
7482 0x0000001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
7483 0x00000001, 0xc00f0000, 0x90e40000, /* mov o0, v0 */
7484 0x00000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
7485 0x00000002, 0xd00f0000, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
7486 0x0000ffff /* end */
7488 static const DWORD swapped_shader_code_2[] =
7490 0xfffe0200, /* vs_2_0 */
7491 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7492 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
7493 0x0200001f, 0x80010005, 0x900f0002, /* dcl_texcoord1 v2 */
7494 0x02000001, 0xc00f0000, 0x90e40000, /* mov o0, v0 */
7495 0x02000001, 0x800f0001, 0x90e40001, /* mov r1, v1 */
7496 0x03000002, 0xd00f0000, 0x80e40001, 0x91e40002, /* sub o1, r1, v2 */
7497 0x0000ffff /* end */
7499 static const DWORD texcoord_color_shader_code_3[] =
7501 0xfffe0300, /* vs_3_0 */
7502 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
7503 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
7504 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7505 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
7506 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
7507 0x02000001, 0xe00f0001, 0x90e40001, /* mov o1, v1 */
7508 0x0000ffff /* end */
7510 static const DWORD texcoord_color_shader_code_2[] =
7512 0xfffe0200, /* vs_2_0 */
7513 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7514 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
7515 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
7516 0x02000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
7517 0x0000ffff /* end */
7519 static const DWORD texcoord_color_shader_code_1[] =
7521 0xfffe0101, /* vs_1_1 */
7522 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7523 0x0000001f, 0x80000005, 0x900f0001, /* dcl_texcoord v1 */
7524 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
7525 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
7526 0x0000ffff /* end */
7528 static const DWORD color_color_shader_code_3[] =
7530 0xfffe0300, /* vs_3_0 */
7531 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
7532 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color o1 */
7533 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7534 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
7535 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
7536 0x03000005, 0xe00f0001, 0xa0e40000, 0x90e40001, /* mul o1, c0, v1 */
7537 0x0000ffff /* end */
7539 static const DWORD color_color_shader_code_2[] =
7541 0xfffe0200, /* vs_2_0 */
7542 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7543 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
7544 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
7545 0x03000005, 0xd00f0000, 0xa0e40000, 0x90e40001, /* mul oD0, c0, v1 */
7546 0x0000ffff /* end */
7548 static const DWORD color_color_shader_code_1[] =
7550 0xfffe0101, /* vs_1_1 */
7551 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
7552 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
7553 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
7554 0x00000005, 0xd00f0000, 0xa0e40000, 0x90e40001, /* mul oD0, c0, v1 */
7555 0x0000ffff /* end */
7557 static const DWORD ps3_code[] =
7559 0xffff0300, /* ps_3_0 */
7560 0x0200001f, 0x8000000a, 0x900f0000, /* dcl_color0 v0 */
7561 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
7562 0x0000ffff /* end */
7564 static const float quad1[] =
7566 -1.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7567 -1.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7568 0.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7569 0.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7571 static const float quad2[] =
7573 0.0f, -1.0f, 0.1f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
7574 0.0f, 0.0f, 0.1f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
7575 1.0f, -1.0f, 0.1f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
7576 1.0f, 0.0f, 0.1f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
7578 static const float quad3[] =
7580 -1.0f, 0.0f, 0.1f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 0.0f, 0.0f,
7581 -1.0f, 1.0f, 0.1f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f,
7582 0.0f, 0.0f, 0.1f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f,
7583 0.0f, 1.0f, 0.1f, -1.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f,
7585 static const float quad4[] =
7587 0.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7588 0.0f, 1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7589 1.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7590 1.0f, 1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.5f, 0.0f,
7592 static const float quad1_modified[] =
7594 -1.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f,
7595 -1.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f,
7596 0.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f,
7597 0.0f, 0.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f, -1.0f, -1.0f, -1.0f, 0.0f,
7599 static const float quad2_modified[] =
7601 0.0f, -1.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
7602 0.0f, 0.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
7603 1.0f, -1.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
7604 1.0f, 0.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
7606 static const struct
7608 struct vec3 position;
7609 DWORD diffuse;
7611 quad1_color[] =
7613 {{-1.0f, -1.0f, 0.1f}, 0x00ff8040},
7614 {{-1.0f, 0.0f, 0.1f}, 0x00ff8040},
7615 {{ 0.0f, -1.0f, 0.1f}, 0x00ff8040},
7616 {{ 0.0f, 0.0f, 0.1f}, 0x00ff8040},
7618 quad2_color[] =
7620 {{ 0.0f, -1.0f, 0.1f}, 0x00ff8040},
7621 {{ 0.0f, 0.0f, 0.1f}, 0x00ff8040},
7622 {{ 1.0f, -1.0f, 0.1f}, 0x00ff8040},
7623 {{ 1.0f, 0.0f, 0.1f}, 0x00ff8040},
7625 quad3_color[] =
7627 {{-1.0f, 0.0f, 0.1f}, 0x00ff8040},
7628 {{-1.0f, 1.0f, 0.1f}, 0x00ff8040},
7629 {{ 0.0f, 0.0f, 0.1f}, 0x00ff8040},
7630 {{ 0.0f, 1.0f, 0.1f}, 0x00ff8040},
7632 static const float quad4_color[] =
7634 0.0f, 0.0f, 0.1f, 1.0f, 1.0f, 0.0f, 0.0f,
7635 0.0f, 1.0f, 0.1f, 1.0f, 1.0f, 0.0f, 0.0f,
7636 1.0f, 0.0f, 0.1f, 1.0f, 1.0f, 0.0f, 1.0f,
7637 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 0.0f, 1.0f,
7639 static const struct vec3 quad_nocolor[] =
7641 {-1.0f, -1.0f, 0.1f},
7642 {-1.0f, 1.0f, 0.1f},
7643 { 1.0f, -1.0f, 0.1f},
7644 { 1.0f, 1.0f, 0.1f},
7646 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd[] =
7648 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7649 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
7650 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
7651 D3DDECL_END()
7653 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_rightorder[] =
7655 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7656 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
7657 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
7658 D3DDECL_END()
7660 static const D3DVERTEXELEMENT9 decl_elements_onetexcrd[] =
7662 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7663 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
7664 D3DDECL_END()
7666 static const D3DVERTEXELEMENT9 decl_elements_twotexcrd_wrongidx[] =
7668 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7669 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
7670 {0, 28, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 2},
7671 D3DDECL_END()
7673 static const D3DVERTEXELEMENT9 decl_elements_texcoord_color[] =
7675 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7676 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
7677 D3DDECL_END()
7679 static const D3DVERTEXELEMENT9 decl_elements_color_color[] =
7681 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7682 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7683 D3DDECL_END()
7685 static const D3DVERTEXELEMENT9 decl_elements_color_ubyte[] =
7687 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7688 {0, 12, D3DDECLTYPE_UBYTE4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7689 D3DDECL_END()
7691 static const D3DVERTEXELEMENT9 decl_elements_color_float[] =
7693 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7694 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
7695 D3DDECL_END()
7697 static const D3DVERTEXELEMENT9 decl_elements_nocolor[] =
7699 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
7700 D3DDECL_END()
7702 static const float normalize[4] = {1.0f / 256.0f, 1.0f / 256.0f, 1.0f / 256.0f, 1.0f / 256.0f};
7703 static const float no_normalize[4] = {1.0f, 1.0f, 1.0f, 1.0f};
7705 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
7706 0, 0, 640, 480, NULL, NULL, NULL, NULL);
7707 d3d = Direct3DCreate9(D3D_SDK_VERSION);
7708 ok(!!d3d, "Failed to create a D3D object.\n");
7709 if (!(device = create_device(d3d, window, window, TRUE)))
7711 skip("Failed to create a D3D device, skipping tests.\n");
7712 goto done;
7715 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
7716 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
7717 if (caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
7719 skip("No vs_3_0 support, skipping tests.\n");
7720 IDirect3DDevice9_Release(device);
7721 goto done;
7724 hr = IDirect3D9_GetAdapterIdentifier(d3d, D3DADAPTER_DEFAULT, 0, &identifier);
7725 ok(SUCCEEDED(hr), "Failed to get adapter identifier, hr %#x.\n", hr);
7726 warp = adapter_is_warp(&identifier);
7728 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd, &decl_twotexcrd);
7729 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
7730 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_onetexcrd, &decl_onetexcrd);
7731 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
7732 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_wrongidx, &decl_twotex_wrongidx);
7733 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
7734 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_twotexcrd_rightorder, &decl_twotexcrd_rightorder);
7735 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
7737 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_texcoord_color, &decl_texcoord_color);
7738 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
7739 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_color, &decl_color_color);
7740 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
7741 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_ubyte, &decl_color_ubyte);
7742 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
7743 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_color_float, &decl_color_float);
7744 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
7745 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_nocolor, &decl_nocolor);
7746 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
7748 hr = IDirect3DDevice9_CreatePixelShader(device, ps3_code, &ps);
7749 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader returned %08x\n", hr);
7751 for (i = 1; i <= 3; ++i)
7753 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 1.0f, 0);
7754 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
7755 if(i == 3) {
7756 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_3, &swapped_shader);
7757 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
7758 hr = IDirect3DDevice9_SetPixelShader(device, ps);
7759 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
7760 } else if(i == 2){
7761 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_2, &swapped_shader);
7762 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
7763 } else if(i == 1) {
7764 hr = IDirect3DDevice9_CreateVertexShader(device, swapped_shader_code_1, &swapped_shader);
7765 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
7768 hr = IDirect3DDevice9_BeginScene(device);
7769 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7771 hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
7772 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
7774 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
7775 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
7776 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(float) * 11);
7777 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7779 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
7780 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
7781 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(float) * 11);
7782 if (i == 3 || i == 2)
7783 ok(SUCCEEDED(hr), "Failed to draw, i %u, hr %#x.\n", i, hr);
7784 else if (i == 1)
7785 /* Succeeds or fails, depending on SW or HW vertex processing. */
7786 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
7788 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd_rightorder);
7789 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
7790 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(float) * 11);
7791 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7793 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotex_wrongidx);
7794 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
7795 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(float) * 11);
7796 if (i == 3 || i == 2)
7797 ok(SUCCEEDED(hr), "Failed to draw, i %u, hr %#x.\n", i, hr);
7798 else if (i == 1)
7799 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
7801 hr = IDirect3DDevice9_EndScene(device);
7802 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7804 if(i == 3 || i == 2) {
7805 color = getPixelColor(device, 160, 360);
7806 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
7807 "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00ffff80\n", color);
7809 /* The last value of the read but undefined stream is used, it is 0x00. The defined input is vec4(1, 0, 0, 0) */
7810 color = getPixelColor(device, 480, 360);
7811 /* On the Windows 8 testbot (WARP) the draw succeeds, but uses
7812 * mostly random data as input. */
7813 ok(color == 0x00ffff00 || color == 0x00ff0000 || broken(warp),
7814 "Got unexpected color 0x%08x for quad 2 (1crd).\n", color);
7815 color = getPixelColor(device, 160, 120);
7816 /* Same as above, accept both the last used value and 0.0 for the undefined streams */
7817 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
7818 "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00ff0080\n", color);
7820 color = getPixelColor(device, 480, 160);
7821 ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
7822 } else if(i == 1) {
7823 color = getPixelColor(device, 160, 360);
7824 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x80), 1),
7825 "Input test: Quad 1(2crd) returned color 0x%08x, expected 0x00ffff80\n", color);
7826 color = getPixelColor(device, 480, 360);
7827 /* Accept the clear color as well in this case, since SW VP
7828 * returns an error. On the Windows 8 testbot (WARP) the draw
7829 * succeeds, but uses mostly random data as input. */
7830 ok(color == 0x00ffff00 || color == 0x00ff0000 || broken(warp),
7831 "Got unexpected color 0x%08x for quad 2 (1crd).\n", color);
7832 color = getPixelColor(device, 160, 120);
7833 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x80), 1) || color == D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00),
7834 "Input test: Quad 3(2crd-wrongidx) returned color 0x%08x, expected 0x00ff0080\n", color);
7835 color = getPixelColor(device, 480, 160);
7836 ok(color == 0x00000000, "Input test: Quad 4(2crd-rightorder) returned color 0x%08x, expected 0x00000000\n", color);
7839 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7840 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
7842 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff808080, 0.0, 0);
7843 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
7845 /* Now find out if the whole streams are re-read, or just the last
7846 * active value for the vertices is used. */
7847 hr = IDirect3DDevice9_BeginScene(device);
7848 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7850 hr = IDirect3DDevice9_SetVertexShader(device, swapped_shader);
7851 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
7853 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_twotexcrd);
7854 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
7855 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 3, quad1_modified, sizeof(float) * 11);
7856 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7858 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_onetexcrd);
7859 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
7860 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_modified, sizeof(float) * 11);
7861 if (i == 3 || i == 2)
7862 ok(SUCCEEDED(hr), "Failed to draw, i %u, hr %#x.\n", i, hr);
7863 else if (i == 1)
7864 /* Succeeds or fails, depending on SW or HW vertex processing. */
7865 ok(hr == D3DERR_INVALIDCALL || hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
7867 hr = IDirect3DDevice9_EndScene(device);
7868 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7870 color = getPixelColor(device, 480, 350);
7871 /* vs_1_1 may fail, accept the clear color. Some drivers also set the undefined streams to 0, accept that
7872 * as well.
7874 * NOTE: This test fails on the reference rasterizer. In the refrast, the 4 vertices have different colors,
7875 * i.e., the whole old stream is read, and not just the last used attribute. Some games require that this
7876 * does *not* happen, otherwise they can crash because of a read from a bad pointer, so do not accept the
7877 * refrast's result.
7879 * A test app for this behavior is Half Life 2 Episode 2 in dxlevel 95, and related games(Portal, TF2).
7881 ok(color == 0x000000ff || color == 0x00808080 || color == 0x00000000
7882 || broken(color_match(color, D3DCOLOR_ARGB(0x00, 0x0b, 0x75, 0x80), 1)),
7883 "Got unexpected color 0x%08x for quad 2 (different colors).\n", color);
7885 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7886 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
7888 IDirect3DDevice9_SetVertexShader(device, NULL);
7889 IDirect3DDevice9_SetPixelShader(device, NULL);
7890 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7892 IDirect3DVertexShader9_Release(swapped_shader);
7895 for (i = 1; i <= 3; ++i)
7897 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
7898 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear returned %#x.\n", hr);
7899 if(i == 3) {
7900 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_3, &texcoord_color_shader);
7901 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
7902 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_3, &color_color_shader);
7903 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
7904 hr = IDirect3DDevice9_SetPixelShader(device, ps);
7905 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader returned %08x\n", hr);
7906 } else if(i == 2){
7907 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_2, &texcoord_color_shader);
7908 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
7909 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_2, &color_color_shader);
7910 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
7911 } else if(i == 1) {
7912 hr = IDirect3DDevice9_CreateVertexShader(device, texcoord_color_shader_code_1, &texcoord_color_shader);
7913 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
7914 hr = IDirect3DDevice9_CreateVertexShader(device, color_color_shader_code_1, &color_color_shader);
7915 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
7918 hr = IDirect3DDevice9_BeginScene(device);
7919 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7921 hr = IDirect3DDevice9_SetVertexShader(device, texcoord_color_shader);
7922 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
7923 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_texcoord_color);
7924 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
7925 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1_color, sizeof(quad1_color[0]));
7926 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7928 hr = IDirect3DDevice9_SetVertexShader(device, color_color_shader);
7929 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
7931 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, normalize, 1);
7932 ok(SUCCEEDED(hr), "Failed to set vertex shader constant, hr %#x.\n", hr);
7933 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_ubyte);
7934 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
7935 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2_color, sizeof(quad2_color[0]));
7936 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7938 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, no_normalize, 1);
7939 ok(SUCCEEDED(hr), "Failed to set vertex shader constant, hr %#x.\n", hr);
7940 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_color);
7941 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
7942 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3_color, sizeof(quad3_color[0]));
7943 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7945 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_color_float);
7946 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
7947 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4_color, sizeof(float) * 7);
7948 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7950 hr = IDirect3DDevice9_EndScene(device);
7951 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7953 color = getPixelColor(device, 160, 360);
7954 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
7955 "Input test: Quad 1(color-texcoord) returned color 0x%08x, expected 0x00ff8040\n", color);
7956 color = getPixelColor(device, 480, 360);
7957 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x40, 0x80, 0xff), 1),
7958 "Input test: Quad 2(color-ubyte) returned color 0x%08x, expected 0x004080ff\n", color);
7959 color = getPixelColor(device, 160, 120);
7960 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0x80, 0x40), 1),
7961 "Input test: Quad 3(color-color) returned color 0x%08x, expected 0x00ff8040\n", color);
7962 color = getPixelColor(device, 480, 160);
7963 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00), 1),
7964 "Input test: Quad 4(color-float) returned color 0x%08x, expected 0x00ffff00\n", color);
7966 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
7967 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
7969 hr = IDirect3DDevice9_SetVertexDeclaration(device, decl_nocolor);
7970 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
7972 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
7973 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
7975 hr = IDirect3DDevice9_BeginScene(device);
7976 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
7977 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_nocolor, sizeof(quad_nocolor[0]));
7978 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
7979 hr = IDirect3DDevice9_EndScene(device);
7980 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
7982 /* WARP ends up using the color attribute from the previous draw. Let's mark
7983 * that behavior as broken. */
7984 color = getPixelColor(device, 160, 360);
7985 ok(color_match(color, 0x00000000, 1)
7986 || broken(color_match(color, 0x00ffff00, 1)),
7987 "Got unexpected color 0x%08x for no color attribute test.\n", color);
7989 IDirect3DDevice9_SetVertexShader(device, NULL);
7990 IDirect3DDevice9_SetVertexDeclaration(device, NULL);
7991 IDirect3DDevice9_SetPixelShader(device, NULL);
7993 IDirect3DVertexShader9_Release(texcoord_color_shader);
7994 IDirect3DVertexShader9_Release(color_color_shader);
7997 IDirect3DVertexDeclaration9_Release(decl_twotexcrd);
7998 IDirect3DVertexDeclaration9_Release(decl_onetexcrd);
7999 IDirect3DVertexDeclaration9_Release(decl_twotex_wrongidx);
8000 IDirect3DVertexDeclaration9_Release(decl_twotexcrd_rightorder);
8002 IDirect3DVertexDeclaration9_Release(decl_texcoord_color);
8003 IDirect3DVertexDeclaration9_Release(decl_color_color);
8004 IDirect3DVertexDeclaration9_Release(decl_color_ubyte);
8005 IDirect3DVertexDeclaration9_Release(decl_color_float);
8006 IDirect3DVertexDeclaration9_Release(decl_nocolor);
8008 IDirect3DPixelShader9_Release(ps);
8009 refcount = IDirect3DDevice9_Release(device);
8010 ok(!refcount, "Device has %u references left.\n", refcount);
8011 done:
8012 IDirect3D9_Release(d3d);
8013 DestroyWindow(window);
8016 static void srgbtexture_test(void)
8018 /* Fill a texture with 0x7f (~ .5), and then turn on the D3DSAMP_SRGBTEXTURE
8019 * texture stage state to render a quad using that texture. The resulting
8020 * color components should be 0x36 (~ 0.21), per this formula:
8021 * linear_color = ((srgb_color + 0.055) / 1.055) ^ 2.4
8022 * This is true where srgb_color > 0.04045. */
8023 struct IDirect3DTexture9 *texture;
8024 struct IDirect3DSurface9 *surface;
8025 IDirect3DDevice9 *device;
8026 IDirect3D9 *d3d;
8027 D3DCOLOR color;
8028 ULONG refcount;
8029 HWND window;
8030 HRESULT hr;
8032 static const float quad[] =
8034 -1.0f, -1.0f, 0.0f, 0.0f, 1.0f,
8035 -1.0f, 1.0f, 0.0f, 0.0f, 0.0f,
8036 1.0f, -1.0f, 0.0f, 1.0f, 1.0f,
8037 1.0f, 1.0f, 0.0f, 1.0f, 0.0f,
8040 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
8041 0, 0, 640, 480, NULL, NULL, NULL, NULL);
8042 d3d = Direct3DCreate9(D3D_SDK_VERSION);
8043 ok(!!d3d, "Failed to create a D3D object.\n");
8044 if (!(device = create_device(d3d, window, window, TRUE)))
8046 skip("Failed to create a D3D device, skipping tests.\n");
8047 goto done;
8050 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
8051 D3DFMT_X8R8G8B8, D3DUSAGE_QUERY_SRGBREAD, D3DRTYPE_TEXTURE, D3DFMT_A8R8G8B8) != D3D_OK)
8053 skip("D3DFMT_A8R8G8B8 textures with SRGBREAD not supported.\n");
8054 IDirect3DDevice9_Release(device);
8055 goto done;
8058 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
8059 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
8060 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
8061 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
8063 fill_surface(surface, 0xff7f7f7f, 0);
8064 IDirect3DSurface9_Release(surface);
8066 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
8067 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8068 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
8069 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
8071 hr = IDirect3DDevice9_BeginScene(device);
8072 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
8074 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, TRUE);
8075 ok(SUCCEEDED(hr), "Failed to set sampler state, hr %#x.\n", hr);
8076 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8077 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
8078 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 5 * sizeof(float));
8079 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8081 hr = IDirect3DDevice9_EndScene(device);
8082 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
8084 color = getPixelColor(device, 320, 240);
8085 ok(color_match(color, 0x00363636, 1), "sRGB quad has color 0x%08x, expected 0x00363636.\n", color);
8087 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8088 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
8090 IDirect3DTexture9_Release(texture);
8091 refcount = IDirect3DDevice9_Release(device);
8092 ok(!refcount, "Device has %u references left.\n", refcount);
8093 done:
8094 IDirect3D9_Release(d3d);
8095 DestroyWindow(window);
8098 static void test_shademode(void)
8100 IDirect3DVertexBuffer9 *vb_strip;
8101 IDirect3DVertexBuffer9 *vb_list;
8102 IDirect3DVertexShader9 *vs;
8103 IDirect3DPixelShader9 *ps;
8104 IDirect3DDevice9 *device;
8105 DWORD color0, color1;
8106 void *data = NULL;
8107 IDirect3D9 *d3d;
8108 ULONG refcount;
8109 D3DCAPS9 caps;
8110 HWND window;
8111 HRESULT hr;
8112 UINT i;
8113 static const DWORD vs1_code[] =
8115 0xfffe0101, /* vs_1_1 */
8116 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
8117 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
8118 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
8119 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
8120 0x0000ffff
8122 static const DWORD vs2_code[] =
8124 0xfffe0200, /* vs_2_0 */
8125 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
8126 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
8127 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
8128 0x02000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
8129 0x0000ffff
8131 static const DWORD vs3_code[] =
8133 0xfffe0300, /* vs_3_0 */
8134 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
8135 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
8136 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
8137 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color0 o1 */
8138 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
8139 0x02000001, 0xe00f0001, 0x90e40001, /* mov o1, v1 */
8140 0x0000ffff
8142 static const DWORD ps1_code[] =
8144 0xffff0101, /* ps_1_1 */
8145 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
8146 0x0000ffff
8148 static const DWORD ps2_code[] =
8150 0xffff0200, /* ps_2_0 */
8151 0x0200001f, 0x80000000, 0x900f0000, /* dcl v0 */
8152 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
8153 0x0000ffff
8155 static const DWORD ps3_code[] =
8157 0xffff0300, /* ps_3_0 */
8158 0x0200001f, 0x8000000a, 0x900f0000, /* dcl_color0 v0 */
8159 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
8160 0x0000ffff
8162 static const struct
8164 struct vec3 position;
8165 DWORD diffuse;
8167 quad_strip[] =
8169 {{-1.0f, -1.0f, 0.0f}, 0xffff0000},
8170 {{-1.0f, 1.0f, 0.0f}, 0xff00ff00},
8171 {{ 1.0f, -1.0f, 0.0f}, 0xff0000ff},
8172 {{ 1.0f, 1.0f, 0.0f}, 0xffffffff},
8174 quad_list[] =
8176 {{-1.0f, -1.0f, 0.0f}, 0xffff0000},
8177 {{-1.0f, 1.0f, 0.0f}, 0xff00ff00},
8178 {{ 1.0f, -1.0f, 0.0f}, 0xff0000ff},
8180 {{ 1.0f, -1.0f, 0.0f}, 0xff0000ff},
8181 {{-1.0f, 1.0f, 0.0f}, 0xff00ff00},
8182 {{ 1.0f, 1.0f, 0.0f}, 0xffffffff},
8184 static const struct test_shader
8186 DWORD version;
8187 const DWORD *code;
8189 novs = {0, NULL},
8190 vs_1 = {D3DVS_VERSION(1, 1), vs1_code},
8191 vs_2 = {D3DVS_VERSION(2, 0), vs2_code},
8192 vs_3 = {D3DVS_VERSION(3, 0), vs3_code},
8193 nops = {0, NULL},
8194 ps_1 = {D3DPS_VERSION(1, 1), ps1_code},
8195 ps_2 = {D3DPS_VERSION(2, 0), ps2_code},
8196 ps_3 = {D3DPS_VERSION(3, 0), ps3_code};
8197 static const struct
8199 const struct test_shader *vs, *ps;
8200 DWORD primtype;
8201 DWORD shademode;
8202 DWORD color0, color1;
8203 BOOL todo;
8205 tests[] =
8207 {&novs, &nops, D3DPT_TRIANGLESTRIP, D3DSHADE_FLAT, 0x00ff0000, 0x0000ff00, FALSE},
8208 {&novs, &nops, D3DPT_TRIANGLESTRIP, D3DSHADE_PHONG, 0x000dca28, 0x000d45c7, FALSE},
8209 {&novs, &nops, D3DPT_TRIANGLESTRIP, D3DSHADE_GOURAUD, 0x000dca28, 0x000d45c7, FALSE},
8210 {&novs, &nops, D3DPT_TRIANGLESTRIP, D3DSHADE_PHONG, 0x000dca28, 0x000d45c7, FALSE},
8211 {&novs, &nops, D3DPT_TRIANGLELIST, D3DSHADE_FLAT, 0x00ff0000, 0x000000ff, FALSE},
8212 {&novs, &nops, D3DPT_TRIANGLELIST, D3DSHADE_GOURAUD, 0x000dca28, 0x000d45c7, FALSE},
8213 {&vs_1, &ps_1, D3DPT_TRIANGLESTRIP, D3DSHADE_FLAT, 0x00ff0000, 0x0000ff00, FALSE},
8214 {&vs_1, &ps_1, D3DPT_TRIANGLESTRIP, D3DSHADE_GOURAUD, 0x000dca28, 0x000d45c7, FALSE},
8215 {&vs_1, &ps_1, D3DPT_TRIANGLELIST, D3DSHADE_FLAT, 0x00ff0000, 0x000000ff, FALSE},
8216 {&vs_1, &ps_1, D3DPT_TRIANGLELIST, D3DSHADE_GOURAUD, 0x000dca28, 0x000d45c7, FALSE},
8217 {&novs, &ps_1, D3DPT_TRIANGLESTRIP, D3DSHADE_FLAT, 0x00ff0000, 0x0000ff00, FALSE},
8218 {&vs_1, &nops, D3DPT_TRIANGLESTRIP, D3DSHADE_FLAT, 0x00ff0000, 0x0000ff00, FALSE},
8219 {&vs_2, &ps_2, D3DPT_TRIANGLESTRIP, D3DSHADE_FLAT, 0x00ff0000, 0x0000ff00, FALSE},
8220 {&vs_2, &ps_2, D3DPT_TRIANGLESTRIP, D3DSHADE_GOURAUD, 0x000dca28, 0x000d45c7, FALSE},
8221 {&vs_3, &ps_3, D3DPT_TRIANGLESTRIP, D3DSHADE_FLAT, 0x00ff0000, 0x0000ff00, TRUE},
8222 {&vs_3, &ps_3, D3DPT_TRIANGLESTRIP, D3DSHADE_GOURAUD, 0x000dca28, 0x000d45c7, FALSE},
8225 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
8226 0, 0, 640, 480, NULL, NULL, NULL, NULL);
8227 d3d = Direct3DCreate9(D3D_SDK_VERSION);
8228 ok(!!d3d, "Failed to create a D3D object.\n");
8229 if (!(device = create_device(d3d, window, window, TRUE)))
8231 skip("Failed to create a D3D device, skipping tests.\n");
8232 goto done;
8235 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
8236 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8237 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
8238 ok(SUCCEEDED(hr), "Failed to disable fog, hr %#x.\n", hr);
8240 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8241 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
8243 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_strip), 0, 0, D3DPOOL_MANAGED, &vb_strip, NULL);
8244 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
8245 hr = IDirect3DVertexBuffer9_Lock(vb_strip, 0, sizeof(quad_strip), &data, 0);
8246 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
8247 memcpy(data, quad_strip, sizeof(quad_strip));
8248 hr = IDirect3DVertexBuffer9_Unlock(vb_strip);
8249 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
8251 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad_list), 0, 0, D3DPOOL_MANAGED, &vb_list, NULL);
8252 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
8253 hr = IDirect3DVertexBuffer9_Lock(vb_list, 0, sizeof(quad_list), &data, 0);
8254 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
8255 memcpy(data, quad_list, sizeof(quad_list));
8256 hr = IDirect3DVertexBuffer9_Unlock(vb_list);
8257 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
8259 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8260 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
8262 /* Try it first with a TRIANGLESTRIP. Do it with different geometry because
8263 * the color fixups we have to do for FLAT shading will be dependent on that. */
8265 for (i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i)
8267 if (tests[i].vs->version)
8269 if (caps.VertexShaderVersion >= tests[i].vs->version)
8271 hr = IDirect3DDevice9_CreateVertexShader(device, tests[i].vs->code, &vs);
8272 ok(hr == D3D_OK, "Failed to create vertex shader, hr %#x.\n", hr);
8273 hr = IDirect3DDevice9_SetVertexShader(device, vs);
8274 ok(hr == D3D_OK, "Failed to set vertex shader, hr %#x.\n", hr);
8276 else
8278 skip("Shader version unsupported, skipping some tests.\n");
8279 continue;
8282 else
8284 vs = NULL;
8286 if (tests[i].ps->version)
8288 if (caps.PixelShaderVersion >= tests[i].ps->version)
8290 hr = IDirect3DDevice9_CreatePixelShader(device, tests[i].ps->code, &ps);
8291 ok(hr == D3D_OK, "Failed to create pixel shader, hr %#x.\n", hr);
8292 hr = IDirect3DDevice9_SetPixelShader(device, ps);
8293 ok(hr == D3D_OK, "Failed to set pixel shader, hr %#x.\n", hr);
8295 else
8297 skip("Shader version unsupported, skipping some tests.\n");
8298 if (vs)
8300 IDirect3DDevice9_SetVertexShader(device, NULL);
8301 IDirect3DVertexShader9_Release(vs);
8303 continue;
8306 else
8308 ps = NULL;
8311 hr = IDirect3DDevice9_SetStreamSource(device, 0,
8312 tests[i].primtype == D3DPT_TRIANGLESTRIP ? vb_strip : vb_list, 0, sizeof(quad_strip[0]));
8313 ok(hr == D3D_OK, "Failed to set stream source, hr %#x.\n", hr);
8315 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
8316 ok(hr == D3D_OK, "Failed to clear, hr %#x.\n", hr);
8318 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, tests[i].shademode);
8319 ok(hr == D3D_OK, "Failed to set shade mode, hr %#x.\n", hr);
8321 hr = IDirect3DDevice9_BeginScene(device);
8322 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
8323 hr = IDirect3DDevice9_DrawPrimitive(device, tests[i].primtype, 0, 2);
8324 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8325 hr = IDirect3DDevice9_EndScene(device);
8326 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
8328 color0 = getPixelColor(device, 100, 100); /* Inside first triangle */
8329 color1 = getPixelColor(device, 500, 350); /* Inside second triangle */
8331 /* For D3DSHADE_FLAT it should take the color of the first vertex of
8332 * each triangle. This requires EXT_provoking_vertex or similar
8333 * functionality being available. */
8334 /* PHONG should be the same as GOURAUD, since no hardware implements
8335 * this. */
8336 if (tests[i].todo)
8338 todo_wine ok(color0 == tests[i].color0, "Test %u shading has color0 %08x, expected %08x.\n",
8339 i, color0, tests[i].color0);
8340 todo_wine ok(color1 == tests[i].color1, "Test %u shading has color1 %08x, expected %08x.\n",
8341 i, color1, tests[i].color1);
8343 else
8345 ok(color0 == tests[i].color0, "Test %u shading has color0 %08x, expected %08x.\n",
8346 i, color0, tests[i].color0);
8347 ok(color1 == tests[i].color1, "Test %u shading has color1 %08x, expected %08x.\n",
8348 i, color1, tests[i].color1);
8350 IDirect3DDevice9_SetVertexShader(device, NULL);
8351 IDirect3DDevice9_SetPixelShader(device, NULL);
8353 if (ps)
8354 IDirect3DPixelShader9_Release(ps);
8355 if (vs)
8356 IDirect3DVertexShader9_Release(vs);
8359 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8360 ok(hr == D3D_OK, "Failed to present, hr %#x.\n", hr);
8362 IDirect3DVertexBuffer9_Release(vb_strip);
8363 IDirect3DVertexBuffer9_Release(vb_list);
8364 refcount = IDirect3DDevice9_Release(device);
8365 ok(!refcount, "Device has %u references left.\n", refcount);
8366 done:
8367 IDirect3D9_Release(d3d);
8368 DestroyWindow(window);
8371 static void test_blend(void)
8373 IDirect3DSurface9 *backbuffer, *offscreen;
8374 IDirect3DTexture9 *offscreenTexture;
8375 IDirect3DDevice9 *device;
8376 IDirect3D9 *d3d;
8377 D3DCOLOR color;
8378 ULONG refcount;
8379 HWND window;
8380 HRESULT hr;
8382 static const struct
8384 struct vec3 position;
8385 DWORD diffuse;
8387 quad1[] =
8389 {{-1.0f, -1.0f, 0.1f}, 0x4000ff00},
8390 {{-1.0f, 0.0f, 0.1f}, 0x4000ff00},
8391 {{ 1.0f, -1.0f, 0.1f}, 0x4000ff00},
8392 {{ 1.0f, 0.0f, 0.1f}, 0x4000ff00},
8394 quad2[] =
8396 {{-1.0f, 0.0f, 0.1f}, 0xc00000ff},
8397 {{-1.0f, 1.0f, 0.1f}, 0xc00000ff},
8398 {{ 1.0f, 0.0f, 0.1f}, 0xc00000ff},
8399 {{ 1.0f, 1.0f, 0.1f}, 0xc00000ff},
8401 static const float composite_quad[][5] =
8403 { 0.0f, -1.0f, 0.1f, 0.0f, 1.0f},
8404 { 0.0f, 1.0f, 0.1f, 0.0f, 0.0f},
8405 { 1.0f, -1.0f, 0.1f, 1.0f, 1.0f},
8406 { 1.0f, 1.0f, 0.1f, 1.0f, 0.0f},
8409 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
8410 0, 0, 640, 480, NULL, NULL, NULL, NULL);
8411 d3d = Direct3DCreate9(D3D_SDK_VERSION);
8412 ok(!!d3d, "Failed to create a D3D object.\n");
8413 if (!(device = create_device(d3d, window, window, TRUE)))
8415 skip("Failed to create a D3D device, skipping tests.\n");
8416 goto done;
8419 /* Clear the render target with alpha = 0.5 */
8420 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x80ff0000, 1.0f, 0);
8421 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
8423 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET,
8424 D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
8425 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
8427 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
8428 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
8430 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
8431 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
8433 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
8434 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %#08x\n", hr);
8436 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
8437 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8438 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
8439 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
8440 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
8441 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
8442 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
8443 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
8444 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
8445 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
8447 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
8448 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
8449 hr = IDirect3DDevice9_BeginScene(device);
8450 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
8452 /* Draw two quads, one with src alpha blending, one with dest alpha
8453 * blending. */
8454 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
8455 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
8456 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
8457 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
8458 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
8459 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8461 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
8462 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
8463 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
8464 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
8465 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
8466 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8468 /* Switch to the offscreen buffer, and redo the testing. The offscreen
8469 * render target doesn't have an alpha channel. DESTALPHA and INVDESTALPHA
8470 * "don't work" on render targets without alpha channel, they give
8471 * essentially ZERO and ONE blend factors. */
8472 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
8473 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
8474 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x80ff0000, 1.0f, 0);
8475 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
8477 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
8478 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
8479 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
8480 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
8481 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
8482 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8484 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_DESTALPHA);
8485 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
8486 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVDESTALPHA);
8487 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
8488 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
8489 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8491 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
8492 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
8494 /* Render the offscreen texture onto the frame buffer to be able to
8495 * compare it regularly. Disable alpha blending for the final
8496 * composition. */
8497 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
8498 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
8499 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
8500 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
8502 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) offscreenTexture);
8503 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
8504 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, composite_quad, sizeof(float) * 5);
8505 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8507 hr = IDirect3DDevice9_EndScene(device);
8508 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
8510 color = getPixelColor(device, 160, 360);
8511 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
8512 "SRCALPHA on frame buffer returned color %08x, expected 0x00bf4000\n", color);
8514 color = getPixelColor(device, 160, 120);
8515 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x7f, 0x00, 0x80), 2),
8516 "DSTALPHA on frame buffer returned color %08x, expected 0x007f0080\n", color);
8518 color = getPixelColor(device, 480, 360);
8519 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0xbf, 0x40, 0x00), 1),
8520 "SRCALPHA on texture returned color %08x, expected 0x00bf4000\n", color);
8522 color = getPixelColor(device, 480, 120);
8523 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff), 1),
8524 "DSTALPHA on texture returned color %08x, expected 0x000000ff\n", color);
8526 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8528 IDirect3DSurface9_Release(backbuffer);
8529 IDirect3DTexture9_Release(offscreenTexture);
8530 IDirect3DSurface9_Release(offscreen);
8531 refcount = IDirect3DDevice9_Release(device);
8532 ok(!refcount, "Device has %u references left.\n", refcount);
8533 done:
8534 IDirect3D9_Release(d3d);
8535 DestroyWindow(window);
8538 static void fixed_function_decl_test(void)
8540 IDirect3DVertexDeclaration9 *dcl_float = NULL, *dcl_short = NULL, *dcl_ubyte = NULL, *dcl_color = NULL;
8541 IDirect3DVertexDeclaration9 *dcl_color_2 = NULL, *dcl_ubyte_2 = NULL, *dcl_nocolor, *dcl_positiont;
8542 IDirect3DVertexBuffer9 *vb, *vb2;
8543 IDirect3DDevice9 *device;
8544 BOOL s_ok, ub_ok, f_ok;
8545 DWORD color, size, i;
8546 IDirect3D9 *d3d;
8547 ULONG refcount;
8548 D3DCAPS9 caps;
8549 HWND window;
8550 void *data;
8551 HRESULT hr;
8553 static const D3DVERTEXELEMENT9 decl_elements_d3dcolor[] = {
8554 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8555 {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
8556 D3DDECL_END()
8558 static const D3DVERTEXELEMENT9 decl_elements_d3dcolor_2streams[] = {
8559 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8560 {1, 0, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
8561 D3DDECL_END()
8563 static const D3DVERTEXELEMENT9 decl_elements_ubyte4n[] = {
8564 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8565 {0, 12, D3DDECLTYPE_UBYTE4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
8566 D3DDECL_END()
8568 static const D3DVERTEXELEMENT9 decl_elements_ubyte4n_2streams[] = {
8569 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8570 {1, 0, D3DDECLTYPE_UBYTE4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
8571 D3DDECL_END()
8573 static const D3DVERTEXELEMENT9 decl_elements_short4[] = {
8574 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8575 {0, 12, D3DDECLTYPE_USHORT4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
8576 D3DDECL_END()
8578 static const D3DVERTEXELEMENT9 decl_elements_float[] = {
8579 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8580 {0, 12, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
8581 D3DDECL_END()
8583 static const D3DVERTEXELEMENT9 decl_elements_nocolor[] = {
8584 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
8585 D3DDECL_END()
8587 static const D3DVERTEXELEMENT9 decl_elements_positiont[] = {
8588 {0, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT, 0},
8589 {0, 16, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
8590 D3DDECL_END()
8592 static const struct
8594 struct vec3 position;
8595 DWORD diffuse;
8597 quad1[] = /* D3DCOLOR */
8599 {{-1.0f, -1.0f, 0.1f}, 0x00ffff00},
8600 {{-1.0f, 0.0f, 0.1f}, 0x00ffff00},
8601 {{ 0.0f, -1.0f, 0.1f}, 0x00ffff00},
8602 {{ 0.0f, 0.0f, 0.1f}, 0x00ffff00},
8604 quad2[] = /* UBYTE4N */
8606 {{-1.0f, 0.0f, 0.1f}, 0x00ffff00},
8607 {{-1.0f, 1.0f, 0.1f}, 0x00ffff00},
8608 {{ 0.0f, 0.0f, 0.1f}, 0x00ffff00},
8609 {{ 0.0f, 1.0f, 0.1f}, 0x00ffff00},
8611 static const struct
8613 struct vec3 position;
8614 struct { unsigned short x, y, z, w; } color;
8616 quad3[] = /* USHORT4N */
8618 {{0.0f, -1.0f, 0.1f}, {0x0000, 0x0000, 0xffff, 0xffff}},
8619 {{0.0f, 0.0f, 0.1f}, {0x0000, 0x0000, 0xffff, 0xffff}},
8620 {{1.0f, -1.0f, 0.1f}, {0x0000, 0x0000, 0xffff, 0xffff}},
8621 {{1.0f, 0.0f, 0.1f}, {0x0000, 0x0000, 0xffff, 0xffff}},
8623 static const struct
8625 struct vec3 position;
8626 struct vec4 color;
8628 quad4[] =
8630 {{0.0f, 0.0f, 0.1f}, {1.0f, 0.0f, 0.0f, 0.0f}},
8631 {{0.0f, 1.0f, 0.1f}, {1.0f, 0.0f, 0.0f, 0.0f}},
8632 {{1.0f, 0.0f, 0.1f}, {1.0f, 0.0f, 0.0f, 0.0f}},
8633 {{1.0f, 1.0f, 0.1f}, {1.0f, 0.0f, 0.0f, 0.0f}},
8635 static const DWORD colors[] =
8637 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8638 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8639 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8640 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8641 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8642 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8643 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8644 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8645 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8646 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8647 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8648 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8649 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8650 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8651 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8652 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff,
8654 static const float quads[] =
8656 -1.0f, -1.0f, 0.1f,
8657 -1.0f, 0.0f, 0.1f,
8658 0.0f, -1.0f, 0.1f,
8659 0.0f, 0.0f, 0.1f,
8661 0.0f, -1.0f, 0.1f,
8662 0.0f, 0.0f, 0.1f,
8663 1.0f, -1.0f, 0.1f,
8664 1.0f, 0.0f, 0.1f,
8666 0.0f, 0.0f, 0.1f,
8667 0.0f, 1.0f, 0.1f,
8668 1.0f, 0.0f, 0.1f,
8669 1.0f, 1.0f, 0.1f,
8671 -1.0f, 0.0f, 0.1f,
8672 -1.0f, 1.0f, 0.1f,
8673 0.0f, 0.0f, 0.1f,
8674 0.0f, 1.0f, 0.1f,
8676 static const struct
8678 struct vec4 position;
8679 DWORD diffuse;
8681 quad_transformed[] =
8683 {{ 90.0f, 110.0f, 0.1f, 2.0f}, 0x00ffff00},
8684 {{570.0f, 110.0f, 0.1f, 2.0f}, 0x00ffff00},
8685 {{ 90.0f, 300.0f, 0.1f, 2.0f}, 0x00ffff00},
8686 {{570.0f, 300.0f, 0.1f, 2.0f}, 0x00ffff00},
8689 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
8690 0, 0, 640, 480, NULL, NULL, NULL, NULL);
8691 d3d = Direct3DCreate9(D3D_SDK_VERSION);
8692 ok(!!d3d, "Failed to create a D3D object.\n");
8693 if (!(device = create_device(d3d, window, window, TRUE)))
8695 skip("Failed to create a D3D device, skipping tests.\n");
8696 goto done;
8699 memset(&caps, 0, sizeof(caps));
8700 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
8701 ok(hr == D3D_OK, "GetDeviceCaps failed, hr = %08x\n", hr);
8703 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
8704 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
8706 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor, &dcl_color);
8707 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
8708 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_short4, &dcl_short);
8709 ok(SUCCEEDED(hr) || hr == E_FAIL, "CreateVertexDeclaration failed (%08x)\n", hr);
8710 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_float, &dcl_float);
8711 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
8712 if(caps.DeclTypes & D3DDTCAPS_UBYTE4N) {
8713 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n_2streams, &dcl_ubyte_2);
8714 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
8715 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_ubyte4n, &dcl_ubyte);
8716 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
8717 } else {
8718 trace("D3DDTCAPS_UBYTE4N not supported\n");
8719 dcl_ubyte_2 = NULL;
8720 dcl_ubyte = NULL;
8722 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_d3dcolor_2streams, &dcl_color_2);
8723 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
8724 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_nocolor, &dcl_nocolor);
8725 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
8726 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements_positiont, &dcl_positiont);
8727 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (%08x)\n", hr);
8729 size = max(sizeof(quad1), max(sizeof(quad2), max(sizeof(quad3), max(sizeof(quad4), sizeof(quads)))));
8730 hr = IDirect3DDevice9_CreateVertexBuffer(device, size,
8731 0, 0, D3DPOOL_MANAGED, &vb, NULL);
8732 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
8734 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
8735 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
8737 hr = IDirect3DDevice9_BeginScene(device);
8738 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
8740 f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
8741 if (dcl_color)
8743 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
8744 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8745 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
8746 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8749 /* Tests with non-standard fixed function types fail on the refrast. The
8750 * ATI driver partially accepts them, the NVIDIA driver accepts them all.
8751 * All those differences even though we're using software vertex
8752 * processing. Doh! */
8753 if (dcl_ubyte)
8755 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
8756 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8757 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
8758 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
8759 ub_ok = SUCCEEDED(hr);
8762 if (dcl_short)
8764 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
8765 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8766 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(quad3[0]));
8767 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
8768 s_ok = SUCCEEDED(hr);
8771 if (dcl_float)
8773 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
8774 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8775 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(quad4[0]));
8776 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
8777 f_ok = SUCCEEDED(hr);
8780 hr = IDirect3DDevice9_EndScene(device);
8781 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
8783 if(dcl_short) {
8784 color = getPixelColor(device, 480, 360);
8785 ok(color == 0x000000ff || !s_ok,
8786 "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
8788 if(dcl_ubyte) {
8789 color = getPixelColor(device, 160, 120);
8790 ok(color == 0x0000ffff || !ub_ok,
8791 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
8793 if(dcl_color) {
8794 color = getPixelColor(device, 160, 360);
8795 ok(color == 0x00ffff00,
8796 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
8798 if(dcl_float) {
8799 color = getPixelColor(device, 480, 120);
8800 ok(color == 0x00ff0000 || !f_ok,
8801 "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
8803 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8805 /* The following test with vertex buffers doesn't serve to find out new
8806 * information from windows. It is a plain regression test because wined3d
8807 * uses different codepaths for attribute conversion with vertex buffers.
8808 * It makes sure that the vertex buffer one works, while the above tests
8809 * whether the immediate mode code works. */
8810 f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
8811 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
8812 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
8813 hr = IDirect3DDevice9_BeginScene(device);
8814 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
8816 if (dcl_color)
8818 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad1), &data, 0);
8819 ok(SUCCEEDED(hr), "Failed to lock vertex buffer, hr %#x.\n", hr);
8820 memcpy(data, quad1, sizeof(quad1));
8821 hr = IDirect3DVertexBuffer9_Unlock(vb);
8822 ok(SUCCEEDED(hr), "Failed to unlock vertex buffer, hr %#x.\n", hr);
8823 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
8824 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8825 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad1[0]));
8826 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
8827 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
8828 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8831 if (dcl_ubyte)
8833 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad2), &data, 0);
8834 ok(SUCCEEDED(hr), "Failed to lock vertex buffer, hr %#x.\n", hr);
8835 memcpy(data, quad2, sizeof(quad2));
8836 hr = IDirect3DVertexBuffer9_Unlock(vb);
8837 ok(SUCCEEDED(hr), "Failed to unlock vertex buffer, hr %#x.\n", hr);
8838 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
8839 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8840 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad2[0]));
8841 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
8842 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
8843 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
8844 ub_ok = SUCCEEDED(hr);
8847 if (dcl_short)
8849 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad3), &data, 0);
8850 ok(SUCCEEDED(hr), "Failed to lock vertex buffer, hr %#x.\n", hr);
8851 memcpy(data, quad3, sizeof(quad3));
8852 hr = IDirect3DVertexBuffer9_Unlock(vb);
8853 ok(SUCCEEDED(hr), "Failed to unlock vertex buffer, hr %#x.\n", hr);
8854 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
8855 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8856 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad3[0]));
8857 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
8858 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
8859 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
8860 s_ok = SUCCEEDED(hr);
8863 if (dcl_float)
8865 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad4), &data, 0);
8866 ok(SUCCEEDED(hr), "Failed to lock vertex buffer, hr %#x.\n", hr);
8867 memcpy(data, quad4, sizeof(quad4));
8868 hr = IDirect3DVertexBuffer9_Unlock(vb);
8869 ok(SUCCEEDED(hr), "Failed to unlock vertex buffer, hr %#x.\n", hr);
8870 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
8871 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8872 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad4[0]));
8873 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
8874 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
8875 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
8876 f_ok = SUCCEEDED(hr);
8879 hr = IDirect3DDevice9_EndScene(device);
8880 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
8882 if(dcl_short) {
8883 color = getPixelColor(device, 480, 360);
8884 ok(color == 0x000000ff || !s_ok,
8885 "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff\n", color);
8887 if(dcl_ubyte) {
8888 color = getPixelColor(device, 160, 120);
8889 ok(color == 0x0000ffff || !ub_ok,
8890 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff\n", color);
8892 if(dcl_color) {
8893 color = getPixelColor(device, 160, 360);
8894 ok(color == 0x00ffff00,
8895 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00\n", color);
8897 if(dcl_float) {
8898 color = getPixelColor(device, 480, 120);
8899 ok(color == 0x00ff0000 || !f_ok,
8900 "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000\n", color);
8902 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8904 /* Test with no diffuse color attribute. */
8905 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
8906 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
8908 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_nocolor);
8909 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8910 hr = IDirect3DDevice9_BeginScene(device);
8911 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
8912 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quads, sizeof(float) * 3);
8913 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8914 hr = IDirect3DDevice9_EndScene(device);
8915 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
8917 color = getPixelColor(device, 160, 360);
8918 ok(color == 0x00ffffff, "Got unexpected color 0x%08x in the no color attribute test.\n", color);
8920 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8922 /* Test what happens with specular lighting enabled and no specular color attribute. */
8923 f_ok = FALSE; s_ok = FALSE; ub_ok = FALSE;
8924 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
8925 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
8926 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARENABLE, TRUE);
8927 ok(SUCCEEDED(hr), "Failed to enable specular lighting, hr %#x.\n", hr);
8928 hr = IDirect3DDevice9_BeginScene(device);
8929 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
8931 if (dcl_color)
8933 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color);
8934 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8935 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
8936 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
8938 if (dcl_ubyte)
8940 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte);
8941 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8942 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
8943 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
8944 ub_ok = SUCCEEDED(hr);
8946 if (dcl_short)
8948 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_short);
8949 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8950 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(quad3[0]));
8951 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
8952 s_ok = SUCCEEDED(hr);
8954 if (dcl_float)
8956 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_float);
8957 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
8958 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(quad4[0]));
8959 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
8960 f_ok = SUCCEEDED(hr);
8963 hr = IDirect3DDevice9_EndScene(device);
8964 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
8965 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SPECULARENABLE, FALSE);
8966 ok(SUCCEEDED(hr), "Failed to disable specular lighting, hr %#x.\n", hr);
8968 if (dcl_short)
8970 color = getPixelColor(device, 480, 360);
8971 ok(color == 0x000000ff || !s_ok,
8972 "D3DDECLTYPE_USHORT4N returned color %08x, expected 0x000000ff.\n", color);
8974 if (dcl_ubyte)
8976 color = getPixelColor(device, 160, 120);
8977 ok(color == 0x0000ffff || !ub_ok,
8978 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x0000ffff.\n", color);
8980 if (dcl_color)
8982 color = getPixelColor(device, 160, 360);
8983 ok(color == 0x00ffff00,
8984 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ffff00.\n", color);
8986 if (dcl_float)
8988 color = getPixelColor(device, 480, 120);
8989 ok(color == 0x00ff0000 || !f_ok,
8990 "D3DDECLTYPE_FLOAT4 returned color %08x, expected 0x00ff0000.\n", color);
8992 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
8994 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad_transformed), &data, 0);
8995 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
8996 memcpy(data, quad_transformed, sizeof(quad_transformed));
8997 hr = IDirect3DVertexBuffer9_Unlock(vb);
8998 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
9000 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_positiont);
9001 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed with %08x\n", hr);
9003 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
9004 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9006 hr = IDirect3DDevice9_BeginScene(device);
9007 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9008 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(quad_transformed[0]));
9009 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
9010 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
9011 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9012 hr = IDirect3DDevice9_EndScene(device);
9013 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9015 color = getPixelColor(device, 88, 108);
9016 ok(color == 0x000000ff,
9017 "pixel 88/108 has color %08x, expected 0x000000ff\n", color);
9018 color = getPixelColor(device, 92, 108);
9019 ok(color == 0x000000ff,
9020 "pixel 92/108 has color %08x, expected 0x000000ff\n", color);
9021 color = getPixelColor(device, 88, 112);
9022 ok(color == 0x000000ff,
9023 "pixel 88/112 has color %08x, expected 0x000000ff\n", color);
9024 color = getPixelColor(device, 92, 112);
9025 ok(color == 0x00ffff00,
9026 "pixel 92/112 has color %08x, expected 0x00ffff00\n", color);
9028 color = getPixelColor(device, 568, 108);
9029 ok(color == 0x000000ff,
9030 "pixel 568/108 has color %08x, expected 0x000000ff\n", color);
9031 color = getPixelColor(device, 572, 108);
9032 ok(color == 0x000000ff,
9033 "pixel 572/108 has color %08x, expected 0x000000ff\n", color);
9034 color = getPixelColor(device, 568, 112);
9035 ok(color == 0x00ffff00,
9036 "pixel 568/112 has color %08x, expected 0x00ffff00\n", color);
9037 color = getPixelColor(device, 572, 112);
9038 ok(color == 0x000000ff,
9039 "pixel 572/112 has color %08x, expected 0x000000ff\n", color);
9041 color = getPixelColor(device, 88, 298);
9042 ok(color == 0x000000ff,
9043 "pixel 88/298 has color %08x, expected 0x000000ff\n", color);
9044 color = getPixelColor(device, 92, 298);
9045 ok(color == 0x00ffff00,
9046 "pixel 92/298 has color %08x, expected 0x00ffff00\n", color);
9047 color = getPixelColor(device, 88, 302);
9048 ok(color == 0x000000ff,
9049 "pixel 88/302 has color %08x, expected 0x000000ff\n", color);
9050 color = getPixelColor(device, 92, 302);
9051 ok(color == 0x000000ff,
9052 "pixel 92/302 has color %08x, expected 0x000000ff\n", color);
9054 color = getPixelColor(device, 568, 298);
9055 ok(color == 0x00ffff00,
9056 "pixel 568/298 has color %08x, expected 0x00ffff00\n", color);
9057 color = getPixelColor(device, 572, 298);
9058 ok(color == 0x000000ff,
9059 "pixel 572/298 has color %08x, expected 0x000000ff\n", color);
9060 color = getPixelColor(device, 568, 302);
9061 ok(color == 0x000000ff,
9062 "pixel 568/302 has color %08x, expected 0x000000ff\n", color);
9063 color = getPixelColor(device, 572, 302);
9064 ok(color == 0x000000ff,
9065 "pixel 572/302 has color %08x, expected 0x000000ff\n", color);
9067 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9069 /* This test is pointless without those two declarations: */
9070 if((!dcl_color_2) || (!dcl_ubyte_2)) {
9071 skip("color-ubyte switching test declarations aren't supported\n");
9072 goto out;
9075 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quads), &data, 0);
9076 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9077 memcpy(data, quads, sizeof(quads));
9078 hr = IDirect3DVertexBuffer9_Unlock(vb);
9079 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
9080 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(colors),
9081 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
9082 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
9083 hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(colors), &data, 0);
9084 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
9085 memcpy(data, colors, sizeof(colors));
9086 hr = IDirect3DVertexBuffer9_Unlock(vb2);
9087 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed (%08x)\n", hr);
9089 for(i = 0; i < 2; i++) {
9090 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0, 0);
9091 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
9093 hr = IDirect3DDevice9_SetStreamSource(device, 0, vb, 0, sizeof(float) * 3);
9094 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
9095 if(i == 0) {
9096 hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 0, sizeof(DWORD) * 4);
9097 } else {
9098 hr = IDirect3DDevice9_SetStreamSource(device, 1, vb2, 8, sizeof(DWORD) * 4);
9100 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed with %08x\n", hr);
9102 hr = IDirect3DDevice9_BeginScene(device);
9103 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9105 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
9106 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
9107 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
9108 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
9109 ub_ok = SUCCEEDED(hr);
9111 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_color_2);
9112 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
9113 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
9114 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9116 hr = IDirect3DDevice9_SetVertexDeclaration(device, dcl_ubyte_2);
9117 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
9118 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
9119 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
9120 ub_ok = (SUCCEEDED(hr) && ub_ok);
9122 hr = IDirect3DDevice9_EndScene(device);
9123 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9125 if(i == 0) {
9126 color = getPixelColor(device, 480, 360);
9127 ok(color == 0x00ff0000,
9128 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x00ff0000\n", color);
9129 color = getPixelColor(device, 160, 120);
9130 ok(color == 0x00ffffff,
9131 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
9132 color = getPixelColor(device, 160, 360);
9133 ok(color == 0x000000ff || !ub_ok,
9134 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
9135 color = getPixelColor(device, 480, 120);
9136 ok(color == 0x000000ff || !ub_ok,
9137 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x000000ff\n", color);
9138 } else {
9139 color = getPixelColor(device, 480, 360);
9140 ok(color == 0x000000ff,
9141 "D3DDECLTYPE_D3DCOLOR returned color %08x, expected 0x000000ff\n", color);
9142 color = getPixelColor(device, 160, 120);
9143 ok(color == 0x00ffffff,
9144 "Unused quad returned color %08x, expected 0x00ffffff\n", color);
9145 color = getPixelColor(device, 160, 360);
9146 ok(color == 0x00ff0000 || !ub_ok,
9147 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
9148 color = getPixelColor(device, 480, 120);
9149 ok(color == 0x00ff0000 || !ub_ok,
9150 "D3DDECLTYPE_UBYTE4N returned color %08x, expected 0x00ff0000\n", color);
9152 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9155 IDirect3DVertexBuffer9_Release(vb2);
9156 out:
9157 IDirect3DVertexBuffer9_Release(vb);
9158 if(dcl_float) IDirect3DVertexDeclaration9_Release(dcl_float);
9159 if(dcl_short) IDirect3DVertexDeclaration9_Release(dcl_short);
9160 if(dcl_ubyte) IDirect3DVertexDeclaration9_Release(dcl_ubyte);
9161 if(dcl_color) IDirect3DVertexDeclaration9_Release(dcl_color);
9162 if(dcl_color_2) IDirect3DVertexDeclaration9_Release(dcl_color_2);
9163 if(dcl_ubyte_2) IDirect3DVertexDeclaration9_Release(dcl_ubyte_2);
9164 IDirect3DVertexDeclaration9_Release(dcl_nocolor);
9165 IDirect3DVertexDeclaration9_Release(dcl_positiont);
9166 refcount = IDirect3DDevice9_Release(device);
9167 ok(!refcount, "Device has %u references left.\n", refcount);
9168 done:
9169 IDirect3D9_Release(d3d);
9170 DestroyWindow(window);
9173 static void test_vshader_float16(void)
9175 IDirect3DVertexDeclaration9 *vdecl = NULL;
9176 IDirect3DVertexBuffer9 *buffer = NULL;
9177 IDirect3DVertexShader9 *shader;
9178 IDirect3DDevice9 *device;
9179 IDirect3D9 *d3d;
9180 ULONG refcount;
9181 D3DCAPS9 caps;
9182 DWORD color;
9183 HWND window;
9184 void *data;
9185 HRESULT hr;
9187 static const D3DVERTEXELEMENT9 decl_elements[] =
9189 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9190 {0, 12, D3DDECLTYPE_FLOAT16_4,D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
9191 D3DDECL_END()
9193 static const DWORD shader_code[] =
9195 0xfffe0101, /* vs_1_1 */
9196 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
9197 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color v1 */
9198 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
9199 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
9200 0x0000ffff,
9202 static const struct vertex_float16color
9204 float x, y, z;
9205 DWORD c1, c2;
9207 quad[] =
9209 { -1.0, -1.0, 0.1, 0x3c000000, 0x00000000 }, /* green */
9210 { -1.0, 0.0, 0.1, 0x3c000000, 0x00000000 },
9211 { 0.0, -1.0, 0.1, 0x3c000000, 0x00000000 },
9212 { 0.0, 0.0, 0.1, 0x3c000000, 0x00000000 },
9214 { 0.0, -1.0, 0.1, 0x00003c00, 0x00000000 }, /* red */
9215 { 0.0, 0.0, 0.1, 0x00003c00, 0x00000000 },
9216 { 1.0, -1.0, 0.1, 0x00003c00, 0x00000000 },
9217 { 1.0, 0.0, 0.1, 0x00003c00, 0x00000000 },
9219 { 0.0, 0.0, 0.1, 0x00000000, 0x00003c00 }, /* blue */
9220 { 0.0, 1.0, 0.1, 0x00000000, 0x00003c00 },
9221 { 1.0, 0.0, 0.1, 0x00000000, 0x00003c00 },
9222 { 1.0, 1.0, 0.1, 0x00000000, 0x00003c00 },
9224 { -1.0, 0.0, 0.1, 0x00000000, 0x3c000000 }, /* alpha */
9225 { -1.0, 1.0, 0.1, 0x00000000, 0x3c000000 },
9226 { 0.0, 0.0, 0.1, 0x00000000, 0x3c000000 },
9227 { 0.0, 1.0, 0.1, 0x00000000, 0x3c000000 },
9230 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
9231 0, 0, 640, 480, NULL, NULL, NULL, NULL);
9232 d3d = Direct3DCreate9(D3D_SDK_VERSION);
9233 ok(!!d3d, "Failed to create a D3D object.\n");
9234 if (!(device = create_device(d3d, window, window, TRUE)))
9236 skip("Failed to create a D3D device, skipping tests.\n");
9237 goto done;
9240 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9241 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
9242 if (caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
9244 skip("No vs_3_0 support, skipping tests.\n");
9245 IDirect3DDevice9_Release(device);
9246 goto done;
9249 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff102030, 1.0f, 0);
9250 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
9252 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vdecl);
9253 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x\n", hr);
9254 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
9255 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
9256 hr = IDirect3DDevice9_SetVertexShader(device, shader);
9257 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
9259 hr = IDirect3DDevice9_BeginScene(device);
9260 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9261 hr = IDirect3DDevice9_SetVertexDeclaration(device, vdecl);
9262 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
9263 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 0, sizeof(quad[0]));
9264 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9265 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 4, sizeof(quad[0]));
9266 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9267 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 8, sizeof(quad[0]));
9268 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9269 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad + 12, sizeof(quad[0]));
9270 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9271 hr = IDirect3DDevice9_EndScene(device);
9272 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9274 color = getPixelColor(device, 480, 360);
9275 ok(color == 0x00ff0000,
9276 "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
9277 color = getPixelColor(device, 160, 120);
9278 ok(color == 0x00000000,
9279 "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
9280 color = getPixelColor(device, 160, 360);
9281 ok(color == 0x0000ff00,
9282 "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
9283 color = getPixelColor(device, 480, 120);
9284 ok(color == 0x000000ff,
9285 "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
9286 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9288 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff102030, 0.0, 0);
9289 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
9291 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0,
9292 D3DPOOL_MANAGED, &buffer, NULL);
9293 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexBuffer failed, hr=%08x\n", hr);
9294 hr = IDirect3DVertexBuffer9_Lock(buffer, 0, sizeof(quad), &data, 0);
9295 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed, hr=%08x\n", hr);
9296 memcpy(data, quad, sizeof(quad));
9297 hr = IDirect3DVertexBuffer9_Unlock(buffer);
9298 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed, hr=%08x\n", hr);
9299 hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer, 0, sizeof(quad[0]));
9300 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSource failed, hr=%08x\n", hr);
9302 hr = IDirect3DDevice9_BeginScene(device);
9303 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9304 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, 2);
9305 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9306 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 4, 2);
9307 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9308 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 8, 2);
9309 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9310 hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 12, 2);
9311 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9312 hr = IDirect3DDevice9_EndScene(device);
9313 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9315 color = getPixelColor(device, 480, 360);
9316 ok(color == 0x00ff0000,
9317 "Input 0x00003c00, 0x00000000 returned color %08x, expected 0x00ff0000\n", color);
9318 color = getPixelColor(device, 160, 120);
9319 ok(color == 0x00000000,
9320 "Input 0x00000000, 0x3c000000 returned color %08x, expected 0x00000000\n", color);
9321 color = getPixelColor(device, 160, 360);
9322 ok(color == 0x0000ff00,
9323 "Input 0x3c000000, 0x00000000 returned color %08x, expected 0x0000ff00\n", color);
9324 color = getPixelColor(device, 480, 120);
9325 ok(color == 0x000000ff,
9326 "Input 0x00000000, 0x00003c00 returned color %08x, expected 0x000000ff\n", color);
9327 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9329 IDirect3DVertexDeclaration9_Release(vdecl);
9330 IDirect3DVertexShader9_Release(shader);
9331 IDirect3DVertexBuffer9_Release(buffer);
9332 refcount = IDirect3DDevice9_Release(device);
9333 ok(!refcount, "Device has %u references left.\n", refcount);
9334 done:
9335 IDirect3D9_Release(d3d);
9336 DestroyWindow(window);
9339 static void conditional_np2_repeat_test(void)
9341 IDirect3DTexture9 *texture;
9342 IDirect3DDevice9 *device;
9343 D3DLOCKED_RECT rect;
9344 unsigned int x, y;
9345 DWORD *dst, color;
9346 IDirect3D9 *d3d;
9347 ULONG refcount;
9348 D3DCAPS9 caps;
9349 HWND window;
9350 HRESULT hr;
9352 static const float quad[] =
9354 -1.0f, -1.0f, 0.1f, -0.2f, -0.2f,
9355 -1.0f, 1.0f, 0.1f, -0.2f, 1.2f,
9356 1.0f, -1.0f, 0.1f, 1.2f, -0.2f,
9357 1.0f, 1.0f, 0.1f, 1.2f, 1.2f,
9360 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
9361 0, 0, 640, 480, NULL, NULL, NULL, NULL);
9362 d3d = Direct3DCreate9(D3D_SDK_VERSION);
9363 ok(!!d3d, "Failed to create a D3D object.\n");
9364 if (!(device = create_device(d3d, window, window, TRUE)))
9366 skip("Failed to create a D3D device, skipping tests.\n");
9367 goto done;
9370 memset(&caps, 0, sizeof(caps));
9371 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9372 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
9373 if (caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL)
9375 /* NP2 conditional requires the POW2 flag. Check that while we're at it */
9376 ok(caps.TextureCaps & D3DPTEXTURECAPS_POW2,
9377 "Card has conditional NP2 support without power of two restriction set\n");
9379 else if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
9381 skip("No conditional NP2 support, skipping conditional NP2 tests\n");
9382 IDirect3DDevice9_Release(device);
9383 goto done;
9385 else
9387 skip("Card has unconditional NP2 support, skipping conditional NP2 tests\n");
9388 IDirect3DDevice9_Release(device);
9389 goto done;
9392 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff000000, 1.0f, 0);
9393 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
9395 hr = IDirect3DDevice9_CreateTexture(device, 10, 10, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
9396 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
9398 memset(&rect, 0, sizeof(rect));
9399 hr = IDirect3DTexture9_LockRect(texture, 0, &rect, NULL, 0);
9400 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
9401 for(y = 0; y < 10; y++) {
9402 for(x = 0; x < 10; x++) {
9403 dst = (DWORD *) ((BYTE *) rect.pBits + y * rect.Pitch + x * sizeof(DWORD));
9404 if(x == 0 || x == 9 || y == 0 || y == 9) {
9405 *dst = 0x00ff0000;
9406 } else {
9407 *dst = 0x000000ff;
9411 hr = IDirect3DTexture9_UnlockRect(texture, 0);
9412 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
9414 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
9415 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
9416 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9417 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
9418 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
9419 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
9420 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
9421 ok(hr == D3D_OK, "IDirect3DDevice9_SetSamplerState failed hr=%08x\n", hr);
9422 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9423 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexDeclaration failed, hr=%08x\n", hr);
9425 hr = IDirect3DDevice9_BeginScene(device);
9426 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9427 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
9428 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9429 hr = IDirect3DDevice9_EndScene(device);
9430 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9432 color = getPixelColor(device, 1, 1);
9433 ok(color == 0x00ff0000, "NP2: Pixel 1, 1 has color %08x, expected 0x00ff0000\n", color);
9434 color = getPixelColor(device, 639, 479);
9435 ok(color == 0x00ff0000, "NP2: Pixel 639, 479 has color %08x, expected 0x00ff0000\n", color);
9437 color = getPixelColor(device, 135, 101);
9438 ok(color == 0x00ff0000, "NP2: Pixel 135, 101 has color %08x, expected 0x00ff0000\n", color);
9439 color = getPixelColor(device, 140, 101);
9440 ok(color == 0x00ff0000, "NP2: Pixel 140, 101 has color %08x, expected 0x00ff0000\n", color);
9441 color = getPixelColor(device, 135, 105);
9442 ok(color == 0x00ff0000, "NP2: Pixel 135, 105 has color %08x, expected 0x00ff0000\n", color);
9443 color = getPixelColor(device, 140, 105);
9444 ok(color == 0x000000ff, "NP2: Pixel 140, 105 has color %08x, expected 0x000000ff\n", color);
9446 color = getPixelColor(device, 135, 376);
9447 ok(color == 0x00ff0000, "NP2: Pixel 135, 376 has color %08x, expected 0x00ff0000\n", color);
9448 color = getPixelColor(device, 140, 376);
9449 ok(color == 0x000000ff, "NP2: Pixel 140, 376 has color %08x, expected 0x000000ff\n", color);
9450 color = getPixelColor(device, 135, 379);
9451 ok(color == 0x00ff0000, "NP2: Pixel 135, 379 has color %08x, expected 0x00ff0000\n", color);
9452 color = getPixelColor(device, 140, 379);
9453 ok(color == 0x00ff0000, "NP2: Pixel 140, 379 has color %08x, expected 0x00ff0000\n", color);
9455 color = getPixelColor(device, 500, 101);
9456 ok(color == 0x00ff0000, "NP2: Pixel 500, 101 has color %08x, expected 0x00ff0000\n", color);
9457 color = getPixelColor(device, 504, 101);
9458 ok(color == 0x00ff0000, "NP2: Pixel 504, 101 has color %08x, expected 0x00ff0000\n", color);
9459 color = getPixelColor(device, 500, 105);
9460 ok(color == 0x000000ff, "NP2: Pixel 500, 105 has color %08x, expected 0x000000ff\n", color);
9461 color = getPixelColor(device, 504, 105);
9462 ok(color == 0x00ff0000, "NP2: Pixel 504, 105 has color %08x, expected 0x00ff0000\n", color);
9464 color = getPixelColor(device, 500, 376);
9465 ok(color == 0x000000ff, "NP2: Pixel 500, 376 has color %08x, expected 0x000000ff\n", color);
9466 color = getPixelColor(device, 504, 376);
9467 ok(color == 0x00ff0000, "NP2: Pixel 504, 376 has color %08x, expected 0x00ff0000\n", color);
9468 color = getPixelColor(device, 500, 380);
9469 ok(color == 0x00ff0000, "NP2: Pixel 500, 380 has color %08x, expected 0x00ff0000\n", color);
9470 color = getPixelColor(device, 504, 380);
9471 ok(color == 0x00ff0000, "NP2: Pixel 504, 380 has color %08x, expected 0x00ff0000\n", color);
9473 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9475 IDirect3DTexture9_Release(texture);
9476 refcount = IDirect3DDevice9_Release(device);
9477 ok(!refcount, "Device has %u references left.\n", refcount);
9478 done:
9479 IDirect3D9_Release(d3d);
9480 DestroyWindow(window);
9483 static void vface_register_test(void)
9485 IDirect3DSurface9 *surface, *backbuffer;
9486 IDirect3DVertexShader9 *vshader;
9487 IDirect3DPixelShader9 *shader;
9488 IDirect3DTexture9 *texture;
9489 IDirect3DDevice9 *device;
9490 IDirect3D9 *d3d;
9491 ULONG refcount;
9492 D3DCAPS9 caps;
9493 DWORD color;
9494 HWND window;
9495 HRESULT hr;
9497 static const DWORD shader_code[] =
9499 0xffff0300, /* ps_3_0 */
9500 0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
9501 0x05000051, 0xa00f0001, 0x3f800000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.0, 0.0, 0.0, 0.0 */
9502 0x0200001f, 0x80000000, 0x900f1001, /* dcl vFace */
9503 0x02000001, 0x800f0001, 0xa0e40001, /* mov r1, c1 */
9504 0x04000058, 0x800f0000, 0x90e41001, 0xa0e40000, 0x80e40001, /* cmp r0, vFace, c0, r1 */
9505 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
9506 0x0000ffff /* END */
9508 static const DWORD vshader_code[] =
9510 0xfffe0300, /* vs_3_0 */
9511 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
9512 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
9513 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
9514 0x0000ffff /* end */
9516 static const float quad[] =
9518 -1.0f, -1.0f, 0.1f,
9519 1.0f, -1.0f, 0.1f,
9520 -1.0f, 0.0f, 0.1f,
9522 1.0f, -1.0f, 0.1f,
9523 1.0f, 0.0f, 0.1f,
9524 -1.0f, 0.0f, 0.1f,
9526 -1.0f, 0.0f, 0.1f,
9527 -1.0f, 1.0f, 0.1f,
9528 1.0f, 0.0f, 0.1f,
9530 1.0f, 0.0f, 0.1f,
9531 -1.0f, 1.0f, 0.1f,
9532 1.0f, 1.0f, 0.1f,
9534 static const float blit[] =
9536 0.0f, -1.0f, 0.1f, 0.0f, 0.0f,
9537 1.0f, -1.0f, 0.1f, 1.0f, 0.0f,
9538 0.0f, 1.0f, 0.1f, 0.0f, 1.0f,
9539 1.0f, 1.0f, 0.1f, 1.0f, 1.0f,
9542 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
9543 0, 0, 640, 480, NULL, NULL, NULL, NULL);
9544 d3d = Direct3DCreate9(D3D_SDK_VERSION);
9545 ok(!!d3d, "Failed to create a D3D object.\n");
9546 if (!(device = create_device(d3d, window, window, TRUE)))
9548 skip("Failed to create a D3D device, skipping tests.\n");
9549 goto done;
9552 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9553 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
9554 if (caps.PixelShaderVersion < D3DPS_VERSION(3, 0) || caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
9556 skip("No shader model 3 support, skipping tests.\n");
9557 IDirect3DDevice9_Release(device);
9558 goto done;
9561 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
9562 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
9563 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
9564 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
9565 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, NULL);
9566 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
9567 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface);
9568 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed hr=%08x\n", hr);
9569 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
9570 ok(SUCCEEDED(hr), "Failed to set cull mode, hr %#x.\n", hr);
9571 hr = IDirect3DDevice9_SetPixelShader(device, shader);
9572 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
9573 hr = IDirect3DDevice9_SetVertexShader(device, vshader);
9574 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
9575 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
9576 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
9577 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
9578 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
9580 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
9581 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
9583 hr = IDirect3DDevice9_BeginScene(device);
9584 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9586 /* First, draw to the texture and the back buffer to test both offscreen and onscreen cases */
9587 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
9588 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
9589 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
9590 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
9591 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
9592 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9593 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
9594 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
9595 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 4, quad, sizeof(float) * 3);
9596 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9598 /* Blit the texture onto the back buffer to make it visible */
9599 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
9600 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
9601 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
9602 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
9603 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
9604 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
9605 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9606 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
9607 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9608 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
9609 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
9610 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
9611 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, blit, sizeof(float) * 5);
9612 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9614 hr = IDirect3DDevice9_EndScene(device);
9615 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9617 color = getPixelColor(device, 160, 360);
9618 ok(color == 0x00ff0000, "vFace: Onscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
9619 color = getPixelColor(device, 160, 120);
9620 ok(color == 0x0000ff00, "vFace: Onscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
9621 color = getPixelColor(device, 480, 360);
9622 ok(color == 0x0000ff00, "vFace: Offscreen rendered back facing quad has color 0x%08x, expected 0x0000ff00\n", color);
9623 color = getPixelColor(device, 480, 120);
9624 ok(color == 0x00ff0000, "vFace: Offscreen rendered front facing quad has color 0x%08x, expected 0x00ff0000\n", color);
9625 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9626 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
9628 IDirect3DPixelShader9_Release(shader);
9629 IDirect3DVertexShader9_Release(vshader);
9630 IDirect3DSurface9_Release(surface);
9631 IDirect3DSurface9_Release(backbuffer);
9632 IDirect3DTexture9_Release(texture);
9633 refcount = IDirect3DDevice9_Release(device);
9634 ok(!refcount, "Device has %u references left.\n", refcount);
9635 done:
9636 IDirect3D9_Release(d3d);
9637 DestroyWindow(window);
9640 static void fixed_function_bumpmap_test(void)
9642 IDirect3DVertexDeclaration9 *vertex_declaration;
9643 IDirect3DTexture9 *texture, *tex1, *tex2;
9644 D3DLOCKED_RECT locked_rect;
9645 IDirect3DDevice9 *device;
9646 BOOL L6V5U5_supported;
9647 float scale, offset;
9648 IDirect3D9 *d3d;
9649 unsigned int i;
9650 D3DCOLOR color;
9651 ULONG refcount;
9652 D3DCAPS9 caps;
9653 HWND window;
9654 HRESULT hr;
9656 static const float quad[][7] =
9658 {-1.0f, -1.0f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f},
9659 {-1.0f, 1.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f},
9660 { 1.0f, -1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 0.0f},
9661 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, 1.0f, 1.0f},
9663 static const D3DVERTEXELEMENT9 decl_elements[] =
9665 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
9666 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
9667 {0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
9668 D3DDECL_END()
9670 /* use asymmetric matrix to test loading */
9671 static const float bumpenvmat[4] = {0.0f, 0.5f, -0.5f, 0.0f};
9673 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
9674 0, 0, 640, 480, NULL, NULL, NULL, NULL);
9675 d3d = Direct3DCreate9(D3D_SDK_VERSION);
9676 ok(!!d3d, "Failed to create a D3D object.\n");
9677 if (!(device = create_device(d3d, window, window, TRUE)))
9679 skip("Failed to create a D3D device, skipping tests.\n");
9680 goto done;
9683 memset(&caps, 0, sizeof(caps));
9684 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9685 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
9686 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAP))
9688 skip("D3DTEXOPCAPS_BUMPENVMAP not set, skipping bumpmap tests\n");
9689 IDirect3DDevice9_Release(device);
9690 goto done;
9693 /* This check is disabled, some Windows drivers do not handle
9694 * D3DUSAGE_QUERY_LEGACYBUMPMAP properly. They report that it is not
9695 * supported, but after that bump mapping works properly. So just test if
9696 * the format is generally supported, and check the BUMPENVMAP flag. */
9697 L6V5U5_supported = SUCCEEDED(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
9698 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_L6V5U5));
9699 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
9700 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_V8U8)))
9702 skip("D3DFMT_V8U8 not supported for legacy bump mapping\n");
9703 IDirect3DDevice9_Release(device);
9704 return;
9707 /* Generate the textures */
9708 generate_bumpmap_textures(device);
9710 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT00, *(LPDWORD)&bumpenvmat[0]);
9711 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9712 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT01, *(LPDWORD)&bumpenvmat[1]);
9713 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9714 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT10, *(LPDWORD)&bumpenvmat[2]);
9715 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9716 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVMAT11, *(LPDWORD)&bumpenvmat[3]);
9717 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9719 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAP);
9720 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9721 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
9722 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9723 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_CURRENT );
9724 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9726 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
9727 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9728 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
9729 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9730 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
9731 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9733 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
9734 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9736 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
9737 ok(SUCCEEDED(hr), "SetVertexShader failed (%08x)\n", hr);
9739 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff00ff, 1.0f, 0);
9740 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed (%08x)\n", hr);
9742 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
9743 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed (0x%08x)\n", hr);
9744 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
9745 ok(SUCCEEDED(hr), "SetVertexDeclaration failed (0x%08x)\n", hr);
9747 hr = IDirect3DDevice9_BeginScene(device);
9748 ok(SUCCEEDED(hr), "BeginScene failed (0x%08x)\n", hr);
9750 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
9751 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed (0x%08x)\n", hr);
9753 hr = IDirect3DDevice9_EndScene(device);
9754 ok(SUCCEEDED(hr), "EndScene failed (0x%08x)\n", hr);
9756 color = getPixelColor(device, 240, 60);
9757 ok(color_match(color, 0x005ea000, 4), "Got unexpected color 0x%08x.\n", color);
9758 color = getPixelColor(device, 400, 60);
9759 ok(color_match(color, 0x009ea000, 4), "Got unexpected color 0x%08x.\n", color);
9760 color = getPixelColor(device, 80, 180);
9761 ok(color_match(color, 0x005ea000, 4), "Got unexpected color 0x%08x.\n", color);
9762 color = getPixelColor(device, 560, 180);
9763 ok(color_match(color, 0x009ea000, 4), "Got unexpected color 0x%08x.\n", color);
9764 color = getPixelColor(device, 80, 300);
9765 ok(color_match(color, 0x005e6000, 4), "Got unexpected color 0x%08x.\n", color);
9766 color = getPixelColor(device, 560, 300);
9767 ok(color_match(color, 0x009e6000, 4), "Got unexpected color 0x%08x.\n", color);
9768 color = getPixelColor(device, 240, 420);
9769 ok(color_match(color, 0x005e6000, 4), "Got unexpected color 0x%08x.\n", color);
9770 color = getPixelColor(device, 400, 420);
9771 ok(color_match(color, 0x009e6000, 4), "Got unexpected color 0x%08x.\n", color);
9772 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9773 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
9775 for(i = 0; i < 2; i++) {
9776 hr = IDirect3DDevice9_GetTexture(device, i, (IDirect3DBaseTexture9 **) &texture);
9777 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetTexture failed (0x%08x)\n", hr);
9778 IDirect3DTexture9_Release(texture); /* For the GetTexture */
9779 hr = IDirect3DDevice9_SetTexture(device, i, NULL);
9780 ok(SUCCEEDED(hr), "SetTexture failed (0x%08x)\n", hr);
9781 IDirect3DTexture9_Release(texture); /* To destroy it */
9784 if (!L6V5U5_supported || !(caps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAPLUMINANCE))
9786 skip("L6V5U5 / D3DTOP_BUMPENVMAPLUMINANCE not supported, skipping tests.\n");
9787 IDirect3DVertexDeclaration9_Release(vertex_declaration);
9788 IDirect3DDevice9_Release(device);
9789 goto done;
9792 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
9793 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
9794 /* This test only tests the luminance part. The bumpmapping part was already tested above and
9795 * would only make this test more complicated
9797 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_L6V5U5, D3DPOOL_MANAGED, &tex1, NULL);
9798 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
9799 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
9800 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
9802 memset(&locked_rect, 0, sizeof(locked_rect));
9803 hr = IDirect3DTexture9_LockRect(tex1, 0, &locked_rect, NULL, 0);
9804 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9805 *((DWORD *)locked_rect.pBits) = 0x4000; /* L = 0.25, V = 0.0, U = 0.0 */
9806 hr = IDirect3DTexture9_UnlockRect(tex1, 0);
9807 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
9809 memset(&locked_rect, 0, sizeof(locked_rect));
9810 hr = IDirect3DTexture9_LockRect(tex2, 0, &locked_rect, NULL, 0);
9811 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
9812 *((DWORD *)locked_rect.pBits) = 0x00ff80c0;
9813 hr = IDirect3DTexture9_UnlockRect(tex2, 0);
9814 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
9816 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
9817 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
9818 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
9819 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTexture failed (%08x)\n", hr);
9821 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BUMPENVMAPLUMINANCE);
9822 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9823 scale = 2.0;
9824 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
9825 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9826 offset = 0.1;
9827 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
9828 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9830 hr = IDirect3DDevice9_BeginScene(device);
9831 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9832 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
9833 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9834 hr = IDirect3DDevice9_EndScene(device);
9835 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9837 color = getPixelColor(device, 320, 240);
9838 /* red: 1.0 * (0.25 * 2.0 + 0.1) = 1.0 * 0.6 = 0.6 = 0x99
9839 * green: 0.5 * (0.25 * 2.0 + 0.1) = 0.5 * 0.6 = 0.3 = 0x4c
9840 * green: 0.75 * (0.25 * 2.0 + 0.1) = 0.75 * 0.6 = 0.45 = 0x72
9842 ok(color_match(color, 0x00994c72, 5), "bumpmap failed: Got color 0x%08x, expected 0x00994c72.\n", color);
9843 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9844 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
9846 /* Check a result scale factor > 1.0 */
9847 scale = 10;
9848 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
9849 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9850 offset = 10;
9851 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
9852 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9854 hr = IDirect3DDevice9_BeginScene(device);
9855 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9856 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
9857 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9858 hr = IDirect3DDevice9_EndScene(device);
9859 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9861 color = getPixelColor(device, 320, 240);
9862 ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
9863 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9864 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
9866 /* Check clamping in the scale factor calculation */
9867 scale = 1000;
9868 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLSCALE, *((DWORD *)&scale));
9869 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9870 offset = -1;
9871 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_BUMPENVLOFFSET, *((DWORD *)&offset));
9872 ok(SUCCEEDED(hr), "SetTextureStageState failed (%08x)\n", hr);
9874 hr = IDirect3DDevice9_BeginScene(device);
9875 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
9876 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(quad[0]));
9877 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
9878 hr = IDirect3DDevice9_EndScene(device);
9879 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
9881 color = getPixelColor(device, 320, 240);
9882 ok(color_match(color, 0x00ff80c0, 1), "bumpmap failed: Got color 0x%08x, expected 0x00ff80c0.\n", color);
9883 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
9884 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
9886 IDirect3DTexture9_Release(tex1);
9887 IDirect3DTexture9_Release(tex2);
9888 IDirect3DVertexDeclaration9_Release(vertex_declaration);
9889 refcount = IDirect3DDevice9_Release(device);
9890 ok(!refcount, "Device has %u references left.\n", refcount);
9891 done:
9892 IDirect3D9_Release(d3d);
9893 DestroyWindow(window);
9896 static void stencil_cull_test(void)
9898 IDirect3DDevice9 *device;
9899 IDirect3D9 *d3d;
9900 ULONG refcount;
9901 D3DCAPS9 caps;
9902 HWND window;
9903 HRESULT hr;
9904 static const float quad1[] =
9906 -1.0, -1.0, 0.1,
9907 0.0, -1.0, 0.1,
9908 -1.0, 0.0, 0.1,
9909 0.0, 0.0, 0.1,
9911 static const float quad2[] =
9913 0.0, -1.0, 0.1,
9914 1.0, -1.0, 0.1,
9915 0.0, 0.0, 0.1,
9916 1.0, 0.0, 0.1,
9918 static const float quad3[] =
9920 0.0, 0.0, 0.1,
9921 1.0, 0.0, 0.1,
9922 0.0, 1.0, 0.1,
9923 1.0, 1.0, 0.1,
9925 static const float quad4[] =
9927 -1.0, 0.0, 0.1,
9928 0.0, 0.0, 0.1,
9929 -1.0, 1.0, 0.1,
9930 0.0, 1.0, 0.1,
9932 struct
9934 struct vec3 position;
9935 DWORD diffuse;
9937 painter[] =
9939 {{-1.0f, -1.0f, 0.0f}, 0x00000000},
9940 {{ 1.0f, -1.0f, 0.0f}, 0x00000000},
9941 {{-1.0f, 1.0f, 0.0f}, 0x00000000},
9942 {{ 1.0f, 1.0f, 0.0f}, 0x00000000},
9944 static const WORD indices_cw[] = {0, 1, 3};
9945 static const WORD indices_ccw[] = {0, 2, 3};
9946 unsigned int i;
9947 DWORD color;
9949 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
9950 0, 0, 640, 480, NULL, NULL, NULL, NULL);
9951 d3d = Direct3DCreate9(D3D_SDK_VERSION);
9952 ok(!!d3d, "Failed to create a D3D object.\n");
9953 if (!(device = create_device(d3d, window, window, TRUE)))
9955 skip("Cannot create a device with a D24S8 stencil buffer.\n");
9956 DestroyWindow(window);
9957 IDirect3D9_Release(d3d);
9958 return;
9960 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
9961 ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
9962 if (!(caps.StencilCaps & D3DSTENCILCAPS_TWOSIDED))
9964 skip("No two sided stencil support\n");
9965 goto cleanup;
9968 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_STENCIL, 0x00ff0000, 0.0, 0x8);
9969 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
9970 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
9971 ok(SUCCEEDED(hr), "Failed to set FVF,hr %#x.\n", hr);
9973 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
9974 ok(hr == D3D_OK, "Failed to disable Z test, %#x.\n", hr);
9975 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
9976 ok(hr == D3D_OK, "Failed to disable lighting, %#x.\n", hr);
9977 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_INCR);
9978 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9979 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_DECR);
9980 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9981 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE);
9982 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9983 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, 0x3);
9984 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9986 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILFAIL, D3DSTENCILOP_REPLACE);
9987 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9988 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILZFAIL, D3DSTENCILOP_DECR);
9989 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9990 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CCW_STENCILPASS, D3DSTENCILOP_INCR);
9991 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9993 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, TRUE);
9994 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9995 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
9996 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
9998 /* First pass: Fill the stencil buffer with some values... */
9999 hr = IDirect3DDevice9_BeginScene(device);
10000 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
10002 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
10003 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10004 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
10005 1 /* PrimCount */, indices_cw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
10006 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10007 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
10008 1 /* PrimCount */, indices_ccw, D3DFMT_INDEX16, quad1, sizeof(float) * 3);
10009 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10011 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, TRUE);
10012 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10013 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
10014 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10015 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
10016 1 /* PrimCount */, indices_cw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
10017 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10018 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
10019 1 /* PrimCount */, indices_ccw, D3DFMT_INDEX16, quad2, sizeof(float) * 3);
10020 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10022 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CW);
10023 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10024 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
10025 1 /* PrimCount */, indices_cw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
10026 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10027 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
10028 1 /* PrimCount */, indices_ccw, D3DFMT_INDEX16, quad3, sizeof(float) * 3);
10029 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10031 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_CCW);
10032 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10033 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
10034 1 /* PrimCount */, indices_cw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
10035 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10036 hr = IDirect3DDevice9_DrawIndexedPrimitiveUP(device, D3DPT_TRIANGLELIST, 0 /* MinIndex */, 4 /* NumVerts */,
10037 1 /* PrimCount */, indices_ccw, D3DFMT_INDEX16, quad4, sizeof(float) * 3);
10038 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10040 hr = IDirect3DDevice9_EndScene(device);
10041 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
10043 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
10044 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10045 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
10046 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10047 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
10048 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10049 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TWOSIDEDSTENCILMODE, FALSE);
10050 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10051 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
10052 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10053 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILFUNC, D3DCMP_EQUAL);
10054 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10056 /* 2nd pass: Make the stencil values visible */
10057 hr = IDirect3DDevice9_BeginScene(device);
10058 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
10059 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
10060 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
10061 for (i = 0; i < 16; ++i)
10063 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILREF, i);
10064 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10066 painter[0].diffuse = (i * 16); /* Creates shades of blue */
10067 painter[1].diffuse = (i * 16);
10068 painter[2].diffuse = (i * 16);
10069 painter[3].diffuse = (i * 16);
10070 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, painter, sizeof(painter[0]));
10071 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10073 hr = IDirect3DDevice9_EndScene(device);
10074 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
10076 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
10077 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
10079 color = getPixelColor(device, 160, 420);
10080 ok(color == 0x00000030, "CCW triangle, twoside FALSE, cull cw, replace, has color 0x%08x, expected 0x00000030\n", color);
10081 color = getPixelColor(device, 160, 300);
10082 ok(color == 0x00000080, "CW triangle, twoside FALSE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
10084 color = getPixelColor(device, 480, 420);
10085 ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull off, incr, has color 0x%08x, expected 0x00000090\n", color);
10086 color = getPixelColor(device, 480, 300);
10087 ok(color == 0x00000030, "CW triangle, twoside TRUE, cull off, replace, has color 0x%08x, expected 0x00000030\n", color);
10089 color = getPixelColor(device, 160, 180);
10090 ok(color == 0x00000080, "CCW triangle, twoside TRUE, cull ccw, culled, has color 0x%08x, expected 0x00000080\n", color);
10091 color = getPixelColor(device, 160, 60);
10092 ok(color == 0x00000030, "CW triangle, twoside TRUE, cull ccw, replace, has color 0x%08x, expected 0x00000030\n", color);
10094 color = getPixelColor(device, 480, 180);
10095 ok(color == 0x00000090, "CCW triangle, twoside TRUE, cull cw, incr, has color 0x%08x, expected 0x00000090\n", color);
10096 color = getPixelColor(device, 480, 60);
10097 ok(color == 0x00000080, "CW triangle, twoside TRUE, cull cw, culled, has color 0x%08x, expected 0x00000080\n", color);
10099 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10100 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
10102 cleanup:
10103 refcount = IDirect3DDevice9_Release(device);
10104 ok(!refcount, "Device has %u references left.\n", refcount);
10105 IDirect3D9_Release(d3d);
10106 DestroyWindow(window);
10109 static void test_fragment_coords(void)
10111 IDirect3DSurface9 *surface = NULL, *backbuffer;
10112 IDirect3DPixelShader9 *shader, *shader_frac;
10113 IDirect3DVertexShader9 *vshader;
10114 IDirect3DDevice9 *device;
10115 D3DLOCKED_RECT lr;
10116 IDirect3D9 *d3d;
10117 ULONG refcount;
10118 D3DCAPS9 caps;
10119 DWORD color;
10120 HWND window;
10121 HRESULT hr;
10122 DWORD *pos;
10124 static const DWORD shader_code[] =
10126 0xffff0300, /* ps_3_0 */
10127 0x0200001f, 0x80000000, 0x90031000, /* dcl vPos.xy */
10128 0x03000002, 0x80030000, 0x90541000, 0xa1fe0000, /* sub r0.xy, vPos.xy, c0.zw */
10129 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */
10130 0x02000001, 0x80080002, 0xa0550000, /* mov r2.a, c0.y */
10131 0x02000001, 0x80010002, 0xa0550000, /* mov r2.r, c0.y */
10132 0x04000058, 0x80020002, 0x80000000, 0x80000001, 0x80550001, /* cmp r2.g, r0.x, r1.x, r1.y */
10133 0x04000058, 0x80040002, 0x80550000, 0x80000001, 0x80550001, /* cmp r2.b, r0.y, r1.x, r1.y */
10134 0x02000001, 0x800f0800, 0x80e40002, /* mov oC0, r2 */
10135 0x0000ffff /* end */
10137 static const DWORD shader_frac_code[] =
10139 0xffff0300, /* ps_3_0 */
10140 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, /* def c0, 0.0, 0.0, 0.0, 0.0 */
10141 0x0200001f, 0x80000000, 0x90031000, /* dcl vPos.xy */
10142 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
10143 0x02000013, 0x80030000, 0x90541000, /* frc r0.xy, vPos.xy */
10144 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
10145 0x0000ffff /* end */
10147 static const DWORD vshader_code[] =
10149 0xfffe0300, /* vs_3_0 */
10150 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
10151 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
10152 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
10153 0x0000ffff /* end */
10155 static const float quad[] =
10157 -1.0f, -1.0f, 0.1f, 0.0f, 0.0f,
10158 -1.0f, 1.0f, 0.1f, 0.0f, 1.0f,
10159 1.0f, -1.0f, 0.1f, 1.0f, 0.0f,
10160 1.0f, 1.0f, 0.1f, 1.0f, 1.0f,
10162 float constant[4] = {1.0, 0.0, 320, 240};
10164 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
10165 0, 0, 640, 480, NULL, NULL, NULL, NULL);
10166 d3d = Direct3DCreate9(D3D_SDK_VERSION);
10167 ok(!!d3d, "Failed to create a D3D object.\n");
10168 if (!(device = create_device(d3d, window, window, TRUE)))
10170 skip("Failed to create a D3D device, skipping tests.\n");
10171 goto done;
10174 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10175 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
10176 if (caps.PixelShaderVersion < D3DPS_VERSION(3, 0) || caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
10178 skip("No shader model 3 support, skipping tests.\n");
10179 IDirect3DDevice9_Release(device);
10180 goto done;
10183 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
10184 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
10185 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vshader);
10186 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
10187 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
10188 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
10189 hr = IDirect3DDevice9_CreatePixelShader(device, shader_frac_code, &shader_frac);
10190 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed hr=%08x\n", hr);
10191 hr = IDirect3DDevice9_SetPixelShader(device, shader);
10192 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
10193 hr = IDirect3DDevice9_SetVertexShader(device, vshader);
10194 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
10195 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10196 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
10197 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
10198 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed hr=%08x\n", hr);
10200 hr = IDirect3DDevice9_BeginScene(device);
10201 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
10202 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
10203 ok(SUCCEEDED(hr), "Failed to set pixel shader constant, hr %#x.\n", hr);
10204 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
10205 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10206 hr = IDirect3DDevice9_EndScene(device);
10207 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
10209 /* This has to be pixel exact */
10210 color = getPixelColor(device, 319, 239);
10211 ok(color == 0x00000000, "vPos: Pixel 319,239 has color 0x%08x, expected 0x00000000\n", color);
10212 color = getPixelColor(device, 320, 239);
10213 ok(color == 0x0000ff00, "vPos: Pixel 320,239 has color 0x%08x, expected 0x0000ff00\n", color);
10214 color = getPixelColor(device, 319, 240);
10215 ok(color == 0x000000ff, "vPos: Pixel 319,240 has color 0x%08x, expected 0x000000ff\n", color);
10216 color = getPixelColor(device, 320, 240);
10217 ok(color == 0x0000ffff, "vPos: Pixel 320,240 has color 0x%08x, expected 0x0000ffff\n", color);
10218 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10220 hr = IDirect3DDevice9_CreateRenderTarget(device, 32, 32, D3DFMT_X8R8G8B8, 0, 0, TRUE,
10221 &surface, NULL);
10222 ok(hr == D3D_OK, "IDirect3DDevice9_CreateRenderTarget failed hr=%08x\n", hr);
10223 hr = IDirect3DDevice9_BeginScene(device);
10224 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
10225 constant[2] = 16; constant[3] = 16;
10226 hr = IDirect3DDevice9_SetPixelShaderConstantF(device, 0, constant, 1);
10227 ok(SUCCEEDED(hr), "Failed to set pixel shader constant, hr %#x.\n", hr);
10228 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surface);
10229 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
10230 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
10231 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10232 hr = IDirect3DDevice9_EndScene(device);
10233 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
10235 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
10236 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
10238 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
10239 color = *pos & 0x00ffffff;
10240 ok(color == 0x00000000, "Pixel 14/14 has color 0x%08x, expected 0x00000000\n", color);
10241 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 18 * sizeof(DWORD));
10242 color = *pos & 0x00ffffff;
10243 ok(color == 0x0000ff00, "Pixel 14/18 has color 0x%08x, expected 0x0000ff00\n", color);
10244 pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 14 * sizeof(DWORD));
10245 color = *pos & 0x00ffffff;
10246 ok(color == 0x000000ff, "Pixel 18/14 has color 0x%08x, expected 0x000000ff\n", color);
10247 pos = (DWORD *) (((BYTE *) lr.pBits) + 18 * lr.Pitch + 18 * sizeof(DWORD));
10248 color = *pos & 0x00ffffff;
10249 ok(color == 0x0000ffff, "Pixel 18/18 has color 0x%08x, expected 0x0000ffff\n", color);
10251 hr = IDirect3DSurface9_UnlockRect(surface);
10252 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
10254 /* Test the fraction value of vPos. This is tested with the offscreen target and not the backbuffer to
10255 * have full control over the multisampling setting inside this test
10257 hr = IDirect3DDevice9_SetPixelShader(device, shader_frac);
10258 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
10259 hr = IDirect3DDevice9_BeginScene(device);
10260 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
10261 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
10262 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
10263 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
10264 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10265 hr = IDirect3DDevice9_EndScene(device);
10266 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
10268 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
10269 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
10271 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, D3DLOCK_READONLY);
10272 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr=%08x\n", hr);
10274 pos = (DWORD *) (((BYTE *) lr.pBits) + 14 * lr.Pitch + 14 * sizeof(DWORD));
10275 color = *pos & 0x00ffffff;
10276 ok(color == 0x00000000, "vPos fraction test has color 0x%08x, expected 0x00000000\n", color);
10278 hr = IDirect3DSurface9_UnlockRect(surface);
10279 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr=%08x\n", hr);
10281 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
10282 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed hr=%08x\n", hr);
10283 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
10284 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
10285 IDirect3DPixelShader9_Release(shader);
10286 IDirect3DPixelShader9_Release(shader_frac);
10287 IDirect3DVertexShader9_Release(vshader);
10288 if(surface) IDirect3DSurface9_Release(surface);
10289 IDirect3DSurface9_Release(backbuffer);
10290 refcount = IDirect3DDevice9_Release(device);
10291 ok(!refcount, "Device has %u references left.\n", refcount);
10292 done:
10293 IDirect3D9_Release(d3d);
10294 DestroyWindow(window);
10297 static BOOL point_match(IDirect3DDevice9 *device, UINT x, UINT y, UINT r)
10299 D3DCOLOR color;
10301 color = D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff);
10302 if (!color_match(getPixelColor(device, x + r, y), color, 1)) return FALSE;
10303 if (!color_match(getPixelColor(device, x - r, y), color, 1)) return FALSE;
10304 if (!color_match(getPixelColor(device, x, y + r), color, 1)) return FALSE;
10305 if (!color_match(getPixelColor(device, x, y - r), color, 1)) return FALSE;
10307 ++r;
10308 color = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff);
10309 if (!color_match(getPixelColor(device, x + r, y), color, 1)) return FALSE;
10310 if (!color_match(getPixelColor(device, x - r, y), color, 1)) return FALSE;
10311 if (!color_match(getPixelColor(device, x, y + r), color, 1)) return FALSE;
10312 if (!color_match(getPixelColor(device, x, y - r), color, 1)) return FALSE;
10314 return TRUE;
10317 static void test_pointsize(void)
10319 static const float a = 1.0f, b = 1.0f, c = 1.0f;
10320 float ptsize, ptsizemax_orig, ptsizemin_orig;
10321 IDirect3DSurface9 *rt, *backbuffer;
10322 IDirect3DTexture9 *tex1, *tex2;
10323 IDirect3DDevice9 *device;
10324 IDirect3DVertexShader9 *vs;
10325 IDirect3DPixelShader9 *ps;
10326 D3DLOCKED_RECT lr;
10327 IDirect3D9 *d3d;
10328 D3DCOLOR color;
10329 ULONG refcount;
10330 D3DCAPS9 caps;
10331 HWND window;
10332 HRESULT hr;
10333 unsigned int i, j;
10335 static const RECT rect = {0, 0, 128, 128};
10336 static const DWORD tex1_data[4] = {0x00ff0000, 0x00ff0000, 0x00000000, 0x00000000};
10337 static const DWORD tex2_data[4] = {0x00000000, 0x0000ff00, 0x00000000, 0x0000ff00};
10338 static const float vertices[] =
10340 64.0f, 64.0f, 0.1f,
10341 128.0f, 64.0f, 0.1f,
10342 192.0f, 64.0f, 0.1f,
10343 256.0f, 64.0f, 0.1f,
10344 320.0f, 64.0f, 0.1f,
10345 384.0f, 64.0f, 0.1f,
10346 448.0f, 64.0f, 0.1f,
10347 512.0f, 64.0f, 0.1f,
10349 static const struct
10351 float x, y, z;
10352 float point_size;
10354 vertex_pointsize = {64.0f, 64.0f, 0.1f, 48.0f},
10355 vertex_pointsize_scaled = {64.0f, 64.0f, 0.1f, 24.0f},
10356 vertex_pointsize_zero = {64.0f, 64.0f, 0.1f, 0.0f};
10357 static const DWORD vshader_code[] =
10359 0xfffe0101, /* vs_1_1 */
10360 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
10361 0x00000005, 0x800f0000, 0x90000000, 0xa0e40000, /* mul r0, v0.x, c0 */
10362 0x00000004, 0x800f0000, 0x90550000, 0xa0e40001, 0x80e40000, /* mad r0, v0.y, c1, r0 */
10363 0x00000004, 0x800f0000, 0x90aa0000, 0xa0e40002, 0x80e40000, /* mad r0, v0.z, c2, r0 */
10364 0x00000004, 0xc00f0000, 0x90ff0000, 0xa0e40003, 0x80e40000, /* mad oPos, v0.w, c3, r0 */
10365 0x0000ffff
10367 static const DWORD vshader_psize_code[] =
10369 0xfffe0101, /* vs_1_1 */
10370 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
10371 0x0000001f, 0x80000004, 0x900f0001, /* dcl_psize v1 */
10372 0x00000005, 0x800f0000, 0x90000000, 0xa0e40000, /* mul r0, v0.x, c0 */
10373 0x00000004, 0x800f0000, 0x90550000, 0xa0e40001, 0x80e40000, /* mad r0, v0.y, c1, r0 */
10374 0x00000004, 0x800f0000, 0x90aa0000, 0xa0e40002, 0x80e40000, /* mad r0, v0.z, c2, r0 */
10375 0x00000004, 0xc00f0000, 0x90ff0000, 0xa0e40003, 0x80e40000, /* mad oPos, v0.w, c3, r0 */
10376 0x00000001, 0xc00f0002, 0x90000001, /* mov oPts, v1.x */
10377 0x0000ffff
10379 static const DWORD pshader_code[] =
10381 0xffff0101, /* ps_1_1 */
10382 0x00000042, 0xb00f0000, /* tex t0 */
10383 0x00000042, 0xb00f0001, /* tex t1 */
10384 0x00000002, 0x800f0000, 0xb0e40000, 0xb0e40001, /* add r0, t0, t1 */
10385 0x0000ffff
10387 static const DWORD pshader2_code[] =
10389 0xffff0200, /* ps_2_0 */
10390 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
10391 0x0200001f, 0x80000000, 0xb00f0001, /* dcl t1 */
10392 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
10393 0x0200001f, 0x90000000, 0xa00f0801, /* dcl_2d s1 */
10394 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
10395 0x03000042, 0x800f0001, 0xb0e40001, 0xa0e40801, /* texld r1, t1, s1 */
10396 0x03000002, 0x800f0000, 0x80e40000, 0x80e40001, /* add r0, r0, r1 */
10397 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
10398 0x0000ffff
10400 static const DWORD pshader2_zw_code[] =
10402 0xffff0200, /* ps_2_0 */
10403 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
10404 0x0200001f, 0x80000000, 0xb00f0001, /* dcl t1 */
10405 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
10406 0x0200001f, 0x90000000, 0xa00f0801, /* dcl_2d s1 */
10407 0x02000001, 0x80030000, 0xb01b0000, /* mov r0.xy, t0.wzyx */
10408 0x02000001, 0x80030001, 0xb01b0001, /* mov r1.xy, t1.wzyx */
10409 0x03000042, 0x800f0000, 0x80e40000, 0xa0e40800, /* texld r0, r0, s0 */
10410 0x03000042, 0x800f0001, 0x80e40001, 0xa0e40801, /* texld r1, r1, s1 */
10411 0x03000002, 0x800f0000, 0x80e40000, 0x80e40001, /* add r0, r0, r1 */
10412 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
10413 0x0000ffff
10415 static const DWORD vshader3_code[] =
10417 0xfffe0300, /* vs_3_0 */
10418 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
10419 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
10420 0x03000005, 0x800f0000, 0x90000000, 0xa0e40000, /* mul r0, v0.x, c0 */
10421 0x04000004, 0x800f0000, 0x90550000, 0xa0e40001, 0x80e40000, /* mad r0, v0.y, c1, r0 */
10422 0x04000004, 0x800f0000, 0x90aa0000, 0xa0e40002, 0x80e40000, /* mad r0, v0.z, c2, r0 */
10423 0x04000004, 0xe00f0000, 0x90ff0000, 0xa0e40003, 0x80e40000, /* mad o0, v0.w, c3, r0 */
10424 0x0000ffff
10426 static const DWORD vshader3_psize_code[] =
10428 0xfffe0300, /* vs_3_0 */
10429 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
10430 0x0200001f, 0x80000004, 0x90010001, /* dcl_psize v1.x */
10431 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
10432 0x0200001f, 0x80000004, 0xe00f0001, /* dcl_psize o1 */
10433 0x03000005, 0x800f0000, 0x90000000, 0xa0e40000, /* mul r0, v0.x, c0 */
10434 0x04000004, 0x800f0000, 0x90550000, 0xa0e40001, 0x80e40000, /* mad r0, v0.y, c1, r0 */
10435 0x04000004, 0x800f0000, 0x90aa0000, 0xa0e40002, 0x80e40000, /* mad r0, v0.z, c2, r0 */
10436 0x04000004, 0xe00f0000, 0x90ff0000, 0xa0e40003, 0x80e40000, /* mad o0, v0.w, c3, r0 */
10437 0x02000001, 0xe00f0001, 0x90000001, /* mov o1, v1.x */
10438 0x0000ffff
10440 static const DWORD pshader3_code[] =
10442 0xffff0300, /* ps_3_0 */
10443 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord0 v0 */
10444 0x0200001f, 0x80010005, 0x900f0001, /* dcl_texcoord1 v1 */
10445 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
10446 0x0200001f, 0x90000000, 0xa00f0801, /* dcl_2d s1 */
10447 0x03000042, 0x800f0000, 0x90e40000, 0xa0e40800, /* texld r0, v0, s0 */
10448 0x03000042, 0x800f0001, 0x90e40001, 0xa0e40801, /* texld r1, v1, s1 */
10449 0x03000002, 0x800f0800, 0x80e40000, 0x80e40001, /* add oC0, r0, r1 */
10450 0x0000ffff
10452 static const DWORD pshader3_zw_code[] =
10454 0xffff0300, /* ps_3_0 */
10455 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord0 v0 */
10456 0x0200001f, 0x80010005, 0x900f0001, /* dcl_texcoord1 v1 */
10457 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
10458 0x0200001f, 0x90000000, 0xa00f0801, /* dcl_2d s1 */
10459 0x03000042, 0x800f0000, 0x90fe0000, 0xa0e40800, /* texld r0, v0.zw, s0 */
10460 0x03000042, 0x800f0001, 0x90fe0001, 0xa0e40801, /* texld r1, v1.zw, s1 */
10461 0x03000002, 0x800f0800, 0x80e40000, 0x80e40001, /* add oC0, r0, r1 */
10462 0x0000ffff
10464 static const struct test_shader
10466 DWORD version;
10467 const DWORD *code;
10469 novs = {0, NULL},
10470 vs1 = {D3DVS_VERSION(1, 1), vshader_code},
10471 vs1_psize = {D3DVS_VERSION(1, 1), vshader_psize_code},
10472 vs3 = {D3DVS_VERSION(3, 0), vshader3_code},
10473 vs3_psize = {D3DVS_VERSION(3, 0), vshader3_psize_code},
10474 nops = {0, NULL},
10475 ps1 = {D3DPS_VERSION(1, 1), pshader_code},
10476 ps2 = {D3DPS_VERSION(2, 0), pshader2_code},
10477 ps2_zw = {D3DPS_VERSION(2, 0), pshader2_zw_code},
10478 ps3 = {D3DPS_VERSION(3, 0), pshader3_code},
10479 ps3_zw = {D3DVS_VERSION(3, 0), pshader3_zw_code};
10480 static const struct
10482 const struct test_shader *vs;
10483 const struct test_shader *ps;
10484 DWORD accepted_fvf;
10485 unsigned int nonscaled_size, scaled_size;
10486 BOOL gives_0_0_texcoord;
10487 BOOL allow_broken;
10489 test_setups[] =
10491 {&novs, &nops, D3DFVF_XYZ, 32, 45, FALSE, FALSE},
10492 {&vs1, &ps1, D3DFVF_XYZ, 32, 32, FALSE, FALSE},
10493 {&novs, &ps1, D3DFVF_XYZ, 32, 45, FALSE, FALSE},
10494 {&vs1, &nops, D3DFVF_XYZ, 32, 32, FALSE, FALSE},
10495 {&novs, &ps2, D3DFVF_XYZ, 32, 45, FALSE, TRUE},
10496 {&novs, &ps2_zw, D3DFVF_XYZ, 32, 45, TRUE, FALSE},
10497 {&vs1, &ps2, D3DFVF_XYZ, 32, 32, FALSE, TRUE},
10498 {&vs1, &ps2_zw, D3DFVF_XYZ, 32, 32, TRUE, FALSE},
10499 {&vs3, &ps3, D3DFVF_XYZ, 32, 32, FALSE, TRUE},
10500 {&vs3, &ps3_zw, D3DFVF_XYZ, 32, 32, TRUE, FALSE},
10501 {&novs, &nops, D3DFVF_XYZ | D3DFVF_PSIZE, 48, 33, FALSE, FALSE},
10502 {&vs1_psize, &ps1, D3DFVF_XYZ | D3DFVF_PSIZE, 48, 24, FALSE, FALSE},
10503 {&vs3_psize, &ps3, D3DFVF_XYZ | D3DFVF_PSIZE, 48, 24, FALSE, TRUE},
10505 static const struct
10507 BOOL zero_size;
10508 BOOL scale;
10509 BOOL override_min;
10510 DWORD fvf;
10511 const void *vertex_data;
10512 unsigned int vertex_size;
10514 tests[] =
10516 {FALSE, FALSE, FALSE, D3DFVF_XYZ, vertices, sizeof(float) * 3},
10517 {FALSE, TRUE, FALSE, D3DFVF_XYZ, vertices, sizeof(float) * 3},
10518 {FALSE, FALSE, TRUE, D3DFVF_XYZ, vertices, sizeof(float) * 3},
10519 {TRUE, FALSE, FALSE, D3DFVF_XYZ, vertices, sizeof(float) * 3},
10520 {FALSE, FALSE, FALSE, D3DFVF_XYZ | D3DFVF_PSIZE, &vertex_pointsize, sizeof(vertex_pointsize)},
10521 {FALSE, TRUE, FALSE, D3DFVF_XYZ | D3DFVF_PSIZE, &vertex_pointsize_scaled, sizeof(vertex_pointsize_scaled)},
10522 {FALSE, FALSE, TRUE, D3DFVF_XYZ | D3DFVF_PSIZE, &vertex_pointsize, sizeof(vertex_pointsize)},
10523 {TRUE, FALSE, FALSE, D3DFVF_XYZ | D3DFVF_PSIZE, &vertex_pointsize_zero, sizeof(vertex_pointsize_zero)},
10525 /* Transforms the coordinate system [-1.0;1.0]x[1.0;-1.0] to
10526 * [0.0;0.0]x[640.0;480.0]. Z is untouched. */
10527 D3DMATRIX matrix =
10529 2.0f / 640.0f, 0.0f, 0.0f, 0.0f,
10530 0.0f, -2.0f / 480.0f, 0.0f, 0.0f,
10531 0.0f, 0.0f, 1.0f, 0.0f,
10532 -1.0f, 1.0f, 0.0f, 1.0f,
10533 }}};
10535 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
10536 0, 0, 640, 480, NULL, NULL, NULL, NULL);
10537 d3d = Direct3DCreate9(D3D_SDK_VERSION);
10538 ok(!!d3d, "Failed to create a D3D object.\n");
10539 if (!(device = create_device(d3d, window, window, TRUE)))
10541 skip("Failed to create a D3D device, skipping tests.\n");
10542 goto done;
10545 memset(&caps, 0, sizeof(caps));
10546 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10547 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed hr=%08x\n", hr);
10548 if(caps.MaxPointSize < 32.0) {
10549 skip("MaxPointSize < 32.0, skipping(MaxPointsize = %f)\n", caps.MaxPointSize);
10550 IDirect3DDevice9_Release(device);
10551 goto done;
10554 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
10555 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
10556 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
10557 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
10558 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
10559 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform failed, hr=%08x\n", hr);
10560 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
10561 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed hr=%08x\n", hr);
10563 hr = IDirect3DDevice9_BeginScene(device);
10564 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
10566 ptsize = 15.0f;
10567 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
10568 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10569 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
10570 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10572 ptsize = 31.0f;
10573 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
10574 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10575 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[3], sizeof(float) * 3);
10576 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10578 ptsize = 30.75f;
10579 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
10580 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10581 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[6], sizeof(float) * 3);
10582 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10584 if (caps.MaxPointSize >= 63.0f)
10586 ptsize = 63.0f;
10587 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
10588 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10589 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[9], sizeof(float) * 3);
10590 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10592 ptsize = 62.75f;
10593 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
10594 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10595 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[15], sizeof(float) * 3);
10596 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10599 ptsize = 1.0f;
10600 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
10601 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10602 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[12], sizeof(float) * 3);
10603 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10605 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MAX, (DWORD *)&ptsizemax_orig);
10606 ok(SUCCEEDED(hr), "Failed to get render state, hr %#x.\n", hr);
10607 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE_MIN, (DWORD *)&ptsizemin_orig);
10608 ok(SUCCEEDED(hr), "Failed to get render state, hr %#x.\n", hr);
10610 /* What happens if point scaling is disabled, and POINTSIZE_MAX < POINTSIZE? */
10611 ptsize = 15.0f;
10612 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
10613 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10614 ptsize = 1.0f;
10615 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *(DWORD *)&ptsize);
10616 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10617 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[18], sizeof(float) * 3);
10618 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10620 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MAX, *(DWORD *)&ptsizemax_orig);
10621 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10623 /* pointsize < pointsize_min < pointsize_max?
10624 * pointsize = 1.0, pointsize_min = 15.0, pointsize_max = default(usually 64.0) */
10625 ptsize = 1.0f;
10626 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
10627 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10628 ptsize = 15.0f;
10629 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *(DWORD *)&ptsize);
10630 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10631 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[21], sizeof(float) * 3);
10632 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10634 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *(DWORD *)&ptsizemin_orig);
10635 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
10637 hr = IDirect3DDevice9_EndScene(device);
10638 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
10640 ok(point_match(device, 64, 64, 7), "point_match(64, 64, 7) failed, expected point size 15.\n");
10641 ok(point_match(device, 128, 64, 15), "point_match(128, 64, 15) failed, expected point size 31.\n");
10642 ok(point_match(device, 192, 64, 15), "point_match(192, 64, 15) failed, expected point size 31.\n");
10644 if (caps.MaxPointSize >= 63.0)
10646 ok(point_match(device, 256, 64, 31), "point_match(256, 64, 31) failed, expected point size 63.\n");
10647 ok(point_match(device, 384, 64, 31), "point_match(384, 64, 31) failed, expected point size 63.\n");
10650 ok(point_match(device, 320, 64, 0), "point_match(320, 64, 0) failed, expected point size 1.\n");
10651 /* ptsize = 15, ptsize_max = 1 --> point has size 1 */
10652 ok(point_match(device, 448, 64, 0), "point_match(448, 64, 0) failed, expected point size 1.\n");
10653 /* ptsize = 1, ptsize_max = default(64), ptsize_min = 15 --> point has size 15 */
10654 ok(point_match(device, 512, 64, 7), "point_match(512, 64, 7) failed, expected point size 15.\n");
10656 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10658 /* The following code tests point sprites with two textures, to see if each texture coordinate unit
10659 * generates texture coordinates for the point(result: Yes, it does)
10661 * However, not all GL implementations support point sprites(they need GL_ARB_point_sprite), but there
10662 * is no point sprite cap bit in d3d because native d3d software emulates point sprites. Until the
10663 * SW emulation is implemented in wined3d, this test will fail on GL drivers that does not support them.
10665 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
10666 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
10668 hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex1, NULL);
10669 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
10670 hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &tex2, NULL);
10671 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed hr=%08x\n", hr);
10672 memset(&lr, 0, sizeof(lr));
10673 hr = IDirect3DTexture9_LockRect(tex1, 0, &lr, NULL, 0);
10674 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
10675 memcpy(lr.pBits, tex1_data, sizeof(tex1_data));
10676 hr = IDirect3DTexture9_UnlockRect(tex1, 0);
10677 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
10678 memset(&lr, 0, sizeof(lr));
10679 hr = IDirect3DTexture9_LockRect(tex2, 0, &lr, NULL, 0);
10680 ok(hr == D3D_OK, "IDirect3DTexture9_LockRect failed hr=%08x\n", hr);
10681 memcpy(lr.pBits, tex2_data, sizeof(tex2_data));
10682 hr = IDirect3DTexture9_UnlockRect(tex2, 0);
10683 ok(hr == D3D_OK, "IDirect3DTexture9_UnlockRect failed hr=%08x\n", hr);
10684 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
10685 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
10686 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *) tex2);
10687 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed hr=%08x\n", hr);
10688 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
10689 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
10690 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
10691 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
10692 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
10693 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
10694 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
10695 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
10696 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
10697 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed hr=%08x\n", hr);
10699 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSPRITEENABLE, TRUE);
10700 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed hr=%08x\n", hr);
10701 ptsize = 32.0;
10702 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *((DWORD *) (&ptsize)));
10703 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr=%08x\n", hr);
10705 hr = IDirect3DDevice9_BeginScene(device);
10706 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
10707 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1, &vertices[0], sizeof(float) * 3);
10708 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10709 hr = IDirect3DDevice9_EndScene(device);
10710 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
10712 color = getPixelColor(device, 64-4, 64-4);
10713 ok(color == 0x00ff0000, "pSprite: Pixel (64-4),(64-4) has color 0x%08x, expected 0x00ff0000\n", color);
10714 color = getPixelColor(device, 64-4, 64+4);
10715 ok(color == 0x00000000, "pSprite: Pixel (64-4),(64+4) has color 0x%08x, expected 0x00000000\n", color);
10716 color = getPixelColor(device, 64+4, 64+4);
10717 ok(color == 0x0000ff00, "pSprite: Pixel (64+4),(64+4) has color 0x%08x, expected 0x0000ff00\n", color);
10718 color = getPixelColor(device, 64+4, 64-4);
10719 ok(color == 0x00ffff00, "pSprite: Pixel (64+4),(64-4) has color 0x%08x, expected 0x00ffff00\n", color);
10720 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
10722 U(matrix).m[0][0] = 1.0f / 64.0f;
10723 U(matrix).m[1][1] = -1.0f / 64.0f;
10724 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &matrix);
10725 ok(SUCCEEDED(hr), "SetTransform failed, hr %#x.\n", hr);
10727 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
10728 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
10730 hr = IDirect3DDevice9_CreateRenderTarget(device, 128, 128, D3DFMT_A8R8G8B8,
10731 D3DMULTISAMPLE_NONE, 0, TRUE, &rt, NULL );
10732 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
10734 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSCALE_A, *(DWORD *)&a);
10735 ok(SUCCEEDED(hr), "Failed setting point scale attenuation coefficient, hr %#x.\n", hr);
10736 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSCALE_B, *(DWORD *)&b);
10737 ok(SUCCEEDED(hr), "Failed setting point scale attenuation coefficient, hr %#x.\n", hr);
10738 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSCALE_C, *(DWORD *)&c);
10739 ok(SUCCEEDED(hr), "Failed setting point scale attenuation coefficient, hr %#x.\n", hr);
10740 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
10742 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, &S(U(matrix))._11, 4);
10743 ok(SUCCEEDED(hr), "Failed to set vertex shader constants, hr %#x.\n", hr);
10746 if (caps.MaxPointSize < 63.0f)
10748 skip("MaxPointSize %f < 63.0, skipping some tests.\n", caps.MaxPointSize);
10749 goto cleanup;
10752 for (i = 0; i < sizeof(test_setups) / sizeof(test_setups[0]); ++i)
10754 if (caps.VertexShaderVersion < test_setups[i].vs->version
10755 || caps.PixelShaderVersion < test_setups[i].ps->version)
10757 skip("Vertex / pixel shader version not supported, skipping test.\n");
10758 continue;
10760 if (test_setups[i].vs->code)
10762 hr = IDirect3DDevice9_CreateVertexShader(device, test_setups[i].vs->code, &vs);
10763 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x (case %u).\n", hr, i);
10765 else
10767 vs = NULL;
10769 if (test_setups[i].ps->code)
10771 hr = IDirect3DDevice9_CreatePixelShader(device, test_setups[i].ps->code, &ps);
10772 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x (case %u).\n", hr, i);
10774 else
10776 ps = NULL;
10779 hr = IDirect3DDevice9_SetVertexShader(device, vs);
10780 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
10781 hr = IDirect3DDevice9_SetPixelShader(device, ps);
10782 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
10784 for (j = 0; j < sizeof(tests) / sizeof(tests[0]); ++j)
10786 BOOL allow_broken = test_setups[i].allow_broken;
10787 unsigned int size = tests[j].override_min ? 63 : tests[j].zero_size ? 0 : tests[j].scale
10788 ? test_setups[i].scaled_size : test_setups[i].nonscaled_size;
10790 if (test_setups[i].accepted_fvf != tests[j].fvf)
10791 continue;
10793 ptsize = tests[j].zero_size ? 0.0f : 32.0f;
10794 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, *(DWORD *)&ptsize);
10795 ok(SUCCEEDED(hr), "Failed to set pointsize, hr %#x.\n", hr);
10797 ptsize = tests[j].override_min ? 63.0f : tests[j].zero_size ? 0.0f : ptsizemin_orig;
10798 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE_MIN, *(DWORD *)&ptsize);
10799 ok(SUCCEEDED(hr), "Failed to set minimum pointsize, hr %#x.\n", hr);
10801 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSCALEENABLE, tests[j].scale);
10802 ok(SUCCEEDED(hr), "Failed setting point scale state, hr %#x.\n", hr);
10804 hr = IDirect3DDevice9_SetFVF(device, tests[j].fvf);
10805 ok(SUCCEEDED(hr), "Failed setting FVF, hr %#x.\n", hr);
10807 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
10808 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
10809 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
10810 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
10812 hr = IDirect3DDevice9_BeginScene(device);
10813 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
10814 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1,
10815 tests[j].vertex_data, tests[j].vertex_size);
10816 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
10817 hr = IDirect3DDevice9_EndScene(device);
10818 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
10820 hr = IDirect3DDevice9_StretchRect(device, rt, &rect, backbuffer, &rect, D3DTEXF_NONE);
10821 ok(SUCCEEDED(hr), "Failed to blit, hr %#x.\n", hr);
10822 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
10823 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
10825 if (tests[j].zero_size)
10827 /* Technically 0 pointsize is undefined in OpenGL but in practice it seems like
10828 * it does the "useful" thing on all the drivers I tried. */
10829 /* On WARP it does draw some pixels, most of the time. */
10830 color = getPixelColor(device, 64, 64);
10831 ok(color_match(color, 0x0000ffff, 0)
10832 || broken(color_match(color, 0x00ff0000, 0))
10833 || broken(color_match(color, 0x00ffff00, 0))
10834 || broken(color_match(color, 0x00000000, 0))
10835 || broken(color_match(color, 0x0000ff00, 0)),
10836 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
10838 else
10840 struct surface_readback rb;
10842 get_rt_readback(backbuffer, &rb);
10843 /* On AMD apparently only the first texcoord is modified by the point coordinates
10844 * when using SM2/3 pixel shaders. */
10845 color = get_readback_color(&rb, 64 - size / 2 + 1, 64 - size / 2 + 1);
10846 ok(color_match(color, 0x00ff0000, 0),
10847 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
10848 color = get_readback_color(&rb, 64 + size / 2 - 1, 64 - size / 2 + 1);
10849 ok(color_match(color, test_setups[i].gives_0_0_texcoord ? 0x00ff0000 : 0x00ffff00, 0)
10850 || (allow_broken && broken(color_match(color, 0x00ff0000, 0))),
10851 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
10852 color = get_readback_color(&rb, 64 - size / 2 + 1, 64 + size / 2 - 1);
10853 ok(color_match(color, test_setups[i].gives_0_0_texcoord ? 0x00ff0000 : 0x00000000, 0),
10854 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
10855 color = get_readback_color(&rb, 64 + size / 2 - 1, 64 + size / 2 - 1);
10856 ok(color_match(color, test_setups[i].gives_0_0_texcoord ? 0x00ff0000 : 0x0000ff00, 0)
10857 || (allow_broken && broken(color_match(color, 0x00000000, 0))),
10858 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
10860 color = get_readback_color(&rb, 64 - size / 2 - 1, 64 - size / 2 - 1);
10861 ok(color_match(color, 0xff00ffff, 0),
10862 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
10863 color = get_readback_color(&rb, 64 + size / 2 + 1, 64 - size / 2 - 1);
10864 ok(color_match(color, 0xff00ffff, 0),
10865 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
10866 color = get_readback_color(&rb, 64 - size / 2 - 1, 64 + size / 2 + 1);
10867 ok(color_match(color, 0xff00ffff, 0),
10868 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
10869 color = get_readback_color(&rb, 64 + size / 2 + 1, 64 + size / 2 + 1);
10870 ok(color_match(color, 0xff00ffff, 0),
10871 "Got unexpected color 0x%08x (case %u, %u, size %u).\n", color, i, j, size);
10873 release_surface_readback(&rb);
10876 IDirect3DDevice9_SetVertexShader(device, NULL);
10877 IDirect3DDevice9_SetPixelShader(device, NULL);
10878 if (vs)
10879 IDirect3DVertexShader9_Release(vs);
10880 if (ps)
10881 IDirect3DVertexShader9_Release(ps);
10884 cleanup:
10885 IDirect3DSurface9_Release(backbuffer);
10886 IDirect3DSurface9_Release(rt);
10888 IDirect3DTexture9_Release(tex1);
10889 IDirect3DTexture9_Release(tex2);
10890 refcount = IDirect3DDevice9_Release(device);
10891 ok(!refcount, "Device has %u references left.\n", refcount);
10892 done:
10893 IDirect3D9_Release(d3d);
10894 DestroyWindow(window);
10897 static void multiple_rendertargets_test(void)
10899 IDirect3DSurface9 *surf1, *surf2, *backbuf, *readback;
10900 IDirect3DPixelShader9 *ps1, *ps2;
10901 IDirect3DTexture9 *tex1, *tex2;
10902 IDirect3DVertexShader9 *vs;
10903 IDirect3DDevice9 *device;
10904 IDirect3D9 *d3d;
10905 ULONG refcount;
10906 D3DCAPS9 caps;
10907 DWORD color;
10908 HWND window;
10909 HRESULT hr;
10910 UINT i, j;
10912 static const DWORD vshader_code[] =
10914 0xfffe0300, /* vs_3_0 */
10915 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
10916 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
10917 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
10918 0x0000ffff /* end */
10920 static const DWORD pshader_code1[] =
10922 0xffff0300, /* ps_3_0 */
10923 0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
10924 0x02000001, 0x800f0800, 0xa0e40000, /* mov oC0, c0 */
10925 0x0000ffff /* end */
10927 static const DWORD pshader_code2[] =
10929 0xffff0300, /* ps_3_0 */
10930 0x05000051, 0xa00f0000, 0x00000000, 0x3f800000, 0x00000000, 0x00000000, /* def c0, 0.0, 1.0, 0.0, 0.0 */
10931 0x05000051, 0xa00f0001, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c1, 0.0, 0.0, 1.0, 0.0 */
10932 0x02000001, 0x800f0800, 0xa0e40000, /* mov oC0, c0 */
10933 0x02000001, 0x800f0801, 0xa0e40001, /* mov oC1, c1 */
10934 0x0000ffff /* end */
10936 static const float quad[] =
10938 -1.0f, -1.0f, 0.1f,
10939 -1.0f, 1.0f, 0.1f,
10940 1.0f, -1.0f, 0.1f,
10941 1.0f, 1.0f, 0.1f,
10943 static const float texquad[] =
10945 -1.0f, -1.0f, 0.1f, 0.0f, 0.0f,
10946 -1.0f, 1.0f, 0.1f, 0.0f, 1.0f,
10947 0.0f, -1.0f, 0.1f, 1.0f, 0.0f,
10948 0.0f, 1.0f, 0.1f, 1.0f, 1.0f,
10950 0.0f, -1.0f, 0.1f, 0.0f, 0.0f,
10951 0.0f, 1.0f, 0.1f, 0.0f, 1.0f,
10952 1.0f, -1.0f, 0.1f, 1.0f, 0.0f,
10953 1.0f, 1.0f, 0.1f, 1.0f, 1.0f,
10956 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
10957 0, 0, 640, 480, NULL, NULL, NULL, NULL);
10958 d3d = Direct3DCreate9(D3D_SDK_VERSION);
10959 ok(!!d3d, "Failed to create a D3D object.\n");
10960 if (!(device = create_device(d3d, window, window, TRUE)))
10962 skip("Failed to create a D3D device, skipping tests.\n");
10963 goto done;
10966 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
10967 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
10968 if (caps.NumSimultaneousRTs < 2)
10970 skip("Only 1 simultaneous render target supported, skipping MRT test.\n");
10971 IDirect3DDevice9_Release(device);
10972 goto done;
10974 if (caps.PixelShaderVersion < D3DPS_VERSION(3, 0) || caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
10976 skip("No shader model 3 support, skipping tests.\n");
10977 IDirect3DDevice9_Release(device);
10978 goto done;
10981 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 1.0f, 0);
10982 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed, hr=%08x\n", hr);
10984 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 16, 16,
10985 D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &readback, NULL);
10986 ok(SUCCEEDED(hr), "CreateOffscreenPlainSurface failed, hr %#x.\n", hr);
10988 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET,
10989 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex1, NULL);
10990 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
10991 hr = IDirect3DDevice9_CreateTexture(device, 16, 16, 1, D3DUSAGE_RENDERTARGET,
10992 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex2, NULL);
10993 ok(hr == D3D_OK, "IDirect3DDevice9_CreateTexture failed, hr=%08x\n", hr);
10994 hr = IDirect3DDevice9_CreateVertexShader(device, vshader_code, &vs);
10995 ok(SUCCEEDED(hr), "CreateVertexShader failed, hr %#x.\n", hr);
10996 hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code1, &ps1);
10997 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
10998 hr = IDirect3DDevice9_CreatePixelShader(device, pshader_code2, &ps2);
10999 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
11001 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuf);
11002 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr=%08x\n", hr);
11003 hr = IDirect3DTexture9_GetSurfaceLevel(tex1, 0, &surf1);
11004 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
11005 hr = IDirect3DTexture9_GetSurfaceLevel(tex2, 0, &surf2);
11006 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed, hr=%08x\n", hr);
11008 hr = IDirect3DDevice9_SetVertexShader(device, vs);
11009 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
11010 hr = IDirect3DDevice9_SetRenderTarget(device, 0, surf1);
11011 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
11012 hr = IDirect3DDevice9_SetRenderTarget(device, 1, surf2);
11013 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
11014 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
11015 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr=%08x\n", hr);
11017 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0f, 0);
11018 ok(SUCCEEDED(hr), "Clear failed, hr %#x,\n", hr);
11019 hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, readback);
11020 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
11021 color = getPixelColorFromSurface(readback, 8, 8);
11022 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
11023 "Expected color 0x000000ff, got 0x%08x.\n", color);
11024 hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
11025 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
11026 color = getPixelColorFromSurface(readback, 8, 8);
11027 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
11028 "Expected color 0x000000ff, got 0x%08x.\n", color);
11030 /* Render targets not written by the pixel shader should be unmodified. */
11031 hr = IDirect3DDevice9_SetPixelShader(device, ps1);
11032 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
11033 hr = IDirect3DDevice9_BeginScene(device);
11034 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
11035 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
11036 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
11037 hr = IDirect3DDevice9_EndScene(device);
11038 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
11039 hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, readback);
11040 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
11041 color = getPixelColorFromSurface(readback, 8, 8);
11042 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
11043 "Expected color 0xff00ff00, got 0x%08x.\n", color);
11044 hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
11045 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
11046 for (i = 6; i < 10; ++i)
11048 for (j = 6; j < 10; ++j)
11050 color = getPixelColorFromSurface(readback, j, i);
11051 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff), 0),
11052 "Expected color 0xff0000ff, got 0x%08x at %u, %u.\n", color, j, i);
11056 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0f, 0);
11057 ok(SUCCEEDED(hr), "Clear failed, hr %#x,\n", hr);
11058 hr = IDirect3DDevice9_GetRenderTargetData(device, surf1, readback);
11059 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
11060 color = getPixelColorFromSurface(readback, 8, 8);
11061 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00), 0),
11062 "Expected color 0x0000ff00, got 0x%08x.\n", color);
11063 hr = IDirect3DDevice9_GetRenderTargetData(device, surf2, readback);
11064 ok(SUCCEEDED(hr), "GetRenderTargetData failed, hr %#x.\n", hr);
11065 color = getPixelColorFromSurface(readback, 8, 8);
11066 ok(color_match(color, D3DCOLOR_ARGB(0xff, 0x00, 0xff, 0x00), 0),
11067 "Expected color 0x0000ff00, got 0x%08x.\n", color);
11069 hr = IDirect3DDevice9_SetPixelShader(device, ps2);
11070 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
11072 hr = IDirect3DDevice9_BeginScene(device);
11073 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
11075 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
11076 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
11078 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11079 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
11080 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
11081 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
11082 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
11083 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
11084 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuf);
11085 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
11086 hr = IDirect3DDevice9_SetRenderTarget(device, 1, NULL);
11087 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
11088 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
11089 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
11091 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex1);
11092 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
11093 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[0], 5 * sizeof(float));
11094 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
11096 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) tex2);
11097 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
11098 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &texquad[20], 5 * sizeof(float));
11099 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
11101 hr = IDirect3DDevice9_EndScene(device);
11102 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
11104 color = getPixelColor(device, 160, 240);
11105 ok(color == 0x0000ff00, "Texture 1(output color 1) has color 0x%08x, expected 0x0000ff00\n", color);
11106 color = getPixelColor(device, 480, 240);
11107 ok(color == 0x000000ff, "Texture 2(output color 2) has color 0x%08x, expected 0x000000ff\n", color);
11108 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11110 IDirect3DPixelShader9_Release(ps2);
11111 IDirect3DPixelShader9_Release(ps1);
11112 IDirect3DVertexShader9_Release(vs);
11113 IDirect3DTexture9_Release(tex1);
11114 IDirect3DTexture9_Release(tex2);
11115 IDirect3DSurface9_Release(surf1);
11116 IDirect3DSurface9_Release(surf2);
11117 IDirect3DSurface9_Release(backbuf);
11118 IDirect3DSurface9_Release(readback);
11119 refcount = IDirect3DDevice9_Release(device);
11120 ok(!refcount, "Device has %u references left.\n", refcount);
11121 done:
11122 IDirect3D9_Release(d3d);
11123 DestroyWindow(window);
11126 static void pixelshader_blending_test(void)
11128 IDirect3DSurface9 *backbuffer = NULL, *offscreen = NULL;
11129 IDirect3DTexture9 *offscreenTexture = NULL;
11130 IDirect3DDevice9 *device;
11131 IDirect3D9 *d3d;
11132 ULONG refcount;
11133 int fmt_index;
11134 DWORD color;
11135 HWND window;
11136 HRESULT hr;
11138 static const struct
11140 const char *fmtName;
11141 D3DFORMAT textureFormat;
11142 D3DCOLOR resultColorBlending;
11143 D3DCOLOR resultColorNoBlending;
11145 test_formats[] =
11147 {"D3DFMT_G16R16", D3DFMT_G16R16, 0x001818ff, 0x002010ff},
11148 {"D3DFMT_R16F", D3DFMT_R16F, 0x0018ffff, 0x0020ffff},
11149 {"D3DFMT_G16R16F", D3DFMT_G16R16F, 0x001818ff, 0x002010ff},
11150 {"D3DFMT_A16B16G16R16F", D3DFMT_A16B16G16R16F, 0x00181800, 0x00201000},
11151 {"D3DFMT_R32F", D3DFMT_R32F, 0x0018ffff, 0x0020ffff},
11152 {"D3DFMT_G32R32F", D3DFMT_G32R32F, 0x001818ff, 0x002010ff},
11153 {"D3DFMT_A32B32G32R32F", D3DFMT_A32B32G32R32F, 0x00181800, 0x00201000},
11155 static const float quad[][5] =
11157 {-0.5f, -0.5f, 0.1f, 0.0f, 0.0f},
11158 {-0.5f, 0.5f, 0.1f, 0.0f, 1.0f},
11159 { 0.5f, -0.5f, 0.1f, 1.0f, 0.0f},
11160 { 0.5f, 0.5f, 0.1f, 1.0f, 1.0f},
11162 static const struct
11164 struct vec3 position;
11165 DWORD diffuse;
11167 /* Quad with R=0x10, G=0x20 */
11168 quad1[] =
11170 {{-1.0f, -1.0f, 0.1f}, 0x80102000},
11171 {{-1.0f, 1.0f, 0.1f}, 0x80102000},
11172 {{ 1.0f, -1.0f, 0.1f}, 0x80102000},
11173 {{ 1.0f, 1.0f, 0.1f}, 0x80102000},
11175 /* Quad with R=0x20, G=0x10 */
11176 quad2[] =
11178 {{-1.0f, -1.0f, 0.1f}, 0x80201000},
11179 {{-1.0f, 1.0f, 0.1f}, 0x80201000},
11180 {{ 1.0f, -1.0f, 0.1f}, 0x80201000},
11181 {{ 1.0f, 1.0f, 0.1f}, 0x80201000},
11184 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
11185 0, 0, 640, 480, NULL, NULL, NULL, NULL);
11186 d3d = Direct3DCreate9(D3D_SDK_VERSION);
11187 ok(!!d3d, "Failed to create a D3D object.\n");
11188 if (!(device = create_device(d3d, window, window, TRUE)))
11190 skip("Failed to create a D3D device, skipping tests.\n");
11191 goto done;
11194 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
11195 ok(hr == D3D_OK, "Can't get back buffer, hr = %08x\n", hr);
11197 for (fmt_index = 0; fmt_index < sizeof(test_formats) / sizeof(*test_formats); ++fmt_index)
11199 D3DFORMAT fmt = test_formats[fmt_index].textureFormat;
11201 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
11202 D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, fmt) != D3D_OK)
11204 skip("%s textures not supported as render targets.\n", test_formats[fmt_index].fmtName);
11205 continue;
11208 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
11209 ok(hr == D3D_OK, "Clear failed, hr = %08x\n", hr);
11211 hr = IDirect3DDevice9_CreateTexture(device, 128, 128, 1, D3DUSAGE_RENDERTARGET, fmt, D3DPOOL_DEFAULT, &offscreenTexture, NULL);
11212 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "Creating the offscreen render target failed, hr = %08x\n", hr);
11213 if(!offscreenTexture) {
11214 continue;
11217 hr = IDirect3DTexture9_GetSurfaceLevel(offscreenTexture, 0, &offscreen);
11218 ok(hr == D3D_OK, "Can't get offscreen surface, hr = %08x\n", hr);
11219 if(!offscreen) {
11220 continue;
11223 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11224 ok(hr == D3D_OK, "SetFVF failed, hr = %08x\n", hr);
11226 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
11227 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
11228 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
11229 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
11230 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
11231 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MINFILTER failed (0x%08x)\n", hr);
11232 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
11233 ok(SUCCEEDED(hr), "SetSamplerState D3DSAMP_MAGFILTER failed (0x%08x)\n", hr);
11234 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11235 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
11237 /* Below we will draw two quads with different colors and try to blend
11238 * them together. The result color is compared with the expected
11239 * outcome. */
11240 hr = IDirect3DDevice9_BeginScene(device);
11241 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
11243 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen);
11244 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
11245 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ffffff, 1.0f, 0);
11246 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
11248 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
11249 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
11251 /* Draw a quad using color 0x0010200. */
11252 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_ONE);
11253 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
11254 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_ZERO);
11255 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
11256 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(quad1[0]));
11257 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
11259 /* Draw a quad using color 0x0020100. */
11260 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
11261 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
11262 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
11263 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
11264 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(quad2[0]));
11265 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
11267 /* We don't want to blend the result on the backbuffer. */
11268 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, FALSE);
11269 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
11271 /* Prepare rendering the 'blended' texture quad to the backbuffer. */
11272 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
11273 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
11274 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)offscreenTexture);
11275 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
11277 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
11278 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
11280 /* This time with the texture. */
11281 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
11282 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
11284 hr = IDirect3DDevice9_EndScene(device);
11285 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
11287 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
11288 D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, D3DRTYPE_TEXTURE, fmt) == D3D_OK)
11290 /* Compare the color of the center quad with our expectation. */
11291 color = getPixelColor(device, 320, 240);
11292 ok(color_match(color, test_formats[fmt_index].resultColorBlending, 1),
11293 "Offscreen failed for %s: Got color 0x%08x, expected 0x%08x.\n",
11294 test_formats[fmt_index].fmtName, color, test_formats[fmt_index].resultColorBlending);
11296 else
11298 /* No pixel shader blending is supported so expect garbage. The
11299 * type of 'garbage' depends on the driver version and OS. E.g. on
11300 * G16R16 ATI reports (on old r9600 drivers) 0x00ffffff and on
11301 * modern ones 0x002010ff which is also what NVIDIA reports. On
11302 * Vista NVIDIA seems to report 0x00ffffff on Geforce7 cards. */
11303 color = getPixelColor(device, 320, 240);
11304 ok((color == 0x00ffffff) || (color == test_formats[fmt_index].resultColorNoBlending),
11305 "Offscreen failed for %s: Got unexpected color 0x%08x, expected no color blending.\n",
11306 test_formats[fmt_index].fmtName, color);
11308 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11310 IDirect3DDevice9_SetTexture(device, 0, NULL);
11311 if(offscreenTexture) {
11312 IDirect3DTexture9_Release(offscreenTexture);
11314 if(offscreen) {
11315 IDirect3DSurface9_Release(offscreen);
11319 IDirect3DSurface9_Release(backbuffer);
11320 refcount = IDirect3DDevice9_Release(device);
11321 ok(!refcount, "Device has %u references left.\n", refcount);
11322 done:
11323 IDirect3D9_Release(d3d);
11324 DestroyWindow(window);
11327 static void tssargtemp_test(void)
11329 IDirect3DDevice9 *device;
11330 IDirect3D9 *d3d;
11331 D3DCOLOR color;
11332 ULONG refcount;
11333 D3DCAPS9 caps;
11334 HWND window;
11335 HRESULT hr;
11337 static const struct
11339 struct vec3 position;
11340 DWORD diffuse;
11342 quad[] =
11344 {{-1.0f, -1.0f, 0.1f}, 0x00ff0000},
11345 {{-1.0f, 1.0f, 0.1f}, 0x00ff0000},
11346 {{ 1.0f, -1.0f, 0.1f}, 0x00ff0000},
11347 {{ 1.0f, 1.0f, 0.1f}, 0x00ff0000},
11350 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
11351 0, 0, 640, 480, NULL, NULL, NULL, NULL);
11352 d3d = Direct3DCreate9(D3D_SDK_VERSION);
11353 ok(!!d3d, "Failed to create a D3D object.\n");
11354 if (!(device = create_device(d3d, window, window, TRUE)))
11356 skip("Failed to create a D3D device, skipping tests.\n");
11357 goto done;
11360 memset(&caps, 0, sizeof(caps));
11361 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11362 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with %08x\n", hr);
11363 if(!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP)) {
11364 skip("D3DPMISCCAPS_TSSARGTEMP not supported\n");
11365 IDirect3DDevice9_Release(device);
11366 goto done;
11369 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff000000, 1.0f, 0);
11370 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
11372 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
11373 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
11374 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
11375 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
11377 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
11378 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
11379 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TFACTOR);
11380 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
11381 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_RESULTARG, D3DTA_TEMP);
11382 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
11384 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_ADD);
11385 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
11386 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG1, D3DTA_CURRENT);
11387 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
11388 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLORARG2, D3DTA_TEMP);
11389 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
11391 hr = IDirect3DDevice9_SetTextureStageState(device, 3, D3DTSS_COLOROP, D3DTOP_DISABLE);
11392 ok(hr == D3D_OK, "SetTextureStageState failed, hr = %08x\n", hr);
11394 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x0000ff00);
11395 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed, hr = %08x\n", hr);
11396 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11397 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
11398 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
11399 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed, hr = %08x\n", hr);
11401 hr = IDirect3DDevice9_BeginScene(device);
11402 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
11403 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
11404 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
11405 hr = IDirect3DDevice9_EndScene(device);
11406 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
11408 color = getPixelColor(device, 320, 240);
11409 ok(color == 0x00ffff00, "TSSARGTEMP test returned color 0x%08x, expected 0x00ffff00\n", color);
11410 IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11412 refcount = IDirect3DDevice9_Release(device);
11413 ok(!refcount, "Device has %u references left.\n", refcount);
11414 done:
11415 IDirect3D9_Release(d3d);
11416 DestroyWindow(window);
11419 /* Drawing Indexed Geometry with instances*/
11420 static void stream_test(void)
11422 IDirect3DVertexDeclaration9 *pDecl = NULL;
11423 IDirect3DVertexShader9 *shader = NULL;
11424 IDirect3DVertexBuffer9 *vb3 = NULL;
11425 IDirect3DVertexBuffer9 *vb2 = NULL;
11426 IDirect3DVertexBuffer9 *vb = NULL;
11427 IDirect3DIndexBuffer9 *ib = NULL;
11428 IDirect3DDevice9 *device;
11429 IDirect3D9 *d3d;
11430 ULONG refcount;
11431 D3DCAPS9 caps;
11432 DWORD color;
11433 HWND window;
11434 unsigned i;
11435 HRESULT hr;
11436 BYTE *data;
11437 DWORD ind;
11439 static const struct testdata
11441 DWORD idxVertex; /* number of instances in the first stream */
11442 DWORD idxColor; /* number of instances in the second stream */
11443 DWORD idxInstance; /* should be 1 ?? */
11444 DWORD color1; /* color 1 instance */
11445 DWORD color2; /* color 2 instance */
11446 DWORD color3; /* color 3 instance */
11447 DWORD color4; /* color 4 instance */
11448 WORD strVertex; /* specify which stream to use 0-2*/
11449 WORD strColor;
11450 WORD strInstance;
11452 testcases[]=
11454 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 0 */
11455 {3, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /* 1 */
11456 {2, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /* 2 */
11457 {1, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /* 3 */
11458 {4, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 4 */
11459 {4, 2, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 5 */
11460 {4, 1, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 6 */
11461 {4, 0, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 1, 2}, /* 7 */
11462 {3, 3, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ffffff, 0, 1, 2}, /* 8 */
11463 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 0, 2}, /* 9 */
11464 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0, 2, 1}, /* 10 */
11465 {4, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 3, 1}, /* 11 */
11466 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 2, 0, 1}, /* 12 */
11467 {4, 4, 1, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 1, 2, 3}, /* 13 */
11468 #if 0
11469 /* This draws one instance on some machines, no instance on others. */
11470 {0, 4, 1, 0x00ff0000, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0, 1, 2}, /* 14 */
11471 /* This case is handled in a stand alone test,
11472 * SetStreamSourceFreq(0, (D3DSTREAMSOURCE_INSTANCEDATA | 1)) has to
11473 * return D3DERR_INVALIDCALL. */
11474 {4, 4, 1, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 2, 1, 0}, /* 15 */
11475 #endif
11477 static const DWORD shader_code[] =
11479 0xfffe0101, /* vs_1_1 */
11480 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
11481 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
11482 0x0000001f, 0x80000005, 0x900f0002, /* dcl_texcoord v2 */
11483 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
11484 0x00000002, 0xc00f0000, 0x80e40000, 0x90e40002, /* add oPos, r0, v2 */
11485 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
11486 0x0000ffff
11488 static const float quad[][3] =
11490 {-0.5f, -0.5f, 1.1f}, /*0 */
11491 {-0.5f, 0.5f, 1.1f}, /*1 */
11492 { 0.5f, -0.5f, 1.1f}, /*2 */
11493 { 0.5f, 0.5f, 1.1f}, /*3 */
11495 static const float vertcolor[][4] =
11497 {1.0f, 0.0f, 0.0f, 1.0f}, /*0 */
11498 {1.0f, 0.0f, 0.0f, 1.0f}, /*1 */
11499 {1.0f, 0.0f, 0.0f, 1.0f}, /*2 */
11500 {1.0f, 0.0f, 0.0f, 1.0f}, /*3 */
11502 /* 4 position for 4 instances */
11503 static const float instancepos[][3] =
11505 {-0.6f,-0.6f, 0.0f},
11506 { 0.6f,-0.6f, 0.0f},
11507 { 0.6f, 0.6f, 0.0f},
11508 {-0.6f, 0.6f, 0.0f},
11510 static const short indices[] = {0, 1, 2, 2, 1, 3};
11511 D3DVERTEXELEMENT9 decl[] =
11513 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
11514 {1, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
11515 {2, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
11516 D3DDECL_END()
11519 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
11520 0, 0, 640, 480, NULL, NULL, NULL, NULL);
11521 d3d = Direct3DCreate9(D3D_SDK_VERSION);
11522 ok(!!d3d, "Failed to create a D3D object.\n");
11523 if (!(device = create_device(d3d, window, window, TRUE)))
11525 skip("Failed to create a D3D device, skipping tests.\n");
11526 goto done;
11529 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11530 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
11531 if (caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
11533 skip("No vs_3_0 support, skipping tests.\n");
11534 IDirect3DDevice9_Release(device);
11535 goto done;
11538 /* set the default value because it isn't done in wine? */
11539 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
11540 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
11542 /* check for D3DSTREAMSOURCE_INDEXEDDATA at stream0 */
11543 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 0, (D3DSTREAMSOURCE_INSTANCEDATA | 1));
11544 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
11546 /* check wrong cases */
11547 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 0);
11548 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
11549 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
11550 ok(hr == D3D_OK && ind == 1, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
11551 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 2);
11552 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
11553 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
11554 ok(hr == D3D_OK && ind == 2, "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
11555 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INDEXEDDATA | 0));
11556 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
11557 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
11558 ok(hr == D3D_OK && ind == (D3DSTREAMSOURCE_INDEXEDDATA | 0), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
11559 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | 0));
11560 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
11561 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
11562 ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
11563 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, (D3DSTREAMSOURCE_INSTANCEDATA | D3DSTREAMSOURCE_INDEXEDDATA | 0));
11564 ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
11565 hr = IDirect3DDevice9_GetStreamSourceFreq(device, 1, &ind);
11566 ok(hr == D3D_OK && ind == (0U | D3DSTREAMSOURCE_INSTANCEDATA), "IDirect3DDevice9_GetStreamSourceFreq failed with %08x\n", hr);
11568 /* set the default value back */
11569 hr = IDirect3DDevice9_SetStreamSourceFreq(device, 1, 1);
11570 ok(hr == D3D_OK, "IDirect3DDevice9_SetStreamSourceFreq failed with %08x\n", hr);
11572 /* create all VertexBuffers*/
11573 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(quad), 0, 0, D3DPOOL_MANAGED, &vb, NULL);
11574 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
11575 if(!vb) {
11576 skip("Failed to create a vertex buffer\n");
11577 IDirect3DDevice9_Release(device);
11578 goto done;
11580 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(vertcolor), 0, 0, D3DPOOL_MANAGED, &vb2, NULL);
11581 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
11582 if(!vb2) {
11583 skip("Failed to create a vertex buffer\n");
11584 goto out;
11586 hr = IDirect3DDevice9_CreateVertexBuffer(device, sizeof(instancepos), 0, 0, D3DPOOL_MANAGED, &vb3, NULL);
11587 ok(hr == D3D_OK, "CreateVertexBuffer failed with %08x\n", hr);
11588 if(!vb3) {
11589 skip("Failed to create a vertex buffer\n");
11590 goto out;
11593 /* create IndexBuffer*/
11594 hr = IDirect3DDevice9_CreateIndexBuffer(device, sizeof(indices), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ib, NULL);
11595 ok(hr == D3D_OK, "IDirect3DDevice9_CreateIndexBuffer failed with %08x\n", hr);
11596 if(!ib) {
11597 skip("Failed to create an index buffer\n");
11598 goto out;
11601 /* copy all Buffers (Vertex + Index)*/
11602 hr = IDirect3DVertexBuffer9_Lock(vb, 0, sizeof(quad), (void **) &data, 0);
11603 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
11604 memcpy(data, quad, sizeof(quad));
11605 hr = IDirect3DVertexBuffer9_Unlock(vb);
11606 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
11607 hr = IDirect3DVertexBuffer9_Lock(vb2, 0, sizeof(vertcolor), (void **) &data, 0);
11608 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
11609 memcpy(data, vertcolor, sizeof(vertcolor));
11610 hr = IDirect3DVertexBuffer9_Unlock(vb2);
11611 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
11612 hr = IDirect3DVertexBuffer9_Lock(vb3, 0, sizeof(instancepos), (void **) &data, 0);
11613 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Lock failed with %08x\n", hr);
11614 memcpy(data, instancepos, sizeof(instancepos));
11615 hr = IDirect3DVertexBuffer9_Unlock(vb3);
11616 ok(hr == D3D_OK, "IDirect3DVertexBuffer9_Unlock failed with %08x\n", hr);
11617 hr = IDirect3DIndexBuffer9_Lock(ib, 0, sizeof(indices), (void **) &data, 0);
11618 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Lock failed with %08x\n", hr);
11619 memcpy(data, indices, sizeof(indices));
11620 hr = IDirect3DIndexBuffer9_Unlock(ib);
11621 ok(hr == D3D_OK, "IDirect3DIndexBuffer9_Unlock failed with %08x\n", hr);
11623 /* create VertexShader */
11624 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
11625 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexShader failed hr=%08x\n", hr);
11626 if(!shader) {
11627 skip("Failed to create a vetex shader\n");
11628 goto out;
11631 hr = IDirect3DDevice9_SetVertexShader(device, shader);
11632 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShader failed hr=%08x\n", hr);
11634 hr = IDirect3DDevice9_SetIndices(device, ib);
11635 ok(hr == D3D_OK, "IDirect3DDevice9_SetIndices failed with %08x\n", hr);
11637 /* run all tests */
11638 for( i = 0; i < sizeof(testcases)/sizeof(testcases[0]); ++i)
11640 struct testdata act = testcases[i];
11641 decl[0].Stream = act.strVertex;
11642 decl[1].Stream = act.strColor;
11643 decl[2].Stream = act.strInstance;
11644 /* create VertexDeclarations */
11645 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl, &pDecl);
11646 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateVertexDeclaration failed hr=%08x (case %i)\n", hr, i);
11648 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
11649 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x (case %i)\n", hr, i);
11651 hr = IDirect3DDevice9_BeginScene(device);
11652 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
11654 hr = IDirect3DDevice9_SetVertexDeclaration(device, pDecl);
11655 ok(SUCCEEDED(hr), "Failed to set vertex declaration, hr %#x.\n", hr);
11657 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex,
11658 (D3DSTREAMSOURCE_INDEXEDDATA | act.idxVertex));
11659 ok(SUCCEEDED(hr), "Failed to set stream source frequency, hr %#x.\n", hr);
11660 hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, vb, 0, sizeof(quad[0]));
11661 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
11663 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strColor,
11664 (D3DSTREAMSOURCE_INDEXEDDATA | act.idxColor));
11665 ok(SUCCEEDED(hr), "Failed to set stream source frequency, hr %#x.\n", hr);
11666 hr = IDirect3DDevice9_SetStreamSource(device, act.strColor, vb2, 0, sizeof(vertcolor[0]));
11667 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
11669 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strInstance,
11670 (D3DSTREAMSOURCE_INSTANCEDATA | act.idxInstance));
11671 ok(SUCCEEDED(hr), "Failed to set stream source frequency, hr %#x.\n", hr);
11672 hr = IDirect3DDevice9_SetStreamSource(device, act.strInstance, vb3, 0, sizeof(instancepos[0]));
11673 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
11675 hr = IDirect3DDevice9_DrawIndexedPrimitive(device, D3DPT_TRIANGLELIST, 0, 0, 4, 0, 2);
11676 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
11677 hr = IDirect3DDevice9_EndScene(device);
11678 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
11680 /* set all StreamSource && StreamSourceFreq back to default */
11681 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.strVertex, 1);
11682 ok(SUCCEEDED(hr), "Failed to set stream source frequency, hr %#x.\n", hr);
11683 hr = IDirect3DDevice9_SetStreamSource(device, act.strVertex, NULL, 0, 0);
11684 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
11685 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxColor, 1);
11686 ok(SUCCEEDED(hr), "Failed to set stream source frequency, hr %#x.\n", hr);
11687 hr = IDirect3DDevice9_SetStreamSource(device, act.idxColor, NULL, 0, 0);
11688 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
11689 hr = IDirect3DDevice9_SetStreamSourceFreq(device, act.idxInstance, 1);
11690 ok(SUCCEEDED(hr), "Failed to set stream source frequency, hr %#x.\n", hr);
11691 hr = IDirect3DDevice9_SetStreamSource(device, act.idxInstance, NULL, 0, 0);
11692 ok(SUCCEEDED(hr), "Failed to set stream source, hr %#x.\n", hr);
11694 hr = IDirect3DVertexDeclaration9_Release(pDecl);
11695 ok(hr == D3D_OK, "IDirect3DVertexDeclaration9_Release failed with %08x (case %i)\n", hr, i);
11697 color = getPixelColor(device, 160, 360);
11698 ok(color == act.color1, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color1, i);
11699 color = getPixelColor(device, 480, 360);
11700 ok(color == act.color2, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color2, i);
11701 color = getPixelColor(device, 480, 120);
11702 ok(color == act.color3, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color3, i);
11703 color = getPixelColor(device, 160, 120);
11704 ok(color == act.color4, "has color 0x%08x, expected 0x%08x (case %i)\n", color, act.color4, i);
11706 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11707 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x (case %i)\n", hr, i);
11710 out:
11711 if(vb) IDirect3DVertexBuffer9_Release(vb);
11712 if(vb2)IDirect3DVertexBuffer9_Release(vb2);
11713 if(vb3)IDirect3DVertexBuffer9_Release(vb3);
11714 if(ib)IDirect3DIndexBuffer9_Release(ib);
11715 if(shader)IDirect3DVertexShader9_Release(shader);
11716 refcount = IDirect3DDevice9_Release(device);
11717 ok(!refcount, "Device has %u references left.\n", refcount);
11718 done:
11719 IDirect3D9_Release(d3d);
11720 DestroyWindow(window);
11723 static void np2_stretch_rect_test(void)
11725 IDirect3DSurface9 *src = NULL, *dst = NULL, *backbuffer = NULL;
11726 IDirect3DTexture9 *dsttex = NULL;
11727 IDirect3DDevice9 *device;
11728 IDirect3D9 *d3d;
11729 D3DCOLOR color;
11730 ULONG refcount;
11731 HWND window;
11732 HRESULT hr;
11734 static const D3DRECT r1 = {0, 0, 50, 50 };
11735 static const D3DRECT r2 = {50, 0, 100, 50 };
11736 static const D3DRECT r3 = {50, 50, 100, 100};
11737 static const D3DRECT r4 = {0, 50, 50, 100};
11738 static const float quad[] =
11740 -1.0f, -1.0f, 0.1f, 0.0f, 0.0f,
11741 -1.0f, 1.0f, 0.1f, 0.0f, 1.0f,
11742 1.0f, -1.0f, 0.1f, 1.0f, 0.0f,
11743 1.0f, 1.0f, 0.1f, 1.0f, 1.0f,
11746 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
11747 0, 0, 640, 480, NULL, NULL, NULL, NULL);
11748 d3d = Direct3DCreate9(D3D_SDK_VERSION);
11749 ok(!!d3d, "Failed to create a D3D object.\n");
11750 if (!(device = create_device(d3d, window, window, TRUE)))
11752 skip("Failed to create a D3D device, skipping tests.\n");
11753 goto done;
11756 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
11757 ok(hr == D3D_OK, "IDirect3DDevice9_GetBackBuffer failed with %08x\n", hr);
11759 hr = IDirect3DDevice9_CreateRenderTarget(device, 100, 100, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &src, NULL );
11760 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateRenderTarget failed with %08x\n", hr);
11761 hr = IDirect3DDevice9_CreateTexture(device, 25, 25, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &dsttex, NULL);
11762 ok(hr == D3D_OK || hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_CreateTexture failed with %08x\n", hr);
11764 if(!src || !dsttex) {
11765 skip("One or more test resources could not be created\n");
11766 goto cleanup;
11769 hr = IDirect3DTexture9_GetSurfaceLevel(dsttex, 0, &dst);
11770 ok(hr == D3D_OK, "IDirect3DTexture9_GetSurfaceLevel failed with %08x\n", hr);
11772 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
11773 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
11775 /* Clear the StretchRect destination for debugging */
11776 hr = IDirect3DDevice9_SetRenderTarget(device, 0, dst);
11777 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
11778 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff00ff, 0.0, 0);
11779 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
11781 hr = IDirect3DDevice9_SetRenderTarget(device, 0, src);
11782 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
11784 hr = IDirect3DDevice9_Clear(device, 1, &r1, D3DCLEAR_TARGET, 0xffff0000, 0.0, 0);
11785 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
11786 hr = IDirect3DDevice9_Clear(device, 1, &r2, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
11787 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
11788 hr = IDirect3DDevice9_Clear(device, 1, &r3, D3DCLEAR_TARGET, 0xff0000ff, 0.0, 0);
11789 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
11790 hr = IDirect3DDevice9_Clear(device, 1, &r4, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
11791 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %08x\n", hr);
11793 /* Stretchrect before setting the render target back to the backbuffer. This will make Wine use
11794 * the target -> texture GL blit path
11796 hr = IDirect3DDevice9_StretchRect(device, src, NULL, dst, NULL, D3DTEXF_POINT);
11797 ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %08x\n", hr);
11798 IDirect3DSurface9_Release(dst);
11800 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
11801 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed with %08x\n", hr);
11803 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) dsttex);
11804 ok(hr == D3D_OK, "IDirect3DDevice9_SetTexture failed with %08x\n", hr);
11805 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
11806 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
11807 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
11808 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with %08x\n", hr);
11809 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
11810 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with %08x\n", hr);
11812 hr = IDirect3DDevice9_BeginScene(device);
11813 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
11814 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float) * 5);
11815 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
11816 hr = IDirect3DDevice9_EndScene(device);
11817 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
11819 color = getPixelColor(device, 160, 360);
11820 ok(color == 0x00ff0000, "stretchrect: Pixel 160,360 has color 0x%08x, expected 0x00ff0000\n", color);
11821 color = getPixelColor(device, 480, 360);
11822 ok(color == 0x0000ff00, "stretchrect: Pixel 480,360 has color 0x%08x, expected 0x0000ff00\n", color);
11823 color = getPixelColor(device, 480, 120);
11824 ok(color == 0x000000ff, "stretchrect: Pixel 480,120 has color 0x%08x, expected 0x000000ff\n", color);
11825 color = getPixelColor(device, 160, 120);
11826 ok(color == 0x00000000, "stretchrect: Pixel 160,120 has color 0x%08x, expected 0x00000000\n", color);
11827 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11828 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
11830 cleanup:
11831 if(src) IDirect3DSurface9_Release(src);
11832 if(backbuffer) IDirect3DSurface9_Release(backbuffer);
11833 if(dsttex) IDirect3DTexture9_Release(dsttex);
11834 refcount = IDirect3DDevice9_Release(device);
11835 ok(!refcount, "Device has %u references left.\n", refcount);
11836 done:
11837 IDirect3D9_Release(d3d);
11838 DestroyWindow(window);
11841 static void texop_test(void)
11843 IDirect3DVertexDeclaration9 *vertex_declaration = NULL;
11844 IDirect3DTexture9 *texture = NULL;
11845 D3DLOCKED_RECT locked_rect;
11846 IDirect3DDevice9 *device;
11847 IDirect3D9 *d3d;
11848 D3DCOLOR color;
11849 ULONG refcount;
11850 D3DCAPS9 caps;
11851 HWND window;
11852 HRESULT hr;
11853 unsigned i;
11855 static const struct {
11856 float x, y, z;
11857 float s, t;
11858 D3DCOLOR diffuse;
11859 } quad[] = {
11860 {-1.0f, -1.0f, 0.1f, -1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
11861 {-1.0f, 1.0f, 0.1f, -1.0f, 1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
11862 { 1.0f, -1.0f, 0.1f, 1.0f, -1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)},
11863 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f, D3DCOLOR_ARGB(0x55, 0xff, 0x00, 0x00)}
11866 static const D3DVERTEXELEMENT9 decl_elements[] = {
11867 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
11868 {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
11869 {0, 20, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
11870 D3DDECL_END()
11873 static const struct {
11874 D3DTEXTUREOP op;
11875 const char *name;
11876 DWORD caps_flag;
11877 D3DCOLOR result;
11878 } test_data[] = {
11879 {D3DTOP_SELECTARG1, "SELECTARG1", D3DTEXOPCAPS_SELECTARG1, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
11880 {D3DTOP_SELECTARG2, "SELECTARG2", D3DTEXOPCAPS_SELECTARG2, D3DCOLOR_ARGB(0x00, 0x33, 0x33, 0x33)},
11881 {D3DTOP_MODULATE, "MODULATE", D3DTEXOPCAPS_MODULATE, D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x00)},
11882 {D3DTOP_MODULATE2X, "MODULATE2X", D3DTEXOPCAPS_MODULATE2X, D3DCOLOR_ARGB(0x00, 0x00, 0x66, 0x00)},
11883 {D3DTOP_MODULATE4X, "MODULATE4X", D3DTEXOPCAPS_MODULATE4X, D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
11884 {D3DTOP_ADD, "ADD", D3DTEXOPCAPS_ADD, D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
11885 {D3DTOP_ADDSIGNED, "ADDSIGNED", D3DTEXOPCAPS_ADDSIGNED, D3DCOLOR_ARGB(0x00, 0x00, 0xb2, 0x00)},
11886 {D3DTOP_ADDSIGNED2X, "ADDSIGNED2X", D3DTEXOPCAPS_ADDSIGNED2X, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
11887 {D3DTOP_SUBTRACT, "SUBTRACT", D3DTEXOPCAPS_SUBTRACT, D3DCOLOR_ARGB(0x00, 0x00, 0xcc, 0x00)},
11888 {D3DTOP_ADDSMOOTH, "ADDSMOOTH", D3DTEXOPCAPS_ADDSMOOTH, D3DCOLOR_ARGB(0x00, 0x33, 0xff, 0x33)},
11889 {D3DTOP_BLENDDIFFUSEALPHA, "BLENDDIFFUSEALPHA", D3DTEXOPCAPS_BLENDDIFFUSEALPHA, D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
11890 {D3DTOP_BLENDTEXTUREALPHA, "BLENDTEXTUREALPHA", D3DTEXOPCAPS_BLENDTEXTUREALPHA, D3DCOLOR_ARGB(0x00, 0x14, 0xad, 0x14)},
11891 {D3DTOP_BLENDFACTORALPHA, "BLENDFACTORALPHA", D3DTEXOPCAPS_BLENDFACTORALPHA, D3DCOLOR_ARGB(0x00, 0x07, 0xe4, 0x07)},
11892 {D3DTOP_BLENDTEXTUREALPHAPM, "BLENDTEXTUREALPHAPM", D3DTEXOPCAPS_BLENDTEXTUREALPHAPM, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
11893 {D3DTOP_BLENDCURRENTALPHA, "BLENDCURRENTALPHA", D3DTEXOPCAPS_BLENDCURRENTALPHA, D3DCOLOR_ARGB(0x00, 0x22, 0x77, 0x22)},
11894 {D3DTOP_MODULATEALPHA_ADDCOLOR, "MODULATEALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x1f, 0xff, 0x1f)},
11895 {D3DTOP_MODULATECOLOR_ADDALPHA, "MODULATECOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0x99, 0xcc, 0x99)},
11896 {D3DTOP_MODULATEINVALPHA_ADDCOLOR, "MODULATEINVALPHA_ADDCOLOR", D3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR, D3DCOLOR_ARGB(0x00, 0x14, 0xff, 0x14)},
11897 {D3DTOP_MODULATEINVCOLOR_ADDALPHA, "MODULATEINVCOLOR_ADDALPHA", D3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA, D3DCOLOR_ARGB(0x00, 0xcc, 0x99, 0xcc)},
11898 /* BUMPENVMAP & BUMPENVMAPLUMINANCE have their own tests */
11899 {D3DTOP_DOTPRODUCT3, "DOTPRODUCT3", D3DTEXOPCAPS_DOTPRODUCT3, D3DCOLOR_ARGB(0x00, 0x99, 0x99, 0x99)},
11900 {D3DTOP_MULTIPLYADD, "MULTIPLYADD", D3DTEXOPCAPS_MULTIPLYADD, D3DCOLOR_ARGB(0x00, 0xff, 0x33, 0x00)},
11901 {D3DTOP_LERP, "LERP", D3DTEXOPCAPS_LERP, D3DCOLOR_ARGB(0x00, 0x00, 0x33, 0x33)},
11904 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
11905 0, 0, 640, 480, NULL, NULL, NULL, NULL);
11906 d3d = Direct3DCreate9(D3D_SDK_VERSION);
11907 ok(!!d3d, "Failed to create a D3D object.\n");
11908 if (!(device = create_device(d3d, window, window, TRUE)))
11910 skip("Failed to create a D3D device, skipping tests.\n");
11911 goto done;
11914 memset(&caps, 0, sizeof(caps));
11915 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
11916 ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
11918 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
11919 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed with 0x%08x\n", hr);
11920 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
11921 ok(SUCCEEDED(hr), "SetVertexDeclaration failed with 0x%08x\n", hr);
11923 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
11924 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
11925 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
11926 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
11927 *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x99, 0x00, 0xff, 0x00);
11928 hr = IDirect3DTexture9_UnlockRect(texture, 0);
11929 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
11930 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
11931 ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
11933 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG0, D3DTA_DIFFUSE);
11934 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
11935 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
11936 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
11937 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
11938 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
11940 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
11941 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
11943 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
11944 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
11945 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xdd333333);
11946 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
11947 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_ALPHA);
11948 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
11950 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
11951 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
11953 for (i = 0; i < sizeof(test_data) / sizeof(*test_data); ++i)
11955 if (!(caps.TextureOpCaps & test_data[i].caps_flag))
11957 skip("tex operation %s not supported\n", test_data[i].name);
11958 continue;
11961 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, test_data[i].op);
11962 ok(SUCCEEDED(hr), "SetTextureStageState (%s) failed with 0x%08x\n", test_data[i].name, hr);
11964 hr = IDirect3DDevice9_BeginScene(device);
11965 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
11967 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
11968 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
11970 hr = IDirect3DDevice9_EndScene(device);
11971 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
11973 color = getPixelColor(device, 320, 240);
11974 ok(color_match(color, test_data[i].result, 3), "Operation %s returned color 0x%08x, expected 0x%08x\n",
11975 test_data[i].name, color, test_data[i].result);
11977 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
11978 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
11981 IDirect3DTexture9_Release(texture);
11982 IDirect3DVertexDeclaration9_Release(vertex_declaration);
11983 refcount = IDirect3DDevice9_Release(device);
11984 ok(!refcount, "Device has %u references left.\n", refcount);
11985 done:
11986 IDirect3D9_Release(d3d);
11987 DestroyWindow(window);
11990 static void yuv_color_test(void)
11992 HRESULT hr;
11993 IDirect3DSurface9 *surface, *target;
11994 unsigned int i;
11995 D3DLOCKED_RECT lr;
11996 IDirect3D9 *d3d;
11997 D3DCOLOR color;
11998 D3DFORMAT skip_once = D3DFMT_UNKNOWN;
11999 IDirect3DDevice9 *device;
12000 D3DSURFACE_DESC desc;
12001 ULONG refcount;
12002 HWND window;
12004 static const struct
12006 DWORD in;
12007 D3DFORMAT format;
12008 const char *fmt_string;
12009 D3DCOLOR left, right;
12011 test_data[] =
12013 {0x00000000, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00008700, 0x00008700},
12014 {0xff000000, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00008700, 0x004bff1c},
12015 {0x00ff0000, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00b30000, 0x00b30000},
12016 {0x0000ff00, D3DFMT_UYVY, "D3DFMT_UYVY", 0x004bff1c, 0x00008700},
12017 {0x000000ff, D3DFMT_UYVY, "D3DFMT_UYVY", 0x000030e1, 0x000030e1},
12018 {0xffff0000, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00b30000, 0x00ffd01c},
12019 {0xff00ff00, D3DFMT_UYVY, "D3DFMT_UYVY", 0x004bff1c, 0x004bff1c},
12020 {0xff0000ff, D3DFMT_UYVY, "D3DFMT_UYVY", 0x000030e1, 0x004bffff},
12021 {0x00ffff00, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00ffd01c, 0x00b30000},
12022 {0x00ff00ff, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00b300e1, 0x00b300e1},
12023 {0x0000ffff, D3DFMT_UYVY, "D3DFMT_UYVY", 0x004bffff, 0x001030e1},
12024 {0xffffff00, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00ffd01c, 0x00ffd01c},
12025 {0xffff00ff, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00b300e1, 0x00ff79ff},
12026 {0xffffffff, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00ff79ff, 0x00ff79ff},
12027 {0x4cff4c54, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00ff0000, 0x00ff0000},
12028 {0x00800080, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00000000, 0x00000000},
12029 {0xff80ff80, D3DFMT_UYVY, "D3DFMT_UYVY", 0x00ffffff, 0x00ffffff},
12030 {0x1c6b1cff, D3DFMT_UYVY, "D3DFMT_UYVY", 0x000000fd, 0x000000fd},
12032 {0x00000000, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00008700, 0x00008700},
12033 {0xff000000, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00b30000, 0x00b30000},
12034 {0x00ff0000, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00008700, 0x004bff1c},
12035 {0x0000ff00, D3DFMT_YUY2, "D3DFMT_YUY2", 0x000030e1, 0x000030e1},
12036 {0x000000ff, D3DFMT_YUY2, "D3DFMT_YUY2", 0x004bff1c, 0x00008700},
12037 {0xffff0000, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00b30000, 0x00ffd01c},
12038 {0xff00ff00, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00b300e1, 0x00b300e1},
12039 {0xff0000ff, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00ffd01c, 0x00b30000},
12040 {0x00ffff00, D3DFMT_YUY2, "D3DFMT_YUY2", 0x000030e1, 0x004bffff},
12041 {0x00ff00ff, D3DFMT_YUY2, "D3DFMT_YUY2", 0x004bff1c, 0x004bff1c},
12042 {0x0000ffff, D3DFMT_YUY2, "D3DFMT_YUY2", 0x004bffff, 0x000030e1},
12043 {0xffffff00, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00b300e1, 0x00ff79ff},
12044 {0xffff00ff, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00ffd01c, 0x00ffd01c},
12045 {0xffffffff, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00ff79ff, 0x00ff79ff},
12046 {0x4cff4c54, D3DFMT_YUY2, "D3DFMT_YUY2", 0x000b8b00, 0x00b6ffa3},
12047 {0x00800080, D3DFMT_YUY2, "D3DFMT_YUY2", 0x0000ff00, 0x0000ff00},
12048 {0xff80ff80, D3DFMT_YUY2, "D3DFMT_YUY2", 0x00ff00ff, 0x00ff00ff},
12049 {0x1c6b1cff, D3DFMT_YUY2, "D3DFMT_YUY2", 0x006dff45, 0x0000d500},
12052 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
12053 0, 0, 640, 480, NULL, NULL, NULL, NULL);
12054 d3d = Direct3DCreate9(D3D_SDK_VERSION);
12055 ok(!!d3d, "Failed to create a D3D object.\n");
12056 if (!(device = create_device(d3d, window, window, TRUE)))
12058 skip("Failed to create a D3D device, skipping tests.\n");
12059 goto done;
12062 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &target);
12063 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
12064 hr = IDirect3DSurface9_GetDesc(target, &desc);
12065 ok(SUCCEEDED(hr), "Failed to get surface description, hr %#x.\n", hr);
12067 for (i = 0; i < sizeof(test_data) / sizeof(test_data[0]); i++)
12069 /* Some(all?) Windows drivers do not support YUV 3D textures, only 2D surfaces in StretchRect.
12070 * Thus use StretchRect to draw the YUV surface onto the screen instead of drawPrimitive. */
12071 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
12072 D3DFMT_X8R8G8B8, 0, D3DRTYPE_SURFACE, test_data[i].format)))
12074 if (skip_once != test_data[i].format)
12076 skip("%s is not supported.\n", test_data[i].fmt_string);
12077 skip_once = test_data[i].format;
12079 continue;
12081 if (FAILED(IDirect3D9_CheckDeviceFormatConversion(d3d, 0,
12082 D3DDEVTYPE_HAL, test_data[i].format, desc.Format)))
12084 if (skip_once != test_data[i].format)
12086 skip("Driver cannot blit %s surfaces.\n", test_data[i].fmt_string);
12087 skip_once = test_data[i].format;
12089 continue;
12092 /* A pixel is effectively 16 bit large, but two pixels are stored together, so the minimum size is 2x1.
12093 * However, Nvidia Windows drivers have problems with 2x1 YUY2/UYVY surfaces, so use a 4x1 surface and
12094 * fill the second block with dummy data. If the surface has a size of 2x1, those drivers ignore the
12095 * second luminance value, resulting in an incorrect color in the right pixel. */
12096 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 4, 1, test_data[i].format,
12097 D3DPOOL_DEFAULT, &surface, NULL);
12098 ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
12101 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
12102 ok(SUCCEEDED(hr), "Failed to lock surface, hr %#x.\n", hr);
12103 ((DWORD *)lr.pBits)[0] = test_data[i].in;
12104 ((DWORD *)lr.pBits)[1] = 0x00800080;
12105 hr = IDirect3DSurface9_UnlockRect(surface);
12106 ok(SUCCEEDED(hr), "Failed to unlock surface, hr %#x.\n", hr);
12108 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00000000, 1.0f, 0);
12109 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
12110 hr = IDirect3DDevice9_StretchRect(device, surface, NULL, target, NULL, D3DTEXF_POINT);
12111 ok(SUCCEEDED(hr), "Failed to draw surface onto backbuffer, hr %#x.\n", hr);
12113 /* Some Windows drivers (mostly Nvidia, but also some VM drivers) insist on doing linear filtering
12114 * although we asked for point filtering. Be careful when reading the results and use the pixel
12115 * centers. In the future we may want to add tests for the filtered pixels as well.
12117 * Unfortunately different implementations(Windows-Nvidia and Mac-AMD tested) interpret some colors
12118 * vastly differently, so we need a max diff of 18. */
12119 color = getPixelColor(device, 1, 240);
12120 ok(color_match(color, test_data[i].left, 18),
12121 "Input 0x%08x: Got color 0x%08x for pixel 1/1, expected 0x%08x, format %s.\n",
12122 test_data[i].in, color, test_data[i].left, test_data[i].fmt_string);
12123 color = getPixelColor(device, 318, 240);
12124 ok(color_match(color, test_data[i].right, 18),
12125 "Input 0x%08x: Got color 0x%08x for pixel 2/1, expected 0x%08x, format %s.\n",
12126 test_data[i].in, color, test_data[i].right, test_data[i].fmt_string);
12127 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12128 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
12129 IDirect3DSurface9_Release(surface);
12132 IDirect3DSurface9_Release(target);
12133 refcount = IDirect3DDevice9_Release(device);
12134 ok(!refcount, "Device has %u references left.\n", refcount);
12135 done:
12136 IDirect3D9_Release(d3d);
12137 DestroyWindow(window);
12140 static void yuv_layout_test(void)
12142 HRESULT hr;
12143 IDirect3DSurface9 *surface, *target;
12144 unsigned int fmt, i, x, y;
12145 D3DFORMAT format;
12146 const char *fmt_string;
12147 D3DLOCKED_RECT lr;
12148 IDirect3D9 *d3d;
12149 D3DCOLOR color;
12150 DWORD ref_color;
12151 BYTE *buf, *chroma_buf, *u_buf, *v_buf;
12152 UINT width = 20, height = 16;
12153 IDirect3DDevice9 *device;
12154 ULONG refcount;
12155 D3DCAPS9 caps;
12156 D3DSURFACE_DESC desc;
12157 HWND window;
12159 static const struct
12161 DWORD color1, color2;
12162 DWORD rgb1, rgb2;
12164 test_data[] =
12166 { 0x000000, 0xffffff, 0x00008800, 0x00ff7dff },
12167 { 0xff0000, 0x00ffff, 0x004aff14, 0x00b800ee },
12168 { 0x00ff00, 0xff00ff, 0x000024ee, 0x00ffe114 },
12169 { 0x0000ff, 0xffff00, 0x00b80000, 0x004affff },
12170 { 0xffff00, 0x0000ff, 0x004affff, 0x00b80000 },
12171 { 0xff00ff, 0x00ff00, 0x00ffe114, 0x000024ee },
12172 { 0x00ffff, 0xff0000, 0x00b800ee, 0x004aff14 },
12173 { 0xffffff, 0x000000, 0x00ff7dff, 0x00008800 },
12176 static const struct
12178 D3DFORMAT format;
12179 const char *str;
12181 formats[] =
12183 { D3DFMT_UYVY, "D3DFMT_UYVY", },
12184 { D3DFMT_YUY2, "D3DFMT_YUY2", },
12185 { MAKEFOURCC('Y','V','1','2'), "D3DFMT_YV12", },
12186 { MAKEFOURCC('N','V','1','2'), "D3DFMT_NV12", },
12189 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
12190 0, 0, 640, 480, NULL, NULL, NULL, NULL);
12191 d3d = Direct3DCreate9(D3D_SDK_VERSION);
12192 ok(!!d3d, "Failed to create a D3D object.\n");
12193 if (!(device = create_device(d3d, window, window, TRUE)))
12195 skip("Failed to create a D3D device, skipping tests.\n");
12196 goto done;
12199 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
12200 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
12201 if (caps.TextureCaps & D3DPTEXTURECAPS_POW2
12202 && !(caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL))
12204 skip("No NP2 texture support, skipping YUV texture layout test.\n");
12205 IDirect3DDevice9_Release(device);
12206 goto done;
12209 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &target);
12210 ok(hr == D3D_OK, "IDirect3DDevice9_GetRenderTarget failed, hr = %#x.\n", hr);
12211 hr = IDirect3DSurface9_GetDesc(target, &desc);
12212 ok(SUCCEEDED(hr), "Failed to get surface description, hr %#x.\n", hr);
12214 for (fmt = 0; fmt < sizeof(formats) / sizeof(formats[0]); fmt++)
12216 format = formats[fmt].format;
12217 fmt_string = formats[fmt].str;
12219 /* Some (all?) Windows drivers do not support YUV 3D textures, only 2D surfaces in
12220 * StretchRect. Thus use StretchRect to draw the YUV surface onto the screen instead
12221 * of drawPrimitive. */
12222 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0,
12223 D3DRTYPE_SURFACE, format) != D3D_OK)
12225 skip("%s is not supported.\n", fmt_string);
12226 continue;
12228 if (FAILED(IDirect3D9_CheckDeviceFormatConversion(d3d, 0,
12229 D3DDEVTYPE_HAL, format, desc.Format)))
12231 skip("Driver cannot blit %s surfaces.\n", fmt_string);
12232 continue;
12235 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, width, height, format, D3DPOOL_DEFAULT, &surface, NULL);
12236 ok(hr == D3D_OK, "IDirect3DDevice9_CreateOffscreenPlainSurface failed, hr = %#x.\n", hr);
12238 for (i = 0; i < sizeof(test_data) / sizeof(test_data[0]); i++)
12240 hr = IDirect3DSurface9_LockRect(surface, &lr, NULL, 0);
12241 ok(hr == D3D_OK, "IDirect3DSurface9_LockRect failed, hr = %#x.\n", hr);
12242 buf = lr.pBits;
12243 chroma_buf = buf + lr.Pitch * height;
12244 if (format == MAKEFOURCC('Y','V','1','2'))
12246 v_buf = chroma_buf;
12247 u_buf = chroma_buf + height / 2 * lr.Pitch/2;
12249 /* Draw the top left quarter of the screen with color1, the rest with color2 */
12250 for (y = 0; y < height; y++)
12252 for (x = 0; x < width; x += 2)
12254 DWORD color = (x < width / 2 && y < height / 2) ? test_data[i].color1 : test_data[i].color2;
12255 BYTE Y = (color >> 16) & 0xff;
12256 BYTE U = (color >> 8) & 0xff;
12257 BYTE V = (color >> 0) & 0xff;
12258 if (format == D3DFMT_UYVY)
12260 buf[y * lr.Pitch + 2 * x + 0] = U;
12261 buf[y * lr.Pitch + 2 * x + 1] = Y;
12262 buf[y * lr.Pitch + 2 * x + 2] = V;
12263 buf[y * lr.Pitch + 2 * x + 3] = Y;
12265 else if (format == D3DFMT_YUY2)
12267 buf[y * lr.Pitch + 2 * x + 0] = Y;
12268 buf[y * lr.Pitch + 2 * x + 1] = U;
12269 buf[y * lr.Pitch + 2 * x + 2] = Y;
12270 buf[y * lr.Pitch + 2 * x + 3] = V;
12272 else if (format == MAKEFOURCC('Y','V','1','2'))
12274 buf[y * lr.Pitch + x + 0] = Y;
12275 buf[y * lr.Pitch + x + 1] = Y;
12276 u_buf[(y / 2) * (lr.Pitch / 2) + (x / 2)] = U;
12277 v_buf[(y / 2) * (lr.Pitch / 2) + (x / 2)] = V;
12279 else if (format == MAKEFOURCC('N','V','1','2'))
12281 buf[y * lr.Pitch + x + 0] = Y;
12282 buf[y * lr.Pitch + x + 1] = Y;
12283 chroma_buf[(y / 2) * lr.Pitch + 2 * (x / 2) + 0] = U;
12284 chroma_buf[(y / 2) * lr.Pitch + 2 * (x / 2) + 1] = V;
12288 hr = IDirect3DSurface9_UnlockRect(surface);
12289 ok(hr == D3D_OK, "IDirect3DSurface9_UnlockRect failed, hr = %#x.\n", hr);
12291 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00000000, 1.0f, 0);
12292 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with %#x.\n", hr);
12293 hr = IDirect3DDevice9_StretchRect(device, surface, NULL, target, NULL, D3DTEXF_POINT);
12294 ok(hr == D3D_OK, "IDirect3DDevice9_StretchRect failed with %#x.\n", hr);
12296 /* Some Windows drivers (mostly Nvidia, but also some VM drivers) insist on doing linear filtering
12297 * although we asked for point filtering. To prevent running into precision problems, read at points
12298 * with some margin within each quadrant.
12300 * Unfortunately different implementations(Windows-Nvidia and Mac-AMD tested) interpret some colors
12301 * vastly differently, so we need a max diff of 18. */
12302 for (y = 0; y < 4; y++)
12304 for (x = 0; x < 4; x++)
12306 UINT xcoord = (1 + 2 * x) * 640 / 8;
12307 UINT ycoord = (1 + 2 * y) * 480 / 8;
12308 ref_color = (y < 2 && x < 2) ? test_data[i].rgb1 : test_data[i].rgb2;
12309 color = getPixelColor(device, xcoord, ycoord);
12310 ok(color_match(color, ref_color, 18),
12311 "Format %s: Got color %#x for pixel (%d/%d)/(%d/%d), pixel %d %d, expected %#x.\n",
12312 fmt_string, color, x, 4, y, 4, xcoord, ycoord, ref_color);
12315 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12317 ok(SUCCEEDED(hr), "Present failed with %#x.\n", hr);
12319 IDirect3DSurface9_Release(surface);
12322 IDirect3DSurface9_Release(target);
12323 refcount = IDirect3DDevice9_Release(device);
12324 ok(!refcount, "Device has %u references left.\n", refcount);
12325 done:
12326 IDirect3D9_Release(d3d);
12327 DestroyWindow(window);
12330 static void texop_range_test(void)
12332 IDirect3DTexture9 *texture;
12333 D3DLOCKED_RECT locked_rect;
12334 IDirect3DDevice9 *device;
12335 IDirect3D9 *d3d;
12336 ULONG refcount;
12337 D3DCAPS9 caps;
12338 DWORD color;
12339 HWND window;
12340 HRESULT hr;
12342 static const struct
12344 float x, y, z;
12345 D3DCOLOR diffuse;
12347 quad[] =
12349 {-1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
12350 {-1.0f, 1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
12351 { 1.0f, -1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)},
12352 { 1.0f, 1.0f, 0.1f, D3DCOLOR_ARGB(0xff, 0xff, 0xff, 0xff)}
12355 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
12356 0, 0, 640, 480, NULL, NULL, NULL, NULL);
12357 d3d = Direct3DCreate9(D3D_SDK_VERSION);
12358 ok(!!d3d, "Failed to create a D3D object.\n");
12359 if (!(device = create_device(d3d, window, window, TRUE)))
12361 skip("Failed to create a D3D device, skipping tests.\n");
12362 goto done;
12365 /* We need ADD and SUBTRACT operations */
12366 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
12367 ok(SUCCEEDED(hr), "GetDeviceCaps failed with 0x%08x\n", hr);
12368 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_ADD))
12370 skip("D3DTOP_ADD is not supported, skipping value range test.\n");
12371 IDirect3DDevice9_Release(device);
12372 goto done;
12374 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_SUBTRACT))
12376 skip("D3DTEXOPCAPS_SUBTRACT is not supported, skipping value range test.\n");
12377 IDirect3DDevice9_Release(device);
12378 goto done;
12381 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
12382 ok(SUCCEEDED(hr), "SetFVF failed with 0x%08x\n", hr);
12383 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
12384 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
12385 /* Stage 1: result = diffuse(=1.0) + diffuse
12386 * stage 2: result = result - tfactor(= 0.5)
12388 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
12389 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
12390 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
12391 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12392 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
12393 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12394 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_ADD);
12395 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12396 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
12397 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12398 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_TFACTOR);
12399 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12400 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
12401 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12403 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
12404 ok(SUCCEEDED(hr), "Failed to clear device, hr %#x.\n\n", hr);
12405 hr = IDirect3DDevice9_BeginScene(device);
12406 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
12407 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12408 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
12409 hr = IDirect3DDevice9_EndScene(device);
12410 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
12412 color = getPixelColor(device, 320, 240);
12413 ok(color_match(color, 0x00808080, 1), "texop Range > 1.0 returned 0x%08x, expected 0x00808080\n",
12414 color);
12415 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12416 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
12418 hr = IDirect3DDevice9_CreateTexture(device, 1, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL);
12419 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateTexture failed with 0x%08x\n", hr);
12420 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
12421 ok(SUCCEEDED(hr), "LockRect failed with 0x%08x\n", hr);
12422 *((DWORD *)locked_rect.pBits) = D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0x00);
12423 hr = IDirect3DTexture9_UnlockRect(texture, 0);
12424 ok(SUCCEEDED(hr), "UnlockRect failed with 0x%08x\n", hr);
12425 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
12426 ok(SUCCEEDED(hr), "SetTexture failed with 0x%08x\n", hr);
12428 /* Stage 1: result = texture(=0.0) - tfactor(= 0.5)
12429 * stage 2: result = result + diffuse(1.0)
12431 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
12432 ok(SUCCEEDED(hr), "SetRenderState failed with 0x%08x\n", hr);
12433 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
12434 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12435 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
12436 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12437 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SUBTRACT);
12438 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12439 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT);
12440 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12441 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
12442 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12443 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
12444 ok(SUCCEEDED(hr), "SetTextureStageState failed with 0x%08x\n", hr);
12446 hr = IDirect3DDevice9_BeginScene(device);
12447 ok(SUCCEEDED(hr), "BeginScene failed with 0x%08x\n", hr);
12448 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12449 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed with 0x%08x\n", hr);
12450 hr = IDirect3DDevice9_EndScene(device);
12451 ok(SUCCEEDED(hr), "EndScene failed with 0x%08x\n", hr);
12453 color = getPixelColor(device, 320, 240);
12454 ok(color_match(color, 0x00ffffff, 1), "texop Range < 0.0 returned 0x%08x, expected 0x00ffffff\n",
12455 color);
12456 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12457 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
12459 IDirect3DTexture9_Release(texture);
12460 refcount = IDirect3DDevice9_Release(device);
12461 ok(!refcount, "Device has %u references left.\n", refcount);
12462 done:
12463 IDirect3D9_Release(d3d);
12464 DestroyWindow(window);
12467 static void alphareplicate_test(void)
12469 IDirect3DDevice9 *device;
12470 IDirect3D9 *d3d;
12471 ULONG refcount;
12472 DWORD color;
12473 HWND window;
12474 HRESULT hr;
12476 static const struct
12478 struct vec3 position;
12479 DWORD diffuse;
12481 quad[] =
12483 {{-1.0f, -1.0f, 0.1f}, 0x80ff00ff},
12484 {{-1.0f, 1.0f, 0.1f}, 0x80ff00ff},
12485 {{ 1.0f, -1.0f, 0.1f}, 0x80ff00ff},
12486 {{ 1.0f, 1.0f, 0.1f}, 0x80ff00ff},
12489 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
12490 0, 0, 640, 480, NULL, NULL, NULL, NULL);
12491 d3d = Direct3DCreate9(D3D_SDK_VERSION);
12492 ok(!!d3d, "Failed to create a D3D object.\n");
12493 if (!(device = create_device(d3d, window, window, TRUE)))
12495 skip("Failed to create a D3D device, skipping tests.\n");
12496 goto done;
12499 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
12500 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
12502 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
12503 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
12505 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
12506 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
12507 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE | D3DTA_ALPHAREPLICATE);
12508 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
12510 hr = IDirect3DDevice9_BeginScene(device);
12511 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
12512 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12513 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
12514 hr = IDirect3DDevice9_EndScene(device);
12515 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
12517 color = getPixelColor(device, 320, 240);
12518 ok(color_match(color, 0x00808080, 1), "alphareplicate test 0x%08x, expected 0x00808080\n",
12519 color);
12520 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12521 ok(SUCCEEDED(hr), "Present failed with 0x%08x\n", hr);
12523 refcount = IDirect3DDevice9_Release(device);
12524 ok(!refcount, "Device has %u references left.\n", refcount);
12525 done:
12526 IDirect3D9_Release(d3d);
12527 DestroyWindow(window);
12530 static void dp3_alpha_test(void)
12532 IDirect3DDevice9 *device;
12533 IDirect3D9 *d3d;
12534 ULONG refcount;
12535 D3DCAPS9 caps;
12536 DWORD color;
12537 HWND window;
12538 HRESULT hr;
12540 static const struct
12542 struct vec3 position;
12543 DWORD diffuse;
12545 quad[] =
12547 {{-1.0f, -1.0f, 0.1f}, 0x408080c0},
12548 {{-1.0f, 1.0f, 0.1f}, 0x408080c0},
12549 {{ 1.0f, -1.0f, 0.1f}, 0x408080c0},
12550 {{ 1.0f, 1.0f, 0.1f}, 0x408080c0},
12553 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
12554 0, 0, 640, 480, NULL, NULL, NULL, NULL);
12555 d3d = Direct3DCreate9(D3D_SDK_VERSION);
12556 ok(!!d3d, "Failed to create a D3D object.\n");
12557 if (!(device = create_device(d3d, window, window, TRUE)))
12559 skip("Failed to create a D3D device, skipping tests.\n");
12560 goto done;
12563 memset(&caps, 0, sizeof(caps));
12564 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
12565 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
12566 if (!(caps.TextureOpCaps & D3DTEXOPCAPS_DOTPRODUCT3))
12568 skip("D3DTOP_DOTPRODUCT3 not supported\n");
12569 IDirect3DDevice9_Release(device);
12570 goto done;
12573 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
12574 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
12576 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
12577 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
12579 /* dp3_x4 r0, diffuse_bias, tfactor_bias
12580 * mov r0.a, diffuse.a
12581 * mov r0, r0.a
12583 * It turns out that the 2nd line is ignored, and the dp3 result written into r0.a instead
12584 * 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
12585 * (0.0 * 0.5 + 0.0 * 0.5 + 0.25 * 0.5) * 4 = 0.125 * 4 = 0.5, with a bunch of inprecision.
12587 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DOTPRODUCT3);
12588 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
12589 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
12590 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
12591 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
12592 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
12593 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
12594 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
12595 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
12596 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
12597 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
12598 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
12599 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_CURRENT | D3DTA_ALPHAREPLICATE);
12600 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
12601 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
12602 ok(hr == D3D_OK, "IDirect3DDevice9_SetTextureStageState failed with 0x%08x\n", hr);
12603 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0xffffffff);
12604 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
12605 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
12606 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
12608 hr = IDirect3DDevice9_BeginScene(device);
12609 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
12610 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12611 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
12612 hr = IDirect3DDevice9_EndScene(device);
12613 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
12615 color = getPixelColor(device, 320, 240);
12616 ok(color_match(color, 0x00808080, 4), "dp3 alpha test 0x%08x, expected 0x00808080\n",
12617 color);
12618 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12619 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
12621 refcount = IDirect3DDevice9_Release(device);
12622 ok(!refcount, "Device has %u references left.\n", refcount);
12623 done:
12624 IDirect3D9_Release(d3d);
12625 DestroyWindow(window);
12628 static void zwriteenable_test(void)
12630 IDirect3DDevice9 *device;
12631 IDirect3D9 *d3d;
12632 D3DCOLOR color;
12633 ULONG refcount;
12634 HWND window;
12635 HRESULT hr;
12637 static const struct
12639 struct vec3 position;
12640 DWORD diffuse;
12642 quad1[] =
12644 {{-1.0f, -1.0f, 0.1f}, 0x00ff0000},
12645 {{-1.0f, 1.0f, 0.1f}, 0x00ff0000},
12646 {{ 1.0f, -1.0f, 0.1f}, 0x00ff0000},
12647 {{ 1.0f, 1.0f, 0.1f}, 0x00ff0000},
12649 quad2[] =
12651 {{-1.0f, -1.0f, 0.9f}, 0x0000ff00},
12652 {{-1.0f, 1.0f, 0.9f}, 0x0000ff00},
12653 {{ 1.0f, -1.0f, 0.9f}, 0x0000ff00},
12654 {{ 1.0f, 1.0f, 0.9f}, 0x0000ff00},
12657 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
12658 0, 0, 640, 480, NULL, NULL, NULL, NULL);
12659 d3d = Direct3DCreate9(D3D_SDK_VERSION);
12660 ok(!!d3d, "Failed to create a D3D object.\n");
12661 if (!(device = create_device(d3d, window, window, TRUE)))
12663 skip("Failed to create a D3D device, skipping tests.\n");
12664 goto done;
12667 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
12668 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
12670 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
12671 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
12672 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
12673 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
12674 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
12675 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
12676 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
12677 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
12678 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
12679 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
12681 hr = IDirect3DDevice9_BeginScene(device);
12682 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
12683 /* The Z buffer is filled with 1.0. Draw a red quad with z = 0.1,
12684 * zenable = D3DZB_FALSE, zwriteenable = TRUE. The red color is written
12685 * because the z test is disabled. The question is whether the z = 0.1
12686 * values are written into the Z buffer. After the draw, set
12687 * zenable = TRUE and draw a green quad at z = 0.9. If the values are
12688 * written, the z test will fail(0.9 > 0.1) and the red color remains. If
12689 * the values are not written, the z test succeeds(0.9 < 1.0) and the
12690 * green color is written. It turns out that the screen is green, so
12691 * zenable = D3DZB_FALSE and zwriteenable = TRUE does NOT write to the z
12692 * buffer. */
12693 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
12694 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
12695 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
12696 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
12697 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
12698 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
12699 hr = IDirect3DDevice9_EndScene(device);
12700 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
12702 color = getPixelColor(device, 320, 240);
12703 ok(color_match(color, 0x0000ff00, 1), "zwriteenable test returned 0x%08x, expected 0x0000ff00\n",
12704 color);
12705 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12706 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
12708 refcount = IDirect3DDevice9_Release(device);
12709 ok(!refcount, "Device has %u references left.\n", refcount);
12710 done:
12711 IDirect3D9_Release(d3d);
12712 DestroyWindow(window);
12715 static void alphatest_test(void)
12717 #define ALPHATEST_PASSED 0x0000ff00
12718 #define ALPHATEST_FAILED 0x00ff0000
12719 IDirect3DDevice9 *device;
12720 unsigned int i, j;
12721 IDirect3D9 *d3d;
12722 D3DCOLOR color;
12723 ULONG refcount;
12724 D3DCAPS9 caps;
12725 HWND window;
12726 HRESULT hr;
12728 static const struct
12730 D3DCMPFUNC func;
12731 D3DCOLOR color_less;
12732 D3DCOLOR color_equal;
12733 D3DCOLOR color_greater;
12735 testdata[] =
12737 {D3DCMP_NEVER, ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_FAILED},
12738 {D3DCMP_LESS, ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_FAILED},
12739 {D3DCMP_EQUAL, ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_FAILED},
12740 {D3DCMP_LESSEQUAL, ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_FAILED},
12741 {D3DCMP_GREATER, ALPHATEST_FAILED, ALPHATEST_FAILED, ALPHATEST_PASSED},
12742 {D3DCMP_NOTEQUAL, ALPHATEST_PASSED, ALPHATEST_FAILED, ALPHATEST_PASSED},
12743 {D3DCMP_GREATEREQUAL, ALPHATEST_FAILED, ALPHATEST_PASSED, ALPHATEST_PASSED},
12744 {D3DCMP_ALWAYS, ALPHATEST_PASSED, ALPHATEST_PASSED, ALPHATEST_PASSED},
12746 static const struct
12748 struct vec3 position;
12749 DWORD diffuse;
12751 quad[] =
12753 {{-1.0f, -1.0f, 0.1f}, ALPHATEST_PASSED | 0x80000000},
12754 {{-1.0f, 1.0f, 0.1f}, ALPHATEST_PASSED | 0x80000000},
12755 {{ 1.0f, -1.0f, 0.1f}, ALPHATEST_PASSED | 0x80000000},
12756 {{ 1.0f, 1.0f, 0.1f}, ALPHATEST_PASSED | 0x80000000},
12759 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
12760 0, 0, 640, 480, NULL, NULL, NULL, NULL);
12761 d3d = Direct3DCreate9(D3D_SDK_VERSION);
12762 ok(!!d3d, "Failed to create a D3D object.\n");
12763 if (!(device = create_device(d3d, window, window, TRUE)))
12765 skip("Failed to create a D3D device, skipping tests.\n");
12766 goto done;
12769 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
12770 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
12772 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
12773 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
12774 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHATESTENABLE, TRUE);
12775 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
12776 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
12777 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
12779 for (j = 0; j < 2; ++j)
12781 if (j == 1)
12783 /* Try a pixel shader instead of fixed function. The wined3d code
12784 * may emulate the alpha test either for performance reasons
12785 * (floating point RTs) or to work around driver bugs (GeForce
12786 * 7x00 cards on MacOS). There may be a different codepath for ffp
12787 * and shader in this case, and the test should cover both. */
12788 IDirect3DPixelShader9 *ps;
12789 static const DWORD shader_code[] =
12791 0xffff0101, /* ps_1_1 */
12792 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
12793 0x0000ffff /* end */
12795 memset(&caps, 0, sizeof(caps));
12796 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
12797 ok(hr == D3D_OK, "IDirect3DDevice9_GetDeviceCaps failed with 0x%08x\n", hr);
12798 if(caps.PixelShaderVersion < D3DPS_VERSION(1, 1)) {
12799 break;
12802 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &ps);
12803 ok(hr == D3D_OK, "IDirect3DDevice9_CreatePixelShader failed with 0x%08x\n", hr);
12804 hr = IDirect3DDevice9_SetPixelShader(device, ps);
12805 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed with 0x%08x\n", hr);
12806 IDirect3DPixelShader9_Release(ps);
12809 for(i = 0; i < (sizeof(testdata)/sizeof(testdata[0])); i++) {
12810 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAFUNC, testdata[i].func);
12811 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
12813 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
12814 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
12815 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x90);
12816 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
12817 hr = IDirect3DDevice9_BeginScene(device);
12818 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
12819 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12820 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
12821 hr = IDirect3DDevice9_EndScene(device);
12822 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
12823 color = getPixelColor(device, 320, 240);
12824 ok(color_match(color, testdata[i].color_less, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha < ref, func %u\n",
12825 color, testdata[i].color_less, testdata[i].func);
12826 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12827 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
12829 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
12830 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
12831 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x80);
12832 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
12833 hr = IDirect3DDevice9_BeginScene(device);
12834 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
12835 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12836 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
12837 hr = IDirect3DDevice9_EndScene(device);
12838 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
12839 color = getPixelColor(device, 320, 240);
12840 ok(color_match(color, testdata[i].color_equal, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha == ref, func %u\n",
12841 color, testdata[i].color_equal, testdata[i].func);
12842 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12843 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
12845 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, ALPHATEST_FAILED, 0.0, 0);
12846 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
12847 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHAREF, 0x70);
12848 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed with 0x%08x\n", hr);
12849 hr = IDirect3DDevice9_BeginScene(device);
12850 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
12851 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
12852 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
12853 hr = IDirect3DDevice9_EndScene(device);
12854 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
12855 color = getPixelColor(device, 320, 240);
12856 ok(color_match(color, testdata[i].color_greater, 1), "Alphatest failed. Got color 0x%08x, expected 0x%08x. alpha > ref, func %u\n",
12857 color, testdata[i].color_greater, testdata[i].func);
12858 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12859 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present failed with 0x%08x\n", hr);
12863 refcount = IDirect3DDevice9_Release(device);
12864 ok(!refcount, "Device has %u references left.\n", refcount);
12865 done:
12866 IDirect3D9_Release(d3d);
12867 DestroyWindow(window);
12870 static void sincos_test(void)
12872 IDirect3DVertexShader9 *sin_shader, *cos_shader;
12873 IDirect3DDevice9 *device;
12874 struct vec3 data[1280];
12875 IDirect3D9 *d3d;
12876 unsigned int i;
12877 ULONG refcount;
12878 D3DCAPS9 caps;
12879 HWND window;
12880 HRESULT hr;
12882 static const DWORD sin_shader_code[] =
12884 0xfffe0200, /* vs_2_0 */
12885 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
12886 0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a, /* def c2, 3.14159, 1, 0, 0.85 */
12887 0x03000005, 0x80010001, 0x90000000, 0xa0000002, /* mul r1.x, v0.x, c2.x */
12888 0x04000025, 0x80020000, 0x80000001, 0xa0e40000, 0xa0e40001, /* sincos r0.y, r1.x, c0, c1 */
12889 0x02000001, 0xc00d0000, 0x90e40000, /* mov oPos.xzw, v0 */
12890 0x03000005, 0xc0020000, 0x80550000, 0xa0ff0002, /* mul oPos.y, r0.y, c2.w */
12891 0x02000001, 0xd00f0000, 0xa0a60002, /* mov oD0, c2.zyzz */
12892 0x0000ffff /* end */
12894 static const DWORD cos_shader_code[] =
12896 0xfffe0200, /* vs_2_0 */
12897 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
12898 0x05000051, 0xa00f0002, 0x40490fdb, 0x3f800000, 0x00000000, 0x3f59999a, /* def c2, 3.14159, 1, 0, 0.85 */
12899 0x03000005, 0x80010001, 0x90000000, 0xa0000002, /* mul r1.x, v0.x, c2.x */
12900 0x04000025, 0x80010000, 0x80000001, 0xa0e40000, 0xa0e40001, /* sincos r0.x, r1.x, c0, c1 */
12901 0x02000001, 0xc00d0000, 0x90e40000, /* mov oPos.xzw, v0 */
12902 0x03000005, 0xc0020000, 0x80000000, 0xa0ff0002, /* mul oPos.y, r0.x, c2.w */
12903 0x02000001, 0xd00f0000, 0xa0a90002, /* mov oD0, c2.yzzz */
12904 0x0000ffff /* end */
12906 static const float sincosc1[4] = {D3DSINCOSCONST1};
12907 static const float sincosc2[4] = {D3DSINCOSCONST2};
12909 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
12910 0, 0, 640, 480, NULL, NULL, NULL, NULL);
12911 d3d = Direct3DCreate9(D3D_SDK_VERSION);
12912 ok(!!d3d, "Failed to create a D3D object.\n");
12913 if (!(device = create_device(d3d, window, window, TRUE)))
12915 skip("Failed to create a D3D device, skipping tests.\n");
12916 goto done;
12919 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
12920 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
12921 if (caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
12923 skip("No vs_2_0 support, skipping tests.\n");
12924 IDirect3DDevice9_Release(device);
12925 goto done;
12928 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
12929 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
12931 hr = IDirect3DDevice9_CreateVertexShader(device, sin_shader_code, &sin_shader);
12932 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
12933 hr = IDirect3DDevice9_CreateVertexShader(device, cos_shader_code, &cos_shader);
12934 ok(hr == D3D_OK, "IDirect3DDevice9_Clear failed with 0x%08x\n", hr);
12935 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
12936 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with 0x%08x\n", hr);
12937 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, sincosc1, 1);
12938 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
12939 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, sincosc2, 1);
12940 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShaderConstantF failed with 0x%08x\n", hr);
12942 /* Generate a point from -1 to 1 every 0.5 pixels */
12943 for(i = 0; i < 1280; i++) {
12944 data[i].x = (-640.0 + i) / 640.0;
12945 data[i].y = 0.0;
12946 data[i].z = 0.1;
12949 hr = IDirect3DDevice9_BeginScene(device);
12950 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
12952 hr = IDirect3DDevice9_SetVertexShader(device, sin_shader);
12953 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
12954 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
12955 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
12957 hr = IDirect3DDevice9_SetVertexShader(device, cos_shader);
12958 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
12959 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_POINTLIST, 1280, data, sizeof(*data));
12960 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
12962 hr = IDirect3DDevice9_EndScene(device);
12963 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
12965 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
12966 ok(SUCCEEDED(hr), "IDirect3DDevice9_Present returned %#x.\n", hr);
12967 /* TODO: Find a way to properly validate the lines. Precicion issues make this a kinda nasty task */
12969 IDirect3DVertexShader9_Release(sin_shader);
12970 IDirect3DVertexShader9_Release(cos_shader);
12971 refcount = IDirect3DDevice9_Release(device);
12972 ok(!refcount, "Device has %u references left.\n", refcount);
12973 done:
12974 IDirect3D9_Release(d3d);
12975 DestroyWindow(window);
12978 static void loop_index_test(void)
12980 IDirect3DVertexShader9 *shader;
12981 IDirect3DDevice9 *device;
12982 IDirect3D9 *d3d;
12983 float values[4];
12984 ULONG refcount;
12985 D3DCAPS9 caps;
12986 DWORD color;
12987 HWND window;
12988 HRESULT hr;
12990 static const DWORD shader_code[] =
12992 0xfffe0200, /* vs_2_0 */
12993 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
12994 0x02000001, 0x800f0000, 0xa0e40000, /* mov r0, c0 */
12995 0x0200001b, 0xf0e40800, 0xf0e40000, /* loop aL, i0 */
12996 0x04000002, 0x800f0000, 0x80e40000, 0xa0e42001, 0xf0e40800, /* add r0, r0, c[aL + 1] */
12997 0x0000001d, /* endloop */
12998 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
12999 0x02000001, 0xd00f0000, 0x80e40000, /* mov oD0, r0 */
13000 0x0000ffff /* END */
13002 static const float quad[] =
13004 -1.0f, -1.0f, 0.1f,
13005 -1.0f, 1.0f, 0.1f,
13006 1.0f, -1.0f, 0.1f,
13007 1.0f, 1.0f, 0.1f,
13009 static const float zero[4] = {0.0f, 0.0f, 0.0f, 0.0f};
13010 static const float one[4] = {1.0f, 1.0f, 1.0f, 1.0f};
13011 static const int i0[4] = {2, 10, -3, 0};
13013 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
13014 0, 0, 640, 480, NULL, NULL, NULL, NULL);
13015 d3d = Direct3DCreate9(D3D_SDK_VERSION);
13016 ok(!!d3d, "Failed to create a D3D object.\n");
13017 if (!(device = create_device(d3d, window, window, TRUE)))
13019 skip("Failed to create a D3D device, skipping tests.\n");
13020 goto done;
13023 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
13024 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
13025 if (caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
13027 skip("No vs_2_0 support, skipping tests.\n");
13028 IDirect3DDevice9_Release(device);
13029 goto done;
13032 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
13033 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
13034 hr = IDirect3DDevice9_SetVertexShader(device, shader);
13035 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
13036 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
13037 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
13038 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff0000, 1.0f, 0);
13039 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
13041 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 0, zero, 1);
13042 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13043 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 1, one, 1);
13044 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13045 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 2, one, 1);
13046 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13047 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 3, one, 1);
13048 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13049 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 4, one, 1);
13050 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13051 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 5, one, 1);
13052 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13053 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 6, one, 1);
13054 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13055 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 7, one, 1);
13056 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13057 values[0] = 1.0;
13058 values[1] = 1.0;
13059 values[2] = 0.0;
13060 values[3] = 0.0;
13061 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 8, values, 1);
13062 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13063 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 9, one, 1);
13064 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13065 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 10, one, 1);
13066 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13067 values[0] = -1.0;
13068 values[1] = 0.0;
13069 values[2] = 0.0;
13070 values[3] = 0.0;
13071 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 11, values, 1);
13072 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13073 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 12, one, 1);
13074 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13075 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 13, one, 1);
13076 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13077 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 14, one, 1);
13078 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13079 hr = IDirect3DDevice9_SetVertexShaderConstantF(device, 15, one, 1);
13080 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantF returned %#x.\n", hr);
13082 hr = IDirect3DDevice9_SetVertexShaderConstantI(device, 0, i0, 1);
13083 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetVertexShaderConstantI returned %#x.\n", hr);
13085 hr = IDirect3DDevice9_BeginScene(device);
13086 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
13087 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
13088 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
13089 hr = IDirect3DDevice9_EndScene(device);
13090 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
13091 color = getPixelColor(device, 320, 240);
13092 ok(color_match(color, 0x0000ff00, 1),
13093 "aL indexing test returned color 0x%08x, expected 0x0000ff00\n", color);
13094 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13095 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
13097 IDirect3DVertexShader9_Release(shader);
13098 refcount = IDirect3DDevice9_Release(device);
13099 ok(!refcount, "Device has %u references left.\n", refcount);
13100 done:
13101 IDirect3D9_Release(d3d);
13102 DestroyWindow(window);
13105 static void sgn_test(void)
13107 IDirect3DVertexShader9 *shader;
13108 IDirect3DDevice9 *device;
13109 IDirect3D9 *d3d;
13110 ULONG refcount;
13111 D3DCAPS9 caps;
13112 DWORD color;
13113 HWND window;
13114 HRESULT hr;
13116 static const DWORD shader_code[] =
13118 0xfffe0200, /* vs_2_0 */
13119 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position o0 */
13120 0x05000051, 0xa00f0000, 0xbf000000, 0x00000000, 0x3f000000, 0x41400000, /* def c0, -0.5, 0.0, 0.5, 12.0 */
13121 0x05000051, 0xa00f0001, 0x3fc00000, 0x00000000, 0x00000000, 0x00000000, /* def c1, 1.5, 0.0, 0.0, 0.0 */
13122 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
13123 0x04000022, 0x800f0000, 0xa0e40000, 0x80e40001, 0x80e40002, /* sgn r0, c0, r1, r2 */
13124 0x03000002, 0xd00f0000, 0x80e40000, 0xa0e40001, /* add oD0, r0, c1 */
13125 0x0000ffff /* end */
13127 static const float quad[] =
13129 -1.0f, -1.0f, 0.1f,
13130 -1.0f, 1.0f, 0.1f,
13131 1.0f, -1.0f, 0.1f,
13132 1.0f, 1.0f, 0.1f,
13135 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
13136 0, 0, 640, 480, NULL, NULL, NULL, NULL);
13137 d3d = Direct3DCreate9(D3D_SDK_VERSION);
13138 ok(!!d3d, "Failed to create a D3D object.\n");
13139 if (!(device = create_device(d3d, window, window, TRUE)))
13141 skip("Failed to create a D3D device, skipping tests.\n");
13142 goto done;
13145 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
13146 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
13147 if (caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
13149 skip("No vs_2_0 support, skipping tests.\n");
13150 IDirect3DDevice9_Release(device);
13151 goto done;
13154 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
13155 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader failed with %08x\n", hr);
13156 hr = IDirect3DDevice9_SetVertexShader(device, shader);
13157 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed with %08x\n", hr);
13158 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
13159 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF failed with %08x\n", hr);
13160 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff0000, 1.0f, 0);
13161 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
13163 hr = IDirect3DDevice9_BeginScene(device);
13164 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
13165 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
13166 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
13167 hr = IDirect3DDevice9_EndScene(device);
13168 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
13169 color = getPixelColor(device, 320, 240);
13170 ok(color_match(color, 0x008000ff, 1),
13171 "sgn test returned color 0x%08x, expected 0x008000ff\n", color);
13172 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13173 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
13175 IDirect3DVertexShader9_Release(shader);
13176 refcount = IDirect3DDevice9_Release(device);
13177 ok(!refcount, "Device has %u references left.\n", refcount);
13178 done:
13179 IDirect3D9_Release(d3d);
13180 DestroyWindow(window);
13183 static void viewport_test(void)
13185 IDirect3DDevice9 *device;
13186 BOOL draw_failed = TRUE;
13187 D3DVIEWPORT9 vp;
13188 IDirect3D9 *d3d;
13189 ULONG refcount;
13190 DWORD color;
13191 HWND window;
13192 HRESULT hr;
13194 static const float quad[] =
13196 -0.5f, -0.5f, 0.1f,
13197 -0.5f, 0.5f, 0.1f,
13198 0.5f, -0.5f, 0.1f,
13199 0.5f, 0.5f, 0.1f,
13202 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
13203 0, 0, 640, 480, NULL, NULL, NULL, NULL);
13204 d3d = Direct3DCreate9(D3D_SDK_VERSION);
13205 ok(!!d3d, "Failed to create a D3D object.\n");
13206 if (!(device = create_device(d3d, window, window, TRUE)))
13208 skip("Failed to create a D3D device, skipping tests.\n");
13209 goto done;
13212 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff0000, 1.0f, 0);
13213 ok(hr == D3D_OK, "IDirect3DDevice9_Clear returned %08x\n", hr);
13215 /* Test a viewport with Width and Height bigger than the surface dimensions
13217 * TODO: Test Width < surface.width, but X + Width > surface.width
13218 * TODO: Test Width < surface.width, what happens with the height?
13220 * The expected behavior is that the viewport behaves like the "default"
13221 * viewport with X = Y = 0, Width = surface_width, Height = surface_height,
13222 * MinZ = 0.0, MaxZ = 1.0.
13224 * Starting with Windows 7 the behavior among driver versions is not
13225 * consistent. The SetViewport call is accepted on all drivers. Some
13226 * drivers(older nvidia ones) refuse to draw and return an error. Newer
13227 * nvidia drivers draw, but use the actual values in the viewport and only
13228 * display the upper left part on the surface.
13230 memset(&vp, 0, sizeof(vp));
13231 vp.X = 0;
13232 vp.Y = 0;
13233 vp.Width = 10000;
13234 vp.Height = 10000;
13235 vp.MinZ = 0.0;
13236 vp.MaxZ = 0.0;
13237 hr = IDirect3DDevice9_SetViewport(device, &vp);
13238 ok(hr == D3D_OK, "IDirect3DDevice9_SetViewport failed with %08x\n", hr);
13240 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
13241 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
13243 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
13244 ok(hr == D3D_OK, "IDirect3DDevice9_SetFVF returned %08x\n", hr);
13245 hr = IDirect3DDevice9_BeginScene(device);
13246 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
13247 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, 3 * sizeof(float));
13248 ok(hr == D3D_OK || broken(hr == D3DERR_INVALIDCALL), "Got unexpected hr %#x.\n", hr);
13249 draw_failed = FAILED(hr);
13250 hr = IDirect3DDevice9_EndScene(device);
13251 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
13253 if(!draw_failed)
13255 color = getPixelColor(device, 158, 118);
13256 ok(color == 0x00ff0000, "viewport test: (158,118) has color %08x\n", color);
13257 color = getPixelColor(device, 162, 118);
13258 ok(color == 0x00ff0000, "viewport test: (162,118) has color %08x\n", color);
13259 color = getPixelColor(device, 158, 122);
13260 ok(color == 0x00ff0000, "viewport test: (158,122) has color %08x\n", color);
13261 color = getPixelColor(device, 162, 122);
13262 ok(color == 0x00ffffff || broken(color == 0x00ff0000), "viewport test: (162,122) has color %08x\n", color);
13264 color = getPixelColor(device, 478, 358);
13265 ok(color == 0x00ffffff || broken(color == 0x00ff0000), "viewport test: (478,358 has color %08x\n", color);
13266 color = getPixelColor(device, 482, 358);
13267 ok(color == 0x00ff0000, "viewport test: (482,358) has color %08x\n", color);
13268 color = getPixelColor(device, 478, 362);
13269 ok(color == 0x00ff0000, "viewport test: (478,362) has color %08x\n", color);
13270 color = getPixelColor(device, 482, 362);
13271 ok(color == 0x00ff0000, "viewport test: (482,362) has color %08x\n", color);
13274 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13275 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
13277 refcount = IDirect3DDevice9_Release(device);
13278 ok(!refcount, "Device has %u references left.\n", refcount);
13279 done:
13280 IDirect3D9_Release(d3d);
13281 DestroyWindow(window);
13284 /* This test tests depth clamping / clipping behaviour:
13285 * - With software vertex processing, depth values are clamped to the
13286 * minimum / maximum z value when D3DRS_CLIPPING is disabled, and clipped
13287 * when D3DRS_CLIPPING is enabled. Pretransformed vertices behave the
13288 * same as regular vertices here.
13289 * - With hardware vertex processing, D3DRS_CLIPPING seems to be ignored.
13290 * Normal vertices are always clipped. Pretransformed vertices are
13291 * clipped when D3DPMISCCAPS_CLIPTLVERTS is set, clamped when it isn't.
13292 * - The viewport's MinZ/MaxZ is irrelevant for this.
13294 static void depth_clamp_test(void)
13296 IDirect3DDevice9 *device;
13297 D3DVIEWPORT9 vp;
13298 IDirect3D9 *d3d;
13299 D3DCOLOR color;
13300 ULONG refcount;
13301 D3DCAPS9 caps;
13302 HWND window;
13303 HRESULT hr;
13305 static const struct
13307 struct vec4 position;
13308 DWORD diffuse;
13310 quad1[] =
13312 {{ 0.0f, 0.0f, 5.0f, 1.0f}, 0xff002b7f},
13313 {{640.0f, 0.0f, 5.0f, 1.0f}, 0xff002b7f},
13314 {{ 0.0f, 480.0f, 5.0f, 1.0f}, 0xff002b7f},
13315 {{640.0f, 480.0f, 5.0f, 1.0f}, 0xff002b7f},
13317 quad2[] =
13319 {{ 0.0f, 300.0f, 10.0f, 1.0f}, 0xfff9e814},
13320 {{640.0f, 300.0f, 10.0f, 1.0f}, 0xfff9e814},
13321 {{ 0.0f, 360.0f, 10.0f, 1.0f}, 0xfff9e814},
13322 {{640.0f, 360.0f, 10.0f, 1.0f}, 0xfff9e814},
13324 quad3[] =
13326 {{112.0f, 108.0f, 5.0f, 1.0f}, 0xffffffff},
13327 {{208.0f, 108.0f, 5.0f, 1.0f}, 0xffffffff},
13328 {{112.0f, 204.0f, 5.0f, 1.0f}, 0xffffffff},
13329 {{208.0f, 204.0f, 5.0f, 1.0f}, 0xffffffff},
13331 quad4[] =
13333 {{ 42.0f, 41.0f, 10.0f, 1.0f}, 0xffffffff},
13334 {{112.0f, 41.0f, 10.0f, 1.0f}, 0xffffffff},
13335 {{ 42.0f, 108.0f, 10.0f, 1.0f}, 0xffffffff},
13336 {{112.0f, 108.0f, 10.0f, 1.0f}, 0xffffffff},
13338 static const struct
13340 struct vec3 position;
13341 DWORD diffuse;
13343 quad5[] =
13345 {{-0.5f, 0.5f, 10.0f}, 0xff14f914},
13346 {{ 0.5f, 0.5f, 10.0f}, 0xff14f914},
13347 {{-0.5f, -0.5f, 10.0f}, 0xff14f914},
13348 {{ 0.5f, -0.5f, 10.0f}, 0xff14f914},
13350 quad6[] =
13352 {{-1.0f, 0.5f, 10.0f}, 0xfff91414},
13353 {{ 1.0f, 0.5f, 10.0f}, 0xfff91414},
13354 {{-1.0f, 0.25f, 10.0f}, 0xfff91414},
13355 {{ 1.0f, 0.25f, 10.0f}, 0xfff91414},
13358 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
13359 0, 0, 640, 480, NULL, NULL, NULL, NULL);
13360 d3d = Direct3DCreate9(D3D_SDK_VERSION);
13361 ok(!!d3d, "Failed to create a D3D object.\n");
13362 if (!(device = create_device(d3d, window, window, TRUE)))
13364 skip("Failed to create a D3D device, skipping tests.\n");
13365 goto done;
13368 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
13369 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
13371 vp.X = 0;
13372 vp.Y = 0;
13373 vp.Width = 640;
13374 vp.Height = 480;
13375 vp.MinZ = 0.0;
13376 vp.MaxZ = 7.5;
13378 hr = IDirect3DDevice9_SetViewport(device, &vp);
13379 if(FAILED(hr))
13381 /* Windows 7 rejects MaxZ > 1.0, Windows XP allows it. This doesn't break
13382 * the tests because the 7.5 is just intended to show that it doesn't have
13383 * any influence on the drawing or D3DRS_CLIPPING = FALSE. Set an accepted
13384 * viewport and continue.
13386 ok(broken(hr == D3DERR_INVALIDCALL), "D3D rejected maxZ > 1.0\n");
13387 vp.MaxZ = 1.0;
13388 hr = IDirect3DDevice9_SetViewport(device, &vp);
13390 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
13392 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0, 0);
13393 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
13395 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
13396 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13397 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
13398 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13399 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13400 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13401 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
13402 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13404 hr = IDirect3DDevice9_BeginScene(device);
13405 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13407 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
13408 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
13410 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
13411 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13412 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
13413 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13415 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
13416 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13418 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
13419 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13420 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad4, sizeof(*quad4));
13421 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13423 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
13424 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13426 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
13427 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
13429 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad5, sizeof(*quad5));
13430 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13432 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
13433 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13435 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad6, sizeof(*quad6));
13436 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13438 hr = IDirect3DDevice9_EndScene(device);
13439 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13441 if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_CLIPTLVERTS)
13443 color = getPixelColor(device, 75, 75);
13444 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
13445 color = getPixelColor(device, 150, 150);
13446 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
13447 color = getPixelColor(device, 320, 240);
13448 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
13449 color = getPixelColor(device, 320, 330);
13450 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
13451 color = getPixelColor(device, 320, 330);
13452 ok(color_match(color, 0x0000ff00, 1), "color 0x%08x.\n", color);
13454 else
13456 color = getPixelColor(device, 75, 75);
13457 ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
13458 color = getPixelColor(device, 150, 150);
13459 ok(color_match(color, 0x00ffffff, 1), "color 0x%08x.\n", color);
13460 color = getPixelColor(device, 320, 240);
13461 ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);
13462 color = getPixelColor(device, 320, 330);
13463 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
13464 color = getPixelColor(device, 320, 330);
13465 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
13468 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13469 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
13471 refcount = IDirect3DDevice9_Release(device);
13472 ok(!refcount, "Device has %u references left.\n", refcount);
13473 done:
13474 IDirect3D9_Release(d3d);
13475 DestroyWindow(window);
13478 static void depth_bounds_test(void)
13480 static const struct
13482 struct vec4 position;
13483 DWORD diffuse;
13485 quad1[] =
13487 {{ 0.0f, 0.0f, 0.0f, 1.0f}, 0xfff9e814},
13488 {{640.0f, 0.0f, 0.0f, 1.0f}, 0xfff9e814},
13489 {{ 0.0f, 480.0f, 1.0f, 1.0f}, 0xfff9e814},
13490 {{640.0f, 480.0f, 1.0f, 1.0f}, 0xfff9e814},
13492 quad2[] =
13494 {{ 0.0f, 0.0f, 0.6f, 1.0f}, 0xff002b7f},
13495 {{640.0f, 0.0f, 0.6f, 1.0f}, 0xff002b7f},
13496 {{ 0.0f, 480.0f, 0.6f, 1.0f}, 0xff002b7f},
13497 {{640.0f, 480.0f, 0.6f, 1.0f}, 0xff002b7f},
13499 quad3[] =
13501 {{ 0.0f, 100.0f, 0.6f, 1.0f}, 0xfff91414},
13502 {{640.0f, 100.0f, 0.6f, 1.0f}, 0xfff91414},
13503 {{ 0.0f, 160.0f, 0.6f, 1.0f}, 0xfff91414},
13504 {{640.0f, 160.0f, 0.6f, 1.0f}, 0xfff91414},
13507 union {
13508 DWORD d;
13509 float f;
13510 } tmpvalue;
13512 IDirect3DSurface9 *offscreen_surface = NULL;
13513 IDirect3DDevice9 *device;
13514 IDirect3D9 *d3d;
13515 D3DCOLOR color;
13516 ULONG refcount;
13517 HWND window;
13518 HRESULT hr;
13520 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
13521 0, 0, 640, 480, NULL, NULL, NULL, NULL);
13522 d3d = Direct3DCreate9(D3D_SDK_VERSION);
13523 ok(!!d3d, "Failed to create a D3D object.\n");
13524 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL,
13525 D3DFMT_X8R8G8B8, 0, D3DRTYPE_SURFACE, MAKEFOURCC('N','V','D','B')) != D3D_OK)
13527 skip("No NVDB (depth bounds test) support, skipping tests.\n");
13528 goto done;
13530 if (!(device = create_device(d3d, window, window, TRUE)))
13532 skip("Failed to create a D3D device, skipping tests.\n");
13533 goto done;
13536 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 32, 32,
13537 MAKEFOURCC('N','V','D','B'), D3DPOOL_DEFAULT, &offscreen_surface, NULL);
13538 ok(FAILED(hr), "Able to create surface, hr %#x.\n", hr);
13539 if (offscreen_surface) IDirect3DSurface9_Release(offscreen_surface);
13541 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0, 0);
13542 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
13544 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
13545 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13546 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
13547 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13548 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13549 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13550 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
13551 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13554 hr = IDirect3DDevice9_BeginScene(device);
13555 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13557 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
13558 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
13560 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
13561 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13563 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_X, MAKEFOURCC('N','V','D','B'));
13564 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13566 tmpvalue.f = 0.625;
13567 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_Z, tmpvalue.d);
13568 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13570 tmpvalue.f = 0.75;
13571 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_W, tmpvalue.d);
13572 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13574 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
13575 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13577 tmpvalue.f = 0.75;
13578 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_Z, tmpvalue.d);
13579 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13581 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
13582 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13584 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ADAPTIVETESS_X, 0);
13585 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13587 hr = IDirect3DDevice9_EndScene(device);
13588 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13590 color = getPixelColor(device, 150, 130);
13591 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
13592 color = getPixelColor(device, 150, 200);
13593 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
13594 color = getPixelColor(device, 150, 300-5);
13595 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
13596 color = getPixelColor(device, 150, 300+5);
13597 ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);/**/
13598 color = getPixelColor(device, 150, 330);
13599 ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);
13600 color = getPixelColor(device, 150, 360-5);
13601 ok(color_match(color, 0x00002b7f, 1), "color 0x%08x.\n", color);/**/
13602 color = getPixelColor(device, 150, 360+5);
13603 ok(color_match(color, 0x00f9e814, 1), "color 0x%08x.\n", color);
13605 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13606 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
13607 refcount = IDirect3DDevice9_Release(device);
13608 ok(!refcount, "Device has %u references left.\n", refcount);
13609 done:
13610 IDirect3D9_Release(d3d);
13611 DestroyWindow(window);
13614 static void depth_buffer_test(void)
13616 static const struct
13618 struct vec3 position;
13619 DWORD diffuse;
13621 quad1[] =
13623 {{-1.0, 1.0, 0.33f}, 0xff00ff00},
13624 {{ 1.0, 1.0, 0.33f}, 0xff00ff00},
13625 {{-1.0, -1.0, 0.33f}, 0xff00ff00},
13626 {{ 1.0, -1.0, 0.33f}, 0xff00ff00},
13628 quad2[] =
13630 {{-1.0, 1.0, 0.50f}, 0xffff00ff},
13631 {{ 1.0, 1.0, 0.50f}, 0xffff00ff},
13632 {{-1.0, -1.0, 0.50f}, 0xffff00ff},
13633 {{ 1.0, -1.0, 0.50f}, 0xffff00ff},
13635 quad3[] =
13637 {{-1.0, 1.0, 0.66f}, 0xffff0000},
13638 {{ 1.0, 1.0, 0.66f}, 0xffff0000},
13639 {{-1.0, -1.0, 0.66f}, 0xffff0000},
13640 {{ 1.0, -1.0, 0.66f}, 0xffff0000},
13642 static const DWORD expected_colors[4][4] =
13644 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
13645 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
13646 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x00ff0000},
13647 {0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
13650 IDirect3DSurface9 *backbuffer, *rt1, *rt2, *rt3;
13651 IDirect3DDevice9 *device;
13652 unsigned int i, j;
13653 D3DVIEWPORT9 vp;
13654 IDirect3D9 *d3d;
13655 D3DCOLOR color;
13656 ULONG refcount;
13657 HWND window;
13658 HRESULT hr;
13660 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
13661 0, 0, 640, 480, NULL, NULL, NULL, NULL);
13662 d3d = Direct3DCreate9(D3D_SDK_VERSION);
13663 ok(!!d3d, "Failed to create a D3D object.\n");
13664 if (!(device = create_device(d3d, window, window, TRUE)))
13666 skip("Failed to create a D3D device, skipping tests.\n");
13667 goto done;
13670 vp.X = 0;
13671 vp.Y = 0;
13672 vp.Width = 640;
13673 vp.Height = 480;
13674 vp.MinZ = 0.0;
13675 vp.MaxZ = 1.0;
13677 hr = IDirect3DDevice9_SetViewport(device, &vp);
13678 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
13680 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
13681 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13682 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
13683 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13684 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13685 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13686 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
13687 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13688 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
13689 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
13691 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
13692 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
13693 hr = IDirect3DDevice9_CreateRenderTarget(device, 320, 240, D3DFMT_A8R8G8B8,
13694 D3DMULTISAMPLE_NONE, 0, FALSE, &rt1, NULL);
13695 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
13696 hr = IDirect3DDevice9_CreateRenderTarget(device, 480, 360, D3DFMT_A8R8G8B8,
13697 D3DMULTISAMPLE_NONE, 0, FALSE, &rt2, NULL);
13698 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
13699 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
13700 D3DMULTISAMPLE_NONE, 0, FALSE, &rt3, NULL);
13701 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
13703 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt3);
13704 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
13705 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 0.0f, 0);
13706 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
13708 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
13709 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
13710 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
13711 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
13713 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt1);
13714 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
13715 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0f, 0);
13716 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
13718 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt2);
13719 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
13720 hr = IDirect3DDevice9_BeginScene(device);
13721 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13722 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
13723 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13724 hr = IDirect3DDevice9_EndScene(device);
13725 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13727 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
13728 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
13730 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
13731 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13733 hr = IDirect3DDevice9_BeginScene(device);
13734 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13735 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
13736 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13737 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad3, sizeof(*quad3));
13738 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13739 hr = IDirect3DDevice9_EndScene(device);
13740 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13742 for (i = 0; i < 4; ++i)
13744 for (j = 0; j < 4; ++j)
13746 unsigned int x = 80 * ((2 * j) + 1);
13747 unsigned int y = 60 * ((2 * i) + 1);
13748 color = getPixelColor(device, x, y);
13749 ok(color_match(color, expected_colors[i][j], 0),
13750 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors[i][j], x, y, color);
13754 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13755 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
13757 IDirect3DSurface9_Release(backbuffer);
13758 IDirect3DSurface9_Release(rt3);
13759 IDirect3DSurface9_Release(rt2);
13760 IDirect3DSurface9_Release(rt1);
13761 refcount = IDirect3DDevice9_Release(device);
13762 ok(!refcount, "Device has %u references left.\n", refcount);
13763 done:
13764 IDirect3D9_Release(d3d);
13765 DestroyWindow(window);
13768 /* Test that partial depth copies work the way they're supposed to. The clear
13769 * on rt2 only needs a partial copy of the onscreen depth/stencil buffer, and
13770 * the following draw should only copy back the part that was modified. */
13771 static void depth_buffer2_test(void)
13773 static const struct
13775 struct vec3 position;
13776 DWORD diffuse;
13778 quad[] =
13780 {{-1.0f, 1.0f, 0.66f}, 0xffff0000},
13781 {{ 1.0f, 1.0f, 0.66f}, 0xffff0000},
13782 {{-1.0f, -1.0f, 0.66f}, 0xffff0000},
13783 {{ 1.0f, -1.0f, 0.66f}, 0xffff0000},
13786 IDirect3DSurface9 *backbuffer, *rt1, *rt2;
13787 IDirect3DDevice9 *device;
13788 unsigned int i, j;
13789 D3DVIEWPORT9 vp;
13790 IDirect3D9 *d3d;
13791 D3DCOLOR color;
13792 ULONG refcount;
13793 HWND window;
13794 HRESULT hr;
13796 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
13797 0, 0, 640, 480, NULL, NULL, NULL, NULL);
13798 d3d = Direct3DCreate9(D3D_SDK_VERSION);
13799 ok(!!d3d, "Failed to create a D3D object.\n");
13800 if (!(device = create_device(d3d, window, window, TRUE)))
13802 skip("Failed to create a D3D device, skipping tests.\n");
13803 goto done;
13806 vp.X = 0;
13807 vp.Y = 0;
13808 vp.Width = 640;
13809 vp.Height = 480;
13810 vp.MinZ = 0.0;
13811 vp.MaxZ = 1.0;
13813 hr = IDirect3DDevice9_SetViewport(device, &vp);
13814 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
13816 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
13817 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13818 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
13819 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13820 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
13821 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13822 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
13823 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13824 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
13825 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
13827 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
13828 D3DMULTISAMPLE_NONE, 0, FALSE, &rt1, NULL);
13829 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
13830 hr = IDirect3DDevice9_CreateRenderTarget(device, 480, 360, D3DFMT_A8R8G8B8,
13831 D3DMULTISAMPLE_NONE, 0, FALSE, &rt2, NULL);
13832 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
13833 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
13834 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
13836 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt1);
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, backbuffer);
13842 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
13843 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 0.5f, 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_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 0.0f, 0);
13849 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
13851 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
13852 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
13854 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
13855 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13857 hr = IDirect3DDevice9_BeginScene(device);
13858 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
13859 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
13860 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
13861 hr = IDirect3DDevice9_EndScene(device);
13862 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
13864 for (i = 0; i < 4; ++i)
13866 for (j = 0; j < 4; ++j)
13868 unsigned int x = 80 * ((2 * j) + 1);
13869 unsigned int y = 60 * ((2 * i) + 1);
13870 color = getPixelColor(device, x, y);
13871 ok(color_match(color, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00), 0),
13872 "Expected color 0x0000ff00 at %u,%u, got 0x%08x.\n", x, y, color);
13876 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
13877 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
13879 IDirect3DSurface9_Release(backbuffer);
13880 IDirect3DSurface9_Release(rt2);
13881 IDirect3DSurface9_Release(rt1);
13882 refcount = IDirect3DDevice9_Release(device);
13883 ok(!refcount, "Device has %u references left.\n", refcount);
13884 done:
13885 IDirect3D9_Release(d3d);
13886 DestroyWindow(window);
13889 static void depth_blit_test(void)
13891 static const struct
13893 struct vec3 position;
13894 DWORD diffuse;
13896 quad1[] =
13898 {{-1.0f, 1.0f, 0.33f}, 0xff00ff00},
13899 {{ 1.0f, 1.0f, 0.33f}, 0xff00ff00},
13900 {{-1.0f, -1.0f, 0.33f}, 0xff00ff00},
13901 {{ 1.0f, -1.0f, 0.33f}, 0xff00ff00},
13903 quad2[] =
13905 {{-1.0f, 1.0f, 0.66f}, 0xff0000ff},
13906 {{ 1.0f, 1.0f, 0.66f}, 0xff0000ff},
13907 {{-1.0f, -1.0f, 0.66f}, 0xff0000ff},
13908 {{ 1.0f, -1.0f, 0.66f}, 0xff0000ff},
13910 static const DWORD expected_colors[4][4] =
13912 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
13913 {0x000000ff, 0x000000ff, 0x0000ff00, 0x00ff0000},
13914 {0x0000ff00, 0x0000ff00, 0x0000ff00, 0x00ff0000},
13915 {0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
13918 IDirect3DSurface9 *backbuffer, *ds1, *ds2, *ds3;
13919 IDirect3DDevice9 *device;
13920 RECT src_rect, dst_rect;
13921 unsigned int i, j;
13922 D3DVIEWPORT9 vp;
13923 IDirect3D9 *d3d;
13924 D3DCOLOR color;
13925 ULONG refcount;
13926 HWND window;
13927 HRESULT hr;
13929 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
13930 0, 0, 640, 480, NULL, NULL, NULL, NULL);
13931 d3d = Direct3DCreate9(D3D_SDK_VERSION);
13932 ok(!!d3d, "Failed to create a D3D object.\n");
13933 if (!(device = create_device(d3d, window, window, TRUE)))
13935 skip("Failed to create a D3D device, skipping tests.\n");
13936 goto done;
13939 vp.X = 0;
13940 vp.Y = 0;
13941 vp.Width = 640;
13942 vp.Height = 480;
13943 vp.MinZ = 0.0;
13944 vp.MaxZ = 1.0;
13946 hr = IDirect3DDevice9_SetViewport(device, &vp);
13947 ok(SUCCEEDED(hr), "SetViewport failed, hr %#x.\n", hr);
13949 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
13950 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
13951 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds1);
13952 ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
13953 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8, 0, 0, FALSE, &ds2, NULL);
13954 ok(SUCCEEDED(hr), "CreateDepthStencilSurface failed, hr %#x.\n", hr);
13955 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds2);
13956 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
13957 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 320, 240, D3DFMT_D24S8, 0, 0, FALSE, &ds3, NULL);
13958 ok(SUCCEEDED(hr), "CreateDepthStencilSurface failed, hr %#x.\n", hr);
13960 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
13961 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13962 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
13963 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13964 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
13965 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
13966 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
13967 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
13969 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
13970 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
13971 SetRect(&dst_rect, 0, 0, 480, 360);
13972 hr = IDirect3DDevice9_Clear(device, 1, (D3DRECT *)&dst_rect, D3DCLEAR_ZBUFFER, 0, 0.5f, 0);
13973 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
13974 SetRect(&dst_rect, 0, 0, 320, 240);
13975 hr = IDirect3DDevice9_Clear(device, 1, (D3DRECT *)&dst_rect, D3DCLEAR_ZBUFFER, 0, 1.0f, 0);
13976 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
13978 /* Partial blit. */
13979 SetRect(&src_rect, 0, 0, 320, 240);
13980 SetRect(&dst_rect, 0, 0, 320, 240);
13981 hr = IDirect3DDevice9_StretchRect(device, ds2, &src_rect, ds1, &dst_rect, D3DTEXF_POINT);
13982 ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
13983 /* Flipped. */
13984 SetRect(&src_rect, 0, 0, 640, 480);
13985 SetRect(&dst_rect, 0, 480, 640, 0);
13986 hr = IDirect3DDevice9_StretchRect(device, ds2, &src_rect, ds1, &dst_rect, D3DTEXF_POINT);
13987 ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
13988 /* Full, explicit. */
13989 SetRect(&src_rect, 0, 0, 640, 480);
13990 SetRect(&dst_rect, 0, 0, 640, 480);
13991 hr = IDirect3DDevice9_StretchRect(device, ds2, &src_rect, ds1, &dst_rect, D3DTEXF_POINT);
13992 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
13993 /* Filtered blit. */
13994 hr = IDirect3DDevice9_StretchRect(device, ds2, NULL, ds1, NULL, D3DTEXF_LINEAR);
13995 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
13996 /* Depth -> color blit.*/
13997 hr = IDirect3DDevice9_StretchRect(device, ds2, NULL, backbuffer, NULL, D3DTEXF_POINT);
13998 ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
13999 IDirect3DSurface9_Release(backbuffer);
14000 /* Full surface, different sizes */
14001 hr = IDirect3DDevice9_StretchRect(device, ds3, NULL, ds1, NULL, D3DTEXF_POINT);
14002 ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
14003 hr = IDirect3DDevice9_StretchRect(device, ds1, NULL, ds3, NULL, D3DTEXF_POINT);
14004 ok(hr == D3DERR_INVALIDCALL, "StretchRect returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
14006 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds1);
14007 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
14008 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER | D3DCLEAR_TARGET, 0xffff0000, 1.0f, 0);
14009 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
14010 hr = IDirect3DDevice9_StretchRect(device, ds2, NULL, ds1, NULL, D3DTEXF_POINT);
14011 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
14013 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
14014 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14015 hr = IDirect3DDevice9_BeginScene(device);
14016 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14017 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
14018 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14019 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
14020 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14021 hr = IDirect3DDevice9_EndScene(device);
14022 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14024 for (i = 0; i < 4; ++i)
14026 for (j = 0; j < 4; ++j)
14028 unsigned int x = 80 * ((2 * j) + 1);
14029 unsigned int y = 60 * ((2 * i) + 1);
14030 color = getPixelColor(device, x, y);
14031 ok(color_match(color, expected_colors[i][j], 0),
14032 "Expected color 0x%08x at %u,%u, got 0x%08x.\n", expected_colors[i][j], x, y, color);
14036 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14037 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
14039 IDirect3DSurface9_Release(ds3);
14040 IDirect3DSurface9_Release(ds2);
14041 IDirect3DSurface9_Release(ds1);
14042 refcount = IDirect3DDevice9_Release(device);
14043 ok(!refcount, "Device has %u references left.\n", refcount);
14044 done:
14045 IDirect3D9_Release(d3d);
14046 DestroyWindow(window);
14049 static void intz_test(void)
14051 static const DWORD ps_code[] =
14053 0xffff0200, /* ps_2_0 */
14054 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
14055 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
14056 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0.0, 0.0, 0.0, 1.0 */
14057 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */
14058 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
14059 0x03010042, 0x800f0001, 0xb0e40000, 0xa0e40800, /* texldp r1, t0, s0 */
14060 0x02000001, 0x80020000, 0x80000001, /* mov r0.y, r1.x */
14061 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
14062 0x0000ffff, /* end */
14064 struct
14066 float x, y, z;
14067 float s, t, p, q;
14069 quad[] =
14071 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f},
14072 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
14073 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
14074 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f},
14076 half_quad_1[] =
14078 { -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f},
14079 { 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
14080 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
14081 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f},
14083 half_quad_2[] =
14085 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f},
14086 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
14087 { -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
14088 { 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f},
14090 struct
14092 UINT x, y;
14093 D3DCOLOR color;
14095 expected_colors[] =
14097 { 80, 100, 0x20204020},
14098 {240, 100, 0x6060bf60},
14099 {400, 100, 0x9f9f409f},
14100 {560, 100, 0xdfdfbfdf},
14101 { 80, 450, 0x20204020},
14102 {240, 450, 0x6060bf60},
14103 {400, 450, 0x9f9f409f},
14104 {560, 450, 0xdfdfbfdf},
14107 IDirect3DSurface9 *original_rt, *rt;
14108 struct surface_readback rb;
14109 IDirect3DTexture9 *texture;
14110 IDirect3DPixelShader9 *ps;
14111 IDirect3DDevice9 *device;
14112 IDirect3DSurface9 *ds;
14113 IDirect3D9 *d3d;
14114 ULONG refcount;
14115 D3DCAPS9 caps;
14116 HWND window;
14117 HRESULT hr;
14118 UINT i;
14120 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
14121 0, 0, 640, 480, NULL, NULL, NULL, NULL);
14122 d3d = Direct3DCreate9(D3D_SDK_VERSION);
14123 ok(!!d3d, "Failed to create a D3D object.\n");
14124 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
14125 D3DFMT_X8R8G8B8, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, MAKEFOURCC('I','N','T','Z'))))
14127 skip("No INTZ support, skipping INTZ test.\n");
14128 goto done;
14130 if (!(device = create_device(d3d, window, window, TRUE)))
14132 skip("Failed to create a D3D device, skipping tests.\n");
14133 goto done;
14136 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
14137 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
14138 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
14140 skip("No pixel shader 2.0 support, skipping INTZ test.\n");
14141 IDirect3DDevice9_Release(device);
14142 goto done;
14144 if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
14146 skip("No unconditional NP2 texture support, skipping INTZ test.\n");
14147 IDirect3DDevice9_Release(device);
14148 goto done;
14151 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
14152 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
14154 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
14155 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
14156 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
14157 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
14158 D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
14159 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
14160 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
14161 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
14163 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
14164 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
14165 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
14166 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14167 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
14168 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14169 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
14170 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14171 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
14172 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14174 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
14175 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
14176 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
14177 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
14178 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
14179 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
14180 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
14181 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
14182 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
14183 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
14185 /* Render offscreen, using the INTZ texture as depth buffer */
14186 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
14187 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
14188 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
14189 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
14190 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
14191 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
14192 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
14193 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
14195 /* Setup the depth/stencil surface. */
14196 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
14197 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
14199 hr = IDirect3DDevice9_BeginScene(device);
14200 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14201 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
14202 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14203 hr = IDirect3DDevice9_EndScene(device);
14204 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14206 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
14207 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
14208 IDirect3DSurface9_Release(ds);
14209 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
14210 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
14211 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
14212 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
14213 hr = IDirect3DDevice9_SetPixelShader(device, ps);
14214 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
14216 /* Read the depth values back. */
14217 hr = IDirect3DDevice9_BeginScene(device);
14218 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14219 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
14220 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14221 hr = IDirect3DDevice9_EndScene(device);
14222 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14224 get_rt_readback(original_rt, &rb);
14225 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
14227 D3DCOLOR color = get_readback_color(&rb, expected_colors[i].x, expected_colors[i].y);
14228 ok(color_match(color, expected_colors[i].color, 1),
14229 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
14230 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
14232 release_surface_readback(&rb);
14234 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14235 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
14237 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
14238 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
14239 IDirect3DTexture9_Release(texture);
14241 /* Render onscreen while using the INTZ texture as depth buffer */
14242 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
14243 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
14244 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
14245 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
14246 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
14247 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
14248 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
14249 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
14251 /* Setup the depth/stencil surface. */
14252 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
14253 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
14255 hr = IDirect3DDevice9_BeginScene(device);
14256 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14257 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
14258 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14259 hr = IDirect3DDevice9_EndScene(device);
14260 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14262 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
14263 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
14264 IDirect3DSurface9_Release(ds);
14265 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
14266 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
14267 hr = IDirect3DDevice9_SetPixelShader(device, ps);
14268 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
14270 /* Read the depth values back. */
14271 hr = IDirect3DDevice9_BeginScene(device);
14272 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14273 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
14274 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14275 hr = IDirect3DDevice9_EndScene(device);
14276 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14278 get_rt_readback(original_rt, &rb);
14279 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
14281 D3DCOLOR color = get_readback_color(&rb, expected_colors[i].x, expected_colors[i].y);
14282 ok(color_match(color, expected_colors[i].color, 1),
14283 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
14284 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
14286 release_surface_readback(&rb);
14288 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14289 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
14291 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
14292 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
14293 IDirect3DTexture9_Release(texture);
14295 /* Render offscreen, then onscreen, and finally check the INTZ texture in both areas */
14296 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
14297 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
14298 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
14299 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
14301 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
14302 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
14303 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
14304 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
14305 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
14306 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
14308 /* Setup the depth/stencil surface. */
14309 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
14310 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
14312 hr = IDirect3DDevice9_BeginScene(device);
14313 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14314 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, half_quad_1, sizeof(*half_quad_1));
14315 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14316 hr = IDirect3DDevice9_EndScene(device);
14317 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14319 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
14320 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
14322 hr = IDirect3DDevice9_BeginScene(device);
14323 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14324 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, half_quad_2, sizeof(*half_quad_2));
14325 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14326 hr = IDirect3DDevice9_EndScene(device);
14327 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14329 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
14330 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
14331 IDirect3DSurface9_Release(ds);
14332 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
14333 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
14334 hr = IDirect3DDevice9_SetPixelShader(device, ps);
14335 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
14337 /* Read the depth values back. */
14338 hr = IDirect3DDevice9_BeginScene(device);
14339 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14340 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
14341 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14342 hr = IDirect3DDevice9_EndScene(device);
14343 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14345 get_rt_readback(original_rt, &rb);
14346 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
14348 D3DCOLOR color = get_readback_color(&rb, expected_colors[i].x, expected_colors[i].y);
14349 ok(color_match(color, expected_colors[i].color, 1),
14350 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
14351 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
14353 release_surface_readback(&rb);
14355 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14356 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
14358 IDirect3DTexture9_Release(texture);
14359 IDirect3DPixelShader9_Release(ps);
14360 IDirect3DSurface9_Release(original_rt);
14361 IDirect3DSurface9_Release(rt);
14362 refcount = IDirect3DDevice9_Release(device);
14363 ok(!refcount, "Device has %u references left.\n", refcount);
14364 done:
14365 IDirect3D9_Release(d3d);
14366 DestroyWindow(window);
14369 static void shadow_test(void)
14371 static const DWORD ps_code[] =
14373 0xffff0200, /* ps_2_0 */
14374 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
14375 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
14376 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0.0, 0.0, 0.0, 1.0 */
14377 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */
14378 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
14379 0x03010042, 0x800f0001, 0xb0e40000, 0xa0e40800, /* texldp r1, t0, s0 */
14380 0x02000001, 0x80020000, 0x80000001, /* mov r0.y, r1.x */
14381 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
14382 0x0000ffff, /* end */
14384 struct
14386 D3DFORMAT format;
14387 const char *name;
14389 formats[] =
14391 {D3DFMT_D16_LOCKABLE, "D3DFMT_D16_LOCKABLE"},
14392 {D3DFMT_D32, "D3DFMT_D32"},
14393 {D3DFMT_D15S1, "D3DFMT_D15S1"},
14394 {D3DFMT_D24S8, "D3DFMT_D24S8"},
14395 {D3DFMT_D24X8, "D3DFMT_D24X8"},
14396 {D3DFMT_D24X4S4, "D3DFMT_D24X4S4"},
14397 {D3DFMT_D16, "D3DFMT_D16"},
14398 {D3DFMT_D32F_LOCKABLE, "D3DFMT_D32F_LOCKABLE"},
14399 {D3DFMT_D24FS8, "D3DFMT_D24FS8"},
14401 struct
14403 float x, y, z;
14404 float s, t, p, q;
14406 quad[] =
14408 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f},
14409 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f},
14410 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
14411 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f},
14413 struct
14415 UINT x, y;
14416 D3DCOLOR color;
14418 expected_colors[] =
14420 {400, 60, 0x00000000},
14421 {560, 180, 0xffff00ff},
14422 {560, 300, 0xffff00ff},
14423 {400, 420, 0xffffffff},
14424 {240, 420, 0xffffffff},
14425 { 80, 300, 0x00000000},
14426 { 80, 180, 0x00000000},
14427 {240, 60, 0x00000000},
14430 IDirect3DSurface9 *original_ds, *original_rt, *rt;
14431 struct surface_readback rb;
14432 IDirect3DPixelShader9 *ps;
14433 IDirect3DDevice9 *device;
14434 IDirect3D9 *d3d;
14435 ULONG refcount;
14436 D3DCAPS9 caps;
14437 HWND window;
14438 HRESULT hr;
14439 UINT i;
14441 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
14442 0, 0, 640, 480, NULL, NULL, NULL, NULL);
14443 d3d = Direct3DCreate9(D3D_SDK_VERSION);
14444 ok(!!d3d, "Failed to create a D3D object.\n");
14445 if (!(device = create_device(d3d, window, window, TRUE)))
14447 skip("Failed to create a D3D device, skipping tests.\n");
14448 goto done;
14451 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
14452 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
14453 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
14455 skip("No pixel shader 2.0 support, skipping shadow test.\n");
14456 IDirect3DDevice9_Release(device);
14457 goto done;
14460 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
14461 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
14462 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
14463 ok(SUCCEEDED(hr), "GetDepthStencilSurface failed, hr %#x.\n", hr);
14465 hr = IDirect3DDevice9_CreateRenderTarget(device, 1024, 1024, D3DFMT_A8R8G8B8,
14466 D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
14467 ok(SUCCEEDED(hr), "CreateRenderTarget failed, hr %#x.\n", hr);
14468 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
14469 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
14471 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
14472 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
14473 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
14474 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14475 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
14476 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14477 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
14478 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14479 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
14480 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14482 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
14483 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
14484 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
14485 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
14486 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
14487 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
14488 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
14489 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
14490 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
14491 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
14493 for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
14495 D3DFORMAT format = formats[i].format;
14496 IDirect3DTexture9 *texture;
14497 IDirect3DSurface9 *ds;
14498 unsigned int j;
14500 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
14501 D3DFMT_X8R8G8B8, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, format)))
14502 continue;
14504 hr = IDirect3DDevice9_CreateTexture(device, 1024, 1024, 1,
14505 D3DUSAGE_DEPTHSTENCIL, format, D3DPOOL_DEFAULT, &texture, NULL);
14506 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
14508 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &ds);
14509 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
14511 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
14512 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
14514 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
14515 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
14517 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
14518 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
14520 /* Setup the depth/stencil surface. */
14521 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 0.0f, 0);
14522 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
14524 hr = IDirect3DDevice9_BeginScene(device);
14525 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14526 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
14527 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14528 hr = IDirect3DDevice9_EndScene(device);
14529 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14531 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
14532 ok(SUCCEEDED(hr), "SetDepthStencilSurface failed, hr %#x.\n", hr);
14533 IDirect3DSurface9_Release(ds);
14535 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
14536 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
14538 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
14539 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
14541 hr = IDirect3DDevice9_SetPixelShader(device, ps);
14542 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
14544 /* Do the actual shadow mapping. */
14545 hr = IDirect3DDevice9_BeginScene(device);
14546 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14547 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
14548 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14549 hr = IDirect3DDevice9_EndScene(device);
14550 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14552 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
14553 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
14554 IDirect3DTexture9_Release(texture);
14556 get_rt_readback(original_rt, &rb);
14557 for (j = 0; j < sizeof(expected_colors) / sizeof(*expected_colors); ++j)
14559 D3DCOLOR color = get_readback_color(&rb, expected_colors[j].x, expected_colors[j].y);
14560 ok(color_match(color, expected_colors[j].color, 0),
14561 "Expected color 0x%08x at (%u, %u) for format %s, got 0x%08x.\n",
14562 expected_colors[j].color, expected_colors[j].x, expected_colors[j].y,
14563 formats[i].name, color);
14565 release_surface_readback(&rb);
14567 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14568 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
14571 IDirect3DPixelShader9_Release(ps);
14572 IDirect3DSurface9_Release(original_ds);
14573 IDirect3DSurface9_Release(original_rt);
14574 IDirect3DSurface9_Release(rt);
14575 refcount = IDirect3DDevice9_Release(device);
14576 ok(!refcount, "Device has %u references left.\n", refcount);
14577 done:
14578 IDirect3D9_Release(d3d);
14579 DestroyWindow(window);
14582 static void clip_planes(IDirect3DDevice9 *device, const char *test_name)
14584 static const struct
14586 struct vec3 position;
14587 DWORD diffuse;
14589 quad1[] =
14591 {{-1.0f, -1.0f, 0.0f}, 0xfff9e814},
14592 {{-1.0f, 1.0f, 0.0f}, 0xfff9e814},
14593 {{ 1.0f, -1.0f, 0.0f}, 0xfff9e814},
14594 {{ 1.0f, 1.0f, 0.0f}, 0xfff9e814},
14596 quad2[] =
14598 {{-1.0f, -1.0f, 0.0f}, 0xff002b7f},
14599 {{-1.0f, 1.0f, 0.0f}, 0xff002b7f},
14600 {{ 1.0f, -1.0f, 0.0f}, 0xff002b7f},
14601 {{ 1.0f, 1.0f, 0.0f}, 0xff002b7f},
14603 D3DCOLOR color;
14604 HRESULT hr;
14606 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 1.0, 0);
14607 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
14609 hr = IDirect3DDevice9_BeginScene(device);
14610 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14612 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
14613 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
14615 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPLANEENABLE, 0);
14616 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14617 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad1, sizeof(*quad1));
14618 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14620 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPLANEENABLE, 0x1);
14621 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14622 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad2, sizeof(*quad2));
14623 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14625 hr = IDirect3DDevice9_EndScene(device);
14626 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14628 color = getPixelColor(device, 1, 240);
14629 ok(color_match(color, 0x00002b7f, 1), "%s test: color 0x%08x.\n", test_name, color);
14630 color = getPixelColor(device, 638, 240);
14631 ok(color_match(color, 0x00002b7f, 1), "%s test: color 0x%08x.\n", test_name, color);
14633 color = getPixelColor(device, 1, 241);
14634 ok(color_match(color, 0x00f9e814, 1), "%s test: color 0x%08x.\n", test_name, color);
14635 color = getPixelColor(device, 638, 241);
14636 ok(color_match(color, 0x00f9e814, 1), "%s test: color 0x%08x.\n", test_name, color);
14639 static void clip_planes_test(void)
14641 IDirect3DSurface9 *offscreen_surface, *original_rt;
14642 IDirect3DTexture9 *offscreen = NULL;
14643 IDirect3DVertexShader9 *shader;
14644 IDirect3DDevice9 *device;
14645 IDirect3D9 *d3d;
14646 ULONG refcount;
14647 D3DCAPS9 caps;
14648 HWND window;
14649 HRESULT hr;
14651 static const float plane0[4] = {0.0f, 1.0f, 0.0f, 0.5f / 480.0f}; /* a quarter-pixel offset */
14652 static const DWORD shader_code[] =
14654 0xfffe0200, /* vs_2_0 */
14655 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
14656 0x0200001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
14657 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
14658 0x02000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
14659 0x0000ffff /* end */
14662 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
14663 0, 0, 640, 480, NULL, NULL, NULL, NULL);
14664 d3d = Direct3DCreate9(D3D_SDK_VERSION);
14665 ok(!!d3d, "Failed to create a D3D object.\n");
14666 if (!(device = create_device(d3d, window, window, TRUE)))
14668 skip("Failed to create a D3D device, skipping tests.\n");
14669 goto done;
14672 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
14673 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
14674 if (caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
14676 skip("No vs_2_0 support, skipping tests.\n");
14677 IDirect3DDevice9_Release(device);
14678 goto done;
14681 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
14682 ok(SUCCEEDED(hr), "GetRenderTarget failed, hr %#x.\n", hr);
14684 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
14685 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14686 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
14687 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14688 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
14689 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14690 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, TRUE);
14691 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14693 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
14694 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader failed, hr=%08x\n", hr);
14695 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
14696 ok(hr == D3D_OK, "IDirect3DDevice9_SetPixelShader failed, hr=%08x\n", hr);
14698 IDirect3DDevice9_SetClipPlane(device, 0, plane0);
14700 clip_planes(device, "Onscreen FFP");
14702 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &offscreen, NULL);
14703 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
14704 hr = IDirect3DTexture9_GetSurfaceLevel(offscreen, 0, &offscreen_surface);
14705 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
14706 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen_surface);
14707 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
14709 clip_planes(device, "Offscreen FFP");
14711 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14712 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
14714 hr = IDirect3DDevice9_CreateVertexShader(device, shader_code, &shader);
14715 ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexShader returned %08x\n", hr);
14716 hr = IDirect3DDevice9_SetVertexShader(device, shader);
14717 ok(hr == D3D_OK, "IDirect3DDevice9_SetVertexShader returned %08x\n", hr);
14719 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
14720 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
14722 clip_planes(device, "Onscreen vertex shader");
14724 hr = IDirect3DDevice9_SetRenderTarget(device, 0, offscreen_surface);
14725 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderTarget failed, hr=%08x\n", hr);
14727 clip_planes(device, "Offscreen vertex shader");
14729 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14730 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
14732 IDirect3DVertexShader9_Release(shader);
14733 IDirect3DSurface9_Release(original_rt);
14734 IDirect3DSurface9_Release(offscreen_surface);
14735 IDirect3DTexture9_Release(offscreen);
14736 refcount = IDirect3DDevice9_Release(device);
14737 ok(!refcount, "Device has %u references left.\n", refcount);
14738 done:
14739 IDirect3D9_Release(d3d);
14740 DestroyWindow(window);
14743 static void fp_special_test(void)
14745 /* Microsoft's assembler generates nan and inf with "1.#QNAN" and "1.#INF." respectively */
14746 static const DWORD vs_header[] =
14748 0xfffe0200, /* vs_2_0 */
14749 0x05000051, 0xa00f0000, 0x00000000, 0x3f000000, 0x3f800000, 0x40000000, /* def c0, 0.0, 0.5, 1.0, 2.0 */
14750 0x05000051, 0xa00f0001, 0x7fc00000, 0xff800000, 0x7f800000, 0x00000000, /* def c1, nan, -inf, inf, 0 */
14751 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
14752 0x0200001f, 0x80000005, 0x900f0001, /* dcl_texcoord0 v1 */
14755 static const DWORD vs_log[] = {0x0200000f, 0x80010000, 0x90000001}; /* log r0.x, v1.x */
14756 static const DWORD vs_pow[] =
14757 {0x03000020, 0x80010000, 0x90000001, 0x90000001}; /* pow r0.x, v1.x, v1.x */
14758 static const DWORD vs_nrm[] = {0x02000024, 0x80070000, 0x90000001}; /* nrm r0.xyz, v1.x */
14759 static const DWORD vs_rcp1[] = {0x02000006, 0x80010000, 0x90000001}; /* rcp r0.x, v1.x */
14760 static const DWORD vs_rcp2[] = {0x02000006, 0x80010000, 0x91000001}; /* rcp r0.x, -v1.x */
14761 static const DWORD vs_rsq1[] = {0x02000007, 0x80010000, 0x90000001}; /* rsq r0.x, v1.x */
14762 static const DWORD vs_rsq2[] = {0x02000007, 0x80010000, 0x91000001}; /* rsq r0.x, -v1.x */
14763 static const DWORD vs_lit[] = {0x02000010, 0x800f0000, 0x90000001, /* lit r0, v1.xxxx */
14764 0x02000001, 0x80010000, 0x80aa0000}; /* mov r0.x, v0.z */
14765 static const DWORD vs_def1[] = {0x02000001, 0x80010000, 0xa0000001}; /* mov r0.x, c1.x */
14766 static const DWORD vs_def2[] = {0x02000001, 0x80010000, 0xa0550001}; /* mov r0.x, c1.y */
14767 static const DWORD vs_def3[] = {0x02000001, 0x80010000, 0xa0aa0001}; /* mov r0.x, c1.z */
14769 static const DWORD vs_footer[] =
14771 0x03000005, 0x80020000, 0x80000000, 0xa0ff0000, /* mul r0.y, r0.x, c0.w */
14772 0x0300000d, 0x80040000, 0x80000000, 0x80550000, /* sge r0.z, r0.x, r0.y */
14773 0x0300000d, 0x80020000, 0x80e40000, 0x80000000, /* sge r0.y, r0, r0.x */
14774 0x03000005, 0x80040000, 0x80550000, 0x80e40000, /* mul r0.z, r0.y, r0 */
14775 0x0300000b, 0x80080000, 0x81aa0000, 0x80aa0000, /* max r0.w, -r0.z, r0.z */
14776 0x0300000c, 0x80020000, 0x80000000, 0x80000000, /* slt r0.y, r0.x, r0.x */
14777 0x03000002, 0x80040000, 0x80550000, 0x80550000, /* add r0.z, r0.y, r0.y */
14778 0x0300000c, 0x80020000, 0xa0000000, 0x80ff0000, /* slt r0.y, c0.x, r0.w */
14779 0x0300000b, 0x80080000, 0x81aa0000, 0x80aa0000, /* max r0.w, -r0.z, r0.z */
14780 0x03000002, 0x80040000, 0x81550000, 0xa0e40000, /* add r0.z, -r0.y, c0 */
14781 0x0300000c, 0x80080000, 0xa0000000, 0x80e40000, /* slt r0.w, c0.x, r0 */
14782 0x03000005, 0x80040000, 0x80ff0000, 0x80e40000, /* mul r0.z, r0.w, r0 */
14783 0x04000004, 0x80020000, 0x80aa0000, 0xa0e40000, 0x80e40000, /* mad r0.y, r0.z, c0, r0 */
14784 0x02000001, 0xe0030000, 0x80e40000, /* mov oT0.xy, r0 */
14785 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
14786 0x0000ffff, /* end */
14789 static const struct
14791 const char *name;
14792 const DWORD *ops;
14793 DWORD size;
14794 D3DCOLOR r500;
14795 D3DCOLOR r600;
14796 D3DCOLOR nv40;
14797 D3DCOLOR nv50;
14798 D3DCOLOR warp;
14800 vs_body[] =
14802 /* The basic ideas here are:
14803 * 2.0 * +/-INF == +/-INF
14804 * NAN != NAN
14806 * The vertex shader value is written to the red component, with 0.0
14807 * and +/-INF mapping to 0xff, and NAN to 0x7f. Anything else should
14808 * result in 0x00. The pixel shader value is written to the green
14809 * component, but here 0.0 also results in 0x00. The actual value is
14810 * written to the blue component.
14812 * There are considerable differences between graphics cards in how
14813 * these are handled, but pow and nrm never generate INF or NAN on
14814 * real hardware. */
14815 {"log", vs_log, sizeof(vs_log), 0x00000000, 0x00000000, 0x00ff0000, 0x00ff7f00, 0x00ff8000},
14816 {"pow", vs_pow, sizeof(vs_pow), 0x000000ff, 0x000000ff, 0x0000ff00, 0x000000ff, 0x00008000},
14817 {"nrm", vs_nrm, sizeof(vs_nrm), 0x00ff0000, 0x00ff0000, 0x0000ff00, 0x00ff0000, 0x00008000},
14818 {"rcp1", vs_rcp1, sizeof(vs_rcp1), 0x000000ff, 0x000000ff, 0x00ff00ff, 0x00ff7f00, 0x00ff8000},
14819 {"rcp2", vs_rcp2, sizeof(vs_rcp2), 0x000000ff, 0x00000000, 0x00ff0000, 0x00ff7f00, 0x00ff8000},
14820 {"rsq1", vs_rsq1, sizeof(vs_rsq1), 0x000000ff, 0x000000ff, 0x00ff00ff, 0x00ff7f00, 0x00ff8000},
14821 {"rsq2", vs_rsq2, sizeof(vs_rsq2), 0x000000ff, 0x000000ff, 0x00ff00ff, 0x00ff7f00, 0x00ff8000},
14822 {"lit", vs_lit, sizeof(vs_lit), 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000},
14823 {"def1", vs_def1, sizeof(vs_def1), 0x000000ff, 0x00007f00, 0x0000ff00, 0x00007f00, 0x00008000},
14824 {"def2", vs_def2, sizeof(vs_def2), 0x00ff0000, 0x00ff7f00, 0x00ff0000, 0x00ff7f00, 0x00ff8000},
14825 {"def3", vs_def3, sizeof(vs_def3), 0x00ff00ff, 0x00ff7f00, 0x00ff00ff, 0x00ff7f00, 0x00ff8000},
14828 static const DWORD ps_code[] =
14830 0xffff0200, /* ps_2_0 */
14831 0x05000051, 0xa00f0000, 0x00000000, 0x3f000000, 0x3f800000, 0x40000000, /* def c0, 0.0, 0.5, 1.0, 2.0 */
14832 0x0200001f, 0x80000000, 0xb0030000, /* dcl t0.xy */
14833 0x0300000b, 0x80010001, 0xb0e40000, 0xa0e40000, /* max r1.x, t0, c0 */
14834 0x0300000a, 0x80010000, 0xb0e40000, 0xa0e40000, /* min r0.x, t0, c0 */
14835 0x03000002, 0x80010000, 0x80e40000, 0x81e40001, /* add r0.x, r0, -r1 */
14836 0x04000004, 0x80010001, 0xb0e40000, 0xa0ff0000, 0xb1e40000, /* mad r1.x, t0, c0.w. -t0 */
14837 0x02000023, 0x80010002, 0x80e40001, /* abs r2.x, r1 */
14838 0x02000023, 0x80010000, 0x80e40000, /* abs r0.x, r0 */
14839 0x02000023, 0x80010001, 0xb0e40000, /* abs r1.x, t0 */
14840 0x04000058, 0x80010002, 0x81e40002, 0xa0aa0000, 0xa0e40000, /* cmp r2.x, -r2, c0.z, c0 */
14841 0x02000023, 0x80010002, 0x80e40002, /* abs r2.x, r2 */
14842 0x04000058, 0x80010001, 0x81e40001, 0xa0aa0000, 0xa0e40000, /* cmp r1.x, -r1, c0.z, c0 */
14843 0x02000023, 0x80010001, 0x80e40001, /* abs r1.x, r1 */
14844 0x04000058, 0x80010003, 0x81e40002, 0xa0aa0000, 0xa0e40000, /* cmp r3.x, -r2, c0.z, c0 */
14845 0x04000058, 0x80010002, 0x81e40001, 0xa0aa0000, 0xa0e40000, /* cmp r2.x, -r1, c0.z, c0 */
14846 0x04000058, 0x80010000, 0x81e40000, 0xa0550000, 0xa0e40000, /* cmp r0.x, -r0, c0.y, c0 */
14847 0x03000005, 0x80010002, 0x80e40002, 0x80e40003, /* mul r2.x, r2, r3 */
14848 0x04000058, 0x80010000, 0x81e40002, 0xa0aa0000, 0x80e40000, /* cmp r0.x, -r2, c0.z, r0 */
14849 0x04000058, 0x80020000, 0x81000001, 0x80000000, 0xa0000000, /* cmp r0.y, -r1.x, r0.x, c0.x */
14850 0x02000001, 0x80050000, 0xb0c90000, /* mov r0.xz, t0.yzxw */
14851 0x02000001, 0x80080000, 0xa0aa0000, /* mov r0.w, c0.z */
14852 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
14853 0x0000ffff, /* end */
14856 struct
14858 float x, y, z;
14859 float s;
14861 quad[] =
14863 { -1.0f, 1.0f, 0.0f, 0.0f},
14864 { 1.0f, 1.0f, 1.0f, 0.0f},
14865 { -1.0f, -1.0f, 0.0f, 0.0f},
14866 { 1.0f, -1.0f, 1.0f, 0.0f},
14869 IDirect3DPixelShader9 *ps;
14870 IDirect3DDevice9 *device;
14871 UINT body_size = 0;
14872 IDirect3D9 *d3d;
14873 DWORD *vs_code;
14874 ULONG refcount;
14875 D3DCAPS9 caps;
14876 HWND window;
14877 HRESULT hr;
14878 UINT i;
14880 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
14881 0, 0, 640, 480, NULL, NULL, NULL, NULL);
14882 d3d = Direct3DCreate9(D3D_SDK_VERSION);
14883 ok(!!d3d, "Failed to create a D3D object.\n");
14884 if (!(device = create_device(d3d, window, window, TRUE)))
14886 skip("Failed to create a D3D device, skipping tests.\n");
14887 goto done;
14890 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
14891 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
14892 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0) || caps.VertexShaderVersion < D3DVS_VERSION(2, 0))
14894 skip("No shader model 2.0 support, skipping floating point specials test.\n");
14895 IDirect3DDevice9_Release(device);
14896 goto done;
14899 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE1(0));
14900 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
14902 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
14903 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
14904 hr = IDirect3DDevice9_SetPixelShader(device, ps);
14905 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
14907 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
14908 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
14910 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0f, 0);
14911 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
14913 for (i = 0; i < sizeof(vs_body) / sizeof(*vs_body); ++i)
14915 if (vs_body[i].size > body_size) body_size = vs_body[i].size;
14918 vs_code = HeapAlloc(GetProcessHeap(), 0, sizeof(vs_header) + body_size + sizeof(vs_footer));
14919 memcpy(vs_code, vs_header, sizeof(vs_header));
14921 for (i = 0; i < sizeof(vs_body) / sizeof(*vs_body); ++i)
14923 DWORD offset = sizeof(vs_header) / sizeof(*vs_header);
14924 IDirect3DVertexShader9 *vs;
14925 D3DCOLOR color;
14927 memcpy(vs_code + offset, vs_body[i].ops, vs_body[i].size);
14928 offset += vs_body[i].size / sizeof(*vs_body[i].ops);
14929 memcpy(vs_code + offset, vs_footer, sizeof(vs_footer));
14931 hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vs);
14932 ok(SUCCEEDED(hr), "CreateVertexShader failed, hr %#x.\n", hr);
14933 hr = IDirect3DDevice9_SetVertexShader(device, vs);
14934 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
14936 hr = IDirect3DDevice9_BeginScene(device);
14937 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
14938 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
14939 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
14940 hr = IDirect3DDevice9_EndScene(device);
14941 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
14943 color = getPixelColor(device, 320, 240);
14944 ok(color_match(color, vs_body[i].r500, 1)
14945 || color_match(color, vs_body[i].r600, 1)
14946 || color_match(color, vs_body[i].nv40, 1)
14947 || color_match(color, vs_body[i].nv50, 1)
14948 || broken(color_match(color, vs_body[i].warp, 1)),
14949 "Expected color 0x%08x, 0x%08x, 0x%08x or 0x%08x for instruction \"%s\", got 0x%08x.\n",
14950 vs_body[i].r500, vs_body[i].r600, vs_body[i].nv40, vs_body[i].nv50, vs_body[i].name, color);
14952 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
14953 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
14955 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
14956 ok(SUCCEEDED(hr), "SetVertexShader failed, hr %#x.\n", hr);
14957 IDirect3DVertexShader9_Release(vs);
14960 HeapFree(GetProcessHeap(), 0, vs_code);
14962 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
14963 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
14964 IDirect3DPixelShader9_Release(ps);
14965 refcount = IDirect3DDevice9_Release(device);
14966 ok(!refcount, "Device has %u references left.\n", refcount);
14967 done:
14968 IDirect3D9_Release(d3d);
14969 DestroyWindow(window);
14972 static void srgbwrite_format_test(void)
14974 IDirect3D9 *d3d;
14975 IDirect3DSurface9 *rt, *backbuffer;
14976 IDirect3DTexture9 *texture;
14977 IDirect3DDevice9 *device;
14978 ULONG refcount;
14979 HWND window;
14980 HRESULT hr;
14981 int i;
14982 DWORD color_rgb = 0x00808080, color_srgb = 0x00bcbcbc, color;
14983 static const struct
14985 D3DFORMAT fmt;
14986 const char *name;
14988 formats[] =
14990 { D3DFMT_R5G6B5, "D3DFMT_R5G6B5" },
14991 { D3DFMT_X8R8G8B8, "D3DFMT_X8R8G8B8" },
14992 { D3DFMT_A8R8G8B8, "D3DFMT_A8R8G8B8" },
14993 { D3DFMT_A16B16G16R16F, "D3DFMT_A16B16G16R16F" },
14994 { D3DFMT_A32B32G32R32F, "D3DFMT_A32B32G32R32F" },
14996 static const struct
14998 float x, y, z;
14999 float u, v;
15001 quad[] =
15003 {-1.0f, -1.0f, 0.1f, 0.0f, 0.0f},
15004 {-1.0f, 1.0f, 0.1f, 1.0f, 0.0f},
15005 { 1.0f, -1.0f, 0.1f, 0.0f, 1.0f},
15006 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f}
15009 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
15010 0, 0, 640, 480, NULL, NULL, NULL, NULL);
15011 d3d = Direct3DCreate9(D3D_SDK_VERSION);
15012 ok(!!d3d, "Failed to create a D3D object.\n");
15013 if (!(device = create_device(d3d, window, window, TRUE)))
15015 skip("Failed to create a D3D device, skipping tests.\n");
15016 goto done;
15019 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
15020 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
15021 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
15022 ok(SUCCEEDED(hr), "GetBackBuffer failed, hr %#x.\n", hr);
15023 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
15024 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
15025 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x80808080);
15026 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15028 for(i = 0; i < (sizeof(formats) / sizeof(*formats)); i++)
15030 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
15031 D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, formats[i].fmt)))
15033 skip("Format %s not supported as render target, skipping test.\n",
15034 formats[i].name);
15035 continue;
15038 hr = IDirect3DDevice9_CreateTexture(device, 8, 8, 1, D3DUSAGE_RENDERTARGET,
15039 formats[i].fmt, D3DPOOL_DEFAULT, &texture, NULL);
15040 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
15041 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff0000, 1.0f, 0);
15042 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
15044 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &rt);
15045 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
15046 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
15047 ok(SUCCEEDED(hr), "SetRenderTarget failed, hr %#x.\n", hr);
15048 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x000000ff, 0.0f, 0);
15049 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
15051 hr = IDirect3DDevice9_BeginScene(device);
15052 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
15054 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, TRUE);
15055 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
15056 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TFACTOR);
15057 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
15058 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15059 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
15061 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRGBWRITEENABLE, FALSE);
15062 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
15063 hr = IDirect3DDevice9_SetRenderTarget(device, 0, backbuffer);
15064 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
15065 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
15066 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
15067 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
15068 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
15069 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15070 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
15071 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
15072 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
15074 hr = IDirect3DDevice9_EndScene(device);
15075 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
15077 IDirect3DSurface9_Release(rt);
15078 IDirect3DTexture9_Release(texture);
15080 color = getPixelColor(device, 360, 240);
15081 if(IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
15082 D3DUSAGE_QUERY_SRGBWRITE,
15083 D3DRTYPE_TEXTURE, formats[i].fmt) == D3D_OK)
15085 /* Big slop for R5G6B5 */
15086 ok(color_match(color, color_srgb, 5), "Format %s supports srgb, expected color 0x%08x, got 0x%08x\n",
15087 formats[i].name, color_srgb, color);
15089 else
15091 /* Big slop for R5G6B5 */
15092 ok(color_match(color, color_rgb, 5), "Format %s does not support srgb, expected color 0x%08x, got 0x%08x\n",
15093 formats[i].name, color_rgb, color);
15096 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
15097 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
15100 IDirect3DSurface9_Release(backbuffer);
15101 refcount = IDirect3DDevice9_Release(device);
15102 ok(!refcount, "Device has %u references left.\n", refcount);
15103 done:
15104 IDirect3D9_Release(d3d);
15105 DestroyWindow(window);
15108 static void ds_size_test(void)
15110 IDirect3DSurface9 *ds, *rt, *old_rt, *old_ds, *readback;
15111 IDirect3DDevice9 *device;
15112 DWORD num_passes;
15113 IDirect3D9 *d3d;
15114 ULONG refcount;
15115 HWND window;
15116 HRESULT hr;
15118 static const struct
15120 float x, y, z;
15122 quad[] =
15124 {-1.0f, -1.0f, 0.0f},
15125 {-1.0f, 1.0f, 0.0f},
15126 { 1.0f, -1.0f, 0.0f},
15127 { 1.0f, 1.0f, 0.0f},
15130 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
15131 0, 0, 640, 480, NULL, NULL, NULL, NULL);
15132 d3d = Direct3DCreate9(D3D_SDK_VERSION);
15133 ok(!!d3d, "Failed to create a D3D object.\n");
15134 if (!(device = create_device(d3d, window, window, TRUE)))
15136 skip("Failed to create a D3D device, skipping tests.\n");
15137 goto done;
15140 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, FALSE, &rt, NULL);
15141 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateRenderTarget failed, hr %#x.\n", hr);
15142 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 32, 32, D3DFMT_D24X8, D3DMULTISAMPLE_NONE, 0, TRUE, &ds, NULL);
15143 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateDepthStencilSurface failed, hr %#x.\n", hr);
15144 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 64, 64, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &readback, NULL);
15145 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateOffscreenPlainSurface failed, hr %#x.\n", hr);
15147 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
15148 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
15150 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
15151 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
15152 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
15153 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
15154 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
15155 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
15156 hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
15157 ok(SUCCEEDED(hr), "IDirect3DDevice9_ValidateDevice failed, hr %#x.\n", hr);
15158 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &old_rt);
15159 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetRenderTarget failed, hr %#x.\n", hr);
15160 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &old_ds);
15161 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetDepthStencilSurface failed, hr %#x.\n", hr);
15162 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
15163 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
15164 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
15165 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetDepthStencilSurface failed, hr %#x.\n", hr);
15166 hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
15167 ok(SUCCEEDED(hr), "IDirect3DDevice9_ValidateDevice failed, hr %#x.\n", hr);
15169 /* The D3DCLEAR_TARGET clear works. D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER returns OK,
15170 * but does not change the surface's contents. */
15171 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x000000FF, 0.0f, 0);
15172 ok(SUCCEEDED(hr), "Target clear failed, hr %#x.\n", hr);
15173 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 0.2f, 0);
15174 ok(SUCCEEDED(hr), "Z Buffer clear failed, hr %#x.\n", hr);
15175 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff0000, 0.5f, 0);
15176 ok(SUCCEEDED(hr), "Target and Z Buffer clear failed, hr %#x.\n", hr);
15178 /* Nvidia does not clear the surface(The color is still 0x000000ff), AMD does(the color is 0x00ff0000) */
15180 /* Turning on any depth-related state results in a ValidateDevice failure */
15181 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
15182 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
15183 hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
15184 ok(hr == D3DERR_CONFLICTINGRENDERSTATE || hr == D3D_OK, "IDirect3DDevice9_ValidateDevice returned %#x, expected "
15185 "D3DERR_CONFLICTINGRENDERSTATE.\n", hr);
15186 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
15187 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
15188 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
15189 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderState failed, hr %#x.\n", hr);
15190 hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
15191 ok(hr == D3DERR_CONFLICTINGRENDERSTATE || hr == D3D_OK, "IDirect3DDevice9_ValidateDevice returned %#x, expected "
15192 "D3DERR_CONFLICTINGRENDERSTATE.\n", hr);
15194 /* Try to draw with the device in an invalid state. */
15195 hr = IDirect3DDevice9_BeginScene(device);
15196 ok(SUCCEEDED(hr), "Failed to begin scene, 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_EndScene(device);
15200 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
15202 /* Don't check the resulting draw unless we find an app that needs it. On
15203 * NVIDIA ValidateDevice() returns CONFLICTINGRENDERSTATE, so the result
15204 * is undefined. On AMD D3D seems to assume the stored Z buffer value is
15205 * 0.0 for all pixels, even those that are covered by the depth buffer. */
15207 hr = IDirect3DDevice9_SetRenderTarget(device, 0, old_rt);
15208 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
15209 hr = IDirect3DDevice9_SetDepthStencilSurface(device, old_ds);
15210 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetDepthStencilSurface failed, hr %#x.\n", hr);
15211 hr = IDirect3DDevice9_ValidateDevice(device, &num_passes);
15212 ok(SUCCEEDED(hr), "IDirect3DDevice9_ValidateDevice failed, hr %#x.\n", hr);
15214 IDirect3DSurface9_Release(readback);
15215 IDirect3DSurface9_Release(ds);
15216 IDirect3DSurface9_Release(rt);
15217 IDirect3DSurface9_Release(old_rt);
15218 IDirect3DSurface9_Release(old_ds);
15219 refcount = IDirect3DDevice9_Release(device);
15220 ok(!refcount, "Device has %u references left.\n", refcount);
15221 done:
15222 IDirect3D9_Release(d3d);
15223 DestroyWindow(window);
15226 static void unbound_sampler_test(void)
15228 IDirect3DPixelShader9 *ps, *ps_cube, *ps_volume;
15229 IDirect3DSurface9 *rt, *old_rt;
15230 IDirect3DDevice9 *device;
15231 IDirect3D9 *d3d;
15232 ULONG refcount;
15233 D3DCAPS9 caps;
15234 DWORD color;
15235 HWND window;
15236 HRESULT hr;
15238 static const DWORD ps_code[] =
15240 0xffff0200, /* ps_2_0 */
15241 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
15242 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
15243 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
15244 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
15245 0x0000ffff, /* end */
15247 static const DWORD ps_code_cube[] =
15249 0xffff0200, /* ps_2_0 */
15250 0x0200001f, 0x98000000, 0xa00f0800, /* dcl_cube s0 */
15251 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
15252 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
15253 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
15254 0x0000ffff, /* end */
15256 static const DWORD ps_code_volume[] =
15258 0xffff0200, /* ps_2_0 */
15259 0x0200001f, 0xa0000000, 0xa00f0800, /* dcl_volume s0 */
15260 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
15261 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
15262 0x02000001, 0x800f0800, 0x80e40000, /* mov oC0, r0 */
15263 0x0000ffff, /* end */
15266 static const struct
15268 float x, y, z;
15269 float u, v;
15271 quad[] =
15273 {-1.0f, -1.0f, 0.1f, 0.0f, 0.0f},
15274 {-1.0f, 1.0f, 0.1f, 1.0f, 0.0f},
15275 { 1.0f, -1.0f, 0.1f, 0.0f, 1.0f},
15276 { 1.0f, 1.0f, 0.1f, 1.0f, 1.0f}
15279 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
15280 0, 0, 640, 480, NULL, NULL, NULL, NULL);
15281 d3d = Direct3DCreate9(D3D_SDK_VERSION);
15282 ok(!!d3d, "Failed to create a D3D object.\n");
15283 if (!(device = create_device(d3d, window, window, TRUE)))
15285 skip("Failed to create a D3D device, skipping tests.\n");
15286 goto done;
15289 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
15290 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
15291 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
15293 skip("No ps_2_0 support, skipping tests.\n");
15294 IDirect3DDevice9_Release(device);
15295 goto done;
15297 if (!(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP) || !(caps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP))
15299 skip("No cube / volume texture support, skipping tests.\n");
15300 IDirect3DDevice9_Release(device);
15301 goto done;
15304 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
15305 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetTextureStage failed, %#x.\n", hr);
15307 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
15308 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreatePixelShader failed, hr %#x.\n", hr);
15309 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code_cube, &ps_cube);
15310 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreatePixelShader failed, hr %#x.\n", hr);
15311 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code_volume, &ps_volume);
15312 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreatePixelShader failed, hr %#x.\n", hr);
15314 hr = IDirect3DDevice9_CreateRenderTarget(device, 64, 64, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &rt, NULL);
15315 ok(SUCCEEDED(hr), "IDirect3DDevice9_CreateRenderTarget failed, hr %#x.\n", hr);
15317 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &old_rt);
15318 ok(SUCCEEDED(hr), "IDirect3DDevice9_GetRenderTarget failed, hr %#x.\n", hr);
15320 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
15321 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetRenderTarget failed, hr %#x.\n", hr);
15323 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 );
15324 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetFVF failed, hr %#x.\n", hr);
15326 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x56ffffff, 1.0f, 0);
15327 ok(SUCCEEDED(hr), "IDirect3DDevice9_Clear failed, hr %#x.\n", hr);
15329 hr = IDirect3DDevice9_SetPixelShader(device, ps);
15330 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetPixelShader failed, hr %#x.\n", hr);
15332 hr = IDirect3DDevice9_BeginScene(device);
15333 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
15334 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15335 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
15336 hr = IDirect3DDevice9_EndScene(device);
15337 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
15339 color = getPixelColorFromSurface(rt, 32, 32);
15340 ok(color == 0xff000000, "Unbound sampler color is %#x.\n", color);
15342 /* Now try with a cube texture */
15343 hr = IDirect3DDevice9_SetPixelShader(device, ps_cube);
15344 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetPixelShader failed, hr %#x.\n", hr);
15346 hr = IDirect3DDevice9_BeginScene(device);
15347 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
15348 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15349 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
15350 hr = IDirect3DDevice9_EndScene(device);
15351 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
15353 color = getPixelColorFromSurface(rt, 32, 32);
15354 ok(color == 0xff000000, "Unbound sampler color is %#x.\n", color);
15356 /* And then with a volume texture */
15357 hr = IDirect3DDevice9_SetPixelShader(device, ps_volume);
15358 ok(SUCCEEDED(hr), "IDirect3DDevice9_SetPixelShader failed, hr %#x.\n", hr);
15360 hr = IDirect3DDevice9_BeginScene(device);
15361 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
15362 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
15363 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
15364 hr = IDirect3DDevice9_EndScene(device);
15365 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
15367 color = getPixelColorFromSurface(rt, 32, 32);
15368 ok(color == 0xff000000, "Unbound sampler color is %#x.\n", color);
15370 IDirect3DSurface9_Release(rt);
15371 IDirect3DSurface9_Release(old_rt);
15372 IDirect3DPixelShader9_Release(ps);
15373 IDirect3DPixelShader9_Release(ps_cube);
15374 IDirect3DPixelShader9_Release(ps_volume);
15375 refcount = IDirect3DDevice9_Release(device);
15376 ok(!refcount, "Device has %u references left.\n", refcount);
15377 done:
15378 IDirect3D9_Release(d3d);
15379 DestroyWindow(window);
15382 static void update_surface_test(void)
15384 static const BYTE blocks[][8] =
15386 {0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00}, /* White */
15387 {0x00, 0xf8, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00}, /* Red */
15388 {0xe0, 0xff, 0xe0, 0xff, 0x00, 0x00, 0x00, 0x00}, /* Yellow */
15389 {0xe0, 0x07, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00}, /* Green */
15390 {0xff, 0x07, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00}, /* Cyan */
15391 {0x1f, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00}, /* Blue */
15392 {0x1f, 0xf8, 0x1f, 0xf8, 0x00, 0x00, 0x00, 0x00}, /* Magenta */
15394 static const struct
15396 UINT x, y;
15397 D3DCOLOR color;
15399 expected_colors[] =
15401 { 18, 240, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0xff)},
15402 { 57, 240, D3DCOLOR_ARGB(0x00, 0x00, 0x00, 0xff)},
15403 {109, 240, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0xff)},
15404 {184, 240, D3DCOLOR_ARGB(0x00, 0x00, 0xff, 0x00)},
15405 {290, 240, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0x00)},
15406 {440, 240, D3DCOLOR_ARGB(0x00, 0xff, 0x00, 0x00)},
15407 {584, 240, D3DCOLOR_ARGB(0x00, 0xff, 0xff, 0xff)},
15409 static const struct
15411 float x, y, z, w;
15412 float u, v;
15414 tri[] =
15416 { 0.0f, 480.0f, 0.0f, 1.0f, 0.0f, 0.0f},
15417 { 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
15418 {640.0f, 240.0f, 0.0f, 10.0f, 100.0f, 0.5f},
15420 static const RECT rect_2x2 = {0, 0, 2, 2};
15421 static const struct
15423 UINT src_level;
15424 UINT dst_level;
15425 const RECT *r;
15426 HRESULT hr;
15428 block_size_tests[] =
15430 {1, 0, NULL, D3D_OK},
15431 {0, 1, NULL, D3DERR_INVALIDCALL},
15432 {5, 4, NULL, D3DERR_INVALIDCALL},
15433 {4, 5, NULL, D3DERR_INVALIDCALL},
15434 {4, 5, &rect_2x2, D3DERR_INVALIDCALL},
15435 {5, 5, &rect_2x2, D3D_OK},
15438 IDirect3DSurface9 *src_surface, *dst_surface;
15439 IDirect3DTexture9 *src_tex, *dst_tex;
15440 IDirect3DDevice9 *device;
15441 IDirect3D9 *d3d;
15442 ULONG refcount;
15443 UINT count, i;
15444 HWND window;
15445 HRESULT hr;
15447 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
15448 0, 0, 640, 480, NULL, NULL, NULL, NULL);
15449 d3d = Direct3DCreate9(D3D_SDK_VERSION);
15450 ok(!!d3d, "Failed to create a D3D object.\n");
15451 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
15452 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, D3DFMT_DXT1)))
15454 skip("DXT1 not supported, skipping tests.\n");
15455 goto done;
15457 if (!(device = create_device(d3d, window, window, TRUE)))
15459 skip("Failed to create a D3D device, skipping tests.\n");
15460 goto done;
15463 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 0, 0, D3DFMT_DXT1, D3DPOOL_SYSTEMMEM, &src_tex, NULL);
15464 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
15465 hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 0, 0, D3DFMT_DXT1, D3DPOOL_DEFAULT, &dst_tex, NULL);
15466 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
15468 count = IDirect3DTexture9_GetLevelCount(src_tex);
15469 ok(count == 7, "Got level count %u, expected 7.\n", count);
15471 for (i = 0; i < count; ++i)
15473 UINT row_count, block_count, x, y;
15474 D3DSURFACE_DESC desc;
15475 BYTE *row, *block;
15476 D3DLOCKED_RECT r;
15478 hr = IDirect3DTexture9_GetLevelDesc(src_tex, i, &desc);
15479 ok(SUCCEEDED(hr), "Failed to get level desc, hr %#x.\n", hr);
15481 hr = IDirect3DTexture9_LockRect(src_tex, i, &r, NULL, 0);
15482 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
15484 row_count = ((desc.Height + 3) & ~3) / 4;
15485 block_count = ((desc.Width + 3) & ~3) / 4;
15486 row = r.pBits;
15488 for (y = 0; y < row_count; ++y)
15490 block = row;
15491 for (x = 0; x < block_count; ++x)
15493 memcpy(block, blocks[i], sizeof(blocks[i]));
15494 block += sizeof(blocks[i]);
15496 row += r.Pitch;
15499 hr = IDirect3DTexture9_UnlockRect(src_tex, i);
15500 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
15503 for (i = 0; i < sizeof(block_size_tests) / sizeof(*block_size_tests); ++i)
15505 hr = IDirect3DTexture9_GetSurfaceLevel(src_tex, block_size_tests[i].src_level, &src_surface);
15506 ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
15507 hr = IDirect3DTexture9_GetSurfaceLevel(dst_tex, block_size_tests[i].dst_level, &dst_surface);
15508 ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
15510 hr = IDirect3DDevice9_UpdateSurface(device, src_surface, block_size_tests[i].r, dst_surface, NULL);
15511 ok(hr == block_size_tests[i].hr, "Update surface returned %#x for test %u, expected %#x.\n",
15512 hr, i, block_size_tests[i].hr);
15514 IDirect3DSurface9_Release(dst_surface);
15515 IDirect3DSurface9_Release(src_surface);
15518 for (i = 0; i < count; ++i)
15520 hr = IDirect3DTexture9_GetSurfaceLevel(src_tex, i, &src_surface);
15521 ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
15522 hr = IDirect3DTexture9_GetSurfaceLevel(dst_tex, i, &dst_surface);
15523 ok(SUCCEEDED(hr), "Failed to get texture surface, hr %#x.\n", hr);
15525 hr = IDirect3DDevice9_UpdateSurface(device, src_surface, NULL, dst_surface, NULL);
15526 ok(SUCCEEDED(hr), "Failed to update surface at level %u, hr %#x.\n", i, hr);
15528 IDirect3DSurface9_Release(dst_surface);
15529 IDirect3DSurface9_Release(src_surface);
15532 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
15533 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15534 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
15535 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
15536 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_TEX1);
15537 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
15538 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)dst_tex);
15539 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
15540 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
15541 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
15542 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
15543 ok(SUCCEEDED(hr), "SetTextureStageState failed, hr %#x.\n", hr);
15545 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0f, 0);
15546 ok(SUCCEEDED(hr), "Clear failed, hr %#x.\n", hr);
15548 hr = IDirect3DDevice9_BeginScene(device);
15549 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
15550 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLELIST, 1, tri, sizeof(*tri));
15551 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
15552 hr = IDirect3DDevice9_EndScene(device);
15553 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
15555 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
15557 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
15558 ok(color_match(color, expected_colors[i].color, 0),
15559 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
15560 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
15563 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
15564 ok(SUCCEEDED(hr), "Present failed, hr %#x.\n", hr);
15566 IDirect3DTexture9_Release(dst_tex);
15567 IDirect3DTexture9_Release(src_tex);
15568 refcount = IDirect3DDevice9_Release(device);
15569 ok(!refcount, "Device has %u references left.\n", refcount);
15570 done:
15571 IDirect3D9_Release(d3d);
15572 DestroyWindow(window);
15575 static void multisample_get_rtdata_test(void)
15577 IDirect3DSurface9 *original_ds, *original_rt, *rt, *readback;
15578 IDirect3DDevice9 *device;
15579 IDirect3D9 *d3d;
15580 ULONG refcount;
15581 HWND window;
15582 HRESULT hr;
15584 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
15585 0, 0, 640, 480, NULL, NULL, NULL, NULL);
15586 d3d = Direct3DCreate9(D3D_SDK_VERSION);
15587 ok(!!d3d, "Failed to create a D3D object.\n");
15588 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
15589 D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
15591 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping tests.\n");
15592 goto done;
15594 if (!(device = create_device(d3d, window, window, TRUE)))
15596 skip("Failed to create a D3D device, skipping tests.\n");
15597 goto done;
15600 hr = IDirect3DDevice9_CreateRenderTarget(device, 256, 256, D3DFMT_A8R8G8B8,
15601 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt, NULL);
15602 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
15603 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, 256, 256, D3DFMT_A8R8G8B8,
15604 D3DPOOL_SYSTEMMEM, &readback, NULL);
15605 ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
15607 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
15608 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
15609 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
15610 ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#x.\n", hr);
15612 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
15613 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
15614 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
15615 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
15617 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
15618 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
15619 hr = IDirect3DDevice9_GetRenderTargetData(device, rt, readback);
15620 ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr %#x.\n", hr);
15622 hr = IDirect3DDevice9_SetDepthStencilSurface(device, original_ds);
15623 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
15624 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
15625 ok(SUCCEEDED(hr), "Failed to restore original render target, hr %#x.\n", hr);
15627 IDirect3DSurface9_Release(original_ds);
15628 IDirect3DSurface9_Release(original_rt);
15629 IDirect3DSurface9_Release(readback);
15630 IDirect3DSurface9_Release(rt);
15631 refcount = IDirect3DDevice9_Release(device);
15632 ok(!refcount, "Device has %u references left.\n", refcount);
15633 done:
15634 IDirect3D9_Release(d3d);
15635 DestroyWindow(window);
15638 static void multisampled_depth_buffer_test(void)
15640 IDirect3DDevice9 *device = 0;
15641 IDirect3DSurface9 *original_rt, *rt, *readback, *ds, *original_ds;
15642 IDirect3D9 *d3d;
15643 D3DCAPS9 caps;
15644 HRESULT hr;
15645 D3DPRESENT_PARAMETERS present_parameters;
15646 unsigned int i;
15647 static const struct
15649 float x, y, z;
15650 D3DCOLOR color;
15652 quad_1[] =
15654 { -1.0f, 1.0f, 0.0f, 0xffff0000},
15655 { 1.0f, 1.0f, 1.0f, 0xffff0000},
15656 { -1.0f, -1.0f, 0.0f, 0xffff0000},
15657 { 1.0f, -1.0f, 1.0f, 0xffff0000},
15659 quad_2[] =
15661 { -1.0f, 1.0f, 1.0f, 0xff0000ff},
15662 { 1.0f, 1.0f, 0.0f, 0xff0000ff},
15663 { -1.0f, -1.0f, 1.0f, 0xff0000ff},
15664 { 1.0f, -1.0f, 0.0f, 0xff0000ff},
15666 static const struct
15668 UINT x, y;
15669 D3DCOLOR color;
15671 expected_colors[] =
15673 { 80, 100, D3DCOLOR_ARGB(0xff, 0xff, 0x00, 0x00)},
15674 {240, 100, D3DCOLOR_ARGB(0xff, 0xff, 0x00, 0x00)},
15675 {400, 100, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff)},
15676 {560, 100, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff)},
15677 { 80, 450, D3DCOLOR_ARGB(0xff, 0xff, 0x00, 0x00)},
15678 {240, 450, D3DCOLOR_ARGB(0xff, 0xff, 0x00, 0x00)},
15679 {400, 450, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff)},
15680 {560, 450, D3DCOLOR_ARGB(0xff, 0x00, 0x00, 0xff)},
15683 d3d = Direct3DCreate9(D3D_SDK_VERSION);
15684 ok(!!d3d, "Failed to create a D3D object.\n");
15686 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT,
15687 D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
15689 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping multisampled depth buffer test.\n");
15690 IDirect3D9_Release(d3d);
15691 return;
15693 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT,
15694 D3DDEVTYPE_HAL, D3DFMT_D24S8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
15696 skip("Multisampling not supported for D3DFMT_D24S8, skipping multisampled depth buffer test.\n");
15697 IDirect3D9_Release(d3d);
15698 return;
15701 ZeroMemory(&present_parameters, sizeof(present_parameters));
15702 present_parameters.Windowed = TRUE;
15703 present_parameters.hDeviceWindow = create_window();
15704 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
15705 present_parameters.BackBufferWidth = 640;
15706 present_parameters.BackBufferHeight = 480;
15707 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
15708 present_parameters.EnableAutoDepthStencil = TRUE;
15709 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
15710 present_parameters.MultiSampleType = D3DMULTISAMPLE_2_SAMPLES;
15712 hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
15713 present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING,
15714 &present_parameters, &device);
15715 ok(hr == D3D_OK, "Failed to create a device, hr %#x.\n", hr);
15717 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
15718 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
15719 if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
15721 skip("No unconditional NP2 texture support, skipping multisampled depth buffer test.\n");
15722 goto cleanup;
15725 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
15726 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt, NULL);
15727 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
15728 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
15729 D3DMULTISAMPLE_NONE, 0, TRUE, &readback, NULL);
15730 ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
15732 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
15733 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
15734 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds);
15735 ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#x.\n", hr);
15737 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
15738 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15739 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
15740 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15741 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
15742 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15743 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
15744 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15745 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
15746 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
15748 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
15749 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
15751 /* Render onscreen and then offscreen */
15752 hr = IDirect3DDevice9_BeginScene(device);
15753 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
15754 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_1, sizeof(*quad_1));
15755 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
15756 hr = IDirect3DDevice9_EndScene(device);
15757 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
15759 hr = IDirect3DDevice9_StretchRect(device, original_rt, NULL, rt, NULL, D3DTEXF_POINT);
15760 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
15761 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
15762 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
15764 hr = IDirect3DDevice9_BeginScene(device);
15765 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
15766 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_2, sizeof(*quad_2));
15767 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
15768 hr = IDirect3DDevice9_EndScene(device);
15769 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
15771 hr = IDirect3DDevice9_StretchRect(device, rt, NULL, readback, NULL, D3DTEXF_POINT);
15772 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
15774 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
15776 D3DCOLOR color = getPixelColorFromSurface(readback, expected_colors[i].x, expected_colors[i].y);
15777 ok(color_match(color, expected_colors[i].color, 1),
15778 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
15779 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
15782 hr = IDirect3DDevice9_StretchRect(device, rt, NULL, original_rt, NULL, D3DTEXF_POINT);
15783 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
15784 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
15785 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
15787 /* Render offscreen and then onscreen */
15788 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
15789 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
15790 IDirect3DSurface9_Release(ds);
15791 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
15792 D3DMULTISAMPLE_2_SAMPLES, 0, TRUE, &ds, NULL);
15793 ok(SUCCEEDED(hr), "Failed to create depth/stencil, hr %#x.\n", hr);
15794 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
15795 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
15797 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
15798 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
15800 hr = IDirect3DDevice9_BeginScene(device);
15801 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
15802 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_1, sizeof(*quad_1));
15803 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
15804 hr = IDirect3DDevice9_EndScene(device);
15805 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
15807 hr = IDirect3DDevice9_StretchRect(device, rt, NULL, original_rt, NULL, D3DTEXF_POINT);
15808 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
15809 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
15810 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
15812 hr = IDirect3DDevice9_BeginScene(device);
15813 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
15814 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_2, sizeof(*quad_2));
15815 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
15816 hr = IDirect3DDevice9_EndScene(device);
15817 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
15819 hr = IDirect3DDevice9_StretchRect(device, original_rt, NULL, readback, NULL, D3DTEXF_POINT);
15820 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
15822 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
15824 D3DCOLOR color = getPixelColorFromSurface(readback, expected_colors[i].x, expected_colors[i].y);
15825 ok(color_match(color, expected_colors[i].color, 1),
15826 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
15827 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
15830 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
15831 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
15833 IDirect3DSurface9_Release(ds);
15834 IDirect3DSurface9_Release(readback);
15835 IDirect3DSurface9_Release(rt);
15836 IDirect3DSurface9_Release(original_rt);
15837 cleanup_device(device);
15839 ZeroMemory(&present_parameters, sizeof(present_parameters));
15840 present_parameters.Windowed = TRUE;
15841 present_parameters.hDeviceWindow = create_window();
15842 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
15843 present_parameters.BackBufferWidth = 640;
15844 present_parameters.BackBufferHeight = 480;
15845 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
15846 present_parameters.EnableAutoDepthStencil = TRUE;
15847 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
15848 present_parameters.MultiSampleType = D3DMULTISAMPLE_NONE;
15850 hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
15851 present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING,
15852 &present_parameters, &device);
15853 ok(hr == D3D_OK, "Failed to create a device, hr %#x.\n", hr);
15855 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ffff, 1.0f, 0);
15856 ok(SUCCEEDED(hr), "Failed to clear depth buffer, hr %#x.\n", hr);
15858 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
15859 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt, NULL);
15860 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
15861 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
15862 D3DMULTISAMPLE_NONE, 0, TRUE, &readback, NULL);
15863 ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
15864 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
15865 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &ds, NULL);
15866 ok(SUCCEEDED(hr), "CreateDepthStencilSurface failed, hr %#x.\n", hr);
15868 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
15869 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
15870 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &original_ds);
15871 ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#x.\n", hr);
15872 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
15873 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
15874 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
15875 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
15877 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
15878 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15879 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
15880 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15881 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
15882 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15883 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
15884 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
15885 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
15886 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
15888 /* Render to a multisampled offscreen frame buffer and then blit to
15889 * the onscreen (not multisampled) frame buffer. */
15890 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
15891 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
15893 hr = IDirect3DDevice9_BeginScene(device);
15894 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
15895 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_1, sizeof(*quad_1));
15896 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
15897 hr = IDirect3DDevice9_EndScene(device);
15898 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
15900 hr = IDirect3DDevice9_StretchRect(device, rt, NULL, original_rt, NULL, D3DTEXF_POINT);
15901 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
15902 hr = IDirect3DDevice9_StretchRect(device, ds, NULL, original_ds, NULL, D3DTEXF_POINT);
15903 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
15905 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
15906 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
15907 hr = IDirect3DDevice9_SetDepthStencilSurface(device, original_ds);
15908 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
15910 hr = IDirect3DDevice9_BeginScene(device);
15911 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
15912 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad_2, sizeof(*quad_2));
15913 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
15914 hr = IDirect3DDevice9_EndScene(device);
15915 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
15917 hr = IDirect3DDevice9_StretchRect(device, original_rt, NULL, readback, NULL, D3DTEXF_POINT);
15918 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
15920 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
15922 D3DCOLOR color = getPixelColorFromSurface(readback, expected_colors[i].x, expected_colors[i].y);
15923 ok(color_match(color, expected_colors[i].color, 1),
15924 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
15925 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
15928 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
15929 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
15931 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
15932 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
15933 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
15934 ok(SUCCEEDED(hr), "Failed to restore original render target, hr %#x.\n", hr);
15936 IDirect3DSurface9_Release(original_ds);
15937 IDirect3DSurface9_Release(original_rt);
15938 IDirect3DSurface9_Release(ds);
15939 IDirect3DSurface9_Release(readback);
15940 IDirect3DSurface9_Release(rt);
15941 cleanup:
15942 cleanup_device(device);
15943 IDirect3D9_Release(d3d);
15946 static void resz_test(void)
15948 IDirect3DDevice9 *device = 0;
15949 IDirect3DSurface9 *rt, *original_rt, *ds, *readback, *intz_ds;
15950 D3DCAPS9 caps;
15951 HRESULT hr;
15952 D3DPRESENT_PARAMETERS present_parameters;
15953 unsigned int i;
15954 static const DWORD ps_code[] =
15956 0xffff0200, /* ps_2_0 */
15957 0x0200001f, 0x90000000, 0xa00f0800, /* dcl_2d s0 */
15958 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
15959 0x05000051, 0xa00f0000, 0x00000000, 0x00000000, 0x00000000, 0x3f800000, /* def c0, 0.0, 0.0, 0.0, 1.0 */
15960 0x02000001, 0x800f0001, 0xa0e40000, /* mov r1, c0 */
15961 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texld r0, t0, s0 */
15962 0x02000001, 0x80010001, 0x80e40000, /* mov r1.x, r0 */
15963 0x03010042, 0x800f0000, 0xb0e40000, 0xa0e40800, /* texldp r0, t0, s0 */
15964 0x02000001, 0x80020001, 0x80000000, /* mov r1.y, r0.x */
15965 0x02000001, 0x800f0800, 0x80e40001, /* mov oC0, r1 */
15966 0x0000ffff, /* end */
15968 struct
15970 float x, y, z;
15971 float s, t, p, q;
15973 quad[] =
15975 { -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f},
15976 { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.5f},
15977 { -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f},
15978 { 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.5f},
15980 struct
15982 UINT x, y;
15983 D3DCOLOR color;
15985 expected_colors[] =
15987 { 80, 100, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
15988 {240, 100, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
15989 {400, 100, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
15990 {560, 100, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
15991 { 80, 450, D3DCOLOR_ARGB(0x00, 0x20, 0x40, 0x00)},
15992 {240, 450, D3DCOLOR_ARGB(0x00, 0x60, 0xbf, 0x00)},
15993 {400, 450, D3DCOLOR_ARGB(0x00, 0x9f, 0x40, 0x00)},
15994 {560, 450, D3DCOLOR_ARGB(0x00, 0xdf, 0xbf, 0x00)},
15996 IDirect3DTexture9 *texture;
15997 IDirect3DPixelShader9 *ps;
15998 IDirect3D9 *d3d;
15999 DWORD value;
16001 d3d = Direct3DCreate9(D3D_SDK_VERSION);
16002 ok(!!d3d, "Failed to create a D3D object.\n");
16004 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT,
16005 D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
16007 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping RESZ test.\n");
16008 IDirect3D9_Release(d3d);
16009 return;
16011 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT,
16012 D3DDEVTYPE_HAL, D3DFMT_D24S8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
16014 skip("Multisampling not supported for D3DFMT_D24S8, skipping RESZ test.\n");
16015 IDirect3D9_Release(d3d);
16016 return;
16019 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
16020 D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, MAKEFOURCC('I','N','T','Z'))))
16022 skip("No INTZ support, skipping RESZ test.\n");
16023 IDirect3D9_Release(d3d);
16024 return;
16027 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
16028 D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE, MAKEFOURCC('R','E','S','Z'))))
16030 skip("No RESZ support, skipping RESZ test.\n");
16031 IDirect3D9_Release(d3d);
16032 return;
16035 ZeroMemory(&present_parameters, sizeof(present_parameters));
16036 present_parameters.Windowed = TRUE;
16037 present_parameters.hDeviceWindow = create_window();
16038 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
16039 present_parameters.BackBufferWidth = 640;
16040 present_parameters.BackBufferHeight = 480;
16041 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
16042 present_parameters.EnableAutoDepthStencil = FALSE;
16043 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
16044 present_parameters.MultiSampleType = D3DMULTISAMPLE_NONE;
16046 hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
16047 present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device);
16048 ok(hr == D3D_OK, "Failed to create a device, hr %#x.\n", hr);
16050 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
16051 ok(SUCCEEDED(hr), "GetDeviceCaps failed, hr %#x.\n", hr);
16052 if (caps.PixelShaderVersion < D3DPS_VERSION(2, 0))
16054 skip("No pixel shader 2.0 support, skipping INTZ test.\n");
16055 cleanup_device(device);
16056 IDirect3D9_Release(d3d);
16057 return;
16059 if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
16061 skip("No unconditional NP2 texture support, skipping INTZ test.\n");
16062 cleanup_device(device);
16063 IDirect3D9_Release(d3d);
16064 return;
16067 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
16068 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
16070 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
16071 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt, NULL);
16072 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
16073 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
16074 D3DMULTISAMPLE_2_SAMPLES, 0, TRUE, &ds, NULL);
16075 ok(SUCCEEDED(hr), "Failed to create depth/stencil, hr %#x.\n", hr);
16076 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
16077 D3DMULTISAMPLE_NONE, 0, TRUE, &readback, NULL);
16078 ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
16080 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
16081 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
16082 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
16083 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &intz_ds);
16084 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
16085 hr = IDirect3DDevice9_SetDepthStencilSurface(device, intz_ds);
16086 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16087 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 1.0f, 0);
16088 ok(SUCCEEDED(hr), "Failed to clear depth/stencil, hr %#x.\n", hr);
16089 IDirect3DSurface9_Release(intz_ds);
16090 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
16091 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
16093 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
16094 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
16095 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
16096 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16097 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
16098 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16099 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
16100 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16101 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
16102 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16104 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
16105 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
16106 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
16107 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
16108 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
16109 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
16110 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
16111 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
16112 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
16113 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
16115 /* Render offscreen (multisampled), blit the depth buffer
16116 * into the INTZ texture and then check its contents */
16117 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
16118 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
16119 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
16120 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16121 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
16122 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
16124 hr = IDirect3DDevice9_BeginScene(device);
16125 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
16126 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16127 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16129 /* The destination depth texture has to be bound to sampler 0 */
16130 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
16131 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
16133 /* the ATI "spec" says you have to do a dummy draw to ensure correct commands ordering */
16134 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
16135 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16136 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
16137 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16138 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0);
16139 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16140 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16141 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16142 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
16143 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16144 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
16145 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16146 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0xf);
16147 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16149 /* The actual multisampled depth buffer resolve happens here */
16150 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
16151 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
16152 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, &value);
16153 ok(SUCCEEDED(hr) && value == 0x7fa05000, "GetRenderState failed, hr %#x, value %#x.\n", hr, value);
16155 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
16156 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
16157 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
16158 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16159 hr = IDirect3DDevice9_SetPixelShader(device, ps);
16160 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
16162 /* Read the depth values back */
16163 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16164 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16165 hr = IDirect3DDevice9_EndScene(device);
16166 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
16168 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
16170 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
16171 ok(color_match(color, expected_colors[i].color, 1),
16172 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
16173 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
16176 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16177 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
16179 IDirect3DSurface9_Release(ds);
16180 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
16181 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
16182 IDirect3DTexture9_Release(texture);
16183 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
16184 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
16185 IDirect3DPixelShader9_Release(ps);
16186 IDirect3DSurface9_Release(readback);
16187 IDirect3DSurface9_Release(original_rt);
16188 IDirect3DSurface9_Release(rt);
16189 cleanup_device(device);
16191 ZeroMemory(&present_parameters, sizeof(present_parameters));
16192 present_parameters.Windowed = TRUE;
16193 present_parameters.hDeviceWindow = create_window();
16194 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
16195 present_parameters.BackBufferWidth = 640;
16196 present_parameters.BackBufferHeight = 480;
16197 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
16198 present_parameters.EnableAutoDepthStencil = TRUE;
16199 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
16200 present_parameters.MultiSampleType = D3DMULTISAMPLE_2_SAMPLES;
16202 hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
16203 present_parameters.hDeviceWindow, D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device);
16204 ok(hr == D3D_OK, "Failed to create a device, hr %#x.\n", hr);
16206 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &original_rt);
16207 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
16208 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds);
16209 ok(SUCCEEDED(hr), "Failed to get depth/stencil, hr %#x.\n", hr);
16210 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
16211 D3DMULTISAMPLE_NONE, 0, TRUE, &readback, NULL);
16212 ok(SUCCEEDED(hr), "Failed to create readback surface, hr %#x.\n", hr);
16213 hr = IDirect3DDevice9_CreateTexture(device, 640, 480, 1,
16214 D3DUSAGE_DEPTHSTENCIL, MAKEFOURCC('I','N','T','Z'), D3DPOOL_DEFAULT, &texture, NULL);
16215 ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
16216 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &intz_ds);
16217 ok(SUCCEEDED(hr), "GetSurfaceLevel failed, hr %#x.\n", hr);
16218 hr = IDirect3DDevice9_SetRenderTarget(device, 0, readback);
16219 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
16220 hr = IDirect3DDevice9_SetDepthStencilSurface(device, intz_ds);
16221 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16222 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0, 1.0f, 0);
16223 ok(SUCCEEDED(hr), "Failed to clear depth/stencil, hr %#x.\n", hr);
16224 IDirect3DSurface9_Release(intz_ds);
16225 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
16226 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
16228 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0));
16229 ok(SUCCEEDED(hr), "SetFVF failed, hr %#x.\n", hr);
16230 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
16231 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16232 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_ALWAYS);
16233 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16234 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
16235 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16236 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
16237 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16239 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
16240 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
16241 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
16242 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
16243 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
16244 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
16245 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
16246 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
16247 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
16248 ok(SUCCEEDED(hr), "SetSamplerState failed, hr %#x.\n", hr);
16250 /* Render onscreen, blit the depth buffer into the INTZ texture
16251 * and then check its contents */
16252 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
16253 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
16254 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
16255 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16256 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff00ff00, 1.0f, 0);
16257 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
16259 hr = IDirect3DDevice9_BeginScene(device);
16260 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
16261 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16262 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16263 hr = IDirect3DDevice9_EndScene(device);
16264 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
16266 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
16267 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
16269 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
16270 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16271 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
16272 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16273 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0);
16274 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16275 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16276 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16277 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
16278 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16279 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
16280 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16281 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0xf);
16282 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16284 /* The actual multisampled depth buffer resolve happens here */
16285 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
16286 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
16287 hr = IDirect3DDevice9_GetRenderState(device, D3DRS_POINTSIZE, &value);
16288 ok(SUCCEEDED(hr) && value == 0x7fa05000, "GetRenderState failed, hr %#x, value %#x.\n", hr, value);
16290 hr = IDirect3DDevice9_SetRenderTarget(device, 0, readback);
16291 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
16292 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
16293 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16294 hr = IDirect3DDevice9_SetPixelShader(device, ps);
16295 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
16297 /* Read the depth values back */
16298 hr = IDirect3DDevice9_BeginScene(device);
16299 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
16300 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16301 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16302 hr = IDirect3DDevice9_EndScene(device);
16303 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
16305 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
16307 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
16308 ok(color_match(color, expected_colors[i].color, 1),
16309 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
16310 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
16313 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16314 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
16317 /* Test edge cases - try with no texture at all */
16318 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
16319 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
16320 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
16321 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
16322 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
16323 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16324 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
16325 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16327 hr = IDirect3DDevice9_BeginScene(device);
16328 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
16329 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16330 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16331 hr = IDirect3DDevice9_EndScene(device);
16332 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
16334 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
16335 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
16337 /* With a non-multisampled depth buffer */
16338 IDirect3DSurface9_Release(ds);
16339 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8,
16340 D3DMULTISAMPLE_NONE, 0, TRUE, &ds, NULL);
16341 ok(SUCCEEDED(hr), "Failed to create depth stencil surface, hr %#x.\n", hr);
16343 hr = IDirect3DDevice9_SetRenderTarget(device, 0, readback);
16344 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
16345 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
16346 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16347 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
16348 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
16350 hr = IDirect3DDevice9_BeginScene(device);
16351 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
16352 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16353 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16355 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
16356 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
16358 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
16359 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16360 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
16361 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16362 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0);
16363 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16364 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16365 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16366 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, TRUE);
16367 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16368 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, TRUE);
16369 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16370 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_COLORWRITEENABLE, 0xf);
16371 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
16372 hr = IDirect3DDevice9_EndScene(device);
16373 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
16375 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
16376 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
16378 hr = IDirect3DDevice9_SetPixelShader(device, ps);
16379 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
16381 /* Read the depth values back. */
16382 hr = IDirect3DDevice9_BeginScene(device);
16383 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
16384 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16385 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16386 hr = IDirect3DDevice9_EndScene(device);
16387 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
16389 for (i = 0; i < sizeof(expected_colors) / sizeof(*expected_colors); ++i)
16391 D3DCOLOR color = getPixelColor(device, expected_colors[i].x, expected_colors[i].y);
16392 ok(color_match(color, expected_colors[i].color, 1),
16393 "Expected color 0x%08x at (%u, %u), got 0x%08x.\n",
16394 expected_colors[i].color, expected_colors[i].x, expected_colors[i].y, color);
16397 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16398 ok(SUCCEEDED(hr), "Present failed (0x%08x)\n", hr);
16400 /* Without a current depth-stencil buffer set */
16401 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
16402 ok(SUCCEEDED(hr), "SetPixelShader failed, hr %#x.\n", hr);
16403 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
16404 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16406 hr = IDirect3DDevice9_BeginScene(device);
16407 ok(SUCCEEDED(hr), "BeginScene failed, hr %#x.\n", hr);
16408 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16409 ok(SUCCEEDED(hr), "DrawPrimitiveUP failed, hr %#x.\n", hr);
16410 hr = IDirect3DDevice9_EndScene(device);
16411 ok(SUCCEEDED(hr), "EndScene failed, hr %#x.\n", hr);
16413 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_POINTSIZE, 0x7fa05000);
16414 ok(SUCCEEDED(hr), "SetRenderState (multisampled depth buffer resolve) failed, hr %#x.\n", hr);
16416 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
16417 ok(SUCCEEDED(hr), "Failed to set depth/stencil, hr %#x.\n", hr);
16418 IDirect3DSurface9_Release(ds);
16419 hr = IDirect3DDevice9_SetRenderTarget(device, 0, original_rt);
16420 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
16421 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
16422 ok(SUCCEEDED(hr), "SetTexture failed, hr %#x.\n", hr);
16423 IDirect3DTexture9_Release(texture);
16424 IDirect3DPixelShader9_Release(ps);
16425 IDirect3DSurface9_Release(readback);
16426 IDirect3DSurface9_Release(original_rt);
16427 cleanup_device(device);
16428 IDirect3D9_Release(d3d);
16431 static void zenable_test(void)
16433 static const struct
16435 struct vec4 position;
16436 D3DCOLOR diffuse;
16438 tquad[] =
16440 {{ 0.0f, 480.0f, -0.5f, 1.0f}, 0xff00ff00},
16441 {{ 0.0f, 0.0f, -0.5f, 1.0f}, 0xff00ff00},
16442 {{640.0f, 480.0f, 1.5f, 1.0f}, 0xff00ff00},
16443 {{640.0f, 0.0f, 1.5f, 1.0f}, 0xff00ff00},
16445 IDirect3DDevice9 *device;
16446 IDirect3D9 *d3d;
16447 D3DCOLOR color;
16448 ULONG refcount;
16449 D3DCAPS9 caps;
16450 HWND window;
16451 HRESULT hr;
16452 UINT x, y;
16453 UINT i, j;
16454 UINT test;
16455 IDirect3DSurface9 *ds;
16457 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
16458 0, 0, 640, 480, NULL, NULL, NULL, NULL);
16459 d3d = Direct3DCreate9(D3D_SDK_VERSION);
16460 ok(!!d3d, "Failed to create a D3D object.\n");
16461 if (!(device = create_device(d3d, window, window, TRUE)))
16463 skip("Failed to create a D3D device, skipping tests.\n");
16464 goto done;
16467 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds);
16468 ok(SUCCEEDED(hr), "Failed to get depth stencil surface, hr %#x.\n", hr);
16470 for (test = 0; test < 2; ++test)
16472 /* The Windows 8 testbot (WARP) appears to clip with
16473 * ZENABLE = D3DZB_TRUE and no depth buffer set. */
16474 static const D3DCOLOR expected_broken[] =
16476 0x00ff0000, 0x0000ff00, 0x0000ff00, 0x00ff0000,
16477 0x00ff0000, 0x0000ff00, 0x0000ff00, 0x00ff0000,
16478 0x00ff0000, 0x0000ff00, 0x0000ff00, 0x00ff0000,
16479 0x00ff0000, 0x0000ff00, 0x0000ff00, 0x00ff0000,
16482 if (!test)
16484 hr = IDirect3DDevice9_SetDepthStencilSurface(device, NULL);
16485 ok(SUCCEEDED(hr), "Failed to set depth stencil surface, hr %#x.\n", hr);
16487 else
16489 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
16490 ok(SUCCEEDED(hr), "Failed to disable z-buffering, hr %#x.\n", hr);
16491 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
16492 ok(SUCCEEDED(hr), "Failed to set depth stencil surface, hr %#x.\n", hr);
16493 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 0.0f, 0);
16494 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
16496 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
16497 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
16499 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffff0000, 0.0f, 0);
16500 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
16501 hr = IDirect3DDevice9_BeginScene(device);
16502 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
16503 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, tquad, sizeof(*tquad));
16504 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
16505 hr = IDirect3DDevice9_EndScene(device);
16506 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
16508 for (i = 0; i < 4; ++i)
16510 for (j = 0; j < 4; ++j)
16512 x = 80 * ((2 * j) + 1);
16513 y = 60 * ((2 * i) + 1);
16514 color = getPixelColor(device, x, y);
16515 ok(color_match(color, 0x0000ff00, 1)
16516 || broken(color_match(color, expected_broken[i * 4 + j], 1) && !test),
16517 "Expected color 0x0000ff00 at %u, %u, got 0x%08x, test %u.\n",
16518 x, y, color, test);
16522 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16523 ok(SUCCEEDED(hr), "Failed to present backbuffer, hr %#x.\n", hr);
16526 IDirect3DSurface9_Release(ds);
16528 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
16529 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
16531 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1)
16532 && caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
16534 static const DWORD vs_code[] =
16536 0xfffe0101, /* vs_1_1 */
16537 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
16538 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
16539 0x00000001, 0xd00f0000, 0x90e40000, /* mov oD0, v0 */
16540 0x0000ffff
16542 static const DWORD ps_code[] =
16544 0xffff0101, /* ps_1_1 */
16545 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
16546 0x0000ffff /* end */
16548 static const struct vec3 quad[] =
16550 {-1.0f, -1.0f, -0.5f},
16551 {-1.0f, 1.0f, -0.5f},
16552 { 1.0f, -1.0f, 1.5f},
16553 { 1.0f, 1.0f, 1.5f},
16555 static const D3DCOLOR expected[] =
16557 0x00ff0000, 0x0060df60, 0x009fdf9f, 0x00ff0000,
16558 0x00ff0000, 0x00609f60, 0x009f9f9f, 0x00ff0000,
16559 0x00ff0000, 0x00606060, 0x009f609f, 0x00ff0000,
16560 0x00ff0000, 0x00602060, 0x009f209f, 0x00ff0000,
16562 /* The Windows 8 testbot (WARP) appears to not clip z for regular
16563 * vertices either. */
16564 static const D3DCOLOR expected_broken[] =
16566 0x0020df20, 0x0060df60, 0x009fdf9f, 0x00dfdfdf,
16567 0x00209f20, 0x00609f60, 0x009f9f9f, 0x00df9fdf,
16568 0x00206020, 0x00606060, 0x009f609f, 0x00df60df,
16569 0x00202020, 0x00602060, 0x009f209f, 0x00df20df,
16572 IDirect3DVertexShader9 *vs;
16573 IDirect3DPixelShader9 *ps;
16575 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
16576 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
16577 hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vs);
16578 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
16579 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
16580 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
16581 hr = IDirect3DDevice9_SetVertexShader(device, vs);
16582 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
16583 hr = IDirect3DDevice9_SetPixelShader(device, ps);
16584 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
16586 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffff0000, 0.0f, 0);
16587 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
16588 hr = IDirect3DDevice9_BeginScene(device);
16589 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
16590 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16591 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
16592 hr = IDirect3DDevice9_EndScene(device);
16593 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
16595 for (i = 0; i < 4; ++i)
16597 for (j = 0; j < 4; ++j)
16599 x = 80 * ((2 * j) + 1);
16600 y = 60 * ((2 * i) + 1);
16601 color = getPixelColor(device, x, y);
16602 ok(color_match(color, expected[i * 4 + j], 1)
16603 || broken(color_match(color, expected_broken[i * 4 + j], 1)),
16604 "Expected color 0x%08x at %u, %u, got 0x%08x.\n", expected[i * 4 + j], x, y, color);
16608 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16609 ok(SUCCEEDED(hr), "Failed to present backbuffer, hr %#x.\n", hr);
16611 IDirect3DPixelShader9_Release(ps);
16612 IDirect3DVertexShader9_Release(vs);
16615 refcount = IDirect3DDevice9_Release(device);
16616 ok(!refcount, "Device has %u references left.\n", refcount);
16617 done:
16618 IDirect3D9_Release(d3d);
16619 DestroyWindow(window);
16622 static void fog_special_test(void)
16624 static const struct
16626 struct vec3 position;
16627 D3DCOLOR diffuse;
16629 quad[] =
16631 {{ -1.0f, -1.0f, 0.0f}, 0xff00ff00},
16632 {{ -1.0f, 1.0f, 0.0f}, 0xff00ff00},
16633 {{ 1.0f, -1.0f, 1.0f}, 0xff00ff00},
16634 {{ 1.0f, 1.0f, 1.0f}, 0xff00ff00}
16636 static const struct
16638 DWORD vertexmode, tablemode;
16639 BOOL vs, ps;
16640 D3DCOLOR color_left, color_right;
16642 tests[] =
16644 {D3DFOG_LINEAR, D3DFOG_NONE, FALSE, FALSE, 0x00ff0000, 0x00ff0000},
16645 {D3DFOG_LINEAR, D3DFOG_NONE, FALSE, TRUE, 0x00ff0000, 0x00ff0000},
16646 {D3DFOG_LINEAR, D3DFOG_NONE, TRUE, FALSE, 0x00ff0000, 0x00ff0000},
16647 {D3DFOG_LINEAR, D3DFOG_NONE, TRUE, TRUE, 0x00ff0000, 0x00ff0000},
16649 {D3DFOG_NONE, D3DFOG_LINEAR, FALSE, FALSE, 0x0000ff00, 0x00ff0000},
16650 {D3DFOG_NONE, D3DFOG_LINEAR, FALSE, TRUE, 0x0000ff00, 0x00ff0000},
16651 {D3DFOG_NONE, D3DFOG_LINEAR, TRUE, FALSE, 0x0000ff00, 0x00ff0000},
16652 {D3DFOG_NONE, D3DFOG_LINEAR, TRUE, TRUE, 0x0000ff00, 0x00ff0000},
16654 static const DWORD pixel_shader_code[] =
16656 0xffff0101, /* ps_1_1 */
16657 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
16658 0x0000ffff
16660 static const DWORD vertex_shader_code[] =
16662 0xfffe0101, /* vs_1_1 */
16663 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
16664 0x0000001f, 0x8000000a, 0x900f0001, /* dcl_color0 v1 */
16665 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
16666 0x00000001, 0xd00f0000, 0x90e40001, /* mov oD0, v1 */
16667 0x0000ffff
16669 static const D3DMATRIX identity =
16671 1.0f, 0.0f, 0.0f, 0.0f,
16672 0.0f, 1.0f, 0.0f, 0.0f,
16673 0.0f, 0.0f, 1.0f, 0.0f,
16674 0.0f, 0.0f, 0.0f, 1.0f,
16675 }}};
16676 union
16678 float f;
16679 DWORD d;
16680 } conv;
16681 DWORD color;
16682 HRESULT hr;
16683 unsigned int i;
16684 IDirect3DPixelShader9 *ps;
16685 IDirect3DVertexShader9 *vs;
16686 IDirect3DDevice9 *device;
16687 IDirect3D9 *d3d;
16688 ULONG refcount;
16689 D3DCAPS9 caps;
16690 HWND window;
16692 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
16693 0, 0, 640, 480, NULL, NULL, NULL, NULL);
16694 d3d = Direct3DCreate9(D3D_SDK_VERSION);
16695 ok(!!d3d, "Failed to create a D3D object.\n");
16696 if (!(device = create_device(d3d, window, window, TRUE)))
16698 skip("Failed to create a D3D device, skipping tests.\n");
16699 goto done;
16702 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
16703 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
16704 if (caps.VertexShaderVersion >= D3DVS_VERSION(1, 1))
16706 hr = IDirect3DDevice9_CreateVertexShader(device, vertex_shader_code, &vs);
16707 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x.\n", hr);
16709 else
16711 skip("Vertex Shaders not supported, skipping some fog tests.\n");
16712 vs = NULL;
16714 if (caps.PixelShaderVersion >= D3DPS_VERSION(1, 1))
16716 hr = IDirect3DDevice9_CreatePixelShader(device, pixel_shader_code, &ps);
16717 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
16719 else
16721 skip("Pixel Shaders not supported, skipping some fog tests.\n");
16722 ps = NULL;
16725 /* The table fog tests seem to depend on the projection matrix explicitly
16726 * being set to an identity matrix, even though that's the default.
16727 * (AMD Radeon HD 6310, Windows 7) */
16728 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &identity);
16729 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
16731 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
16732 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
16733 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
16734 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
16735 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
16736 ok(SUCCEEDED(hr), "Failed to enable fog, hr %#x.\n", hr);
16737 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0xffff0000);
16738 ok(SUCCEEDED(hr), "Failed to set fog color, hr %#x.\n", hr);
16740 conv.f = 0.5f;
16741 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, conv.d);
16742 ok(SUCCEEDED(hr), "Failed to set fog start, hr %#x.\n", hr);
16743 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, conv.d);
16744 ok(SUCCEEDED(hr), "Failed to set fog end, hr %#x.\n", hr);
16746 for (i = 0; i < sizeof(tests) / sizeof(*tests); i++)
16748 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xff0000ff, 1.0f, 0);
16749 ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
16751 if (!tests[i].vs)
16753 hr = IDirect3DDevice9_SetVertexShader(device, NULL);
16754 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
16756 else if (vs)
16758 hr = IDirect3DDevice9_SetVertexShader(device, vs);
16759 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
16761 else
16763 continue;
16766 if (!tests[i].ps)
16768 hr = IDirect3DDevice9_SetPixelShader(device, NULL);
16769 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
16771 else if (ps)
16773 hr = IDirect3DDevice9_SetPixelShader(device, ps);
16774 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
16776 else
16778 continue;
16781 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, tests[i].vertexmode);
16782 ok(SUCCEEDED(hr), "Failed to set fogvertexmode, hr %#x.\n", hr);
16783 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, tests[i].tablemode);
16784 ok(SUCCEEDED(hr), "Failed to set fogtablemode, hr %#x.\n", hr);
16786 hr = IDirect3DDevice9_BeginScene(device);
16787 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
16788 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16789 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
16790 hr = IDirect3DDevice9_EndScene(device);
16791 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
16793 color = getPixelColor(device, 310, 240);
16794 ok(color_match(color, tests[i].color_left, 1),
16795 "Expected left color 0x%08x, got 0x%08x, case %u.\n", tests[i].color_left, color, i);
16796 color = getPixelColor(device, 330, 240);
16797 ok(color_match(color, tests[i].color_right, 1),
16798 "Expected right color 0x%08x, got 0x%08x, case %u.\n", tests[i].color_right, color, i);
16800 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16801 ok(SUCCEEDED(hr), "Failed to present backbuffer, hr %#x.\n", hr);
16804 if (vs)
16805 IDirect3DVertexShader9_Release(vs);
16806 if (ps)
16807 IDirect3DPixelShader9_Release(ps);
16808 refcount = IDirect3DDevice9_Release(device);
16809 ok(!refcount, "Device has %u references left.\n", refcount);
16810 done:
16811 IDirect3D9_Release(d3d);
16812 DestroyWindow(window);
16815 static void volume_srgb_test(void)
16817 HRESULT hr;
16818 unsigned int i, j;
16819 IDirect3DVolumeTexture9 *tex1, *tex2;
16820 D3DPOOL pool;
16821 D3DLOCKED_BOX locked_box;
16822 IDirect3DDevice9 *device;
16823 IDirect3D9 *d3d;
16824 D3DCOLOR color;
16825 ULONG refcount;
16826 HWND window;
16828 static const struct
16830 BOOL srgb;
16831 DWORD color;
16833 tests[] =
16835 /* Try toggling on and off */
16836 { FALSE, 0x007f7f7f },
16837 { TRUE, 0x00363636 },
16838 { FALSE, 0x007f7f7f },
16840 static const struct
16842 struct vec3 pos;
16843 struct vec3 texcrd;
16845 quad[] =
16847 {{-1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}},
16848 {{-1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}},
16849 {{ 1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}},
16850 {{ 1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}},
16853 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
16854 0, 0, 640, 480, NULL, NULL, NULL, NULL);
16855 d3d = Direct3DCreate9(D3D_SDK_VERSION);
16856 ok(!!d3d, "Failed to create a D3D object.\n");
16857 if (IDirect3D9_CheckDeviceFormat(d3d, 0, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,
16858 D3DUSAGE_QUERY_SRGBREAD, D3DRTYPE_VOLUMETEXTURE, D3DFMT_A8R8G8B8) != D3D_OK)
16860 skip("D3DFMT_A8R8G8B8 volume textures with SRGBREAD not supported.\n");
16861 goto done;
16863 if (!(device = create_device(d3d, window, window, TRUE)))
16865 skip("Failed to create a D3D device, skipping tests.\n");
16866 goto done;
16869 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
16870 ok(SUCCEEDED(hr), "Failed to set color op 0, hr %#x.\n", hr);
16871 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
16872 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
16873 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
16874 ok(SUCCEEDED(hr), "Failed to set color op 0, hr %#x.\n", hr);
16875 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE3(0));
16876 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr);
16878 for (i = 0; i < 2; i++)
16880 if (!i)
16881 pool = D3DPOOL_SYSTEMMEM;
16882 else
16883 pool = D3DPOOL_MANAGED;
16885 hr = IDirect3DDevice9_CreateVolumeTexture(device, 1, 1, 1, 1, 0, D3DFMT_A8R8G8B8, pool, &tex1, NULL);
16886 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
16887 hr = IDirect3DVolumeTexture9_LockBox(tex1, 0, &locked_box, NULL, 0);
16888 ok(SUCCEEDED(hr), "Failed to lock volume texture, hr %#x.\n", hr);
16889 *((DWORD *)locked_box.pBits) = 0x7f7f7f7f;
16890 hr = IDirect3DVolumeTexture9_UnlockBox(tex1, 0);
16891 ok(SUCCEEDED(hr), "Failed to lock volume texture, hr %#x.\n", hr);
16893 if (!i)
16895 hr = IDirect3DDevice9_CreateVolumeTexture(device, 1, 1, 1, 1, 0,
16896 D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex2, NULL);
16897 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
16898 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex1, (IDirect3DBaseTexture9 *)tex2);
16899 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
16900 IDirect3DVolumeTexture9_Release(tex1);
16902 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex2);
16903 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
16904 IDirect3DVolumeTexture9_Release(tex2);
16906 else
16908 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex1);
16909 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
16910 IDirect3DVolumeTexture9_Release(tex1);
16913 for (j = 0; j < sizeof(tests) / sizeof(*tests); j++)
16915 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_SRGBTEXTURE, tests[j].srgb);
16916 ok(SUCCEEDED(hr), "Failed to set srgb state, hr %#x.\n", hr);
16918 hr = IDirect3DDevice9_BeginScene(device);
16919 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
16920 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
16921 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
16922 hr = IDirect3DDevice9_EndScene(device);
16923 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
16925 color = getPixelColor(device, 320, 240);
16926 ok(color_match(color, tests[j].color, 2),
16927 "Expected color 0x%08x, got 0x%08x, i = %u, j = %u.\n", tests[j].color, color, i, j);
16929 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
16930 ok(SUCCEEDED(hr), "Failed to present backbuffer, hr %#x.\n", hr);
16934 refcount = IDirect3DDevice9_Release(device);
16935 ok(!refcount, "Device has %u references left.\n", refcount);
16936 done:
16937 IDirect3D9_Release(d3d);
16938 DestroyWindow(window);
16941 static void volume_dxt5_test(void)
16943 IDirect3DVolumeTexture9 *texture;
16944 IDirect3DDevice9 *device;
16945 D3DLOCKED_BOX box;
16946 IDirect3D9 *d3d;
16947 unsigned int i;
16948 ULONG refcount;
16949 DWORD color;
16950 HWND window;
16951 HRESULT hr;
16953 static const char texture_data[] =
16955 /* A 8x4x2 texture consisting of 4 4x4 blocks. The colors of the blocks are red, green, blue and white. */
16956 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00,
16957 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00,
16958 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00,
16959 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00
16961 static const struct
16963 struct vec3 position;
16964 struct vec3 texcrd;
16966 quads[] =
16968 {{ -1.0f, -1.0f, 0.0f}, { 0.0f, 0.0f, 0.25f}},
16969 {{ -1.0f, 1.0f, 0.0f}, { 0.0f, 1.0f, 0.25f}},
16970 {{ 0.0f, -1.0f, 1.0f}, { 1.0f, 0.0f, 0.25f}},
16971 {{ 0.0f, 1.0f, 1.0f}, { 1.0f, 1.0f, 0.25f}},
16973 {{ 0.0f, -1.0f, 0.0f}, { 0.0f, 0.0f, 0.75f}},
16974 {{ 0.0f, 1.0f, 0.0f}, { 0.0f, 1.0f, 0.75f}},
16975 {{ 1.0f, -1.0f, 1.0f}, { 1.0f, 0.0f, 0.75f}},
16976 {{ 1.0f, 1.0f, 1.0f}, { 1.0f, 1.0f, 0.75f}},
16978 static const DWORD expected_colors[] = {0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff};
16980 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
16981 0, 0, 640, 480, NULL, NULL, NULL, NULL);
16982 d3d = Direct3DCreate9(D3D_SDK_VERSION);
16983 ok(!!d3d, "Failed to create a D3D object.\n");
16984 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
16985 D3DFMT_X8R8G8B8, 0, D3DRTYPE_VOLUMETEXTURE, D3DFMT_DXT5)))
16987 skip("DXT5 volume textures are not supported, skipping test.\n");
16988 goto done;
16990 if (!(device = create_device(d3d, window, window, TRUE)))
16992 skip("Failed to create a D3D device, skipping tests.\n");
16993 goto done;
16996 hr = IDirect3DDevice9_CreateVolumeTexture(device, 8, 4, 2, 1, 0, D3DFMT_DXT5,
16997 D3DPOOL_MANAGED, &texture, NULL);
16998 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
17000 hr = IDirect3DVolumeTexture9_LockBox(texture, 0, &box, NULL, 0);
17001 ok(SUCCEEDED(hr), "Failed to lock volume texture, hr %#x.\n", hr);
17002 memcpy(box.pBits, texture_data, sizeof(texture_data));
17003 hr = IDirect3DVolumeTexture9_UnlockBox(texture, 0);
17004 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#x.\n", hr);
17006 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE3(0));
17007 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
17008 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
17009 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
17010 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
17011 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
17012 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
17013 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
17014 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
17015 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
17016 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
17017 ok(SUCCEEDED(hr), "Failed to set mag filter, hr %#x.\n", hr);
17019 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff00ff, 1.0f, 0);
17020 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
17021 hr = IDirect3DDevice9_BeginScene(device);
17022 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
17023 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads));
17024 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
17025 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[4], sizeof(*quads));
17026 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
17027 hr = IDirect3DDevice9_EndScene(device);
17028 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
17030 for (i = 0; i < 4; i++)
17032 color = getPixelColor(device, 80 + 160 * i, 240);
17033 ok (color_match(color, expected_colors[i], 1),
17034 "Expected color 0x%08x, got 0x%08x, case %u.\n", expected_colors[i], color, i);
17037 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17038 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17039 IDirect3DVolumeTexture9_Release(texture);
17040 refcount = IDirect3DDevice9_Release(device);
17041 ok(!refcount, "Device has %u references left.\n", refcount);
17042 done:
17043 IDirect3D9_Release(d3d);
17044 DestroyWindow(window);
17047 static void volume_v16u16_test(void)
17049 IDirect3DVolumeTexture9 *texture;
17050 IDirect3DPixelShader9 *shader;
17051 IDirect3DDevice9 *device;
17052 D3DLOCKED_BOX box;
17053 IDirect3D9 *d3d;
17054 unsigned int i;
17055 ULONG refcount;
17056 D3DCAPS9 caps;
17057 SHORT *texel;
17058 DWORD color;
17059 HWND window;
17060 HRESULT hr;
17062 static const struct
17064 struct vec3 position;
17065 struct vec3 texcrd;
17067 quads[] =
17069 {{ -1.0f, -1.0f, 0.0f}, { 0.0f, 0.0f, 0.25f}},
17070 {{ -1.0f, 1.0f, 0.0f}, { 0.0f, 1.0f, 0.25f}},
17071 {{ 0.0f, -1.0f, 1.0f}, { 1.0f, 0.0f, 0.25f}},
17072 {{ 0.0f, 1.0f, 1.0f}, { 1.0f, 1.0f, 0.25f}},
17074 {{ 0.0f, -1.0f, 0.0f}, { 0.0f, 0.0f, 0.75f}},
17075 {{ 0.0f, 1.0f, 0.0f}, { 0.0f, 1.0f, 0.75f}},
17076 {{ 1.0f, -1.0f, 1.0f}, { 1.0f, 0.0f, 0.75f}},
17077 {{ 1.0f, 1.0f, 1.0f}, { 1.0f, 1.0f, 0.75f}},
17079 static const DWORD shader_code[] =
17081 0xffff0101, /* ps_1_1 */
17082 0x00000051, 0xa00f0000, 0x3f000000, 0x3f000000, /* def c0, 0.5, 0.5, */
17083 0x3f000000, 0x3f000000, /* 0.5, 0.5 */
17084 0x00000042, 0xb00f0000, /* tex t0 */
17085 0x00000004, 0x800f0000, 0xb0e40000, 0xa0e40000, 0xa0e40000, /* mad r0, t0, c0, c0 */
17086 0x0000ffff /* end */
17089 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
17090 0, 0, 640, 480, NULL, NULL, NULL, NULL);
17091 d3d = Direct3DCreate9(D3D_SDK_VERSION);
17092 ok(!!d3d, "Failed to create a D3D object.\n");
17093 if (!(device = create_device(d3d, window, window, TRUE)))
17095 skip("Failed to create a D3D device, skipping tests.\n");
17096 goto done;
17099 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
17100 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
17101 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 1))
17103 skip("No ps_1_1 support, skipping tests.\n");
17104 IDirect3DDevice9_Release(device);
17105 goto done;
17107 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
17108 D3DFMT_X8R8G8B8, 0, D3DRTYPE_VOLUMETEXTURE, D3DFMT_V16U16)))
17110 skip("Volume V16U16 textures are not supported, skipping test.\n");
17111 IDirect3DDevice9_Release(device);
17112 goto done;
17115 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE3(0));
17116 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
17117 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
17118 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
17119 hr = IDirect3DDevice9_SetPixelShader(device, shader);
17120 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
17121 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
17122 ok(SUCCEEDED(hr), "Failed to set filter, hr %#x.\n", hr);
17124 for (i = 0; i < 2; i++)
17126 D3DPOOL pool;
17128 if (i)
17129 pool = D3DPOOL_SYSTEMMEM;
17130 else
17131 pool = D3DPOOL_MANAGED;
17133 hr = IDirect3DDevice9_CreateVolumeTexture(device, 1, 2, 2, 1, 0, D3DFMT_V16U16,
17134 pool, &texture, NULL);
17135 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
17137 hr = IDirect3DVolumeTexture9_LockBox(texture, 0, &box, NULL, 0);
17138 ok(SUCCEEDED(hr), "Failed to lock volume texture, hr %#x.\n", hr);
17140 texel = (SHORT *)((BYTE *)box.pBits + 0 * box.RowPitch + 0 * box.SlicePitch);
17141 texel[0] = 32767;
17142 texel[1] = 32767;
17143 texel = (SHORT *)((BYTE *)box.pBits + 1 * box.RowPitch + 0 * box.SlicePitch);
17144 texel[0] = -32768;
17145 texel[1] = 0;
17146 texel = (SHORT *)((BYTE *)box.pBits + 0 * box.RowPitch + 1 * box.SlicePitch);
17147 texel[0] = -16384;
17148 texel[1] = 16384;
17149 texel = (SHORT *)((BYTE *)box.pBits + 1 * box.RowPitch + 1 * box.SlicePitch);
17150 texel[0] = 0;
17151 texel[1] = 0;
17153 hr = IDirect3DVolumeTexture9_UnlockBox(texture, 0);
17154 ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#x.\n", hr);
17156 if (i)
17158 IDirect3DVolumeTexture9 *texture2;
17160 hr = IDirect3DDevice9_CreateVolumeTexture(device, 1, 2, 2, 1, 0, D3DFMT_V16U16,
17161 D3DPOOL_DEFAULT, &texture2, NULL);
17162 ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
17164 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)texture,
17165 (IDirect3DBaseTexture9 *)texture2);
17166 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17168 IDirect3DVolumeTexture9_Release(texture);
17169 texture = texture2;
17172 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *) texture);
17173 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
17175 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff00ff, 1.0f, 0);
17176 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
17177 hr = IDirect3DDevice9_BeginScene(device);
17178 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
17179 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads));
17180 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
17181 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[4], sizeof(*quads));
17182 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
17183 hr = IDirect3DDevice9_EndScene(device);
17184 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
17186 color = getPixelColor(device, 120, 160);
17187 ok (color_match(color, 0x000080ff, 2),
17188 "Expected color 0x000080ff, got 0x%08x, V16U16 input -32768, 0.\n", color);
17189 color = getPixelColor(device, 120, 400);
17190 ok (color_match(color, 0x00ffffff, 2),
17191 "Expected color 0x00ffffff, got 0x%08x, V16U16 input 32767, 32767.\n", color);
17192 color = getPixelColor(device, 360, 160);
17193 ok (color_match(color, 0x007f7fff, 2),
17194 "Expected color 0x007f7fff, got 0x%08x, V16U16 input 0, 0.\n", color);
17195 color = getPixelColor(device, 360, 400);
17196 ok (color_match(color, 0x0040c0ff, 2),
17197 "Expected color 0x0040c0ff, got 0x%08x, V16U16 input -16384, 16384.\n", color);
17199 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17200 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17202 IDirect3DVolumeTexture9_Release(texture);
17205 IDirect3DPixelShader9_Release(shader);
17206 refcount = IDirect3DDevice9_Release(device);
17207 ok(!refcount, "Device has %u references left.\n", refcount);
17208 done:
17209 IDirect3D9_Release(d3d);
17210 DestroyWindow(window);
17213 static void add_dirty_rect_test_draw(IDirect3DDevice9 *device)
17215 HRESULT hr;
17216 static const struct
17218 struct vec3 position;
17219 struct vec2 texcoord;
17221 quad[] =
17223 {{-1.0, -1.0, 0.0}, {0.0, 0.0}},
17224 {{-1.0, 1.0, 0.0}, {0.0, 1.0}},
17225 {{ 1.0, -1.0, 0.0}, {1.0, 0.0}},
17226 {{ 1.0, 1.0, 0.0}, {1.0, 1.0}},
17229 hr = IDirect3DDevice9_BeginScene(device);
17230 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
17231 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad, sizeof(*quad));
17232 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
17233 hr = IDirect3DDevice9_EndScene(device);
17234 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
17237 static void add_dirty_rect_test(void)
17239 HRESULT hr;
17240 IDirect3DTexture9 *tex_dst1, *tex_dst2, *tex_src_red, *tex_src_green, *tex_managed;
17241 IDirect3DSurface9 *surface_dst2, *surface_src_green, *surface_src_red, *surface_managed;
17242 IDirect3DDevice9 *device;
17243 IDirect3D9 *d3d;
17244 unsigned int i;
17245 ULONG refcount;
17246 DWORD *texel;
17247 HWND window;
17248 D3DLOCKED_RECT locked_rect;
17249 static const RECT part_rect = {96, 96, 160, 160};
17250 DWORD color;
17252 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
17253 0, 0, 640, 480, NULL, NULL, NULL, NULL);
17254 d3d = Direct3DCreate9(D3D_SDK_VERSION);
17255 ok(!!d3d, "Failed to create a D3D object.\n");
17256 if (!(device = create_device(d3d, window, window, TRUE)))
17258 skip("Failed to create a D3D device, skipping tests.\n");
17259 IDirect3D9_Release(d3d);
17260 DestroyWindow(window);
17261 return;
17264 hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 1, 0, D3DFMT_X8R8G8B8,
17265 D3DPOOL_DEFAULT, &tex_dst1, NULL);
17266 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
17267 hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 1, 0, D3DFMT_X8R8G8B8,
17268 D3DPOOL_DEFAULT, &tex_dst2, NULL);
17269 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
17270 hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 1, 0, D3DFMT_X8R8G8B8,
17271 D3DPOOL_SYSTEMMEM, &tex_src_red, NULL);
17272 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
17273 hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 1, 0, D3DFMT_X8R8G8B8,
17274 D3DPOOL_SYSTEMMEM, &tex_src_green, NULL);
17275 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
17276 hr = IDirect3DDevice9_CreateTexture(device, 256, 256, 1, 0, D3DFMT_X8R8G8B8,
17277 D3DPOOL_MANAGED, &tex_managed, NULL);
17278 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
17280 hr = IDirect3DTexture9_GetSurfaceLevel(tex_dst2, 0, &surface_dst2);
17281 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
17282 hr = IDirect3DTexture9_GetSurfaceLevel(tex_src_green, 0, &surface_src_green);
17283 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
17284 hr = IDirect3DTexture9_GetSurfaceLevel(tex_src_red, 0, &surface_src_red);
17285 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
17286 hr = IDirect3DTexture9_GetSurfaceLevel(tex_managed, 0, &surface_managed);
17287 ok(SUCCEEDED(hr), "Failed to get surface level, hr %#x.\n", hr);
17289 fill_surface(surface_src_red, 0x00ff0000, 0);
17290 fill_surface(surface_src_green, 0x0000ff00, 0);
17292 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
17293 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr);
17294 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
17295 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
17296 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
17297 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
17299 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
17300 (IDirect3DBaseTexture9 *)tex_dst1);
17301 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17303 /* The second UpdateTexture call writing to tex_dst2 is ignored because tex_src_green is not dirty. */
17304 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_red,
17305 (IDirect3DBaseTexture9 *)tex_dst2);
17306 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17307 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
17308 (IDirect3DBaseTexture9 *)tex_dst2);
17309 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17311 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex_dst1);
17312 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
17313 add_dirty_rect_test_draw(device);
17314 color = getPixelColor(device, 320, 240);
17315 ok(color_match(color, 0x0000ff00, 1),
17316 "Expected color 0x0000ff00, got 0x%08x.\n", color);
17317 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17318 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17320 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex_dst2);
17321 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
17322 add_dirty_rect_test_draw(device);
17323 color = getPixelColor(device, 320, 240);
17324 todo_wine ok(color_match(color, 0x00ff0000, 1),
17325 "Expected color 0x00ff0000, got 0x%08x.\n", color);
17326 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17327 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17329 /* AddDirtyRect on the destination is ignored. */
17330 hr = IDirect3DTexture9_AddDirtyRect(tex_dst2, &part_rect);
17331 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
17332 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
17333 (IDirect3DBaseTexture9 *)tex_dst2);
17334 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17335 add_dirty_rect_test_draw(device);
17336 color = getPixelColor(device, 320, 240);
17337 todo_wine ok(color_match(color, 0x00ff0000, 1),
17338 "Expected color 0x00ff0000, got 0x%08x.\n", color);
17339 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17340 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17342 hr = IDirect3DTexture9_AddDirtyRect(tex_dst2, NULL);
17343 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
17344 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
17345 (IDirect3DBaseTexture9 *)tex_dst2);
17346 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17347 add_dirty_rect_test_draw(device);
17348 color = getPixelColor(device, 320, 240);
17349 todo_wine ok(color_match(color, 0x00ff0000, 1),
17350 "Expected color 0x00ff0000, got 0x%08x.\n", color);
17351 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17352 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17354 /* AddDirtyRect on the source makes UpdateTexture work. Partial rectangle
17355 * tracking is supported. */
17356 hr = IDirect3DTexture9_AddDirtyRect(tex_src_green, &part_rect);
17357 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
17358 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
17359 (IDirect3DBaseTexture9 *)tex_dst2);
17360 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17361 add_dirty_rect_test_draw(device);
17362 color = getPixelColor(device, 320, 240);
17363 ok(color_match(color, 0x0000ff00, 1),
17364 "Expected color 0x0000ff00, got 0x%08x.\n", color);
17365 color = getPixelColor(device, 1, 1);
17366 todo_wine ok(color_match(color, 0x00ff0000, 1),
17367 "Expected color 0x00ff0000, got 0x%08x.\n", color);
17368 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17369 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17371 hr = IDirect3DTexture9_AddDirtyRect(tex_src_green, NULL);
17372 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
17373 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
17374 (IDirect3DBaseTexture9 *)tex_dst2);
17375 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17376 add_dirty_rect_test_draw(device);
17377 color = getPixelColor(device, 1, 1);
17378 ok(color_match(color, 0x0000ff00, 1),
17379 "Expected color 0x0000ff00, got 0x%08x.\n", color);
17381 /* Locks with NO_DIRTY_UPDATE are ignored. */
17382 fill_surface(surface_src_green, 0x00000080, D3DLOCK_NO_DIRTY_UPDATE);
17383 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
17384 (IDirect3DBaseTexture9 *)tex_dst2);
17385 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17386 add_dirty_rect_test_draw(device);
17387 color = getPixelColor(device, 320, 240);
17388 todo_wine ok(color_match(color, 0x0000ff00, 1),
17389 "Expected color 0x0000ff00, got 0x%08x.\n", color);
17390 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17391 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17393 /* Readonly maps write to D3DPOOL_SYSTEMMEM, but don't record a dirty rectangle. */
17394 fill_surface(surface_src_green, 0x000000ff, D3DLOCK_READONLY);
17395 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
17396 (IDirect3DBaseTexture9 *)tex_dst2);
17397 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17398 add_dirty_rect_test_draw(device);
17399 color = getPixelColor(device, 320, 240);
17400 todo_wine ok(color_match(color, 0x0000ff00, 1),
17401 "Expected color 0x0000ff00, got 0x%08x.\n", color);
17402 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17403 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17405 hr = IDirect3DTexture9_AddDirtyRect(tex_src_green, NULL);
17406 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
17407 (IDirect3DBaseTexture9 *)tex_dst2);
17408 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17409 add_dirty_rect_test_draw(device);
17410 color = getPixelColor(device, 320, 240);
17411 ok(color_match(color, 0x000000ff, 1),
17412 "Expected color 0x000000ff, got 0x%08x.\n", color);
17413 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17414 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17416 /* Maps without either of these flags record a dirty rectangle. */
17417 fill_surface(surface_src_green, 0x00ffffff, 0);
17418 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
17419 (IDirect3DBaseTexture9 *)tex_dst2);
17420 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17421 add_dirty_rect_test_draw(device);
17422 color = getPixelColor(device, 320, 240);
17423 ok(color_match(color, 0x00ffffff, 1),
17424 "Expected color 0x00ffffff, got 0x%08x.\n", color);
17425 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17426 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17428 /* Partial LockRect works just like a partial AddDirtyRect call. */
17429 hr = IDirect3DTexture9_LockRect(tex_src_green, 0, &locked_rect, &part_rect, 0);
17430 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
17431 texel = locked_rect.pBits;
17432 for (i = 0; i < 64; i++)
17433 texel[i] = 0x00ff00ff;
17434 for (i = 1; i < 64; i++)
17435 memcpy((BYTE *)locked_rect.pBits + i * locked_rect.Pitch, locked_rect.pBits, locked_rect.Pitch);
17436 hr = IDirect3DTexture9_UnlockRect(tex_src_green, 0);
17437 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
17438 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
17439 (IDirect3DBaseTexture9 *)tex_dst2);
17440 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17441 add_dirty_rect_test_draw(device);
17442 color = getPixelColor(device, 320, 240);
17443 ok(color_match(color, 0x00ff00ff, 1),
17444 "Expected color 0x00ff00ff, got 0x%08x.\n", color);
17445 color = getPixelColor(device, 1, 1);
17446 ok(color_match(color, 0x00ffffff, 1),
17447 "Expected color 0x00ffffff, got 0x%08x.\n", color);
17448 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17449 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17451 fill_surface(surface_src_red, 0x00ff0000, 0);
17452 fill_surface(surface_src_green, 0x0000ff00, 0);
17454 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_green,
17455 (IDirect3DBaseTexture9 *)tex_dst1);
17456 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
17457 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex_dst1);
17458 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
17459 add_dirty_rect_test_draw(device);
17460 color = getPixelColor(device, 320, 240);
17461 ok(color_match(color, 0x0000ff00, 1),
17462 "Expected color 0x0000ff00, got 0x%08x.\n", color);
17463 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17464 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17466 /* UpdateSurface ignores the missing dirty marker. */
17467 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)tex_src_red,
17468 (IDirect3DBaseTexture9 *)tex_dst2);
17469 hr = IDirect3DDevice9_UpdateSurface(device, surface_src_green, NULL, surface_dst2, NULL);
17470 ok(SUCCEEDED(hr), "Failed to update surface, hr %#x.\n", hr);
17471 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex_dst2);
17472 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
17473 add_dirty_rect_test_draw(device);
17474 color = getPixelColor(device, 320, 240);
17475 ok(color_match(color, 0x0000ff00, 1),
17476 "Expected color 0x0000ff00, got 0x%08x.\n", color);
17477 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17478 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17480 fill_surface(surface_managed, 0x00ff0000, 0);
17481 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)tex_managed);
17482 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
17483 add_dirty_rect_test_draw(device);
17484 color = getPixelColor(device, 320, 240);
17485 ok(color_match(color, 0x00ff0000, 1),
17486 "Expected color 0x00ff0000, got 0x%08x.\n", color);
17487 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17488 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17490 /* Managed textures also honor D3DLOCK_NO_DIRTY_UPDATE. */
17491 fill_surface(surface_managed, 0x0000ff00, D3DLOCK_NO_DIRTY_UPDATE);
17492 add_dirty_rect_test_draw(device);
17493 color = getPixelColor(device, 320, 240);
17494 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 /* AddDirtyRect uploads the new contents.
17500 * Side note, not tested in the test: Partial surface updates work, and two separate
17501 * dirty rectangles are tracked individually. Tested on Nvidia Kepler, other drivers
17502 * untested. */
17503 hr = IDirect3DTexture9_AddDirtyRect(tex_managed, NULL);
17504 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
17505 add_dirty_rect_test_draw(device);
17506 color = getPixelColor(device, 320, 240);
17507 ok(color_match(color, 0x0000ff00, 1),
17508 "Expected color 0x0000ff00, got 0x%08x.\n", color);
17509 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17510 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17512 /* So does EvictManagedResources. */
17513 fill_surface(surface_managed, 0x000000ff, D3DLOCK_NO_DIRTY_UPDATE);
17514 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
17515 hr = IDirect3DDevice9_EvictManagedResources(device);
17516 ok(SUCCEEDED(hr), "Failed to evict managed resources, hr %#x.\n", hr);
17517 add_dirty_rect_test_draw(device);
17518 color = getPixelColor(device, 320, 240);
17519 ok(color_match(color, 0x000000ff, 1),
17520 "Expected color 0x000000ff, got 0x%08x.\n", color);
17521 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17522 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17524 /* AddDirtyRect on a locked texture is allowed. */
17525 hr = IDirect3DTexture9_LockRect(tex_src_red, 0, &locked_rect, NULL, 0);
17526 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
17527 hr = IDirect3DTexture9_AddDirtyRect(tex_src_red, NULL);
17528 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
17529 hr = IDirect3DTexture9_UnlockRect(tex_src_red, 0);
17530 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
17532 /* Redundant AddDirtyRect calls are ok. */
17533 hr = IDirect3DTexture9_AddDirtyRect(tex_managed, NULL);
17534 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
17535 hr = IDirect3DTexture9_AddDirtyRect(tex_managed, NULL);
17536 ok(SUCCEEDED(hr), "Failed to add dirty rect, hr %#x.\n", hr);
17538 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_DISABLE);
17539 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
17540 hr = IDirect3DDevice9_SetTexture(device, 0, NULL);
17541 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
17542 IDirect3DSurface9_Release(surface_dst2);
17543 IDirect3DSurface9_Release(surface_managed);
17544 IDirect3DSurface9_Release(surface_src_red);
17545 IDirect3DSurface9_Release(surface_src_green);
17546 IDirect3DTexture9_Release(tex_src_red);
17547 IDirect3DTexture9_Release(tex_src_green);
17548 IDirect3DTexture9_Release(tex_dst1);
17549 IDirect3DTexture9_Release(tex_dst2);
17550 IDirect3DTexture9_Release(tex_managed);
17551 refcount = IDirect3DDevice9_Release(device);
17552 ok(!refcount, "Device has %u references left.\n", refcount);
17553 IDirect3D9_Release(d3d);
17554 DestroyWindow(window);
17557 static void test_per_stage_constant(void)
17559 IDirect3DDevice9 *device;
17560 IDirect3D9 *d3d;
17561 D3DCOLOR color;
17562 ULONG refcount;
17563 D3DCAPS9 caps;
17564 HWND window;
17565 HRESULT hr;
17567 static const struct
17569 struct vec3 position;
17570 D3DCOLOR diffuse;
17572 quad[] =
17574 {{-1.0f, -1.0f, 0.1f}, 0xffff0000},
17575 {{-1.0f, 1.0f, 0.1f}, 0xffff0000},
17576 {{ 1.0f, -1.0f, 0.1f}, 0xffff0000},
17577 {{ 1.0f, 1.0f, 0.1f}, 0xffff0000},
17580 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
17581 0, 0, 640, 480, NULL, NULL, NULL, NULL);
17582 d3d = Direct3DCreate9(D3D_SDK_VERSION);
17583 ok(!!d3d, "Failed to create a D3D object.\n");
17584 if (!(device = create_device(d3d, window, window, TRUE)))
17586 skip("Failed to create a D3D device, skipping tests.\n");
17587 goto done;
17590 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
17591 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
17592 if (!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_PERSTAGECONSTANT))
17594 skip("Per-stage constants not supported, skipping tests.\n");
17595 IDirect3DDevice9_Release(device);
17596 goto done;
17599 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
17600 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
17601 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ALPHABLENDENABLE, TRUE);
17602 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
17603 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
17604 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
17605 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
17606 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
17607 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
17608 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
17610 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_CONSTANT, 0x80a1b2c3);
17611 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
17612 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_CONSTANT);
17613 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
17614 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
17615 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
17617 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
17618 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
17620 hr = IDirect3DDevice9_BeginScene(device);
17621 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
17622 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
17623 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
17624 hr = IDirect3DDevice9_EndScene(device);
17625 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
17627 color = getPixelColor(device, 320, 240);
17628 ok(color_match(color, 0x00a1b2c3, 1), "Got unexpected color 0x%08x.\n", color);
17629 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17630 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17632 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_CONSTANT | D3DTA_COMPLEMENT);
17633 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
17635 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
17636 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
17638 hr = IDirect3DDevice9_BeginScene(device);
17639 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
17640 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
17641 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
17642 hr = IDirect3DDevice9_EndScene(device);
17643 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
17645 color = getPixelColor(device, 320, 240);
17646 ok(color_match(color, 0x005e4d3c, 1), "Got unexpected color 0x%08x.\n", color);
17647 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17648 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17650 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_CONSTANT | D3DTA_ALPHAREPLICATE);
17651 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
17653 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
17654 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
17656 hr = IDirect3DDevice9_BeginScene(device);
17657 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
17658 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
17659 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
17660 hr = IDirect3DDevice9_EndScene(device);
17661 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
17663 color = getPixelColor(device, 320, 240);
17664 ok(color_match(color, 0x00808080, 1), "Got unexpected color 0x%08x.\n", color);
17665 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17666 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17668 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_CONSTANT);
17669 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
17670 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
17671 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
17672 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_CURRENT);
17673 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
17675 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
17676 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
17678 hr = IDirect3DDevice9_BeginScene(device);
17679 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
17680 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
17681 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
17682 hr = IDirect3DDevice9_EndScene(device);
17683 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
17685 color = getPixelColor(device, 320, 240);
17686 ok(color_match(color, 0x0080007f, 1), "Got unexpected color 0x%08x.\n", color);
17687 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17688 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17690 refcount = IDirect3DDevice9_Release(device);
17691 ok(!refcount, "Device has %u references left.\n", refcount);
17692 done:
17693 IDirect3D9_Release(d3d);
17694 DestroyWindow(window);
17697 static void test_3dc_formats(void)
17699 static const char ati1n_data[] =
17701 /* A 4x4 texture with the color component at 50%. */
17702 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
17704 static const char ati2n_data[] =
17706 /* A 8x4 texture consisting of 2 4x4 blocks. The first block has 50% first color component,
17707 * 0% second component. Second block is the opposite. */
17708 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
17709 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
17711 static const struct
17713 struct vec3 position;
17714 struct vec2 texcoord;
17716 quads[] =
17718 {{-1.0f, -1.0f, 0.0f}, {0.0f, 0.0f}},
17719 {{-1.0f, 1.0f, 0.0f}, {0.0f, 1.0f}},
17720 {{ 0.0f, -1.0f, 1.0f}, {1.0f, 0.0f}},
17721 {{ 0.0f, 1.0f, 1.0f}, {1.0f, 1.0f}},
17723 {{ 0.0f, -1.0f, 0.0f}, {0.0f, 0.0f}},
17724 {{ 0.0f, 1.0f, 0.0f}, {0.0f, 1.0f}},
17725 {{ 1.0f, -1.0f, 1.0f}, {1.0f, 0.0f}},
17726 {{ 1.0f, 1.0f, 1.0f}, {1.0f, 1.0f}},
17728 static const DWORD ati1n_fourcc = MAKEFOURCC('A','T','I','1');
17729 static const DWORD ati2n_fourcc = MAKEFOURCC('A','T','I','2');
17730 static const struct
17732 struct vec2 position;
17733 D3DCOLOR amd_r500;
17734 D3DCOLOR amd_r600;
17735 D3DCOLOR nvidia_old;
17736 D3DCOLOR nvidia_new;
17738 expected_colors[] =
17740 {{ 80, 240}, 0x007fffff, 0x003f3f3f, 0x007f7f7f, 0x007f0000},
17741 {{240, 240}, 0x007fffff, 0x003f3f3f, 0x007f7f7f, 0x007f0000},
17742 {{400, 240}, 0x00007fff, 0x00007fff, 0x00007fff, 0x00007fff},
17743 {{560, 240}, 0x007f00ff, 0x007f00ff, 0x007f00ff, 0x007f00ff},
17745 IDirect3D9 *d3d;
17746 IDirect3DDevice9 *device;
17747 IDirect3DTexture9 *ati1n_texture, *ati2n_texture;
17748 D3DCAPS9 caps;
17749 D3DLOCKED_RECT rect;
17750 D3DCOLOR color;
17751 ULONG refcount;
17752 HWND window;
17753 HRESULT hr;
17754 unsigned int i;
17756 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
17757 0, 0, 640, 480, NULL, NULL, NULL, NULL);
17758 d3d = Direct3DCreate9(D3D_SDK_VERSION);
17759 ok(!!d3d, "Failed to create a D3D object.\n");
17760 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
17761 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, ati1n_fourcc)))
17763 skip("ATI1N textures are not supported, skipping test.\n");
17764 goto done;
17766 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
17767 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, ati2n_fourcc)))
17769 skip("ATI2N textures are not supported, skipping test.\n");
17770 goto done;
17772 if (!(device = create_device(d3d, window, window, TRUE)))
17774 skip("Failed to create a D3D device, skipping tests.\n");
17775 goto done;
17777 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
17778 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
17779 if (!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_TSSARGTEMP))
17781 skip("D3DTA_TEMP not supported, skipping tests.\n");
17782 IDirect3DDevice9_Release(device);
17783 goto done;
17786 hr = IDirect3DDevice9_CreateTexture(device, 4, 4, 1, 0, ati1n_fourcc,
17787 D3DPOOL_MANAGED, &ati1n_texture, NULL);
17788 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
17790 hr = IDirect3DTexture9_LockRect(ati1n_texture, 0, &rect, NULL, 0);
17791 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
17792 memcpy(rect.pBits, ati1n_data, sizeof(ati1n_data));
17793 hr = IDirect3DTexture9_UnlockRect(ati1n_texture, 0);
17794 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
17796 hr = IDirect3DDevice9_CreateTexture(device, 8, 4, 1, 0, ati2n_fourcc,
17797 D3DPOOL_MANAGED, &ati2n_texture, NULL);
17798 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
17800 hr = IDirect3DTexture9_LockRect(ati2n_texture, 0, &rect, NULL, 0);
17801 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
17802 memcpy(rect.pBits, ati2n_data, sizeof(ati2n_data));
17803 hr = IDirect3DTexture9_UnlockRect(ati2n_texture, 0);
17804 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
17806 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE2(0));
17807 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
17808 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_BLENDTEXTUREALPHA);
17809 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
17810 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
17811 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
17812 /* The temporary register is initialized to 0. */
17813 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG2, D3DTA_TEMP);
17814 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
17815 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
17816 ok(SUCCEEDED(hr), "Failed to set alpha op, hr %#x.\n", hr);
17817 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
17818 ok(SUCCEEDED(hr), "Failed to set alpha arg, hr %#x.\n", hr);
17819 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
17820 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
17821 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
17822 ok(SUCCEEDED(hr), "Failed to set mag filter, hr %#x.\n", hr);
17824 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff00ff, 1.0f, 0);
17825 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
17826 hr = IDirect3DDevice9_BeginScene(device);
17827 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
17828 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)ati1n_texture);
17829 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
17830 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads));
17831 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
17832 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)ati2n_texture);
17833 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
17834 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[4], sizeof(*quads));
17835 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
17836 hr = IDirect3DDevice9_EndScene(device);
17837 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
17839 for (i = 0; i < 4; ++i)
17841 color = getPixelColor(device, expected_colors[i].position.x, expected_colors[i].position.y);
17842 ok (color_match(color, expected_colors[i].amd_r500, 1)
17843 || color_match(color, expected_colors[i].amd_r600, 1)
17844 || color_match(color, expected_colors[i].nvidia_old, 1)
17845 || color_match(color, expected_colors[i].nvidia_new, 1),
17846 "Got unexpected color 0x%08x, case %u.\n", color, i);
17849 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17850 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17851 IDirect3DTexture9_Release(ati2n_texture);
17852 IDirect3DTexture9_Release(ati1n_texture);
17853 refcount = IDirect3DDevice9_Release(device);
17854 ok(!refcount, "Device has %u references left.\n", refcount);
17856 done:
17857 IDirect3D9_Release(d3d);
17858 DestroyWindow(window);
17861 static void test_fog_interpolation(void)
17863 HRESULT hr;
17864 IDirect3DDevice9 *device;
17865 IDirect3D9 *d3d;
17866 ULONG refcount;
17867 HWND window;
17868 D3DCOLOR color;
17869 static const struct
17871 struct vec3 position;
17872 D3DCOLOR diffuse;
17873 D3DCOLOR specular;
17875 quad[] =
17877 {{-1.0f, -1.0f, 0.0f}, 0xffff0000, 0xff000000},
17878 {{-1.0f, 1.0f, 0.0f}, 0xffff0000, 0xff000000},
17879 {{ 1.0f, -1.0f, 1.0f}, 0xffff0000, 0x00000000},
17880 {{ 1.0f, 1.0f, 1.0f}, 0xffff0000, 0x00000000},
17882 union
17884 DWORD d;
17885 float f;
17886 } conv;
17887 unsigned int i;
17888 static const struct
17890 D3DFOGMODE vfog, tfog;
17891 D3DSHADEMODE shade;
17892 D3DCOLOR middle_color;
17893 BOOL todo;
17895 tests[] =
17897 {D3DFOG_NONE, D3DFOG_NONE, D3DSHADE_FLAT, 0x00007f80, FALSE},
17898 {D3DFOG_NONE, D3DFOG_NONE, D3DSHADE_GOURAUD, 0x00007f80, FALSE},
17899 {D3DFOG_EXP, D3DFOG_NONE, D3DSHADE_FLAT, 0x00007f80, TRUE},
17900 {D3DFOG_EXP, D3DFOG_NONE, D3DSHADE_GOURAUD, 0x00007f80, TRUE},
17901 {D3DFOG_NONE, D3DFOG_EXP, D3DSHADE_FLAT, 0x0000ea15, FALSE},
17902 {D3DFOG_NONE, D3DFOG_EXP, D3DSHADE_GOURAUD, 0x0000ea15, FALSE},
17903 {D3DFOG_EXP, D3DFOG_EXP, D3DSHADE_FLAT, 0x0000ea15, FALSE},
17904 {D3DFOG_EXP, D3DFOG_EXP, D3DSHADE_GOURAUD, 0x0000ea15, FALSE},
17906 static const D3DMATRIX ident_mat =
17908 1.0f, 0.0f, 0.0f, 0.0f,
17909 0.0f, 1.0f, 0.0f, 0.0f,
17910 0.0f, 0.0f, 1.0f, 0.0f,
17911 0.0f, 0.0f, 0.0f, 1.0f
17912 }}};
17913 D3DCAPS9 caps;
17915 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
17916 0, 0, 640, 480, NULL, NULL, NULL, NULL);
17917 d3d = Direct3DCreate9(D3D_SDK_VERSION);
17918 ok(!!d3d, "Failed to create a D3D object.\n");
17920 if (!(device = create_device(d3d, window, window, TRUE)))
17922 skip("Failed to create a D3D device, skipping tests.\n");
17923 IDirect3D9_Release(d3d);
17924 DestroyWindow(window);
17925 return;
17928 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
17929 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
17930 if (!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE))
17931 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping some fog tests\n");
17933 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR);
17934 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr);
17935 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
17936 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
17937 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
17938 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
17939 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
17940 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
17941 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0x0000ff00);
17942 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
17943 conv.f = 5.0;
17944 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGDENSITY, conv.d);
17945 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
17947 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
17948 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
17949 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TFACTOR);
17950 ok(SUCCEEDED(hr), "Failed to set texture stage state, hr %#x.\n", hr);
17951 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x000000ff);
17952 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
17954 /* Some of the tests seem to depend on the projection matrix explicitly
17955 * being set to an identity matrix, even though that's the default.
17956 * (AMD Radeon X1600, AMD Radeon HD 6310, Windows 7). Without this,
17957 * the drivers seem to use a static z = 1.0 input for the fog equation.
17958 * The input value is independent of the actual z and w component of
17959 * the vertex position. */
17960 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &ident_mat);
17961 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
17963 for (i = 0; i < sizeof(tests) / sizeof(*tests); i++)
17965 if(!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE) && tests[i].tfog)
17966 continue;
17968 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00808080, 0.0f, 0);
17969 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
17971 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_SHADEMODE, tests[i].shade);
17972 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
17973 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, tests[i].vfog);
17974 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
17975 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, tests[i].tfog);
17976 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
17977 hr = IDirect3DDevice9_BeginScene(device);
17978 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
17979 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
17980 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
17981 hr = IDirect3DDevice9_EndScene(device);
17982 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
17984 color = getPixelColor(device, 0, 240);
17985 ok(color_match(color, 0x000000ff, 2), "Got unexpected color 0x%08x, case %u.\n", color, i);
17986 color = getPixelColor(device, 320, 240);
17987 if (tests[i].todo)
17988 todo_wine ok(color_match(color, tests[i].middle_color, 2),
17989 "Got unexpected color 0x%08x, case %u.\n", color, i);
17990 else
17991 ok(color_match(color, tests[i].middle_color, 2),
17992 "Got unexpected color 0x%08x, case %u.\n", color, i);
17993 color = getPixelColor(device, 639, 240);
17994 ok(color_match(color, 0x0000fd02, 2), "Got unexpected color 0x%08x, case %u.\n", color, i);
17995 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
17996 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
17999 refcount = IDirect3DDevice9_Release(device);
18000 ok(!refcount, "Device has %u references left.\n", refcount);
18001 IDirect3D9_Release(d3d);
18002 DestroyWindow(window);
18005 static void test_negative_fixedfunction_fog(void)
18007 HRESULT hr;
18008 IDirect3DDevice9 *device;
18009 IDirect3D9 *d3d;
18010 ULONG refcount;
18011 HWND window;
18012 D3DCOLOR color;
18013 static const struct
18015 struct vec3 position;
18016 D3DCOLOR diffuse;
18018 quad[] =
18020 {{-1.0f, -1.0f, -0.5f}, 0xffff0000},
18021 {{-1.0f, 1.0f, -0.5f}, 0xffff0000},
18022 {{ 1.0f, -1.0f, -0.5f}, 0xffff0000},
18023 {{ 1.0f, 1.0f, -0.5f}, 0xffff0000},
18025 static const struct
18027 struct vec4 position;
18028 D3DCOLOR diffuse;
18030 tquad[] =
18032 {{ 0.0f, 0.0f, -0.5f, 1.0f}, 0xffff0000},
18033 {{640.0f, 0.0f, -0.5f, 1.0f}, 0xffff0000},
18034 {{ 0.0f, 480.0f, -0.5f, 1.0f}, 0xffff0000},
18035 {{640.0f, 480.0f, -0.5f, 1.0f}, 0xffff0000},
18037 unsigned int i;
18038 static const D3DMATRIX zero =
18040 1.0f, 0.0f, 0.0f, 0.0f,
18041 0.0f, 1.0f, 0.0f, 0.0f,
18042 0.0f, 0.0f, 0.0f, 0.0f,
18043 0.0f, 0.0f, 0.0f, 1.0f
18044 }}};
18045 /* Needed to make AMD drivers happy. Yeah, it is not supposed to
18046 * have an effect on RHW draws. */
18047 static const D3DMATRIX identity =
18049 1.0f, 0.0f, 0.0f, 0.0f,
18050 0.0f, 1.0f, 0.0f, 0.0f,
18051 0.0f, 0.0f, 1.0f, 0.0f,
18052 0.0f, 0.0f, 0.0f, 1.0f
18053 }}};
18054 static const struct
18056 DWORD pos_type;
18057 const void *quad;
18058 size_t stride;
18059 const D3DMATRIX *matrix;
18060 union
18062 float f;
18063 DWORD d;
18064 } start, end;
18065 D3DFOGMODE vfog, tfog;
18066 DWORD color, color_broken, color_broken2;
18068 tests[] =
18070 /* Run the XYZRHW tests first. Depth clamping is broken after RHW draws on the testbot.
18072 * Geforce8+ GPUs on Windows abs() table fog, everything else does not. */
18073 {D3DFVF_XYZRHW, tquad, sizeof(*tquad), &identity, { 0.0f}, {1.0f},
18074 D3DFOG_NONE, D3DFOG_LINEAR, 0x00ff0000, 0x00808000, 0x00808000},
18075 /* r200 GPUs and presumably all d3d8 and older HW clamp the fog
18076 * parameters to 0.0 and 1.0 in the table fog case. */
18077 {D3DFVF_XYZRHW, tquad, sizeof(*tquad), &identity, {-1.0f}, {0.0f},
18078 D3DFOG_NONE, D3DFOG_LINEAR, 0x00808000, 0x00ff0000, 0x0000ff00},
18079 /* test_fog_interpolation shows that vertex fog evaluates the fog
18080 * equation in the vertex pipeline. Start = -1.0 && end = 0.0 shows
18081 * that the abs happens before the fog equation is evaluated.
18083 * Vertex fog abs() behavior is the same on all GPUs. */
18084 {D3DFVF_XYZ, quad, sizeof(*quad), &zero, { 0.0f}, {1.0f},
18085 D3DFOG_LINEAR, D3DFOG_NONE, 0x00808000, 0x00808000, 0x00808000},
18086 {D3DFVF_XYZ, quad, sizeof(*quad), &zero, {-1.0f}, {0.0f},
18087 D3DFOG_LINEAR, D3DFOG_NONE, 0x0000ff00, 0x0000ff00, 0x0000ff00},
18088 {D3DFVF_XYZ, quad, sizeof(*quad), &zero, { 0.0f}, {1.0f},
18089 D3DFOG_EXP, D3DFOG_NONE, 0x009b6400, 0x009b6400, 0x009b6400},
18091 D3DCAPS9 caps;
18093 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
18094 0, 0, 640, 480, NULL, NULL, NULL, NULL);
18095 d3d = Direct3DCreate9(D3D_SDK_VERSION);
18096 ok(!!d3d, "Failed to create a D3D object.\n");
18098 if (!(device = create_device(d3d, window, window, TRUE)))
18100 skip("Failed to create a D3D device, skipping tests.\n");
18101 IDirect3D9_Release(d3d);
18102 DestroyWindow(window);
18103 return;
18106 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
18107 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
18108 if (!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE))
18109 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping some fog tests.\n");
18111 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
18112 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18113 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
18114 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18115 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
18116 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18117 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0x0000ff00);
18118 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18119 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
18120 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
18122 for (i = 0; i < sizeof(tests) / sizeof(*tests); i++)
18124 if (!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE) && tests[i].tfog)
18125 continue;
18127 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x000000ff, 0.0f, 0);
18128 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
18130 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, tests[i].matrix);
18131 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
18132 hr = IDirect3DDevice9_SetFVF(device, tests[i].pos_type | D3DFVF_DIFFUSE);
18133 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr);
18134 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, tests[i].start.d);
18135 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18136 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, tests[i].end.d);
18137 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18138 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGVERTEXMODE, tests[i].vfog);
18139 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18140 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, tests[i].tfog);
18141 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18143 hr = IDirect3DDevice9_BeginScene(device);
18144 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
18145 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, tests[i].quad, tests[i].stride);
18146 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
18147 hr = IDirect3DDevice9_EndScene(device);
18148 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
18150 color = getPixelColor(device, 320, 240);
18151 ok(color_match(color, tests[i].color, 2) || broken(color_match(color, tests[i].color_broken, 2))
18152 || broken(color_match(color, tests[i].color_broken2, 2)),
18153 "Got unexpected color 0x%08x, case %u.\n", color, i);
18154 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
18155 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
18158 refcount = IDirect3DDevice9_Release(device);
18159 ok(!refcount, "Device has %u references left.\n", refcount);
18160 IDirect3D9_Release(d3d);
18161 DestroyWindow(window);
18164 static void test_position_index(void)
18166 static const D3DVERTEXELEMENT9 decl_elements[] =
18168 {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
18169 {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 1},
18170 D3DDECL_END()
18172 /* Declaring (and using) a position1 output semantic in a VS fails at draw time on AMD
18173 * but works on Nvidia.
18174 * MSDN is not consistent on this point. */
18175 static const DWORD vs_code[] =
18177 0xfffe0300, /* vs_3_0 */
18178 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position0 v0 */
18179 0x0200001f, 0x80010000, 0x900f0001, /* dcl_position1 v1 */
18180 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position0 o0 */
18181 0x0200001f, 0x80010000, 0xe00f0001, /* dcl_position1 o1 */
18182 0x0200001f, 0x80000005, 0xe00f0002, /* dcl_texcoord0 o2 */
18183 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
18184 0x02000001, 0xe00f0001, 0x90e40001, /* mov o1, v1 */
18185 0x02000001, 0xe00f0002, 0x90e40001, /* mov o2, v1 */
18186 0x0000ffff /* end */
18188 static const DWORD vs_code_2[] =
18190 0xfffe0300, /* vs_3_0 */
18191 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position0 v0 */
18192 0x0200001f, 0x80010000, 0x900f0001, /* dcl_position1 v1 */
18193 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position0 o0 */
18194 0x0200001f, 0x80000005, 0xe00f0002, /* dcl_texcoord0 o2 */
18195 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
18196 0x02000001, 0xe00f0002, 0x90e40001, /* mov o2, v1 */
18197 0x0000ffff /* end */
18199 static const DWORD ps_code[] =
18201 0xffff0300, /* ps_3_0 */
18202 0x0200001f, 0x80010000, 0x900f0000, /* dcl_position1 v0 */
18203 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
18204 0x0000ffff /* end */
18206 static const DWORD ps_code_2[] =
18208 0xffff0300, /* ps_3_0 */
18209 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord0 v0 */
18210 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
18211 0x0000ffff /* end */
18213 /* This one is considered invalid by the native shader assembler. */
18214 static const DWORD ps_code_bad[] =
18216 0xffff0300, /* ps_3_0 */
18217 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position0 v0 */
18218 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
18219 0x0000ffff /* end */
18221 static const struct
18223 struct vec3 position;
18224 struct vec3 position1;
18226 quad[] =
18228 {{-1.0f, -1.0f, 0.5f}, {1.0f, 0.0f, 0.0f}},
18229 {{-1.0f, 1.0f, 0.5f}, {1.0f, 0.0f, 0.0f}},
18230 {{ 1.0f, -1.0f, 0.5f}, {0.0f, 1.0f, 0.0f}},
18231 {{ 1.0f, 1.0f, 0.5f}, {0.0f, 1.0f, 0.0f}},
18233 static const struct
18235 struct vec2 position;
18236 D3DCOLOR expected_color;
18237 D3DCOLOR broken_color;
18239 expected_colors[] =
18241 {{ 80, 240}, 0x00df2000, 0x00ff00ff},
18242 {{240, 240}, 0x009f6000, 0x00ff00ff},
18243 {{400, 240}, 0x00609f00, 0x00ff00ff},
18244 {{560, 240}, 0x0020df00, 0x00ff00ff},
18246 IDirect3D9 *d3d;
18247 IDirect3DDevice9 *device;
18248 IDirect3DVertexDeclaration9 *vertex_declaration;
18249 IDirect3DVertexShader9 *vs, *vs2;
18250 IDirect3DPixelShader9 *ps, *ps2;
18251 D3DCAPS9 caps;
18252 D3DCOLOR color;
18253 ULONG refcount;
18254 HWND window;
18255 HRESULT hr;
18256 unsigned int i;
18258 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
18259 0, 0, 640, 480, NULL, NULL, NULL, NULL);
18260 d3d = Direct3DCreate9(D3D_SDK_VERSION);
18261 ok(!!d3d, "Failed to create a D3D object.\n");
18262 if (!(device = create_device(d3d, window, window, TRUE)))
18264 skip("Failed to create a D3D device, skipping tests.\n");
18265 goto done;
18268 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
18269 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
18270 if (caps.VertexShaderVersion < D3DVS_VERSION(3, 0)
18271 || caps.PixelShaderVersion < D3DPS_VERSION(3, 0))
18273 skip("Shader model 3.0 unsupported, skipping tests.\n");
18274 IDirect3DDevice9_Release(device);
18275 goto done;
18278 hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
18279 ok(SUCCEEDED(hr), "CreateVertexDeclaration failed, hr %#x\n", hr);
18281 hr = IDirect3DDevice9_SetVertexDeclaration(device, vertex_declaration);
18282 ok(SUCCEEDED(hr), "SetVertexDeclaration failed, hr %#x\n", hr);
18284 hr = IDirect3DDevice9_CreateVertexShader(device, vs_code, &vs);
18285 ok(SUCCEEDED(hr), "CreateVertexShader failed, hr %#x.\n", hr);
18286 hr = IDirect3DDevice9_CreateVertexShader(device, vs_code_2, &vs2);
18287 ok(SUCCEEDED(hr), "CreateVertexShader failed, hr %#x.\n", hr);
18289 hr = IDirect3DDevice9_SetVertexShader(device, vs);
18290 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
18292 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code_bad, &ps);
18293 ok(hr == D3DERR_INVALIDCALL, "CreatePixelShader returned hr %#x.\n", hr);
18295 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code, &ps);
18296 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
18297 hr = IDirect3DDevice9_CreatePixelShader(device, ps_code_2, &ps2);
18298 ok(SUCCEEDED(hr), "CreatePixelShader failed, hr %#x.\n", hr);
18300 hr = IDirect3DDevice9_SetPixelShader(device, ps);
18301 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
18303 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff00ff, 1.0f, 0);
18304 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
18305 hr = IDirect3DDevice9_BeginScene(device);
18306 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
18307 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
18308 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
18309 hr = IDirect3DDevice9_EndScene(device);
18310 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
18312 for (i = 0; i < sizeof(expected_colors) / sizeof(expected_colors[0]); ++i)
18314 color = getPixelColor(device, expected_colors[i].position.x, expected_colors[i].position.y);
18315 ok (color_match(color, expected_colors[i].expected_color, 1)
18316 || broken(color_match(color, expected_colors[i].broken_color, 1)),
18317 "Got unexpected color 0x%08x, case %u.\n", color, i);
18320 hr = IDirect3DDevice9_SetPixelShader(device, ps2);
18321 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
18323 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff00ff, 1.0f, 0);
18324 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
18325 hr = IDirect3DDevice9_BeginScene(device);
18326 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
18327 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
18328 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
18329 hr = IDirect3DDevice9_EndScene(device);
18330 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
18332 for (i = 0; i < sizeof(expected_colors) / sizeof(expected_colors[0]); ++i)
18334 color = getPixelColor(device, expected_colors[i].position.x, expected_colors[i].position.y);
18335 ok (color_match(color, expected_colors[i].expected_color, 1)
18336 || broken(color_match(color, expected_colors[i].broken_color, 1)),
18337 "Got unexpected color 0x%08x, case %u.\n", color, i);
18340 hr = IDirect3DDevice9_SetVertexShader(device, vs2);
18341 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
18343 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff00ff, 1.0f, 0);
18344 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
18345 hr = IDirect3DDevice9_BeginScene(device);
18346 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
18347 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
18348 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
18349 hr = IDirect3DDevice9_EndScene(device);
18350 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
18352 for (i = 0; i < sizeof(expected_colors) / sizeof(expected_colors[0]); ++i)
18354 color = getPixelColor(device, expected_colors[i].position.x, expected_colors[i].position.y);
18355 ok (color_match(color, expected_colors[i].expected_color, 1),
18356 "Got unexpected color 0x%08x, case %u.\n", color, i);
18359 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
18360 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
18362 IDirect3DPixelShader9_Release(ps2);
18363 IDirect3DPixelShader9_Release(ps);
18364 IDirect3DVertexShader9_Release(vs2);
18365 IDirect3DVertexShader9_Release(vs);
18366 IDirect3DVertexDeclaration9_Release(vertex_declaration);
18367 refcount = IDirect3DDevice9_Release(device);
18368 ok(!refcount, "Device has %u references left.\n", refcount);
18370 done:
18371 IDirect3D9_Release(d3d);
18372 DestroyWindow(window);
18375 static void test_table_fog_zw(void)
18377 HRESULT hr;
18378 IDirect3DDevice9 *device;
18379 IDirect3D9 *d3d;
18380 ULONG refcount;
18381 HWND window;
18382 D3DCOLOR color;
18383 D3DCAPS9 caps;
18384 static struct
18386 struct vec4 position;
18387 D3DCOLOR diffuse;
18389 quad[] =
18391 {{ 0.0f, 0.0f, 0.0f, 0.0f}, 0xffff0000},
18392 {{640.0f, 0.0f, 0.0f, 0.0f}, 0xffff0000},
18393 {{ 0.0f, 480.0f, 0.0f, 0.0f}, 0xffff0000},
18394 {{640.0f, 480.0f, 0.0f, 0.0f}, 0xffff0000},
18396 static const D3DMATRIX identity =
18398 1.0f, 0.0f, 0.0f, 0.0f,
18399 0.0f, 1.0f, 0.0f, 0.0f,
18400 0.0f, 0.0f, 1.0f, 0.0f,
18401 0.0f, 0.0f, 0.0f, 1.0f
18402 }}};
18403 static const struct
18405 float z, w;
18406 D3DZBUFFERTYPE z_test;
18407 D3DCOLOR color;
18409 tests[] =
18411 {0.7f, 0.0f, D3DZB_TRUE, 0x004cb200},
18412 {0.7f, 0.0f, D3DZB_FALSE, 0x004cb200},
18413 {0.7f, 0.3f, D3DZB_TRUE, 0x004cb200},
18414 {0.7f, 0.3f, D3DZB_FALSE, 0x004cb200},
18415 {0.7f, 3.0f, D3DZB_TRUE, 0x004cb200},
18416 {0.7f, 3.0f, D3DZB_FALSE, 0x004cb200},
18417 {0.3f, 0.0f, D3DZB_TRUE, 0x00b24c00},
18418 {0.3f, 0.0f, D3DZB_FALSE, 0x00b24c00},
18420 unsigned int i;
18422 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
18423 0, 0, 640, 480, NULL, NULL, NULL, NULL);
18424 d3d = Direct3DCreate9(D3D_SDK_VERSION);
18425 ok(!!d3d, "Failed to create a D3D object.\n");
18427 if (!(device = create_device(d3d, window, window, TRUE)))
18429 skip("Failed to create a D3D device, skipping tests.\n");
18430 IDirect3D9_Release(d3d);
18431 DestroyWindow(window);
18432 return;
18435 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
18436 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
18437 if (!(caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE))
18439 skip("D3DPRASTERCAPS_FOGTABLE not supported, skipping POSITIONT table fog test.\n");
18440 goto done;
18443 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
18444 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18445 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, TRUE);
18446 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18447 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, 0x0000ff00);
18448 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18449 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
18450 ok(SUCCEEDED(hr), "SetRenderState failed, hr %#x.\n", hr);
18451 /* Work around an AMD Windows driver bug. Needs a proj matrix applied redundantly. */
18452 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &identity);
18453 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
18454 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
18455 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18456 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
18457 ok(SUCCEEDED(hr), "Failed to set fvf, hr %#x.\n", hr);
18459 for (i = 0; i < sizeof(tests) / sizeof(*tests); ++i)
18461 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0);
18462 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
18464 quad[0].position.z = tests[i].z;
18465 quad[1].position.z = tests[i].z;
18466 quad[2].position.z = tests[i].z;
18467 quad[3].position.z = tests[i].z;
18468 quad[0].position.w = tests[i].w;
18469 quad[1].position.w = tests[i].w;
18470 quad[2].position.w = tests[i].w;
18471 quad[3].position.w = tests[i].w;
18472 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, tests[i].z_test);
18473 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18475 hr = IDirect3DDevice9_BeginScene(device);
18476 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
18477 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
18478 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
18479 hr = IDirect3DDevice9_EndScene(device);
18480 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
18482 color = getPixelColor(device, 320, 240);
18483 ok(color_match(color, tests[i].color, 2),
18484 "Got unexpected color 0x%08x, expected 0x%08x, case %u.\n", color, tests[i].color, i);
18485 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
18486 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
18489 done:
18490 refcount = IDirect3DDevice9_Release(device);
18491 ok(!refcount, "Device has %u references left.\n", refcount);
18492 IDirect3D9_Release(d3d);
18493 DestroyWindow(window);
18496 static void test_signed_formats(void)
18498 IDirect3DDevice9 *device;
18499 HWND window;
18500 HRESULT hr;
18501 unsigned int i, j, x, y;
18502 IDirect3DTexture9 *texture, *texture_sysmem;
18503 IDirect3DSurface9 *src_surface, *dst_surface;
18504 D3DLOCKED_RECT locked_rect;
18505 IDirect3DPixelShader9 *shader, *shader_alpha;
18506 IDirect3D9 *d3d;
18507 D3DCOLOR color;
18508 D3DCAPS9 caps;
18509 ULONG refcount;
18511 /* The input data was designed for D3DFMT_L6V5U5 and then transferred
18512 * to the other formats because L6V5U5 is the lowest precision format.
18513 * It tests the extreme values -1.0 (-16) and 1.0 (15) for U/V and
18514 * 0.0 (0) and 1.0 (63) for L, the neutral point 0 as well as -1 and 1.
18515 * Some other intermediate values are tested too. The input value -15
18516 * (min + 1) is tested as well. Unlike what OpenGL 4.4 says in section
18517 * 2.3.4.1, this value does not represent -1.0. In the interest of re-
18518 * using the expected output data the 8 bit and 16 bit values in V8U8
18519 * and V16U16 match (post-normalization) the 5 bit input values. Thus
18520 * -1, 1 and -127 are not tested in V8U8.
18522 * 8 bit specific values like -127 are tested in the Q channel of
18523 * D3DFMT_Q8W8V8U8. Here d3d seems to follow the rules from the GL
18524 * spec. AMD's r200 is broken though and returns a value < -1.0 for
18525 * -128. The difference between using -127 or -128 as the lowest
18526 * possible value gets lost in the slop of 1 though. */
18527 static const USHORT content_v8u8[4][4] =
18529 {0x0000, 0x7f7f, 0x8880, 0x0000},
18530 {0x0080, 0x8000, 0x7f00, 0x007f},
18531 {0x193b, 0xe8c8, 0x0808, 0xf8f8},
18532 {0x4444, 0xc0c0, 0xa066, 0x22e0},
18534 static const DWORD content_v16u16[4][4] =
18536 {0x00000000, 0x7fff7fff, 0x88008000, 0x00000000},
18537 {0x00008000, 0x80000000, 0x7fff0000, 0x00007fff},
18538 {0x19993bbb, 0xe800c800, 0x08880888, 0xf800f800},
18539 {0x44444444, 0xc000c000, 0xa0006666, 0x2222e000},
18541 static const DWORD content_q8w8v8u8[4][4] =
18543 {0x00000000, 0xff7f7f7f, 0x7f008880, 0x817f0000},
18544 {0x10000080, 0x20008000, 0x30007f00, 0x4000007f},
18545 {0x5020193b, 0x6028e8c8, 0x70020808, 0x807ff8f8},
18546 {0x90414444, 0xa000c0c0, 0x8261a066, 0x834922e0},
18548 static const DWORD content_x8l8v8u8[4][4] =
18550 {0x00000000, 0x00ff7f7f, 0x00008880, 0x00ff0000},
18551 {0x00000080, 0x00008000, 0x00007f00, 0x0000007f},
18552 {0x0041193b, 0x0051e8c8, 0x00040808, 0x00fff8f8},
18553 {0x00824444, 0x0000c0c0, 0x00c2a066, 0x009222e0},
18555 /* D3DFMT_L6V5U5 has poor precision on some GPUs. On a GeForce 7 the highest V and U value (15)
18556 * results in the output color 0xfb, which is 4 steps away from the correct value 0xff. It is
18557 * not the ~0xf0 you'd get if you blindly left-shifted the 5 bit value to form an 8 bit value
18558 * though.
18560 * There may also be an off-by-one bug involved: The value -7 should result in the output 0x47,
18561 * but ends up as 0x4d. Likewise, -3 becomes 0x6e instead of 0x67. Those values are close to
18562 * the proper results of -6 and -2.
18564 * On Wine the emulation with unsigned R5G6B5 has poor precision, e.g. the signed 0 becomes 16,
18565 * and ((16 / 31) - 0.5) * 2.0 is 0.032 instead of 0.000. The final output result we read back
18566 * is 0x84 instead of 0x80. */
18567 static const USHORT content_l6v5u5[4][4] =
18569 {0x0000, 0xfdef, 0x0230, 0xfc00},
18570 {0x0010, 0x0200, 0x01e0, 0x000f},
18571 {0x4067, 0x53b9, 0x0421, 0xffff},
18572 {0x8108, 0x0318, 0xc28c, 0x909c},
18574 static const struct
18576 D3DFORMAT format;
18577 const char *name;
18578 const void *content;
18579 SIZE_T pixel_size;
18580 BOOL blue, alpha;
18581 unsigned int slop, slop_broken, alpha_broken;
18583 formats[] =
18585 {D3DFMT_V8U8, "D3DFMT_V8U8", content_v8u8, sizeof(WORD), FALSE, FALSE, 1, 0, FALSE},
18586 {D3DFMT_V16U16, "D3DFMT_V16U16", content_v16u16, sizeof(DWORD), FALSE, FALSE, 1, 0, FALSE},
18587 {D3DFMT_Q8W8V8U8, "D3DFMT_Q8W8V8U8", content_q8w8v8u8, sizeof(DWORD), TRUE, TRUE, 1, 0, TRUE },
18588 {D3DFMT_X8L8V8U8, "D3DFMT_X8L8V8U8", content_x8l8v8u8, sizeof(DWORD), TRUE, FALSE, 1, 0, FALSE},
18589 {D3DFMT_L6V5U5, "D3DFMT_L6V5U5", content_l6v5u5, sizeof(WORD), TRUE, FALSE, 4, 7, FALSE},
18591 static const struct
18593 D3DPOOL pool;
18594 UINT width;
18595 RECT src_rect;
18596 POINT dst_point;
18598 tests[] =
18600 {D3DPOOL_SYSTEMMEM, 4, {1, 1, 2, 3}, {2, 0}},
18601 {D3DPOOL_SYSTEMMEM, 1, {0, 1, 1, 3}, {0, 0}},
18602 {D3DPOOL_MANAGED, 4, {1, 1, 2, 3}, {2, 0}},
18603 {D3DPOOL_MANAGED, 1, {0, 1, 1, 3}, {0, 0}},
18605 static const DWORD shader_code[] =
18607 0xffff0101, /* ps_1_1 */
18608 0x00000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, /* def c0, 0.5, 0.5, 0,5, 0,5 */
18609 0x00000042, 0xb00f0000, /* tex t0 */
18610 0x00000004, 0x800f0000, 0xb0e40000, 0xa0e40000, 0xa0e40000, /* mad r0, t0, c0, c0 */
18611 0x0000ffff /* end */
18613 static const DWORD shader_code_alpha[] =
18615 /* The idea of this shader is to replicate the alpha value in .rg, and set
18616 * blue to 1.0 iff the alpha value is < -1.0 and 0.0 otherwise. */
18617 0xffff0101, /* ps_1_1 */
18618 0x00000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, /* def c0, 0.5, 0.5, 0.5, 0.5 */
18619 0x00000051, 0xa00f0001, 0x3f800000, 0x3f800000, 0x00000000, 0x3f800000, /* def c1, 1.0, 1.0, 0.0, 1.0 */
18620 0x00000051, 0xa00f0002, 0x00000000, 0x00000000, 0x3f800000, 0x00000000, /* def c2, 0.0, 0.0, 1.0, 0.0 */
18621 0x00000042, 0xb00f0000, /* tex t0 */
18622 0x00000004, 0x80070000, 0xb0ff0000, 0xa0e40000, 0xa0e40000, /* mad r0.rgb, t0.a, c0, c0 */
18623 0x00000003, 0x80080000, 0xb1ff0000, 0xa0e40000, /* sub r0.a, -t0.a, c0 */
18624 0x00000050, 0x80080000, 0x80ff0000, 0xa0ff0001, 0xa0ff0002, /* cnd r0.a, r0.a, c1.a, c2.a */
18625 0x00000005, 0x80070001, 0xa0e40001, 0x80e40000, /* mul r1.rgb, c1, r0 */
18626 0x00000004, 0x80070000, 0x80ff0000, 0xa0e40002, 0x80e40001, /* mad r0.rgb, r0.a, c2, r1 */
18627 0x0000ffff /* end */
18629 static const struct
18631 struct vec3 position;
18632 struct vec2 texcrd;
18634 quad[] =
18636 /* Flip the y coordinate to make the input and
18637 * output arrays easier to compare. */
18638 {{ -1.0f, -1.0f, 0.0f}, { 0.0f, 1.0f}},
18639 {{ -1.0f, 1.0f, 0.0f}, { 0.0f, 0.0f}},
18640 {{ 1.0f, -1.0f, 0.0f}, { 1.0f, 1.0f}},
18641 {{ 1.0f, 1.0f, 0.0f}, { 1.0f, 0.0f}},
18643 static const D3DCOLOR expected_alpha[4][4] =
18645 {0x00808000, 0x007f7f00, 0x00ffff00, 0x00000000},
18646 {0x00909000, 0x00a0a000, 0x00b0b000, 0x00c0c000},
18647 {0x00d0d000, 0x00e0e000, 0x00f0f000, 0x00000000},
18648 {0x00101000, 0x00202000, 0x00010100, 0x00020200},
18650 static const BOOL alpha_broken[4][4] =
18652 {FALSE, FALSE, FALSE, FALSE},
18653 {FALSE, FALSE, FALSE, FALSE},
18654 {FALSE, FALSE, FALSE, TRUE },
18655 {FALSE, FALSE, FALSE, FALSE},
18657 static const D3DCOLOR expected_colors[4][4] =
18659 {0x00808080, 0x00fefeff, 0x00010780, 0x008080ff},
18660 {0x00018080, 0x00800180, 0x0080fe80, 0x00fe8080},
18661 {0x00ba98a0, 0x004767a8, 0x00888881, 0x007878ff},
18662 {0x00c3c3c0, 0x003f3f80, 0x00e51fe1, 0x005fa2c8},
18664 static const D3DCOLOR expected_colors2[4][4] =
18666 {0x00808080, 0x00fefeff, 0x00800180, 0x008080ff},
18667 {0x00018080, 0x00800180, 0x004767a8, 0x00fe8080},
18668 {0x00ba98a0, 0x004767a8, 0x00888881, 0x007878ff},
18669 {0x00c3c3c0, 0x003f3f80, 0x00e51fe1, 0x005fa2c8},
18671 static const D3DCOLOR expected_colors3[4] =
18673 0x00018080,
18674 0x00ba98a0,
18675 0x00ba98a0,
18676 0x00c3c3c0,
18678 D3DCOLOR expected_color;
18680 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
18681 0, 0, 640, 480, NULL, NULL, NULL, NULL);
18682 d3d = Direct3DCreate9(D3D_SDK_VERSION);
18683 ok(!!d3d, "Failed to create a D3D object.\n");
18685 if (!(device = create_device(d3d, window, window, TRUE)))
18687 skip("Failed to create a D3D device, skipping tests.\n");
18688 IDirect3D9_Release(d3d);
18689 DestroyWindow(window);
18690 return;
18693 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
18694 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
18696 if (caps.PixelShaderVersion < D3DPS_VERSION(1, 1))
18698 skip("Pixel shaders not supported, skipping converted format test.\n");
18699 goto done;
18702 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
18703 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18704 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1);
18705 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
18706 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code, &shader);
18707 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
18708 hr = IDirect3DDevice9_CreatePixelShader(device, shader_code_alpha, &shader_alpha);
18709 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x.\n", hr);
18711 for (i = 0; i < sizeof(formats) / sizeof(*formats); i++)
18713 hr = IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
18714 D3DFMT_X8R8G8B8, 0, D3DRTYPE_TEXTURE, formats[i].format);
18715 if (FAILED(hr))
18717 skip("Format %s not supported, skipping.\n", formats[i].name);
18718 continue;
18721 for (j = 0; j < sizeof(tests) / sizeof(*tests); j++)
18723 texture_sysmem = NULL;
18724 hr = IDirect3DDevice9_CreateTexture(device, tests[j].width, 4, 1, 0,
18725 formats[i].format, tests[j].pool, &texture, NULL);
18726 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
18728 hr = IDirect3DTexture9_LockRect(texture, 0, &locked_rect, NULL, 0);
18729 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
18730 for (y = 0; y < 4; y++)
18732 memcpy((char *)locked_rect.pBits + y * locked_rect.Pitch,
18733 (char *)formats[i].content + y * 4 * formats[i].pixel_size,
18734 tests[j].width * formats[i].pixel_size);
18736 hr = IDirect3DTexture9_UnlockRect(texture, 0);
18737 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
18739 if (tests[j].pool == D3DPOOL_SYSTEMMEM)
18741 texture_sysmem = texture;
18742 hr = IDirect3DDevice9_CreateTexture(device, tests[j].width, 4, 1, 0,
18743 formats[i].format, D3DPOOL_DEFAULT, &texture, NULL);
18744 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
18746 hr = IDirect3DDevice9_UpdateTexture(device, (IDirect3DBaseTexture9 *)texture_sysmem,
18747 (IDirect3DBaseTexture9 *)texture);
18748 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x.\n", hr);
18751 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
18752 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
18753 hr = IDirect3DDevice9_SetPixelShader(device, shader_alpha);
18754 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
18756 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00330033, 0.0f, 0);
18757 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
18758 hr = IDirect3DDevice9_BeginScene(device);
18759 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
18760 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(*quad));
18761 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
18762 hr = IDirect3DDevice9_EndScene(device);
18763 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
18765 for (y = 0; y < 4; y++)
18767 for (x = 0; x < tests[j].width; x++)
18769 BOOL r200_broken = formats[i].alpha_broken && alpha_broken[y][x];
18770 if (formats[i].alpha)
18771 expected_color = expected_alpha[y][x];
18772 else
18773 expected_color = 0x00ffff00;
18775 color = getPixelColor(device, 80 + 160 * x, 60 + 120 * y);
18776 ok(color_match(color, expected_color, 1) || broken(r200_broken),
18777 "Expected color 0x%08x, got 0x%08x, format %s, location %ux%u.\n",
18778 expected_color, color, formats[i].name, x, y);
18781 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
18782 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
18784 hr = IDirect3DDevice9_SetPixelShader(device, shader);
18785 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
18787 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00330033, 0.0f, 0);
18788 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
18789 hr = IDirect3DDevice9_BeginScene(device);
18790 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
18791 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(*quad));
18792 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
18793 hr = IDirect3DDevice9_EndScene(device);
18794 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
18796 for (y = 0; y < 4; y++)
18798 for (x = 0; x < tests[j].width; x++)
18800 expected_color = expected_colors[y][x];
18801 if (!formats[i].blue)
18802 expected_color |= 0x000000ff;
18804 color = getPixelColor(device, 80 + 160 * x, 60 + 120 * y);
18805 ok(color_match(color, expected_color, formats[i].slop)
18806 || broken(color_match(color, expected_color, formats[i].slop_broken)),
18807 "Expected color 0x%08x, got 0x%08x, format %s, location %ux%u.\n",
18808 expected_color, color, formats[i].name, x, y);
18811 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
18812 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
18814 if (tests[j].pool != D3DPOOL_SYSTEMMEM)
18816 IDirect3DTexture9_Release(texture);
18817 continue;
18820 hr = IDirect3DTexture9_GetSurfaceLevel(texture, 0, &dst_surface);
18821 ok(SUCCEEDED(hr), "Failed to get surface, hr %#x.\n", hr);
18822 IDirect3DTexture9_GetSurfaceLevel(texture_sysmem, 0, &src_surface);
18823 ok(SUCCEEDED(hr), "Failed to get surface, hr %#x.\n", hr);
18825 hr = IDirect3DDevice9_UpdateSurface(device, src_surface,
18826 &tests[j].src_rect, dst_surface, &tests[j].dst_point);
18827 ok(SUCCEEDED(hr), "Failed to update surface, hr %#x.\n", hr);
18829 IDirect3DSurface9_Release(dst_surface);
18830 IDirect3DSurface9_Release(src_surface);
18832 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00003300, 0.0f, 0);
18833 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
18834 hr = IDirect3DDevice9_BeginScene(device);
18835 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
18836 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quad[0], sizeof(*quad));
18837 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
18838 hr = IDirect3DDevice9_EndScene(device);
18839 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
18841 for (y = 0; y < 4; y++)
18843 for (x = 0; x < tests[j].width; x++)
18845 if (tests[j].width == 4)
18846 expected_color = expected_colors2[y][x];
18847 else
18848 expected_color = expected_colors3[y];
18850 if (!formats[i].blue)
18851 expected_color |= 0x000000ff;
18853 color = getPixelColor(device, 80 + 160 * x, 60 + 120 * y);
18854 ok(color_match(color, expected_color, formats[i].slop)
18855 || broken(color_match(color, expected_color, formats[i].slop_broken)),
18856 "Expected color 0x%08x, got 0x%08x, format %s, location %ux%u.\n",
18857 expected_color, color, formats[i].name, x, y);
18860 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
18861 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
18863 IDirect3DTexture9_Release(texture_sysmem);
18864 IDirect3DTexture9_Release(texture);
18868 IDirect3DPixelShader9_Release(shader);
18869 IDirect3DPixelShader9_Release(shader_alpha);
18871 done:
18872 refcount = IDirect3DDevice9_Release(device);
18873 ok(!refcount, "Device has %u references left.\n", refcount);
18874 IDirect3D9_Release(d3d);
18875 DestroyWindow(window);
18878 static void test_multisample_mismatch(void)
18880 IDirect3DDevice9 *device;
18881 IDirect3D9 *d3d;
18882 HWND window;
18883 HRESULT hr;
18884 D3DCOLOR color;
18885 ULONG refcount;
18886 IDirect3DSurface9 *rt, *rt_multi, *ds;
18887 static const struct
18889 struct vec3 position;
18890 DWORD color;
18892 quad[] =
18894 {{ -1.0f, -1.0f, 0.0f}, 0x000000ff},
18895 {{ -1.0f, 1.0f, 0.0f}, 0x000000ff},
18896 {{ 1.0f, -1.0f, 1.0f}, 0x000000ff},
18897 {{ 1.0f, 1.0f, 1.0f}, 0x000000ff},
18900 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
18901 0, 0, 640, 480, NULL, NULL, NULL, NULL);
18902 d3d = Direct3DCreate9(D3D_SDK_VERSION);
18903 ok(!!d3d, "Failed to create a D3D object.\n");
18904 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
18905 D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
18907 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping multisample mismatch test.\n");
18908 IDirect3D9_Release(d3d);
18909 return;
18911 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
18912 D3DFMT_D24X8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
18914 skip("Multisampling not supported for D3DFMT_D24X8, skipping multisample mismatch test.\n");
18915 IDirect3D9_Release(d3d);
18916 return;
18919 if (!(device = create_device(d3d, window, window, TRUE)))
18921 skip("Failed to create a D3D device, skipping tests.\n");
18922 IDirect3D9_Release(d3d);
18923 DestroyWindow(window);
18924 return;
18927 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
18928 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &rt_multi, NULL);
18929 ok(SUCCEEDED(hr), "Failed to create render target, hr %#x.\n", hr);
18931 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 0.1f, 0);
18932 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
18934 hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds);
18935 ok(SUCCEEDED(hr), "Failed to set depth stencil, hr %#x.\n", hr);
18936 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &rt);
18937 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
18938 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt_multi);
18939 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
18941 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
18942 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18943 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
18944 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18946 /* Clear with incompatible buffers. Partial and combined clears. */
18947 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0f, 0);
18948 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
18949 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 0.3f, 0);
18950 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
18951 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x0000ff00, 0.5f, 0);
18952 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
18954 /* The color buffer is reliably cleared on AMD and Nvidia GPUs. */
18955 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
18956 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
18957 hr = IDirect3DDevice9_StretchRect(device, rt_multi, NULL, rt, NULL, D3DTEXF_POINT);
18958 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
18959 color = getPixelColor(device, 320, 240);
18960 ok(color_match(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
18961 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
18962 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
18964 /* Check depth buffer values. AMD GPUs (r500 and evergreen tested) clear the depth buffer
18965 * like you'd expect in a correct framebuffer setup. Nvidia doesn't clear it, neither in
18966 * the Z only clear case nor in the combined clear case. */
18967 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_DIFFUSE);
18968 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
18969 hr = IDirect3DDevice9_BeginScene(device);
18970 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
18971 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
18972 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
18973 hr = IDirect3DDevice9_EndScene(device);
18974 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
18975 color = getPixelColor(device, 62, 240);
18976 ok(color_match(color, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color);
18977 color = getPixelColor(device, 64, 240);
18978 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x000000ff, 1)),
18979 "Got unexpected color 0x%08x.\n", color);
18980 color = getPixelColor(device, 318, 240);
18981 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x000000ff, 1)),
18982 "Got unexpected color 0x%08x.\n", color);
18983 color = getPixelColor(device, 322, 240);
18984 ok(color_match(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
18985 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
18986 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
18988 /* Draw with incompatible buffers. AMD even performs Z testing, and the Z test
18989 * results appear to be correct for this simple draw. Nvidia doesn't draw unless
18990 * the depth test is disabled. Setting ZFUNC = ALWAYS doesn't make the geometry
18991 * show up either. Only test the ZENABLE = FALSE case for now. */
18992 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
18993 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
18994 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt_multi);
18995 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
18996 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0f, 0);
18997 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
18998 hr = IDirect3DDevice9_BeginScene(device);
18999 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
19000 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
19001 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
19002 hr = IDirect3DDevice9_EndScene(device);
19003 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
19005 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
19006 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
19007 hr = IDirect3DDevice9_StretchRect(device, rt_multi, NULL, rt, NULL, D3DTEXF_POINT);
19008 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
19009 color = getPixelColor(device, 320, 240);
19010 ok(color_match(color, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color);
19011 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19012 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
19014 IDirect3DSurface9_Release(ds);
19016 /* Test the reverse situation: Multisampled depth buffer, single sampled color buffer.
19017 * Color clears work as expected, AMD also clears the depth buffer, Nvidia does not. */
19018 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24X8,
19019 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &ds, NULL);
19020 ok(SUCCEEDED(hr), "Failed to create depth/stencil, hr %#x.\n", hr);
19021 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
19022 ok(SUCCEEDED(hr), "Failed to set depth stencil surface, hr %#x.\n", hr);
19023 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt_multi);
19024 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
19025 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ffff00, 0.1f, 0);
19026 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
19028 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
19029 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
19030 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0f, 0);
19031 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
19032 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_ZBUFFER, 0x00000000, 0.3f, 0);
19033 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
19034 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x0000ff00, 0.5f, 0);
19035 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
19037 color = getPixelColor(device, 320, 240);
19038 ok(color_match(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
19039 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19040 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
19042 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt_multi);
19043 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
19044 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
19045 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
19046 hr = IDirect3DDevice9_BeginScene(device);
19047 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
19048 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
19049 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
19050 hr = IDirect3DDevice9_EndScene(device);
19051 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
19053 hr = IDirect3DDevice9_SetRenderTarget(device, 0, rt);
19054 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
19055 hr = IDirect3DDevice9_StretchRect(device, rt_multi, NULL, rt, NULL, D3DTEXF_POINT);
19056 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
19057 color = getPixelColor(device, 62, 240);
19058 ok(color_match(color, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color);
19059 color = getPixelColor(device, 318, 240);
19060 ok(color_match(color, 0x00ffff00, 1) || broken(color_match(color, 0x000000ff, 1)),
19061 "Got unexpected color 0x%08x.\n", color);
19062 color = getPixelColor(device, 322, 240);
19063 ok(color_match(color, 0x00ffff00, 1), "Got unexpected color 0x%08x.\n", color);
19064 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19065 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
19067 /* Draw with a single sampled color buffer and a multisampled depth buffer. Again
19068 * AMD seems to perform correct Z testing, Nvidia doesn't draw unless the Z test
19069 * is disabled. Again only test the ZENABLE = FALSE case. */
19070 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0x00ff0000, 0.0f, 0);
19071 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
19072 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_FALSE);
19073 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
19074 hr = IDirect3DDevice9_BeginScene(device);
19075 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
19076 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
19077 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
19078 hr = IDirect3DDevice9_EndScene(device);
19079 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
19080 color = getPixelColor(device, 320, 240);
19081 ok(color_match(color, 0x000000ff, 1), "Got unexpected color 0x%08x.\n", color);
19082 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19083 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
19085 IDirect3DSurface9_Release(rt);
19086 IDirect3DSurface9_Release(ds);
19087 IDirect3DSurface9_Release(rt_multi);
19089 refcount = IDirect3DDevice9_Release(device);
19090 ok(!refcount, "Device has %u references left.\n", refcount);
19091 IDirect3D9_Release(d3d);
19092 DestroyWindow(window);
19095 static void test_texcoordindex(void)
19097 static const D3DMATRIX mat =
19099 1.0f, 0.0f, 0.0f, 0.0f,
19100 0.0f, 0.0f, 0.0f, 0.0f,
19101 0.0f, 0.0f, 0.0f, 0.0f,
19102 0.0f, 0.0f, 0.0f, 0.0f,
19103 }}};
19104 static const struct
19106 struct vec3 pos;
19107 struct vec2 texcoord1;
19108 struct vec2 texcoord2;
19109 struct vec2 texcoord3;
19111 quad[] =
19113 {{-1.0f, -1.0f, 0.0f}, {0.0f, 1.0f}, {0.0f, 0.0f}, {1.0f, 1.0f}},
19114 {{-1.0f, 1.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 1.0f}, {1.0f, 0.0f}},
19115 {{ 1.0f, -1.0f, 0.0f}, {1.0f, 1.0f}, {1.0f, 0.0f}, {0.0f, 1.0f}},
19116 {{ 1.0f, 1.0f, 0.0f}, {1.0f, 0.0f}, {1.0f, 1.0f}, {0.0f, 0.0f}},
19118 IDirect3DDevice9 *device;
19119 IDirect3D9 *d3d9;
19120 HWND window;
19121 HRESULT hr;
19122 IDirect3DTexture9 *texture1, *texture2;
19123 D3DLOCKED_RECT locked_rect;
19124 ULONG refcount;
19125 D3DCOLOR color;
19126 DWORD *ptr;
19128 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
19129 0, 0, 640, 480, NULL, NULL, NULL, NULL);
19130 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
19131 ok(!!d3d9, "Failed to create a D3D object.\n");
19132 if (!(device = create_device(d3d9, window, window, TRUE)))
19134 skip("Failed to create a D3D device, skipping tests.\n");
19135 IDirect3D9_Release(d3d9);
19136 DestroyWindow(window);
19137 return;
19140 hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture1, NULL);
19141 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
19142 hr = IDirect3DDevice9_CreateTexture(device, 2, 2, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture2, NULL);
19143 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr);
19145 hr = IDirect3DTexture9_LockRect(texture1, 0, &locked_rect, NULL, D3DLOCK_DISCARD);
19146 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
19147 ptr = locked_rect.pBits;
19148 ptr[0] = 0xff000000;
19149 ptr[1] = 0xff00ff00;
19150 ptr[2] = 0xff0000ff;
19151 ptr[3] = 0xff00ffff;
19152 hr = IDirect3DTexture9_UnlockRect(texture1, 0);
19153 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
19155 hr = IDirect3DTexture9_LockRect(texture2, 0, &locked_rect, NULL, D3DLOCK_DISCARD);
19156 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
19157 ptr = locked_rect.pBits;
19158 ptr[0] = 0xff000000;
19159 ptr[1] = 0xff0000ff;
19160 ptr[2] = 0xffff0000;
19161 ptr[3] = 0xffff00ff;
19162 hr = IDirect3DTexture9_UnlockRect(texture2, 0);
19163 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
19165 hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture1);
19166 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
19167 hr = IDirect3DDevice9_SetTexture(device, 1, (IDirect3DBaseTexture9 *)texture2);
19168 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
19169 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX3);
19170 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
19171 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
19172 ok(SUCCEEDED(hr), "Failed to disable lighting, hr %#x.\n", hr);
19173 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
19174 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
19175 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
19176 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
19177 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_ADD);
19178 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
19179 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
19180 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
19181 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLORARG2, D3DTA_CURRENT);
19182 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
19183 hr = IDirect3DDevice9_SetTextureStageState(device, 2, D3DTSS_COLOROP, D3DTOP_DISABLE);
19184 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
19186 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_TEXCOORDINDEX, 1);
19187 ok(SUCCEEDED(hr), "Failed to set texcoord index, hr %#x.\n", hr);
19188 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXCOORDINDEX, 0);
19189 ok(SUCCEEDED(hr), "Failed to set texcoord index, hr %#x.\n", hr);
19191 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 1.0f, 0);
19192 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
19194 hr = IDirect3DDevice9_BeginScene(device);
19195 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
19196 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
19197 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
19198 hr = IDirect3DDevice9_EndScene(device);
19199 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
19201 color = getPixelColor(device, 160, 120);
19202 ok(color_match(color, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color);
19203 color = getPixelColor(device, 480, 120);
19204 ok(color_match(color, 0x0000ffff, 2), "Got unexpected color 0x%08x.\n", color);
19205 color = getPixelColor(device, 160, 360);
19206 ok(color_match(color, 0x00ff0000, 2), "Got unexpected color 0x%08x.\n", color);
19207 color = getPixelColor(device, 480, 360);
19208 ok(color_match(color, 0x00ffffff, 2), "Got unexpected color 0x%08x.\n", color);
19210 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
19211 ok(SUCCEEDED(hr), "Failed to set texture transform flags, hr %#x.\n", hr);
19212 hr = IDirect3DDevice9_SetTransform(device, D3DTS_TEXTURE1, &mat);
19213 ok(SUCCEEDED(hr), "Failed to set transformation matrix, hr %#x.\n", hr);
19215 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 1.0f, 0);
19216 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
19218 hr = IDirect3DDevice9_BeginScene(device);
19219 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
19220 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
19221 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
19222 hr = IDirect3DDevice9_EndScene(device);
19223 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
19225 color = getPixelColor(device, 160, 120);
19226 ok(color_match(color, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color);
19227 color = getPixelColor(device, 480, 120);
19228 ok(color_match(color, 0x0000ffff, 2), "Got unexpected color 0x%08x.\n", color);
19229 color = getPixelColor(device, 160, 360);
19230 ok(color_match(color, 0x00000000, 2), "Got unexpected color 0x%08x.\n", color);
19231 color = getPixelColor(device, 480, 360);
19232 ok(color_match(color, 0x0000ffff, 2), "Got unexpected color 0x%08x.\n", color);
19234 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
19235 ok(SUCCEEDED(hr), "Failed to set texture transform flags, hr %#x.\n", hr);
19236 hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_TEXCOORDINDEX, 2);
19237 ok(SUCCEEDED(hr), "Failed to set texcoord index, hr %#x.\n", hr);
19239 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffff00, 1.0f, 0);
19240 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
19242 hr = IDirect3DDevice9_BeginScene(device);
19243 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
19244 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
19245 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
19246 hr = IDirect3DDevice9_EndScene(device);
19247 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
19249 color = getPixelColor(device, 160, 120);
19250 ok(color_match(color, 0x000000ff, 2), "Got unexpected color 0x%08x.\n", color);
19251 color = getPixelColor(device, 480, 120);
19252 ok(color_match(color, 0x0000ffff, 2), "Got unexpected color 0x%08x.\n", color);
19253 color = getPixelColor(device, 160, 360);
19254 ok(color_match(color, 0x00ff00ff, 2), "Got unexpected color 0x%08x.\n", color);
19255 color = getPixelColor(device, 480, 360);
19256 ok(color_match(color, 0x00ffff00, 2), "Got unexpected color 0x%08x.\n", color);
19258 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19259 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
19261 IDirect3DTexture9_Release(texture1);
19262 IDirect3DTexture9_Release(texture2);
19264 refcount = IDirect3DDevice9_Release(device);
19265 ok(!refcount, "Device has %u references left.\n", refcount);
19266 IDirect3D9_Release(d3d9);
19267 DestroyWindow(window);
19270 static void test_vertex_blending(void)
19272 IDirect3DDevice9 *device;
19273 IDirect3D9 *d3d;
19274 D3DCAPS9 caps;
19275 D3DCOLOR color;
19276 ULONG refcount;
19277 HWND window;
19278 HRESULT hr;
19279 int i;
19281 static const D3DMATRIX view_mat =
19283 2.0f / 10.0f, 0.0f, 0.0f, 0.0f,
19284 0.0f, 2.0f / 10.0f, 0.0f, 0.0f,
19285 0.0f, 0.0f, 1.0f, 0.0f,
19286 0.0f, 0.0f, 0.0f, 1.0f
19287 }}},
19288 upper_left =
19290 1.0f, 0.0f, 0.0f, 0.0f,
19291 0.0f, 1.0f, 0.0f, 0.0f,
19292 0.0f, 0.0f, 1.0f, 0.0f,
19293 -4.0f, 4.0f, 0.0f, 1.0f
19294 }}},
19295 lower_left =
19297 1.0f, 0.0f, 0.0f, 0.0f,
19298 0.0f, 1.0f, 0.0f, 0.0f,
19299 0.0f, 0.0f, 1.0f, 0.0f,
19300 -4.0f, -4.0f, 0.0f, 1.0f
19301 }}},
19302 upper_right =
19304 1.0f, 0.0f, 0.0f, 0.0f,
19305 0.0f, 1.0f, 0.0f, 0.0f,
19306 0.0f, 0.0f, 1.0f, 0.0f,
19307 4.0f, 4.0f, 0.0f, 1.0f
19308 }}},
19309 lower_right =
19311 1.0f, 0.0f, 0.0f, 0.0f,
19312 0.0f, 1.0f, 0.0f, 0.0f,
19313 0.0f, 0.0f, 1.0f, 0.0f,
19314 4.0f, -4.0f, 0.0f, 1.0f
19315 }}};
19317 static const POINT quad_upper_right_points[] =
19319 {576, 48}, {-1, -1},
19321 quad_upper_right_empty_points[] =
19323 {64, 48}, {64, 432}, {576, 432}, {320, 240}, {-1, -1}
19325 quad_center_points[] =
19327 {320, 240}, {-1, -1}
19329 quad_center_empty_points[] =
19331 {64, 48}, {576, 48}, {64, 432}, {576, 432}, {-1, -1}
19333 quad_upper_center_points[] =
19335 {320, 48}, {-1, -1}
19337 quad_upper_center_empty_points[] =
19339 {320, 240}, {64, 48}, {576, 48}, {-1, -1}
19341 quad_fullscreen_points[] =
19343 {320, 48}, {320, 240}, {64, 48}, {576, 48}, {64, 432}, {576, 432}, {-1, -1}
19345 quad_fullscreen_empty_points[] =
19347 {-1, -1}
19350 static const struct
19352 struct
19354 struct vec3 position;
19355 struct vec3 blendweights;
19357 vertex_data[4];
19358 const POINT *quad_points;
19359 const POINT *empty_points;
19361 tests[] =
19363 /* upper right */
19365 {{{-1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}},
19366 {{-1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}},
19367 {{ 1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}},
19368 {{ 1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}}},
19369 quad_upper_right_points, quad_upper_right_empty_points
19371 /* center */
19373 {{{-1.0f, -1.0f, 0.0f}, {0.25f, 0.25f, 0.25f}},
19374 {{-1.0f, 1.0f, 0.0f}, {0.25f, 0.25f, 0.25f}},
19375 {{ 1.0f, -1.0f, 0.0f}, {0.25f, 0.25f, 0.25f}},
19376 {{ 1.0f, 1.0f, 0.0f}, {0.25f, 0.25f, 0.25f}}},
19377 quad_center_points, quad_center_empty_points
19379 /* upper center */
19381 {{{-1.0f, -1.0f, 0.0f}, {0.5f, 0.0f, 0.0f}},
19382 {{-1.0f, 1.0f, 0.0f}, {0.5f, 0.0f, 0.0f}},
19383 {{ 1.0f, -1.0f, 0.0f}, {0.5f, 0.0f, 0.0f}},
19384 {{ 1.0f, 1.0f, 0.0f}, {0.5f, 0.0f, 0.0f}}},
19385 quad_upper_center_points, quad_upper_center_empty_points
19387 /* full screen */
19389 {{{-1.0f, -1.0f, 0.0f}, {0.0f, 1.0f, 0.0f}},
19390 {{-1.0f, 1.0f, 0.0f}, {1.0f, 0.0f, 0.0f}},
19391 {{ 1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, 1.0f}},
19392 {{ 1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}}},
19393 quad_fullscreen_points, quad_fullscreen_empty_points
19397 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
19398 0, 0, 640, 480, NULL, NULL, NULL, NULL);
19399 d3d = Direct3DCreate9(D3D_SDK_VERSION);
19400 ok(!!d3d, "Failed to create a D3D object.\n");
19401 if (!(device = create_device(d3d, window, window, TRUE)))
19403 skip("Failed to create a D3D device, skipping tests.\n");
19404 goto done;
19407 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
19408 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
19409 if (caps.MaxVertexBlendMatrices < 4)
19411 skip("Only %u vertex blend matrices supported, skipping tests.\n", caps.MaxVertexBlendMatrices);
19412 IDirect3DDevice9_Release(device);
19413 goto done;
19416 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
19417 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
19419 hr = IDirect3DDevice9_SetTransform(device, D3DTS_VIEW, &view_mat);
19420 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
19422 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(0), &upper_left);
19423 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
19424 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(1), &lower_left);
19425 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
19426 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(2), &lower_right);
19427 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
19428 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLDMATRIX(3), &upper_right);
19429 ok(hr == D3D_OK, "IDirect3DDevice9_SetTransform returned %08x\n", hr);
19431 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_VERTEXBLEND, D3DVBF_3WEIGHTS);
19432 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState failed %08x\n", hr);
19434 for (i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i)
19436 const POINT *point;
19438 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0, 0);
19439 ok(SUCCEEDED(hr), "Failed to clear %08x\n", hr);
19441 hr = IDirect3DDevice9_BeginScene(device);
19442 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
19444 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZB3);
19445 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
19447 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, tests[i].vertex_data, 6 * sizeof(float));
19448 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
19450 hr = IDirect3DDevice9_EndScene(device);
19451 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
19453 point = tests[i].quad_points;
19454 while (point->x != -1 && point->y != -1)
19456 color = getPixelColor(device, point->x, point->y);
19457 ok(color_match(color, 0x00ffffff, 1), "Expected quad at %dx%d.\n", point->x, point->y);
19458 ++point;
19461 point = tests[i].empty_points;
19462 while (point->x != -1 && point->y != -1)
19464 color = getPixelColor(device, point->x, point->y);
19465 ok(color_match(color, 0x00000000, 1), "Unexpected quad at %dx%d.\n", point->x, point->y);
19466 ++point;
19469 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19470 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
19473 refcount = IDirect3DDevice9_Release(device);
19474 ok(!refcount, "Device has %u references left.\n", refcount);
19476 done:
19477 IDirect3D9_Release(d3d);
19478 DestroyWindow(window);
19481 static void test_updatetexture(void)
19483 IDirect3DDevice9 *device;
19484 IDirect3D9 *d3d9;
19485 HWND window;
19486 HRESULT hr;
19487 IDirect3DBaseTexture9 *src, *dst;
19488 unsigned int t, i, f, l, x, y, z;
19489 D3DLOCKED_RECT locked_rect;
19490 D3DLOCKED_BOX locked_box;
19491 ULONG refcount;
19492 D3DCAPS9 caps;
19493 D3DCOLOR color;
19494 BOOL ati2n_supported, do_visual_test;
19495 static const struct
19497 struct vec3 pos;
19498 struct vec2 texcoord;
19500 quad[] =
19502 {{-1.0f, -1.0f, 0.0f}, {0.0f, 1.0f}},
19503 {{-1.0f, 1.0f, 0.0f}, {0.0f, 0.0f}},
19504 {{ 1.0f, -1.0f, 0.0f}, {1.0f, 1.0f}},
19505 {{ 1.0f, 1.0f, 0.0f}, {1.0f, 0.0f}},
19507 static const struct
19509 struct vec3 pos;
19510 struct vec3 texcoord;
19512 quad_cube_tex[] =
19514 {{-1.0f, -1.0f, 0.0f}, {1.0f, -0.5f, 0.5f}},
19515 {{-1.0f, 1.0f, 0.0f}, {1.0f, 0.5f, 0.5f}},
19516 {{ 1.0f, -1.0f, 0.0f}, {1.0f, -0.5f, -0.5f}},
19517 {{ 1.0f, 1.0f, 0.0f}, {1.0f, 0.5f, -0.5f}},
19519 static const struct
19521 UINT src_width, src_height;
19522 UINT dst_width, dst_height;
19523 UINT src_levels, dst_levels;
19524 D3DFORMAT src_format, dst_format;
19525 BOOL broken;
19527 tests[] =
19529 {8, 8, 8, 8, 0, 0, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 0 */
19530 {8, 8, 8, 8, 4, 4, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 1 */
19531 {8, 8, 8, 8, 2, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 2 */
19532 {8, 8, 8, 8, 1, 1, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 3 */
19533 {8, 8, 8, 8, 4, 0, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 4 */
19534 {8, 8, 2, 2, 4, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 5 */
19535 /* The WARP renderer doesn't handle these cases correctly. */
19536 {8, 8, 8, 8, 4, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, TRUE}, /* 6 */
19537 {8, 8, 4, 4, 4, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, TRUE}, /* 7 */
19538 /* Not clear what happens here on Windows, it doesn't make much sense
19539 * though (on Nvidia it seems to upload the 4x4 surface into the 7x7
19540 * one or something like that). */
19541 /* {8, 8, 7, 7, 4, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, */
19542 {8, 8, 8, 8, 1, 4, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 8 */
19543 {4, 4, 8, 8, 1, 1, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 9 */
19544 /* This one causes weird behavior on Windows (it probably writes out
19545 * of the texture memory). */
19546 /* {8, 8, 4, 4, 1, 1, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, */
19547 {8, 4, 4, 2, 4, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 10 */
19548 {8, 4, 2, 4, 4, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 11 */
19549 {8, 8, 8, 8, 4, 4, D3DFMT_A8R8G8B8, D3DFMT_X8R8G8B8, FALSE}, /* 12 */
19550 {8, 8, 8, 8, 4, 4, D3DFMT_X8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 13 */
19551 /* The data is converted correctly on AMD, on Nvidia nothing happens
19552 * (it draws a black quad). */
19553 {8, 8, 8, 8, 4, 4, D3DFMT_A8R8G8B8, D3DFMT_R5G6B5, TRUE}, /* 14 */
19554 /* Here the data is converted on AMD, just copied and "reinterpreted" as
19555 * a 32 bit float on Nvidia (specifically the tested value becomes a
19556 * very small float number which we get as 0 in the test). */
19557 {8, 8, 8, 8, 4, 4, D3DFMT_A8R8G8B8, D3DFMT_R32F, TRUE}, /* 15 */
19558 /* This one doesn't seem to give the expected results on AMD. */
19559 /* {8, 8, 8, 8, 4, 4, D3DFMT_A8R8G8B8, D3DFMT_Q8W8V8U8, FALSE}, */
19560 {8, 8, 8, 8, 4, 4, MAKEFOURCC('A','T','I','2'), MAKEFOURCC('A','T','I','2'), FALSE}, /* 16 */
19561 {8, 8, 8, 8, 4, 2, MAKEFOURCC('A','T','I','2'), MAKEFOURCC('A','T','I','2'), FALSE}, /* 17 */
19562 {8, 8, 2, 2, 4, 2, MAKEFOURCC('A','T','I','2'), MAKEFOURCC('A','T','I','2'), FALSE}, /* 18 */
19564 static const struct
19566 D3DRESOURCETYPE type;
19567 DWORD fvf;
19568 const void *quad;
19569 unsigned int vertex_size;
19570 DWORD cap;
19571 const char *name;
19573 texture_types[] =
19575 {D3DRTYPE_TEXTURE, D3DFVF_XYZ | D3DFVF_TEX1,
19576 quad, sizeof(*quad), D3DPTEXTURECAPS_MIPMAP, "2D mipmapped"},
19578 {D3DRTYPE_CUBETEXTURE, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE3(0),
19579 quad_cube_tex, sizeof(*quad_cube_tex), D3DPTEXTURECAPS_CUBEMAP, "Cube"},
19581 {D3DRTYPE_VOLUMETEXTURE, D3DFVF_XYZ | D3DFVF_TEX1,
19582 quad, sizeof(*quad), D3DPTEXTURECAPS_VOLUMEMAP, "Volume"}
19585 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
19586 0, 0, 640, 480, NULL, NULL, NULL, NULL);
19587 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
19588 ok(!!d3d9, "Failed to create a D3D object.\n");
19589 if (!(device = create_device(d3d9, window, window, TRUE)))
19591 skip("Failed to create a D3D device, skipping tests.\n");
19592 IDirect3D9_Release(d3d9);
19593 DestroyWindow(window);
19594 return;
19597 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
19598 ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
19600 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
19601 ok(SUCCEEDED(hr), "Failed to set texture filtering state, hr %#x.\n", hr);
19602 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
19603 ok(SUCCEEDED(hr), "Failed to set texture clamping state, hr %#x.\n", hr);
19604 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
19605 ok(SUCCEEDED(hr), "Failed to set texture clamping state, hr %#x.\n", hr);
19606 hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_ADDRESSW, D3DTADDRESS_CLAMP);
19607 ok(SUCCEEDED(hr), "Failed to set texture clamping state, hr %#x.\n", hr);
19608 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
19609 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
19610 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
19611 ok(hr == D3D_OK, "Failed to set texture stage state, hr %#x.\n", hr);
19612 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
19613 ok(hr == D3D_OK, "Failed to set texture stage state, hr %#x.\n", hr);
19615 for (t = 0; t < sizeof(texture_types) / sizeof(*texture_types); ++t)
19617 if (!(caps.TextureCaps & texture_types[t].cap))
19619 skip("%s textures not supported, skipping some tests.\n", texture_types[t].name);
19620 continue;
19623 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
19624 D3DFMT_X8R8G8B8, 0, texture_types[t].type, MAKEFOURCC('A','T','I','2'))))
19626 skip("%s ATI2N textures are not supported, skipping some tests.\n", texture_types[t].name);
19627 ati2n_supported = FALSE;
19629 else
19631 ati2n_supported = TRUE;
19634 hr = IDirect3DDevice9_SetFVF(device, texture_types[t].fvf);
19635 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
19637 for (i = 0; i < sizeof(tests) / sizeof(*tests); ++i)
19639 if (tests[i].src_format == MAKEFOURCC('A','T','I','2') && !ati2n_supported)
19640 continue;
19642 switch (texture_types[t].type)
19644 case D3DRTYPE_TEXTURE:
19645 hr = IDirect3DDevice9_CreateTexture(device,
19646 tests[i].src_width, tests[i].src_height,
19647 tests[i].src_levels, 0, tests[i].src_format, D3DPOOL_SYSTEMMEM,
19648 (IDirect3DTexture9 **)&src, NULL);
19649 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x, case %u, %u.\n", hr, t, i);
19650 hr = IDirect3DDevice9_CreateTexture(device,
19651 tests[i].dst_width, tests[i].dst_height,
19652 tests[i].dst_levels, 0, tests[i].dst_format, D3DPOOL_DEFAULT,
19653 (IDirect3DTexture9 **)&dst, NULL);
19654 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x, case %u, %u.\n", hr, t, i);
19655 break;
19656 case D3DRTYPE_CUBETEXTURE:
19657 hr = IDirect3DDevice9_CreateCubeTexture(device,
19658 tests[i].src_width,
19659 tests[i].src_levels, 0, tests[i].src_format, D3DPOOL_SYSTEMMEM,
19660 (IDirect3DCubeTexture9 **)&src, NULL);
19661 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x, case %u, %u.\n", hr, t, i);
19662 hr = IDirect3DDevice9_CreateCubeTexture(device,
19663 tests[i].dst_width,
19664 tests[i].dst_levels, 0, tests[i].dst_format, D3DPOOL_DEFAULT,
19665 (IDirect3DCubeTexture9 **)&dst, NULL);
19666 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x, case %u, %u.\n", hr, t, i);
19667 break;
19668 case D3DRTYPE_VOLUMETEXTURE:
19669 hr = IDirect3DDevice9_CreateVolumeTexture(device,
19670 tests[i].src_width, tests[i].src_height, tests[i].src_width,
19671 tests[i].src_levels, 0, tests[i].src_format, D3DPOOL_SYSTEMMEM,
19672 (IDirect3DVolumeTexture9 **)&src, NULL);
19673 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x, case %u, %u.\n", hr, t, i);
19674 hr = IDirect3DDevice9_CreateVolumeTexture(device,
19675 tests[i].dst_width, tests[i].dst_height, tests[i].dst_width,
19676 tests[i].dst_levels, 0, tests[i].dst_format, D3DPOOL_DEFAULT,
19677 (IDirect3DVolumeTexture9 **)&dst, NULL);
19678 ok(SUCCEEDED(hr), "Failed to create texture, hr %#x, case %u, %u.\n", hr, t, i);
19679 break;
19680 default:
19681 trace("Unexpected resource type.\n");
19684 /* Skip the visual part of the test for ATI2N (laziness) and cases that
19685 * give a different (and unlikely to be useful) result. */
19686 do_visual_test = (tests[i].src_format == D3DFMT_A8R8G8B8 || tests[i].src_format == D3DFMT_X8R8G8B8)
19687 && tests[i].src_levels != 0
19688 && tests[i].src_width >= tests[i].dst_width && tests[i].src_height >= tests[i].dst_height
19689 && !(tests[i].src_width > tests[i].src_height && tests[i].dst_width < tests[i].dst_height);
19691 if (do_visual_test)
19693 DWORD *ptr = NULL;
19694 unsigned int width, height, depth, row_pitch = 0, slice_pitch = 0;
19696 for (f = 0; f < (texture_types[t].type == D3DRTYPE_CUBETEXTURE ? 6 : 1); ++f)
19698 width = tests[i].src_width;
19699 height = texture_types[t].type != D3DRTYPE_CUBETEXTURE ? tests[i].src_height : tests[i].src_width;
19700 depth = texture_types[t].type == D3DRTYPE_VOLUMETEXTURE ? width : 1;
19702 for (l = 0; l < tests[i].src_levels; ++l)
19704 switch (texture_types[t].type)
19706 case D3DRTYPE_TEXTURE:
19707 hr = IDirect3DTexture9_LockRect((IDirect3DTexture9 *)src,
19708 l, &locked_rect, NULL, 0);
19709 ptr = locked_rect.pBits;
19710 row_pitch = locked_rect.Pitch / sizeof(*ptr);
19711 break;
19712 case D3DRTYPE_CUBETEXTURE:
19713 hr = IDirect3DCubeTexture9_LockRect((IDirect3DCubeTexture9 *)src,
19714 f, l, &locked_rect, NULL, 0);
19715 ptr = locked_rect.pBits;
19716 row_pitch = locked_rect.Pitch / sizeof(*ptr);
19717 break;
19718 case D3DRTYPE_VOLUMETEXTURE:
19719 hr = IDirect3DVolumeTexture9_LockBox((IDirect3DVolumeTexture9 *)src,
19720 l, &locked_box, NULL, 0);
19721 ptr = locked_box.pBits;
19722 row_pitch = locked_box.RowPitch / sizeof(*ptr);
19723 slice_pitch = locked_box.SlicePitch / sizeof(*ptr);
19724 break;
19725 default:
19726 trace("Unexpected resource type.\n");
19728 ok(SUCCEEDED(hr), "Failed to lock texture, hr %#x.\n", hr);
19730 for (z = 0; z < depth; ++z)
19732 for (y = 0; y < height; ++y)
19734 for (x = 0; x < width; ++x)
19736 ptr[z * slice_pitch + y * row_pitch + x] = 0xff000000
19737 | (DWORD)(x / (width - 1.0f) * 255.0f) << 16
19738 | (DWORD)(y / (height - 1.0f) * 255.0f) << 8;
19743 switch (texture_types[t].type)
19745 case D3DRTYPE_TEXTURE:
19746 hr = IDirect3DTexture9_UnlockRect((IDirect3DTexture9 *)src, l);
19747 break;
19748 case D3DRTYPE_CUBETEXTURE:
19749 hr = IDirect3DCubeTexture9_UnlockRect((IDirect3DCubeTexture9 *)src, f, l);
19750 break;
19751 case D3DRTYPE_VOLUMETEXTURE:
19752 hr = IDirect3DVolumeTexture9_UnlockBox((IDirect3DVolumeTexture9 *)src, l);
19753 break;
19754 default:
19755 trace("Unexpected resource type.\n");
19757 ok(SUCCEEDED(hr), "Failed to unlock texture, hr %#x.\n", hr);
19759 width >>= 1;
19760 if (!width)
19761 width = 1;
19762 height >>= 1;
19763 if (!height)
19764 height = 1;
19765 depth >>= 1;
19766 if (!depth)
19767 depth = 1;
19772 hr = IDirect3DDevice9_UpdateTexture(device, src, dst);
19773 if (FAILED(hr))
19775 todo_wine ok(SUCCEEDED(hr), "Failed to update texture, hr %#x, case %u, %u.\n", hr, t, i);
19776 IDirect3DBaseTexture9_Release(src);
19777 IDirect3DBaseTexture9_Release(dst);
19778 continue;
19780 ok(SUCCEEDED(hr), "Failed to update texture, hr %#x, case %u, %u.\n", hr, t, i);
19782 if (do_visual_test)
19784 hr = IDirect3DDevice9_SetTexture(device, 0, dst);
19785 ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
19787 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 1.0f, 0);
19788 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
19790 hr = IDirect3DDevice9_BeginScene(device);
19791 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
19792 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2,
19793 texture_types[t].quad, texture_types[t].vertex_size);
19794 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
19795 hr = IDirect3DDevice9_EndScene(device);
19796 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
19798 color = getPixelColor(device, 320, 240);
19799 ok (color_match(color, 0x007f7f00, 2) || broken(tests[i].broken)
19800 || broken(color == 0x00adbeef), /* WARP device often just breaks down. */
19801 "Got unexpected color 0x%08x, case %u, %u.\n", color, t, i);
19804 IDirect3DBaseTexture9_Release(src);
19805 IDirect3DBaseTexture9_Release(dst);
19808 refcount = IDirect3DDevice9_Release(device);
19809 ok(!refcount, "Device has %u references left.\n", refcount);
19810 IDirect3D9_Release(d3d9);
19811 DestroyWindow(window);
19814 static void test_depthbias(void)
19816 IDirect3DDevice9 *device;
19817 IDirect3D9 *d3d;
19818 IDirect3DSurface9 *ds;
19819 D3DCAPS9 caps;
19820 D3DCOLOR color;
19821 ULONG refcount;
19822 HWND window;
19823 HRESULT hr;
19824 unsigned int i;
19825 static const D3DFORMAT formats[] =
19827 D3DFMT_D16, D3DFMT_D24X8, D3DFMT_D32, D3DFMT_D24S8, MAKEFOURCC('I','N','T','Z'),
19829 /* The scaling factor detection function detects the wrong factor for
19830 * float formats on Nvidia, therefore the following tests are disabled.
19831 * The wined3d function detects 2^23 like for fixed point formats but
19832 * the test needs 2^22 to pass.
19834 * AMD GPUs need a different scaling factor for float depth buffers
19835 * (2^24) than fixed point (2^23), but the wined3d detection function
19836 * works there, producing the right result in the test.
19838 * D3DFMT_D32F_LOCKABLE, D3DFMT_D24FS8,
19842 static const struct
19844 struct vec3 position;
19846 quad[] =
19848 {{-1.0f, -1.0f, 0.0f}},
19849 {{-1.0f, 1.0f, 0.0f}},
19850 {{ 1.0f, -1.0f, 1.0f}},
19851 {{ 1.0f, 1.0f, 1.0f}},
19853 union
19855 float f;
19856 DWORD d;
19857 } conv;
19859 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
19860 0, 0, 640, 480, NULL, NULL, NULL, NULL);
19861 d3d = Direct3DCreate9(D3D_SDK_VERSION);
19862 ok(!!d3d, "Failed to create a D3D object.\n");
19863 if (!(device = create_device(d3d, window, window, TRUE)))
19865 skip("Failed to create a D3D device, skipping tests.\n");
19866 goto done;
19869 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
19870 ok(SUCCEEDED(hr), "Failed to get device caps, hr %#x.\n", hr);
19871 if (!(caps.RasterCaps & D3DPRASTERCAPS_DEPTHBIAS))
19873 IDirect3DDevice9_Release(device);
19874 skip("D3DPRASTERCAPS_DEPTHBIAS not supported.\n");
19875 goto done;
19878 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
19879 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
19880 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZWRITEENABLE, FALSE);
19881 ok(hr == D3D_OK, "IDirect3DDevice9_SetRenderState returned %08x\n", hr);
19882 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP,D3DTOP_SELECTARG1);
19883 ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
19884 hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TFACTOR);
19885 ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
19886 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
19887 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
19889 for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
19891 if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
19892 D3DFMT_X8R8G8B8, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, formats[i])))
19894 skip("Depth format %u not supported, skipping.\n", formats[i]);
19895 continue;
19898 hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, formats[i],
19899 D3DMULTISAMPLE_NONE, 0, FALSE, &ds, NULL);
19900 ok(SUCCEEDED(hr), "Failed to create depth stencil surface, hr %#x.\n", hr);
19901 hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds);
19902 ok(SUCCEEDED(hr), "Failed to set depth stencil surface, hr %#x.\n", hr);
19903 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 0.5f, 0);
19904 ok(SUCCEEDED(hr), "Failed to clear %08x\n", hr);
19906 hr = IDirect3DDevice9_BeginScene(device);
19907 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
19909 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x00ff0000);
19910 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
19911 conv.f = -0.2f;
19912 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DEPTHBIAS, conv.d);
19913 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
19914 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
19915 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
19917 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x0000ff00);
19918 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
19919 conv.f = 0.0f;
19920 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DEPTHBIAS, conv.d);
19921 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
19922 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
19923 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
19925 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x000000ff);
19926 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
19927 conv.f = 0.2f;
19928 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DEPTHBIAS, conv.d);
19929 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
19930 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
19931 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
19933 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x00ffffff);
19934 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
19935 conv.f = 0.4f;
19936 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_DEPTHBIAS, conv.d);
19937 ok(SUCCEEDED(hr), "Failed to set render state, hr %#x.\n", hr);
19938 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
19939 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
19941 color = getPixelColor(device, 61, 240);
19942 ok(color_match(color, 0x00ffffff, 1), "Got unexpected color %08x at x=62, format %u.\n", color, formats[i]);
19943 color = getPixelColor(device, 65, 240);
19945 /* The broken results are for the WARP driver on the testbot. It seems to initialize
19946 * a scaling factor based on the first depth format that is used. Other formats with
19947 * a different depth size then render incorrectly. */
19948 ok(color_match(color, 0x000000ff, 1) || broken(color_match(color, 0x00ffffff, 1)),
19949 "Got unexpected color %08x at x=64, format %u.\n", color, formats[i]);
19950 color = getPixelColor(device, 190, 240);
19951 ok(color_match(color, 0x000000ff, 1) || broken(color_match(color, 0x00ffffff, 1)),
19952 "Got unexpected color %08x at x=190, format %u.\n", color, formats[i]);
19954 color = getPixelColor(device, 194, 240);
19955 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ffffff, 1)),
19956 "Got unexpected color %08x at x=194, format %u.\n", color, formats[i]);
19957 color = getPixelColor(device, 318, 240);
19958 ok(color_match(color, 0x0000ff00, 1) || broken(color_match(color, 0x00ffffff, 1)),
19959 "Got unexpected color %08x at x=318, format %u.\n", color, formats[i]);
19961 color = getPixelColor(device, 322, 240);
19962 ok(color_match(color, 0x00ff0000, 1) || broken(color_match(color, 0x00000000, 1)),
19963 "Got unexpected color %08x at x=322, format %u.\n", color, formats[i]);
19964 color = getPixelColor(device, 446, 240);
19965 ok(color_match(color, 0x00ff0000, 1) || broken(color_match(color, 0x00000000, 1)),
19966 "Got unexpected color %08x at x=446, format %u.\n", color, formats[i]);
19968 color = getPixelColor(device, 450, 240);
19969 ok(color_match(color, 0x00000000, 1), "Got unexpected color %08x at x=446, format %u.\n", color, formats[i]);
19971 hr = IDirect3DDevice9_EndScene(device);
19972 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
19974 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
19975 ok(hr == D3D_OK, "IDirect3DDevice9_Present failed with %08x\n", hr);
19976 IDirect3DSurface9_Release(ds);
19979 refcount = IDirect3DDevice9_Release(device);
19980 ok(!refcount, "Device has %u references left.\n", refcount);
19982 done:
19983 IDirect3D9_Release(d3d);
19984 DestroyWindow(window);
19987 static void test_flip(void)
19989 IDirect3DDevice9 *device;
19990 IDirect3D9 *d3d;
19991 ULONG refcount;
19992 HWND window;
19993 HRESULT hr;
19994 IDirect3DSurface9 *back_buffers[3], *test_surface;
19995 unsigned int i;
19996 D3DCOLOR color;
19997 D3DPRESENT_PARAMETERS present_parameters = {0};
19999 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW,
20000 0, 0, 640, 480, NULL, NULL, NULL, NULL);
20001 d3d = Direct3DCreate9(D3D_SDK_VERSION);
20002 ok(!!d3d, "Failed to create a D3D object.\n");
20004 present_parameters.BackBufferWidth = 640;
20005 present_parameters.BackBufferHeight = 480;
20006 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
20007 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
20008 present_parameters.hDeviceWindow = window;
20009 present_parameters.Windowed = TRUE;
20010 present_parameters.BackBufferCount = 3;
20011 present_parameters.Flags = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER;
20012 hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
20013 window, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device);
20014 if (!device)
20016 skip("Failed to create a D3D device, skipping tests.\n");
20017 IDirect3D9_Release(d3d);
20018 DestroyWindow(window);
20019 return;
20022 for (i = 0; i < sizeof(back_buffers) / sizeof(*back_buffers); ++i)
20024 hr = IDirect3DDevice9_GetBackBuffer(device, 0, i, D3DBACKBUFFER_TYPE_MONO, &back_buffers[i]);
20025 ok(SUCCEEDED(hr), "Failed to get back buffer, hr %#x.\n", hr);
20027 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &test_surface);
20028 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
20029 ok(test_surface == back_buffers[0], "Expected render target %p, got %p.\n", back_buffers[0], test_surface);
20030 IDirect3DSurface9_Release(test_surface);
20032 hr = IDirect3DDevice9_SetRenderTarget(device, 0, back_buffers[2]);
20033 ok(SUCCEEDED(hr), "Failed to set render target, hr %#x.\n", hr);
20035 hr = IDirect3DDevice9_ColorFill(device, back_buffers[0], NULL, 0xffff0000);
20036 ok(SUCCEEDED(hr), "Failed to color fill, hr %#x.\n", hr);
20037 hr = IDirect3DDevice9_ColorFill(device, back_buffers[1], NULL, 0xff00ff00);
20038 ok(SUCCEEDED(hr), "Failed to color fill, hr %#x.\n", hr);
20039 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0f, 0);
20040 ok(SUCCEEDED(hr), "Failed to clear, hr %#x\n", hr);
20042 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
20043 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
20045 /* Render target is unmodified. */
20046 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &test_surface);
20047 ok(SUCCEEDED(hr), "Failed to get render target, hr %#x.\n", hr);
20048 ok(test_surface == back_buffers[2], "Expected render target %p, got %p.\n", back_buffers[2], test_surface);
20049 IDirect3DSurface9_Release(test_surface);
20051 /* Backbuffer surface pointers are unmodified */
20052 for (i = 0; i < sizeof(back_buffers) / sizeof(*back_buffers); ++i)
20054 hr = IDirect3DDevice9_GetBackBuffer(device, 0, i, D3DBACKBUFFER_TYPE_MONO, &test_surface);
20055 ok(SUCCEEDED(hr), "Failed to get back buffer, hr %#x.\n", hr);
20056 ok(test_surface == back_buffers[i], "Expected back buffer %u = %p, got %p.\n",
20057 i, back_buffers[i], test_surface);
20058 IDirect3DSurface9_Release(test_surface);
20061 /* Contents were changed. */
20062 color = getPixelColorFromSurface(back_buffers[0], 1, 1);
20063 todo_wine ok(color == 0xff00ff00, "Got unexpected color 0x%08x.\n", color);
20064 color = getPixelColorFromSurface(back_buffers[1], 1, 1);
20065 todo_wine ok(color == 0xff0000ff, "Got unexpected color 0x%08x.\n", color);
20067 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff808080, 0.0f, 0);
20068 ok(SUCCEEDED(hr), "Failed to clear, hr %#x\n", hr);
20070 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
20071 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
20073 color = getPixelColorFromSurface(back_buffers[0], 1, 1);
20074 todo_wine ok(color == 0xff0000ff, "Got unexpected color 0x%08x.\n", color);
20075 color = getPixelColorFromSurface(back_buffers[1], 1, 1);
20076 todo_wine ok(color == 0xff808080, "Got unexpected color 0x%08x.\n", color);
20078 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
20079 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
20081 color = getPixelColorFromSurface(back_buffers[0], 1, 1);
20082 todo_wine ok(color == 0xff808080, "Got unexpected color 0x%08x.\n", color);
20084 for (i = 0; i < sizeof(back_buffers) / sizeof(*back_buffers); ++i)
20085 IDirect3DSurface9_Release(back_buffers[i]);
20087 refcount = IDirect3DDevice9_Release(device);
20088 ok(!refcount, "Device has %u references left.\n", refcount);
20089 IDirect3D9_Release(d3d);
20090 DestroyWindow(window);
20093 static void test_uninitialized_varyings(void)
20095 static const D3DMATRIX mat =
20097 1.0f, 0.0f, 0.0f, 0.0f,
20098 0.0f, 1.0f, 0.0f, 0.0f,
20099 0.0f, 0.0f, 1.0f, 0.0f,
20100 0.0f, 0.0f, 0.0f, 1.0f,
20101 }}};
20102 static const struct vec3 quad[] =
20104 {-1.0f, -1.0f, 0.1f},
20105 {-1.0f, 1.0f, 0.1f},
20106 { 1.0f, -1.0f, 0.1f},
20107 { 1.0f, 1.0f, 0.1f},
20109 static const DWORD vs1_code[] =
20111 0xfffe0101, /* vs_1_1 */
20112 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
20113 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
20114 0x0000ffff
20116 static const DWORD vs1_partial_code[] =
20118 0xfffe0101, /* vs_1_1 */
20119 0x0000001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
20120 0x00000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, /* def c0, 0.5, 0.5, 0.5, 0.5 */
20121 0x00000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
20122 0x00000001, 0xd0010000, 0xa0e40000, /* mov oD0.x, c0 */
20123 0x00000001, 0xd0010001, 0xa0e40000, /* mov oD1.x, c0 */
20124 0x00000001, 0xe0010000, 0xa0e40000, /* mov oT0.x, c0 */
20125 0x0000ffff
20127 static const DWORD vs2_code[] =
20129 0xfffe0200, /* vs_2_0 */
20130 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
20131 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
20132 0x0000ffff
20134 static const DWORD vs2_partial_code[] =
20136 0xfffe0200, /* vs_2_0 */
20137 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
20138 0x05000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, /* def c0, 0.5, 0.5, 0.5, 0.5 */
20139 0x02000001, 0xc00f0000, 0x90e40000, /* mov oPos, v0 */
20140 0x02000001, 0xd0010000, 0xa0e40000, /* mov oD0.x, c0 */
20141 0x02000001, 0xd0010001, 0xa0e40000, /* mov oD1.x, c0 */
20142 0x02000001, 0xe0010000, 0xa0e40000, /* mov oT0.x, c0 */
20143 0x0000ffff
20145 static const DWORD vs3_code[] =
20147 0xfffe0300, /* vs_3_0 */
20148 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
20149 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
20150 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
20151 0x0000ffff
20153 static const DWORD vs3_partial_code[] =
20155 0xfffe0300, /* vs_3_0 */
20156 0x0200001f, 0x80000000, 0x900f0000, /* dcl_position v0 */
20157 0x0200001f, 0x80000000, 0xe00f0000, /* dcl_position o0 */
20158 0x0200001f, 0x8000000a, 0xe00f0001, /* dcl_color0 o1 */
20159 0x0200001f, 0x8001000a, 0xe00f0002, /* dcl_color1 o2 */
20160 0x0200001f, 0x80000005, 0xe00f0003, /* dcl_texcoord0 o3 */
20161 0x05000051, 0xa00f0000, 0x3f000000, 0x3f000000, 0x3f000000, 0x3f000000, /* def c0, 0.5, 0.5, 0.5, 0.5 */
20162 0x02000001, 0xe00f0000, 0x90e40000, /* mov o0, v0 */
20163 0x02000001, 0xe0010001, 0xa0e40000, /* mov o1.x, c0 */
20164 0x02000001, 0xe0010002, 0xa0e40000, /* mov o2.x, c0 */
20165 0x02000001, 0xe0010003, 0xa0e40000, /* mov o3.x, c0 */
20166 0x0000ffff
20168 static const DWORD ps1_diffuse_code[] =
20170 0xffff0101, /* ps_1_1 */
20171 0x00000001, 0x800f0000, 0x90e40000, /* mov r0, v0 */
20172 0x0000ffff
20174 static const DWORD ps1_specular_code[] =
20176 0xffff0101, /* ps_1_1 */
20177 0x00000001, 0x800f0000, 0x90e40001, /* mov r0, v1 */
20178 0x0000ffff
20180 static const DWORD ps1_texcoord_code[] =
20182 0xffff0101, /* ps_1_1 */
20183 0x00000040, 0xb00f0000, /* texcoord t0 */
20184 0x00000001, 0x800f0000, 0xb0e40000, /* mov r0, t0 */
20185 0x0000ffff
20187 static const DWORD ps2_diffuse_code[] =
20189 0xffff0200, /* ps_2_0 */
20190 0x0200001f, 0x80000000, 0x900f0000, /* dcl v0 */
20191 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
20192 0x0000ffff
20194 static const DWORD ps2_specular_code[] =
20196 0xffff0200, /* ps_2_0 */
20197 0x0200001f, 0x80000000, 0x900f0001, /* dcl v1 */
20198 0x02000001, 0x800f0800, 0x90e40001, /* mov oC0, v1 */
20199 0x0000ffff
20201 static const DWORD ps2_texcoord_code[] =
20203 0xffff0200, /* ps_2_0 */
20204 0x0200001f, 0x80000000, 0xb00f0000, /* dcl t0 */
20205 0x02000001, 0x800f0800, 0xb0e40000, /* mov oC0, t0 */
20206 0x0000ffff
20208 static const DWORD ps3_diffuse_code[] =
20210 0xffff0300, /* ps_3_0 */
20211 0x0200001f, 0x8000000a, 0x900f0000, /* dcl_color0 v0 */
20212 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
20213 0x0000ffff
20215 static const DWORD ps3_specular_code[] =
20217 0xffff0300, /* ps_3_0 */
20218 0x0200001f, 0x8001000a, 0x900f0001, /* dcl_color1 v1 */
20219 0x02000001, 0x800f0800, 0x90e40001, /* mov oC0, v1 */
20220 0x0000ffff
20222 static const DWORD ps3_texcoord_code[] =
20224 0xffff0300, /* ps_3_0 */
20225 0x0200001f, 0x80000005, 0x900f0000, /* dcl_texcoord0 v0 */
20226 0x02000001, 0x800f0800, 0x90e40000, /* mov oC0, v0 */
20227 0x0000ffff
20229 static const struct
20231 DWORD vs_version;
20232 const DWORD *vs;
20233 DWORD ps_version;
20234 const DWORD *ps;
20235 D3DCOLOR expected;
20236 BOOL allow_zero_alpha;
20237 BOOL allow_zero;
20238 BOOL broken_warp;
20240 /* On AMD specular color is generally initialized to 0x00000000 and texcoords to 0xff000000
20241 * while on Nvidia it's the opposite. Just allow both. */
20242 tests[] =
20244 {D3DVS_VERSION(1, 1), vs1_code, 0, NULL, 0xffffffff},
20245 { 0, NULL, D3DPS_VERSION(1, 1), ps1_texcoord_code, 0xff000000, TRUE},
20246 { 0, NULL, D3DPS_VERSION(2, 0), ps2_texcoord_code, 0xff000000, TRUE},
20247 {D3DVS_VERSION(1, 1), vs1_code, D3DPS_VERSION(1, 1), ps1_diffuse_code, 0xffffffff},
20248 {D3DVS_VERSION(1, 1), vs1_code, D3DPS_VERSION(1, 1), ps1_specular_code, 0xff000000, TRUE, FALSE, TRUE},
20249 {D3DVS_VERSION(1, 1), vs1_code, D3DPS_VERSION(1, 1), ps1_texcoord_code, 0xff000000, TRUE},
20250 {D3DVS_VERSION(2, 0), vs2_code, D3DPS_VERSION(2, 0), ps2_diffuse_code, 0xffffffff},
20251 {D3DVS_VERSION(2, 0), vs2_code, D3DPS_VERSION(2, 0), ps2_specular_code, 0xff000000, TRUE, FALSE, TRUE},
20252 {D3DVS_VERSION(2, 0), vs2_code, D3DPS_VERSION(2, 0), ps2_texcoord_code, 0xff000000, TRUE},
20253 {D3DVS_VERSION(3, 0), vs3_code, D3DPS_VERSION(3, 0), ps3_diffuse_code, 0xffffffff, FALSE, TRUE},
20254 {D3DVS_VERSION(3, 0), vs3_code, D3DPS_VERSION(3, 0), ps3_specular_code, 0x00000000, FALSE, FALSE, TRUE},
20255 {D3DVS_VERSION(3, 0), vs3_code, D3DPS_VERSION(3, 0), ps3_texcoord_code, 0x00000000, FALSE, FALSE, TRUE},
20256 {D3DVS_VERSION(1, 1), vs1_partial_code, 0, NULL, 0xff7fffff, FALSE, FALSE, TRUE},
20257 {D3DVS_VERSION(1, 1), vs1_partial_code, D3DPS_VERSION(1, 1), ps1_diffuse_code, 0xff7fffff, FALSE, FALSE, TRUE},
20258 {D3DVS_VERSION(1, 1), vs1_partial_code, D3DPS_VERSION(1, 1), ps1_specular_code, 0xff7f0000, TRUE},
20259 {D3DVS_VERSION(1, 1), vs1_partial_code, D3DPS_VERSION(1, 1), ps1_texcoord_code, 0xff7f0000, TRUE},
20260 {D3DVS_VERSION(2, 0), vs2_partial_code, D3DPS_VERSION(2, 0), ps2_diffuse_code, 0xff7fffff, FALSE, FALSE, TRUE},
20261 {D3DVS_VERSION(2, 0), vs2_partial_code, D3DPS_VERSION(2, 0), ps2_specular_code, 0xff7f0000, TRUE},
20262 {D3DVS_VERSION(2, 0), vs2_partial_code, D3DPS_VERSION(2, 0), ps2_texcoord_code, 0xff7f0000, TRUE},
20263 /* Fails on Radeon HD 2600 with 0x008000ff aka nonsensical color. */
20264 /* {D3DVS_VERSION(3, 0), vs3_partial_code, D3DPS_VERSION(3, 0), ps3_diffuse_code, 0xff7fffff, TRUE}, */
20265 /* Randomly fails on Radeon HD 2600. */
20266 /* {D3DVS_VERSION(3, 0), vs3_partial_code, D3DPS_VERSION(3, 0), ps3_specular_code, 0x007f0000}, */
20267 {D3DVS_VERSION(3, 0), vs3_partial_code, D3DPS_VERSION(3, 0), ps3_texcoord_code, 0xff7f0000, TRUE},
20269 IDirect3DDevice9 *device;
20270 IDirect3D9 *d3d;
20271 HWND window;
20272 HRESULT hr;
20273 D3DADAPTER_IDENTIFIER9 identifier;
20274 IDirect3DSurface9 *backbuffer;
20275 struct surface_readback rb;
20276 IDirect3DVertexShader9 *vs;
20277 IDirect3DPixelShader9 *ps;
20278 unsigned int i;
20279 ULONG refcount;
20280 D3DCAPS9 caps;
20281 D3DCOLOR color;
20282 BOOL warp;
20284 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
20285 0, 0, 640, 480, NULL, NULL, NULL, NULL);
20286 d3d = Direct3DCreate9(D3D_SDK_VERSION);
20287 ok(!!d3d, "Failed to create a D3D object.\n");
20288 if (!(device = create_device(d3d, window, window, TRUE)))
20290 skip("Failed to create a D3D device, skipping tests.\n");
20291 IDirect3D9_Release(d3d);
20292 DestroyWindow(window);
20293 return;
20296 hr = IDirect3D9_GetAdapterIdentifier(d3d, D3DADAPTER_DEFAULT, 0, &identifier);
20297 ok(SUCCEEDED(hr), "Failed to get adapter identifier, hr %#x.\n", hr);
20298 warp = adapter_is_warp(&identifier);
20300 hr = IDirect3DDevice9_GetDeviceCaps(device, &caps);
20301 ok(SUCCEEDED(hr), "Failed to get caps, hr %#x.\n", hr);
20303 hr = IDirect3DDevice9_GetRenderTarget(device, 0, &backbuffer);
20304 ok(SUCCEEDED(hr), "Failed to get backbuffer, hr %#x.\n", hr);
20306 hr = IDirect3DDevice9_SetTransform(device, D3DTS_WORLD, &mat);
20307 ok(SUCCEEDED(hr), "Failed to set world transform, hr %#x.\n", hr);
20308 hr = IDirect3DDevice9_SetTransform(device, D3DTS_VIEW, &mat);
20309 ok(SUCCEEDED(hr), "Failed to set view transform, hr %#x.\n", hr);
20310 hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &mat);
20311 ok(SUCCEEDED(hr), "Failed to set projection transform, hr %#x.\n", hr);
20312 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CLIPPING, FALSE);
20313 ok(SUCCEEDED(hr), "Failed to disable clipping, hr %#x.\n", hr);
20314 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, FALSE);
20315 ok(SUCCEEDED(hr), "Failed to disable Z test, hr %#x.\n", hr);
20316 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGENABLE, FALSE);
20317 ok(SUCCEEDED(hr), "Failed to disable fog, hr %#x.\n", hr);
20318 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_STENCILENABLE, FALSE);
20319 ok(SUCCEEDED(hr), "Failed to disable stencil test, hr %#x.\n", hr);
20320 hr = IDirect3DDevice9_SetRenderState(device, D3DRS_CULLMODE, D3DCULL_NONE);
20321 ok(SUCCEEDED(hr), "Failed to disable culling, hr %#x.\n", hr);
20323 hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
20324 ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
20326 for (i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i)
20328 if (caps.VertexShaderVersion < tests[i].vs_version
20329 || caps.PixelShaderVersion < tests[i].ps_version)
20331 skip("Vertex / pixel shader version not supported, skipping test %u.\n", i);
20332 continue;
20334 if (tests[i].vs)
20336 hr = IDirect3DDevice9_CreateVertexShader(device, tests[i].vs, &vs);
20337 ok(SUCCEEDED(hr), "Failed to create vertex shader, hr %#x (case %u).\n", hr, i);
20339 else
20341 vs = NULL;
20343 if (tests[i].ps)
20345 hr = IDirect3DDevice9_CreatePixelShader(device, tests[i].ps, &ps);
20346 ok(SUCCEEDED(hr), "Failed to create pixel shader, hr %#x (case %u).\n", hr, i);
20348 else
20350 ps = NULL;
20353 hr = IDirect3DDevice9_SetVertexShader(device, vs);
20354 ok(SUCCEEDED(hr), "Failed to set vertex shader, hr %#x.\n", hr);
20355 hr = IDirect3DDevice9_SetPixelShader(device, ps);
20356 ok(SUCCEEDED(hr), "Failed to set pixel shader, hr %#x.\n", hr);
20358 hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0, 0);
20359 ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
20361 hr = IDirect3DDevice9_BeginScene(device);
20362 ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
20364 hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(quad[0]));
20365 ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
20367 hr = IDirect3DDevice9_EndScene(device);
20368 ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
20370 get_rt_readback(backbuffer, &rb);
20371 color = get_readback_color(&rb, 320, 240);
20372 ok(color_match(color, tests[i].expected, 1)
20373 || (tests[i].allow_zero_alpha && color_match(color, tests[i].expected & 0x00ffffff, 1))
20374 || (tests[i].allow_zero && !color) || (broken(warp && tests[i].broken_warp)),
20375 "Got unexpected color 0x%08x, case %u.\n", color, i);
20376 release_surface_readback(&rb);
20378 if (vs)
20379 IDirect3DVertexShader9_Release(vs);
20380 if (ps)
20381 IDirect3DVertexShader9_Release(ps);
20384 hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
20385 ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
20387 IDirect3DSurface9_Release(backbuffer);
20388 refcount = IDirect3DDevice9_Release(device);
20389 ok(!refcount, "Device has %u references left.\n", refcount);
20390 IDirect3D9_Release(d3d);
20391 DestroyWindow(window);
20394 static void test_multisample_init(void)
20396 IDirect3DDevice9 *device;
20397 IDirect3D9 *d3d;
20398 IDirect3DSurface9 *back, *multi;
20399 ULONG refcount;
20400 HWND window;
20401 HRESULT hr;
20402 D3DCOLOR color;
20403 unsigned int x, y;
20404 struct surface_readback rb;
20405 BOOL all_zero = TRUE;
20407 window = CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
20408 0, 0, 640, 480, NULL, NULL, NULL, NULL);
20409 d3d = Direct3DCreate9(D3D_SDK_VERSION);
20410 ok(!!d3d, "Failed to create a D3D object.\n");
20412 if (FAILED(IDirect3D9_CheckDeviceMultiSampleType(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
20413 D3DFMT_A8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, NULL)))
20415 skip("Multisampling not supported for D3DFMT_A8R8G8B8, skipping multisample init test.\n");
20416 goto done;
20419 if (!(device = create_device(d3d, window, window, TRUE)))
20421 skip("Failed to create a D3D device, skipping tests.\n");
20422 goto done;
20425 hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, &back);
20426 ok(SUCCEEDED(hr), "Failed to get back buffer, hr %#x.\n", hr);
20427 hr = IDirect3DDevice9_CreateRenderTarget(device, 640, 480, D3DFMT_A8R8G8B8,
20428 D3DMULTISAMPLE_2_SAMPLES, 0, FALSE, &multi, NULL);
20429 ok(SUCCEEDED(hr), "Failed to create multisampled render target, hr %#x.\n", hr);
20431 hr = IDirect3DDevice9_StretchRect(device, multi, NULL, back, NULL, D3DTEXF_POINT);
20432 ok(SUCCEEDED(hr), "StretchRect failed, hr %#x.\n", hr);
20434 get_rt_readback(back, &rb);
20435 for (y = 0; y < 480; ++y)
20437 for (x = 0; x < 640; x++)
20439 color = get_readback_color(&rb, x, y);
20440 if (!color_match(color, 0x00000000, 0))
20442 all_zero = FALSE;
20443 break;
20446 if (!all_zero)
20447 break;
20449 release_surface_readback(&rb);
20450 ok(all_zero, "Got unexpected color 0x%08x, position %ux%u.\n", color, x, y);
20452 IDirect3DSurface9_Release(multi);
20453 IDirect3DSurface9_Release(back);
20455 refcount = IDirect3DDevice9_Release(device);
20456 ok(!refcount, "Device has %u references left.\n", refcount);
20458 done:
20459 IDirect3D9_Release(d3d);
20460 DestroyWindow(window);
20463 START_TEST(visual)
20465 D3DADAPTER_IDENTIFIER9 identifier;
20466 IDirect3D9 *d3d;
20467 HRESULT hr;
20469 if (!(d3d = Direct3DCreate9(D3D_SDK_VERSION)))
20471 skip("could not create D3D9 object\n");
20472 return;
20475 memset(&identifier, 0, sizeof(identifier));
20476 hr = IDirect3D9_GetAdapterIdentifier(d3d, 0, 0, &identifier);
20477 ok(SUCCEEDED(hr), "Failed to get adapter identifier, hr %#x.\n", hr);
20478 trace("Driver string: \"%s\"\n", identifier.Driver);
20479 trace("Description string: \"%s\"\n", identifier.Description);
20480 /* Only Windows XP's default VGA driver should have an empty description */
20481 ok(identifier.Description[0] || broken(!strcmp(identifier.Driver, "vga.dll")), "Empty driver description.\n");
20482 trace("Device name string: \"%s\"\n", identifier.DeviceName);
20483 ok(identifier.DeviceName[0], "Empty device name.\n");
20484 trace("Driver version %d.%d.%d.%d\n",
20485 HIWORD(U(identifier.DriverVersion).HighPart), LOWORD(U(identifier.DriverVersion).HighPart),
20486 HIWORD(U(identifier.DriverVersion).LowPart), LOWORD(U(identifier.DriverVersion).LowPart));
20488 IDirect3D9_Release(d3d);
20490 test_sanity();
20491 depth_clamp_test();
20492 stretchrect_test();
20493 lighting_test();
20494 test_specular_lighting();
20495 clear_test();
20496 color_fill_test();
20497 fog_test();
20498 test_cube_wrap();
20499 z_range_test();
20500 maxmip_test();
20501 offscreen_test();
20502 ds_size_test();
20503 test_blend();
20504 test_shademode();
20505 srgbtexture_test();
20506 release_buffer_test();
20507 float_texture_test();
20508 g16r16_texture_test();
20509 pixelshader_blending_test();
20510 texture_transform_flags_test();
20511 autogen_mipmap_test();
20512 fixed_function_decl_test();
20513 conditional_np2_repeat_test();
20514 fixed_function_bumpmap_test();
20515 test_pointsize();
20516 tssargtemp_test();
20517 np2_stretch_rect_test();
20518 yuv_color_test();
20519 yuv_layout_test();
20520 zwriteenable_test();
20521 alphatest_test();
20522 viewport_test();
20523 test_constant_clamp_vs();
20524 test_compare_instructions();
20525 test_mova();
20526 loop_index_test();
20527 sincos_test();
20528 sgn_test();
20529 clip_planes_test();
20530 test_vshader_input();
20531 test_vshader_float16();
20532 stream_test();
20533 fog_with_shader_test();
20534 texbem_test();
20535 texdepth_test();
20536 texkill_test();
20537 volume_v16u16_test();
20538 constant_clamp_ps_test();
20539 cnd_test();
20540 dp2add_ps_test();
20541 unbound_sampler_test();
20542 nested_loop_test();
20543 pretransformed_varying_test();
20544 vface_register_test();
20545 test_fragment_coords();
20546 multiple_rendertargets_test();
20547 texop_test();
20548 texop_range_test();
20549 alphareplicate_test();
20550 dp3_alpha_test();
20551 depth_buffer_test();
20552 depth_buffer2_test();
20553 depth_blit_test();
20554 intz_test();
20555 shadow_test();
20556 fp_special_test();
20557 depth_bounds_test();
20558 srgbwrite_format_test();
20559 update_surface_test();
20560 multisample_get_rtdata_test();
20561 zenable_test();
20562 fog_special_test();
20563 volume_srgb_test();
20564 volume_dxt5_test();
20565 add_dirty_rect_test();
20566 multisampled_depth_buffer_test();
20567 resz_test();
20568 stencil_cull_test();
20569 test_per_stage_constant();
20570 test_3dc_formats();
20571 test_fog_interpolation();
20572 test_negative_fixedfunction_fog();
20573 test_position_index();
20574 test_table_fog_zw();
20575 test_signed_formats();
20576 test_multisample_mismatch();
20577 test_texcoordindex();
20578 test_vertex_blending();
20579 test_updatetexture();
20580 test_depthbias();
20581 test_flip();
20582 test_uninitialized_varyings();
20583 test_multisample_init();